From 2629c2c367518774e3c6207c91e7615db99d5f7e Mon Sep 17 00:00:00 2001 From: yz70s Date: Wed, 8 Aug 2018 23:57:39 +0200 Subject: fdc37c93x.cpp: add serial ports (nw) --- src/devices/machine/fdc37c93x.cpp | 153 ++++++++++++++++++++++++++++++++++++++ src/devices/machine/fdc37c93x.h | 23 +++++- 2 files changed, 172 insertions(+), 4 deletions(-) diff --git a/src/devices/machine/fdc37c93x.cpp b/src/devices/machine/fdc37c93x.cpp index a238c3126a4..d30d6080716 100644 --- a/src/devices/machine/fdc37c93x.cpp +++ b/src/devices/machine/fdc37c93x.cpp @@ -11,6 +11,10 @@ SMSC FDC37C93x Plug and Play Compatible Ultra I/O Controller #include "emu.h" #include "bus/isa/isa.h" #include "machine/ds128x.h" +#include "bus/rs232/rs232.h" +#include "bus/rs232/ser_mouse.h" +#include "bus/rs232/terminal.h" +#include "bus/rs232/null_modem.h" #include "machine/fdc37c93x.h" DEFINE_DEVICE_TYPE(FDC37C93X, fdc37c93x_device, "fdc37c93x", "SMSC FDC37C93X") @@ -30,6 +34,8 @@ fdc37c93x_device::fdc37c93x_device(const machine_config &mconfig, const char *ta , m_irq9_callback(*this) , floppy_controller_fdcdev(*this, "fdc") , pc_lpt_lptdev(*this, "lpt") + , pc_serial1_comdev(*this, "uart_0") + , pc_serial2_comdev(*this, "uart_1") , ds12885_rtcdev(*this, "rtc") , m_kbdc(*this, "pc_kbdc") , sysopt_pin(0) @@ -227,6 +233,14 @@ static void pc_hd_floppies(device_slot_interface &device) device.option_add("35dd", FLOPPY_35_DD); } +static void isa_com(device_slot_interface &device) +{ + device.option_add("microsoft_mouse", MSFT_SERIAL_MOUSE); + device.option_add("msystems_mouse", MSYSTEM_SERIAL_MOUSE); + device.option_add("terminal", SERIAL_TERMINAL); + device.option_add("null_modem", NULL_MODEM); +} + FLOPPY_FORMATS_MEMBER(fdc37c93x_device::floppy_formats) FLOPPY_PC_FORMAT, FLOPPY_NASLITE_FORMAT @@ -242,6 +256,29 @@ MACHINE_CONFIG_START(fdc37c93x_device::device_add_mconfig) // parallel port MCFG_DEVICE_ADD("lpt", PC_LPT, 0) MCFG_PC_LPT_IRQ_HANDLER(WRITELINE(*this, fdc37c93x_device, irq_parallel_w)) + // serial ports + MCFG_DEVICE_ADD("uart_0", NS16450, XTAL(1'843'200)) // or NS16550 ? + MCFG_INS8250_OUT_TX_CB(WRITELINE("serport0", rs232_port_device, write_txd)) + MCFG_INS8250_OUT_DTR_CB(WRITELINE("serport0", rs232_port_device, write_dtr)) + MCFG_INS8250_OUT_RTS_CB(WRITELINE("serport0", rs232_port_device, write_rts)) + MCFG_INS8250_OUT_INT_CB(WRITELINE(*this, fdc37c93x_device, irq_serial1_w)) + MCFG_DEVICE_ADD("uart_1", NS16450, XTAL(1'843'200)) + MCFG_INS8250_OUT_TX_CB(WRITELINE("serport1", rs232_port_device, write_txd)) + MCFG_INS8250_OUT_DTR_CB(WRITELINE("serport1", rs232_port_device, write_dtr)) + MCFG_INS8250_OUT_RTS_CB(WRITELINE("serport1", rs232_port_device, write_rts)) + MCFG_INS8250_OUT_INT_CB(WRITELINE(*this, fdc37c93x_device, irq_serial2_w)) + MCFG_DEVICE_ADD("serport0", RS232_PORT, isa_com, "microsoft_mouse") + MCFG_RS232_RXD_HANDLER(WRITELINE("uart_0", ins8250_uart_device, rx_w)) + MCFG_RS232_DCD_HANDLER(WRITELINE("uart_0", ins8250_uart_device, dcd_w)) + MCFG_RS232_DSR_HANDLER(WRITELINE("uart_0", ins8250_uart_device, dsr_w)) + MCFG_RS232_RI_HANDLER(WRITELINE("uart_0", ins8250_uart_device, ri_w)) + MCFG_RS232_CTS_HANDLER(WRITELINE("uart_0", ins8250_uart_device, cts_w)) + MCFG_DEVICE_ADD("serport1", RS232_PORT, isa_com, nullptr) + MCFG_RS232_RXD_HANDLER(WRITELINE("uart_1", ins8250_uart_device, rx_w)) + MCFG_RS232_DCD_HANDLER(WRITELINE("uart_1", ins8250_uart_device, dcd_w)) + MCFG_RS232_DSR_HANDLER(WRITELINE("uart_1", ins8250_uart_device, dsr_w)) + MCFG_RS232_RI_HANDLER(WRITELINE("uart_1", ins8250_uart_device, ri_w)) + MCFG_RS232_CTS_HANDLER(WRITELINE("uart_1", ins8250_uart_device, cts_w)) // RTC MCFG_DS12885_ADD("rtc") MCFG_MC146818_IRQ_HANDLER(WRITELINE(*this, fdc37c93x_device, irq_rtc_w)) @@ -275,6 +312,20 @@ WRITE_LINE_MEMBER(fdc37c93x_device::irq_parallel_w) request_irq(configuration_registers[LogicalDevice::Parallel][0x70], state ? ASSERT_LINE : CLEAR_LINE); } +WRITE_LINE_MEMBER(fdc37c93x_device::irq_serial1_w) +{ + if (enabled_logical[LogicalDevice::Serial1] == false) + return; + request_irq(configuration_registers[LogicalDevice::Serial1][0x70], state ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(fdc37c93x_device::irq_serial2_w) +{ + if (enabled_logical[LogicalDevice::Serial2] == false) + return; + request_irq(configuration_registers[LogicalDevice::Serial2][0x70], state ? ASSERT_LINE : CLEAR_LINE); +} + WRITE_LINE_MEMBER(fdc37c93x_device::irq_rtc_w) { if (enabled_logical[LogicalDevice::RTC] == false) @@ -444,6 +495,64 @@ void fdc37c93x_device::unmap_lpt_addresses() m_isa->unmap_device(base, base + 3); } +void fdc37c93x_device::map_serial1(address_map &map) +{ + map(0x0, 0x7).rw(FUNC(fdc37c93x_device::serial1_read), FUNC(fdc37c93x_device::serial1_write)); +} + +READ8_MEMBER(fdc37c93x_device::serial1_read) +{ + return pc_serial1_comdev->ins8250_r(space, offset, mem_mask); +} + +WRITE8_MEMBER(fdc37c93x_device::serial1_write) +{ + pc_serial1_comdev->ins8250_w(space, offset, data, mem_mask); +} + +void fdc37c93x_device::map_serial1_addresses() +{ + uint16_t base = get_base_address(LogicalDevice::Serial1, 0); + + m_isa->install_device(base, base + 7, *this, &fdc37c93x_device::map_serial1); +} + +void fdc37c93x_device::unmap_serial1_addresses() +{ + uint16_t base = get_base_address(LogicalDevice::Serial1, 0); + + m_isa->unmap_device(base, base + 7); +} + +void fdc37c93x_device::map_serial2(address_map &map) +{ + map(0x0, 0x7).rw(FUNC(fdc37c93x_device::serial2_read), FUNC(fdc37c93x_device::serial2_write)); +} + +READ8_MEMBER(fdc37c93x_device::serial2_read) +{ + return pc_serial2_comdev->ins8250_r(space, offset, mem_mask); +} + +WRITE8_MEMBER(fdc37c93x_device::serial2_write) +{ + pc_serial2_comdev->ins8250_w(space, offset, data, mem_mask); +} + +void fdc37c93x_device::map_serial2_addresses() +{ + uint16_t base = get_base_address(LogicalDevice::Serial2, 0); + + m_isa->install_device(base, base + 7, *this, &fdc37c93x_device::map_serial2); +} + +void fdc37c93x_device::unmap_serial2_addresses() +{ + uint16_t base = get_base_address(LogicalDevice::Serial2, 0); + + m_isa->unmap_device(base, base + 3); +} + void fdc37c93x_device::map_rtc(address_map &map) { map(0x0, 0xf).rw(FUNC(fdc37c93x_device::rtc_read), FUNC(fdc37c93x_device::rtc_write)); @@ -541,6 +650,10 @@ void fdc37c93x_device::remap(int space_id, offs_t start, offs_t end) map_fdc_addresses(); if (enabled_logical[LogicalDevice::Parallel] == true) map_lpt_addresses(); + if (enabled_logical[LogicalDevice::Serial1] == true) + map_serial1_addresses(); + if (enabled_logical[LogicalDevice::Serial2] == true) + map_serial2_addresses(); if (enabled_logical[LogicalDevice::RTC] == true) map_rtc_addresses(); if (enabled_logical[LogicalDevice::Keyboard] == true) @@ -641,6 +754,46 @@ void fdc37c93x_device::write_parallel_configuration_register(int index, int data } } +void fdc37c93x_device::write_serial1_configuration_register(int index, int data) +{ + if (index == 0x30) + { + if (data & 1) + { + if (enabled_logical[LogicalDevice::Serial1] == false) + map_serial1_addresses(); + enabled_logical[LogicalDevice::Serial1] = true; + logerror("Enabled Serial1 at %04X\n", get_base_address(LogicalDevice::Serial1, 0)); + } + else + { + if (enabled_logical[LogicalDevice::Serial1] == true) + unmap_serial1_addresses(); + enabled_logical[LogicalDevice::Serial1] = false; + } + } +} + +void fdc37c93x_device::write_serial2_configuration_register(int index, int data) +{ + if (index == 0x30) + { + if (data & 1) + { + if (enabled_logical[LogicalDevice::Serial2] == false) + map_serial2_addresses(); + enabled_logical[LogicalDevice::Serial2] = true; + logerror("Enabled Serial2 at %04X\n", get_base_address(LogicalDevice::Serial2, 0)); + } + else + { + if (enabled_logical[LogicalDevice::Serial2] == true) + unmap_serial2_addresses(); + enabled_logical[LogicalDevice::Serial2] = false; + } + } +} + void fdc37c93x_device::write_rtc_configuration_register(int index, int data) { if (index == 0x30) diff --git a/src/devices/machine/fdc37c93x.h b/src/devices/machine/fdc37c93x.h index d334a0ab2eb..30150b4b3c3 100644 --- a/src/devices/machine/fdc37c93x.h +++ b/src/devices/machine/fdc37c93x.h @@ -20,6 +20,8 @@ SMSC FDC37C93x Plug and Play Compatible Ultra I/O Controller #include "formats/naslite_dsk.h" // parallel port #include "machine/pc_lpt.h" +// serial port +#include "machine/ins8250.h" // make sure that pckeybrd.cpp 8042kbdc.cpp are present in project @@ -49,6 +51,9 @@ public: DECLARE_WRITE_LINE_MEMBER(drq_floppy_w); // for the internal parallel port DECLARE_WRITE_LINE_MEMBER(irq_parallel_w); + // for the internal serial ports + DECLARE_WRITE_LINE_MEMBER(irq_serial1_w); + DECLARE_WRITE_LINE_MEMBER(irq_serial2_w); // rtc DECLARE_WRITE_LINE_MEMBER(irq_rtc_w); // keyboard @@ -58,9 +63,9 @@ public: void unmap_fdc(address_map &map); void map_lpt(address_map &map); - void unmap_lpt(address_map &map); + void map_serial1(address_map &map); + void map_serial2(address_map &map); void map_rtc(address_map &map); - void unmap_rtc(address_map &map); void map_keyboard(address_map &map); void unmap_keyboard(address_map &map); @@ -68,6 +73,10 @@ public: DECLARE_WRITE8_MEMBER(disabled_write); DECLARE_READ8_MEMBER(lpt_read); DECLARE_WRITE8_MEMBER(lpt_write); + DECLARE_READ8_MEMBER(serial1_read); + DECLARE_WRITE8_MEMBER(serial1_write); + DECLARE_READ8_MEMBER(serial2_read); + DECLARE_WRITE8_MEMBER(serial2_write); DECLARE_READ8_MEMBER(rtc_read); DECLARE_WRITE8_MEMBER(rtc_write); DECLARE_READ8_MEMBER(at_keybc_r); @@ -118,6 +127,8 @@ private: devcb_write_line m_irq9_callback; required_device floppy_controller_fdcdev; required_device pc_lpt_lptdev; + required_device pc_serial1_comdev; + required_device pc_serial2_comdev; required_device ds12885_rtcdev; required_device m_kbdc; int sysopt_pin; @@ -131,6 +142,10 @@ private: void unmap_fdc_addresses(); void map_lpt_addresses(); void unmap_lpt_addresses(); + void map_serial1_addresses(); + void unmap_serial1_addresses(); + void map_serial2_addresses(); + void unmap_serial2_addresses(); void map_rtc_addresses(); void unmap_rtc_addresses(); void map_keyboard_addresses(); @@ -141,8 +156,8 @@ private: void write_ide1_configuration_register(int index, int data) {} void write_ide2_configuration_register(int index, int data) {} void write_parallel_configuration_register(int index, int data); - void write_serial1_configuration_register(int index, int data) {} - void write_serial2_configuration_register(int index, int data) {} + void write_serial1_configuration_register(int index, int data); + void write_serial2_configuration_register(int index, int data); void write_rtc_configuration_register(int index, int data); void write_keyboard_configuration_register(int index, int data); void write_auxio_configuration_register(int index, int data); -- cgit v1.2.3