From 67633fcedda50ae56d66af406a5d46835312bee2 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Sat, 8 Sep 2018 07:02:59 +0200 Subject: -sun4: DMA fixes, began work on AMD LANCE skeleton, fails loopback test. [Ryan Holtz] --- src/mame/drivers/sun4.cpp | 160 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 141 insertions(+), 19 deletions(-) diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp index fec52c0a6c8..a6ad2be131a 100644 --- a/src/mame/drivers/sun4.cpp +++ b/src/mame/drivers/sun4.cpp @@ -541,7 +541,7 @@ public: , m_scc2(*this, SCC2_TAG) , m_fdc(*this, FDC_TAG) , m_scsibus(*this, "scsibus") - , m_scsi(*this, "scsibus:7:ncr5390") + , m_scsi(*this, "scsibus:7:ncr53c90a") , m_type0space(*this, "type0") , m_type1space(*this, "type1") , m_ram(*this, RAM_TAG) @@ -584,6 +584,8 @@ private: DECLARE_WRITE8_MEMBER( fdc_w ); DECLARE_READ32_MEMBER( dma_r ); DECLARE_WRITE32_MEMBER( dma_w ); + DECLARE_READ16_MEMBER( lance_r ); + DECLARE_WRITE16_MEMBER( lance_w ); DECLARE_WRITE_LINE_MEMBER( scsi_irq ); DECLARE_WRITE_LINE_MEMBER( scsi_drq ); @@ -595,7 +597,7 @@ private: uint32_t bw2_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void ncr5390(device_t *device); + void ncr53c90a(device_t *device); void sun4_mem(address_map &map); void sun4c_mem(address_map &map); @@ -612,7 +614,7 @@ private: required_device m_fdc; required_device m_scsibus; - required_device m_scsi; + required_device m_scsi; optional_device m_type0space, m_type1space; required_device m_ram; @@ -642,6 +644,9 @@ private: uint8_t m_diag; int m_arch; + uint16_t m_lance_rap; + uint16_t m_lance_csr[4]; + emu_timer *m_c0_timer, *m_c1_timer; emu_timer *m_reset_timer; @@ -905,7 +910,7 @@ WRITE32_MEMBER( sun4_state::sun4c_mmu_w ) { m_reset_timer->adjust(attotime::from_usec(1)); m_maincpu->set_input_line(SPARC_RESET, ASSERT_LINE); - printf("Asserting reset line\n"); + //printf("Asserting reset line\n"); } //printf("%08x to system enable, mask %08x\n", data, mem_mask); if (m_system_enable & ENA_RESET) @@ -1347,6 +1352,30 @@ void sun4_state::sun4c_mem(address_map &map) static INPUT_PORTS_START( sun4 ) INPUT_PORTS_END +enum +{ + LANCE_CSR0_ERR = 0x8000, + LANCE_CSR0_BABL = 0x4000, + LANCE_CSR0_CERR = 0x2000, + LANCE_CSR0_MISS = 0x1000, + LANCE_CSR0_MERR = 0x0800, + LANCE_CSR0_RINT = 0x0400, + LANCE_CSR0_TINT = 0x0200, + LANCE_CSR0_IDON = 0x0100, + LANCE_CSR0_INTR = 0x0080, + LANCE_CSR0_INEA = 0x0040, + LANCE_CSR0_RXON = 0x0020, + LANCE_CSR0_TXON = 0x0010, + LANCE_CSR0_TDMD = 0x0008, + LANCE_CSR0_STOP = 0x0004, + LANCE_CSR0_STRT = 0x0002, + LANCE_CSR0_INIT = 0x0001, + LANCE_CSR0_ANY_ERR = LANCE_CSR0_BABL | LANCE_CSR0_CERR | LANCE_CSR0_MISS | LANCE_CSR0_MERR, + + LANCE_CSR3_BSWP = 0x0004, + LANCE_CSR3_ACON = 0x0002, + LANCE_CSR3_BCON = 0x0001 +}; void sun4_state::machine_reset() { @@ -1358,6 +1387,10 @@ void sun4_state::machine_reset() m_dma_tc_read = false; m_dma_pack_register = 0; + m_lance_rap = 0; + memset(m_lance_csr, 0, sizeof(uint16_t) * 4); + m_lance_csr[0] = LANCE_CSR0_STOP; + memset(m_counter, 0, sizeof(m_counter)); memset(m_dma, 0, sizeof(m_dma)); } @@ -1480,7 +1513,8 @@ void sun4_state::type1space_map(address_map &map) map(0x07200000, 0x07200003).rw(FUNC(sun4_state::fdc_r), FUNC(sun4_state::fdc_w)); map(0x08000000, 0x08000003).r(FUNC(sun4_state::ss1_sl0_id)); // slot 0 contains SCSI/DMA/Ethernet map(0x08400000, 0x0840000f).rw(FUNC(sun4_state::dma_r), FUNC(sun4_state::dma_w)); - map(0x08800000, 0x0880001f).m(m_scsi, FUNC(ncr5390_device::map)).umask32(0xff000000); + map(0x08800000, 0x0880001f).m(m_scsi, FUNC(ncr53c90a_device::map)).umask32(0xff000000); + map(0x08c00000, 0x08c00003).rw(FUNC(sun4_state::lance_r), FUNC(sun4_state::lance_w)); map(0x0e000000, 0x0e000003).r(FUNC(sun4_state::ss1_sl3_id)); // slot 3 contains video board map(0x0e800000, 0x0e8fffff).ram().share("bw2_vram"); } @@ -1546,7 +1580,6 @@ WRITE8_MEMBER( sun4_state::irq_w ) WRITE_LINE_MEMBER( sun4_state::scc1_int ) { - printf("scc1 int: %d\n", state); m_scc1_int = state; m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE); @@ -1554,7 +1587,6 @@ WRITE_LINE_MEMBER( sun4_state::scc1_int ) WRITE_LINE_MEMBER( sun4_state::scc2_int ) { - printf("scc2 int: %d\n", state); m_scc2_int = state; m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE); @@ -1708,7 +1740,7 @@ void sun4_state::dma_transfer_write() { int bit_index = (3 - pack_cnt) * 8; uint8_t dma_value = m_scsi->dma_r(); - logerror("Read from device: %02x\n", dma_value); + logerror("Read from device: %02x, pack count %d\n", dma_value, pack_cnt); m_dma_pack_register |= dma_value << bit_index; if ((m_dma[DMA_CTRL] & DMA_EN_CNT) != 0) @@ -1717,7 +1749,7 @@ void sun4_state::dma_transfer_write() pack_cnt++; if (pack_cnt == 4) { - logerror("Writing pack register %08x\n", m_dma_pack_register); + logerror("Writing pack register %08x to %08x\n", m_dma_pack_register, m_dma[DMA_ADDR]); if (m_arch == ARCH_SUN4C) { write_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0); @@ -1729,6 +1761,7 @@ void sun4_state::dma_transfer_write() pack_cnt = 0; m_dma_pack_register = 0; + m_dma[DMA_ADDR] += 4; } } @@ -1756,6 +1789,7 @@ void sun4_state::dma_transfer_read() { current_word = read_insn_data(11, space, m_dma[DMA_ADDR] >> 2, ~0); } + word_cached = true; logerror("Current word: %08x\n", current_word); } @@ -1764,12 +1798,12 @@ void sun4_state::dma_transfer_read() logerror("Write to device: %02x\n", dma_value); m_scsi->dma_w(dma_value); + if ((m_dma[DMA_ADDR] & 3) == 3) + word_cached = false; + m_dma[DMA_ADDR]++; if ((m_dma[DMA_CTRL] & DMA_EN_CNT) != 0) m_dma[DMA_BYTE_COUNT]--; - - if ((m_dma[DMA_ADDR] & 3) == 3) - word_cached = false; } } @@ -1784,7 +1818,7 @@ void sun4_state::dma_transfer() dma_transfer_read(); } - if (m_dma[DMA_BYTE_COUNT] == 0 && (m_dma[DMA_CTRL] & DMA_EN_CNT) != 0) + if (m_dma[DMA_BYTE_COUNT] == 0) { m_dma[DMA_CTRL] |= DMA_TC; m_dma_tc_read = false; @@ -1815,13 +1849,32 @@ WRITE32_MEMBER( sun4_state::dma_w ) COMBINE_DATA(&m_dma[DMA_CTRL]); if (data & DMA_RESET) + { + logerror("dma_w: reset\n"); m_dma[DMA_CTRL] &= ~(DMA_ERR_PEND | DMA_PACK_CNT | DMA_INT_EN | DMA_FLUSH | DMA_DRAIN | DMA_WRITE | DMA_EN_DMA | DMA_REQ_PEND | DMA_EN_CNT | DMA_TC); + } else if (data & DMA_FLUSH) { + logerror("dma_w: flush\n"); m_dma[DMA_CTRL] &= ~(DMA_PACK_CNT | DMA_ERR_PEND | DMA_TC); dma_check_interrupts(); } + else if (data & DMA_DRAIN) + { + m_dma[DMA_CTRL] &= ~DMA_DRAIN; + const uint8_t pack_cnt = (m_dma[DMA_CTRL] & DMA_PACK_CNT) >> DMA_PACK_CNT_SHIFT; + for (uint8_t i = 0; i < pack_cnt; i++) + { + const uint32_t bit_index = (3 - i) * 8; + const uint32_t value = m_dma_pack_register & (0xff << bit_index); + logerror("dma_w: draining %02x to RAM address %08x & %08x\n", value >> bit_index, m_dma[DMA_ADDR], 0xff << (24 - bit_index)); + write_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index); + m_dma[DMA_ADDR]++; + } + m_dma_pack_register = 0; + m_dma[DMA_CTRL] &= ~DMA_PACK_CNT; + } // TODO: DMA_DRAIN if (data & DMA_EN_DMA && (m_dma[DMA_CTRL] & DMA_REQ_PEND)) @@ -1878,6 +1931,75 @@ READ32_MEMBER( sun4_state::ss1_sl3_id ) return 0xfe010101; } +READ16_MEMBER( sun4_state::lance_r ) +{ + uint16_t ret = 0; + if (offset) + { + ret = m_lance_rap; + logerror("%s: lance_r: RAP = %04x\n", machine().describe_context(), ret); + } + else + { + ret = m_lance_csr[m_lance_rap]; + logerror("%s: lance_r: CSR%d = %04x\n", machine().describe_context(), m_lance_rap, ret); + } + return ret; +} + +WRITE16_MEMBER( sun4_state::lance_w ) +{ + if (offset) + { + logerror("%s: lance_r: RAP = %d\n", machine().describe_context(), data & 3); + m_lance_rap = data & 3; + } + else + { + logerror("%s: lance_w: CSR%d = %04x\n", machine().describe_context(), m_lance_rap, data); + switch (m_lance_rap) + { + case 0: // Control/Status + m_lance_csr[0] &= ~(data & (LANCE_CSR0_ANY_ERR | LANCE_CSR0_IDON)); + if (m_lance_csr[0] & LANCE_CSR0_ANY_ERR) + m_lance_csr[0] |= LANCE_CSR0_ERR; + else + m_lance_csr[0] &= ~LANCE_CSR0_ERR; + if (data & LANCE_CSR0_STOP) + { + data &= ~(LANCE_CSR0_RXON | LANCE_CSR0_TXON | LANCE_CSR0_TDMD | LANCE_CSR0_STRT | LANCE_CSR0_INIT); + m_lance_csr[0] &= ~(LANCE_CSR0_IDON | LANCE_CSR0_RXON | LANCE_CSR0_TXON | LANCE_CSR0_TDMD | LANCE_CSR0_STRT | LANCE_CSR0_INIT); + m_lance_csr[3] = 0; + } + if (data & LANCE_CSR0_INIT) + { + // TODO: Actually parse initialization block + m_lance_csr[0] &= ~LANCE_CSR0_STOP; + m_lance_csr[0] |= LANCE_CSR0_IDON | LANCE_CSR0_INIT; + } + if (data & LANCE_CSR0_STRT) + { + m_lance_csr[0] &= ~LANCE_CSR0_STOP; + m_lance_csr[0] |= (LANCE_CSR0_RXON | LANCE_CSR0_TXON | LANCE_CSR0_TINT | LANCE_CSR0_RINT); // TODO: Handle DTX/DRX in initialization block + } + if (data & (LANCE_CSR0_BABL | LANCE_CSR0_MISS | LANCE_CSR0_MERR | LANCE_CSR0_RINT | LANCE_CSR0_TINT | LANCE_CSR0_IDON)) + { + m_lance_csr[0] |= LANCE_CSR0_INTR; + } + break; + case 1: // Least significant 15 bits of the Initialization Block + m_lance_csr[1] = data & 0xfffe; + break; + case 2: // Most significant 8 bits of the Initialization Block + m_lance_csr[2] = data & 0x00ff; + break; + case 3: // Bus master interface + m_lance_csr[3] = data & 0x0007; + break; + } + } +} + FLOPPY_FORMATS_MEMBER( sun4_state::floppy_formats ) FLOPPY_PC_FORMAT FLOPPY_FORMATS_END @@ -1891,10 +2013,10 @@ static void sun_scsi_devices(device_slot_interface &device) { device.option_add("cdrom", NSCSI_CDROM); device.option_add("harddisk", NSCSI_HARDDISK); - device.option_add_internal("ncr5390", NCR5390); + device.option_add_internal("ncr53c90a", NCR53C90A); } -void sun4_state::ncr5390(device_t *device) +void sun4_state::ncr53c90a(device_t *device) { devcb_base *devcb; (void)devcb; @@ -1954,8 +2076,8 @@ MACHINE_CONFIG_START(sun4_state::sun4) MCFG_NSCSI_ADD("scsibus:4", sun_scsi_devices, nullptr, false) MCFG_NSCSI_ADD("scsibus:5", sun_scsi_devices, nullptr, false) MCFG_NSCSI_ADD("scsibus:6", sun_scsi_devices, nullptr, false) - MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr5390", true) - MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr5390", [this] (device_t *device) { ncr5390(device); }) + MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr53c90a", true) + MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); }) MACHINE_CONFIG_END MACHINE_CONFIG_START(sun4_state::sun4c) @@ -2008,8 +2130,8 @@ MACHINE_CONFIG_START(sun4_state::sun4c) MCFG_NSCSI_ADD("scsibus:4", sun_scsi_devices, nullptr, false) MCFG_NSCSI_ADD("scsibus:5", sun_scsi_devices, nullptr, false) MCFG_NSCSI_ADD("scsibus:6", sun_scsi_devices, nullptr, false) - MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr5390", true) - MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr5390", [this] (device_t *device) { ncr5390(device); }) + MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr53c90a", true) + MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); }) MCFG_SCREEN_ADD("bwtwo", RASTER) MCFG_SCREEN_UPDATE_DRIVER(sun4_state, bw2_update) -- cgit v1.2.3