mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
bus/qbus: Add dump and skeleton device for TDL-12 SCSI Host Adapter [Bitsavers]
* z8536: Respect data direction registers when reading back from Ports A & B
This commit is contained in:
parent
762b250b7e
commit
0759cce9e7
@ -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",
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
137
src/devices/bus/qbus/tdl12.cpp
Normal file
137
src/devices/bus/qbus/tdl12.cpp
Normal file
@ -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);
|
||||
}
|
42
src/devices/bus/qbus/tdl12.h
Normal file
42
src/devices/bus/qbus/tdl12.h
Normal file
@ -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
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user