diff options
-rw-r--r-- | scripts/src/machine.lua | 12 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 1 | ||||
-rw-r--r-- | scripts/target/mame/mess.lua | 1 | ||||
-rw-r--r-- | src/devices/bus/isa/aha1542b.cpp | 38 | ||||
-rw-r--r-- | src/devices/bus/isa/aha1542b.h | 14 | ||||
-rw-r--r-- | src/devices/bus/isa/aha174x.cpp | 7 | ||||
-rw-r--r-- | src/devices/bus/isa/aha174x.h | 2 | ||||
-rw-r--r-- | src/devices/machine/aic565.cpp | 271 | ||||
-rw-r--r-- | src/devices/machine/aic565.h | 66 |
9 files changed, 405 insertions, 7 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 8460d15c16d..0d5de2868b2 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -3897,6 +3897,18 @@ end --------------------------------------------------- -- +--@src/devices/machine/aic565.h,MACHINES["AIC565"] = true +--------------------------------------------------- + +if (MACHINES["AIC565"]~=null) then + files { + MAME_DIR .. "src/devices/machine/aic565.cpp", + MAME_DIR .. "src/devices/machine/aic565.h", + } +end + +--------------------------------------------------- +-- --@src/devices/machine/aic6250.h,MACHINES["AIC6250"] = true --------------------------------------------------- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 306ae73c33a..df0e9e9d88a 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -660,6 +660,7 @@ MACHINES["PS2INTC"] = true --MACHINES["IOPINTC"] = true --MACHINES["IOPSIO2"] = true --MACHINES["IOPTIMER"] = true +MACHINES["AIC565"] = true MACHINES["AIC6250"] = true -------------------------------------------------- diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index d0bdbb6ed6a..ce764e3673f 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -691,6 +691,7 @@ MACHINES["IOPINTC"] = true MACHINES["IOPSIO2"] = true MACHINES["IOPTIMER"] = true MACHINES["Z8038"] = true +MACHINES["AIC565"] = true MACHINES["AIC6250"] = true MACHINES["DC7085"] = true MACHINES["I82357"] = true diff --git a/src/devices/bus/isa/aha1542b.cpp b/src/devices/bus/isa/aha1542b.cpp index 1f557fab484..3256c98d84b 100644 --- a/src/devices/bus/isa/aha1542b.cpp +++ b/src/devices/bus/isa/aha1542b.cpp @@ -37,6 +37,7 @@ aha1542a_device::aha1542a_device(const machine_config &mconfig, const char *tag, aha1542b_device::aha1542b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : aha154x_device(mconfig, AHA1542B, tag, owner, clock) + , m_busaic(*this, "busaic") { } @@ -44,13 +45,21 @@ void aha154x_device::device_start() { } -void aha154x_device::i8085_map(address_map &map) +void aha1542a_device::i8085_map(address_map &map) { map(0x0000, 0x3fff).rom().region("mcode", 0); map(0x8000, 0x800f).m("scsi:7:scsic", FUNC(aic6250_device::map)); map(0xe000, 0xe7ff).ram(); } +void aha1542b_device::i8085_map(address_map &map) +{ + map(0x0000, 0x3fff).rom().region("mcode", 0); + map(0x8000, 0x800f).m("scsi:7:scsic", FUNC(aic6250_device::map)); + map(0xa000, 0xa003).rw(m_busaic, FUNC(aic565_device::local_r), FUNC(aic565_device::local_w)); + map(0xe000, 0xe7ff).ram(); +} + static INPUT_PORTS_START(aha1542a) PORT_START("SETUP") PORT_DIPNAME(0x01, 0x01, "Synchronous Negotiation") PORT_DIPLOCATION("J1:1") @@ -338,11 +347,8 @@ void aha154x_device::scsic_config(device_t *device) downcast<aic6250_device &>(*device).port_b_r_cb().set_ioport("^^CONFIG"); } -void aha154x_device::device_add_mconfig(machine_config &config) +void aha154x_device::scsi_add(machine_config &config) { - i8085a_cpu_device &localcpu(I8085A(config, "localcpu", 10'000'000)); - localcpu.set_addrmap(AS_PROGRAM, &aha154x_device::i8085_map); - NSCSI_BUS(config, "scsi"); NSCSI_CONNECTOR(config, "scsi:0", aha154x_scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:1", aha154x_scsi_devices, nullptr); @@ -353,6 +359,28 @@ void aha154x_device::device_add_mconfig(machine_config &config) NSCSI_CONNECTOR(config, "scsi:6", aha154x_scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:7", aha154x_scsi_devices, "scsic", true) .set_option_machine_config("scsic", [this] (device_t *device) { scsic_config(device); }); +} + +void aha1542a_device::device_add_mconfig(machine_config &config) +{ + i8085a_cpu_device &localcpu(I8085A(config, "localcpu", 10'000'000)); + localcpu.set_addrmap(AS_PROGRAM, &aha1542a_device::i8085_map); + + scsi_add(config); + + DP8473(config, m_fdc, 24_MHz_XTAL); +} + +void aha1542b_device::device_add_mconfig(machine_config &config) +{ + i8085a_cpu_device &localcpu(I8085A(config, "localcpu", 10'000'000)); + localcpu.set_addrmap(AS_PROGRAM, &aha1542b_device::i8085_map); + + AIC565(config, m_busaic); + m_busaic->hrst_callback().set_inputline("localcpu", INPUT_LINE_RESET); + // Soft reset interrupt is not used + + scsi_add(config); DP8473(config, m_fdc, 24_MHz_XTAL); } diff --git a/src/devices/bus/isa/aha1542b.h b/src/devices/bus/isa/aha1542b.h index 88f18941909..acd58d70f93 100644 --- a/src/devices/bus/isa/aha1542b.h +++ b/src/devices/bus/isa/aha1542b.h @@ -12,6 +12,7 @@ #pragma once #include "isa.h" +#include "machine/aic565.h" #include "machine/upd765.h" class aha154x_device : public device_t, public device_isa16_card_interface @@ -20,9 +21,8 @@ protected: aha154x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); virtual void device_start() override; - virtual void device_add_mconfig(machine_config &config) override; - void i8085_map(address_map &map); + void scsi_add(machine_config &config); void scsic_config(device_t *device); required_device<upd765_family_device> m_fdc; @@ -39,6 +39,10 @@ public: protected: virtual ioport_constructor device_input_ports() const override; virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + +private: + void i8085_map(address_map &map); }; class aha1542b_device : public aha154x_device @@ -51,6 +55,12 @@ public: protected: virtual ioport_constructor device_input_ports() const override; virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + +private: + void i8085_map(address_map &map); + + required_device<aic565_device> m_busaic; }; DECLARE_DEVICE_TYPE(AHA1542A, aha1542a_device) diff --git a/src/devices/bus/isa/aha174x.cpp b/src/devices/bus/isa/aha174x.cpp index 0130522e4f8..21304f7fe9d 100644 --- a/src/devices/bus/isa/aha174x.cpp +++ b/src/devices/bus/isa/aha174x.cpp @@ -46,6 +46,7 @@ aha174x_device::aha174x_device(const machine_config &mconfig, device_type type, : device_t(mconfig, type, tag, owner, clock) , device_isa16_card_interface(mconfig, *this) , m_hpc(*this, "hpc") + , m_busaic(*this, "busaic") , m_bios(*this, "bios") { } @@ -68,6 +69,7 @@ void aha174x_device::device_start() void aha174x_device::hpc_map(address_map &map) { + map(0x2000, 0x2003).rw(m_busaic, FUNC(aic565_device::local_r), FUNC(aic565_device::local_w)); map(0x4000, 0x4002).rw("bmic", FUNC(i82355_device::local_r), FUNC(i82355_device::local_w)); map(0x5000, 0x500f).m("scsi:7:scsic", FUNC(aic6251a_device::map)); map(0x8000, 0xffff).rom().region("mcode", 0); @@ -108,7 +110,12 @@ void aha1742a_device::device_add_mconfig(machine_config &config) HPC46003(config, m_hpc, 40_MHz_XTAL / 2); m_hpc->set_addrmap(AS_PROGRAM, &aha1742a_device::hpc_map); + AIC565(config, m_busaic); + m_busaic->hrst_callback().set_inputline(m_hpc, INPUT_LINE_RESET); + //m_busaic->srst_callback().set_inputline(m_hpc, hpc_device::EI_LINE); + I82355(config, "bmic", 0); + //bmic.lint_callback().set_inputline(m_hpc, hpc_device::I2_LINE); NSCSI_BUS(config, "scsi"); NSCSI_CONNECTOR(config, "scsi:0", aha174x_scsi_devices, nullptr); diff --git a/src/devices/bus/isa/aha174x.h b/src/devices/bus/isa/aha174x.h index f65ee7de93a..1aefb148c97 100644 --- a/src/devices/bus/isa/aha174x.h +++ b/src/devices/bus/isa/aha174x.h @@ -13,6 +13,7 @@ #include "isa.h" #include "cpu/hpc/hpc.h" +#include "machine/aic565.h" #include "machine/upd765.h" class aha174x_device : public device_t, public device_isa16_card_interface @@ -26,6 +27,7 @@ protected: void scsic_config(device_t *device); required_device<hpc46003_device> m_hpc; + required_device<aic565_device> m_busaic; required_region_ptr<u8> m_bios; }; diff --git a/src/devices/machine/aic565.cpp b/src/devices/machine/aic565.cpp new file mode 100644 index 00000000000..34da7f4fd14 --- /dev/null +++ b/src/devices/machine/aic565.cpp @@ -0,0 +1,271 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Adaptec AIC-565 Bus Auxiliary Interface Chip + + This ASIC implements the standard mailbox interface for Adaptec's + ISA SCSI host adapters. It provides no specific SCSI functions, + however, and most of the status register bits are defined by + firmware implementation and have no special I/O features. + + The local processor interface is an enhanced version of that which + the AHA-1542A provides using generic logic chips. + +**********************************************************************/ + +#include "emu.h" +#include "aic565.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(AIC565, aic565_device, "aic565", "AIC-565 Bus Auxiliary Interface Chip") + + +//************************************************************************** +// DEVICE IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// aic565_device - constructor +//------------------------------------------------- + +aic565_device::aic565_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, AIC565, tag, owner, clock) + , m_hrst_callback(*this) + , m_srst_callback(*this) + , m_irq_callback(*this) + , m_data_to_host(0) + , m_data_from_host(0) + , m_local_status(0) + , m_aux_status(0) + , m_interrupt_flags(0) +{ +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void aic565_device::device_resolve_objects() +{ + // resolve callbacks + m_hrst_callback.resolve_safe(); + m_srst_callback.resolve_safe(); + m_irq_callback.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void aic565_device::device_start() +{ + // register state + save_item(NAME(m_data_to_host)); + save_item(NAME(m_data_from_host)); + save_item(NAME(m_local_status)); + save_item(NAME(m_aux_status)); + save_item(NAME(m_interrupt_flags)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void aic565_device::device_reset() +{ + m_local_status = 0; + m_aux_status = 0; + m_interrupt_flags = 0; + + m_hrst_callback(CLEAR_LINE); + m_srst_callback(CLEAR_LINE); + m_irq_callback(CLEAR_LINE); +} + + +//------------------------------------------------- +// host_r - read one byte from a host register +//------------------------------------------------- + +u8 aic565_device::host_r(offs_t offset) +{ + switch (offset & 0x03) + { + case 0: + // Bit 2 = data in port full + // Bit 3 = command/data out port full + return (m_local_status & 0xf1) | (m_aux_status & 0x80) >> 5 | (m_aux_status & 0x04) << 1; + + case 1: + // Data in port is no longer full + if (!machine().side_effects_disabled()) + m_aux_status &= 0x7f; + return m_data_to_host; + + case 2: + return m_interrupt_flags; + + default: + if (!machine().side_effects_disabled()) + logerror("Host read from undocumented register %d\n", offset); + return 0; + } +} + + +//------------------------------------------------- +// host_w - write one byte to a host register +//------------------------------------------------- + +void aic565_device::host_w(offs_t offset, u8 data) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(aic565_device::host_sync_w), this), (offset & 3) << 8 | data); +} + + +//------------------------------------------------- +// host_sync_w - synchronization callback for +// host register writes +//------------------------------------------------- + +TIMER_CALLBACK_MEMBER(aic565_device::host_sync_w) +{ + const offs_t offset = param >> 8; + const u8 data = param & 0xff; + + switch (offset) + { + case 0: + if (BIT(data, 7)) + { + // Hard reset (self-clearing) + m_hrst_callback(ASSERT_LINE); + m_hrst_callback(CLEAR_LINE); + } + if (BIT(data, 6)) + { + // Soft reset (may cause interrupt on local processor) + m_aux_status |= 0x10; + m_srst_callback(ASSERT_LINE); + } + if (BIT(data, 5)) + { + // Host interrupt reset + m_aux_status &= 0xfe; + m_interrupt_flags = 0; + m_irq_callback(CLEAR_LINE); + } + if (BIT(data, 4)) + { + // SCSI bus reset + m_aux_status |= 0x08; + } + break; + + case 1: + // Fill the command/data out port + m_data_from_host = data; + m_aux_status |= 0x04; + break; + + default: + logerror("Host write to undocumented register %d = %02X\n", offset, data); + break; + } +} + + +//------------------------------------------------- +// local_r - read one byte from a local register +//------------------------------------------------- + +u8 aic565_device::local_r(offs_t offset) +{ + // Local read register 3 is the auxiliary status register + // Local read register 2 seems to be an undocumented mirror of this + if (BIT(offset, 1)) + return m_aux_status; + else if (BIT(offset, 0)) + { + // Command/data out port is no longer full + if (!machine().side_effects_disabled()) + m_aux_status &= 0xfb; + return m_data_from_host; + } + else + return m_interrupt_flags; // also not documented (bits 3 and 0 tested) +} + + +//------------------------------------------------- +// local_w - write one byte to a local register +//------------------------------------------------- + +void aic565_device::local_w(offs_t offset, u8 data) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(aic565_device::local_sync_w), this), (offset & 3) << 8 | data); +} + + +//------------------------------------------------- +// local_sync_w - synchronization callback for +// local writes +//------------------------------------------------- + +TIMER_CALLBACK_MEMBER(aic565_device::local_sync_w) +{ + const offs_t offset = param >> 8; + const u8 data = param & 0xff; + + switch (offset) + { + case 0: + // Set the local status + m_local_status = data; + break; + + case 1: + // Fill the data in port + m_data_to_host = data; + m_aux_status |= 0x80; + break; + + case 2: + // Bit 7 = host interrupt active + if (BIT(m_interrupt_flags, 7) != BIT(data, 7)) + { + if (BIT(data, 7)) + { + m_aux_status |= 0x01; + m_irq_callback(ASSERT_LINE); + } + else + { + m_aux_status &= 0xfe; + m_irq_callback(CLEAR_LINE); + } + } + + // Other bits of this register are firmware-defined + m_interrupt_flags = data; + break; + + case 3: + // Clear reset (data is irrelevant) + if (BIT(m_aux_status, 4)) + m_srst_callback(CLEAR_LINE); + m_aux_status &= 0xe7; + break; + } +} diff --git a/src/devices/machine/aic565.h b/src/devices/machine/aic565.h new file mode 100644 index 00000000000..2f2fdf72b91 --- /dev/null +++ b/src/devices/machine/aic565.h @@ -0,0 +1,66 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Adaptec AIC-565 Bus Auxiliary Interface Chip + +**********************************************************************/ + +#ifndef MAME_MACHINE_AIC565_H +#define MAME_MACHINE_AIC565_H 1 + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> aic565_device + +class aic565_device : public device_t +{ +public: + // construction/destruction + aic565_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // callback configuration + auto hrst_callback() { return m_hrst_callback.bind(); } + auto srst_callback() { return m_srst_callback.bind(); } + auto irq_callback() { return m_irq_callback.bind(); } + + // host register access + u8 host_r(offs_t offset); + void host_w(offs_t offset, u8 data); + + // local CPU access + u8 local_r(offs_t offset); + void local_w(offs_t offset, u8 data); + +protected: + // device-level overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + // synchronization helpers + TIMER_CALLBACK_MEMBER(host_sync_w); + TIMER_CALLBACK_MEMBER(local_sync_w); + + // callback objects + devcb_write_line m_hrst_callback; + devcb_write_line m_srst_callback; + devcb_write_line m_irq_callback; + + // internal state + uint8_t m_data_to_host; + uint8_t m_data_from_host; + uint8_t m_local_status; + uint8_t m_aux_status; + uint8_t m_interrupt_flags; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(AIC565, aic565_device) + +#endif // MAME_MACHINE_AIC565_H |