From fdf3d6ef1ac0d714f90baef9707883101d8a7cf8 Mon Sep 17 00:00:00 2001 From: mahlemiut Date: Sat, 26 Aug 2017 22:21:00 +1200 Subject: fmtowns: add preliminary RS232C port. --- src/mame/drivers/fmtowns.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++- src/mame/includes/fmtowns.h | 29 +++++++++++++++ 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/src/mame/drivers/fmtowns.cpp b/src/mame/drivers/fmtowns.cpp index 8d93418eec1..d9d68c49671 100644 --- a/src/mame/drivers/fmtowns.cpp +++ b/src/mame/drivers/fmtowns.cpp @@ -74,7 +74,7 @@ * 0x0600 RW: Keyboard data port (8042) * 0x0602 : Keyboard control port (8042) * 0x0604 : (8042) - * 0x0a00-08: RS-232C interface (i8251) + * 0x0a00-0a: RS-232C interface (i8251) * 0x3000 - 0x3fff : CMOS RAM * 0xfd90-a0: CRTC / Video * 0xff81: CRTC / Video - returns value in RAM location 0xcff81? @@ -2133,6 +2133,72 @@ WRITE_LINE_MEMBER( towns_state::pit_out2_changed ) m_speaker->level_w(speaker_get_spk()); } +WRITE_LINE_MEMBER( towns_state::pit2_out1_changed ) +{ + m_i8251->write_rxc(state); + m_i8251->write_txc(state); +} + +WRITE8_MEMBER( towns_state::towns_serial_w ) +{ + switch(offset) + { + case 0: + m_i8251->data_w(space,0,data); + break; + case 1: + m_i8251->control_w(space,0,data); + break; + case 4: + m_serial_irq_enable = data; + break; + default: + logerror("Invalid or unimplemented serial port write [offset=%02x, data=%02x]\n",offset,data); + } +} + +READ8_MEMBER( towns_state::towns_serial_r ) +{ + switch(offset) + { + case 0: + return m_i8251->data_r(space,0); + case 1: + return m_i8251->status_r(space,0); + case 3: + return m_serial_irq_source; + default: + logerror("Invalid or unimplemented serial port read [offset=%02x]\n",offset); + return 0xff; + } +} + +WRITE_LINE_MEMBER( towns_state::towns_serial_irq ) +{ + m_serial_irq_source = state ? 0x01 : 0x00; + m_pic_master->ir2_w(state); + popmessage("Serial IRQ state: %i\n",state); +} + +WRITE_LINE_MEMBER( towns_state::towns_rxrdy_irq ) +{ + if(m_serial_irq_enable & RXRDY_IRQ_ENABLE) + towns_serial_irq(state); +} + +WRITE_LINE_MEMBER( towns_state::towns_txrdy_irq ) +{ + if(m_serial_irq_enable & TXRDY_IRQ_ENABLE) + towns_serial_irq(state); +} + +WRITE_LINE_MEMBER( towns_state::towns_syndet_irq ) +{ + if(m_serial_irq_enable & SYNDET_IRQ_ENABLE) + towns_serial_irq(state); +} + + static ADDRESS_MAP_START(towns_mem, AS_PROGRAM, 32, towns_state) // memory map based on FM-Towns/Bochs (Bochs modified to emulate the FM-Towns) // may not be (and probably is not) correct @@ -2255,6 +2321,8 @@ static ADDRESS_MAP_START( towns_io , AS_IO, 32, towns_state) AM_RANGE(0x05e8,0x05ef) AM_READWRITE8(towns_sys5e8_r, towns_sys5e8_w, 0x00ff00ff) // Keyboard (8042 MCU) AM_RANGE(0x0600,0x0607) AM_READWRITE8(towns_keyboard_r, towns_keyboard_w,0x00ff00ff) + // RS-232C interface + AM_RANGE(0x0a00,0x0a0b) AM_READWRITE8(towns_serial_r, towns_serial_w, 0x00ff00ff) // SCSI controller AM_RANGE(0x0c30,0x0c37) AM_DEVREADWRITE8("fmscsi",fmscsi_device,fmscsi_r,fmscsi_w,0x00ff00ff) // CMOS @@ -2310,6 +2378,8 @@ static ADDRESS_MAP_START( towns16_io , AS_IO, 16, towns_state) // for the 386SX AM_RANGE(0x05e8,0x05ef) AM_READWRITE8(towns_sys5e8_r, towns_sys5e8_w, 0x00ff) // Keyboard (8042 MCU) AM_RANGE(0x0600,0x0607) AM_READWRITE8(towns_keyboard_r, towns_keyboard_w,0x00ff) + // RS-232C interface + AM_RANGE(0x0a00,0x0a0b) AM_READWRITE8(towns_serial_r, towns_serial_w, 0x00ff) // SCSI controller AM_RANGE(0x0c30,0x0c37) AM_DEVREADWRITE8("fmscsi",fmscsi_device,fmscsi_r,fmscsi_w,0x00ff) // CMOS @@ -2644,6 +2714,7 @@ void towns_state::machine_reset() m_towns_rtc_timer->adjust(attotime::zero,0,attotime::from_hz(1)); m_towns_kb_timer->adjust(attotime::zero,0,attotime::from_msec(10)); m_towns_freerun_counter->adjust(attotime::zero,0,attotime::from_usec(1)); + m_serial_irq_source = 0; } READ8_MEMBER(towns_state::get_slave_ack) @@ -2733,7 +2804,8 @@ static MACHINE_CONFIG_START( towns_base ) MCFG_DEVICE_ADD("pit2", PIT8253, 0) MCFG_PIT8253_CLK0(307200) // reserved - MCFG_PIT8253_CLK1(307200) // RS-232 + MCFG_PIT8253_CLK1(1228800) // RS-232 + MCFG_PIT8253_OUT1_HANDLER(WRITELINE(towns_state, pit2_out1_changed)) MCFG_PIT8253_CLK2(307200) // reserved MCFG_PIC8259_ADD( "pic8259_master", INPUTLINE("maincpu", 0), VCC, READ8(towns_state,get_slave_ack)) @@ -2781,6 +2853,18 @@ static MACHINE_CONFIG_START( towns_base ) MCFG_UPD71071_DMA_WRITE_1_CB(WRITE16(towns_state, towns_scsi_dma_w)) //MCFG_VIDEO_START_OVERRIDE(towns_state,towns) + + MCFG_DEVICE_ADD("i8251", I8251, 0) + MCFG_I8251_RXRDY_HANDLER(WRITELINE(towns_state, towns_rxrdy_irq)) + MCFG_I8251_TXRDY_HANDLER(WRITELINE(towns_state, towns_txrdy_irq)) + MCFG_I8251_SYNDET_HANDLER(WRITELINE(towns_state, towns_syndet_irq)) + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232c", rs232_port_device, write_dtr)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232c", rs232_port_device, write_rts)) + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232c", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232c", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("i8251",i8251_device, write_rxd)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("i8251",i8251_device, write_dsr)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("i8251",i8251_device, write_cts)) MCFG_FMT_ICMEMCARD_ADD("icmemcard") diff --git a/src/mame/includes/fmtowns.h b/src/mame/includes/fmtowns.h index fff7ba23a12..8309acdf37f 100644 --- a/src/mame/includes/fmtowns.h +++ b/src/mame/includes/fmtowns.h @@ -16,6 +16,7 @@ #include "machine/ram.h" #include "machine/upd71071.h" #include "machine/wd_fdc.h" +#include "machine/i8251.h" #include "sound/2612intf.h" #include "sound/cdda.h" #include "sound/rf5c68.h" @@ -23,6 +24,7 @@ #include "bus/generic/carts.h" #include "bus/generic/slot.h" +#include "bus/rs232/rs232.h" #include "formats/fmtowns_dsk.h" @@ -99,6 +101,8 @@ class towns_state : public driver_device m_flop0(*this, "fdc:0"), m_flop1(*this, "fdc:1"), m_icmemcard(*this, "icmemcard"), + m_i8251(*this, "i8251"), + m_rs232(*this, "rs232c"), m_nvram(*this, "nvram"), m_nvram16(*this, "nvram16"), m_ctrltype(*this, "ctrltype"), @@ -132,6 +136,8 @@ class towns_state : public driver_device required_device m_flop0; required_device m_flop1; required_device m_icmemcard; + required_device m_i8251; + required_device m_rs232; ram_device* m_messram; cdrom_image_device* m_cdrom; cdda_device* m_cdda; @@ -190,7 +196,22 @@ class towns_state : public driver_device uint8_t m_pit_out2; uint8_t m_timer0; uint8_t m_timer1; + + uint8_t m_serial_irq_source; + uint8_t m_serial_irq_enable; // RS232 interrupt control + enum + { + TXC_EXTERNAL = 0x80, + RXC_EXTERNAL = 0x40, + ER_CONTROL = 0x20, + CI_IRQ_ENABLE = 0x10, + CS_IRQ_ENABLE = 0x08, + SYNDET_IRQ_ENABLE = 0x04, + RXRDY_IRQ_ENABLE = 0x02, + TXRDY_IRQ_ENABLE = 0x01 + }; + emu_timer* m_towns_wait_timer; emu_timer* m_towns_status_timer; emu_timer* m_towns_cdda_timer; @@ -276,6 +297,13 @@ class towns_state : public driver_device DECLARE_WRITE_LINE_MEMBER(mb8877a_irq_w); DECLARE_WRITE_LINE_MEMBER(mb8877a_drq_w); DECLARE_WRITE_LINE_MEMBER(pit_out2_changed); + + DECLARE_WRITE_LINE_MEMBER(towns_serial_irq); + DECLARE_WRITE_LINE_MEMBER(towns_rxrdy_irq); + DECLARE_WRITE_LINE_MEMBER(towns_txrdy_irq); + DECLARE_WRITE_LINE_MEMBER(towns_syndet_irq); + DECLARE_READ8_MEMBER(towns_serial_r); + DECLARE_WRITE8_MEMBER(towns_serial_w); RF5C68_SAMPLE_END_CB_MEMBER(towns_pcm_irq); @@ -333,6 +361,7 @@ public: DECLARE_WRITE_LINE_MEMBER(towns_scsi_drq); DECLARE_WRITE_LINE_MEMBER(towns_pit_out0_changed); DECLARE_WRITE_LINE_MEMBER(towns_pit_out1_changed); + DECLARE_WRITE_LINE_MEMBER(pit2_out1_changed); DECLARE_READ8_MEMBER(get_slave_ack); DECLARE_WRITE_LINE_MEMBER(towns_fm_irq); DECLARE_FLOPPY_FORMATS(floppy_formats); -- cgit v1.2.3