mirror of
https://github.com/holub/mame
synced 2025-10-08 09:30:17 +03:00
hpc3: Fixed up and re-enabled audio DMA. Gets SGI Indy driver its boot chime back. [Ryan Holtz]
This commit is contained in:
parent
35d42f82f8
commit
489c6eaba0
@ -72,6 +72,7 @@ public:
|
|||||||
, m_mainram(*this, "mainram")
|
, m_mainram(*this, "mainram")
|
||||||
, m_mem_ctrl(*this, "memctrl")
|
, m_mem_ctrl(*this, "memctrl")
|
||||||
, m_scsi_ctrl(*this, "wd33c93")
|
, m_scsi_ctrl(*this, "wd33c93")
|
||||||
|
, m_dac(*this, "dac")
|
||||||
, m_newport(*this, "newport")
|
, m_newport(*this, "newport")
|
||||||
, m_hal2(*this, HAL2_TAG)
|
, m_hal2(*this, HAL2_TAG)
|
||||||
, m_hpc3(*this, HPC3_TAG)
|
, m_hpc3(*this, HPC3_TAG)
|
||||||
@ -90,6 +91,9 @@ private:
|
|||||||
virtual void machine_start() override;
|
virtual void machine_start() override;
|
||||||
virtual void machine_reset() override;
|
virtual void machine_reset() override;
|
||||||
|
|
||||||
|
DECLARE_READ32_MEMBER(enet_r);
|
||||||
|
DECLARE_WRITE32_MEMBER(enet_w);
|
||||||
|
|
||||||
DECLARE_WRITE32_MEMBER(ip22_write_ram);
|
DECLARE_WRITE32_MEMBER(ip22_write_ram);
|
||||||
|
|
||||||
void ip225015_map(address_map &map);
|
void ip225015_map(address_map &map);
|
||||||
@ -105,6 +109,7 @@ private:
|
|||||||
required_shared_ptr<uint32_t> m_mainram;
|
required_shared_ptr<uint32_t> m_mainram;
|
||||||
required_device<sgi_mc_device> m_mem_ctrl;
|
required_device<sgi_mc_device> m_mem_ctrl;
|
||||||
required_device<wd33c93_device> m_scsi_ctrl;
|
required_device<wd33c93_device> m_scsi_ctrl;
|
||||||
|
required_device<dac_16bit_r2r_twos_complement_device> m_dac;
|
||||||
required_device<newport_video_device> m_newport;
|
required_device<newport_video_device> m_newport;
|
||||||
required_device<hal2_device> m_hal2;
|
required_device<hal2_device> m_hal2;
|
||||||
required_device<hpc3_device> m_hpc3;
|
required_device<hpc3_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
|
// 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)
|
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(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(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(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(0x1fbd8000, 0x1fbd83ff).rw(m_hal2, FUNC(hal2_device::read), FUNC(hal2_device::write));
|
||||||
map(0x1fbd8400, 0x1fbd87ff).ram(); /* hack */
|
map(0x1fbd8400, 0x1fbd87ff).ram(); /* hack */
|
||||||
map(0x1fbd9000, 0x1fbd93ff).rw(m_hpc3, FUNC(hpc3_device::pbus4_r), FUNC(hpc3_device::pbus4_w));
|
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, "lspeaker").front_left();
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
|
|
||||||
dac_16bit_r2r_twos_complement_device &dac(DAC_16BIT_R2R_TWOS_COMPLEMENT(config, "dac", 0));
|
DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac, 0);
|
||||||
dac.add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
m_dac->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||||
dac.add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
m_dac->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||||
|
|
||||||
voltage_regulator_device &vreg = VOLTAGE_REGULATOR(config, "vref");
|
voltage_regulator_device &vreg = VOLTAGE_REGULATOR(config, "vref");
|
||||||
vreg.set_output(5.0);
|
vreg.set_output(5.0);
|
||||||
@ -250,7 +279,7 @@ void ip22_state::ip225015(machine_config &config)
|
|||||||
|
|
||||||
SGI_HAL2(config, m_hal2);
|
SGI_HAL2(config, m_hal2);
|
||||||
SGI_IOC2_GUINNESS(config, m_ioc2, m_maincpu);
|
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);
|
DS1386_8K(config, m_rtc, 32768);
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
@ -16,6 +16,7 @@ hpc3_device::hpc3_device(const machine_config &mconfig, const char *tag, device_
|
|||||||
, m_maincpu(*this, finder_base::DUMMY_TAG)
|
, m_maincpu(*this, finder_base::DUMMY_TAG)
|
||||||
, m_wd33c93(*this, finder_base::DUMMY_TAG)
|
, m_wd33c93(*this, finder_base::DUMMY_TAG)
|
||||||
, m_ioc2(*this, finder_base::DUMMY_TAG)
|
, m_ioc2(*this, finder_base::DUMMY_TAG)
|
||||||
|
, m_dac(*this, finder_base::DUMMY_TAG)
|
||||||
, m_mainram(*this, ":mainram")
|
, m_mainram(*this, ":mainram")
|
||||||
, m_unkpbus0(*this, ":unkpbus0")
|
, m_unkpbus0(*this, ":unkpbus0")
|
||||||
{
|
{
|
||||||
@ -38,6 +39,8 @@ inline void ATTR_PRINTF(3,4) hpc3_device::verboselog(int n_level, const char *s_
|
|||||||
|
|
||||||
void hpc3_device::device_start()
|
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()
|
void hpc3_device::device_reset()
|
||||||
@ -45,13 +48,14 @@ void hpc3_device::device_reset()
|
|||||||
m_enetr_nbdp = 0x80000000;
|
m_enetr_nbdp = 0x80000000;
|
||||||
m_enetr_cbp = 0x80000000;
|
m_enetr_cbp = 0x80000000;
|
||||||
m_pbus_dma.m_active = 0;
|
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)
|
void hpc3_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
{
|
{
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case TIMER_DMA:
|
case TIMER_PBUS_DMA:
|
||||||
do_dma(ptr, param);
|
do_dma(ptr, param);
|
||||||
break;
|
break;
|
||||||
default:
|
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_CALLBACK_MEMBER(hpc3_device::do_dma)
|
||||||
{
|
{
|
||||||
timer_set(attotime::never, TIMER_DMA);
|
m_pbus_dma_timer->adjust(attotime::never);
|
||||||
#if 0
|
|
||||||
if (m_pbus_dma.m_active)
|
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));
|
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_cur_ptr += 4;
|
||||||
|
|
||||||
m_pbus_dma.m_words_left -= 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_desc_ptr = m_pbus_dma.m_next_ptr;
|
||||||
m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4];
|
logerror("Next PBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr); fflush(stdout);
|
||||||
m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1];
|
m_pbus_dma.m_cur_ptr = space.read_dword(m_pbus_dma.m_desc_ptr);
|
||||||
m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2];
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -88,9 +97,8 @@ TIMER_CALLBACK_MEMBER(hpc3_device::do_dma)
|
|||||||
return;
|
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)
|
READ32_MEMBER(hpc3_device::hd_enet_r)
|
||||||
@ -98,19 +106,19 @@ READ32_MEMBER(hpc3_device::hd_enet_r)
|
|||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0x0004/4:
|
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;
|
return m_scsi0_desc;
|
||||||
case 0x1004/4:
|
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;
|
return m_scsi0_dma_ctrl;
|
||||||
case 0x4000/4:
|
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;
|
return m_enetr_cbp;
|
||||||
case 0x4004/4:
|
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;
|
return m_enetr_nbdp;
|
||||||
default:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,23 +128,23 @@ WRITE32_MEMBER(hpc3_device::hd_enet_w)
|
|||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0x0004/4:
|
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;
|
m_scsi0_desc = data;
|
||||||
break;
|
break;
|
||||||
case 0x1004/4:
|
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;
|
m_scsi0_dma_ctrl = data;
|
||||||
break;
|
break;
|
||||||
case 0x4000/4:
|
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;
|
m_enetr_cbp = data;
|
||||||
break;
|
break;
|
||||||
case 0x4004/4:
|
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;
|
m_enetr_nbdp = data;
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +155,7 @@ READ32_MEMBER(hpc3_device::hd0_r)
|
|||||||
{
|
{
|
||||||
case 0x0000/4:
|
case 0x0000/4:
|
||||||
case 0x4000/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)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
return m_wd33c93->read(space, 0);
|
return m_wd33c93->read(space, 0);
|
||||||
@ -158,7 +166,7 @@ READ32_MEMBER(hpc3_device::hd0_r)
|
|||||||
}
|
}
|
||||||
case 0x0004/4:
|
case 0x0004/4:
|
||||||
case 0x4004/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)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
return m_wd33c93->read(space, 1);
|
return m_wd33c93->read(space, 1);
|
||||||
@ -168,7 +176,7 @@ READ32_MEMBER(hpc3_device::hd0_r)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,7 +187,7 @@ WRITE32_MEMBER(hpc3_device::hd0_w)
|
|||||||
{
|
{
|
||||||
case 0x0000/4:
|
case 0x0000/4:
|
||||||
case 0x4000/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)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
m_wd33c93->write(space, 0, data & 0x000000ff);
|
m_wd33c93->write(space, 0, data & 0x000000ff);
|
||||||
@ -187,14 +195,14 @@ WRITE32_MEMBER(hpc3_device::hd0_w)
|
|||||||
break;
|
break;
|
||||||
case 0x0004/4:
|
case 0x0004/4:
|
||||||
case 0x4004/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)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
m_wd33c93->write(space, 1, data & 0x000000ff);
|
m_wd33c93->write(space, 1, data & 0x000000ff);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,16 +213,16 @@ READ32_MEMBER(hpc3_device::pbus4_r)
|
|||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0x0004/4:
|
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;
|
return m_unk0;
|
||||||
case 0x000c/4:
|
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;
|
return m_ic_unk0;
|
||||||
case 0x0014/4:
|
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;
|
return m_unk1;
|
||||||
default:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,19 +232,19 @@ WRITE32_MEMBER(hpc3_device::pbus4_w)
|
|||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0x0004/4:
|
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;
|
m_unk0 = data;
|
||||||
break;
|
break;
|
||||||
case 0x000c/4:
|
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;
|
m_ic_unk0 = data;
|
||||||
break;
|
break;
|
||||||
case 0x0014/4:
|
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;
|
m_unk1 = data;
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +252,7 @@ WRITE32_MEMBER(hpc3_device::pbus4_w)
|
|||||||
READ32_MEMBER(hpc3_device::pbusdma_r)
|
READ32_MEMBER(hpc3_device::pbusdma_r)
|
||||||
{
|
{
|
||||||
//uint32_t channel = offset / (0x2000/4);
|
//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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,75 +263,75 @@ WRITE32_MEMBER(hpc3_device::pbusdma_w)
|
|||||||
switch (offset & 0x07ff)
|
switch (offset & 0x07ff)
|
||||||
{
|
{
|
||||||
case 0x0000/4:
|
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;
|
return;
|
||||||
case 0x0004/4:
|
case 0x0004/4:
|
||||||
//verboselog((machine, 0, "PBUS DMA Channel %d Descriptor Pointer Write: 0x%08x\n", channel, data );
|
//verboselog(machine, 0, "PBUS DMA Channel %d Descriptor Pointer Write: 0x%08x\n", channel, data);
|
||||||
if (channel == 1)
|
if (channel == 1)
|
||||||
{
|
{
|
||||||
m_pbus_dma.m_desc_ptr = data;
|
m_pbus_dma.m_desc_ptr = data;
|
||||||
m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4];
|
logerror("PBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr); fflush(stdout);
|
||||||
m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1];
|
m_pbus_dma.m_cur_ptr = space.read_dword(m_pbus_dma.m_desc_ptr);
|
||||||
m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2];
|
m_pbus_dma.m_words_left = space.read_dword(m_pbus_dma.m_desc_ptr + 4);
|
||||||
//verboselog((machine, 0, "nPBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr );
|
m_pbus_dma.m_next_ptr = space.read_dword(m_pbus_dma.m_desc_ptr + 8);
|
||||||
//verboselog((machine, 0, "nPBUS_DMA_CurPtr = %08x\n", m_pbus_dma.m_cur_ptr );
|
logerror("PBUS_DMA_CurPtr = %08x\n", m_pbus_dma.m_cur_ptr); fflush(stdout);
|
||||||
//verboselog((machine, 0, "nPBUS_DMA_WordsLeft = %08x\n", m_pbus_dma.m_words_left );
|
logerror("PBUS_DMA_WordsLeft = %08x\n", m_pbus_dma.m_words_left); fflush(stdout);
|
||||||
//verboselog((machine, 0, "nPBUS_DMA_NextPtr = %08x\n", m_pbus_dma.m_next_ptr );
|
logerror("PBUS_DMA_NextPtr = %08x\n", m_pbus_dma.m_next_ptr); fflush(stdout);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x1000/4:
|
case 0x1000/4:
|
||||||
//verboselog((machine, 0, "PBUS DMA Channel %d Control Register Write: 0x%08x\n", channel, data );
|
logerror("PBUS DMA Channel %d Control Register Write: 0x%08x\n", channel, data);
|
||||||
if (data & PBUS_CTRL_ENDIAN)
|
if (data & PBUS_CTRL_ENDIAN)
|
||||||
{
|
{
|
||||||
//verboselog((machine, 0, " Little Endian\n" );
|
logerror(" Little Endian\n");
|
||||||
}
|
}
|
||||||
else
|
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
|
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 );
|
logerror(" 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 );
|
logerror(" 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 );
|
logerror(" FIFO End: Rowe %04x\n", (data & PBUS_CTRL_FIFO_END) >> 24);
|
||||||
if ((data & PBUS_CTRL_DMASTART) || (data & PBUS_CTRL_LOAD_EN))
|
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;
|
m_pbus_dma.m_active = 1;
|
||||||
}
|
}
|
||||||
return;
|
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)
|
READ32_MEMBER(hpc3_device::unkpbus0_r)
|
||||||
{
|
{
|
||||||
return 0;
|
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];
|
//return m_unkpbus0[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE32_MEMBER(hpc3_device::unkpbus0_w)
|
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]);
|
//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)
|
WRITE_LINE_MEMBER(hpc3_device::scsi_irq)
|
||||||
{
|
{
|
||||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
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())
|
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_ENABLE)
|
||||||
{
|
{
|
||||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_IRQ)
|
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_IRQ)
|
||||||
logerror("IP22: Unhandled SCSI DMA IRQ\n");
|
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_ENABLE)
|
||||||
{
|
{
|
||||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR)
|
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR)
|
||||||
{
|
{
|
||||||
// HPC3 DMA: host to device
|
// 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);
|
//logerror("DMA to device: %d bytes @ %x\n", byte_count, m_scsi0_addr);
|
||||||
m_scsi0_desc += words * 4;
|
|
||||||
|
|
||||||
logerror("DMA to device: %d words @ %x\n", words, srcoffs);
|
if (byte_count <= 512)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < byte_count; i++)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
dump_chain(space, m_scsi0_desc);
|
m_wd33c93->dma_write_data(byte_count, m_dma_buffer);
|
||||||
|
}
|
||||||
if (words <= (512/4))
|
else
|
||||||
{
|
{
|
||||||
int dstoffs = 0;
|
int dstoffs = 0;
|
||||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
while (byte_count)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < words; i++)
|
int sub_count = std::min(512, byte_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < sub_count; i++)
|
||||||
{
|
{
|
||||||
uint32_t tmpword = space.read_dword(srcoffs);
|
m_dma_buffer[big_endian ? BYTE4_XOR_BE(dstoffs+i) : BYTE4_XOR_LE(dstoffs+i)] = space.read_byte(m_scsi0_addr);
|
||||||
m_dma_buffer[dstoffs+3] = (tmpword >> 24) & 0xff;
|
m_scsi0_addr++;
|
||||||
m_dma_buffer[dstoffs+2] = (tmpword >> 16) & 0xff;
|
if (!decrement_chain(space))
|
||||||
m_dma_buffer[dstoffs+1] = (tmpword >> 8) & 0xff;
|
break;
|
||||||
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_wd33c93->dma_write_data(m_wd33c93->get_dma_count(), m_dma_buffer);
|
m_wd33c93->dma_write_data(sub_count, m_dma_buffer);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (words)
|
|
||||||
{
|
|
||||||
int twords = std::min(512/4, words);
|
|
||||||
m_scsi0_desc += twords*4;
|
|
||||||
|
|
||||||
int dstoffs = 0;
|
byte_count -= sub_count;
|
||||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
|
||||||
{
|
|
||||||
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_wd33c93->dma_write_data(512, m_dma_buffer);
|
|
||||||
|
|
||||||
words -= (512/4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear DMA on the controller too
|
// clear DMA on the controller too
|
||||||
m_wd33c93->clear_dma();
|
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
|
else
|
||||||
{
|
{
|
||||||
// HPC3 DMA: device to host
|
// HPC3 DMA: device to host
|
||||||
int words = (m_wd33c93->get_dma_count() + 3) / 4;
|
int byte_count = m_wd33c93->get_dma_count();
|
||||||
|
//dump_chain(space, m_scsi0_desc);
|
||||||
uint32_t dstoffs = space.read_dword(m_scsi0_desc);
|
fetch_chain(space);
|
||||||
|
|
||||||
// logerror("DMA from device: %d words @ %x\n", words, dstoffs);
|
// logerror("DMA from device: %d words @ %x\n", words, dstoffs);
|
||||||
|
|
||||||
dump_chain(space, m_scsi0_desc);
|
if (byte_count < 512)
|
||||||
|
{
|
||||||
|
m_wd33c93->dma_read_data(byte_count, m_dma_buffer);
|
||||||
|
|
||||||
if (words < (512/4))
|
for (int i = 0; i < byte_count; i++)
|
||||||
{
|
{
|
||||||
// one-shot
|
space.write_byte(big_endian ? BYTE4_XOR_BE(m_scsi0_addr+i) : BYTE4_XOR_LE(m_scsi0_addr+i), m_dma_buffer[i]);
|
||||||
m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
|
if (!decrement_chain(space))
|
||||||
|
break;
|
||||||
int srcoffs = 0;
|
|
||||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
|
||||||
{
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < words; i++)
|
while (byte_count)
|
||||||
{
|
{
|
||||||
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];
|
int sub_count = m_wd33c93->dma_read_data(512, m_dma_buffer);
|
||||||
space.write_dword(dstoffs, tmpword);
|
|
||||||
dstoffs += 4;
|
|
||||||
srcoffs += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (words)
|
|
||||||
{
|
|
||||||
int length = (m_wd33c93->dma_read_data(512, m_dma_buffer) + 3) / 4;
|
|
||||||
|
|
||||||
int srcoffs = 0;
|
for (int i = 0; i < sub_count; i++)
|
||||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < length; i++)
|
space.write_byte(big_endian ? BYTE4_XOR_BE(m_scsi0_addr) : BYTE4_XOR_LE(m_scsi0_addr), m_dma_buffer[i]);
|
||||||
{
|
m_scsi0_addr++;
|
||||||
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];
|
if (!decrement_chain(space))
|
||||||
space.write_dword(dstoffs, tmpword);
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
words -= (512/4);
|
byte_count -= sub_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,17 +14,19 @@
|
|||||||
#include "cpu/mips/mips3.h"
|
#include "cpu/mips/mips3.h"
|
||||||
#include "machine/ioc2.h"
|
#include "machine/ioc2.h"
|
||||||
#include "machine/wd33c93.h"
|
#include "machine/wd33c93.h"
|
||||||
|
#include "sound/dac.h"
|
||||||
|
|
||||||
class hpc3_device : public device_t
|
class hpc3_device : public device_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename T, typename U, typename V>
|
template <typename T, typename U, typename V, typename W>
|
||||||
hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&scsi_tag, V &&ioc2_tag)
|
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)
|
: hpc3_device(mconfig, tag, owner, (uint32_t)0)
|
||||||
{
|
{
|
||||||
m_maincpu.set_tag(std::forward<T>(cpu_tag));
|
m_maincpu.set_tag(std::forward<T>(cpu_tag));
|
||||||
m_wd33c93.set_tag(std::forward<U>(scsi_tag));
|
m_wd33c93.set_tag(std::forward<U>(scsi_tag));
|
||||||
m_ioc2.set_tag(std::forward<V>(ioc2_tag));
|
m_ioc2.set_tag(std::forward<V>(ioc2_tag));
|
||||||
|
m_dac.set_tag(std::forward<W>(dac_tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
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 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 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
|
struct pbus_dma_t
|
||||||
{
|
{
|
||||||
@ -60,11 +66,6 @@ protected:
|
|||||||
uint32_t m_words_left;
|
uint32_t m_words_left;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TIMER_DMA
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PBUS_CTRL_ENDIAN = 0x00000002,
|
PBUS_CTRL_ENDIAN = 0x00000002,
|
||||||
@ -99,6 +100,7 @@ protected:
|
|||||||
required_device<mips3_device> m_maincpu;
|
required_device<mips3_device> m_maincpu;
|
||||||
required_device<wd33c93_device> m_wd33c93;
|
required_device<wd33c93_device> m_wd33c93;
|
||||||
required_device<ioc2_device> m_ioc2;
|
required_device<ioc2_device> m_ioc2;
|
||||||
|
required_device<dac_16bit_r2r_twos_complement_device> m_dac;
|
||||||
required_shared_ptr<uint32_t> m_mainram;
|
required_shared_ptr<uint32_t> m_mainram;
|
||||||
required_shared_ptr<uint32_t> m_unkpbus0;
|
required_shared_ptr<uint32_t> m_unkpbus0;
|
||||||
|
|
||||||
@ -108,8 +110,13 @@ protected:
|
|||||||
uint32_t m_unk1;
|
uint32_t m_unk1;
|
||||||
uint32_t m_ic_unk0;
|
uint32_t m_ic_unk0;
|
||||||
uint32_t m_scsi0_desc;
|
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;
|
uint32_t m_scsi0_dma_ctrl;
|
||||||
pbus_dma_t m_pbus_dma;
|
pbus_dma_t m_pbus_dma;
|
||||||
|
emu_timer *m_pbus_dma_timer;
|
||||||
|
|
||||||
uint8_t m_dma_buffer[4096];
|
uint8_t m_dma_buffer[4096];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user