diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 5550ff2e396..eee10688f64 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1585,6 +1585,8 @@ if (BUSES["ISA"]~=null) then MAME_DIR .. "src/devices/bus/isa/asc88.h", MAME_DIR .. "src/devices/bus/isa/bblue2.cpp", MAME_DIR .. "src/devices/bus/isa/bblue2.h", + MAME_DIR .. "src/devices/bus/isa/3xtwin.cpp", + MAME_DIR .. "src/devices/bus/isa/3xtwin.h", } end diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 012119a8a7e..8d4069947f0 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -983,6 +983,18 @@ if (MACHINES["CHESSMACHINE"]~=null) then end +--------------------------------------------------- +-- +--@src/devices/machine/com52c50.h,MACHINES["COM52C50"] = true +--------------------------------------------------- + +if (MACHINES["COM52C50"]~=null) then + files { + MAME_DIR .. "src/devices/machine/com52c50.cpp", + MAME_DIR .. "src/devices/machine/com52c50.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/com8116.h,MACHINES["COM8116"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 75ef61332ee..6b40790f785 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -463,6 +463,7 @@ MACHINES["CDP1871"] = true MACHINES["CHESSMACHINE"] = true MACHINES["CMOS40105"] = true MACHINES["CDU76S"] = true +MACHINES["COM52C50"] = true MACHINES["COM8116"] = true MACHINES["CR589"] = true --MACHINES["CS4031"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index e96b17cf4b7..b584cbaebe2 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -483,6 +483,7 @@ MACHINES["CDP1879"] = true --MACHINES["CDU76S"] = true MACHINES["CHESSMACHINE"] = true MACHINES["CMOS40105"] = true +MACHINES["COM52C50"] = true MACHINES["COM8116"] = true MACHINES["COP452"] = true MACHINES["CR589"] = true diff --git a/src/devices/bus/isa/3xtwin.cpp b/src/devices/bus/isa/3xtwin.cpp new file mode 100644 index 00000000000..b30c83ab1ce --- /dev/null +++ b/src/devices/bus/isa/3xtwin.cpp @@ -0,0 +1,95 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Emerald Technology Inc. 3XTwin IBM 5251/11 twinax emulation board + + This smallish card is rather tightly packed with DIP ICs (mostly simple + LSTTL and a few line drivers/receivers) to the point where their + location numbers are difficult to read. There is no host BIOS, and the + 65C02's "TWINMON" firmware does very little, clearly relying on + external software. + + Communication between the host system and local CPU seems to take place + via shared access to a KM62256LP-10 SRAM. + +***************************************************************************/ + +#include "emu.h" +#include "3xtwin.h" + +#include "cpu/m6502/r65c02.h" +#include "machine/com52c50.h" + + +// device type definition +DEFINE_DEVICE_TYPE(ISA8_3XTWIN, isa8_3xtwin_device, "3xtwin", "Emerald Technology 3XTwin Twinax Emulation Card") + +isa8_3xtwin_device::isa8_3xtwin_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, ISA8_3XTWIN, tag, owner, clock) + , device_isa8_card_interface(mconfig, *this) +{ +} + +void isa8_3xtwin_device::device_start() +{ +} + +void isa8_3xtwin_device::mpu_map(address_map &map) +{ + map(0x0000, 0x1fff).ram(); + map(0x2000, 0x2007).m("tic", FUNC(com52c50_device::map)); + map(0x4000, 0xbfff).ram(); + map(0xe000, 0xffff).rom().region("firmware", 0); +} + + +static INPUT_PORTS_START(3xtwin) + PORT_START("IOBASE") + PORT_DIPNAME(0x1f, 0x19, "Base I/O Address") PORT_DIPLOCATION("S1:5,4,3,2,1") + PORT_DIPSETTING(0x10, "200") + PORT_DIPSETTING(0x11, "220") + PORT_DIPSETTING(0x12, "240") + PORT_DIPSETTING(0x13, "260") + PORT_DIPSETTING(0x14, "280") + PORT_DIPSETTING(0x15, "2A0") + PORT_DIPSETTING(0x16, "2C0") + PORT_DIPSETTING(0x17, "2E0") + PORT_DIPSETTING(0x18, "300") + PORT_DIPSETTING(0x19, "320") + PORT_DIPSETTING(0x1a, "340") + PORT_DIPSETTING(0x1b, "360") + PORT_DIPSETTING(0x1c, "380") + PORT_DIPSETTING(0x1d, "3A0") + PORT_DIPSETTING(0x1e, "3C0") + PORT_DIPSETTING(0x1f, "3E0") + + // TODO: IRQ jumpers +INPUT_PORTS_END + +ioport_constructor isa8_3xtwin_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(3xtwin); +} + +void isa8_3xtwin_device::device_add_mconfig(machine_config &config) +{ + r65c02_device &mpu(R65C02(config, "mpu", 16_MHz_XTAL / 4)); // R65C02P4 + mpu.set_addrmap(AS_PROGRAM, &isa8_3xtwin_device::mpu_map); + + com52c50_device &tic(COM52C50(config, "tic", 16_MHz_XTAL)); + tic.int1_callback().set_inputline("mpu", r65c02_device::IRQ_LINE); + tic.int2_callback().set_inputline("mpu", r65c02_device::NMI_LINE); +} + +ROM_START(3xtwin) + ROM_REGION(0x2000, "firmware", 0) // "MON VER E.01" + ROM_LOAD("370906502.u2", 0x0000, 0x2000, CRC(d4157bc4) SHA1(359428ce0047f9192a44790c8670af956cf6ed70)) + + // PLDs (undumped) marked "TWINCLK" (U9: ULC24/22V10-15) and "TWINLGC" (U12: PAL20L10ACNS) +ROM_END + +const tiny_rom_entry *isa8_3xtwin_device::device_rom_region() const +{ + return ROM_NAME(3xtwin); +} diff --git a/src/devices/bus/isa/3xtwin.h b/src/devices/bus/isa/3xtwin.h new file mode 100644 index 00000000000..cb9aeb286eb --- /dev/null +++ b/src/devices/bus/isa/3xtwin.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Emerald Technology Inc. 3XTwin IBM 5251/11 emulation board + +***************************************************************************/ + +#ifndef MAME_BUS_ISA_3XTWIN_H +#define MAME_BUS_ISA_3XTWIN_H + +#pragma once + +#include "isa.h" + + +// ======================> isa8_3xtwin_device + +class isa8_3xtwin_device : public device_t, public device_isa8_card_interface +{ +public: + // device type constructor + isa8_3xtwin_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + // local memory map + void mpu_map(address_map &map); +}; + +// device type declaration +DECLARE_DEVICE_TYPE(ISA8_3XTWIN, isa8_3xtwin_device) + +#endif // MAME_BUS_ISA_3XTWIN_H diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp index 8f1232dcd13..ce23388ea1d 100644 --- a/src/devices/bus/isa/isa_cards.cpp +++ b/src/devices/bus/isa/isa_cards.cpp @@ -72,6 +72,7 @@ #include "eis_sad8852.h" #include "eis_twib.h" #include "np600.h" +#include "3xtwin.h" // communication ports #include "lpt.h" @@ -138,6 +139,7 @@ void pc_isa8_cards(device_slot_interface &device) device.option_add("epc_twib", ISA8_EIS_TWIB); device.option_add("babyblue2", ISA8_BABYBLUE2); device.option_add("acb2072", ACB2072); + device.option_add("3xtwin", ISA8_3XTWIN); } void pc_isa16_cards(device_slot_interface &device) @@ -183,6 +185,7 @@ void pc_isa16_cards(device_slot_interface &device) device.option_add("epc_twib", ISA8_EIS_TWIB); device.option_add("babyblue2", ISA8_BABYBLUE2); device.option_add("acb2072", ACB2072); + device.option_add("3xtwin", ISA8_3XTWIN); // 16-bit device.option_add("ide", ISA16_IDE); device.option_add("ne2000", NE2000); diff --git a/src/devices/machine/com52c50.cpp b/src/devices/machine/com52c50.cpp new file mode 100644 index 00000000000..89b4e176f85 --- /dev/null +++ b/src/devices/machine/com52c50.cpp @@ -0,0 +1,165 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Standard Microsystems Corp. COM52C50 Twinax Interface Circuit (TIC) + + Skeleton device. + +***************************************************************************/ + +#include "emu.h" +#include "com52c50.h" + + +// device type definition +DEFINE_DEVICE_TYPE(COM52C50, com52c50_device, "com52c50", "SMC COM52C50 TIC") + +com52c50_device::com52c50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, COM52C50, tag, owner, clock) + , m_int1_callback(*this) + , m_int2_callback(*this) + , m_rx_dma_callback(*this) + , m_tx_dma_callback(*this) + , m_int_mask(0) + , m_int_status(0) + , m_zero_fill(0) + , m_present_address(0) + , m_rx_status(0) + , m_tx_status(0) + , m_control(0) + , m_mode(0) +{ +} + +void com52c50_device::map(address_map &map) +{ + map(0, 0).w(FUNC(com52c50_device::mode_w)); + map(1, 1).rw(FUNC(com52c50_device::int_status_r), FUNC(com52c50_device::int_mask_w)); + map(2, 2).rw(FUNC(com52c50_device::rx_status_r), FUNC(com52c50_device::address_select_w)); + map(3, 3).rw(FUNC(com52c50_device::rx_buffer_r), FUNC(com52c50_device::control_w)); + map(4, 4).w(FUNC(com52c50_device::zero_fill_w)); + map(5, 5).rw(FUNC(com52c50_device::present_address_r), FUNC(com52c50_device::present_address_w)); + map(6, 6).mirror(1).r(FUNC(com52c50_device::tx_status_r)); + map(6, 6).w(FUNC(com52c50_device::tx_buffer_w)); + map(7, 7).w(FUNC(com52c50_device::tx_buffer_eom_w)); +} + +void com52c50_device::device_resolve_objects() +{ + m_int1_callback.resolve_safe(); + m_int2_callback.resolve_safe(); + m_rx_dma_callback.resolve_safe(); + m_tx_dma_callback.resolve_safe(); +} + +void com52c50_device::device_start() +{ + save_item(NAME(m_int_mask)); + save_item(NAME(m_int_status)); + save_item(NAME(m_zero_fill)); + save_item(NAME(m_present_address)); + save_item(NAME(m_rx_status)); + save_item(NAME(m_tx_status)); + save_item(NAME(m_control)); + save_item(NAME(m_mode)); +} + +void com52c50_device::device_reset() +{ + m_int_mask = 0; + m_int_status = 0; + m_zero_fill = 0; + m_rx_status = 0; + m_tx_status = 0; + m_control = 0x01; + m_mode = 0; + + m_int1_callback(CLEAR_LINE); + m_int2_callback(CLEAR_LINE); +} + +u8 com52c50_device::rx_buffer_r() +{ + if (!machine().side_effects_disabled()) + logerror("%s: Reading data from RX buffer\n", machine().describe_context()); + return 0; +} + +void com52c50_device::tx_buffer_w(u8 data) +{ + logerror("%s: Writing %02X to TX buffer\n", machine().describe_context(), data); +} + +void com52c50_device::tx_buffer_eom_w(u8 data) +{ + logerror("%s: Writing %02X to TX buffer EOM\n", machine().describe_context(), data); +} + +void com52c50_device::zero_fill_w(u8 data) +{ + logerror("%s: Writing %02X to zero fill register\n", machine().describe_context(), data); + m_zero_fill = data; +} + +void com52c50_device::int_mask_w(u8 data) +{ + logerror("%s: Writing %02X to interrupt mask register\n", machine().describe_context(), data); + m_int_mask = data; +} + +void com52c50_device::address_select_w(u8 data) +{ + logerror("%s: Writing %02X to address select register\n", machine().describe_context(), data); +} + +u8 com52c50_device::present_address_r() +{ + return m_present_address; +} + +void com52c50_device::present_address_w(u8 data) +{ + logerror("%s: Writing %02X to present address register\n", machine().describe_context(), data); + m_present_address = data & 0x07; +} + +u8 com52c50_device::int_status_r() +{ + return m_int_status; +} + +u8 com52c50_device::rx_status_r() +{ + return m_rx_status | (m_present_address << 1); +} + +u8 com52c50_device::tx_status_r() +{ + return m_tx_status; +} + +void com52c50_device::control_w(u8 data) +{ + if (!BIT(data, 0)) + { + logerror("%s: Software reset\n", machine().describe_context()); + + m_int_mask = 0; + m_int_status = 0; + m_zero_fill = 0; + m_rx_status = 0; + m_tx_status = 0; + m_mode = 0; + } + + logerror("%s: Writing %02X to control register\n", machine().describe_context(), data); + m_control = data; +} + +void com52c50_device::mode_w(u8 data) +{ + logerror("%s: Writing %02X to mode register\n", machine().describe_context(), data); + m_mode = data; +} + diff --git a/src/devices/machine/com52c50.h b/src/devices/machine/com52c50.h new file mode 100644 index 00000000000..085a3e0808a --- /dev/null +++ b/src/devices/machine/com52c50.h @@ -0,0 +1,89 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Standard Microsystems Corp. COM52C50 Twinax Interface Circuit (TIC) + +**************************************************************************** + _____ _____ + D2 1 |* \__/ | 28 Vcc + D3 2 | | 27 D1 + /WR 3 | | 26 D0 + /TXEN 4 | | 25 /CS + /DTX 5 | | 24 /RD + TX 6 | | 23 A0 + TX DMA 7 | | 22 A1 + RX 8 | COM52C50 | 21 A2 + D4 9 | | 20 /INT1 + D5 10 | | 19 /INT2 + /RESET 11 | | 18 RX DMA + XTAL2 12 | | 17 CLKOUT + XTAL1 13 | | 16 D7 + GND 14 |______________| 15 D6 + +***************************************************************************/ + +#ifndef MAME_MACHINE_COM52C50_H +#define MAME_MACHINE_COM52C50_H + +#pragma once + + +// ======================> com52c50_device + +class com52c50_device : public device_t +{ +public: + // device type constructor + com52c50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // callback configuration + auto int1_callback() { return m_int1_callback.bind(); } + auto int2_callback() { return m_int2_callback.bind(); } + auto rx_dma_callback() { return m_rx_dma_callback.bind(); } + auto tx_dma_callback() { return m_tx_dma_callback.bind(); } + + // bus interface + u8 rx_buffer_r(); + void tx_buffer_w(u8 data); + void tx_buffer_eom_w(u8 data); + void zero_fill_w(u8 data); + void int_mask_w(u8 data); + void address_select_w(u8 data); + u8 present_address_r(); + void present_address_w(u8 data); + u8 int_status_r(); + u8 rx_status_r(); + u8 tx_status_r(); + void control_w(u8 data); + void mode_w(u8 data); + void map(address_map &map); + +protected: + // device-level overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + // device callbacks + devcb_write_line m_int1_callback; + devcb_write_line m_int2_callback; + devcb_write_line m_rx_dma_callback; + devcb_write_line m_tx_dma_callback; + + // internal state + u8 m_int_mask; + u8 m_int_status; + u8 m_zero_fill; + u8 m_present_address; + u8 m_rx_status; + u8 m_tx_status; + u8 m_control; + u8 m_mode; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(COM52C50, com52c50_device) + +#endif // MAME_MACHINE_COM52C50_H