diff options
Diffstat (limited to 'src/devices/machine/ps2sif.cpp')
-rw-r--r-- | src/devices/machine/ps2sif.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/devices/machine/ps2sif.cpp b/src/devices/machine/ps2sif.cpp new file mode 100644 index 00000000000..26c09293774 --- /dev/null +++ b/src/devices/machine/ps2sif.cpp @@ -0,0 +1,199 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony PlayStation 2 SIF device skeleton +* +* To Do: +* Everything +* +*/ + +#include "ps2sif.h" +#include "cpu/mips/ps2vu.h" + +DEFINE_DEVICE_TYPE(SONYPS2_SIF, ps2_sif_device, "ps2sif", "PlayStation 2 SIF") + +/*static*/ const size_t ps2_sif_device::MAX_FIFO_DEPTH = 0x20; + +ps2_sif_device::ps2_sif_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SONYPS2_SIF, tag, owner, clock) + , m_intc(*this, finder_base::DUMMY_TAG) +{ +} + +void ps2_sif_device::device_start() +{ + save_item(NAME(m_ms_mailbox)); + save_item(NAME(m_sm_mailbox)); + save_item(NAME(m_ms_flag)); + save_item(NAME(m_sm_flag)); + save_item(NAME(m_ctrl)); + + m_fifo[0] = std::make_unique<uint32_t[]>(MAX_FIFO_DEPTH); + m_fifo[1] = std::make_unique<uint32_t[]>(MAX_FIFO_DEPTH); +} + +void ps2_sif_device::device_reset() +{ + m_ms_mailbox = 0; + m_sm_mailbox = 0; + m_ms_flag = 0; + m_sm_flag = 0; + m_ctrl = 0; + + memset(m_fifo[0].get(), 0, sizeof(uint32_t) * MAX_FIFO_DEPTH); + memset(m_fifo[1].get(), 0, sizeof(uint32_t) * MAX_FIFO_DEPTH); + m_fifo_curr[0] = 0; + m_fifo_curr[1] = 0; +} + +READ32_MEMBER(ps2_sif_device::ee_r) +{ + uint32_t ret = 0; + switch (offset) + { + case 0: + ret = m_ms_mailbox; + //logerror("%s: ee_r: SIF master->slave mailbox (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 2: + ret = m_sm_mailbox; + //logerror("%s: ee_r: SIF slave->master mailbox (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 4: + ret = m_ms_flag; + //logerror("%s: ee_r: SIF master->slave flag (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 6: + ret = m_sm_flag; + //if (ret != 0) + //logerror("%s: ee_r: SIF slave->master flag (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 8: + ret = m_ctrl | 0xF0000102; + //logerror("%s: ee_r: SIF control (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + default: + logerror("%s: ee_r: Unknown (%08x & %08x)\n", machine().describe_context(), 0x1000f200 + (offset << 3), mem_mask); + break; + } + return ret; +} + +WRITE32_MEMBER(ps2_sif_device::ee_w) +{ + switch (offset) + { + case 0: + //logerror("%s: ee_w: SIF master->slave mailbox (%08x & %08x)\n", machine().describe_context(), data, mem_mask); + m_ms_mailbox = data; + break; + case 4: + //logerror("%s: ee_w: SIF set master->slave flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask); + m_ms_flag |= data; + break; + case 6: + //logerror("%s: ee_w: SIF clear slave->master flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask); + m_sm_flag &= ~data; + break; + case 8: + //logerror("%s: ee_w: SIF set control = %08x & %08x\n", machine().describe_context(), data, mem_mask); + if (BIT(data, 8)) + m_ctrl |= (1 << 8); + else + m_ctrl &= ~(1 << 8); + // ?? + break; + default: + logerror("%s: ee_w: Unknown %08x = %08x & %08x\n", machine().describe_context(), 0x1000f200 + (offset << 3), data, mem_mask); + break; + } +} + +READ32_MEMBER(ps2_sif_device::iop_r) +{ + uint32_t ret = 0; + switch (offset) + { + case 0: + ret = m_ms_mailbox; + //logerror("%s: iop_r: SIF master->slave mailbox (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 4: + ret = m_sm_mailbox; + //logerror("%s: iop_r: SIF slave->master mailbox (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 8: + ret = m_ms_flag; + //if (ret != 0) + //logerror("%s: iop_r: SIF master->slave flag (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 12: + ret = m_sm_flag; + //logerror("%s: iop_r: SIF slave->master flag (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 16: + ret = m_ctrl | 0xf0000002; + //logerror("%s: iop_r: SIF control register (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + default: + logerror("%s: iop_r: Unknown read (%08x & %08x)\n", machine().describe_context(), 0x1d000000 + (offset << 2), mem_mask); + break; + } + return ret; +} + +WRITE32_MEMBER(ps2_sif_device::iop_w) +{ + switch (offset) + { + case 4: + //logerror("%s: iop_w: SIF slave->master mailbox (%08x & %08x)\n", machine().describe_context(), data, mem_mask); + m_sm_mailbox = data; + break; + case 8: + //logerror("%s: iop_w: SIF clear master->slave flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask); + m_ms_flag &= ~data; + break; + case 12: + //logerror("%s: iop_w: SIF set slave->master flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask); + m_sm_flag |= data; + break; + case 16: + //logerror("%s: iop_w: SIF set control (%08x & %08x)\n", machine().describe_context(), data, mem_mask); + m_ctrl ^= data & 0xf0; + if (data & 0x80 || data & 0x20) + { + m_ctrl &= ~0xf000; + m_ctrl |= 0x2000; + } + break; + default: + logerror("%s: iop_w: Unknown write %08x = %08x & %08x\n", machine().describe_context(), 0x1d000000 + (offset << 2), data, mem_mask); + break; + } +} + +uint32_t ps2_sif_device::fifo_depth(uint32_t channel) +{ + assert(channel < 2); + return m_fifo_curr[channel]; +} + +uint32_t ps2_sif_device::fifo_pop(uint32_t channel) +{ + assert(channel < 2); + assert(m_fifo_curr[channel] > 0); + uint32_t ret = m_fifo[channel][0]; + m_fifo_curr[channel]--; + memcpy(&m_fifo[channel][0], &m_fifo[channel][1], sizeof(uint32_t) * m_fifo_curr[channel]); + return ret; +} + +void ps2_sif_device::fifo_push(uint32_t channel, uint32_t value) +{ + assert(m_fifo_curr[channel] < MAX_FIFO_DEPTH); + m_fifo[channel][m_fifo_curr[channel]] = value; + m_fifo_curr[channel]++; +} |