From d4eb7c7d2cc2673c6fdaef3cd51616ee78775a17 Mon Sep 17 00:00:00 2001 From: AJR Date: Fri, 25 Oct 2019 16:51:03 -0400 Subject: [PATCH] aha1542a, aha1542b: Split out AIC-580 emulation to new device (nw) --- scripts/src/machine.lua | 12 + scripts/target/mame/arcade.lua | 1 + scripts/target/mame/mess.lua | 1 + src/devices/bus/isa/aha1542b.cpp | 88 +------ src/devices/bus/isa/aha1542b.h | 13 -- src/devices/machine/aic580.cpp | 378 +++++++++++++++++++++++++++++++ src/devices/machine/aic580.h | 87 +++++++ 7 files changed, 490 insertions(+), 90 deletions(-) create mode 100644 src/devices/machine/aic580.cpp create mode 100644 src/devices/machine/aic580.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index fc300170ce3..3c574fe3762 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -4078,6 +4078,18 @@ if (MACHINES["AIC565"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/aic580.h,MACHINES["AIC580"] = true +--------------------------------------------------- + +if (MACHINES["AIC580"]~=null) then + files { + MAME_DIR .. "src/devices/machine/aic580.cpp", + MAME_DIR .. "src/devices/machine/aic580.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 80f1245f5bb..210ac27c79b 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -685,6 +685,7 @@ MACHINES["PS2INTC"] = true --MACHINES["IOPSIO2"] = true --MACHINES["IOPTIMER"] = true MACHINES["AIC565"] = true +MACHINES["AIC580"] = true MACHINES["AIC6250"] = true MACHINES["VRENDER0"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 0c3620cc8b3..f09ec3d999d 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -720,6 +720,7 @@ MACHINES["IOPSIO2"] = true MACHINES["IOPTIMER"] = true MACHINES["Z8038"] = true MACHINES["AIC565"] = true +MACHINES["AIC580"] = 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 f1b26839fd1..bba0bb76d41 100644 --- a/src/devices/bus/isa/aha1542b.cpp +++ b/src/devices/bus/isa/aha1542b.cpp @@ -14,6 +14,7 @@ #include "bus/nscsi/devices.h" #include "cpu/i8085/i8085.h" +#include "machine/aic580.h" #include "machine/gen_latch.h" #include "machine/nscsi_bus.h" @@ -29,10 +30,6 @@ aha154x_device::aha154x_device(const machine_config &mconfig, device_type type, , m_scsic(*this, "scsi:7:scsic") , m_fdc(*this, "fdc") , m_bios(*this, "bios") - , m_fifo_data(*this, "fifo_data") - , m_fifo_read_index(0) - , m_fifo_write_index(0) - , m_dma_mode(0) { } @@ -49,85 +46,17 @@ aha1542b_device::aha1542b_device(const machine_config &mconfig, const char *tag, void aha154x_device::device_start() { - save_item(NAME(m_fifo_read_index)); - save_item(NAME(m_fifo_write_index)); - save_item(NAME(m_dma_mode)); } void aha154x_device::device_reset() { - m_fifo_read_index = 0; - m_fifo_write_index = 0; - m_dma_mode = 0; -} - -void aha154x_device::transfer_speed_w(u8 data) -{ - const unsigned div = BIT(data, 3) ? (data & 3) + 5 : 4; - logerror("Transfer speed = %.2f MB/s\n", 20.0 * 2 / div); -} - -void aha154x_device::dma_mode_w(u8 data) -{ - m_dma_mode = data; -} - -void aha154x_device::bus_on_time_w(u8 data) -{ - logerror("Bus on time = %d microseconds\n", data & 0x0f); -} - -void aha154x_device::bus_off_time_w(u8 data) -{ - logerror("Bus off time = %d microseconds\n", std::max(1, (data & 0x0f) * 4)); -} - -u8 aha154x_device::fifo_data_r() -{ - const u8 data = m_fifo_data[m_fifo_read_index]; - if (!machine().side_effects_disabled()) - m_fifo_read_index = (m_fifo_read_index + 1) % 10; - return data; -} - -void aha154x_device::fifo_data_w(u8 data) -{ - m_fifo_data[m_fifo_write_index] = data; - if (!machine().side_effects_disabled()) - m_fifo_write_index = (m_fifo_write_index + 1) % 10; -} - -WRITE_LINE_MEMBER(aha154x_device::aic_breq_w) -{ - if (state) - { - if (m_dma_mode == 0x80) - { - m_fifo_data[m_fifo_write_index] = m_scsic->dma_r(); - m_fifo_write_index = (m_fifo_write_index + 1) % 10; - m_scsic->back_w(0); - } - else if (m_dma_mode == 0x90) - { - m_scsic->dma_w(m_fifo_data[m_fifo_read_index]); - m_fifo_read_index = (m_fifo_read_index + 1) % 10; - m_scsic->back_w(0); - } - else - logerror("AIC-6250 BREQ (DMA mode %02X)\n", m_dma_mode); - } } void aha154x_device::i8085_base_map(address_map &map) { map(0x0000, 0x3fff).rom().region("mcode", 0); map(0x8000, 0x800f).m(m_scsic, FUNC(aic6250_device::map)); - map(0xc080, 0xc080).w(FUNC(aha154x_device::transfer_speed_w)); - map(0xc082, 0xc082).w(FUNC(aha154x_device::dma_mode_w)); - map(0xc08c, 0xc08c).w(FUNC(aha154x_device::bus_on_time_w)); - map(0xc08d, 0xc08d).w(FUNC(aha154x_device::bus_off_time_w)); - map(0xc0ac, 0xc0ac).rw(FUNC(aha154x_device::fifo_data_r), FUNC(aha154x_device::fifo_data_w)); - map(0xc0c0, 0xc0c9).ram().share("fifo_data"); + map(0xc000, 0xc0ff).m("dmaaic", FUNC(aic580_device::mpu_map)); map(0xe000, 0xe7ff).ram(); } @@ -452,9 +381,9 @@ ioport_constructor aha1542b_device::device_input_ports() const void aha154x_device::scsic_config(device_t *device) { - device->set_clock(20'000'000); + device->set_clock(20_MHz_XTAL); downcast(*device).int_cb().set_inputline("^^localcpu", I8085_RST65_LINE); - downcast(*device).breq_cb().set("^^", FUNC(aha154x_device::aic_breq_w)); + downcast(*device).breq_cb().set("^^dmaaic", FUNC(aic580_device::breq_w)); downcast(*device).port_a_r_cb().set_ioport("^^SETUP"); downcast(*device).port_b_r_cb().set_ioport("^^CONFIG"); } @@ -471,11 +400,16 @@ void aha154x_device::scsi_add(machine_config &config) NSCSI_CONNECTOR(config, "scsi:6", default_scsi_devices, nullptr); NSCSI_CONNECTOR(config, "scsi:7").option_set("scsic", AIC6250) .machine_config([this] (device_t *device) { scsic_config(device); }); + + aic580_device &dmaaic(AIC580(config, "dmaaic", 20_MHz_XTAL)); + dmaaic.bdin_callback().set(m_scsic, FUNC(aic6250_device::dma_r)); + dmaaic.bdout_callback().set(m_scsic, FUNC(aic6250_device::dma_w)); + dmaaic.back_callback().set(m_scsic, FUNC(aic6250_device::back_w)); } void aha1542a_device::device_add_mconfig(machine_config &config) { - i8085a_cpu_device &localcpu(I8085A(config, m_localcpu, 10'000'000)); + i8085a_cpu_device &localcpu(I8085A(config, m_localcpu, 20_MHz_XTAL / 2)); localcpu.set_addrmap(AS_PROGRAM, &aha1542a_device::i8085_map); generic_latch_8_device &fromhost(GENERIC_LATCH_8(config, "fromhost")); @@ -490,7 +424,7 @@ void aha1542a_device::device_add_mconfig(machine_config &config) void aha1542b_device::device_add_mconfig(machine_config &config) { - i8085a_cpu_device &localcpu(I8085A(config, m_localcpu, 10'000'000)); + i8085a_cpu_device &localcpu(I8085A(config, m_localcpu, 20_MHz_XTAL / 2)); localcpu.set_addrmap(AS_PROGRAM, &aha1542b_device::i8085_map); AIC565(config, m_busaic); diff --git a/src/devices/bus/isa/aha1542b.h b/src/devices/bus/isa/aha1542b.h index f2d7fe85501..c46f456bfe9 100644 --- a/src/devices/bus/isa/aha1542b.h +++ b/src/devices/bus/isa/aha1542b.h @@ -24,14 +24,6 @@ protected: virtual void device_start() override; virtual void device_reset() override; - void transfer_speed_w(u8 data); - void dma_mode_w(u8 data); - void bus_on_time_w(u8 data); - void bus_off_time_w(u8 data); - u8 fifo_data_r(); - void fifo_data_w(u8 data); - DECLARE_WRITE_LINE_MEMBER(aic_breq_w); - void i8085_base_map(address_map &map); void scsi_add(machine_config &config); void scsic_config(device_t *device); @@ -40,11 +32,6 @@ protected: required_device m_scsic; required_device m_fdc; required_region_ptr m_bios; - required_shared_ptr m_fifo_data; - - u8 m_fifo_read_index; - u8 m_fifo_write_index; - u8 m_dma_mode; }; class aha1542a_device : public aha154x_device diff --git a/src/devices/machine/aic580.cpp b/src/devices/machine/aic580.cpp new file mode 100644 index 00000000000..d9f7b1cc321 --- /dev/null +++ b/src/devices/machine/aic580.cpp @@ -0,0 +1,378 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Adaptec AIC-580 + + This 84-pin PLCC ASIC provides 16-bit DMA bus mastering capabilities + for the AIC-1540A/1542A and AIC-1540B/1542B PC/AT SCSI host adapters + and the AIC-1640 Micro Channel SCSI host adapter. + + No documentation for this IC has been found. It might function somewhat + similarly to the AIC-560, which is also poorly documented. + +***************************************************************************/ + +#include "emu.h" +#include "aic580.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(AIC580, aic580_device, "aic580", "AIC-580 DMA Bus Master") + + +//************************************************************************** +// DEVICE IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// aic580_device - constructor +//------------------------------------------------- + +aic580_device::aic580_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, AIC580, tag, owner, clock) + , m_bdin_callback(*this) + , m_bdout_callback(*this) + , m_back_callback(*this) + , m_sread_callback(*this) + , m_swrite_callback(*this) + , m_dma_mode(0) + , m_channel_addr{0} + , m_fifo_read_index(0) + , m_fifo_write_index(0) + , m_fifo_data{0} +{ +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void aic580_device::device_resolve_objects() +{ + // resolve callbacks + m_bdin_callback.resolve_safe(0); + m_bdout_callback.resolve_safe(); + m_back_callback.resolve_safe(); + m_sread_callback.resolve_safe(0); + m_swrite_callback.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void aic580_device::device_start() +{ + // register state + save_item(NAME(m_dma_mode)); + save_item(NAME(m_channel_addr)); + save_item(NAME(m_fifo_read_index)); + save_item(NAME(m_fifo_write_index)); + save_item(NAME(m_fifo_data)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void aic580_device::device_reset() +{ + m_fifo_read_index = 0; + m_fifo_write_index = 0; + m_dma_mode = 0; +} + + +//------------------------------------------------- +// breq_w - handle transfer requests for port B +//------------------------------------------------- + +WRITE_LINE_MEMBER(aic580_device::breq_w) +{ + if (state) + { + if (m_dma_mode == 0x80) + { + m_fifo_data[m_fifo_write_index] = m_bdin_callback(); + m_fifo_write_index = (m_fifo_write_index + 1) & 15; + m_back_callback(0); + } + else if (m_dma_mode == 0x90) + { + m_bdout_callback(m_fifo_data[m_fifo_read_index]); + m_fifo_read_index = (m_fifo_read_index + 1) & 15; + m_back_callback(0); + } + else + logerror("BREQ with unemulated DMA mode %02X\n", m_dma_mode); + } +} + + +//************************************************************************** +// REGISTER HANDLERS +//************************************************************************** + +//------------------------------------------------- +// r80_r - local read from register 80h +//------------------------------------------------- + +u8 aic580_device::r80_r() +{ + if (!machine().side_effects_disabled()) + logerror("%s: Read from register 80h\n", machine().describe_context()); + return 0; +} + + +//------------------------------------------------- +// transfer_speed_w - local write to register 80h +//------------------------------------------------- + +void aic580_device::transfer_speed_w(u8 data) +{ + const unsigned div = BIT(data, 3) ? (data & 3) + 5 : 4; + logerror("Transfer speed = %.2f MB/s\n", clock() * 2.0E-6 / div); +} + + +//------------------------------------------------- +// dma_mode_w - local write to register 82h +//------------------------------------------------- + +void aic580_device::dma_mode_w(u8 data) +{ + m_dma_mode = data; +} + + +//------------------------------------------------- +// r83_w - local write to register 83h +//------------------------------------------------- + +void aic580_device::r83_w(u8 data) +{ + logerror("%s: Write %02Xh to register 83h\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// r86_w - local write to register 86h +//------------------------------------------------- + +void aic580_device::r86_w(u8 data) +{ + logerror("%s: Write %02Xh to register 86h\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// r88_r - local read from register 88h +//------------------------------------------------- + +u8 aic580_device::r88_r() +{ + if (!machine().side_effects_disabled()) + logerror("%s: Read from register 88h\n", machine().describe_context()); + return 0; +} + + +//------------------------------------------------- +// r88_w - local write to register 88h +//------------------------------------------------- + +void aic580_device::r88_w(u8 data) +{ + logerror("%s: Write %02Xh to register 88h\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// r8a_w - local write to register 8Ah +//------------------------------------------------- + +void aic580_device::r8a_w(u8 data) +{ + logerror("%s: Write %02Xh to register 8Ah\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// r8b_w - local write to register 8Bh +//------------------------------------------------- + +void aic580_device::r8b_w(u8 data) +{ + logerror("%s: Write %02Xh to register 8Bh\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// bus_on_time_w - local write to register 8Ch +//------------------------------------------------- + +void aic580_device::bus_on_time_w(u8 data) +{ + logerror("Bus on time = %d microseconds\n", data & 0x0f); +} + + +//------------------------------------------------- +// bus_off_time_w - local write to register 8Dh +//------------------------------------------------- + +void aic580_device::bus_off_time_w(u8 data) +{ + logerror("Bus off time = %d microseconds\n", std::max(1, (data & 0x0f) * 4)); +} + + +//------------------------------------------------- +// ch_addrl_w - set bits 7:0 of buffer address +// for channel 1 or 2 +//------------------------------------------------- + +template +void aic580_device::ch_addrl_w(u8 data) +{ + m_channel_addr[Channel] = (m_channel_addr[Channel] & 0xffff00) | data; +} + + +//------------------------------------------------- +// ch_addrm_w - set bits 15:8 of buffer address +// for channel 1 or 2 +//------------------------------------------------- + +template +void aic580_device::ch_addrm_w(u8 data) +{ + m_channel_addr[Channel] = (m_channel_addr[Channel] & 0xff00ff) | u32(data) << 8; +} + + +//------------------------------------------------- +// ch_addrh_w - set bits 23:16 of buffer address +// for channel 1 or 2 +//------------------------------------------------- + +template +void aic580_device::ch_addrh_w(u8 data) +{ + m_channel_addr[Channel] = (m_channel_addr[Channel] & 0x00ffff) | u32(data) << 16; +} + + +//------------------------------------------------- +// ra2_w - local write to register A2h +//------------------------------------------------- + +void aic580_device::ra2_w(u8 data) +{ + logerror("%s: Write %02Xh to register A2h\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// ra3_w - local write to register A3h +//------------------------------------------------- + +void aic580_device::ra3_w(u8 data) +{ + logerror("%s: Write %02Xh to register A3h\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// ra4_w - local write to register A4h +//------------------------------------------------- + +void aic580_device::ra4_w(u8 data) +{ + logerror("%s: Write %02Xh to register A4h\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// fifo_data_r - local read from register ACh +//------------------------------------------------- + +u8 aic580_device::fifo_data_r() +{ + const u8 data = m_fifo_data[m_fifo_read_index]; + if (!machine().side_effects_disabled()) + m_fifo_read_index = (m_fifo_read_index + 1) & 15; + return data; +} + + +//------------------------------------------------- +// fifo_data_w - local write to register ACh +//------------------------------------------------- + +void aic580_device::fifo_data_w(u8 data) +{ + m_fifo_data[m_fifo_write_index] = data; + if (!machine().side_effects_disabled()) + m_fifo_write_index = (m_fifo_write_index + 1) & 15; +} + + +//------------------------------------------------- +// buffer_r - local read from registers C0h–CFh +//------------------------------------------------- + +u8 aic580_device::buffer_r(offs_t offset) +{ + return m_fifo_data[offset]; +} + + +//------------------------------------------------- +// buffer_w - local write to registers C0h–CFh +//------------------------------------------------- + +void aic580_device::buffer_w(offs_t offset, u8 data) +{ + m_fifo_data[offset] = data; +} + + +//------------------------------------------------- +// mpu_map - address map for local microprocessor +//------------------------------------------------- + +void aic580_device::mpu_map(address_map &map) +{ + map(0x80, 0x80).rw(FUNC(aic580_device::r80_r), FUNC(aic580_device::transfer_speed_w)); + map(0x82, 0x82).w(FUNC(aic580_device::dma_mode_w)); + map(0x83, 0x83).w(FUNC(aic580_device::r83_w)); + map(0x86, 0x86).w(FUNC(aic580_device::r86_w)); + map(0x88, 0x88).rw(FUNC(aic580_device::r88_r), FUNC(aic580_device::r88_w)); + map(0x8a, 0x8a).w(FUNC(aic580_device::r8a_w)); + map(0x8b, 0x8b).w(FUNC(aic580_device::r8b_w)); + map(0x8c, 0x8c).w(FUNC(aic580_device::bus_on_time_w)); + map(0x8d, 0x8d).w(FUNC(aic580_device::bus_off_time_w)); + map(0x98, 0x98).w(FUNC(aic580_device::ch_addrl_w<0>)); + map(0x99, 0x99).w(FUNC(aic580_device::ch_addrm_w<0>)); + map(0x9a, 0x9a).w(FUNC(aic580_device::ch_addrh_w<0>)); + map(0x9c, 0x9c).w(FUNC(aic580_device::ch_addrl_w<1>)); + map(0x9d, 0x9d).w(FUNC(aic580_device::ch_addrm_w<1>)); + map(0x9e, 0x9e).w(FUNC(aic580_device::ch_addrh_w<1>)); + map(0xa2, 0xa2).w(FUNC(aic580_device::ra2_w)); + map(0xa3, 0xa3).w(FUNC(aic580_device::ra3_w)); + map(0xa4, 0xa4).w(FUNC(aic580_device::ra4_w)); + map(0xac, 0xac).rw(FUNC(aic580_device::fifo_data_r), FUNC(aic580_device::fifo_data_w)); + map(0xc0, 0xcf).rw(FUNC(aic580_device::buffer_r), FUNC(aic580_device::buffer_w)); +} diff --git a/src/devices/machine/aic580.h b/src/devices/machine/aic580.h new file mode 100644 index 00000000000..b764daa1710 --- /dev/null +++ b/src/devices/machine/aic580.h @@ -0,0 +1,87 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Adaptec AIC-580 + +**********************************************************************/ + +#ifndef MAME_MACHINE_AIC580_H +#define MAME_MACHINE_AIC580_H + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> aic580_device + +class aic580_device : public device_t +{ +public: + // construction/destruction + aic580_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // callback configuration + auto bdin_callback() { return m_bdin_callback.bind(); } + auto bdout_callback() { return m_bdout_callback.bind(); } + auto back_callback() { return m_back_callback.bind(); } + auto sread_callback() { return m_sread_callback.bind(); } + auto swrite_callback() { return m_swrite_callback.bind(); } + + // microprocessor interface + void mpu_map(address_map &map); + + // port B DMA interface + DECLARE_WRITE_LINE_MEMBER(breq_w); + +protected: + // device-specific overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + // register handlers + u8 r80_r(); + void transfer_speed_w(u8 data); + void dma_mode_w(u8 data); + void r83_w(u8 data); + void r86_w(u8 data); + u8 r88_r(); + void r88_w(u8 data); + void r8a_w(u8 data); + void r8b_w(u8 data); + void bus_on_time_w(u8 data); + void bus_off_time_w(u8 data); + template void ch_addrl_w(u8 data); + template void ch_addrm_w(u8 data); + template void ch_addrh_w(u8 data); + void ra2_w(u8 data); + void ra3_w(u8 data); + void ra4_w(u8 data); + u8 fifo_data_r(); + void fifo_data_w(u8 data); + u8 buffer_r(offs_t offset); + void buffer_w(offs_t offset, u8 data); + + // callback objects + devcb_read8 m_bdin_callback; + devcb_write8 m_bdout_callback; + devcb_write_line m_back_callback; + devcb_read16 m_sread_callback; + devcb_write16 m_swrite_callback; + + // internal state + u8 m_dma_mode; + u32 m_channel_addr[2]; + u8 m_fifo_read_index; + u8 m_fifo_write_index; + u8 m_fifo_data[16]; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(AIC580, aic580_device) + +#endif // MAME_MACHINE_AIC580_H