mac.cpp, mac128.cpp, macprtb.cpp, macpwrbk030.cpp, macquadra.cpp: Add helper device to permit use of "new" SCSI bus and 53(C)80 emulation with macse and later

This commit is contained in:
AJR 2021-05-08 13:01:38 -04:00
parent 173a0cf3b6
commit 7ed1de96c9
12 changed files with 609 additions and 164 deletions

View File

@ -1816,6 +1816,8 @@ files {
MAME_DIR .. "src/mame/machine/macpci.cpp",
MAME_DIR .. "src/mame/machine/cuda.cpp",
MAME_DIR .. "src/mame/machine/cuda.h",
MAME_DIR .. "src/mame/machine/macscsi.cpp",
MAME_DIR .. "src/mame/machine/macscsi.h",
MAME_DIR .. "src/mame/drivers/iphone2g.cpp",
MAME_DIR .. "src/mame/drivers/superga2.cpp",
}

View File

@ -29,4 +29,10 @@ void default_scsi_devices(device_slot_interface &device)
device.option_add("cdu561_25", CDU561_25);
device.option_add("smoc501", SMOC501);
device.option_add("aplcd150", APPLECD150);
};
}
void mac_scsi_devices(device_slot_interface &device)
{
device.option_add("harddisk", NSCSI_HARDDISK);
device.option_add("cdrom", NSCSI_CDROM_APPLE);
}

View File

@ -7,5 +7,6 @@
#pragma once
extern void default_scsi_devices(device_slot_interface &device);
extern void mac_scsi_devices(device_slot_interface &device);
#endif // MAME_BUS_NSCSI_DEVICES_H

View File

@ -20,9 +20,7 @@
#include "machine/iwm.h"
#include "machine/swim1.h"
#include "machine/swim2.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsihd.h"
#include "bus/scsi/scsicd.h"
#include "bus/nscsi/devices.h"
// NuBus and 030/040 PDS cards
#include "bus/nubus/nubus_48gc.h"
@ -50,9 +48,9 @@
#include "speaker.h"
#include "mac.lh"
#define C7M (7833600)
#define C15M (C7M*2)
#define C32M (C15M*2)
#define C32M (31.3344_MHz_XTAL)
#define C15M (C32M/2)
#define C7M (C32M/4)
// do this here - screen_update is called each scanline when stepping in the
// debugger, which means you can't escape the VIA2 IRQ handler
@ -637,15 +635,27 @@ void mac_state::add_base_devices(machine_config &config, bool rtc, int woz_versi
void mac_state::add_scsi(machine_config &config, bool cdrom)
{
scsi_port_device &scsibus(SCSI_PORT(config, "scsi"));
scsibus.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_6));
scsibus.set_slot_device(2, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_5));
if (cdrom)
scsibus.set_slot_device(3, "cdrom", SCSICD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4));
NSCSI_BUS(config, "scsi");
NSCSI_CONNECTOR(config, "scsi:0", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:1", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:2", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:3", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, cdrom ? "cdrom" : nullptr);
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:6", mac_scsi_devices, "harddisk");
NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5380", NCR53C80).machine_config([this](device_t *device) {
ncr53c80_device &adapter = downcast<ncr53c80_device &>(*device);
adapter.irq_handler().set(*this, FUNC(mac_state::mac_scsi_irq));
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
});
NCR5380(config, m_ncr5380, C7M);
m_ncr5380->set_scsi_port("scsi");
m_ncr5380->irq_callback().set(FUNC(mac_state::mac_scsi_irq));
MAC_SCSI_HELPER(config, m_scsihelp);
m_scsihelp->scsi_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::read));
m_scsihelp->scsi_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::write));
m_scsihelp->scsi_dma_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_r));
m_scsihelp->scsi_dma_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_w));
m_scsihelp->cpu_halt_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_scsihelp->timeout_error_callback().set(FUNC(mac_state::scsi_berr_w));
SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd");
}

View File

@ -88,9 +88,6 @@ Scanline 0 is the start of vblank.
#include "bus/mackbd/mackbd.h"
#include "bus/macpds/hyperdrive.h"
#include "bus/scsi/scsicd.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsihd.h"
#include "cpu/m68000/m68000.h"
#include "machine/6522via.h"
#include "machine/iwm.h"
@ -98,14 +95,13 @@ Scanline 0 is the start of vblank.
#include "machine/ncr5380n.h"
#include "machine/nscsi_bus.h"
#include "machine/rescap.h"
#include "bus/nscsi/hd.h"
#include "bus/nscsi/cd.h"
#include "machine/ncr5380.h"
#include "bus/nscsi/devices.h"
#include "machine/ram.h"
#include "machine/applefdintf.h"
#include "machine/timer.h"
#include "machine/z80scc.h"
#include "machine/macadb.h"
#include "machine/macscsi.h"
#include "sound/dac.h"
#include "sound/flt_biquad.h"
#include "bus/macpds/pds_tpdfpd.h"
@ -139,8 +135,8 @@ public:
m_via(*this, "via6522_0"),
m_macadb(*this, "macadb"),
m_ram(*this, RAM_TAG),
m_ncr5380(*this, "ncr5380"),
m_scsibus(*this, "scsibus"),
m_scsihelp(*this, "scsihelp"),
m_ncr5380n(*this, "scsibus:7:ncr5380n"),
m_iwm(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
@ -175,8 +171,8 @@ private:
required_device<via6522_device> m_via;
optional_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
optional_device<ncr5380_device> m_ncr5380;
optional_device<nscsi_bus_device> m_scsibus;
optional_device<mac_scsi_helper_device> m_scsihelp;
optional_device<ncr5380n_device> m_ncr5380n;
required_device<applefdintf_device> m_iwm;
required_device_array<floppy_connector, 2> m_floppy;
@ -218,6 +214,7 @@ private:
void macse_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
DECLARE_WRITE_LINE_MEMBER(scsi_irq_w);
DECLARE_WRITE_LINE_MEMBER(scsi_drq_w);
void scsi_berr_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(set_scc_interrupt);
DECLARE_WRITE_LINE_MEMBER(vblank_w);
@ -619,6 +616,11 @@ WRITE_LINE_MEMBER(mac128_state::scsi_drq_w)
m_scsi_drq = state;
}
void mac128_state::scsi_berr_w(uint8_t data)
{
m_maincpu->pulse_input_line(M68K_LINE_BUSERROR, attotime::zero);
}
uint16_t mac128_state::macplus_scsi_r(offs_t offset, uint16_t mem_mask)
{
int reg = (offset >> 3) & 0xf;
@ -664,12 +666,7 @@ uint16_t mac128_state::macse_scsi_r(offs_t offset, uint16_t mem_mask)
// logerror("macplus_scsi_r: offset %x mask %x\n", offset, mem_mask);
if ((reg == 6) && (offset == 0x130))
{
reg = R5380_CURDATA_DTACK;
}
return m_ncr5380->ncr5380_read_reg(reg)<<8;
return m_scsihelp->read_wrapper(BIT(offset, 8), reg)<<8;
}
void mac128_state::macse_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
@ -678,12 +675,7 @@ void mac128_state::macse_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
// logerror("macplus_scsi_w: data %x offset %x mask %x\n", data, offset, mem_mask);
if ((reg == 0) && (offset == 0x100))
{
reg = R5380_OUTDATA_DTACK;
}
m_ncr5380->ncr5380_write_reg(reg, data);
m_scsihelp->write_wrapper(BIT(offset, 8), reg, data>>8);
}
void mac128_state::scc_mouse_irq(int x, int y)
@ -1125,12 +1117,6 @@ void mac128_state::macse_map(address_map &map)
MACHINE DRIVERS
***************************************************************************/
static void mac_scsi_devices(device_slot_interface &device)
{
device.option_add("harddisk", NSCSI_HARDDISK);
device.option_add("cdrom", NSCSI_CDROM);
}
static void mac_pds_cards(device_slot_interface &device)
{
device.option_add("hyperdrive", PDS_HYPERDRIVE); // GCC HyperDrive ST-506 interface
@ -1256,7 +1242,6 @@ void mac128_state::macse(machine_config &config)
config.device_remove("kbd");
config.device_remove("pds");
config.device_remove("scsibus");
IWM(config.replace(), m_iwm, C7M*2);
m_iwm->phases_cb().set(FUNC(mac128_state::phases_w));
@ -1265,13 +1250,19 @@ void mac128_state::macse(machine_config &config)
applefdintf_device::add_35(config, m_floppy[0]);
applefdintf_device::add_35(config, m_floppy[1]);
scsi_port_device &scsibus(SCSI_PORT(config, "scsi"));
scsibus.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_6));
scsibus.set_slot_device(2, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_5));
MAC_SCSI_HELPER(config, m_scsihelp);
m_scsihelp->scsi_read_callback().set(m_ncr5380n, FUNC(ncr5380n_device::read));
m_scsihelp->scsi_write_callback().set(m_ncr5380n, FUNC(ncr5380n_device::write));
m_scsihelp->scsi_dma_read_callback().set(m_ncr5380n, FUNC(ncr5380n_device::dma_r));
m_scsihelp->scsi_dma_write_callback().set(m_ncr5380n, FUNC(ncr5380n_device::dma_w));
m_scsihelp->cpu_halt_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_scsihelp->timeout_error_callback().set(FUNC(mac128_state::scsi_berr_w));
NCR5380(config, m_ncr5380, C7M);
m_ncr5380->set_scsi_port("scsi");
m_ncr5380->irq_callback().set(FUNC(mac128_state::scsi_irq_w));
subdevice<nscsi_connector>("scsibus:7")->set_option_machine_config("ncr5380n", [this](device_t *device) {
ncr5380n_device &adapter = downcast<ncr5380n_device &>(*device);
adapter.irq_handler().set(*this, FUNC(mac128_state::scsi_irq_w));
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
});
MACADB(config, m_macadb, C7M);
m_macadb->via_clock_callback().set(m_via, FUNC(via6522_device::write_cb1));
@ -1312,6 +1303,12 @@ void mac128_state::macclasc(machine_config &config)
config.device_remove("pds");
config.device_remove("sepds");
NSCSI_CONNECTOR(config.replace(), "scsibus:7").option_set("ncr5380n", NCR53C80).machine_config([this](device_t *device) {
ncr5380n_device &adapter = downcast<ncr5380n_device &>(*device);
adapter.irq_handler().set(*this, FUNC(mac128_state::scsi_irq_w));
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
});
}
static INPUT_PORTS_START( macplus )

View File

@ -98,9 +98,10 @@
#include "machine/timer.h"
#include "machine/z80scc.h"
#include "machine/macadb.h"
#include "machine/ncr5380.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsihd.h"
#include "machine/macscsi.h"
#include "machine/ncr5380n.h"
#include "machine/nscsi_bus.h"
#include "bus/nscsi/devices.h"
#include "sound/asc.h"
#include "formats/ap_dsk35.h"
@ -109,9 +110,9 @@
#include "softlist.h"
#include "speaker.h"
#define C7M (7833600)
#define C15M (C7M*2)
#define C32M (C15M*2)
#define C32M (31.3344_MHz_XTAL)
#define C15M (C32M/2)
#define C7M (C32M/4)
class macportable_state : public driver_device
{
@ -122,7 +123,8 @@ public:
m_pmu(*this, "pmu"),
m_via1(*this, "via1"),
m_macadb(*this, "macadb"),
m_ncr5380(*this, "ncr5380"),
m_ncr5380(*this, "scsi:7:ncr5380"),
m_scsihelp(*this, "scsihelp"),
m_ram(*this, RAM_TAG),
m_swim(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
@ -145,7 +147,8 @@ private:
required_device<m50753_device> m_pmu;
required_device<via6522_device> m_via1;
required_device<macadb_device> m_macadb;
required_device<ncr5380_device> m_ncr5380;
required_device<ncr53c80_device> m_ncr5380;
required_device<mac_scsi_helper_device> m_scsihelp;
required_device<ram_device> m_ram;
required_device<applefdintf_device> m_swim;
required_device_array<floppy_connector, 2> m_floppy;
@ -177,7 +180,7 @@ private:
DECLARE_WRITE_LINE_MEMBER(via_irq_w);
TIMER_CALLBACK_MEMBER(mac_6015_tick);
int m_via_cycles, m_via_interrupt, m_scc_interrupt, m_asc_interrupt, m_last_taken_interrupt;
int m_irq_count, m_ca1_data, m_ca2_data;
int m_ca1_data;
void phases_w(uint8_t phases);
void devsel_w(uint8_t devsel);
@ -187,6 +190,7 @@ private:
uint16_t scsi_r(offs_t offset, uint16_t mem_mask);
void scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask);
void scsi_berr_w(uint8_t data);
uint16_t mac_scc_r(offs_t offset)
{
@ -220,9 +224,9 @@ private:
field_interrupts();
}
u8 m_pmu_via_bus, m_pmu_ack, m_pmu_req;
u8 pmu_data_r() { return m_pmu_via_bus; }
void pmu_data_w(u8 data) { m_pmu_via_bus = data; }
u8 m_pmu_to_via, m_pmu_from_via, m_pmu_ack, m_pmu_req;
u8 pmu_data_r() { return m_pmu_from_via; }
void pmu_data_w(u8 data) { m_pmu_to_via = data; }
u8 pmu_comms_r() { return (m_pmu_req<<7); }
void pmu_comms_w(u8 data)
{
@ -231,6 +235,7 @@ private:
m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
}
m_via1->write_ca2(BIT(data, 4));
m_via1->write_cb1(BIT(data, 5));
m_pmu_ack = BIT(data, 6);
@ -280,8 +285,9 @@ void macportable_state::machine_start()
m_via_cycles = -50;
m_via_interrupt = m_scc_interrupt = m_asc_interrupt = 0;
m_last_taken_interrupt = -1;
m_irq_count = m_ca1_data = m_ca2_data = 0;
m_pmu_via_bus = 0;
m_ca1_data = 0;
m_pmu_to_via = 0;
m_pmu_from_via = 0;
m_pmu_ack = m_pmu_req = 0;
m_adb_line = 1;
@ -294,9 +300,8 @@ void macportable_state::machine_reset()
m_overlay = true;
m_via_interrupt = m_scc_interrupt = 0;
m_last_taken_interrupt = -1;
m_irq_count = m_ca1_data = m_ca2_data = 0;
m_ca1_data = 0;
m_pmu_via_bus = 0;
m_pmu_ack = 1;
// start 60.15 Hz timer
@ -391,15 +396,6 @@ TIMER_CALLBACK_MEMBER(macportable_state::mac_6015_tick)
m_pmu->set_input_line(m50753_device::M50753_INT1_LINE, ASSERT_LINE);
m_macadb->adb_vblank();
if (++m_irq_count == 60)
{
m_irq_count = 0;
m_ca2_data ^= 1;
/* signal 1 Hz irq on CA2 input on the VIA */
m_via1->write_ca2(m_ca2_data);
}
}
uint16_t macportable_state::scsi_r(offs_t offset, uint16_t mem_mask)
@ -408,12 +404,9 @@ uint16_t macportable_state::scsi_r(offs_t offset, uint16_t mem_mask)
// logerror("macplus_scsi_r: offset %x mask %x\n", offset, mem_mask);
if ((reg == 6) && (offset == 0x130))
{
reg = R5380_CURDATA_DTACK;
}
bool pseudo_dma = (reg == 6) && (offset == 0x130);
return m_ncr5380->ncr5380_read_reg(reg) << 8;
return m_scsihelp->read_wrapper(pseudo_dma, reg) << 8;
}
void macportable_state::scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
@ -422,13 +415,16 @@ void macportable_state::scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
// logerror("macplus_scsi_w: data %x offset %x mask %x\n", data, offset, mem_mask);
if ((reg == 0) && (offset == 0x100))
{
reg = R5380_OUTDATA_DTACK;
bool pseudo_dma = (reg == 0) && (offset == 0x100);
m_scsihelp->write_wrapper(pseudo_dma, reg, data);
}
m_ncr5380->ncr5380_write_reg(reg, data);
void macportable_state::scsi_berr_w(uint8_t data)
{
m_maincpu->pulse_input_line(M68K_LINE_BUSERROR, attotime::zero);
}
/***************************************************************************
ADDRESS MAPS
***************************************************************************/
@ -449,7 +445,7 @@ void macportable_state::macprtb_map(address_map &map)
uint8_t macportable_state::mac_via_in_a()
{
return m_pmu_via_bus;
return m_pmu_to_via;
}
uint8_t macportable_state::mac_via_in_b()
@ -459,7 +455,7 @@ uint8_t macportable_state::mac_via_in_b()
void macportable_state::mac_via_out_a(uint8_t data)
{
m_pmu_via_bus = data;
m_pmu_from_via = data;
}
void macportable_state::mac_via_out_b(uint8_t data)
@ -515,10 +511,12 @@ void macportable_state::macprtb(machine_config &config)
M50753(config, m_pmu, 3.93216_MHz_XTAL);
m_pmu->read_p<2>().set(FUNC(macportable_state::pmu_data_r));
m_pmu->write_p<2>().set(FUNC(macportable_state::pmu_data_w));
m_pmu->set_pullups<2>(0xff); // internal pullup option?
m_pmu->read_p<3>().set(FUNC(macportable_state::pmu_comms_r));
m_pmu->write_p<3>().set(FUNC(macportable_state::pmu_comms_w));
m_pmu->read_p<4>().set(FUNC(macportable_state::pmu_adb_r));
m_pmu->write_p<4>().set(FUNC(macportable_state::pmu_adb_w));
m_pmu->set_pullups<4>(0x0f); // external pullups
m_pmu->read_in_p().set(FUNC(macportable_state::pmu_in_r));
m_pmu->ad_in<0>().set(FUNC(macportable_state::ad_in_r));
m_pmu->ad_in<1>().set(FUNC(macportable_state::ad_in_r));
@ -546,12 +544,27 @@ void macportable_state::macprtb(machine_config &config)
applefdintf_device::add_35_hd(config, m_floppy[0]);
applefdintf_device::add_35_nc(config, m_floppy[1]);
scsi_port_device &scsibus(SCSI_PORT(config, "scsi"));
scsibus.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_6));
scsibus.set_slot_device(2, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_5));
NSCSI_BUS(config, "scsi");
NSCSI_CONNECTOR(config, "scsi:0", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:1", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:2", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:3", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:6", mac_scsi_devices, "harddisk");
NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5380", NCR53C80).machine_config([this](device_t *device) {
ncr53c80_device &adapter = downcast<ncr53c80_device &>(*device);
adapter.irq_handler().set(m_via1, FUNC(r65c22_device::write_cb2));
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
});
NCR5380(config, m_ncr5380, C7M);
m_ncr5380->set_scsi_port("scsi");
MAC_SCSI_HELPER(config, m_scsihelp);
m_scsihelp->scsi_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::read));
m_scsihelp->scsi_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::write));
m_scsihelp->scsi_dma_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_r));
m_scsihelp->scsi_dma_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_w));
m_scsihelp->cpu_halt_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_scsihelp->timeout_error_callback().set(FUNC(macportable_state::scsi_berr_w));
SCC85C30(config, m_scc, C7M);
// m_scc->intrq_callback().set(FUNC(macportable_state::set_scc_interrupt));
@ -576,6 +589,7 @@ void macportable_state::macprtb(machine_config &config)
m_ram->set_extra_options("1M,3M,5M,7M,9M");
SOFTWARE_LIST(config, "flop35_list").set_original("mac_flop");
SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd");
}
ROM_START(macprtb)

View File

@ -106,9 +106,10 @@
#include "machine/timer.h"
#include "machine/z80scc.h"
#include "machine/macadb.h"
#include "machine/ncr5380.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsihd.h"
#include "machine/macscsi.h"
#include "machine/ncr5380n.h"
#include "machine/nscsi_bus.h"
#include "bus/nscsi/devices.h"
#include "sound/asc.h"
#include "formats/ap_dsk35.h"
@ -117,9 +118,9 @@
#include "softlist.h"
#include "speaker.h"
#define C7M (7833600)
#define C15M (C7M*2)
#define C32M (C15M*2)
#define C32M (31.3344_MHz_XTAL)
#define C15M (C32M/2)
#define C7M (C32M/4)
class macpb030_state : public driver_device
{
@ -131,7 +132,8 @@ public:
m_via1(*this, "via1"),
m_via2(*this, "via2"),
m_macadb(*this, "macadb"),
m_ncr5380(*this, "ncr5380"),
m_ncr5380(*this, "scsi:7:ncr5380"),
m_scsihelp(*this, "scsihelp"),
m_ram(*this, RAM_TAG),
m_swim(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
@ -164,7 +166,8 @@ private:
required_device<via6522_device> m_via1;
required_device<via6522_device> m_via2;
required_device<macadb_device> m_macadb;
required_device<ncr5380_device> m_ncr5380;
required_device<ncr53c80_device> m_ncr5380;
required_device<mac_scsi_helper_device> m_scsihelp;
required_device<ram_device> m_ram;
required_device<applefdintf_device> m_swim;
required_device_array<floppy_connector, 2> m_floppy;
@ -217,6 +220,7 @@ private:
void scsi_w(offs_t offset, u16 data, u16 mem_mask);
uint32_t scsi_drq_r(offs_t offset, uint32_t mem_mask = ~0);
void scsi_drq_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void scsi_berr_w(uint8_t data);
u16 mac_scc_r(offs_t offset)
{
mac_via_sync();
@ -607,12 +611,9 @@ u16 macpb030_state::scsi_r(offs_t offset, u16 mem_mask)
//printf("scsi_r: offset %x mask %x\n", offset, mem_mask);
if ((reg == 6) && (offset == 0x130))
{
reg = R5380_CURDATA_DTACK;
}
bool pseudo_dma = (reg == 6) && (offset == 0x130);
return m_ncr5380->ncr5380_read_reg(reg) << 8;
return m_scsihelp->read_wrapper(pseudo_dma, reg) << 8;
}
void macpb030_state::scsi_w(offs_t offset, u16 data, u16 mem_mask)
@ -621,12 +622,9 @@ void macpb030_state::scsi_w(offs_t offset, u16 data, u16 mem_mask)
//printf("scsi_w: data %x offset %x mask %x\n", data, offset, mem_mask);
if ((reg == 0) && (offset == 0x100))
{
reg = R5380_OUTDATA_DTACK;
}
bool pseudo_dma = (reg == 0) && (offset == 0x100);
m_ncr5380->ncr5380_write_reg(reg, data>>8);
m_scsihelp->write_wrapper(pseudo_dma, reg, data>>8);
}
uint32_t macpb030_state::scsi_drq_r(offs_t offset, uint32_t mem_mask)
@ -634,13 +632,13 @@ uint32_t macpb030_state::scsi_drq_r(offs_t offset, uint32_t mem_mask)
switch (mem_mask)
{
case 0xff000000:
return m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24;
return m_scsihelp->read_wrapper(true, 6)<<24;
case 0xffff0000:
return (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<16);
return (m_scsihelp->read_wrapper(true, 6)<<24) | (m_scsihelp->read_wrapper(true, 6)<<16);
case 0xffffffff:
return (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<16) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<8) | m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK);
return (m_scsihelp->read_wrapper(true, 6)<<24) | (m_scsihelp->read_wrapper(true, 6)<<16) | (m_scsihelp->read_wrapper(true, 6)<<8) | m_scsihelp->read_wrapper(true, 6);
default:
logerror("scsi_drq_r: unknown mem_mask %08x\n", mem_mask);
@ -654,19 +652,19 @@ void macpb030_state::scsi_drq_w(offs_t offset, uint32_t data, uint32_t mem_mask)
switch (mem_mask)
{
case 0xff000000:
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
m_scsihelp->write_wrapper(true, 0, data>>24);
break;
case 0xffff0000:
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>16);
m_scsihelp->write_wrapper(true, 0, data>>24);
m_scsihelp->write_wrapper(true, 0, data>>16);
break;
case 0xffffffff:
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>16);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>8);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data&0xff);
m_scsihelp->write_wrapper(true, 0, data>>24);
m_scsihelp->write_wrapper(true, 0, data>>16);
m_scsihelp->write_wrapper(true, 0, data>>8);
m_scsihelp->write_wrapper(true, 0, data&0xff);
break;
default:
@ -675,6 +673,11 @@ void macpb030_state::scsi_drq_w(offs_t offset, uint32_t data, uint32_t mem_mask)
}
}
void macpb030_state::scsi_berr_w(uint8_t data)
{
m_maincpu->pulse_input_line(M68K_LINE_BUSERROR, attotime::zero);
}
uint8_t macpb030_state::mac_gsc_r(offs_t offset)
{
if (offset == 1)
@ -919,12 +922,26 @@ void macpb030_state::macpb140(machine_config &config)
applefdintf_device::add_35_hd(config, m_floppy[0]);
applefdintf_device::add_35_nc(config, m_floppy[1]);
scsi_port_device &scsibus(SCSI_PORT(config, "scsi"));
scsibus.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_6));
scsibus.set_slot_device(2, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_5));
NSCSI_BUS(config, "scsi");
NSCSI_CONNECTOR(config, "scsi:0", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:1", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:2", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:3", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:6", mac_scsi_devices, "harddisk");
NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5380", NCR53C80).machine_config([this](device_t *device) {
ncr53c80_device &adapter = downcast<ncr53c80_device &>(*device);
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
});
NCR5380(config, m_ncr5380, C7M);
m_ncr5380->set_scsi_port("scsi");
MAC_SCSI_HELPER(config, m_scsihelp);
m_scsihelp->scsi_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::read));
m_scsihelp->scsi_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::write));
m_scsihelp->scsi_dma_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_r));
m_scsihelp->scsi_dma_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_w));
m_scsihelp->cpu_halt_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_scsihelp->timeout_error_callback().set(FUNC(macpb030_state::scsi_berr_w));
SCC85C30(config, m_scc, C7M);
// m_scc->intrq_callback().set(FUNC(macpb030_state::set_scc_interrupt));
@ -957,6 +974,7 @@ void macpb030_state::macpb140(machine_config &config)
m_ram->set_extra_options("4M,6M,8M");
SOFTWARE_LIST(config, "flop35_list").set_original("mac_flop");
SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd");
}
// PowerBook 145 = 140 @ 25 MHz (still 2MB RAM - the 145B upped that to 4MB)
@ -1015,12 +1033,26 @@ void macpb030_state::macpb160(machine_config &config)
applefdintf_device::add_35_hd(config, m_floppy[0]);
applefdintf_device::add_35_nc(config, m_floppy[1]);
scsi_port_device &scsibus(SCSI_PORT(config, "scsi"));
scsibus.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_6));
scsibus.set_slot_device(2, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_5));
NSCSI_BUS(config, "scsi");
NSCSI_CONNECTOR(config, "scsi:0", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:1", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:2", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:3", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:6", mac_scsi_devices, "harddisk");
NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5380", NCR53C80).machine_config([this](device_t *device) {
ncr53c80_device &adapter = downcast<ncr53c80_device &>(*device);
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
});
NCR5380(config, m_ncr5380, C7M);
m_ncr5380->set_scsi_port("scsi");
MAC_SCSI_HELPER(config, m_scsihelp);
m_scsihelp->scsi_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::read));
m_scsihelp->scsi_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::write));
m_scsihelp->scsi_dma_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_r));
m_scsihelp->scsi_dma_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_w));
m_scsihelp->cpu_halt_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_scsihelp->timeout_error_callback().set(FUNC(macpb030_state::scsi_berr_w));
SCC85C30(config, m_scc, C7M);
// m_scc->intrq_callback().set(FUNC(macpb030_state::set_scc_interrupt));
@ -1053,6 +1085,7 @@ void macpb030_state::macpb160(machine_config &config)
m_ram->set_extra_options("4M,6M,8M");
SOFTWARE_LIST(config, "flop35_list").set_original("mac_flop");
SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd");
}
void macpb030_state::macpb180(machine_config &config)

View File

@ -26,8 +26,7 @@
#include "sound/asc.h"
#include "formats/ap_dsk35.h"
#include "bus/nscsi/cd.h"
#include "bus/nscsi/hd.h"
#include "bus/nscsi/devices.h"
#include "bus/nubus/nubus.h"
#include "bus/nubus/nubus_48gc.h"
@ -936,12 +935,6 @@ static void mac_nubus_cards(device_slot_interface &device)
device.option_add("laserview", NUBUS_LASERVIEW); /* Sigma Designs LaserView monochrome video card */
}
static void mac_scsi_devices(device_slot_interface &device)
{
device.option_add("harddisk", NSCSI_HARDDISK);
device.option_add("cdrom", NSCSI_CDROM);
}
void macquadra_state::macqd700(machine_config &config)
{
/* basic machine hardware */

View File

@ -14,6 +14,8 @@
#include "machine/8530scc.h"
#include "machine/6522via.h"
#include "machine/ncr5380n.h"
#include "machine/nscsi_bus.h"
#include "machine/ram.h"
#include "machine/timer.h"
#include "machine/egret.h"
@ -22,8 +24,8 @@
#include "bus/nubus/nubus.h"
#include "bus/macpds/macpds.h"
#include "machine/applefdintf.h"
#include "machine/ncr5380.h"
#include "machine/macrtc.h"
#include "machine/macscsi.h"
#include "sound/asc.h"
#include "sound/dac.h"
#include "cpu/m68000/m68000.h"
@ -59,7 +61,8 @@ public:
m_macadb(*this, "macadb"),
m_ram(*this, RAM_TAG),
m_scc(*this, "scc"),
m_ncr5380(*this, "ncr5380"),
m_ncr5380(*this, "scsi:7:ncr5380"),
m_scsihelp(*this, "scsihelp"),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
m_rtc(*this, "rtc"),
@ -196,7 +199,8 @@ private:
optional_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
required_device<scc8530_legacy_device> m_scc;
optional_device<ncr5380_device> m_ncr5380;
required_device<ncr53c80_device> m_ncr5380;
required_device<mac_scsi_helper_device> m_scsihelp;
required_device<applefdintf_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
optional_device<rtc3430042_device> m_rtc;
@ -286,6 +290,7 @@ private:
void macii_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint32_t macii_scsi_drq_r(offs_t offset, uint32_t mem_mask = ~0);
void macii_scsi_drq_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
void scsi_berr_w(uint8_t data);
uint32_t rbv_ramdac_r();
void rbv_ramdac_w(offs_t offset, uint32_t data);

View File

@ -468,12 +468,9 @@ uint16_t mac_state::macplus_scsi_r(offs_t offset, uint16_t mem_mask)
// logerror("macplus_scsi_r: offset %x mask %x\n", offset, mem_mask);
if ((reg == 6) && (offset == 0x130))
{
reg = R5380_CURDATA_DTACK;
}
bool pseudo_dma = (reg == 6) && (offset == 0x130);
return m_ncr5380->ncr5380_read_reg(reg)<<8;
return m_scsihelp->read_wrapper(pseudo_dma, reg)<<8;
}
uint32_t mac_state::macii_scsi_drq_r(offs_t offset, uint32_t mem_mask)
@ -481,13 +478,13 @@ uint32_t mac_state::macii_scsi_drq_r(offs_t offset, uint32_t mem_mask)
switch (mem_mask)
{
case 0xff000000:
return m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24;
return m_scsihelp->read_wrapper(true, 6)<<24;
case 0xffff0000:
return (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<16);
return (m_scsihelp->read_wrapper(true, 6)<<24) | (m_scsihelp->read_wrapper(true, 6)<<16);
case 0xffffffff:
return (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<16) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<8) | m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK);
return (m_scsihelp->read_wrapper(true, 6)<<24) | (m_scsihelp->read_wrapper(true, 6)<<16) | (m_scsihelp->read_wrapper(true, 6)<<8) | m_scsihelp->read_wrapper(true, 6);
default:
logerror("macii_scsi_drq_r: unknown mem_mask %08x\n", mem_mask);
@ -501,19 +498,19 @@ void mac_state::macii_scsi_drq_w(offs_t offset, uint32_t data, uint32_t mem_mask
switch (mem_mask)
{
case 0xff000000:
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
m_scsihelp->write_wrapper(true, 0, data>>24);
break;
case 0xffff0000:
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>16);
m_scsihelp->write_wrapper(true, 0, data>>24);
m_scsihelp->write_wrapper(true, 0, data>>16);
break;
case 0xffffffff:
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>16);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>8);
m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data&0xff);
m_scsihelp->write_wrapper(true, 0, data>>24);
m_scsihelp->write_wrapper(true, 0, data>>16);
m_scsihelp->write_wrapper(true, 0, data>>8);
m_scsihelp->write_wrapper(true, 0, data&0xff);
break;
default:
@ -528,12 +525,9 @@ void mac_state::macplus_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
// logerror("macplus_scsi_w: data %x offset %x mask %x\n", data, offset, mem_mask);
if ((reg == 0) && (offset == 0x100))
{
reg = R5380_OUTDATA_DTACK;
}
bool pseudo_dma = (reg == 0) && (offset == 0x100);
m_ncr5380->ncr5380_write_reg(reg, data);
m_scsihelp->write_wrapper(pseudo_dma, reg, data);
}
void mac_state::macii_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
@ -542,12 +536,9 @@ void mac_state::macii_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
// logerror("macplus_scsi_w: data %x offset %x mask %x (PC=%x)\n", data, offset, mem_mask, m_maincpu->pc());
if ((reg == 0) && (offset == 0x100))
{
reg = R5380_OUTDATA_DTACK;
}
bool pseudo_dma = (reg == 0) && (offset == 0x100);
m_ncr5380->ncr5380_write_reg(reg, data>>8);
m_scsihelp->write_wrapper(pseudo_dma, reg, data>>8);
}
WRITE_LINE_MEMBER(mac_state::mac_scsi_irq)
@ -561,6 +552,11 @@ WRITE_LINE_MEMBER(mac_state::mac_scsi_irq)
}*/
}
void mac_state::scsi_berr_w(uint8_t data)
{
m_maincpu->pulse_input_line(M68K_LINE_BUSERROR, attotime::zero);
}
/* *************************************************************************
* SCC
*

View File

@ -0,0 +1,318 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Apple Macintosh 5380 SCSI helper
The Macintosh Toolbox's SCSI Manager defines two methods each for
reading and writing SCSI data (including data comparisons). All
of these methods are implemented using the 5380's pseudo-DMA mode.
For SCSIRead and SCSIWrite, the CPU polls DRQ before it reads or
writes each byte, but SCSIRBlind and SCSIWBlind, in order to
transfer data as quickly as possible, do not perform this check in
software except before the very first byte (to give SCSI devices
time to react to commands). Rather, the hardware enables DRQ onto
DTACK (MC68000) or DSACK0 (MC68020/030) so wait states can be
inserted to correspond to SCSI delays. Too long a delay will
result in a BERR timeout, and the SCSI Manager anticipates bus
errors by inserting its own exception handler in the vector table.
The exact timeout is system-dependent. Later Macs will attempt a
limited number of recoveries from bus errors during SCSI transfers
before exiting with the scBusTOErr code; the MC68000's rudimentary
handling of bus errors does not permit this.
This causes some conflicts between MAME's line-level emulation of
the SCSI bus and its current M68000 family core, which has no
working concept of wait states and tries to execute each read or
write instruction instantaneously. The problems are least
pronounced on the Macintosh Plus, which never reads or writes more
than one SCSI byte at a time in any case. However, the SE and
later models implement the "blind" transfer modes using unrolled
loops with MOVEP.L (MC68000) or MOVE.L (MC68020/030) to transfer
four bytes at a time (after first transfering a single byte if its
buffer pointer is not word-aligned).
The workaround this device provides is to mediate pseudo-DMA
transfers through four-byte FIFOs (implementing these using
32-bit integers is not a coincidence) and halt the CPU to keep
the FIFO filled during read operations and emptied during write
operations. In the case of read operations, the buffer must of
course be filled before CPU attempts its first data read, which
could be a MOVEP.L or MOVE.L already. To make read operations a
little more realistic, the device waits until the CPU polls DRQ as
active before it begins halting the CPU to fill the FIFO. The CPU
halt will be released if DRQ is not asserted within a certain
time.
It is possible for the current implementation to lose data if
there are still bytes in the FIFO when the pseudo-DMA operation
ends. However, this is unlikely to be relevant due to a defect in
the SCSI Manager which Apple's documentation warns about.
**********************************************************************/
#include "emu.h"
#include "macscsi.h"
#define VERBOSE 0
#include "logmacro.h"
static constexpr u8 BAD_BYTE = 0xbb;
static constexpr u8 READ_ERROR = 1;
static constexpr u8 WRITE_ERROR = 0;
// device type definition
DEFINE_DEVICE_TYPE(MAC_SCSI_HELPER, mac_scsi_helper_device, "scsipdma", "Mac 5380 SCSI helper")
ALLOW_SAVE_TYPE(mac_scsi_helper_device::mode);
mac_scsi_helper_device::mac_scsi_helper_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, MAC_SCSI_HELPER, tag, owner, clock)
, m_scsi_read_callback(*this)
, m_scsi_write_callback(*this)
, m_scsi_dma_read_callback(*this)
, m_scsi_dma_write_callback(*this)
, m_cpu_halt_callback(*this)
, m_timeout_error_callback(*this)
, m_timeout(attotime::from_usec(16))
, m_pseudo_dma_timer(nullptr)
, m_mode(mode::NON_DMA)
, m_read_fifo_bytes(0)
, m_write_fifo_bytes(0)
, m_read_fifo_data(0)
, m_write_fifo_data(0)
{
}
void mac_scsi_helper_device::device_resolve_objects()
{
m_scsi_read_callback.resolve_safe(BAD_BYTE);
m_scsi_write_callback.resolve_safe();
m_scsi_dma_read_callback.resolve_safe(BAD_BYTE);
m_scsi_dma_write_callback.resolve_safe();
m_cpu_halt_callback.resolve_safe();
m_timeout_error_callback.resolve_safe();
}
void mac_scsi_helper_device::device_start()
{
m_pseudo_dma_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_scsi_helper_device::timer_callback), this));
save_item(NAME(m_mode));
save_item(NAME(m_read_fifo_bytes));
save_item(NAME(m_write_fifo_bytes));
save_item(NAME(m_read_fifo_data));
save_item(NAME(m_write_fifo_data));
}
void mac_scsi_helper_device::device_reset()
{
dma_stop();
m_cpu_halt_callback(CLEAR_LINE);
m_pseudo_dma_timer->enable(false);
}
void mac_scsi_helper_device::read_fifo_process()
{
assert(m_read_fifo_bytes < 4);
u8 data = m_scsi_dma_read_callback(6);
++m_read_fifo_bytes;
LOG("Read byte %02X into FIFO (%d/4 filled)\n", data, m_read_fifo_bytes);
m_read_fifo_data |= u32(data) << (32 - m_read_fifo_bytes * 8);
if (m_read_fifo_bytes != 4)
m_pseudo_dma_timer->adjust(m_timeout);
else
{
m_cpu_halt_callback(CLEAR_LINE);
m_pseudo_dma_timer->enable(false);
}
}
void mac_scsi_helper_device::write_fifo_process()
{
assert(m_write_fifo_bytes != 0);
--m_write_fifo_bytes;
u8 data = BIT(m_write_fifo_data, m_write_fifo_bytes * 8, 8);
LOG("Write byte %02X from FIFO (%d left)\n", data, m_write_fifo_bytes);
m_scsi_dma_write_callback(0, data);
if (m_write_fifo_bytes != 0)
m_pseudo_dma_timer->adjust(m_timeout);
else
{
m_cpu_halt_callback(CLEAR_LINE);
m_pseudo_dma_timer->enable(false);
}
}
WRITE_LINE_MEMBER(mac_scsi_helper_device::drq_w)
{
if (state)
{
if (m_mode == mode::READ_DMA && m_read_fifo_bytes < 4)
read_fifo_process();
else if ((m_mode == mode::WRITE_DMA || m_mode == mode::BAD_DMA) && m_write_fifo_bytes != 0)
write_fifo_process();
}
}
TIMER_CALLBACK_MEMBER(mac_scsi_helper_device::timer_callback)
{
if (m_mode == mode::WRITE_DMA && m_write_fifo_bytes != 0 && BIT(m_scsi_read_callback(5), 6))
write_fifo_process();
else if (m_mode == mode::READ_DMA || m_mode == mode::WRITE_DMA)
{
LOG("DMA timed out\n");
m_cpu_halt_callback(CLEAR_LINE);
}
else
dma_stop();
}
void mac_scsi_helper_device::dma_stop()
{
if (m_read_fifo_bytes != 0)
logerror("%s: %d unread byte(s) lost (%08X)\n", machine().describe_context(), m_read_fifo_bytes, m_read_fifo_data);
if (m_write_fifo_bytes != 0)
logerror("%s: %d unwritten byte(s) lost (%08X)\n", machine().describe_context(), m_write_fifo_bytes, m_write_fifo_data);
m_mode = mode::NON_DMA;
m_read_fifo_bytes = 0;
m_write_fifo_bytes = 0;
m_read_fifo_data = 0;
m_write_fifo_data = 0;
}
u8 mac_scsi_helper_device::read_wrapper(bool pseudo_dma, offs_t offset)
{
u8 data = BAD_BYTE;
switch (offset & 7)
{
case 2:
data = m_scsi_read_callback(2);
if (!machine().side_effects_disabled() && !BIT(data, 1))
dma_stop();
break;
case 5:
data = m_scsi_read_callback(5);
if (!machine().side_effects_disabled())
{
if (!BIT(m_scsi_read_callback(2), 1))
dma_stop();
if (m_mode == mode::READ_WAIT_DRQ && BIT(data, 6))
{
m_mode = mode::READ_DMA;
m_read_fifo_data = u32(m_scsi_dma_read_callback(6)) << 24;
LOG("%s: Pseudo-DMA read started: first byte = %02X\n", machine().describe_context(), m_read_fifo_data >> 24);
m_read_fifo_bytes = 1;
m_pseudo_dma_timer->adjust(m_timeout);
m_cpu_halt_callback(ASSERT_LINE);
}
}
if ((m_mode == mode::READ_DMA && m_read_fifo_bytes != 0) || (m_mode == mode::WRITE_DMA && m_write_fifo_bytes < 4))
data |= 0x40;
break;
case 6:
if (!machine().side_effects_disabled() && !BIT(m_scsi_read_callback(2), 1))
dma_stop();
if (m_read_fifo_bytes != 0)
{
data = BIT(m_read_fifo_data, 24, 8);
if (!machine().side_effects_disabled())
{
--m_read_fifo_bytes;
LOG("%s: CPU read byte %02X from FIFO (%d left)\n", machine().describe_context(), data, m_read_fifo_bytes);
m_read_fifo_data <<= 8;
if (BIT(m_scsi_read_callback(5), 6))
read_fifo_process();
else if (!m_pseudo_dma_timer->enabled())
{
m_pseudo_dma_timer->adjust(m_timeout);
m_cpu_halt_callback(ASSERT_LINE);
}
}
}
else if (m_mode != mode::NON_DMA && pseudo_dma)
{
if (m_mode != mode::BAD_DMA)
{
logerror("%s: Read underflow on SCSI pseudo-DMA\n", machine().describe_context());
m_mode = mode::BAD_DMA;
}
m_timeout_error_callback(READ_ERROR);
m_pseudo_dma_timer->enable(false);
}
else
data = pseudo_dma ? m_scsi_dma_read_callback(6) : m_scsi_read_callback(6);
break;
default:
if (!machine().side_effects_disabled() && !BIT(m_scsi_read_callback(2), 1))
dma_stop();
data = m_scsi_read_callback(offset & 7);
break;
}
return data;
}
void mac_scsi_helper_device::write_wrapper(bool pseudo_dma, offs_t offset, u8 data)
{
switch (offset & 7)
{
case 0:
if (m_mode == mode::BAD_DMA && pseudo_dma)
m_timeout_error_callback(WRITE_ERROR);
else if (m_mode == mode::WRITE_DMA && (m_write_fifo_bytes != 0 || !BIT(m_scsi_read_callback(5), 6)))
{
if (m_write_fifo_bytes < 4)
{
m_write_fifo_data = (m_write_fifo_data << 8) | data;
++m_write_fifo_bytes;
logerror("%s: CPU writing byte %02X into FIFO (%d/4 filled)\n", machine().describe_context(), data, m_write_fifo_bytes);
if (!m_pseudo_dma_timer->enabled())
{
m_pseudo_dma_timer->adjust(m_timeout);
m_cpu_halt_callback(ASSERT_LINE);
}
}
else if (pseudo_dma)
{
logerror("%s: Write overflow on SCSI pseudo-DMA\n", machine().describe_context());
m_timeout_error_callback(WRITE_ERROR);
m_mode = mode::BAD_DMA;
}
}
else if (pseudo_dma)
m_scsi_dma_write_callback(0, data);
else
m_scsi_write_callback(0, data);
break;
case 2:
if (!BIT(data, 1))
dma_stop();
m_scsi_write_callback(2, data);
break;
case 5:
if (m_mode == mode::NON_DMA && BIT(m_scsi_read_callback(2), 1))
m_mode = mode::WRITE_DMA;
m_scsi_write_callback(5, data);
break;
case 6: case 7:
if (m_mode == mode::NON_DMA && BIT(m_scsi_read_callback(2), 1))
m_mode = mode::READ_WAIT_DRQ;
m_scsi_write_callback(offset & 7, data);
break;
default:
m_scsi_write_callback(offset & 7, data);
break;
}
}

View File

@ -0,0 +1,70 @@
// license:BSD-3-Clause
// copyright-holders:AJR
#ifndef MAME_MACHINE_MACSCSI_H
#define MAME_MACHINE_MACSCSI_H
#pragma once
class mac_scsi_helper_device : public device_t
{
public:
// device type constructor
mac_scsi_helper_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
// callback configuration
auto scsi_read_callback() { return m_scsi_read_callback.bind(); }
auto scsi_write_callback() { return m_scsi_write_callback.bind(); }
auto scsi_dma_read_callback() { return m_scsi_dma_read_callback.bind(); }
auto scsi_dma_write_callback() { return m_scsi_dma_write_callback.bind(); }
auto cpu_halt_callback() { return m_cpu_halt_callback.bind(); }
auto timeout_error_callback() { return m_timeout_error_callback.bind(); }
// miscellaneous configuration
void set_timeout(attotime timeout) { m_timeout = timeout; }
// read/write handlers
u8 read_wrapper(bool pseudo_dma, offs_t offset);
void write_wrapper(bool pseudo_dma, offs_t offset, u8 data);
DECLARE_WRITE_LINE_MEMBER(drq_w);
protected:
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
private:
enum class mode : u8 { NON_DMA, READ_WAIT_DRQ, READ_DMA, WRITE_DMA, BAD_DMA };
// internal helpers
void read_fifo_process();
void write_fifo_process();
TIMER_CALLBACK_MEMBER(timer_callback);
void dma_stop();
// callback objects
devcb_read8 m_scsi_read_callback;
devcb_write8 m_scsi_write_callback;
devcb_read8 m_scsi_dma_read_callback;
devcb_write8 m_scsi_dma_write_callback;
devcb_write_line m_cpu_halt_callback;
devcb_write8 m_timeout_error_callback;
// misc. parameters
attotime m_timeout;
// internal state
emu_timer *m_pseudo_dma_timer;
mode m_mode;
u8 m_read_fifo_bytes;
u8 m_write_fifo_bytes;
u32 m_read_fifo_data;
u32 m_write_fifo_data;
};
// device type declaration
DECLARE_DEVICE_TYPE(MAC_SCSI_HELPER, mac_scsi_helper_device)
#endif // MAME_MACHINE_MACSCSI_H