summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--src/devices/bus/qbus/qbus.cpp2
-rw-r--r--src/devices/bus/qbus/tdl12.cpp137
-rw-r--r--src/devices/bus/qbus/tdl12.h42
-rw-r--r--src/devices/machine/z8536.cpp33
5 files changed, 207 insertions, 9 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 7f18c0431b3..c28d003849a 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -4790,6 +4790,8 @@ if (BUSES["QBUS"]~=null) then
MAME_DIR .. "src/devices/bus/qbus/qg640.h",
MAME_DIR .. "src/devices/bus/qbus/qtx.cpp",
MAME_DIR .. "src/devices/bus/qbus/qtx.h",
+ MAME_DIR .. "src/devices/bus/qbus/tdl12.cpp",
+ MAME_DIR .. "src/devices/bus/qbus/tdl12.h",
MAME_DIR .. "src/devices/bus/qbus/uknc_kmd.cpp",
MAME_DIR .. "src/devices/bus/qbus/uknc_kmd.h",
}
diff --git a/src/devices/bus/qbus/qbus.cpp b/src/devices/bus/qbus/qbus.cpp
index a5293df0c46..d3b639c801f 100644
--- a/src/devices/bus/qbus/qbus.cpp
+++ b/src/devices/bus/qbus/qbus.cpp
@@ -18,6 +18,7 @@
#include "pc11.h"
#include "qg640.h"
#include "qtx.h"
+#include "tdl12.h"
#include "uknc_kmd.h"
@@ -31,6 +32,7 @@ void qbus_cards(device_slot_interface &device)
device.option_add("mz", UKNC_KMD);
device.option_add("qg640", MATROX_QG640);
device.option_add("by", BK_KMD);
+ device.option_add("tdl12", TDL12);
}
diff --git a/src/devices/bus/qbus/tdl12.cpp b/src/devices/bus/qbus/tdl12.cpp
new file mode 100644
index 00000000000..b9ea3a6df71
--- /dev/null
+++ b/src/devices/bus/qbus/tdl12.cpp
@@ -0,0 +1,137 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/***********************************************************************************************************************************
+
+ TDL-12 SCSI Host Adapter (© 1985 T.D. Systems)
+
+************************************************************************************************************************************/
+
+#include "emu.h"
+#include "tdl12.h"
+
+#include "bus/nscsi/devices.h"
+#include "cpu/z80/z80.h"
+#include "machine/eepromser.h"
+#include "machine/ncr5380.h"
+#include "machine/z8536.h"
+
+
+// device type definition
+DEFINE_DEVICE_TYPE(TDL12, tdl12_device, "tdl12", "TDL-12 SCSI Host Adapter")
+
+
+tdl12_device::tdl12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, TDL12, tag, owner, clock)
+ , device_qbus_card_interface(mconfig, *this)
+ , m_tdcpu(*this, "tdcpu")
+{
+}
+
+void tdl12_device::device_start()
+{
+}
+
+u8 tdl12_device::latch_r(offs_t offset)
+{
+ if (!machine().side_effects_disabled())
+ logerror("%s: Reading from latch %c\n", machine().describe_context(), offset ? 'H' : 'L');
+ return 0;
+}
+
+void tdl12_device::latch_w(offs_t offset, u8 data)
+{
+ logerror("%s: Writing %02X to latch %c\n", machine().describe_context(), data, offset ? 'H' : 'L');
+}
+
+u8 tdl12_device::in40_r()
+{
+ // Used as low 8 bits of jump offset
+ // Valid values include 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xd0, 0xff
+ return 0xff;
+}
+
+void tdl12_device::out40_w(u8 data)
+{
+ logerror("%s: Output %02X to port 40\n", machine().describe_context(), data);
+}
+
+void tdl12_device::out70_w(u8 data)
+{
+ // Data written is irrelevant
+ logerror("%s: Output to port 70\n", machine().describe_context());
+}
+
+void tdl12_device::out74_w(u8 data)
+{
+ // Data written is irrelevant
+ logerror("%s: Output to port 74\n", machine().describe_context());
+}
+
+void tdl12_device::mem_map(address_map &map)
+{
+ map(0x0000, 0x3fff).rom().region("firmware", 0);
+ map(0x4000, 0x47ff).ram();
+ map(0x8000, 0x8001).rw(FUNC(tdl12_device::latch_r), FUNC(tdl12_device::latch_w));
+}
+
+void tdl12_device::io_map(address_map &map)
+{
+ map.global_mask(0xff);
+ map(0x00, 0x03).rw("cio", FUNC(z8536_device::read), FUNC(z8536_device::write));
+ map(0x40, 0x40).rw(FUNC(tdl12_device::in40_r), FUNC(tdl12_device::out40_w));
+ map(0x70, 0x70).w(FUNC(tdl12_device::out70_w));
+ map(0x74, 0x74).w(FUNC(tdl12_device::out74_w));
+ map(0x80, 0x87).m("scsi:7:ncr5380", FUNC(ncr5380_device::map));
+}
+
+void tdl12_device::device_add_mconfig(machine_config &config)
+{
+ Z80(config, m_tdcpu, 12_MHz_XTAL / 2); // covered by "TD SYSTEMS INC." sticker (most likely Z80B)
+ m_tdcpu->set_addrmap(AS_PROGRAM, &tdl12_device::mem_map);
+ m_tdcpu->set_addrmap(AS_IO, &tdl12_device::io_map);
+
+ z8536_device &cio(Z8536(config, "cio", 12_MHz_XTAL / 2)); // ST Z8536AB1
+ cio.irq_wr_cb().set_inputline(m_tdcpu, 0);
+ cio.pb_wr_cb().set("eeprom", FUNC(eeprom_serial_93cxx_device::clk_write)).bit(0);
+ cio.pb_wr_cb().append("eeprom", FUNC(eeprom_serial_93cxx_device::di_write)).bit(1);
+ cio.pc_rd_cb().set("eeprom", FUNC(eeprom_serial_93cxx_device::do_read)).lshift(3);
+ cio.pc_wr_cb().set("eeprom", FUNC(eeprom_serial_93cxx_device::cs_write)).bit(2);
+
+ NSCSI_BUS(config, "scsi");
+ NSCSI_CONNECTOR(config, "scsi:0", default_scsi_devices, nullptr);
+ NSCSI_CONNECTOR(config, "scsi:1", default_scsi_devices, nullptr);
+ NSCSI_CONNECTOR(config, "scsi:2", default_scsi_devices, nullptr);
+ NSCSI_CONNECTOR(config, "scsi:3", default_scsi_devices, nullptr);
+ NSCSI_CONNECTOR(config, "scsi:4", default_scsi_devices, nullptr);
+ NSCSI_CONNECTOR(config, "scsi:5", default_scsi_devices, nullptr);
+ NSCSI_CONNECTOR(config, "scsi:6", default_scsi_devices, nullptr);
+ NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5380", NCR5380).machine_config([this](device_t *device) {
+ (void)this;
+ });
+
+ EEPROM_93C46_16BIT(config, "eeprom"); // NMC9346N
+}
+
+
+ROM_START(tdl12)
+ ROM_REGION(0x4000, "firmware", 0)
+ ROM_LOAD("tdl-12_v180.bin", 0x0000, 0x4000, CRC(fd0f4468) SHA1(1cf0bf8702747ff3047691d2b661bb08d40754f0)) // Am(27128?)-25DC
+
+ ROM_REGION(0x40, "proms", 0) // probably either Q-bus address decode or a short bootstrap program
+ ROM_LOAD("m_tdl-11.bin", 0x00, 0x20, NO_DUMP) // N82S123AN
+ ROM_LOAD("m_tdl-12.bin", 0x20, 0x20, NO_DUMP) // N82S123AN
+
+ ROM_REGION(0x7a1, "plds", 0)
+ ROM_LOAD("mst_tdl-13.bin", 0x000, 0x117, NO_DUMP) // TIBPAL16L8-25CN (socketed, next to A/B jumpers)
+ ROM_LOAD("mst_tdl-21.bin", 0x117, 0x117, NO_DUMP) // TIBPAL16L8-25CN
+ ROM_LOAD("mst_tdl-26.bin", 0x22e, 0x117, NO_DUMP) // TIBPAL16L8-25CN
+ ROM_LOAD("mst_tdl-31.bin", 0x345, 0x117, NO_DUMP) // TIBPAL16L8-25CN
+ ROM_LOAD("mst_tdl-40.bin", 0x45c, 0x117, NO_DUMP) // TIBPAL16L8-25CN
+ ROM_LOAD("mst_tdl-41.bin", 0x573, 0x117, NO_DUMP) // TIBPAL16L8-25CN
+ ROM_LOAD("mst_tdl-42.bin", 0x68a, 0x117, NO_DUMP) // TIBPAL16L8-25CN
+ROM_END
+
+const tiny_rom_entry *tdl12_device::device_rom_region() const
+{
+ return ROM_NAME(tdl12);
+}
diff --git a/src/devices/bus/qbus/tdl12.h b/src/devices/bus/qbus/tdl12.h
new file mode 100644
index 00000000000..46716f98ff7
--- /dev/null
+++ b/src/devices/bus/qbus/tdl12.h
@@ -0,0 +1,42 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+
+#ifndef MAME_BUS_QBUS_TDL12_H
+#define MAME_BUS_QBUS_TDL12_H
+
+#pragma once
+
+#include "qbus.h"
+#include "machine/ncr5380.h"
+
+
+class tdl12_device : public device_t, public device_qbus_card_interface
+{
+public:
+ // device type constructor
+ tdl12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+
+private:
+ u8 latch_r(offs_t offset);
+ void latch_w(offs_t offset, u8 data);
+ u8 in40_r();
+ void out40_w(u8 data);
+ void out70_w(u8 data);
+ void out74_w(u8 data);
+
+ void mem_map(address_map &map) ATTR_COLD;
+ void io_map(address_map &map) ATTR_COLD;
+
+ required_device<cpu_device> m_tdcpu;
+};
+
+// device type declaration
+DECLARE_DEVICE_TYPE(TDL12, tdl12_device)
+
+#endif // MAME_BUS_QBUS_TDL12_H
diff --git a/src/devices/machine/z8536.cpp b/src/devices/machine/z8536.cpp
index cb1fa74adb6..af1dd90c28a 100644
--- a/src/devices/machine/z8536.cpp
+++ b/src/devices/machine/z8536.cpp
@@ -201,15 +201,22 @@ u8 cio_base_device::read_register(offs_t offset)
switch (offset)
{
case PORT_A_DATA:
- data = m_read_pa(0);
+ // TODO: take data path polarity into account
+ data = m_output[PORT_A];
+ if (m_register[PORT_A_DATA_DIRECTION] != 0)
+ data = (data & ~m_register[PORT_A_DATA_DIRECTION]) | (m_read_pa() & m_register[PORT_A_DATA_DIRECTION]);
break;
case PORT_B_DATA:
- data = m_read_pb(0);
+ // TODO: take data path polarity into account
+ data = m_output[PORT_B];
+ if (m_register[PORT_B_DATA_DIRECTION] != 0)
+ data = (data & ~m_register[PORT_B_DATA_DIRECTION]) | (m_read_pb() & m_register[PORT_B_DATA_DIRECTION]);
break;
case PORT_C_DATA:
- data = 0xf0 | (m_read_pc(0) & 0x0f);
+ // TODO: take data path polarity into account
+ data = 0xf0 | (m_read_pc() & 0x0f);
break;
case COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE:
@@ -340,17 +347,17 @@ void cio_base_device::write_register(offs_t offset, u8 data)
case PORT_C_DATA_PATH_POLARITY:
LOG("%s CIO Port C Data Path Polarity: %02x\n", machine().describe_context(), data);
- m_register[offset] = data;
+ m_register[offset] = data & 0x0f;
break;
case PORT_C_DATA_DIRECTION:
LOG("%s CIO Port C Data Direction: %02x\n", machine().describe_context(), data);
- m_register[offset] = data;
+ m_register[offset] = data & 0x0f;
break;
case PORT_C_SPECIAL_IO_CONTROL:
LOG("%s CIO Port C Special I/O Control: %02x\n", machine().describe_context(), data);
- m_register[offset] = data;
+ m_register[offset] = data & 0x0f;
break;
case PORT_A_COMMAND_AND_STATUS:
@@ -422,11 +429,15 @@ void cio_base_device::write_register(offs_t offset, u8 data)
break;
case PORT_A_DATA:
- m_write_pa((offs_t)0, data);
+ // TODO: take data path polarity into account
+ m_output[PORT_A] = data;
+ m_write_pa(data);
break;
case PORT_B_DATA:
- m_write_pb((offs_t)0, data);
+ // TODO: take data path polarity into account
+ m_output[PORT_B] = data;
+ m_write_pb(data);
break;
case PORT_C_DATA:
@@ -435,7 +446,8 @@ void cio_base_device::write_register(offs_t offset, u8 data)
m_output[PORT_C] = (m_output[PORT_C] & mask) | ((data & 0x0f) & (mask ^ 0xff));
- m_write_pc((offs_t)0, m_output[PORT_C]);
+ // TODO: take data path polarity into account
+ m_write_pc(m_output[PORT_C]);
}
break;
@@ -862,6 +874,9 @@ void cio_base_device::device_reset()
m_register[PORT_A_COMMAND_AND_STATUS] = PCS_ORE;
m_register[PORT_B_COMMAND_AND_STATUS] = PCS_ORE;
m_register[CURRENT_VECTOR] = 0xff;
+ m_register[PORT_A_DATA_DIRECTION] = 0xff;
+ m_register[PORT_B_DATA_DIRECTION] = 0xff;
+ m_register[PORT_C_DATA_DIRECTION] = 0x0f;
check_interrupt();
}