diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index c093d9c518d..2fcc8ea9a69 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -4361,6 +4361,18 @@ if (MACHINES["FDC37C93X"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/pc87306.h,MACHINES["PC87306"] = true +--------------------------------------------------- + +if (MACHINES["PC87306"]~=null) then + files { + MAME_DIR .. "src/devices/machine/pc87306.cpp", + MAME_DIR .. "src/devices/machine/pc87306.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/w83977tf.h,MACHINES["W83977TF"] = true diff --git a/src/devices/machine/pc87306.cpp b/src/devices/machine/pc87306.cpp new file mode 100644 index 00000000000..c72717e30b9 --- /dev/null +++ b/src/devices/machine/pc87306.cpp @@ -0,0 +1,141 @@ +// 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 + +***************************************************************************/ + +#include "emu.h" +#include "bus/isa/isa.h" +//#include "machine/ds128x.h" +#include "machine/pc87306.h" + +#define VERBOSE (LOG_GENERAL) +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(PC87306, pc87306_device, "pc87306", "National Semiconductor PC87306 Super I/O Enhanced Sidewinder Lite") + +pc87306_device::pc87306_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, PC87306, tag, owner, clock) + , device_isa16_card_interface(mconfig, *this) + , device_memory_interface(mconfig, *this) + , 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_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) +{ } + + +void pc87306_device::device_start() +{ + set_isa_device(); + //m_isa->set_dma_channel(0, this, true); + //m_isa->set_dma_channel(1, this, true); + //m_isa->set_dma_channel(2, this, true); + //m_isa->set_dma_channel(3, this, true); + remap(AS_IO, 0, 0x400); +} + +void pc87306_device::device_reset() +{ + m_locked_state = 2; +} + +device_memory_interface::space_config_vector pc87306_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(0, &m_space_config) + }; +} + +void pc87306_device::device_add_mconfig(machine_config &config) +{ + // doc doesn't explicitly mention this being at 8, assume from intialization + DS12885(config, m_rtc, 32.768_kHz_XTAL); +// m_rtc->irq().set(FUNC(pc87306_device::irq_rtc_w)); + m_rtc->set_century_index(0x32); + + KBDC8042(config, m_kbdc); + m_kbdc->set_keyboard_type(kbdc8042_device::KBDC8042_PS2); + m_kbdc->set_interrupt_type(kbdc8042_device::KBDC8042_DOUBLE); +// m_kbdc->input_buffer_full_callback().set(FUNC(pc87306_device::irq_keyboard_w)); +// m_kbdc->input_buffer_full_mouse_callback().set(FUNC(pc87306_device::irq_mouse_w)); +// m_kbdc->system_reset_callback().set(FUNC(pc87306_device::kbdp20_gp20_reset_w)); +// m_kbdc->gate_a20_callback().set(FUNC(pc87306_device::kbdp21_gp25_gatea20_w)); +} + +void pc87306_device::remap(int space_id, offs_t start, offs_t end) +{ + if (space_id == AS_IO) + { + // TODO: BADDR1/0 config pin controlled + u16 superio_base = 0x0398; + m_isa->install_device(superio_base, superio_base + 1, read8sm_delegate(*this, FUNC(pc87306_device::read)), write8sm_delegate(*this, FUNC(pc87306_device::write))); + + + m_isa->install_device(0x60, 0x60, read8sm_delegate(*m_kbdc, FUNC(kbdc8042_device::data_r)), write8sm_delegate(*m_kbdc, FUNC(kbdc8042_device::data_w))); + m_isa->install_device(0x64, 0x64, read8sm_delegate(*this, FUNC(pc87306_device::keybc_status_r)), write8sm_delegate(*this, FUNC(pc87306_device::keybc_command_w))); + + m_isa->install_device(0x70, 0x71, read8sm_delegate(*m_rtc, FUNC(ds12885_device::read)), write8sm_delegate(*m_rtc, FUNC(ds12885_device::write))); + } +} + +u8 pc87306_device::read(offs_t offset) +{ + if (m_locked_state) + { + if (!machine().side_effects_disabled()) + m_locked_state --; + return (m_locked_state) ? 0x88 : 0x00; + } + + if (offset == 0) + return m_index; + + return space().read_byte(m_index); +} + +void pc87306_device::write(offs_t offset, u8 data) +{ + if (offset == 0) + { + m_index = data; + } + else + { + //remap(AS_IO, 0, 0x400); + space().write_byte(m_index, data); + } +} + +void pc87306_device::config_map(address_map &map) +{ + map(0x00, 0xff).unmaprw(); +} + + +u8 pc87306_device::keybc_status_r(offs_t offset) +{ + return (m_kbdc->data_r(4) & 0xfb) | 0x10; // bios needs bit 2 to be 0 as powerup and bit 4 to be 1 +} + +void pc87306_device::keybc_command_w(offs_t offset, u8 data) +{ + m_kbdc->data_w(4, data); +} diff --git a/src/devices/machine/pc87306.h b/src/devices/machine/pc87306.h new file mode 100644 index 00000000000..f0f4515c916 --- /dev/null +++ b/src/devices/machine/pc87306.h @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders: Angelo Salese + +#ifndef MAME_MACHINE_PC87306_H +#define MAME_MACHINE_PC87306_H + +#pragma once + +#include "bus/isa/isa.h" +#include "machine/8042kbdc.h" +#include "machine/ds128x.h" + +class pc87306_device : public device_t, + public device_isa16_card_interface, + public device_memory_interface +{ +public: + pc87306_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ~pc87306_device() {} + + void remap(int space_id, offs_t start, offs_t end) override; + + auto gp20_reset() { return m_gp20_reset_callback.bind(); } + auto gp25_gatea20() { return m_gp25_gatea20_callback.bind(); } + auto irq1() { return m_irq1_callback.bind(); } + auto irq8() { return m_irq8_callback.bind(); } + auto irq9() { return m_irq9_callback.bind(); } +// auto txd1() { return m_txd1_callback.bind(); } +// auto ndtr1() { return m_ndtr1_callback.bind(); } +// auto nrts1() { return m_nrts1_callback.bind(); } +// auto txd2() { return m_txd2_callback.bind(); } +// auto ndtr2() { return m_ndtr2_callback.bind(); } +// auto nrts2() { return m_nrts2_callback.bind(); } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual space_config_vector memory_space_config() const override; + virtual void device_add_mconfig(machine_config &config) override; + +private: + const address_space_config m_space_config; + + required_device m_kbdc; + required_device m_rtc; +// memory_view m_logical_view; + + devcb_write_line m_gp20_reset_callback; + devcb_write_line m_gp25_gatea20_callback; + devcb_write_line m_irq1_callback; + devcb_write_line m_irq8_callback; + devcb_write_line m_irq9_callback; +// devcb_write_line m_txd1_callback; +// devcb_write_line m_ndtr1_callback; +// devcb_write_line m_nrts1_callback; +// devcb_write_line m_txd2_callback; +// devcb_write_line m_ndtr2_callback; +// devcb_write_line m_nrts2_callback; + + void config_map(address_map &map); + + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + + u8 keybc_status_r(offs_t offset); + void keybc_command_w(offs_t offset, u8 data); + + u8 m_index = 0; + + u8 m_locked_state; +}; + +DECLARE_DEVICE_TYPE(PC87306, pc87306_device); + +#endif // MAME_MACHINE_PC87306_H diff --git a/src/mame/misc/odyssey.cpp b/src/mame/misc/odyssey.cpp index dda94f115a6..b7cc66fc1c1 100644 --- a/src/mame/misc/odyssey.cpp +++ b/src/mame/misc/odyssey.cpp @@ -78,8 +78,8 @@ //#include "bus/rs232/null_modem.h" //#include "bus/rs232/rs232.h" //#include "bus/rs232/sun_kbd.h" -#include "bus/rs232/terminal.h" -#include "machine/fdc37c93x.h" +//#include "bus/rs232/terminal.h" +#include "machine/pc87306.h" namespace { @@ -100,7 +100,7 @@ private: void odyssey_map(address_map &map); void odyssey_io(address_map &map); - static void smc_superio_config(device_t *device); + static void national_superio_config(device_t *device); }; @@ -120,16 +120,16 @@ INPUT_PORTS_END static void isa_internal_devices(device_slot_interface &device) { - // TODO: should be a National Semiconductor PC87306B Super I/O (at I/O ports $2e-$2f) - device.option_add("fdc37c93x", FDC37C93X); + device.option_add("pc87306", PC87306); } -void odyssey_state::smc_superio_config(device_t *device) +void odyssey_state::national_superio_config(device_t *device) { - fdc37c93x_device &fdc = *downcast(device); - fdc.set_sysopt_pin(1); + pc87306_device &fdc = *downcast(device); + //fdc.set_sysopt_pin(1); fdc.gp20_reset().set_inputline(":maincpu", INPUT_LINE_RESET); fdc.gp25_gatea20().set_inputline(":maincpu", INPUT_LINE_A20); +#if 0 fdc.irq1().set(":pci:07.0", FUNC(i82371sb_isa_device::pc_irq1_w)); fdc.irq8().set(":pci:07.0", FUNC(i82371sb_isa_device::pc_irq8n_w)); fdc.txd1().set(":serport0", FUNC(rs232_port_device::write_txd)); @@ -138,8 +138,10 @@ void odyssey_state::smc_superio_config(device_t *device) fdc.txd2().set(":serport1", FUNC(rs232_port_device::write_txd)); fdc.ndtr2().set(":serport1", FUNC(rs232_port_device::write_dtr)); fdc.nrts2().set(":serport1", FUNC(rs232_port_device::write_rts)); +#endif } +#if 0 static void isa_com(device_slot_interface &device) { // device.option_add("microsoft_mouse", MSFT_HLE_SERIAL_MOUSE); @@ -147,10 +149,11 @@ static void isa_com(device_slot_interface &device) // device.option_add("wheel_mouse", WHEEL_HLE_SERIAL_MOUSE); // device.option_add("msystems_mouse", MSYSTEMS_HLE_SERIAL_MOUSE); // device.option_add("rotatable_mouse", ROTATABLE_HLE_SERIAL_MOUSE); - device.option_add("terminal", SERIAL_TERMINAL); +// device.option_add("terminal", SERIAL_TERMINAL); // device.option_add("null_modem", NULL_MODEM); // device.option_add("sun_kbd", SUN_KBD_ADAPTOR); } +#endif // This emulates a Tucson / Triton-II chipset, earlier i430fx TBD // PCI config space is trusted by Intel TC430HX "Technical Product Specification" @@ -184,13 +187,14 @@ void odyssey_state::odyssey(machine_config &config) // pci:0f.0 (J4D1) PCI expansion slot 3 // pci:10.0 (J4C1) PCI expansion slot 4 - ISA16_SLOT(config, "board4", 0, "pci:07.0:isabus", isa_internal_devices, "fdc37c93x", true).set_option_machine_config("fdc37c93x", smc_superio_config); + ISA16_SLOT(config, "board4", 0, "pci:07.0:isabus", isa_internal_devices, "pc87306", true).set_option_machine_config("pc87306", national_superio_config); ISA16_SLOT(config, "isa1", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false); ISA16_SLOT(config, "isa2", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false); ISA16_SLOT(config, "isa3", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false); ISA16_SLOT(config, "isa4", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false); ISA16_SLOT(config, "isa5", 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false); +#if 0 rs232_port_device& serport0(RS232_PORT(config, "serport0", isa_com, nullptr)); // "microsoft_mouse")); serport0.rxd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::rxd1_w)); serport0.dcd_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndcd1_w)); @@ -204,6 +208,7 @@ void odyssey_state::odyssey(machine_config &config) serport1.dsr_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ndsr2_w)); serport1.ri_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::nri2_w)); serport1.cts_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ncts2_w)); +#endif }