summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/fdc37c93x.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/fdc37c93x.cpp')
-rw-r--r--src/devices/machine/fdc37c93x.cpp163
1 files changed, 158 insertions, 5 deletions
diff --git a/src/devices/machine/fdc37c93x.cpp b/src/devices/machine/fdc37c93x.cpp
index f6cd3171fa2..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,16 +256,39 @@ 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))
MCFG_MC146818_CENTURY_INDEX(0x32)
// keyboard
- MCFG_DEVICE_ADD("pc_kbdc", KBDC8042, 0)
- MCFG_KBDC8042_KEYBOARD_TYPE(KBDC8042_PS2)
- MCFG_KBDC8042_INPUT_BUFFER_FULL_CB(WRITELINE(*this, fdc37c93x_device, irq_keyboard_w))
- MCFG_KBDC8042_SYSTEM_RESET_CB(WRITELINE(*this, fdc37c93x_device, kbdp20_gp20_reset_w))
- MCFG_KBDC8042_GATE_A20_CB(WRITELINE(*this, fdc37c93x_device, kbdp21_gp25_gatea20_w))
+ KBDC8042(config, m_kbdc);
+ m_kbdc->set_keyboard_type(kbdc8042_device::KBDC8042_PS2);
+ m_kbdc->input_buffer_full_callback().set(FUNC(fdc37c93x_device::irq_keyboard_w));
+ m_kbdc->system_reset_callback().set(FUNC(fdc37c93x_device::kbdp20_gp20_reset_w));
+ m_kbdc->gate_a20_callback().set(FUNC(fdc37c93x_device::kbdp21_gp25_gatea20_w));
MACHINE_CONFIG_END
WRITE_LINE_MEMBER(fdc37c93x_device::irq_floppy_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)