From 489c6eaba005d75313354e0777e6e912dc701413 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Tue, 6 Nov 2018 23:01:52 +0100 Subject: [PATCH] hpc3: Fixed up and re-enabled audio DMA. Gets SGI Indy driver its boot chime back. [Ryan Holtz] --- src/mame/drivers/indy_indigo2.cpp | 37 ++- src/mame/machine/hpc3.cpp | 410 ++++++++++++------------------ src/mame/machine/hpc3.h | 21 +- 3 files changed, 206 insertions(+), 262 deletions(-) diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp index 5294ef68b9b..a7dec8acfd3 100644 --- a/src/mame/drivers/indy_indigo2.cpp +++ b/src/mame/drivers/indy_indigo2.cpp @@ -72,6 +72,7 @@ public: , m_mainram(*this, "mainram") , m_mem_ctrl(*this, "memctrl") , m_scsi_ctrl(*this, "wd33c93") + , m_dac(*this, "dac") , m_newport(*this, "newport") , m_hal2(*this, HAL2_TAG) , m_hpc3(*this, HPC3_TAG) @@ -90,6 +91,9 @@ private: virtual void machine_start() override; virtual void machine_reset() override; + DECLARE_READ32_MEMBER(enet_r); + DECLARE_WRITE32_MEMBER(enet_w); + DECLARE_WRITE32_MEMBER(ip22_write_ram); void ip225015_map(address_map &map); @@ -105,6 +109,7 @@ private: required_shared_ptr m_mainram; required_device m_mem_ctrl; required_device m_scsi_ctrl; + required_device m_dac; required_device m_newport; required_device m_hal2; required_device m_hpc3; @@ -134,6 +139,29 @@ inline void ATTR_PRINTF(3,4) ip22_state::verboselog(int n_level, const char *s_f } } +READ32_MEMBER(ip22_state::enet_r) +{ + switch (offset) + { + case 0x000/4: + logerror("%s: enet_r: Read MAC Address bytes 0-3, 0x80675309 & %08x\n", machine().describe_context(), mem_mask); + return 0x80675309; + default: + logerror("%s: enet_r: Read Unknown Register %08x & %08x\n", machine().describe_context(), 0x1fbd4000 + (offset << 2), mem_mask); + return 0; + } +} + +WRITE32_MEMBER(ip22_state::enet_w) +{ + switch (offset) + { + default: + logerror("%s: enet_w: Write Unknown Register %08x = %08x & %08x\n", machine().describe_context(), 0x1fbd4000 + (offset << 2), data, mem_mask); + break; + } +} + // a bit hackish, but makes the memory detection work properly and allows a big cleanup of the mapping WRITE32_MEMBER(ip22_state::ip22_write_ram) { @@ -164,6 +192,7 @@ void ip22_state::ip225015_map(address_map &map) map(0x1fbc0000, 0x1fbc7fff).rw(m_hpc3, FUNC(hpc3_device::hd0_r), FUNC(hpc3_device::hd0_w)); map(0x1fbc8000, 0x1fbcffff).rw(m_hpc3, FUNC(hpc3_device::unkpbus0_r), FUNC(hpc3_device::unkpbus0_w)).share("unkpbus0"); map(0x1fb80000, 0x1fb8ffff).rw(m_hpc3, FUNC(hpc3_device::pbusdma_r), FUNC(hpc3_device::pbusdma_w)); + map(0x1fbd4000, 0x1fbd44ff).rw(FUNC(ip22_state::enet_r), FUNC(ip22_state::enet_w)); map(0x1fbd8000, 0x1fbd83ff).rw(m_hal2, FUNC(hal2_device::read), FUNC(hal2_device::write)); map(0x1fbd8400, 0x1fbd87ff).ram(); /* hack */ map(0x1fbd9000, 0x1fbd93ff).rw(m_hpc3, FUNC(hpc3_device::pbus4_r), FUNC(hpc3_device::pbus4_w)); @@ -230,9 +259,9 @@ void ip22_state::ip225015(machine_config &config) SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - dac_16bit_r2r_twos_complement_device &dac(DAC_16BIT_R2R_TWOS_COMPLEMENT(config, "dac", 0)); - dac.add_route(ALL_OUTPUTS, "lspeaker", 0.25); - dac.add_route(ALL_OUTPUTS, "rspeaker", 0.25); + DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac, 0); + m_dac->add_route(ALL_OUTPUTS, "lspeaker", 0.25); + m_dac->add_route(ALL_OUTPUTS, "rspeaker", 0.25); voltage_regulator_device &vreg = VOLTAGE_REGULATOR(config, "vref"); vreg.set_output(5.0); @@ -250,7 +279,7 @@ void ip22_state::ip225015(machine_config &config) SGI_HAL2(config, m_hal2); SGI_IOC2_GUINNESS(config, m_ioc2, m_maincpu); - SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl, m_ioc2); + SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl, m_ioc2, m_dac); DS1386_8K(config, m_rtc, 32768); MACHINE_CONFIG_END diff --git a/src/mame/machine/hpc3.cpp b/src/mame/machine/hpc3.cpp index 644060942b4..e1c11332e4e 100644 --- a/src/mame/machine/hpc3.cpp +++ b/src/mame/machine/hpc3.cpp @@ -16,28 +16,31 @@ hpc3_device::hpc3_device(const machine_config &mconfig, const char *tag, device_ , m_maincpu(*this, finder_base::DUMMY_TAG) , m_wd33c93(*this, finder_base::DUMMY_TAG) , m_ioc2(*this, finder_base::DUMMY_TAG) + , m_dac(*this, finder_base::DUMMY_TAG) , m_mainram(*this, ":mainram") , m_unkpbus0(*this, ":unkpbus0") { } -#define VERBOSE_LEVEL ( 0 ) +#define VERBOSE_LEVEL (0) -inline void ATTR_PRINTF(3,4) hpc3_device::verboselog(int n_level, const char *s_fmt, ... ) +inline void ATTR_PRINTF(3,4) hpc3_device::verboselog(int n_level, const char *s_fmt, ...) { - if( VERBOSE_LEVEL >= n_level ) + if (VERBOSE_LEVEL >= n_level) { va_list v; - char buf[ 32768 ]; - va_start( v, s_fmt ); - vsprintf( buf, s_fmt, v ); - va_end( v ); + char buf[32768]; + va_start(v, s_fmt); + vsprintf(buf, s_fmt, v); + va_end(v); logerror("%s: %s", machine().describe_context(), buf); } } void hpc3_device::device_start() { + m_pbus_dma_timer = timer_alloc(TIMER_PBUS_DMA); + m_pbus_dma_timer->adjust(attotime::never); } void hpc3_device::device_reset() @@ -45,13 +48,14 @@ void hpc3_device::device_reset() m_enetr_nbdp = 0x80000000; m_enetr_cbp = 0x80000000; m_pbus_dma.m_active = 0; + m_pbus_dma_timer->adjust(attotime::never); } void hpc3_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { switch (id) { - case TIMER_DMA: + case TIMER_PBUS_DMA: do_dma(ptr, param); break; default: @@ -61,26 +65,31 @@ void hpc3_device::device_timer(emu_timer &timer, device_timer_id id, int param, TIMER_CALLBACK_MEMBER(hpc3_device::do_dma) { - timer_set(attotime::never, TIMER_DMA); -#if 0 - if( m_pbus_dma.m_active ) + m_pbus_dma_timer->adjust(attotime::never); + + if (m_pbus_dma.m_active) { - uint16_t temp16 = ( m_mainram[(m_pbus_dma.m_cur_ptr - 0x08000000)/4] & 0xffff0000 ) >> 16; + address_space &space = m_maincpu->space(AS_PROGRAM); + uint16_t temp16 = space.read_dword(m_pbus_dma.m_cur_ptr) >> 16; int16_t stemp16 = (int16_t)((temp16 >> 8) | (temp16 << 8)); - m_dac->write_signed16(stemp16); + m_dac->write(stemp16); m_pbus_dma.m_cur_ptr += 4; - m_pbus_dma.m_words_left -= 4; - if( m_pbus_dma.m_words_left == 0 ) + + if (m_pbus_dma.m_words_left == 0) { - if( m_pbus_dma.m_next_ptr != 0 ) + if (m_pbus_dma.m_next_ptr != 0) { m_pbus_dma.m_desc_ptr = m_pbus_dma.m_next_ptr; - m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4]; - m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1]; - m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2]; + logerror("Next PBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr); fflush(stdout); + m_pbus_dma.m_cur_ptr = space.read_dword(m_pbus_dma.m_desc_ptr); + m_pbus_dma.m_words_left = space.read_dword(m_pbus_dma.m_desc_ptr + 4); + m_pbus_dma.m_next_ptr = space.read_dword(m_pbus_dma.m_desc_ptr + 8); + logerror("Next PBUS_DMA_CurPtr = %08x\n", m_pbus_dma.m_cur_ptr); fflush(stdout); + logerror("Next PBUS_DMA_WordsLeft = %08x\n", m_pbus_dma.m_words_left); fflush(stdout); + logerror("Next PBUS_DMA_NextPtr = %08x\n", m_pbus_dma.m_next_ptr); fflush(stdout); } else { @@ -88,69 +97,68 @@ TIMER_CALLBACK_MEMBER(hpc3_device::do_dma) return; } } - timer_set(attotime::from_hz(44100), TIMER_DMA); + m_pbus_dma_timer->adjust(attotime::from_hz(44100)); } -#endif } READ32_MEMBER(hpc3_device::hd_enet_r) { - switch( offset ) + switch (offset) { case 0x0004/4: - //verboselog((machine, 0, "HPC3 SCSI0DESC Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_scsi0_desc ); + //verboselog(machine, 0, "HPC3 SCSI0DESC Read: %08x (%08x): %08x\n", 0x1fb90000 + (offset << 2), mem_mask, m_scsi0_desc); return m_scsi0_desc; case 0x1004/4: - //verboselog((machine, 0, "HPC3 SCSI0DMACTRL Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_scsi0_dma_ctrl ); + //verboselog(machine, 0, "HPC3 SCSI0DMACTRL Read: %08x (%08x): %08x\n", 0x1fb90000 + (offset << 2), mem_mask, m_scsi0_dma_ctrl); return m_scsi0_dma_ctrl; case 0x4000/4: - //verboselog((machine, 2, "HPC3 ENETR CBP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_enetr_nbdp ); + //verboselog(machine, 2, "HPC3 ENETR CBP Read: %08x (%08x): %08x\n", 0x1fb90000 + (offset << 2), mem_mask, m_enetr_nbdp); return m_enetr_cbp; case 0x4004/4: - //verboselog((machine, 2, "HPC3 ENETR NBDP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_enetr_nbdp ); + //verboselog(machine, 2, "HPC3 ENETR NBDP Read: %08x (%08x): %08x\n", 0x1fb90000 + (offset << 2), mem_mask, m_enetr_nbdp); return m_enetr_nbdp; default: - //verboselog((machine, 0, "Unknown HPC3 ENET/HDx Read: %08x (%08x)\n", 0x1fb90000 + ( offset << 2 ), mem_mask ); + //verboselog(machine, 0, "Unknown HPC3 ENET/HDx Read: %08x (%08x)\n", 0x1fb90000 + (offset << 2), mem_mask); return 0; } } WRITE32_MEMBER(hpc3_device::hd_enet_w) { - switch( offset ) + switch (offset) { case 0x0004/4: - //verboselog((machine, 2, "HPC3 SCSI0DESC Write: %08x\n", data ); + //verboselog(machine, 2, "HPC3 SCSI0DESC Write: %08x\n", data); m_scsi0_desc = data; break; case 0x1004/4: - //verboselog((machine, 2, "HPC3 SCSI0DMACTRL Write: %08x\n", data ); + //verboselog(machine, 2, "HPC3 SCSI0DMACTRL Write: %08x\n", data); m_scsi0_dma_ctrl = data; break; case 0x4000/4: - //verboselog((machine, 2, "HPC3 ENETR CBP Write: %08x\n", data ); + //verboselog(machine, 2, "HPC3 ENETR CBP Write: %08x\n", data); m_enetr_cbp = data; break; case 0x4004/4: - //verboselog((machine, 2, "HPC3 ENETR NBDP Write: %08x\n", data ); + //verboselog(machine, 2, "HPC3 ENETR NBDP Write: %08x\n", data); m_enetr_nbdp = data; break; default: - //verboselog((machine, 0, "Unknown HPC3 ENET/HDx write: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2 ), mem_mask, data ); + //verboselog(machine, 0, "Unknown HPC3 ENET/HDx write: %08x (%08x): %08x\n", 0x1fb90000 + (offset << 2), mem_mask, data); break; } } READ32_MEMBER(hpc3_device::hd0_r) { - switch( offset ) + switch (offset) { case 0x0000/4: case 0x4000/4: -// //verboselog((machine, 2, "HPC3 HD0 Status Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[0x17] ); +// //verboselog(machine, 2, "HPC3 HD0 Status Read: %08x (%08x): %08x\n", 0x1fb90000 + (offset << 2), mem_mask, nHPC3_hd0_regs[0x17]); if (ACCESSING_BITS_0_7) { - return m_wd33c93->read( space, 0 ); + return m_wd33c93->read(space, 0); } else { @@ -158,43 +166,43 @@ READ32_MEMBER(hpc3_device::hd0_r) } case 0x0004/4: case 0x4004/4: -// //verboselog((machine, 2, "HPC3 HD0 Register Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[nHPC3_hd0_register] ); +// //verboselog(machine, 2, "HPC3 HD0 Register Read: %08x (%08x): %08x\n", 0x1fb90000 + (offset << 2), mem_mask, nHPC3_hd0_regs[nHPC3_hd0_register]); if (ACCESSING_BITS_0_7) { - return m_wd33c93->read( space, 1 ); + return m_wd33c93->read(space, 1); } else { return 0; } default: - //verboselog((machine, 0, "Unknown HPC3 HD0 Read: %08x (%08x) [%x] PC=%x\n", 0x1fbc0000 + ( offset << 2 ), mem_mask, offset, m_maincpu->pc() ); + //verboselog(machine, 0, "Unknown HPC3 HD0 Read: %08x (%08x) [%x] PC=%x\n", 0x1fbc0000 + (offset << 2), mem_mask, offset, m_maincpu->pc()); return 0; } } WRITE32_MEMBER(hpc3_device::hd0_w) { - switch( offset ) + switch (offset) { case 0x0000/4: case 0x4000/4: -// //verboselog((machine, 2, "HPC3 HD0 Register Select Write: %08x\n", data ); +// //verboselog(machine, 2, "HPC3 HD0 Register Select Write: %08x\n", data); if (ACCESSING_BITS_0_7) { - m_wd33c93->write( space, 0, data & 0x000000ff ); + m_wd33c93->write(space, 0, data & 0x000000ff); } break; case 0x0004/4: case 0x4004/4: -// //verboselog((machine, 2, "HPC3 HD0 Register %d Write: %08x\n", nHPC3_hd0_register, data ); +// //verboselog(machine, 2, "HPC3 HD0 Register %d Write: %08x\n", nHPC3_hd0_register, data); if (ACCESSING_BITS_0_7) { - m_wd33c93->write( space, 1, data & 0x000000ff ); + m_wd33c93->write(space, 1, data & 0x000000ff); } break; default: - //verboselog((machine, 0, "Unknown HPC3 HD0 Write: %08x (%08x): %08x\n", 0x1fbc0000 + ( offset << 2 ), mem_mask, data ); + //verboselog(machine, 0, "Unknown HPC3 HD0 Write: %08x (%08x): %08x\n", 0x1fbc0000 + (offset << 2), mem_mask, data); break; } } @@ -202,41 +210,41 @@ WRITE32_MEMBER(hpc3_device::hd0_w) READ32_MEMBER(hpc3_device::pbus4_r) { - switch( offset ) + switch (offset) { case 0x0004/4: - //verboselog((machine, 2, "HPC3 PBUS4 Unknown 0 Read: (%08x): %08x\n", mem_mask, m_unk0 ); + //verboselog(machine, 2, "HPC3 PBUS4 Unknown 0 Read: (%08x): %08x\n", mem_mask, m_unk0); return m_unk0; case 0x000c/4: - //verboselog((machine, 2, "Interrupt Controller(?) Read: (%08x): %08x\n", mem_mask, m_ic_unk0 ); + //verboselog(machine, 2, "Interrupt Controller(?) Read: (%08x): %08x\n", mem_mask, m_ic_unk0); return m_ic_unk0; case 0x0014/4: - //verboselog((machine, 2, "HPC3 PBUS4 Unknown 1 Read: (%08x): %08x\n", mem_mask, m_unk1 ); + //verboselog(machine, 2, "HPC3 PBUS4 Unknown 1 Read: (%08x): %08x\n", mem_mask, m_unk1); return m_unk1; default: - //verboselog((machine, 0, "Unknown HPC3 PBUS4 Read: %08x (%08x)\n", 0x1fbd9000 + ( offset << 2 ), mem_mask ); + //verboselog(machine, 0, "Unknown HPC3 PBUS4 Read: %08x (%08x)\n", 0x1fbd9000 + (offset << 2), mem_mask); return 0; } } WRITE32_MEMBER(hpc3_device::pbus4_w) { - switch( offset ) + switch (offset) { case 0x0004/4: - //verboselog((machine, 2, "HPC3 PBUS4 Unknown 0 Write: %08x (%08x)\n", data, mem_mask ); + //verboselog(machine, 2, "HPC3 PBUS4 Unknown 0 Write: %08x (%08x)\n", data, mem_mask); m_unk0 = data; break; case 0x000c/4: - //verboselog((machine, 2, "Interrupt Controller(?) Write: (%08x): %08x\n", mem_mask, data ); + //verboselog(machine, 2, "Interrupt Controller(?) Write: (%08x): %08x\n", mem_mask, data); m_ic_unk0 = data; break; case 0x0014/4: - //verboselog((machine, 2, "HPC3 PBUS4 Unknown 1 Write: %08x (%08x)\n", data, mem_mask ); + //verboselog(machine, 2, "HPC3 PBUS4 Unknown 1 Write: %08x (%08x)\n", data, mem_mask); m_unk1 = data; break; default: - //verboselog((machine, 0, "Unknown HPC3 PBUS4 Write: %08x (%08x): %08x\n", 0x1fbd9000 + ( offset << 2 ), mem_mask, data ); + //verboselog(machine, 0, "Unknown HPC3 PBUS4 Write: %08x (%08x): %08x\n", 0x1fbd9000 + (offset << 2), mem_mask, data); break; } } @@ -244,7 +252,7 @@ WRITE32_MEMBER(hpc3_device::pbus4_w) READ32_MEMBER(hpc3_device::pbusdma_r) { //uint32_t channel = offset / (0x2000/4); - //verboselog((machine(), 0, "PBUS DMA Channel %d Read: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, mem_mask ); + //verboselog(machine(), 0, "PBUS DMA Channel %d Read: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, mem_mask); return 0; } @@ -252,78 +260,78 @@ WRITE32_MEMBER(hpc3_device::pbusdma_w) { uint32_t channel = offset / (0x2000/4); - switch( offset & 0x07ff ) + switch (offset & 0x07ff) { case 0x0000/4: - //verboselog((machine, 0, "PBUS DMA Channel %d Buffer Pointer Write: 0x%08x\n", channel, data ); + //verboselog(machine, 0, "PBUS DMA Channel %d Buffer Pointer Write: 0x%08x\n", channel, data); return; case 0x0004/4: - //verboselog((machine, 0, "PBUS DMA Channel %d Descriptor Pointer Write: 0x%08x\n", channel, data ); - if( channel == 1 ) + //verboselog(machine, 0, "PBUS DMA Channel %d Descriptor Pointer Write: 0x%08x\n", channel, data); + if (channel == 1) { m_pbus_dma.m_desc_ptr = data; - m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4]; - m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1]; - m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2]; - //verboselog((machine, 0, "nPBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr ); - //verboselog((machine, 0, "nPBUS_DMA_CurPtr = %08x\n", m_pbus_dma.m_cur_ptr ); - //verboselog((machine, 0, "nPBUS_DMA_WordsLeft = %08x\n", m_pbus_dma.m_words_left ); - //verboselog((machine, 0, "nPBUS_DMA_NextPtr = %08x\n", m_pbus_dma.m_next_ptr ); + logerror("PBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr); fflush(stdout); + m_pbus_dma.m_cur_ptr = space.read_dword(m_pbus_dma.m_desc_ptr); + m_pbus_dma.m_words_left = space.read_dword(m_pbus_dma.m_desc_ptr + 4); + m_pbus_dma.m_next_ptr = space.read_dword(m_pbus_dma.m_desc_ptr + 8); + logerror("PBUS_DMA_CurPtr = %08x\n", m_pbus_dma.m_cur_ptr); fflush(stdout); + logerror("PBUS_DMA_WordsLeft = %08x\n", m_pbus_dma.m_words_left); fflush(stdout); + logerror("PBUS_DMA_NextPtr = %08x\n", m_pbus_dma.m_next_ptr); fflush(stdout); } return; case 0x1000/4: - //verboselog((machine, 0, "PBUS DMA Channel %d Control Register Write: 0x%08x\n", channel, data ); - if( data & PBUS_CTRL_ENDIAN ) + logerror("PBUS DMA Channel %d Control Register Write: 0x%08x\n", channel, data); + if (data & PBUS_CTRL_ENDIAN) { - //verboselog((machine, 0, " Little Endian\n" ); + logerror(" Little Endian\n"); } else { - //verboselog((machine, 0, " Big Endian\n" ); + logerror(" Big Endian\n"); } - if( data & PBUS_CTRL_RECV ) + if (data & PBUS_CTRL_RECV) { - //verboselog((machine, 0, " RX DMA\n" ); + logerror(" RX DMA\n"); } else { - //verboselog((machine, 0, " TX DMA\n" ); + logerror(" TX DMA\n"); } - if( data & PBUS_CTRL_FLUSH ) + if (data & PBUS_CTRL_FLUSH) { - //verboselog((machine, 0, " Flush for RX\n" ); + logerror(" Flush for RX\n"); } - if( data & PBUS_CTRL_DMASTART ) + if (data & PBUS_CTRL_DMASTART) { - //verboselog((machine, 0, " Start DMA\n" ); + logerror(" Start DMA\n"); } - if( data & PBUS_CTRL_LOAD_EN ) + if (data & PBUS_CTRL_LOAD_EN) { - //verboselog((machine, 0, " Load Enable\n" ); + logerror(" Load Enable\n"); } - //verboselog((machine, 0, " High Water Mark: %04x bytes\n", ( data & PBUS_CTRL_HIGHWATER ) >> 8 ); - //verboselog((machine, 0, " FIFO Begin: Row %04x\n", ( data & PBUS_CTRL_FIFO_BEG ) >> 16 ); - //verboselog((machine, 0, " FIFO End: Rowe %04x\n", ( data & PBUS_CTRL_FIFO_END ) >> 24 ); - if( ( data & PBUS_CTRL_DMASTART ) || ( data & PBUS_CTRL_LOAD_EN ) ) + logerror(" High Water Mark: %04x bytes\n", (data & PBUS_CTRL_HIGHWATER) >> 8); + logerror(" FIFO Begin: Row %04x\n", (data & PBUS_CTRL_FIFO_BEG) >> 16); + logerror(" FIFO End: Rowe %04x\n", (data & PBUS_CTRL_FIFO_END) >> 24); + if ((data & PBUS_CTRL_DMASTART) || (data & PBUS_CTRL_LOAD_EN)) { - timer_set(attotime::from_hz(44100), TIMER_DMA); + m_pbus_dma_timer->adjust(attotime::from_hz(44100)); m_pbus_dma.m_active = 1; } return; } - //verboselog((machine, 0, "Unknown PBUS DMA Channel %d Write: 0x%08x: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, data, mem_mask ); + logerror("Unknown PBUS DMA Channel %d Write: 0x%08x: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, data, mem_mask); } READ32_MEMBER(hpc3_device::unkpbus0_r) { return 0; - ////verboselog((machine(), 0, "Unknown PBUS Read: 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, mem_mask ); + //logerror("Unknown PBUS Read: 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, mem_mask); //return m_unkpbus0[offset]; } WRITE32_MEMBER(hpc3_device::unkpbus0_w) { - ////verboselog((machine(), 0, "Unknown PBUS Write: 0x%08x = 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, data, mem_mask ); + //logerror("Unknown PBUS Write: 0x%08x = 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, data, mem_mask); //COMBINE_DATA(&m_unkpbus0[offset]); } @@ -337,6 +345,30 @@ void hpc3_device::dump_chain(address_space &space, uint32_t ch_base) } } +void hpc3_device::fetch_chain(address_space &space) +{ + m_scsi0_addr = space.read_dword(m_scsi0_desc); + m_scsi0_flags = space.read_dword(m_scsi0_desc+4); + m_scsi0_byte_count = m_scsi0_flags & 0x3fff; + m_scsi0_next_addr = space.read_dword(m_scsi0_desc+8); + //logerror("Fetching chain from %08x: %08x %08x %08x (length %04x)\n", m_scsi0_desc, m_scsi0_addr, m_scsi0_flags, m_scsi0_next_addr, m_scsi0_byte_count); +} + +bool hpc3_device::decrement_chain(address_space &space) +{ + m_scsi0_byte_count--; + if (m_scsi0_byte_count == 0) + { + if (BIT(m_scsi0_flags, 31)) + { + return false; + } + m_scsi0_desc = m_scsi0_next_addr; + fetch_chain(space); + } + return true; +} + WRITE_LINE_MEMBER(hpc3_device::scsi_irq) { address_space &space = m_maincpu->space(AS_PROGRAM); @@ -345,219 +377,95 @@ WRITE_LINE_MEMBER(hpc3_device::scsi_irq) { if (m_wd33c93->get_dma_count()) { - logerror("m_wd33c93->get_dma_count() is %d\n", m_wd33c93->get_dma_count() ); + //logerror("m_wd33c93->get_dma_count() is %d\n", m_wd33c93->get_dma_count()); if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) { if (m_scsi0_dma_ctrl & HPC3_DMACTRL_IRQ) logerror("IP22: Unhandled SCSI DMA IRQ\n"); } + bool big_endian = (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN); if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) { if (m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR) { // HPC3 DMA: host to device - int words = (m_wd33c93->get_dma_count() + 3) / 4; + int byte_count = m_wd33c93->get_dma_count(); + //dump_chain(space, m_scsi0_desc); + fetch_chain(space); - uint32_t srcoffs = space.read_dword(m_scsi0_desc); - m_scsi0_desc += words * 4; + //logerror("DMA to device: %d bytes @ %x\n", byte_count, m_scsi0_addr); - logerror("DMA to device: %d words @ %x\n", words, srcoffs); - - dump_chain(space, m_scsi0_desc); - - if (words <= (512/4)) + if (byte_count <= 512) { - int dstoffs = 0; - if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN) + for (int i = 0; i < byte_count; i++) { - for (int i = 0; i < words; i++) - { - uint32_t tmpword = space.read_dword(srcoffs); - m_dma_buffer[dstoffs+3] = (tmpword >> 24) & 0xff; - m_dma_buffer[dstoffs+2] = (tmpword >> 16) & 0xff; - m_dma_buffer[dstoffs+1] = (tmpword >> 8) & 0xff; - m_dma_buffer[dstoffs] = tmpword & 0xff; - srcoffs += 4; - dstoffs += 4; - } - } - else - { - for (int i = 0; i < words; i++) - { - uint32_t tmpword = space.read_dword(srcoffs); - m_dma_buffer[dstoffs] = (tmpword >> 24) & 0xff; - m_dma_buffer[dstoffs+1] = (tmpword >> 16) & 0xff; - m_dma_buffer[dstoffs+2] = (tmpword >> 8) & 0xff; - m_dma_buffer[dstoffs+3] = tmpword & 0xff; - srcoffs += 4; - dstoffs += 4; - } + m_dma_buffer[big_endian ? BYTE4_XOR_BE(i) : BYTE4_XOR_LE(i)] = space.read_byte(m_scsi0_addr+i); + if (!decrement_chain(space)) + break; } - m_wd33c93->dma_write_data(m_wd33c93->get_dma_count(), m_dma_buffer); + m_wd33c93->dma_write_data(byte_count, m_dma_buffer); } else { - while (words) + int dstoffs = 0; + while (byte_count) { - int twords = std::min(512/4, words); - m_scsi0_desc += twords*4; + int sub_count = std::min(512, byte_count); - int dstoffs = 0; - if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN) + for (int i = 0; i < sub_count; i++) { - for (int i = 0; i < twords; i++) - { - uint32_t tmpword = space.read_dword(srcoffs); - m_dma_buffer[dstoffs+3] = (tmpword >> 24) & 0xff; - m_dma_buffer[dstoffs+2] = (tmpword >> 16) & 0xff; - m_dma_buffer[dstoffs+1] = (tmpword >> 8) & 0xff; - m_dma_buffer[dstoffs] = tmpword & 0xff; - dstoffs += 4; - srcoffs += 4; - } - } - else - { - for (int i = 0; i < twords; i++) - { - uint32_t tmpword = space.read_dword(srcoffs); - m_dma_buffer[dstoffs] = (tmpword >> 24) & 0xff; - m_dma_buffer[dstoffs+1] = (tmpword >> 16) & 0xff; - m_dma_buffer[dstoffs+2] = (tmpword >> 8) & 0xff; - m_dma_buffer[dstoffs+3] = tmpword & 0xff; - dstoffs += 4; - srcoffs += 4; - } + m_dma_buffer[big_endian ? BYTE4_XOR_BE(dstoffs+i) : BYTE4_XOR_LE(dstoffs+i)] = space.read_byte(m_scsi0_addr); + m_scsi0_addr++; + if (!decrement_chain(space)) + break; } - m_wd33c93->dma_write_data(512, m_dma_buffer); + m_wd33c93->dma_write_data(sub_count, m_dma_buffer); - words -= (512/4); + byte_count -= sub_count; } } // clear DMA on the controller too m_wd33c93->clear_dma(); -#if 0 - uint32_t dptr, tmpword; - uint32_t bc = space.read_dword(m_scsi0_desc + 4); - uint32_t rptr = space.read_dword(m_scsi0_desc); - int length = bc & 0x3fff; - int xie = (bc & 0x20000000) ? 1 : 0; - int eox = (bc & 0x80000000) ? 1 : 0; - - dump_chain(space, m_scsi0_desc); - - logerror("%s DMA to device: length %x xie %d eox %d\n", machine().describe_context().c_str(), length, xie, eox); - - if (length <= 0x4000) - { - dptr = 0; - while (length > 0) - { - tmpword = space.read_dword(rptr); - if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN) - { - m_dma_buffer[dptr+3] = (tmpword>>24)&0xff; - m_dma_buffer[dptr+2] = (tmpword>>16)&0xff; - m_dma_buffer[dptr+1] = (tmpword>>8)&0xff; - m_dma_buffer[dptr] = tmpword&0xff; - } - else - { - m_dma_buffer[dptr] = (tmpword>>24)&0xff; - m_dma_buffer[dptr+1] = (tmpword>>16)&0xff; - m_dma_buffer[dptr+2] = (tmpword>>8)&0xff; - m_dma_buffer[dptr+3] = tmpword&0xff; - } - - dptr += 4; - rptr += 4; - length -= 4; - } - - length = space.read_dword(m_scsi0_desc+4) & 0x3fff; - m_wd33c93->write_data(length, m_dma_buffer); - - // clear DMA on the controller too - m_wd33c93->clear_dma(); - } - else - { - logerror("IP22: overly large host to device transfer, can't handle!\n"); - } -#endif } else { // HPC3 DMA: device to host - int words = (m_wd33c93->get_dma_count() + 3) / 4; - - uint32_t dstoffs = space.read_dword(m_scsi0_desc); + int byte_count = m_wd33c93->get_dma_count(); + //dump_chain(space, m_scsi0_desc); + fetch_chain(space); // logerror("DMA from device: %d words @ %x\n", words, dstoffs); - dump_chain(space, m_scsi0_desc); - - if (words < (512/4)) + if (byte_count < 512) { - // one-shot - m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer); + m_wd33c93->dma_read_data(byte_count, m_dma_buffer); - int srcoffs = 0; - if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN) + for (int i = 0; i < byte_count; i++) { - for (int i = 0; i < words; i++) - { - uint32_t tmpword = m_dma_buffer[srcoffs+3]<<24 | m_dma_buffer[srcoffs+2]<<16 | m_dma_buffer[srcoffs+1]<<8 | m_dma_buffer[srcoffs]; - space.write_dword(dstoffs, tmpword); - dstoffs += 4; - srcoffs += 4; - } - } - else - { - for (int i = 0; i < words; i++) - { - uint32_t tmpword = m_dma_buffer[srcoffs]<<24 | m_dma_buffer[srcoffs+1]<<16 | m_dma_buffer[srcoffs+2]<<8 | m_dma_buffer[srcoffs+3]; - space.write_dword(dstoffs, tmpword); - dstoffs += 4; - srcoffs += 4; - } + space.write_byte(big_endian ? BYTE4_XOR_BE(m_scsi0_addr+i) : BYTE4_XOR_LE(m_scsi0_addr+i), m_dma_buffer[i]); + if (!decrement_chain(space)) + break; } } else { - while (words) + while (byte_count) { - int length = (m_wd33c93->dma_read_data(512, m_dma_buffer) + 3) / 4; + int sub_count = m_wd33c93->dma_read_data(512, m_dma_buffer); - int srcoffs = 0; - if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN) + for (int i = 0; i < sub_count; i++) { - for (uint32_t i = 0; i < length; i++) - { - uint32_t tmpword = m_dma_buffer[srcoffs+3]<<24 | m_dma_buffer[srcoffs+2]<<16 | m_dma_buffer[srcoffs+1]<<8 | m_dma_buffer[srcoffs]; - space.write_dword(dstoffs, tmpword); - dstoffs += 4; - srcoffs += 4; - } - } - else - { - for (uint32_t i = 0; i < length; i++) - { - uint32_t tmpword = m_dma_buffer[srcoffs]<<24 | m_dma_buffer[srcoffs+1]<<16 | m_dma_buffer[srcoffs+2]<<8 | m_dma_buffer[srcoffs+3]; - space.write_dword(dstoffs, tmpword); - dstoffs += 4; - srcoffs += 4; - } + space.write_byte(big_endian ? BYTE4_XOR_BE(m_scsi0_addr) : BYTE4_XOR_LE(m_scsi0_addr), m_dma_buffer[i]); + m_scsi0_addr++; + if (!decrement_chain(space)) + break; } - words -= (512/4); + byte_count -= sub_count; } } diff --git a/src/mame/machine/hpc3.h b/src/mame/machine/hpc3.h index b9c47db8a9c..b46c3068420 100644 --- a/src/mame/machine/hpc3.h +++ b/src/mame/machine/hpc3.h @@ -14,17 +14,19 @@ #include "cpu/mips/mips3.h" #include "machine/ioc2.h" #include "machine/wd33c93.h" +#include "sound/dac.h" class hpc3_device : public device_t { public: - template - hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&scsi_tag, V &&ioc2_tag) + template + hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&scsi_tag, V &&ioc2_tag, W &&dac_tag) : hpc3_device(mconfig, tag, owner, (uint32_t)0) { m_maincpu.set_tag(std::forward(cpu_tag)); m_wd33c93.set_tag(std::forward(scsi_tag)); m_ioc2.set_tag(std::forward(ioc2_tag)); + m_dac.set_tag(std::forward(dac_tag)); } hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -50,6 +52,10 @@ protected: void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; void dump_chain(address_space &space, uint32_t ch_base); + void fetch_chain(address_space &space); + bool decrement_chain(address_space &space); + + static const device_timer_id TIMER_PBUS_DMA = 0; struct pbus_dma_t { @@ -60,11 +66,6 @@ protected: uint32_t m_words_left; }; - enum - { - TIMER_DMA - }; - enum { PBUS_CTRL_ENDIAN = 0x00000002, @@ -99,6 +100,7 @@ protected: required_device m_maincpu; required_device m_wd33c93; required_device m_ioc2; + required_device m_dac; required_shared_ptr m_mainram; required_shared_ptr m_unkpbus0; @@ -108,8 +110,13 @@ protected: uint32_t m_unk1; uint32_t m_ic_unk0; uint32_t m_scsi0_desc; + uint32_t m_scsi0_addr; + uint32_t m_scsi0_flags; + uint32_t m_scsi0_byte_count; + uint32_t m_scsi0_next_addr; uint32_t m_scsi0_dma_ctrl; pbus_dma_t m_pbus_dma; + emu_timer *m_pbus_dma_timer; uint8_t m_dma_buffer[4096];