diff options
Diffstat (limited to 'src/mame/machine/iopcdvd.cpp')
-rw-r--r-- | src/mame/machine/iopcdvd.cpp | 168 |
1 files changed, 107 insertions, 61 deletions
diff --git a/src/mame/machine/iopcdvd.cpp b/src/mame/machine/iopcdvd.cpp index ff3ce8ac021..16c8eb25973 100644 --- a/src/mame/machine/iopcdvd.cpp +++ b/src/mame/machine/iopcdvd.cpp @@ -11,7 +11,7 @@ #include "iopcdvd.h" -/*static*/ const size_t iop_cdvd_device::BUFFER_SIZE = 2048; // Total guess +/*static*/ const size_t iop_cdvd_device::BUFFER_SIZE = 16; // Total guess DEFINE_DEVICE_TYPE(SONYIOP_CDVD, iop_cdvd_device, "iopcdvd", "Playstation 2 disc controller") @@ -23,23 +23,31 @@ iop_cdvd_device::iop_cdvd_device(const machine_config &mconfig, const char *tag, void iop_cdvd_device::device_start() { - m_out_buf = std::make_unique<uint8_t[]>(BUFFER_SIZE); - - save_item(NAME(m_status_0x05)); - save_item(NAME(m_status_0x17)); - save_item(NAME(m_command)); - save_item(NAME(m_out_count)); - save_item(NAME(m_out_curr)); + save_item(NAME(m_channel[0].m_buffer)); + save_item(NAME(m_channel[0].m_curr)); + save_item(NAME(m_channel[0].m_end)); + save_item(NAME(m_channel[0].m_status)); + save_item(NAME(m_channel[0].m_command)); + save_item(NAME(m_channel[1].m_buffer)); + save_item(NAME(m_channel[1].m_curr)); + save_item(NAME(m_channel[1].m_end)); + save_item(NAME(m_channel[1].m_status)); + save_item(NAME(m_channel[1].m_command)); } void iop_cdvd_device::device_reset() { - m_status_0x05 = CDVD_STATUS_BOOT; - m_status_0x17 = CDVD_STATUS_IDLE; - m_command = 0; - memset(&m_out_buf[0], 0, BUFFER_SIZE); - m_out_count = 0; - m_out_curr = 0; + for (offs_t i = 0; i < 2; i++) + { + memset(m_channel[i].m_buffer, 0, BUFFER_SIZE); + m_channel[i].m_curr = 0; + m_channel[i].m_end = 0; + m_channel[i].m_status = 0; + m_channel[i].m_command = 0; + } + + m_channel[0].m_status |= CDVD_STATUS_IDLE; + m_channel[1].m_status |= CDVD_STATUS_IDLE; } READ8_MEMBER(iop_cdvd_device::read) @@ -47,31 +55,25 @@ READ8_MEMBER(iop_cdvd_device::read) uint8_t ret = 0; switch (offset) { + case 0x04: + ret = m_channel[CHAN_SERVO].m_command; + logerror("%s: cdvd_r: Servo Command (%02x)\n", machine().describe_context(), ret); + break; case 0x05: - ret = m_status_0x05; - logerror("%s: cdvd_r: Status 0x05? (%02x)\n", machine().describe_context(), ret); + ret = m_channel[CHAN_SERVO].m_status; + logerror("%s: cdvd_r: Servo Status (%02x)\n", machine().describe_context(), ret); break; case 0x16: - ret = m_command; - logerror("%s: cdvd_r: Command? (%02x)\n", machine().describe_context(), ret); + ret = m_channel[CHAN_DATA].m_command; + logerror("%s: cdvd_r: Data Command (%02x)\n", machine().describe_context(), ret); break; case 0x17: - ret = m_status_0x17; - logerror("%s: cdvd_r: Status 0x17? (%02x)\n", machine().describe_context(), ret); + ret = m_channel[CHAN_DATA].m_status; + logerror("%s: cdvd_r: Data Status (%02x)\n", machine().describe_context(), ret); break; case 0x18: - ret = m_out_buf[m_out_curr]; - if (m_out_curr < m_out_count) - { - m_out_curr++; - if (m_out_curr == m_out_count) - { - m_status_0x17 |= CDVD_STATUS_IDLE; - m_out_count = 0; - m_out_curr = 0; - } - } - logerror("%s: cdvd_r: Command Output (%02x) (%d left)\n", machine().describe_context(), ret, m_out_count - m_out_curr); + ret = data_fifo_pop(); + logerror("%s: cdvd_r: Data FIFO Out (%02x) (%d left)\n", machine().describe_context(), ret, m_channel[CHAN_DATA].m_end - m_channel[CHAN_DATA].m_curr); break; default: logerror("%s: cdvd_r: Unknown read: %08x\n", machine().describe_context(), 0x1f402000 + offset); @@ -80,43 +82,87 @@ READ8_MEMBER(iop_cdvd_device::read) return ret; } +void iop_cdvd_device::data_fifo_push(uint8_t data) +{ + drive_channel_t &channel = m_channel[CHAN_DATA]; + if (channel.m_end >= BUFFER_SIZE) + { + return; + } + + channel.m_buffer[channel.m_end++] = data; +} + +uint8_t iop_cdvd_device::data_fifo_pop() +{ + drive_channel_t &channel = m_channel[CHAN_DATA]; + if (channel.m_end == channel.m_curr) + { + channel.m_status |= CDVD_STATUS_IDLE; + return 0; + } + + const uint8_t ret = channel.m_buffer[channel.m_curr++]; + if (channel.m_end == channel.m_curr) + { + channel.m_status |= CDVD_STATUS_IDLE; + channel.m_curr = 0; + channel.m_end = 0; + } + return ret; +} + WRITE8_MEMBER(iop_cdvd_device::write) { switch (offset) { case 0x16: - m_command = data; - m_status_0x17 &= ~(CDVD_STATUS_IDLE | CDVD_STATUS_BOOT); - m_status_0x05 &= ~CDVD_STATUS_BOOT; - if (m_out_count > 0) - logerror("%s: cdvd_w: Command warning: Issuing command without reading previous results\n", machine().describe_context()); - switch (data) - { - case 0x15: - logerror("%s: cdvd_w: Command 0x15?\n", machine().describe_context()); - m_out_buf[m_out_count++] = 1; - m_intc->raise_interrupt(5); - break; - case 0x40: - logerror("%s: cdvd_w: Command 0x40?\n", machine().describe_context()); - m_out_buf[m_out_count++] = 0; - break; - case 0x41: - logerror("%s: cdvd_w: Command 0x41?\n", machine().describe_context()); - m_out_count = 0x10; - memset(&m_out_buf[0], 0, 0x10); - break; - case 0x43: - logerror("%s: cdvd_w: Command 0x43?\n", machine().describe_context()); - m_out_buf[m_out_count++] = 0; - break; - default: - logerror("%s: cdvd_r: Unknown command(?) %02x\n", machine().describe_context(), data); - break; - } + handle_data_command(data); + break; + case 0x17: + data_fifo_push(data); + logerror("%s: cdvd_w: Data FIFO push? %02x\n", machine().describe_context(), data); break; default: logerror("%s: cdvd_w: Unknown write: %08x = %02x\n", machine().describe_context(), 0x1f402000 + offset, data); break; } } + +void iop_cdvd_device::handle_data_command(uint8_t data) +{ + drive_channel_t &channel = m_channel[CHAN_DATA]; + channel.m_command = data; + channel.m_status &= ~CDVD_STATUS_IDLE; + if (channel.m_end) + logerror("%s: cdvd_w: Data Command warning: Issuing command without reading previous results\n", machine().describe_context()); + + switch (data) + { + case 0x08: + logerror("%s: cdvd_w: Command 0x08?\n", machine().describe_context()); + for (size_t i = 0; i < 8; i++) + data_fifo_push(0); + break; + case 0x15: + logerror("%s: cdvd_w: Command 0x15?\n", machine().describe_context()); + data_fifo_push(1); + break; + case 0x40: + logerror("%s: cdvd_w: Command 0x40?\n", machine().describe_context()); + data_fifo_push(0); + break; + case 0x41: + logerror("%s: cdvd_w: Command 0x41?\n", machine().describe_context()); + for (size_t i = 0; i < 0x10; i++) + data_fifo_push(0); + break; + case 0x43: + logerror("%s: cdvd_w: Command 0x43?\n", machine().describe_context()); + data_fifo_push(0); + break; + default: + logerror("%s: cdvd_w: Unknown command(?) %02x\n", machine().describe_context(), data); + break; + } +} |