summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mahlemiut <bsr@xnet.co.nz>2017-08-26 22:21:00 +1200
committer mahlemiut <bsr@xnet.co.nz>2017-08-26 22:21:00 +1200
commitfdf3d6ef1ac0d714f90baef9707883101d8a7cf8 (patch)
tree98d47808bf1889dfd0955cd63eda2e4dd6121587
parent348285528ad087b39f66ce424deeaaf0ef900eda (diff)
fmtowns: add preliminary RS232C port.
-rw-r--r--src/mame/drivers/fmtowns.cpp88
-rw-r--r--src/mame/includes/fmtowns.h29
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<floppy_connector> m_flop0;
required_device<floppy_connector> m_flop1;
required_device<fmt_icmem_device> m_icmemcard;
+ required_device<i8251_device> m_i8251;
+ required_device<rs232_port_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);