summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-05-06 00:23:55 -0400
committer AJR <ajrhacker@users.noreply.github.com>2019-05-06 00:24:11 -0400
commitd3132cc13b8a7a29ce6e4e5b3d543294c256dfb7 (patch)
tree670f3afc5731eaeba040ac040da8f1d24fbbea32
parent90b6fd09825abb408535b3b7badba07bf4efc5e1 (diff)
Add AIC-565 device
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/bus/isa/aha1542b.cpp38
-rw-r--r--src/devices/bus/isa/aha1542b.h14
-rw-r--r--src/devices/bus/isa/aha174x.cpp7
-rw-r--r--src/devices/bus/isa/aha174x.h2
-rw-r--r--src/devices/machine/aic565.cpp271
-rw-r--r--src/devices/machine/aic565.h66
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