diff options
Diffstat (limited to 'src/mame/machine/hpc1.cpp')
-rw-r--r-- | src/mame/machine/hpc1.cpp | 227 |
1 files changed, 136 insertions, 91 deletions
diff --git a/src/mame/machine/hpc1.cpp b/src/mame/machine/hpc1.cpp index 7d6dfd6fff3..9bce71552bb 100644 --- a/src/mame/machine/hpc1.cpp +++ b/src/mame/machine/hpc1.cpp @@ -10,9 +10,9 @@ #include "cpu/mips/mips3.h" #include "bus/rs232/rs232.h" #include "bus/rs232/hlemouse.h" -#include "machine/nscsi_bus.h" -#include "machine/nscsi_cd.h" -#include "machine/nscsi_hd.h" +#include "bus/scsi/scsi.h" +#include "bus/scsi/scsicd512.h" +#include "bus/scsi/scsihd.h" #include "bus/sgikbd/sgikbd.h" #include "machine/hpc1.h" #include "speaker.h" @@ -28,10 +28,9 @@ #define LOG_DUART1 (1 << 8) #define LOG_DUART2 (1 << 9) #define LOG_PIT (1 << 10) -#define LOG_CHAIN (1 << 11) #define LOG_REGS (LOG_UNKNOWN | LOG_READS | LOG_WRITES) #define LOG_DUART (LOG_DUART0 | LOG_DUART1 | LOG_DUART2) -#define LOG_ALL (LOG_REGS | LOG_INT | LOG_EEPROM | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT | LOG_CHAIN) +#define LOG_ALL (LOG_REGS | LOG_INT | LOG_EEPROM | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT) #define VERBOSE (LOG_UNKNOWN) #include "logmacro.h" @@ -51,7 +50,7 @@ hpc1_device::hpc1_device(const machine_config &mconfig, const char *tag, device_ : device_t(mconfig, SGI_HPC1, tag, owner, clock) , m_maincpu(*this, finder_base::DUMMY_TAG) , m_eeprom(*this, finder_base::DUMMY_TAG) - , m_wd33c93(*this, "scsibus:0:wd33c93") + , m_wd33c93(*this, "wd33c93") , m_scc(*this, "scc%u", 0U) , m_pit(*this, "pit") , m_rtc(*this, "rtc") @@ -69,14 +68,14 @@ void hpc1_device::device_start() save_item(NAME(m_vme_int_mask)); save_item(NAME(m_scsi_dma.m_desc)); - save_item(NAME(m_scsi_dma.m_addr)); save_item(NAME(m_scsi_dma.m_ctrl)); - save_item(NAME(m_scsi_dma.m_length)); + save_item(NAME(m_scsi_dma.m_addr)); + save_item(NAME(m_scsi_dma.m_flag)); save_item(NAME(m_scsi_dma.m_next)); - save_item(NAME(m_scsi_dma.m_irq)); - save_item(NAME(m_scsi_dma.m_drq)); + save_item(NAME(m_scsi_dma.m_length)); save_item(NAME(m_scsi_dma.m_to_mem)); save_item(NAME(m_scsi_dma.m_active)); + save_item(NAME(m_scsi_dma.m_end)); save_item(NAME(m_duart_int_status)); } @@ -92,14 +91,14 @@ void hpc1_device::device_reset() memset(m_vme_int_mask, 0, sizeof(uint32_t) * 2); m_scsi_dma.m_desc = 0; - m_scsi_dma.m_addr = 0; m_scsi_dma.m_ctrl = 0; - m_scsi_dma.m_length = 0; + m_scsi_dma.m_addr = 0; + m_scsi_dma.m_flag = 0; m_scsi_dma.m_next = 0; - m_scsi_dma.m_irq = false; - m_scsi_dma.m_drq = false; + m_scsi_dma.m_length = 0; m_scsi_dma.m_to_mem = false; m_scsi_dma.m_active = false; + m_scsi_dma.m_end = false; m_duart_int_status = 0; @@ -112,8 +111,8 @@ void hpc1_device::device_reset() void hpc1_device::cdrom_config(device_t *device) { - // cdda_device *cdda = device->subdevice<cdda_device>("cdda"); - // cdda->add_route(ALL_OUTPUTS, "^^mono", 1.0); + cdda_device *cdda = device->subdevice<cdda_device>("cdda"); + cdda->add_route(ALL_OUTPUTS, "^^mono", 1.0); } void hpc1_device::indigo_mice(device_slot_interface &device) @@ -121,19 +120,6 @@ void hpc1_device::indigo_mice(device_slot_interface &device) device.option_add("sgimouse", SGI_HLE_SERIAL_MOUSE); } -void hpc1_device::scsi_devices(device_slot_interface &device) -{ - device.option_add("cdrom", NSCSI_CDROM_SGI); - device.option_add("harddisk", NSCSI_HARDDISK); -} - -void hpc1_device::wd33c93(device_t *device) -{ - device->set_clock(10000000); - downcast<wd33c93_device *>(device)->irq_cb().set(*this, FUNC(hpc1_device::scsi_irq)); - downcast<wd33c93_device *>(device)->drq_cb().set(*this, FUNC(hpc1_device::scsi_drq)); -} - void hpc1_device::device_add_mconfig(machine_config &config) { SCC85C30(config, m_scc[0], SCC_PCLK); @@ -173,19 +159,17 @@ void hpc1_device::device_add_mconfig(machine_config &config) rs232b.dcd_handler().set(m_scc[1], FUNC(scc85c30_device::dcdb_w)); rs232b.rxd_handler().set(m_scc[1], FUNC(scc85c30_device::rxb_w)); - NSCSI_BUS(config, "scsibus", 0); - NSCSI_CONNECTOR(config, "scsibus:0").option_set("wd33c93", WD33C93) - .machine_config([this](device_t *device) { wd33c93(device); }); - NSCSI_CONNECTOR(config, "scsibus:1", scsi_devices, "harddisk", false); - NSCSI_CONNECTOR(config, "scsibus:2", scsi_devices, nullptr, false); - NSCSI_CONNECTOR(config, "scsibus:3", scsi_devices, nullptr, false); - NSCSI_CONNECTOR(config, "scsibus:4", scsi_devices, "cdrom", false); - NSCSI_CONNECTOR(config, "scsibus:5", scsi_devices, nullptr, false); - NSCSI_CONNECTOR(config, "scsibus:6", scsi_devices, nullptr, false); - NSCSI_CONNECTOR(config, "scsibus:7", scsi_devices, nullptr, false); + scsi_port_device &scsi(SCSI_PORT(config, "scsi")); + scsi.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_1)); + scsi.set_slot_device(2, "cdrom", RRD45, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4)); + scsi.slot(2).set_option_machine_config("cdrom", cdrom_config); DP8573(config, m_rtc); + WD33C93(config, m_wd33c93); + m_wd33c93->set_scsi_port("scsi"); + m_wd33c93->irq_cb().set(FUNC(hpc1_device::scsi_irq)); + PIT8254(config, m_pit, 0); m_pit->set_clk<0>(1000000); m_pit->set_clk<1>(1000000); @@ -223,13 +207,13 @@ READ32_MEMBER(hpc1_device::read) return 0x00000000; case 0x0120/4: { - uint32_t ret = m_wd33c93->indir_addr_r() << 8; + uint32_t ret = m_wd33c93->read(space, 0) << 8; LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 0 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); return ret; } case 0x0124/4: { - uint32_t ret = m_wd33c93->indir_reg_r() << 8; + uint32_t ret = m_wd33c93->read(space, 1) << 8; LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 1 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask); return ret; } @@ -348,8 +332,6 @@ WRITE32_MEMBER(hpc1_device::write) m_scsi_dma.m_ctrl = data &~ (HPC_DMACTRL_FLUSH | HPC_DMACTRL_RESET); m_scsi_dma.m_to_mem = (m_scsi_dma.m_ctrl & HPC_DMACTRL_TO_MEM); m_scsi_dma.m_active = (m_scsi_dma.m_ctrl & HPC_DMACTRL_ENABLE); - if (m_scsi_dma.m_drq && m_scsi_dma.m_active) - do_scsi_dma(); break; case 0x00ac/4: @@ -360,14 +342,14 @@ WRITE32_MEMBER(hpc1_device::write) if (ACCESSING_BITS_8_15) { LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_wd33c93->indir_addr_w((uint8_t)(data >> 8)); + m_wd33c93->write(space, 0, (uint8_t)(data >> 8)); } break; case 0x0124/4: if (ACCESSING_BITS_8_15) { LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Data Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_wd33c93->indir_reg_w((uint8_t)(data >> 8)); + m_wd33c93->write(space, 1, (uint8_t)(data >> 8)); } break; case 0x01b0/4: @@ -502,76 +484,134 @@ WRITE32_MEMBER(hpc1_device::write) // SCSI DMA //************************************************************************** -void hpc1_device::dump_chain(uint32_t base) -{ - const uint32_t addr = m_cpu_space->read_dword(base); - const uint32_t ctrl = m_cpu_space->read_dword(base+4); - const uint32_t next = m_cpu_space->read_dword(base+8); - - LOGMASKED(LOG_CHAIN, "Chain Node:\n"); - LOGMASKED(LOG_CHAIN, " Addr: %08x\n", addr); - LOGMASKED(LOG_CHAIN, " Ctrl: %08x\n", ctrl); - LOGMASKED(LOG_CHAIN, " Next: %08x\n", next); - - if (next != 0 && !BIT(addr, 31)) - { - dump_chain(next & 0x0fffffff); - } -} void hpc1_device::fetch_chain() { - m_scsi_dma.m_ctrl = m_cpu_space->read_dword(m_scsi_dma.m_desc); + m_scsi_dma.m_flag = m_cpu_space->read_dword(m_scsi_dma.m_desc); m_scsi_dma.m_addr = m_cpu_space->read_dword(m_scsi_dma.m_desc+4); m_scsi_dma.m_next = m_cpu_space->read_dword(m_scsi_dma.m_desc+8); - m_scsi_dma.m_length = m_scsi_dma.m_ctrl & 0x1fff; - - LOGMASKED(LOG_CHAIN, "Fetching chain from %08x:\n", m_scsi_dma.m_desc); - LOGMASKED(LOG_CHAIN, " Addr: %08x\n", m_scsi_dma.m_addr); - LOGMASKED(LOG_CHAIN, " Ctrl: %08x\n", m_scsi_dma.m_ctrl); - LOGMASKED(LOG_CHAIN, " Next: %08x\n", m_scsi_dma.m_next); + m_scsi_dma.m_length = m_scsi_dma.m_flag & 0x1fff; + LOGMASKED(LOG_SCSI_DMA, "Fetched SCSI DMA Descriptor block:\n"); + LOGMASKED(LOG_SCSI_DMA, " Ctrl: %08x\n", m_scsi_dma.m_flag); + LOGMASKED(LOG_SCSI_DMA, " Addr: %08x\n", m_scsi_dma.m_addr); + LOGMASKED(LOG_SCSI_DMA, " Next: %08x\n", m_scsi_dma.m_next); + LOGMASKED(LOG_SCSI_DMA, " Length: %04x\n", m_scsi_dma.m_length); + m_scsi_dma.m_end = BIT(m_scsi_dma.m_addr, 31); + m_scsi_dma.m_addr &= 0x0fffffff; + m_scsi_dma.m_next &= 0x0fffffff; } -void hpc1_device::decrement_chain() +void hpc1_device::advance_chain() { + m_scsi_dma.m_addr++; m_scsi_dma.m_length--; if (m_scsi_dma.m_length == 0) { - if (BIT(m_scsi_dma.m_addr, 31)) + if (m_scsi_dma.m_end) { + LOGMASKED(LOG_SCSI_DMA, "HPC: Disabling SCSI DMA due to end of chain\n"); m_scsi_dma.m_active = false; m_scsi_dma.m_ctrl &= ~HPC_DMACTRL_ENABLE; - return; } - m_scsi_dma.m_desc = m_scsi_dma.m_next & 0x0fffffff; - fetch_chain(); + else + { + m_scsi_dma.m_desc = m_scsi_dma.m_next; + fetch_chain(); + } } } -WRITE_LINE_MEMBER(hpc1_device::scsi_drq) +void hpc1_device::scsi_dma() { - m_scsi_dma.m_drq = state; + int byte_count = m_wd33c93->get_dma_count(); - if (m_scsi_dma.m_drq && m_scsi_dma.m_active) - { - do_scsi_dma(); - } -} + LOGMASKED(LOG_SCSI_DMA, "HPC: Transferring %d bytes %s %08x %s SCSI0\n", + byte_count, m_scsi_dma.m_to_mem ? "to" : "from", m_scsi_dma.m_addr, m_scsi_dma.m_to_mem ? "from" : "to"); -void hpc1_device::do_scsi_dma() -{ + uint8_t dma_buffer[512]; if (m_scsi_dma.m_to_mem) - m_cpu_space->write_byte(m_scsi_dma.m_addr & 0x0fffffff, m_wd33c93->dma_r()); + { + // HPC SCSI DMA: device to host + if (byte_count <= 512) + { + m_wd33c93->dma_read_data(byte_count, dma_buffer); + + for (int i = 0; i < byte_count; i++) + { + LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + m_cpu_space->write_byte(m_scsi_dma.m_addr, dma_buffer[i]); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + } + else + { + while (byte_count) + { + int sub_count = m_wd33c93->dma_read_data(512, dma_buffer); + + for (int i = 0; i < sub_count; i++) + { + LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + m_cpu_space->write_byte(m_scsi_dma.m_addr, dma_buffer[i]); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + + byte_count -= sub_count; + if (!m_scsi_dma.m_active) + break; + } + } + } else - m_wd33c93->dma_w(m_cpu_space->read_byte(m_scsi_dma.m_addr & 0x0fffffff)); - - m_scsi_dma.m_addr++; - decrement_chain(); - - if (!m_scsi_dma.m_active) { - // clear HPC3 DMA active flag - m_scsi_dma.m_ctrl &= ~HPC_DMACTRL_ENABLE; + // HPC SCSI DMA: host to device + if (byte_count <= 512) + { + for (int i = 0; i < byte_count; i++) + { + dma_buffer[i] = m_cpu_space->read_byte(m_scsi_dma.m_addr); + LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + + m_wd33c93->dma_write_data(byte_count, dma_buffer); + } + else + { + while (byte_count) + { + int sub_count = std::min(512, byte_count); + + for (int i = 0; i < sub_count; i++) + { + dma_buffer[i] = m_cpu_space->read_byte(m_scsi_dma.m_addr); + LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_scsi_dma.m_addr); + advance_chain(); + if (!m_scsi_dma.m_active) + break; + } + + m_wd33c93->dma_write_data(sub_count, dma_buffer); + + if (!m_scsi_dma.m_active) + { + break; + } + else + { + byte_count -= sub_count; + } + } + } } + + // clear DMA on the controller + m_wd33c93->clear_dma(); } //************************************************************************** @@ -670,6 +710,11 @@ WRITE_LINE_MEMBER(hpc1_device::scsi_irq) if (state) { LOGMASKED(LOG_SCSI, "SCSI: Set IRQ\n"); + int count = m_wd33c93->get_dma_count(); + LOGMASKED(LOG_SCSI_DMA, "SCSI: count %d, active %d\n", count, m_scsi_dma.m_active); + if (count && m_scsi_dma.m_active) + scsi_dma(); + raise_local_irq(0, LOCAL0_SCSI); } else |