diff options
Diffstat (limited to 'src/devices/machine/pc87306.cpp')
-rw-r--r-- | src/devices/machine/pc87306.cpp | 220 |
1 files changed, 205 insertions, 15 deletions
diff --git a/src/devices/machine/pc87306.cpp b/src/devices/machine/pc87306.cpp index bc26d2e5c82..8bc2deb00b0 100644 --- a/src/devices/machine/pc87306.cpp +++ b/src/devices/machine/pc87306.cpp @@ -1,18 +1,19 @@ // license:BSD-3-Clause // copyright-holders: Angelo Salese -/*************************************************************************** +/************************************************************************************************** National Semiconductor PC87306 Super I/O TODO: -- Barely enough to make it surpass POST test 0x05 in misc/odyssey.cpp +- Barely enough to make it surpass POST test 0x05 in misc/odyssey.cpp; +- COM1/COM2/LPT1 address and irq select; -***************************************************************************/ +**************************************************************************************************/ #include "emu.h" -#include "bus/isa/isa.h" +#include "pc87306.h" + //#include "machine/ds128x.h" -#include "machine/pc87306.h" #include "machine/pckeybrd.h" #define LOG_WARN (1U << 1) // Show warnings @@ -32,18 +33,19 @@ pc87306_device::pc87306_device(const machine_config &mconfig, const char *tag, d , m_space_config("superio_config_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(pc87306_device::config_map), this)) , m_kbdc(*this, "pc_kbdc") , m_rtc(*this, "rtc") - //, m_logical_view(*this, "logical_view") + , m_pc_com(*this, "uart%d", 0U) + , m_pc_lpt(*this, "lpta") , m_gp20_reset_callback(*this) , m_gp25_gatea20_callback(*this) , m_irq1_callback(*this) , m_irq8_callback(*this) , m_irq9_callback(*this) -// , m_txd1_callback(*this) -// , m_ndtr1_callback(*this) -// , m_nrts1_callback(*this) -// , m_txd2_callback(*this) -// , m_ndtr2_callback(*this) -// , m_nrts2_callback(*this) + , m_txd1_callback(*this) + , m_ndtr1_callback(*this) + , m_nrts1_callback(*this) + , m_txd2_callback(*this) + , m_ndtr2_callback(*this) + , m_nrts2_callback(*this) { } @@ -89,6 +91,21 @@ void pc87306_device::device_add_mconfig(machine_config &config) at_keyboard_device &at_keyb(AT_KEYB(config, "at_keyboard", pc_keyboard_device::KEYBOARD_TYPE::AT, 1)); at_keyb.keypress().set(m_kbdc, FUNC(kbdc8042_device::keyboard_w)); + + PC_LPT(config, m_pc_lpt); + m_pc_lpt->irq_handler().set(FUNC(pc87306_device::irq_parallel_w)); + + NS16550(config, m_pc_com[0], XTAL(1'843'200)); + m_pc_com[0]->out_int_callback().set(FUNC(pc87306_device::irq_serial1_w)); + m_pc_com[0]->out_tx_callback().set(FUNC(pc87306_device::txd_serial1_w)); + m_pc_com[0]->out_dtr_callback().set(FUNC(pc87306_device::dtr_serial1_w)); + m_pc_com[0]->out_rts_callback().set(FUNC(pc87306_device::rts_serial1_w)); + + NS16550(config, m_pc_com[1], XTAL(1'843'200)); + m_pc_com[1]->out_int_callback().set(FUNC(pc87306_device::irq_serial2_w)); + m_pc_com[1]->out_tx_callback().set(FUNC(pc87306_device::txd_serial2_w)); + m_pc_com[1]->out_dtr_callback().set(FUNC(pc87306_device::dtr_serial2_w)); + m_pc_com[1]->out_rts_callback().set(FUNC(pc87306_device::rts_serial2_w)); } void pc87306_device::remap(int space_id, offs_t start, offs_t end) @@ -107,6 +124,16 @@ void pc87306_device::remap(int space_id, offs_t start, offs_t end) if (BIT(m_krr, 3)) m_isa->install_device(0x70, 0x71, read8sm_delegate(*this, FUNC(pc87306_device::rtc_r)), write8sm_delegate(*this, FUNC(pc87306_device::rtc_w))); + + if (BIT(m_fer, 0)) + m_isa->install_device(0x378, 0x37f, read8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::read)), write8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::write))); + + if (BIT(m_fer, 1)) + m_isa->install_device(0x3f8, 0x3ff, read8sm_delegate(*m_pc_com[0], FUNC(ns16450_device::ins8250_r)), write8sm_delegate(*m_pc_com[0], FUNC(ns16450_device::ins8250_w))); + + if (BIT(m_fer, 2)) + m_isa->install_device(0x2f8, 0x2ff, read8sm_delegate(*m_pc_com[1], FUNC(ns16450_device::ins8250_r)), write8sm_delegate(*m_pc_com[1], FUNC(ns16450_device::ins8250_w))); + } } @@ -140,8 +167,8 @@ void pc87306_device::write(offs_t offset, u8 data) void pc87306_device::config_map(address_map &map) { -// map(0x00, 0x00) FER Function Enable Register -// map(0x01, 0x01) FAR Function Address Register + map(0x00, 0x00).rw(FUNC(pc87306_device::fer_r), FUNC(pc87306_device::fer_w)); + map(0x01, 0x01).rw(FUNC(pc87306_device::far_r), FUNC(pc87306_device::far_w)); // map(0x02, 0x02) PTR Power and Test Register // map(0x03, 0x03) FCR Function Control Register // map(0x04, 0x04) PCR Printer Control Register @@ -171,8 +198,49 @@ void pc87306_device::config_map(address_map &map) // map(0x1c, 0x1c) PNP1 Plug and Play Configuration 1 Register } -// [0x05] KRR KBC and RTC Control Register /* + * [0x00] FER Function Enable Register + * x--- ---- IDE address select + * -x-- ---- IDE i/f enable + * --x- ---- FDC address select + * ---x ---- (0) x2 floppy drives (1) x4 floppy drives + * ---- x--- FDC enable + * ---- -x-- UART2 enable + * ---- --x- UART1 enable + * ---- ---x Parallel Port enable + */ +u8 pc87306_device::fer_r(offs_t offset) +{ + return m_fer; +} + +void pc87306_device::fer_w(offs_t offset, u8 data) +{ + m_fer = data; + remap(AS_IO, 0, 0x400); +} + +/* + * [0x01] FAR Function Address Register + * xxxx ---- UART2 address select + * xx-- xx-- UART1 address select + * ---- --xx parallel address select + */ +u8 pc87306_device::far_r(offs_t offset) +{ + return m_far; +} + +void pc87306_device::far_w(offs_t offset, u8 data) +{ + m_far = data; + remap(AS_IO, 0, 0x400); +} + + +/* + * [0x05] KRR KBC and RTC Control Register + * * x--- ---- KBC clock source select (0) X1 clock (1) SYSCLK * --x- ---- RAMSREL RTC bank select * ---- x--- RTC enable bit @@ -254,6 +322,128 @@ void pc87306_device::irq_mouse_w(int state) request_irq(12, state ? ASSERT_LINE : CLEAR_LINE); } +/* + * Serial + */ + +void pc87306_device::irq_serial1_w(int state) +{ + if (!(BIT(m_fer, 1))) + return; + request_irq(3, state ? ASSERT_LINE : CLEAR_LINE); +} + +void pc87306_device::irq_serial2_w(int state) +{ + if (!(BIT(m_fer, 2))) + return; + request_irq(4, state ? ASSERT_LINE : CLEAR_LINE); +} + +void pc87306_device::txd_serial1_w(int state) +{ + if (!(BIT(m_fer, 1))) + return; + m_txd1_callback(state); +} + +void pc87306_device::txd_serial2_w(int state) +{ + if (!(BIT(m_fer, 2))) + return; + m_txd2_callback(state); +} + +void pc87306_device::dtr_serial1_w(int state) +{ + if (!(BIT(m_fer, 1))) + return; + m_ndtr1_callback(state); +} + +void pc87306_device::dtr_serial2_w(int state) +{ + if (!(BIT(m_fer, 2))) + return; + m_ndtr2_callback(state); +} + +void pc87306_device::rts_serial1_w(int state) +{ + if (!(BIT(m_fer, 1))) + return; + m_nrts1_callback(state); +} + +void pc87306_device::rts_serial2_w(int state) +{ + if (!(BIT(m_fer, 2))) + return; + m_nrts2_callback(state); +} + +void pc87306_device::rxd1_w(int state) +{ + m_pc_com[0]->rx_w(state); +} + +void pc87306_device::ndcd1_w(int state) +{ + m_pc_com[0]->dcd_w(state); +} + +void pc87306_device::ndsr1_w(int state) +{ + m_pc_com[0]->dsr_w(state); +} + +void pc87306_device::nri1_w(int state) +{ + m_pc_com[0]->ri_w(state); +} + +void pc87306_device::ncts1_w(int state) +{ + m_pc_com[0]->cts_w(state); +} + +void pc87306_device::rxd2_w(int state) +{ + m_pc_com[1]->rx_w(state); +} + +void pc87306_device::ndcd2_w(int state) +{ + m_pc_com[1]->dcd_w(state); +} + +void pc87306_device::ndsr2_w(int state) +{ + m_pc_com[1]->dsr_w(state); +} + +void pc87306_device::nri2_w(int state) +{ + m_pc_com[1]->ri_w(state); +} + +void pc87306_device::ncts2_w(int state) +{ + m_pc_com[1]->cts_w(state); +} + +/* + * Parallel + */ + +void pc87306_device::irq_parallel_w(int state) +{ + if (!(BIT(m_fer, 0))) + return; + request_irq(5, state ? ASSERT_LINE : CLEAR_LINE); +} + + void pc87306_device::request_irq(int irq, int state) { switch (irq) |