mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
hpc3: Improved DMA transfer behavior. The IRIX installer now loads, but panics. [Ryan Holtz]
This commit is contained in:
parent
b599c91785
commit
bce881ddb7
@ -939,7 +939,7 @@ void wd33c93_device::device_start()
|
||||
save_item(NAME(m_read_pending));
|
||||
}
|
||||
|
||||
void wd33c93_device::dma_read_data(int bytes, uint8_t *data)
|
||||
int wd33c93_device::dma_read_data(int bytes, uint8_t *data)
|
||||
{
|
||||
int len = bytes;
|
||||
|
||||
@ -947,7 +947,7 @@ void wd33c93_device::dma_read_data(int bytes, uint8_t *data)
|
||||
len = get_xfer_count();
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if ((m_temp_input_pos + len) >= TEMP_INPUT_LEN)
|
||||
{
|
||||
@ -960,8 +960,8 @@ void wd33c93_device::dma_read_data(int bytes, uint8_t *data)
|
||||
memcpy(data, &m_temp_input[m_temp_input_pos], len);
|
||||
|
||||
m_temp_input_pos += len;
|
||||
len = get_xfer_count() - len;
|
||||
set_xfer_count(len);
|
||||
set_xfer_count(get_xfer_count() - len);
|
||||
return len;
|
||||
}
|
||||
|
||||
void wd33c93_device::dma_write_data(int bytes, uint8_t *data)
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
DECLARE_READ8_MEMBER(read);
|
||||
DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
void dma_read_data(int bytes, uint8_t *data);
|
||||
int dma_read_data(int bytes, uint8_t *data);
|
||||
void dma_write_data(int bytes, uint8_t *data);
|
||||
void clear_dma();
|
||||
int get_dma_count();
|
||||
@ -72,8 +72,8 @@ private:
|
||||
WD_AUXILIARY_STATUS = 0x1f
|
||||
};
|
||||
|
||||
static constexpr unsigned TEMP_INPUT_LEN = 262144;
|
||||
static constexpr unsigned FIFO_SIZE = 12;
|
||||
static constexpr int TEMP_INPUT_LEN = 262144;
|
||||
static constexpr int FIFO_SIZE = 12;
|
||||
|
||||
uint8_t getunit();
|
||||
void set_xfer_count(int count);
|
||||
|
@ -348,71 +348,117 @@ WRITE_LINE_MEMBER(hpc3_device::scsi_irq)
|
||||
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");
|
||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_IRQ)
|
||||
logerror("IP22: Unhandled SCSI DMA IRQ\n");
|
||||
}
|
||||
|
||||
// HPC3 DMA: host to device
|
||||
if ((m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) && (m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR))
|
||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE)
|
||||
{
|
||||
uint32_t wptr, tmpword;
|
||||
int words, dptr, twords;
|
||||
|
||||
words = m_wd33c93->get_dma_count();
|
||||
words /= 4;
|
||||
|
||||
wptr = space.read_dword(m_scsi0_desc);
|
||||
m_scsi0_desc += words*4;
|
||||
dptr = 0;
|
||||
|
||||
logerror("DMA to device: %d words @ %x\n", words, wptr);
|
||||
|
||||
dump_chain(space, m_scsi0_desc);
|
||||
|
||||
if (words <= (512/4))
|
||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR)
|
||||
{
|
||||
// one-shot
|
||||
//m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
|
||||
// HPC3 DMA: host to device
|
||||
int words = (m_wd33c93->get_dma_count() + 3) / 4;
|
||||
|
||||
while (words)
|
||||
uint32_t srcoffs = space.read_dword(m_scsi0_desc);
|
||||
m_scsi0_desc += words * 4;
|
||||
|
||||
logerror("DMA to device: %d words @ %x\n", words, srcoffs);
|
||||
|
||||
dump_chain(space, m_scsi0_desc);
|
||||
|
||||
if (words <= (512/4))
|
||||
{
|
||||
tmpword = space.read_dword(wptr);
|
||||
|
||||
int dstoffs = 0;
|
||||
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;
|
||||
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
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
wptr += 4;
|
||||
dptr += 4;
|
||||
words--;
|
||||
m_wd33c93->dma_write_data(m_wd33c93->get_dma_count(), m_dma_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (words)
|
||||
{
|
||||
int twords = std::min(512/4, words);
|
||||
m_scsi0_desc += twords*4;
|
||||
|
||||
int dstoffs = 0;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
words = m_wd33c93->get_dma_count();
|
||||
m_wd33c93->dma_write_data(words, m_dma_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (words)
|
||||
// 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)
|
||||
{
|
||||
//m_wd33c93->dma_read_data(512, m_dma_buffer);
|
||||
twords = 512/4;
|
||||
m_scsi0_desc += 512;
|
||||
dptr = 0;
|
||||
|
||||
while (twords)
|
||||
while (length > 0)
|
||||
{
|
||||
tmpword = space.read_dword(wptr);
|
||||
|
||||
tmpword = space.read_dword(rptr);
|
||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
||||
{
|
||||
m_dma_buffer[dptr+3] = (tmpword>>24)&0xff;
|
||||
@ -428,139 +474,96 @@ WRITE_LINE_MEMBER(hpc3_device::scsi_irq)
|
||||
m_dma_buffer[dptr+3] = tmpword&0xff;
|
||||
}
|
||||
|
||||
wptr += 4;
|
||||
dptr += 4;
|
||||
twords--;
|
||||
rptr += 4;
|
||||
length -= 4;
|
||||
}
|
||||
|
||||
m_wd33c93->dma_write_data(512, m_dma_buffer);
|
||||
length = space.read_dword(m_scsi0_desc+4) & 0x3fff;
|
||||
m_wd33c93->write_data(length, m_dma_buffer);
|
||||
|
||||
words -= (512/4);
|
||||
// clear DMA on the controller too
|
||||
m_wd33c93->clear_dma();
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
else
|
||||
{
|
||||
tmpword = space.read_dword(rptr);
|
||||
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);
|
||||
|
||||
// logerror("DMA from device: %d words @ %x\n", words, dstoffs);
|
||||
|
||||
dump_chain(space, m_scsi0_desc);
|
||||
|
||||
if (words < (512/4))
|
||||
{
|
||||
// one-shot
|
||||
m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
|
||||
|
||||
int srcoffs = 0;
|
||||
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;
|
||||
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
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
dptr += 4;
|
||||
rptr += 4;
|
||||
length -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (words)
|
||||
{
|
||||
int length = (m_wd33c93->dma_read_data(512, m_dma_buffer) + 3) / 4;
|
||||
|
||||
length = space.read_dword(m_scsi0_desc+4) & 0x3fff;
|
||||
m_wd33c93->write_data(length, m_dma_buffer);
|
||||
int srcoffs = 0;
|
||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
words -= (512/4);
|
||||
}
|
||||
}
|
||||
|
||||
// clear DMA on the controller too
|
||||
m_wd33c93->clear_dma();
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("IP22: overly large host to device transfer, can't handle!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// HPC3 DMA: device to host
|
||||
if ((m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) && !(m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR))
|
||||
{
|
||||
uint32_t wptr, tmpword;
|
||||
int words, sptr, twords;
|
||||
|
||||
words = m_wd33c93->get_dma_count();
|
||||
words /= 4;
|
||||
|
||||
wptr = space.read_dword(m_scsi0_desc);
|
||||
sptr = 0;
|
||||
|
||||
// osd_printf_info("DMA from device: %d words @ %x\n", words, wptr);
|
||||
|
||||
dump_chain(space, m_scsi0_desc);
|
||||
|
||||
if (words <= (1024/4))
|
||||
{
|
||||
// one-shot
|
||||
m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
|
||||
|
||||
while (words)
|
||||
{
|
||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
||||
{
|
||||
tmpword = m_dma_buffer[sptr+3]<<24 | m_dma_buffer[sptr+2]<<16 | m_dma_buffer[sptr+1]<<8 | m_dma_buffer[sptr];
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpword = m_dma_buffer[sptr]<<24 | m_dma_buffer[sptr+1]<<16 | m_dma_buffer[sptr+2]<<8 | m_dma_buffer[sptr+3];
|
||||
}
|
||||
|
||||
space.write_dword(wptr, tmpword);
|
||||
wptr += 4;
|
||||
sptr += 4;
|
||||
words--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (words)
|
||||
{
|
||||
m_wd33c93->dma_read_data(512, m_dma_buffer);
|
||||
twords = 512/4;
|
||||
sptr = 0;
|
||||
|
||||
while (twords)
|
||||
{
|
||||
if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
|
||||
{
|
||||
tmpword = m_dma_buffer[sptr+3]<<24 | m_dma_buffer[sptr+2]<<16 | m_dma_buffer[sptr+1]<<8 | m_dma_buffer[sptr];
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpword = m_dma_buffer[sptr]<<24 | m_dma_buffer[sptr+1]<<16 | m_dma_buffer[sptr+2]<<8 | m_dma_buffer[sptr+3];
|
||||
}
|
||||
space.write_dword(wptr, tmpword);
|
||||
|
||||
wptr += 4;
|
||||
sptr += 4;
|
||||
twords--;
|
||||
}
|
||||
|
||||
words -= (512/4);
|
||||
}
|
||||
}
|
||||
|
||||
// clear DMA on the controller too
|
||||
m_wd33c93->clear_dma();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user