From ba4f99c559d008f3f328dcff01ec8de335601091 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Mon, 2 Jul 2018 16:07:10 +0200 Subject: ps2sony: Added skeleton DMAC, INTC, and SIF devices, nw --- scripts/target/mame/mess.lua | 12 +- src/devices/cpu/mips/r3000.cpp | 42 ++- src/devices/cpu/mips/r3000.h | 2 +- src/mame/drivers/ps2sony.cpp | 803 +++++------------------------------------ src/mame/machine/iopdma.cpp | 242 +++++++++++-- src/mame/machine/iopdma.h | 89 ++++- src/mame/machine/iopintc.cpp | 98 +++++ src/mame/machine/iopintc.h | 59 +++ src/mame/machine/ioptimer.cpp | 10 +- src/mame/machine/ps2dma.cpp | 544 ++++++++++++++++++++++++++++ src/mame/machine/ps2dma.h | 117 ++++++ src/mame/machine/ps2intc.cpp | 79 ++++ src/mame/machine/ps2intc.h | 70 ++++ src/mame/machine/ps2sif.cpp | 187 ++++++++++ src/mame/machine/ps2sif.h | 61 ++++ src/mame/machine/ps2timer.cpp | 14 +- 16 files changed, 1658 insertions(+), 771 deletions(-) create mode 100644 src/mame/machine/iopintc.cpp create mode 100644 src/mame/machine/iopintc.h create mode 100644 src/mame/machine/ps2dma.cpp create mode 100644 src/mame/machine/ps2dma.h create mode 100644 src/mame/machine/ps2intc.cpp create mode 100644 src/mame/machine/ps2intc.h create mode 100644 src/mame/machine/ps2sif.cpp create mode 100644 src/mame/machine/ps2sif.h diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 10f742d4010..f8b42f03e98 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3058,10 +3058,18 @@ files { MAME_DIR .. "src/mame/drivers/ps2sony.cpp", MAME_DIR .. "src/mame/machine/ps2timer.cpp", MAME_DIR .. "src/mame/machine/ps2timer.h", - MAME_DIR .. "src/mame/machine/ioptimer.cpp", - MAME_DIR .. "src/mame/machine/ioptimer.h", + MAME_DIR .. "src/mame/machine/ps2dma.cpp", + MAME_DIR .. "src/mame/machine/ps2dma.h", + MAME_DIR .. "src/mame/machine/ps2intc.cpp", + MAME_DIR .. "src/mame/machine/ps2intc.h", + MAME_DIR .. "src/mame/machine/ps2sif.cpp", + MAME_DIR .. "src/mame/machine/ps2sif.h", MAME_DIR .. "src/mame/machine/iopdma.cpp", MAME_DIR .. "src/mame/machine/iopdma.h", + MAME_DIR .. "src/mame/machine/iopintc.cpp", + MAME_DIR .. "src/mame/machine/iopintc.h", + MAME_DIR .. "src/mame/machine/ioptimer.cpp", + MAME_DIR .. "src/mame/machine/ioptimer.h", } createMESSProjects(_target, _subtarget, "sord") diff --git a/src/devices/cpu/mips/r3000.cpp b/src/devices/cpu/mips/r3000.cpp index fd906584aa7..b84147483d2 100644 --- a/src/devices/cpu/mips/r3000.cpp +++ b/src/devices/cpu/mips/r3000.cpp @@ -635,10 +635,10 @@ void r3000_device::writecache_le_dword(offs_t offset, uint32_t data) EXECEPTION HANDLING ***************************************************************************/ -inline void r3000_device::generate_exception(int exception) +inline void r3000_device::generate_exception(int exception, bool backup) { // set the exception PC - m_cpr[0][COP0_EPC] = (exception == EXCEPTION_SYSCALL ? m_ppc : m_pc); + m_cpr[0][COP0_EPC] = backup ? m_ppc : m_pc; // put the cause in the low 8 bits and clear the branch delay flag CAUSE = (CAUSE & ~0x800000ff) | (exception << 2); @@ -668,7 +668,7 @@ inline void r3000_device::generate_exception(int exception) inline void r3000_device::invalid_instruction() { - generate_exception(EXCEPTION_INVALIDOP); + generate_exception(EXCEPTION_INVALIDOP, true); } @@ -679,7 +679,7 @@ inline void r3000_device::invalid_instruction() void r3000_device::check_irqs() { if ((CAUSE & SR & 0xff00) && (SR & SR_IEc)) - generate_exception(EXCEPTION_INTERRUPT); + generate_exception(EXCEPTION_INTERRUPT, false); } @@ -756,7 +756,7 @@ inline void r3000_device::set_cop0_creg(int idx, uint32_t val) inline void r3000_device::handle_cop0() { if (!(SR & SR_COP0) && (SR & SR_KUc)) - generate_exception(EXCEPTION_BADCOP); + generate_exception(EXCEPTION_BADCOP, true); switch (RSREG) { @@ -833,7 +833,7 @@ inline void r3000_device::set_cop1_creg(int idx, uint32_t val) inline void r3000_device::handle_cop1() { if (!(SR & SR_COP1)) - generate_exception(EXCEPTION_BADCOP); + generate_exception(EXCEPTION_BADCOP, true); if (!m_hasfpu) return; @@ -901,7 +901,7 @@ inline void r3000_device::set_cop2_creg(int idx, uint32_t val) inline void r3000_device::handle_cop2() { if (!(SR & SR_COP2)) - generate_exception(EXCEPTION_BADCOP); + generate_exception(EXCEPTION_BADCOP, true); switch (RSREG) { @@ -967,7 +967,7 @@ inline void r3000_device::set_cop3_creg(int idx, uint32_t val) inline void r3000_device::handle_cop3() { if (!(SR & SR_COP3)) - generate_exception(EXCEPTION_BADCOP); + generate_exception(EXCEPTION_BADCOP, true); switch (RSREG) { @@ -1076,6 +1076,20 @@ void r3000_device::execute_run() m_ppc = m_pc; debugger_instruction_hook(m_pc); + if ((m_pc & 0x1fffffff) == 0x00012C48 || (m_pc & 0x1fffffff) == 0x0001420C || (m_pc & 0x1fffffff) == 0x0001430C) + { + uint32_t ptr = m_r[5]; + uint32_t length = m_r[6]; + if (length >= 4096) + length = 4095; + while (length) + { + printf("%c", (char)RBYTE(ptr)); + ptr++; + length--; + } + fflush(stdout); + } // instruction fetch m_op = readop(m_pc); @@ -1102,9 +1116,9 @@ void r3000_device::execute_run() case 0x07: /* SRAV */ if (RDREG) RDVAL = (int32_t)RTVAL >> (RSVAL & 31); break; case 0x08: /* JR */ SETPC(RSVAL); break; case 0x09: /* JALR */ SETPCL(RSVAL, RDREG); break; - case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL); break; - case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK); break; - case 0x0f: /* SYNC */ invalid_instruction(); break; + case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL, true); break; + case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK, true); break; + case 0x0f: /* SYNC */ invalid_instruction(); break; case 0x10: /* MFHI */ if (RDREG) RDVAL = m_hi; break; case 0x11: /* MTHI */ m_hi = RSVAL; break; case 0x12: /* MFLO */ if (RDREG) RDVAL = m_lo; break; @@ -1138,12 +1152,12 @@ void r3000_device::execute_run() m_icount -= 34; break; case 0x20: /* ADD */ - if (ENABLE_OVERFLOWS && RSVAL > ~RTVAL) generate_exception(EXCEPTION_OVERFLOW); + if (ENABLE_OVERFLOWS && RSVAL > ~RTVAL) generate_exception(EXCEPTION_OVERFLOW, true); else RDVAL = RSVAL + RTVAL; break; case 0x21: /* ADDU */ if (RDREG) RDVAL = RSVAL + RTVAL; break; case 0x22: /* SUB */ - if (ENABLE_OVERFLOWS && RSVAL < RTVAL) generate_exception(EXCEPTION_OVERFLOW); + if (ENABLE_OVERFLOWS && RSVAL < RTVAL) generate_exception(EXCEPTION_OVERFLOW, true); else RDVAL = RSVAL - RTVAL; break; case 0x23: /* SUBU */ if (RDREG) RDVAL = RSVAL - RTVAL; break; @@ -1191,7 +1205,7 @@ void r3000_device::execute_run() case 0x06: /* BLEZ */ if ((int32_t)RSVAL <= 0) ADDPC(SIMMVAL); break; case 0x07: /* BGTZ */ if ((int32_t)RSVAL > 0) ADDPC(SIMMVAL); break; case 0x08: /* ADDI */ - if (ENABLE_OVERFLOWS && RSVAL > ~SIMMVAL) generate_exception(EXCEPTION_OVERFLOW); + if (ENABLE_OVERFLOWS && RSVAL > ~SIMMVAL) generate_exception(EXCEPTION_OVERFLOW, true); else if (RTREG) RTVAL = RSVAL + SIMMVAL; break; case 0x09: /* ADDIU */ if (RTREG) RTVAL = RSVAL + SIMMVAL; break; diff --git a/src/devices/cpu/mips/r3000.h b/src/devices/cpu/mips/r3000.h index 64537788aa5..79529b01195 100644 --- a/src/devices/cpu/mips/r3000.h +++ b/src/devices/cpu/mips/r3000.h @@ -150,7 +150,7 @@ protected: void writecache_le_dword(offs_t offset, uint32_t data); // interrupts - void generate_exception(int exception); + void generate_exception(int exception, bool backup); void check_irqs(); void set_irq_line(int irqline, int state); void invalid_instruction(); diff --git a/src/mame/drivers/ps2sony.cpp b/src/mame/drivers/ps2sony.cpp index 31d4f22ae96..27bd379e82e 100644 --- a/src/mame/drivers/ps2sony.cpp +++ b/src/mame/drivers/ps2sony.cpp @@ -158,9 +158,13 @@ iLinkSGUID=0x-------- #include "emu.h" #include "cpu/mips/mips3.h" #include "cpu/mips/r3000.h" -#include "machine/ps2timer.h" #include "machine/ioptimer.h" #include "machine/iopdma.h" +#include "machine/iopintc.h" +#include "machine/ps2timer.h" +#include "machine/ps2dma.h" +#include "machine/ps2intc.h" +#include "machine/ps2sif.h" #include "emupal.h" #include "screen.h" @@ -172,9 +176,14 @@ public: , m_maincpu(*this, "maincpu") , m_iop(*this, "iop") , m_timer(*this, "timer%u", 0U) + , m_dmac(*this, "dmac") + , m_intc(*this, "intc") + , m_sif(*this, "sif") , m_iop_timer(*this, "iop_timer") , m_iop_dma(*this, "iop_dma") + , m_iop_intc(*this, "iop_intc") , m_screen(*this, "screen") + , m_ram(*this, "ram") , m_iop_ram(*this, "iop_ram") , m_sp_ram(*this, "sp_ram") , m_vu0_imem(*this, "vu0imem") @@ -209,14 +218,6 @@ protected: DECLARE_WRITE64_MEMBER(gif_fifo_w); DECLARE_READ64_MEMBER(ipu_fifo_r); DECLARE_WRITE64_MEMBER(ipu_fifo_w); - DECLARE_READ32_MEMBER(dmac_channel_r); - DECLARE_WRITE32_MEMBER(dmac_channel_w); - DECLARE_READ32_MEMBER(dmac_r); - DECLARE_WRITE32_MEMBER(dmac_w); - DECLARE_READ32_MEMBER(intc_r); - DECLARE_WRITE32_MEMBER(intc_w); - DECLARE_READ32_MEMBER(sif_r); - DECLARE_WRITE32_MEMBER(sif_w); DECLARE_WRITE8_MEMBER(debug_w); DECLARE_READ32_MEMBER(unk_f430_r); DECLARE_WRITE32_MEMBER(unk_f430_w); @@ -227,33 +228,26 @@ protected: DECLARE_WRITE64_MEMBER(ee_iop_ram_w); DECLARE_READ64_MEMBER(ee_iop_ram_r); - DECLARE_READ32_MEMBER(iop_intc_r); - DECLARE_WRITE32_MEMBER(iop_intc_w); - DECLARE_READ32_MEMBER(iop_sif_r); - DECLARE_WRITE32_MEMBER(iop_sif_w); - DECLARE_READ32_MEMBER(iop_dma_ctrl0_r); - DECLARE_WRITE32_MEMBER(iop_dma_ctrl0_w); - DECLARE_READ32_MEMBER(iop_dma_ctrl1_r); - DECLARE_WRITE32_MEMBER(iop_dma_ctrl1_w); DECLARE_WRITE32_MEMBER(iop_debug_w); + DECLARE_READ32_MEMBER(unk_iop_r); + DECLARE_WRITE32_MEMBER(unk_iop_w); DECLARE_WRITE_LINE_MEMBER(iop_timer_irq); - void check_irq0(); - void raise_interrupt(int line); - - void check_iop_irq(); - void raise_iop_interrupt(int line); - void mem_map(address_map &map); void iop_map(address_map &map); required_device m_maincpu; required_device m_iop; required_device_array m_timer; + required_device m_dmac; + required_device m_intc; + required_device m_sif; required_device m_iop_timer; required_device m_iop_dma; + required_device m_iop_intc; required_device m_screen; + required_shared_ptr m_ram; required_shared_ptr m_iop_ram; required_shared_ptr m_sp_ram; required_shared_ptr m_vu0_imem; @@ -284,34 +278,6 @@ protected: uint32_t m_sif_sm_flag; uint32_t m_sif_ctrl; - uint32_t m_dmac_d5_chcr; - - enum - { - INT_GS = 0, - INT_SBUS, - INT_VB_ON, - INT_VB_OFF, - INT_VIF0, - INT_VIF1, - INT_VU0, - INT_VU1, - INT_IPU, - INT_TIMER0, - INT_TIMER1, - INT_TIMER2, - INT_TIMER3, - INT_SFIFO, - INT_VU0WD - }; - - uint32_t m_istat; - uint32_t m_imask; - - uint32_t m_iop_istat; - uint32_t m_iop_imask; - uint32_t m_iop_ienable; - emu_timer *m_vblank_timer; }; @@ -321,371 +287,16 @@ protected: * */ -READ32_MEMBER(ps2sony_state::dmac_r) -{ - uint32_t ret = 0; - switch (offset) - { - case 0: /* D_CTRL */ - logerror("%s: dmac_r: D_CTRL (%08x)\n", machine().describe_context(), ret); - break; - case 2: /* D_STAT */ - logerror("%s: dmac_r: D_STAT (%08x)\n", machine().describe_context(), ret); - break; - case 4: /* D_PCR */ - logerror("%s: dmac_r: D_PCR (%08x)\n", machine().describe_context(), ret); - break; - case 6: /* D_SQWC */ - logerror("%s: dmac_r: D_SQWC (%08x)\n", machine().describe_context(), ret); - break; - case 8: /* D_RBSR */ - logerror("%s: dmac_r: D_RBSR (%08x)\n", machine().describe_context(), ret); - break; - case 10: /* D_RBOR */ - logerror("%s: dmac_r: D_RBOR (%08x)\n", machine().describe_context(), ret); - break; - case 12: /* D_STADR */ - logerror("%s: dmac_r: D_STADR (%08x)\n", machine().describe_context(), ret); - break; - default: - logerror("%s: dmac_r: Unknown offset %08x\n", machine().describe_context(), 0x1000e000 + (offset << 3)); - break; - } - return ret; -} - -WRITE32_MEMBER(ps2sony_state::dmac_w) -{ - switch (offset) - { - case 0: /* D_CTRL */ - logerror("%s: dmac_w: D_CTRL = %08x\n", machine().describe_context(), data); - break; - case 2: /* D_STAT */ - logerror("%s: dmac_w: D_STAT = %08x\n", machine().describe_context(), data); - break; - case 4: /* D_PCR */ - logerror("%s: dmac_w: D_PCR = %08x\n", machine().describe_context(), data); - break; - case 6: /* D_SQWC */ - logerror("%s: dmac_w: D_SQWC = %08x\n", machine().describe_context(), data); - break; - case 8: /* D_RBSR */ - logerror("%s: dmac_w: D_RBSR = %08x\n", machine().describe_context(), data); - break; - case 10: /* D_RBOR */ - logerror("%s: dmac_w: D_RBOR = %08x\n", machine().describe_context(), data); - break; - case 12: /* D_STADR */ - logerror("%s: dmac_w: D_STADR = %08x\n", machine().describe_context(), data); - break; - default: - logerror("%s: dmac_w: Unknown offset %08x = %08X\n", machine().describe_context(), 0x1000e000 + (offset << 3), data); - break; - } -} - -READ32_MEMBER(ps2sony_state::dmac_channel_r) -{ - uint32_t ret = 0; - switch (offset + 0x8000/8) - { - case 0x8000/8: /* D0_CHCR */ - logerror("%s: dmac_channel_r: D0_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0x8010/8: /* D0_MADR */ - logerror("%s: dmac_channel_r: D0_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0x8020/8: /* D0_QWC */ - logerror("%s: dmac_channel_r: D0_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0x8030/8: /* D0_TADR */ - logerror("%s: dmac_channel_r: D0_TADR (%08x)\n", machine().describe_context(), ret); - break; - case 0x8040/8: /* D0_ASR0 */ - logerror("%s: dmac_channel_r: D0_ASR0 (%08x)\n", machine().describe_context(), ret); - break; - case 0x8050/8: /* D0_ASR1 */ - logerror("%s: dmac_channel_r: D0_ASR1 (%08x)\n", machine().describe_context(), ret); - break; - case 0x9000/8: /* D1_CHCR */ - logerror("%s: dmac_channel_r: D1_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0x9010/8: /* D1_MADR */ - logerror("%s: dmac_channel_r: D1_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0x9020/8: /* D1_QWC */ - logerror("%s: dmac_channel_r: D1_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0x9030/8: /* D1_TADR */ - logerror("%s: dmac_channel_r: D1_TADR (%08x)\n", machine().describe_context(), ret); - break; - case 0x9040/8: /* D1_ASR0 */ - logerror("%s: dmac_channel_r: D1_ASR0 (%08x)\n", machine().describe_context(), ret); - break; - case 0x9050/8: /* D1_ASR1 */ - logerror("%s: dmac_channel_r: D1_ASR1 (%08x)\n", machine().describe_context(), ret); - break; - case 0xa000/8: /* D2_CHCR */ - logerror("%s: dmac_channel_r: D2_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xa010/8: /* D2_MADR */ - logerror("%s: dmac_channel_r: D2_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xa020/8: /* D2_QWC */ - logerror("%s: dmac_channel_r: D2_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xa030/8: /* D2_TADR */ - logerror("%s: dmac_channel_r: D2_TADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xa040/8: /* D2_ASR0 */ - logerror("%s: dmac_channel_r: D2_ASR0 (%08x)\n", machine().describe_context(), ret); - break; - case 0xa050/8: /* D2_ASR1 */ - logerror("%s: dmac_channel_r: D2_ASR1 (%08x)\n", machine().describe_context(), ret); - break; - case 0xb000/8: /* D3_CHCR */ - logerror("%s: dmac_channel_r: D3_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xb010/8: /* D3_MADR */ - logerror("%s: dmac_channel_r: D3_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xb020/8: /* D3_QWC */ - logerror("%s: dmac_channel_r: D3_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xb400/8: /* D4_CHCR */ - logerror("%s: dmac_channel_r: D4_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xb410/8: /* D4_MADR */ - logerror("%s: dmac_channel_r: D4_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xb420/8: /* D4_QWC */ - logerror("%s: dmac_channel_r: D4_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xb430/8: /* D4_TADR */ - logerror("%s: dmac_channel_r: D4_TADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc000/8: /* D5_CHCR */ - ret = m_dmac_d5_chcr; - logerror("%s: dmac_channel_r: D5_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc010/8: /* D5_MADR */ - logerror("%s: dmac_channel_r: D5_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc020/8: /* D5_QWC */ - logerror("%s: dmac_channel_r: D5_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xc400/8: /* D6_CHCR */ - logerror("%s: dmac_channel_r: D6_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc410/8: /* D6_MADR */ - logerror("%s: dmac_channel_r: D6_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc420/8: /* D6_QWC */ - logerror("%s: dmac_channel_r: D6_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xc430/8: /* D6_TADR */ - logerror("%s: dmac_channel_r: D6_TADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc800/8: /* D7_CHCR */ - logerror("%s: dmac_channel_r: D7_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc810/8: /* D7_MADR */ - logerror("%s: dmac_channel_r: D7_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xc820/8: /* D7_QWC */ - logerror("%s: dmac_channel_r: D7_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xd000/8: /* D8_CHCR */ - logerror("%s: dmac_channel_r: D8_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xd010/8: /* D8_MADR */ - logerror("%s: dmac_channel_r: D8_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xd020/8: /* D8_QWC */ - logerror("%s: dmac_channel_r: D8_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xd080/8: /* D8_SADR */ - logerror("%s: dmac_channel_r: D8_SADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xd400/8: /* D9_CHCR */ - logerror("%s: dmac_channel_r: D9_CHCR (%08x)\n", machine().describe_context(), ret); - break; - case 0xd410/8: /* D9_MADR */ - logerror("%s: dmac_channel_r: D9_MADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xd420/8: /* D9_QWC */ - logerror("%s: dmac_channel_r: D9_QWC (%08x)\n", machine().describe_context(), ret); - break; - case 0xd430/8: /* D9_TADR */ - logerror("%s: dmac_channel_r: D9_TADR (%08x)\n", machine().describe_context(), ret); - break; - case 0xd480/8: /* D9_SADR */ - logerror("%s: dmac_channel_r: D9_SADR (%08x)\n", machine().describe_context(), ret); - break; - default: - logerror("%s: dmac_channel_r: Unknown offset %08x\n", machine().describe_context(), 0x10008000 + (offset << 3)); - break; - } - return ret; -} - -WRITE32_MEMBER(ps2sony_state::dmac_channel_w) -{ - static const char* mode_strings[4] = { "Normal", "Chain", "Interleave", "Undefined" }; - - switch (offset + 0x8000/8) - { - case 0x8000/8: /* D0_CHCR */ - logerror("%s: dmac_channel_w: D0_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0x8010/8: /* D0_MADR */ - logerror("%s: dmac_channel_w: D0_MADR = %08x\n", machine().describe_context(), data); - break; - case 0x8020/8: /* D0_QWC */ - logerror("%s: dmac_channel_w: D0_QWC = %08x\n", machine().describe_context(), data); - break; - case 0x8030/8: /* D0_TADR */ - logerror("%s: dmac_channel_w: D0_TADR = %08x\n", machine().describe_context(), data); - break; - case 0x8040/8: /* D0_ASR0 */ - logerror("%s: dmac_channel_w: D0_ASR0 = %08x\n", machine().describe_context(), data); - break; - case 0x8050/8: /* D0_ASR1 */ - logerror("%s: dmac_channel_w: D0_ASR1 = %08x\n", machine().describe_context(), data); - break; - case 0x9000/8: /* D1_CHCR */ - logerror("%s: dmac_channel_w: D1_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0x9010/8: /* D1_MADR */ - logerror("%s: dmac_channel_w: D1_MADR = %08x\n", machine().describe_context(), data); - break; - case 0x9020/8: /* D1_QWC */ - logerror("%s: dmac_channel_w: D1_QWC = %08x\n", machine().describe_context(), data); - break; - case 0x9030/8: /* D1_TADR */ - logerror("%s: dmac_channel_w: D1_TADR = %08x\n", machine().describe_context(), data); - break; - case 0x9040/8: /* D1_ASR0 */ - logerror("%s: dmac_channel_w: D1_ASR0 = %08x\n", machine().describe_context(), data); - break; - case 0x9050/8: /* D1_ASR1 */ - logerror("%s: dmac_channel_w: D1_ASR1 = %08x\n", machine().describe_context(), data); - break; - case 0xa000/8: /* D2_CHCR */ - logerror("%s: dmac_channel_w: D2_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0xa010/8: /* D2_MADR */ - logerror("%s: dmac_channel_w: D2_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xa020/8: /* D2_QWC */ - logerror("%s: dmac_channel_w: D2_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xa030/8: /* D2_TADR */ - logerror("%s: dmac_channel_w: D2_TADR = %08x\n", machine().describe_context(), data); - break; - case 0xa040/8: /* D2_ASR0 */ - logerror("%s: dmac_channel_w: D2_ASR0 = %08x\n", machine().describe_context(), data); - break; - case 0xa050/8: /* D2_ASR1 */ - logerror("%s: dmac_channel_w: D2_ASR1 = %08x\n", machine().describe_context(), data); - break; - case 0xb000/8: /* D3_CHCR */ - logerror("%s: dmac_channel_w: D3_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0xb010/8: /* D3_MADR */ - logerror("%s: dmac_channel_w: D3_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xb020/8: /* D3_QWC */ - logerror("%s: dmac_channel_w: D3_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xb400/8: /* D4_CHCR */ - logerror("%s: dmac_channel_w: D4_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0xb410/8: /* D4_MADR */ - logerror("%s: dmac_channel_w: D4_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xb420/8: /* D4_QWC */ - logerror("%s: dmac_channel_w: D4_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xb430/8: /* D4_TADR */ - logerror("%s: dmac_channel_w: D4_TADR = %08x\n", machine().describe_context(), data); - break; - case 0xc000/8: /* D5_CHCR */ - logerror("%s: dmac_channel_w: D5_CHCR = %08x (DIR=%s Memory, MOD=%s, ASP=%d, TTE=%s DMAtag, \n", machine().describe_context(), data, BIT(data, 0) ? "From" : "To", mode_strings[(data >> 1) & 3], (data >> 3) & 3, BIT(data, 6) ? "Transfers" : "Does not transfer"); - logerror("%s: TIE=%d, START=%d, TAG=%04x\n", machine().describe_context(), BIT(data, 7), BIT(data, 8), data >> 16); - COMBINE_DATA(&m_dmac_d5_chcr); - break; - case 0xc010/8: /* D5_MADR */ - logerror("%s: dmac_channel_w: D5_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xc020/8: /* D5_QWC */ - logerror("%s: dmac_channel_w: D5_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xc400/8: /* D6_CHCR */ - logerror("%s: dmac_channel_w: D6_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0xc410/8: /* D6_MADR */ - logerror("%s: dmac_channel_w: D6_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xc420/8: /* D6_QWC */ - logerror("%s: dmac_channel_w: D6_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xc430/8: /* D6_TADR */ - logerror("%s: dmac_channel_w: D6_TADR = %08x\n", machine().describe_context(), data); - break; - case 0xc800/8: /* D7_CHCR */ - logerror("%s: dmac_channel_w: D7_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0xc810/8: /* D7_MADR */ - logerror("%s: dmac_channel_w: D7_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xc820/8: /* D7_QWC */ - logerror("%s: dmac_channel_w: D7_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xd000/8: /* D8_CHCR */ - logerror("%s: dmac_channel_w: D8_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0xd010/8: /* D8_MADR */ - logerror("%s: dmac_channel_w: D8_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xd020/8: /* D8_QWC */ - logerror("%s: dmac_channel_w: D8_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xd080/8: /* D8_SADR */ - logerror("%s: dmac_channel_w: D8_SADR = %08x\n", machine().describe_context(), data); - break; - case 0xd400/8: /* D9_CHCR */ - logerror("%s: dmac_channel_w: D9_CHCR = %08x\n", machine().describe_context(), data); - break; - case 0xd410/8: /* D9_MADR */ - logerror("%s: dmac_channel_w: D9_MADR = %08x\n", machine().describe_context(), data); - break; - case 0xd420/8: /* D9_QWC */ - logerror("%s: dmac_channel_w: D9_QWC = %08x\n", machine().describe_context(), data); - break; - case 0xd430/8: /* D9_TADR */ - logerror("%s: dmac_channel_w: D9_TADR = %08x\n", machine().describe_context(), data); - break; - case 0xd480/8: /* D9_SADR */ - logerror("%s: dmac_channel_w: D9_SADR = %08x\n", machine().describe_context(), data); - break; - default: - logerror("%s: dmac_channel_w: Unknown offset %08x = %08x\n", machine().describe_context(), 0x10008000 + (offset << 3), data); - break; - } -} - READ64_MEMBER(ps2sony_state::vif0_fifo_r) { uint64_t ret = 0ULL; if (offset) { - logerror("%s: vif0_fifo_r [127..64]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: vif0_fifo_r [127..64]: (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } else { - logerror("%s: vif0_fifo_r [63..0]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: vif0_fifo_r [63..0]: (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } return ret; } @@ -694,11 +305,11 @@ WRITE64_MEMBER(ps2sony_state::vif0_fifo_w) { if (offset) { - logerror("%s: vif0_fifo_w [127..64]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: vif0_fifo_w [127..64]: %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } else { - logerror("%s: vif0_fifo_w [63..0]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: vif0_fifo_w [63..0]: %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } } @@ -707,11 +318,11 @@ READ64_MEMBER(ps2sony_state::vif1_fifo_r) uint64_t ret = 0ULL; if (offset) { - logerror("%s: vif1_fifo_r [127..64]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: vif1_fifo_r [127..64]: (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } else { - logerror("%s: vif1_fifo_r [63..0]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: vif1_fifo_r [63..0]: (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } return ret; } @@ -720,11 +331,11 @@ WRITE64_MEMBER(ps2sony_state::vif1_fifo_w) { if (offset) { - logerror("%s: vif1_fifo_w [127..64]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: vif1_fifo_w [127..64]: %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } else { - logerror("%s: vif1_fifo_w [63..0]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: vif1_fifo_w [63..0]: %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } } @@ -733,11 +344,11 @@ READ64_MEMBER(ps2sony_state::gif_fifo_r) uint64_t ret = 0ULL; if (offset) { - logerror("%s: gif_fifo_r [127..64]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: gif_fifo_r [127..64]: (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } else { - logerror("%s: gif_fifo_r [63..0]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: gif_fifo_r [63..0]: (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } return ret; } @@ -746,11 +357,11 @@ WRITE64_MEMBER(ps2sony_state::gif_fifo_w) { if (offset) { - logerror("%s: gif_fifo_w [127..64]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: gif_fifo_w [127..64]: %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } else { - logerror("%s: gif_fifo_w [63..0]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: gif_fifo_w [63..0]: %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); } } @@ -760,21 +371,21 @@ READ32_MEMBER(ps2sony_state::ipu_r) switch (offset) { case 0: /* IPU_CMD */ - logerror("%s: ipu_r: IPU_CMD (%08x)\n", machine().describe_context(), ret); + logerror("%s: ipu_r: IPU_CMD (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; case 2: /* IPU_CTRL */ ret = m_ipu_in_fifo_index | (m_ipu_out_fifo_index << 4); - logerror("%s: ipu_r: IPU_CTRL (%08x)\n", machine().describe_context(), ret); + logerror("%s: ipu_r: IPU_CTRL (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; case 4: /* IPU_BP */ ret = m_ipu_in_fifo_index << 8; - logerror("%s: ipu_r: IPU_BP (%08x)\n", machine().describe_context(), ret); + logerror("%s: ipu_r: IPU_BP (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; case 6: /* IPU_TOP */ - logerror("%s: ipu_r: IPU_TOP (%08x)\n", machine().describe_context(), ret); + logerror("%s: ipu_r: IPU_TOP (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; default: - logerror("%s: ipu_r: Unknown offset %08x\n", machine().describe_context(), 0x10002000 + (offset << 3)); + logerror("%s: ipu_r: Unknown offset %08x & %08x\n", machine().describe_context(), 0x10002000 + (offset << 3), mem_mask); break; } return ret; @@ -785,20 +396,20 @@ WRITE32_MEMBER(ps2sony_state::ipu_w) switch (offset) { case 0: /* IPU_CMD */ - logerror("%s: ipu_w: IPU_CMD = %08x\n", machine().describe_context(), data); + logerror("%s: ipu_w: IPU_CMD = %08x\n", machine().describe_context(), data, mem_mask); switch ((data >> 28) & 0xf) { case 0x00: /* BCLR */ m_ipu_in_fifo_index = 0; - logerror("%s: IPU command: BCLR (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: BCLR (%08x)\n", machine().describe_context(), data, mem_mask); break; case 0x01: /* IDEC */ - logerror("%s: IPU command: IDEC (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: IDEC (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: FB:%d QSC:%d DT_DECODE:%d SGN:%d DITHER:%d OFM:%s\n", machine().describe_context(), data & 0x3f, (data >> 16) & 0x1f, BIT(data, 24), BIT(data, 25), BIT(data, 26), BIT(data, 27) ? "RGB16" : "RGB32"); break; case 0x02: /* BDEC */ - logerror("%s: IPU command: BDEC (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: BDEC (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: FB:%d QSC:%d DT:%d DCR:%d MBI:%d\n", machine().describe_context(), data & 0x3f, (data >> 16) & 0x1f, BIT(data, 25), BIT(data, 26), BIT(data, 27)); break; @@ -811,40 +422,40 @@ WRITE32_MEMBER(ps2sony_state::ipu_w) "Motion Code", "DMVector" }; - logerror("%s: IPU command: VDEC (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: VDEC (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: FB:%d TBL:%s\n", machine().describe_context(), data & 0x3f, vlc[(data >> 26) & 3]); break; } case 0x04: /* FDEC */ - logerror("%s: IPU command: FDEC (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: FDEC (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: FB:%d\n", machine().describe_context(), data & 0x3f); break; case 0x05: /* SETIQ */ - logerror("%s: IPU command: SETIQ (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: SETIQ (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: FB:%d IQM:%s quantization matrix\n", machine().describe_context(), data & 0x3f, BIT(data, 27) ? "Non-intra" : "Intra"); break; case 0x06: /* SETVQ */ - logerror("%s: IPU command: SETVQ (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: SETVQ (%08x & %08x)\n", machine().describe_context(), data, mem_mask); break; case 0x07: /* CSC */ - logerror("%s: IPU command: CSC (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: CSC (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: MBC:%d DTE:%d OFM:%s\n", machine().describe_context(), data & 0x3ff, BIT(data, 26), BIT(data, 27) ? "RGB16" : "RGB32"); break; case 0x08: /* PACK */ - logerror("%s: IPU command: PACK (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: PACK (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: DITHER:%d OFM:%s\n", machine().describe_context(), BIT(data, 26), BIT(data, 27) ? "RGB16" : "INDX4"); break; case 0x09: /* SETTH */ - logerror("%s: IPU command: SETTH (%08x)\n", machine().describe_context(), data); + logerror("%s: IPU command: SETTH (%08x & %08x)\n", machine().describe_context(), data, mem_mask); logerror("%s: TH0:%d TH1:%s\n", machine().describe_context(), data & 0x1ff, (data >> 16) & 0x1ff); break; default: - logerror("%s: Unknown IPU command: %08x\n", machine().describe_context(), data); + logerror("%s: Unknown IPU command: %08x & %08x\n", machine().describe_context(), data, mem_mask); break; } break; case 2: /* IPU_CTRL */ - logerror("%s: ipu_w: IPU_CTRL = %08x\n", machine().describe_context(), data); + logerror("%s: ipu_w: IPU_CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask); if (BIT(data, 30)) { m_ipu_in_fifo_index = 0; @@ -853,10 +464,10 @@ WRITE32_MEMBER(ps2sony_state::ipu_w) } break; case 4: /* IPU_BP */ - logerror("%s: ipu_w: IPU_BP = %08x (Not Valid!)\n", machine().describe_context(), data); + logerror("%s: ipu_w: IPU_BP = %08x & %08x (Not Valid!)\n", machine().describe_context(), data, mem_mask); break; case 6: /* IPU_TOP */ - logerror("%s: ipu_w: IPU_TOP = %08x\n", machine().describe_context(), data); + logerror("%s: ipu_w: IPU_TOP & %08x = %08x\n", machine().describe_context(), data, mem_mask); break; default: logerror("%s: ipu_w: Unknown offset %08x = %08x\n", machine().describe_context(), 0x10002000 + (offset << 3), data); @@ -870,19 +481,19 @@ READ64_MEMBER(ps2sony_state::ipu_fifo_r) switch (offset) { case 0: - logerror("%s: ipu_fifo_r: IPU_OUT_FIFO[127..64] (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: ipu_fifo_r: IPU_OUT_FIFO[127..64] (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; case 1: - logerror("%s: ipu_fifo_r: IPU_OUT_FIFO[63..0] (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); + logerror("%s: ipu_fifo_r: IPU_OUT_FIFO[63..0] (%08x%08x & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; case 2: - logerror("%s: ipu_fifo_r: IPU_IN_FIFO[127..64] (Not Valid!)\n", machine().describe_context()); + logerror("%s: ipu_fifo_r: IPU_IN_FIFO[127..64] & %08x%08x (Not Valid!)\n", machine().describe_context(), (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; case 3: - logerror("%s: ipu_fifo_r: IPU_IN_FIFO[63..0] (Not Valid!)\n", machine().describe_context()); + logerror("%s: ipu_fifo_r: IPU_IN_FIFO[63..0] & %08x%08x (Not Valid!)\n", machine().describe_context(), (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; default: - logerror("%s: ipu_fifo_r: Unknown offset %08x\n", machine().describe_context(), 0x10007000 + (offset << 1)); + logerror("%s: ipu_fifo_r: Unknown offset %08x\n", machine().describe_context(), 0x10007000 + (offset << 1), (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; } return ret; @@ -893,56 +504,31 @@ WRITE64_MEMBER(ps2sony_state::ipu_fifo_w) switch (offset) { case 0: - logerror("%s: ipu_fifo_w: IPU_OUT_FIFO[127..64] = %08x%08x (Not Valid!)\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: ipu_fifo_w: IPU_OUT_FIFO[127..64] = %08x%08x & %08x%08x (Not Valid!)\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; case 1: - logerror("%s: ipu_fifo_w: IPU_OUT_FIFO[63..0] = %08x%08x (Not Valid!)\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: ipu_fifo_w: IPU_OUT_FIFO[63..0] = %08x%08x & %08x%08x (Not Valid!)\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; case 2: - logerror("%s: ipu_fifo_w: IPU_IN_FIFO[127..64] = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: ipu_fifo_w: IPU_IN_FIFO[127..64] = %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); m_ipu_in_fifo[m_ipu_in_fifo_index] = data; m_ipu_in_fifo_index++; m_ipu_in_fifo_index &= 0xf; break; case 3: - logerror("%s: ipu_fifo_w: IPU_IN_FIFO[63..0] = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: ipu_fifo_w: IPU_IN_FIFO[63..0] = %08x%08x & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; default: - logerror("%s: ipu_fifo_w: Unknown offset %08x = %08x%08x\n", machine().describe_context(), 0x10007000 + (offset << 1), (uint32_t)(data >> 32), (uint32_t)data); + logerror("%s: ipu_fifo_w: Unknown offset %08x = %08x%08x & %08x%08x\n", machine().describe_context(), 0x10007000 + (offset << 1), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask); break; } } -void ps2sony_state::check_irq0() -{ - m_maincpu->set_input_line(MIPS3_IRQ0, (m_istat & m_imask) ? ASSERT_LINE : CLEAR_LINE); -} - -void ps2sony_state::check_iop_irq() -{ - bool active = (m_iop_ienable && (m_iop_istat & m_iop_imask)); - logerror("%s: check_iop_irq: %d\n", machine().describe_context(), active ? 1 : 0); - m_iop->set_input_line(R3000_IRQ0, active ? ASSERT_LINE : CLEAR_LINE); -} - -void ps2sony_state::raise_interrupt(int line) -{ - m_istat |= (1 << line); - check_irq0(); -} - -void ps2sony_state::raise_iop_interrupt(int line) -{ - logerror("%s: raise_iop_interrupt: %d\n", machine().describe_context(), line); - m_iop_istat |= (1 << line); - check_iop_irq(); -} - WRITE_LINE_MEMBER(ps2sony_state::iop_timer_irq) { logerror("%s: iop_timer_irq: %d\n", machine().describe_context(), state); if (state) - raise_iop_interrupt(16); + m_iop_intc->raise_interrupt(iop_intc_device::INT_TIMER); } WRITE32_MEMBER(ps2sony_state::iop_debug_w) @@ -950,203 +536,26 @@ WRITE32_MEMBER(ps2sony_state::iop_debug_w) //printf("%08x ", data); } -READ32_MEMBER(ps2sony_state::iop_intc_r) -{ - uint32_t ret = 0; - switch (offset) - { - case 0: // I_STAT - ret = m_iop_istat; - logerror("%s: iop_intc_r: I_STAT %08x\n", machine().describe_context(), ret); - break; - case 1: // I_MASK - ret = m_iop_imask; - logerror("%s: iop_intc_r: I_MASK %08x\n", machine().describe_context(), ret); - break; - case 2: // I_ENABLE - ret = m_iop_ienable; - m_iop_ienable = 0; - check_iop_irq(); - logerror("%s: iop_intc_r: I_ENABLE %08x\n", machine().describe_context(), ret); - break; - default: - logerror("%s: iop_intc_r: Unknown offset %08x\n", machine().describe_context(), 0x1f801070 + (offset << 2)); - break; - } - return ret; -} - -WRITE32_MEMBER(ps2sony_state::iop_intc_w) -{ - switch (offset) - { - case 0: // I_STAT - logerror("%s: iop_intc_w: I_STAT = %08x\n", machine().describe_context(), data); - m_iop_istat &= data; - check_iop_irq(); - break; - case 1: // I_MASK - logerror("%s: iop_intc_w: I_MASK = %08x\n", machine().describe_context(), data); - m_iop_imask = data; - check_iop_irq(); - break; - case 2: // I_ENABLE - logerror("%s: iop_intc_w: I_ENABLE = %08x\n", machine().describe_context(), data); - m_iop_ienable = BIT(data, 0); - check_iop_irq(); - break; - default: - logerror("%s: iop_intc_w: Unknown offset %08x = %08x\n", machine().describe_context(), 0x1f801070 + (offset << 2), data); - break; - } -} - -READ32_MEMBER(ps2sony_state::intc_r) -{ - switch (offset) - { - case 0: // I_STAT - //logerror("%s: intc_r: I_STAT %08x\n", machine().describe_context(), m_istat); - return m_istat; - case 2: // I_MASK - logerror("%s: intc_r: I_MASK %08x\n", machine().describe_context(), m_imask); - return m_imask; - default: - logerror("%s: intc_r: Unknown offset %08x\n", machine().describe_context(), 0x1000f000 + (offset << 2)); - return 0; - } -} - -WRITE32_MEMBER(ps2sony_state::intc_w) -{ - switch (offset) - { - case 0: // I_STAT - logerror("%s: intc_w: I_STAT = %08x\n", machine().describe_context(), data); - m_istat &= ~data; - check_irq0(); - break; - case 2: // I_MASK - logerror("%s: intc_w: I_MASK = %08x\n", machine().describe_context(), data); - m_imask ^= data & 0x7fff; - check_irq0(); - break; - default: - logerror("%s: intc_w: Unknown offset %08x = %08x\n", machine().describe_context(), 0x1000f000 + (offset << 2), data); - break; - } -} - -READ32_MEMBER(ps2sony_state::iop_sif_r) +READ32_MEMBER(ps2sony_state::unk_iop_r) { uint32_t ret = 0; switch (offset) { - case 0: - ret = m_sif_ms_mailbox; - logerror("%s: iop_sif_r: SIF master->slave mailbox (%08x)\n", machine().describe_context(), ret); - break; - case 4: - ret = m_sif_sm_mailbox; - logerror("%s: iop_sif_r: SIF slave->master mailbox (%08x)\n", machine().describe_context(), ret); - break; - case 8: - ret = m_sif_ms_flag; - logerror("%s: iop_sif_r: SIF master->slave flag (%08x)\n", machine().describe_context(), ret); - break; - case 12: - ret = m_sif_sm_flag; - logerror("%s: iop_sif_r: SIF slave->master flag (%08x)\n", machine().describe_context(), ret); - break; - case 16: - ret = m_sif_ctrl | 0xf0000002; - logerror("%s: iop_sif_r: SIF control register (%08x)\n", machine().describe_context(), ret); - break; - default: - logerror("%s: iop_sif_r: Unknown read (%08x)\n", machine().describe_context(), 0x1d000000 + (offset << 2)); - break; - } - return ret; -} - -WRITE32_MEMBER(ps2sony_state::iop_sif_w) -{ - switch (offset) - { - case 4: - logerror("%s: iop_sif_w: SIF set slave->master mailbox (%08x)\n", machine().describe_context(), data); - m_sif_sm_mailbox = data; - break; - case 12: - if (m_sif_sm_flag == 0 && data != 0) - { - //raise_interrupt(INT_SBUS); - } - logerror("%s: iop_sif_w: SIF set slave->master flag (%08x)\n", machine().describe_context(), data); - m_sif_sm_flag |= data; - break; - default: - logerror("%s: iop_sif_w: Unknown write %08x = %08x\n", machine().describe_context(), 0x1d000000 + (offset << 2), data); - break; - } -} - -READ32_MEMBER(ps2sony_state::sif_r) -{ - uint32_t ret = 0; - switch (offset) - { - case 0: - ret = m_sif_ms_mailbox; - logerror("%s: sif_r: SIF master->slave mailbox (%08x)\n", machine().describe_context(), ret); - break; - case 2: - ret = m_sif_sm_mailbox; - logerror("%s: sif_r: SIF slave->master mailbox (%08x)\n", machine().describe_context(), ret); - break; - case 4: - ret = m_sif_ms_flag; - logerror("%s: sif_r: SIF master->slave flag (%08x)\n", machine().describe_context(), ret); - break; - case 6: - ret = m_sif_sm_flag; - logerror("%s: sif_r: SIF slave->master flag (%08x)\n", machine().describe_context(), ret); - break; - case 8: - ret = m_sif_ctrl; - logerror("%s: sif_r: SIF control (%08x)\n", machine().describe_context(), ret); + case 1: + if (mem_mask & 0xff00) + ret |= 0x4000; + logerror("%s; unk_iop_r: Unknown read: %08x = %08x & %08x\n", machine().describe_context(), 0x1f402000 + (offset << 2), ret, mem_mask); break; default: - logerror("%s: sif_r: Unknown (%08x)\n", machine().describe_context(), 0x1000f200 + (offset << 3)); + logerror("%s; unk_iop_r: Unknown read: %08x & %08x\n", machine().describe_context(), 0x1f402000 + (offset << 2), mem_mask); break; } return ret; } -WRITE32_MEMBER(ps2sony_state::sif_w) +WRITE32_MEMBER(ps2sony_state::unk_iop_w) { - switch (offset) - { - case 0: - logerror("%s: sif_w: SIF set master->slave mailbox (%08x)\n", machine().describe_context(), data); - m_sif_ms_mailbox |= data; - break; - case 4: - logerror("%s: sif_w: SIF set master->slave flag (%08x)\n", machine().describe_context(), data); - m_sif_ms_flag |= data; - break; - case 6: - logerror("%s: sif_w: SIF clear slave->master flag (%08x)\n", machine().describe_context(), data); - m_sif_sm_flag &= ~data; - break; - case 8: - logerror("%s: sif_w: SIF control = %08x\n", machine().describe_context(), data); - m_sif_ctrl = data; // ?? - break; - default: - logerror("%s: sif_w: Unknown %08x = %08x\n", machine().describe_context(), 0x1000f200 + (offset << 3), data); - break; - } + logerror("%s; unk_iop_w: Unknown write: %08x = %08x & %08x\n", machine().describe_context(), 0x1f402000 + (offset << 2), data, mem_mask); } void ps2sony_state::machine_start() @@ -1168,31 +577,12 @@ void ps2sony_state::machine_start() save_item(NAME(m_ipu_out_fifo)); save_item(NAME(m_ipu_out_fifo_index)); - save_item(NAME(m_sif_ms_flag)); - save_item(NAME(m_sif_sm_flag)); - save_item(NAME(m_sif_ctrl)); - - save_item(NAME(m_dmac_d5_chcr)); - - save_item(NAME(m_istat)); - save_item(NAME(m_imask)); - - save_item(NAME(m_iop_istat)); - save_item(NAME(m_iop_imask)); - save_item(NAME(m_iop_ienable)); - if (!m_vblank_timer) m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ps2sony_state::vblank), this)); } void ps2sony_state::machine_reset() { - m_istat = 0; - m_imask = 0; - - m_iop_istat = 0; - m_iop_imask = 0; - m_unk_f430_reg = 0; m_unk_f440_reg = 0; m_unk_f440_ret = 0; @@ -1217,8 +607,6 @@ void ps2sony_state::machine_reset() m_sif_ms_flag = 0; m_sif_sm_flag = 0; m_sif_ctrl = 0; - - m_dmac_d5_chcr = 0; } TIMER_CALLBACK_MEMBER(ps2sony_state::vblank) @@ -1226,15 +614,15 @@ TIMER_CALLBACK_MEMBER(ps2sony_state::vblank) if (param) { // VBlank enter - raise_interrupt(INT_VB_ON); - raise_iop_interrupt(0); + m_intc->raise_interrupt(ps2_intc_device::INT_VB_ON); + m_iop_intc->raise_interrupt(iop_intc_device::INT_VB_ON); m_vblank_timer->adjust(m_screen->time_until_pos(0), 0); } else { // VBlank exit - raise_interrupt(INT_VB_OFF); - raise_iop_interrupt(11); + m_intc->raise_interrupt(ps2_intc_device::INT_VB_OFF); + m_iop_intc->raise_interrupt(iop_intc_device::INT_VB_OFF); m_vblank_timer->adjust(m_screen->time_until_pos(480), 1); } } @@ -1266,12 +654,6 @@ READ64_MEMBER(ps2sony_state::board_id_r) return 0x1234; } -READ32_MEMBER(ps2sony_state::unk_f520_r) -{ - // Unknown purpose - BIOS seems to expect this value initially - return 0x1201; -} - READ32_MEMBER(ps2sony_state::unk_f430_r) { logerror("%s: Unknown 1000f430 read: %08x\n", machine().describe_context(), 0); @@ -1452,7 +834,7 @@ uint32_t ps2sony_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma void ps2sony_state::mem_map(address_map &map) { - map(0x00000000, 0x01ffffff).mirror(0xe000000).ram(); // 32 MB RAM + map(0x00000000, 0x01ffffff).mirror(0xe000000).ram().share(m_ram); // 32 MB RAM map(0x10000000, 0x100007ff).rw(m_timer[0], FUNC(ps2_timer_device::read), FUNC(ps2_timer_device::write)).umask64(0x00000000ffffffff); map(0x10000800, 0x10000fff).rw(m_timer[1], FUNC(ps2_timer_device::read), FUNC(ps2_timer_device::write)).umask64(0x00000000ffffffff); map(0x10001000, 0x100017ff).rw(m_timer[2], FUNC(ps2_timer_device::read), FUNC(ps2_timer_device::write)).umask64(0x00000000ffffffff); @@ -1462,15 +844,16 @@ void ps2sony_state::mem_map(address_map &map) map(0x10005000, 0x1000500f).mirror(0xff0).rw(FUNC(ps2sony_state::vif1_fifo_r), FUNC(ps2sony_state::vif1_fifo_w)); map(0x10006000, 0x1000600f).mirror(0xff0).rw(FUNC(ps2sony_state::gif_fifo_r), FUNC(ps2sony_state::gif_fifo_w)); map(0x10007000, 0x1000701f).mirror(0xfe0).rw(FUNC(ps2sony_state::ipu_fifo_r), FUNC(ps2sony_state::ipu_fifo_w)); - map(0x10008000, 0x1000dfff).rw(FUNC(ps2sony_state::dmac_channel_r), FUNC(ps2sony_state::dmac_channel_w)).umask64(0x00000000ffffffff);; - map(0x1000e000, 0x1000efff).rw(FUNC(ps2sony_state::dmac_r), FUNC(ps2sony_state::dmac_w)).umask64(0x00000000ffffffff); - map(0x1000f000, 0x1000f017).rw(FUNC(ps2sony_state::intc_r), FUNC(ps2sony_state::intc_w)).umask64(0x00000000ffffffff); + map(0x10008000, 0x1000dfff).rw(m_dmac, FUNC(ps2_dmac_device::channel_r), FUNC(ps2_dmac_device::channel_w)).umask64(0x00000000ffffffff);; + map(0x1000e000, 0x1000efff).rw(m_dmac, FUNC(ps2_dmac_device::read), FUNC(ps2_dmac_device::write)).umask64(0x00000000ffffffff); + map(0x1000f000, 0x1000f017).rw(m_intc, FUNC(ps2_intc_device::read), FUNC(ps2_intc_device::write)).umask64(0x00000000ffffffff); map(0x1000f130, 0x1000f137).nopr(); map(0x1000f180, 0x1000f187).w(FUNC(ps2sony_state::debug_w)).umask64(0x00000000000000ff); - map(0x1000f200, 0x1000f24f).rw(FUNC(ps2sony_state::sif_r), FUNC(ps2sony_state::sif_w)).umask64(0x00000000ffffffff); + map(0x1000f200, 0x1000f24f).rw(m_sif, FUNC(ps2_sif_device::ee_r), FUNC(ps2_sif_device::ee_w)).umask64(0x00000000ffffffff); map(0x1000f430, 0x1000f437).rw(FUNC(ps2sony_state::unk_f430_r), FUNC(ps2sony_state::unk_f430_w)).umask64(0x00000000ffffffff); // Unknown map(0x1000f440, 0x1000f447).rw(FUNC(ps2sony_state::unk_f440_r), FUNC(ps2sony_state::unk_f440_w)).umask64(0x00000000ffffffff); // Unknown - map(0x1000f520, 0x1000f527).r(FUNC(ps2sony_state::unk_f520_r)).umask64(0x00000000ffffffff); // Unknown + map(0x1000f520, 0x1000f523).r(m_dmac, FUNC(ps2_dmac_device::disable_mask_r)).umask64(0x00000000ffffffff); + map(0x1000f590, 0x1000f593).w(m_dmac, FUNC(ps2_dmac_device::disable_mask_w)).umask64(0x00000000ffffffff); map(0x11000000, 0x11000fff).mirror(0x3000).ram().share(m_vu0_imem); map(0x11004000, 0x11004fff).mirror(0x3000).ram().share(m_vu0_dmem); map(0x11008000, 0x1100bfff).ram().share(m_vu1_imem); @@ -1487,13 +870,14 @@ void ps2sony_state::mem_map(address_map &map) void ps2sony_state::iop_map(address_map &map) { map(0x00000000, 0x001fffff).ram().share(m_iop_ram); - map(0x1d000000, 0x1d00004f).rw(FUNC(ps2sony_state::iop_sif_r), FUNC(ps2sony_state::iop_sif_w)); - map(0x1f402004, 0x1f402007).nopr(); - map(0x1f801070, 0x1f80107b).rw(FUNC(ps2sony_state::iop_intc_r), FUNC(ps2sony_state::iop_intc_w)); - map(0x1f8010f0, 0x1f8010f7).rw(m_iop_dma, FUNC(iop_dma_device::ctrl0_r), FUNC(iop_dma_device::ctrl0_w)); + map(0x1d000000, 0x1d00004f).rw(m_sif, FUNC(ps2_sif_device::iop_r), FUNC(ps2_sif_device::iop_w)); + map(0x1e000000, 0x1e003fff).nopr(); + map(0x1f402000, 0x1f40200f).rw(FUNC(ps2sony_state::unk_iop_r), FUNC(ps2sony_state::unk_iop_w)); + map(0x1f801070, 0x1f80107b).rw(m_iop_intc, FUNC(iop_intc_device::read), FUNC(iop_intc_device::write)); + map(0x1f801080, 0x1f8010f7).rw(m_iop_dma, FUNC(iop_dma_device::bank0_r), FUNC(iop_dma_device::bank0_w)); map(0x1f801450, 0x1f801453).noprw(); map(0x1f8014a0, 0x1f8014af).rw(m_iop_timer, FUNC(iop_timer_device::read), FUNC(iop_timer_device::write)); - map(0x1f801570, 0x1f801577).rw(m_iop_dma, FUNC(iop_dma_device::ctrl1_r), FUNC(iop_dma_device::ctrl1_w)); + map(0x1f801500, 0x1f801577).rw(m_iop_dma, FUNC(iop_dma_device::bank1_r), FUNC(iop_dma_device::bank1_w)); map(0x1f801578, 0x1f80157b).noprw(); map(0x1f802070, 0x1f802073).w(FUNC(ps2sony_state::iop_debug_w)).nopr(); map(0x1fc00000, 0x1fffffff).rom().region("bios", 0); @@ -1510,21 +894,26 @@ MACHINE_CONFIG_START(ps2sony_state::ps2sony) MCFG_MIPS3_DCACHE_SIZE(16384) MCFG_DEVICE_PROGRAM_MAP(mem_map) + MCFG_DEVICE_ADD(m_timer[0], SONYPS2_TIMER, 294912000/2, true) + MCFG_DEVICE_ADD(m_timer[1], SONYPS2_TIMER, 294912000/2, true) + MCFG_DEVICE_ADD(m_timer[2], SONYPS2_TIMER, 294912000/2, false) + MCFG_DEVICE_ADD(m_timer[3], SONYPS2_TIMER, 294912000/2, false) + + MCFG_DEVICE_ADD(m_intc, SONYPS2_INTC, m_maincpu) + MCFG_DEVICE_ADD(m_dmac, SONYPS2_DMAC, 294912000/2, m_maincpu, m_ram, m_sif) + MCFG_DEVICE_ADD(m_sif, SONYPS2_SIF, m_intc) + MCFG_DEVICE_ADD(m_iop, SONYPS2_IOP, XTAL(67'737'600)/2) MCFG_DEVICE_PROGRAM_MAP(iop_map) MCFG_QUANTUM_PERFECT_CPU("maincpu") MCFG_QUANTUM_PERFECT_CPU("iop") - MCFG_DEVICE_ADD(m_timer[0], SONYPS2_TIMER, 294912000/2, true) - MCFG_DEVICE_ADD(m_timer[1], SONYPS2_TIMER, 294912000/2, true) - MCFG_DEVICE_ADD(m_timer[2], SONYPS2_TIMER, 294912000/2, false) - MCFG_DEVICE_ADD(m_timer[3], SONYPS2_TIMER, 294912000/2, false) - + MCFG_DEVICE_ADD(m_iop_intc, SONYIOP_INTC, m_iop) MCFG_DEVICE_ADD(m_iop_timer, SONYIOP_TIMER, XTAL(67'737'600)/2) MCFG_IOP_TIMER_IRQ_CALLBACK(WRITELINE(*this, ps2sony_state, iop_timer_irq)) - MCFG_DEVICE_ADD(m_iop_dma, SONYIOP_DMA, XTAL(67'737'600)/2) + MCFG_DEVICE_ADD(m_iop_dma, SONYIOP_DMA, XTAL(67'737'600)/2, m_iop_intc, m_iop_ram, m_sif) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/machine/iopdma.cpp b/src/mame/machine/iopdma.cpp index dbf1374cd01..1d841555ccb 100644 --- a/src/mame/machine/iopdma.cpp +++ b/src/mame/machine/iopdma.cpp @@ -16,33 +16,156 @@ DEFINE_DEVICE_TYPE(SONYIOP_DMA, iop_dma_device, "iopdma", "Sony IOP DMA") iop_dma_device::iop_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SONYIOP_DMA, tag, owner, clock) + , device_execute_interface(mconfig, *this) + , m_intc(*this, finder_base::DUMMY_TAG) + , m_ram(*this, finder_base::DUMMY_TAG) + , m_sif(*this, finder_base::DUMMY_TAG) + , m_icount(0) { } void iop_dma_device::device_start() { + set_icountptr(m_icount); + + for (uint32_t channel = 0; channel < 16; channel++) + { + save_item(NAME(m_channels[channel].m_priority), channel); + save_item(NAME(m_channels[channel].m_enabled), channel); + save_item(NAME(m_channels[channel].m_busy), channel); + save_item(NAME(m_channels[channel].m_end), channel); + + save_item(NAME(m_channels[channel].m_addr), channel); + save_item(NAME(m_channels[channel].m_block), channel); + save_item(NAME(m_channels[channel].m_ctrl), channel); + save_item(NAME(m_channels[channel].m_tag_addr), channel); + + save_item(NAME(m_channels[channel].m_size), channel); + save_item(NAME(m_channels[channel].m_count), channel); + } + + save_item(NAME(m_running_mask)); + save_item(NAME(m_icount)); + save_item(NAME(m_dpcr[0])); + save_item(NAME(m_dpcr[1])); + save_item(NAME(m_dicr[0])); + save_item(NAME(m_dicr[1])); + save_item(NAME(m_int_ctrl[0].m_mask)); + save_item(NAME(m_int_ctrl[0].m_status)); + save_item(NAME(m_int_ctrl[0].m_enabled)); + save_item(NAME(m_int_ctrl[1].m_mask)); + save_item(NAME(m_int_ctrl[1].m_status)); + save_item(NAME(m_int_ctrl[1].m_enabled)); + + save_item(NAME(m_last_serviced)); } void iop_dma_device::device_reset() { + memset(m_channels, 0, sizeof(channel_t) * 16); + memset(m_int_ctrl, 0, sizeof(intctrl_t) * 2); m_dpcr[0] = 0; m_dpcr[1] = 0; m_dicr[0] = 0; m_dicr[1] = 0; + m_last_serviced = 0; +} + +void iop_dma_device::execute_run() +{ + if (!m_running_mask) + { + m_icount = 0; + return; + } + + while (m_icount > 0) + { + // TODO: Is this right? This doesn't seem right. + for (; m_last_serviced < 16; m_last_serviced++) + { + const uint32_t channel = m_last_serviced; + if (m_channels[channel].enabled() && m_channels[channel].busy()) + { + switch (channel) + { + case 11: + transfer_sif1(channel); + break; + default: + logerror("%s: Attempting to transfer an unimplemented DMA channel (%d)\n", machine().describe_context(), channel); + break; + } + } + } + if (m_last_serviced == 16) + m_last_serviced = 0; + m_icount--; + } } -READ32_MEMBER(iop_dma_device::ctrl0_r) +void iop_dma_device::transfer_sif1(uint32_t chan) +{ + channel_t &channel = m_channels[chan]; + if (channel.m_count) + { + if (m_sif->fifo_depth(1)) + { + printf("."); + const uint64_t data = m_sif->fifo_pop(1); + m_ram[channel.m_addr >> 2] = data; + + channel.m_addr += 4; + channel.m_count--; + } + } + else + { + if (channel.end()) + { + channel.m_ctrl &= ~0x1000000; + channel.m_busy = false; + const uint32_t index = BIT(chan, 3); + const uint8_t subchan = chan & 7; + m_int_ctrl[index].m_status |= (1 << subchan); + m_dicr[index] |= 1 << (subchan + 24); + printf("channel.end\n"); + if (m_int_ctrl[index].m_status & m_int_ctrl[index].m_mask) + { + printf("raising interrupt\n"); + m_intc->raise_interrupt(iop_intc_device::INT_DMA); + } + } + else if (m_sif->fifo_depth(1) >= 4) + { + const uint32_t next_tag = m_sif->fifo_pop(1); + channel.m_addr = next_tag & 0x00ffffff; + channel.m_count = m_sif->fifo_pop(1); + + // ?? + m_sif->fifo_pop(1); + m_sif->fifo_pop(1); + + if (next_tag & 0xc0000000) + { + channel.m_end = true; + } + } + } +} + +READ32_MEMBER(iop_dma_device::bank0_r) { uint32_t ret = 0; switch (offset) { - case 0: // 0x1f8010f0, DPCR + case 0x70/4: // 0x1f8010f0, DPCR ret = m_dpcr[0]; - logerror("%s: ctrl0_r: DPCR (%08x)\n", machine().describe_context(), ret); + logerror("%s: bank0_r: DPCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; - case 1: // 0x1f8010f4, DICR + case 0x74/4: // 0x1f8010f4, DICR ret = m_dicr[0]; - logerror("%s: ctrl0_r: DICR (%08x)\n", machine().describe_context(), ret); + logerror("%s: bank0_r: DICR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; default: // Can't happen @@ -51,16 +174,33 @@ READ32_MEMBER(iop_dma_device::ctrl0_r) return ret; } -WRITE32_MEMBER(iop_dma_device::ctrl0_w) +WRITE32_MEMBER(iop_dma_device::bank0_w) { switch (offset) { - case 0: // 0x1f8010f0, DPCR - logerror("%s: ctrl0_w: DPCR = %08x\n", machine().describe_context(), data); + case 0x00/4: case 0x10/4: case 0x20/4: case 0x30/4: case 0x40/4: case 0x50/4: case 0x60/4: + logerror("%s: bank0_w: channel[%d].addr = %08x & %08x\n", machine().describe_context(), offset >> 2, data, mem_mask); + m_channels[offset >> 2].set_addr(data); + break; + case 0x04/4: case 0x14/4: case 0x24/4: case 0x34/4: case 0x44/4: case 0x54/4: case 0x64/4: + logerror("%s: bank0_w: channel[%d].block = %08x & %08x\n", machine().describe_context(), offset >> 2, data, mem_mask); + m_channels[offset >> 2].set_block(data, mem_mask); + break; + case 0x08/4: case 0x18/4: case 0x28/4: case 0x38/4: case 0x48/4: case 0x58/4: case 0x68/4: + logerror("%s: bank0_w: channel[%d].ctrl = %08x & %08x\n", machine().describe_context(), offset >> 2, data, mem_mask); + m_channels[offset >> 2].set_ctrl(data); + m_running_mask |= m_channels[offset >> 2].busy() ? (1 << (offset >> 2)) : 0; + break; + case 0x0c/4: case 0x1c/4: case 0x2c/4: case 0x3c/4: case 0x4c/4: case 0x5c/4: case 0x6c/4: + logerror("%s: bank0_w: channel[%d].tag_addr = %08x & %08x\n", machine().describe_context(), offset >> 2, data, mem_mask); + m_channels[offset >> 2].set_tag_addr(data); + break; + case 0x70/4: // 0x1f8010f0, DPCR + logerror("%s: bank0_w: DPCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); set_dpcr(data, 0); break; - case 1: // 0x1f8010f4, DICR - logerror("%s: ctrl0_w: DICR = %08x\n", machine().describe_context(), data); + case 0x74/4: // 0x1f8010f4, DICR + logerror("%s: bank0_w: DICR = %08x & %08x\n", machine().describe_context(), data, mem_mask); set_dicr(data, 0); break; default: @@ -69,18 +209,18 @@ WRITE32_MEMBER(iop_dma_device::ctrl0_w) } } -READ32_MEMBER(iop_dma_device::ctrl1_r) +READ32_MEMBER(iop_dma_device::bank1_r) { uint32_t ret = 0; switch (offset) { - case 0: // 0x1f801570, DPCR2 + case 0x70/4: // 0x1f801570, DPCR2 ret = m_dpcr[1]; - logerror("%s: ctrl1_r: DPCR2 (%08x)\n", machine().describe_context(), ret); + logerror("%s: bank1_r: DPCR2 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; - case 1: // 0x1f801574, DICR2 + case 0x74/4: // 0x1f801574, DICR2 ret = m_dicr[1]; - logerror("%s: ctrl1_r: DICR2 (%08x)\n", machine().describe_context(), ret); + logerror("%s: bank1_r: DICR2 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; default: // Can't happen @@ -89,16 +229,33 @@ READ32_MEMBER(iop_dma_device::ctrl1_r) return ret; } -WRITE32_MEMBER(iop_dma_device::ctrl1_w) +WRITE32_MEMBER(iop_dma_device::bank1_w) { - switch (offset) + switch (offset & 0x1f) { - case 0: // 0x1f8010f0, DPCR - logerror("%s: ctrl1_w: DPCR2 = %08x\n", machine().describe_context(), data); + case 0x00/4: case 0x10/4: case 0x20/4: case 0x30/4: case 0x40/4: case 0x50/4: case 0x60/4: + logerror("%s: bank1_w: channel[%d].addr = %08x & %08x\n", machine().describe_context(), (offset >> 2) + 8, data, mem_mask); + m_channels[(offset >> 2) + 8].set_addr(data); + break; + case 0x04/4: case 0x14/4: case 0x24/4: case 0x34/4: case 0x44/4: case 0x54/4: case 0x64/4: + logerror("%s: bank1_w: channel[%d].block = %08x & %08x\n", machine().describe_context(), (offset >> 2) + 8, data, mem_mask); + m_channels[(offset >> 2) + 8].set_block(data, mem_mask); + break; + case 0x08/4: case 0x18/4: case 0x28/4: case 0x38/4: case 0x48/4: case 0x58/4: case 0x68/4: + logerror("%s: bank1_w: channel[%d].ctrl = %08x & %08x\n", machine().describe_context(), (offset >> 2) + 8, data, mem_mask); + m_channels[(offset >> 2) + 8].set_ctrl(data); + m_running_mask |= m_channels[(offset >> 2) + 8].busy() ? (1 << ((offset >> 2) + 8)) : 0; + break; + case 0x0c/4: case 0x1c/4: case 0x2c/4: case 0x3c/4: case 0x4c/4: case 0x5c/4: case 0x6c/4: + logerror("%s: bank1_w: channel[%d].tag_addr = %08x & %08x\n", machine().describe_context(), (offset >> 2) + 8, data, mem_mask); + m_channels[(offset >> 2) + 8].set_tag_addr(data); + break; + case 0x70/4: // 0x1f801570, DPCR2 + logerror("%s: bank1_w: DPCR2 = %08x & %08x\n", machine().describe_context(), data, mem_mask); set_dpcr(data, 1); break; - case 1: // 0x1f8010f4, DICR - logerror("%s: ctrl1_w: DICR2 = %08x\n", machine().describe_context(), data); + case 0x74/4: // 0x1f801574, DICR2 + logerror("%s: bank1_w: DICR2 = %08x & %08x\n", machine().describe_context(), data, mem_mask); set_dicr(data, 1); break; default: @@ -118,14 +275,11 @@ void iop_dma_device::set_dpcr(uint32_t data, uint32_t index) for (uint32_t channel = index*8, bit = 0; channel < index*8 + 8; channel++, bit += 4) { const uint8_t field = (data >> bit) & 0xf; - const bool was_enabled = m_channels[channel].m_enabled; - const bool is_enabled = BIT(field, 3); - m_channels[channel].m_enabled = is_enabled; - m_channels[channel].m_priority = field & 7; - if (!was_enabled && is_enabled) - { - // Check for running status? - } + m_channels[channel].set_pri_ctrl(field); + if (BIT(field, 3)) + m_running_mask |= 0x10000 << channel; + else + m_running_mask &= ~(0x10000 << channel); } } @@ -137,3 +291,33 @@ void iop_dma_device::set_dicr(uint32_t data, uint32_t index) m_int_ctrl[index].m_enabled = BIT(data, 23); update_interrupts(); } + +void iop_dma_device::channel_t::set_pri_ctrl(uint32_t pri_ctrl) +{ + m_enabled = BIT(pri_ctrl, 3); + m_priority = pri_ctrl & 7; +} + +void iop_dma_device::channel_t::set_addr(uint32_t addr) +{ + m_addr = addr; +} + +void iop_dma_device::channel_t::set_block(uint32_t block, uint32_t mem_mask) +{ + if (mem_mask & 0xffff) + m_count = (uint16_t)block; + if (mem_mask & 0xffff0000) + m_size = (uint16_t)(block >> 16); +} + +void iop_dma_device::channel_t::set_ctrl(uint32_t ctrl) +{ + m_ctrl = ctrl; + m_busy = BIT(ctrl, 24); +} + +void iop_dma_device::channel_t::set_tag_addr(uint32_t tag_addr) +{ + m_tag_addr = tag_addr; +} diff --git a/src/mame/machine/iopdma.h b/src/mame/machine/iopdma.h index d39c3f88160..3e17fb54e9c 100644 --- a/src/mame/machine/iopdma.h +++ b/src/mame/machine/iopdma.h @@ -14,16 +14,48 @@ #pragma once +#include "emu.h" +#include "ps2sif.h" +#include "iopintc.h" -class iop_dma_device : public device_t +class iop_dma_device : public device_t, public device_execute_interface { public: + template + iop_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&intc_tag, U &&ram_tag, V &&sif_tag) + : iop_dma_device(mconfig, tag, owner, clock) + { + m_intc.set_tag(std::forward(intc_tag)); + m_ram.set_tag(std::forward(ram_tag)); + m_sif.set_tag(std::forward(sif_tag)); + } + iop_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_READ32_MEMBER(ctrl0_r); - DECLARE_WRITE32_MEMBER(ctrl0_w); - DECLARE_READ32_MEMBER(ctrl1_r); - DECLARE_WRITE32_MEMBER(ctrl1_w); + DECLARE_READ32_MEMBER(bank0_r); + DECLARE_WRITE32_MEMBER(bank0_w); + DECLARE_READ32_MEMBER(bank1_r); + DECLARE_WRITE32_MEMBER(bank1_w); + + enum channel_type : uint32_t + { + MDEC_IN = 0, + MDEC_OUT, + GPU, + CDVD, + SPU, + PIO, + OTC, + UNUSED_BANK0, + SPU2, + UNKNOWN0, + SIF0, + SIF1, + SIO2_IN, + SIO2_OUT, + UNKNOWN1, + UNUSED_BANK1 + }; protected: struct intctrl_t @@ -33,23 +65,68 @@ protected: bool m_enabled; }; - struct channel_t + class channel_t { + friend class iop_dma_device; + + public: + channel_t() + : m_priority(0), m_enabled(false), m_addr(0), m_block(0), m_ctrl(0), m_tag_addr(0), m_size(0), m_count(0) + { + } + + void set_pri_ctrl(uint32_t pri_ctrl); + void set_addr(uint32_t addr); + void set_block(uint32_t block, uint32_t mem_mask); + void set_ctrl(uint32_t ctrl); + void set_tag_addr(uint32_t tag_addr); + + bool enabled() const { return m_enabled; } + bool busy() const { return m_busy; } + uint32_t addr() const { return m_addr; } + uint32_t block() const { return m_block; } + uint32_t ctrl() const { return m_ctrl; } + uint32_t tag_addr() const { return m_tag_addr; } + bool end() const { return m_end; } + + protected: uint8_t m_priority; bool m_enabled; + bool m_busy; + bool m_end; + + uint32_t m_addr; + uint32_t m_block; + uint32_t m_ctrl; + uint32_t m_tag_addr; + + uint32_t m_size; + uint32_t m_count; }; virtual void device_start() override; virtual void device_reset() override; + virtual void execute_run() override; void set_dpcr(uint32_t data, uint32_t index); void set_dicr(uint32_t data, uint32_t index); void update_interrupts(); + void transfer_sif1(uint32_t chan); + + required_device m_intc; + required_shared_ptr m_ram; + required_device m_sif; + + int m_icount; + uint32_t m_dpcr[2]; uint32_t m_dicr[2]; channel_t m_channels[16]; intctrl_t m_int_ctrl[2]; + + uint32_t m_running_mask; + uint32_t m_last_serviced; }; DECLARE_DEVICE_TYPE(SONYIOP_DMA, iop_dma_device) diff --git a/src/mame/machine/iopintc.cpp b/src/mame/machine/iopintc.cpp new file mode 100644 index 00000000000..9b383643d2e --- /dev/null +++ b/src/mame/machine/iopintc.cpp @@ -0,0 +1,98 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 IOP interrupt controller device skeleton +* +* To Do: +* Everything +* +*/ + +#include "iopintc.h" + +DEFINE_DEVICE_TYPE(SONYIOP_INTC, iop_intc_device, "iopintc", "Playstation 2 IOP INTC") + +iop_intc_device::iop_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SONYIOP_INTC, tag, owner, clock) + , m_iop(*this, finder_base::DUMMY_TAG) +{ +} + +void iop_intc_device::device_start() +{ + save_item(NAME(m_status)); + save_item(NAME(m_mask)); + save_item(NAME(m_enabled)); +} + +void iop_intc_device::device_reset() +{ + m_status = 0; + m_mask = 0; + m_enabled = false; +} + +READ32_MEMBER(iop_intc_device::read) +{ + uint32_t ret = 0; + switch (offset) + { + case 0: // I_STAT + ret = m_status; + logerror("%s: read: I_STAT %08x & %08x\n", machine().describe_context(), ret, mem_mask); + break; + case 1: // I_MASK + ret = m_mask; + logerror("%s: read: I_MASK %08x & %08x\n", machine().describe_context(), ret, mem_mask); + break; + case 2: // I_ENABLE + ret = m_enabled ? 1 : 0; + m_enabled = false; + update_interrupts(); + //logerror("%s: read: I_ENABLE %08x & %08x\n", machine().describe_context(), ret, mem_mask); + break; + default: + logerror("%s: read: Unknown offset %08x & %08x\n", machine().describe_context(), 0x1f801070 + (offset << 2), mem_mask); + break; + } + return ret; +} + +WRITE32_MEMBER(iop_intc_device::write) +{ + switch (offset) + { + case 0: // I_STAT + logerror("%s: write: I_STAT = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_status &= data; + update_interrupts(); + break; + case 1: // I_MASK + logerror("%s: write: I_MASK = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_mask = data; + update_interrupts(); + break; + case 2: // I_ENABLE + //logerror("%s: write: I_ENABLE = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_enabled = BIT(data, 0); + update_interrupts(); + break; + default: + logerror("%s: write: Unknown offset %08x = %08x & %08x\n", machine().describe_context(), 0x1f801070 + (offset << 2), data, mem_mask); + break; + } +} + +void iop_intc_device::raise_interrupt(uint32_t line) +{ + logerror("%s: raise_interrupt: %d\n", machine().describe_context(), line); + m_status |= (1 << line); + update_interrupts(); +} + +void iop_intc_device::update_interrupts() +{ + bool active = (m_enabled && (m_status & m_mask)); + m_iop->set_input_line(R3000_IRQ0, active ? ASSERT_LINE : CLEAR_LINE); +} diff --git a/src/mame/machine/iopintc.h b/src/mame/machine/iopintc.h new file mode 100644 index 00000000000..794936fad13 --- /dev/null +++ b/src/mame/machine/iopintc.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 IOP interrupt controller device skeleton +* +* To Do: +* Everything +* +*/ + +#ifndef MAME_MACHINE_IOPINTC_H +#define MAME_MACHINE_IOPINTC_H + +#pragma once + +#include "emu.h" +#include "cpu/mips/r3000.h" + +class iop_intc_device : public device_t +{ +public: + template + iop_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&iop_tag) + : iop_intc_device(mconfig, tag, owner, (uint32_t)0) + { + m_iop.set_tag(std::forward(iop_tag)); + } + + iop_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ32_MEMBER(read); + DECLARE_WRITE32_MEMBER(write); + + void raise_interrupt(uint32_t line); + + enum + { + INT_VB_ON = 0, + INT_DMA = 3, + INT_VB_OFF = 11, + INT_TIMER = 16 + }; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + void update_interrupts(); + + required_device m_iop; + uint32_t m_status; + uint32_t m_mask; + bool m_enabled; +}; + +DECLARE_DEVICE_TYPE(SONYIOP_INTC, iop_intc_device) + +#endif // MAME_MACHINE_IOPINTC_H \ No newline at end of file diff --git a/src/mame/machine/ioptimer.cpp b/src/mame/machine/ioptimer.cpp index 244797d7b41..55b05dbdd61 100644 --- a/src/mame/machine/ioptimer.cpp +++ b/src/mame/machine/ioptimer.cpp @@ -209,18 +209,18 @@ READ32_MEMBER(iop_timer_device::read) update_count(); ret = m_count; if (old != m_count) - logerror("%s: IOP timer read: COUNT (%08x)\n", machine().describe_context(), ret); + logerror("%s: IOP timer read: COUNT (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; } case 0x01: ret = m_ctrl | (m_ovf_int ? CTRL_OVFF : 0) | (m_cmp_int ? CTRL_CMPF : 0); - logerror("%s: IOP timer read: MODE (%08x)\n", machine().describe_context(), ret); + logerror("%s: IOP timer read: MODE (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; case 0x02: ret = m_compare; - logerror("%s: IOP timer read: COMPARE (%08x)\n", machine().describe_context(), ret); + logerror("%s: IOP timer read: COMPARE (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; default: @@ -235,7 +235,7 @@ WRITE32_MEMBER(iop_timer_device::write) { case 0x00: m_count = data; - logerror("%s: IOP timer write: COUNT = %08x\n", machine().describe_context(), data); + logerror("%s: IOP timer write: COUNT = %08x & %08x\n", machine().describe_context(), data, mem_mask); update_compare_timer(); update_overflow_timer(); break; @@ -246,7 +246,7 @@ WRITE32_MEMBER(iop_timer_device::write) case 0x02: { - logerror("%s: IOP timer write: COMPARE = %08x\n", machine().describe_context(), data); + logerror("%s: IOP timer write: COMPARE = %08x & %08x\n", machine().describe_context(), data, mem_mask); if (m_compare == data) break; diff --git a/src/mame/machine/ps2dma.cpp b/src/mame/machine/ps2dma.cpp new file mode 100644 index 00000000000..d81cca0550d --- /dev/null +++ b/src/mame/machine/ps2dma.cpp @@ -0,0 +1,544 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 DMAC device skeleton +* +* To Do: +* Everything +* +*/ + +#include "ps2sif.h" +#include "ps2dma.h" +#include "cpu/mips/mips3.h" + +DEFINE_DEVICE_TYPE(SONYPS2_DMAC, ps2_dmac_device, "ps2dmac", "EE Core DMAC") + +ps2_dmac_device::ps2_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SONYPS2_DMAC, tag, owner, clock) + , device_execute_interface(mconfig, *this) + , m_ee(*this, finder_base::DUMMY_TAG) + , m_ram(*this, finder_base::DUMMY_TAG) + , m_sif(*this, finder_base::DUMMY_TAG) + , m_icount(0) +{ +} + +void ps2_dmac_device::device_start() +{ + set_icountptr(m_icount); + + for (uint32_t channel = 0; channel < 10; channel++) + { + //save_item(NAME(m_channels[channel].m_priority), channel); + } + + save_item(NAME(m_icount)); + save_item(NAME(m_ctrl)); + save_item(NAME(m_mem_drain)); + save_item(NAME(m_enabled)); + + save_item(NAME(m_disable_mask)); + + save_item(NAME(m_istat)); + save_item(NAME(m_imask)); + + save_item(NAME(m_last_serviced)); + + for (uint32_t channel = 0; channel < 10; channel++) + { + save_item(NAME(m_channels[channel].m_chcr), channel); + save_item(NAME(m_channels[channel].m_mode), channel); + save_item(NAME(m_channels[channel].m_enabled), channel); + save_item(NAME(m_channels[channel].m_end_tag), channel); + save_item(NAME(m_channels[channel].m_qwc), channel); + save_item(NAME(m_channels[channel].m_addr), channel); + } +} + +void ps2_dmac_device::device_reset() +{ + m_ctrl = 0; + m_mem_drain = 0; + m_enabled = false; + + m_disable_mask = 0x1201; + + m_istat = 0; + m_imask = 0; + + m_last_serviced = 0; +} + +void ps2_dmac_device::execute_run() +{ + if (!m_enabled || (m_disable_mask & 0x10000)) + { + m_icount = 0; + return; + } + + while (m_icount > 0) + { + for (; m_last_serviced < 10 && m_icount > 0; m_last_serviced++, m_icount--) + { + if (!m_channels[m_last_serviced].enabled()) + continue; + + switch (m_last_serviced) + { + case SIF0: + transfer_sif0(); + break; + } + } + if (m_last_serviced == 10) + m_last_serviced = 0; + } +} + +void ps2_dmac_device::transfer_sif0() +{ + channel_t &channel = m_channels[SIF0]; + const uint32_t count = channel.quadword_count(); + if (count) + { + printf("count\n"); + if (m_sif->fifo_depth(0) > 4) + { + const uint32_t addr = channel.addr(); + for (uint32_t word = 0; word < 4; word++) + { + m_ee->space(AS_PROGRAM).write_dword(addr + word, m_sif->fifo_pop(0)); + } + channel.set_addr(addr + 0x10); + channel.set_quadword_count(count - 1); + } + } + else + { + if (channel.end_tag()) + { + printf("end\n"); + transfer_finish(SIF0); + } + else if (m_sif->fifo_depth(0) >= 2) + { + printf("follow\n"); + } + else + { + } + } +} + +void ps2_dmac_device::follow_tag(uint32_t channel) +{ +} + +void ps2_dmac_device::transfer_finish(uint32_t chan) +{ + channel_t &channel = m_channels[chan]; + channel.set_chcr(channel.chcr() & ~0x100); + m_istat |= (1 << chan); + update_interrupts(); +} + +void ps2_dmac_device::update_interrupts() +{ + logerror("%s: update_interrupts: %d\n", machine().describe_context(), (m_istat & m_imask) ? 1 : 0); + m_ee->set_input_line(MIPS3_IRQ1, (m_istat & m_imask) ? ASSERT_LINE : CLEAR_LINE); +} + +READ32_MEMBER(ps2_dmac_device::read) +{ + uint32_t ret = 0; + switch (offset) + { + case 0: /* D_CTRL */ + ret = m_ctrl; + logerror("%s: dmac_r: D_CTRL (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 2: /* D_STAT */ + ret = m_istat | (m_imask << 16); + logerror("%s: dmac_r: D_STAT (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 4: /* D_PCR */ + logerror("%s: dmac_r: D_PCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 6: /* D_SQWC */ + logerror("%s: dmac_r: D_SQWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 8: /* D_RBSR */ + logerror("%s: dmac_r: D_RBSR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 10: /* D_RBOR */ + logerror("%s: dmac_r: D_RBOR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 12: /* D_STADR */ + logerror("%s: dmac_r: D_STADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + default: + logerror("%s: dmac_r: Unknown offset %08x & %08x\n", machine().describe_context(), 0x1000e000 + (offset << 3), mem_mask); + break; + } + return ret; +} + +WRITE32_MEMBER(ps2_dmac_device::write) +{ + switch (offset) + { + case 0: /* D_CTRL */ + logerror("%s: dmac_w: D_CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask); + logerror("%s: ENABLE=%d MEM_DRAIN=%d\n", machine().describe_context(), BIT(data, 0), (data >> 2) & 3); + m_enabled = BIT(data, 0); + m_mem_drain = (data >> 2) & 3; + break; + case 2: /* D_STAT */ + logerror("%s: dmac_w: D_STAT = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_istat &= ~(data & 0x7fff); + m_imask ^= (data >> 16) & 0x7fff; + update_interrupts(); + break; + case 4: /* D_PCR */ + logerror("%s: dmac_w: D_PCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 6: /* D_SQWC */ + logerror("%s: dmac_w: D_SQWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 8: /* D_RBSR */ + logerror("%s: dmac_w: D_RBSR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 10: /* D_RBOR */ + logerror("%s: dmac_w: D_RBOR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 12: /* D_STADR */ + logerror("%s: dmac_w: D_STADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + default: + logerror("%s: dmac_w: Unknown offset %08x = %08X & %08x\n", machine().describe_context(), 0x1000e000 + (offset << 3), data, mem_mask); + break; + } +} + +READ32_MEMBER(ps2_dmac_device::channel_r) +{ + uint32_t ret = 0; + switch (offset + 0x8000/8) + { + case 0x8000/8: /* D0_CHCR */ + logerror("%s: dmac_channel_r: D0_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x8010/8: /* D0_MADR */ + logerror("%s: dmac_channel_r: D0_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x8020/8: /* D0_QWC */ + logerror("%s: dmac_channel_r: D0_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x8030/8: /* D0_TADR */ + logerror("%s: dmac_channel_r: D0_TADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x8040/8: /* D0_ASR0 */ + logerror("%s: dmac_channel_r: D0_ASR0 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x8050/8: /* D0_ASR1 */ + logerror("%s: dmac_channel_r: D0_ASR1 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x9000/8: /* D1_CHCR */ + logerror("%s: dmac_channel_r: D1_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x9010/8: /* D1_MADR */ + logerror("%s: dmac_channel_r: D1_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x9020/8: /* D1_QWC */ + logerror("%s: dmac_channel_r: D1_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x9030/8: /* D1_TADR */ + logerror("%s: dmac_channel_r: D1_TADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x9040/8: /* D1_ASR0 */ + logerror("%s: dmac_channel_r: D1_ASR0 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0x9050/8: /* D1_ASR1 */ + logerror("%s: dmac_channel_r: D1_ASR1 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xa000/8: /* D2_CHCR */ + logerror("%s: dmac_channel_r: D2_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xa010/8: /* D2_MADR */ + logerror("%s: dmac_channel_r: D2_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xa020/8: /* D2_QWC */ + logerror("%s: dmac_channel_r: D2_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xa030/8: /* D2_TADR */ + logerror("%s: dmac_channel_r: D2_TADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xa040/8: /* D2_ASR0 */ + logerror("%s: dmac_channel_r: D2_ASR0 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xa050/8: /* D2_ASR1 */ + logerror("%s: dmac_channel_r: D2_ASR1 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xb000/8: /* D3_CHCR */ + logerror("%s: dmac_channel_r: D3_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xb010/8: /* D3_MADR */ + logerror("%s: dmac_channel_r: D3_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xb020/8: /* D3_QWC */ + logerror("%s: dmac_channel_r: D3_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xb400/8: /* D4_CHCR */ + logerror("%s: dmac_channel_r: D4_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xb410/8: /* D4_MADR */ + logerror("%s: dmac_channel_r: D4_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xb420/8: /* D4_QWC */ + logerror("%s: dmac_channel_r: D4_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xb430/8: /* D4_TADR */ + logerror("%s: dmac_channel_r: D4_TADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc000/8: /* SIF0_CHCR */ + ret = m_channels[SIF0].chcr(); + logerror("%s: dmac_channel_r: SIF0_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc010/8: /* SIF0_MADR */ + ret = m_channels[SIF0].addr(); + logerror("%s: dmac_channel_r: SIF0_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc020/8: /* SIF0_QWC */ + ret = m_channels[SIF0].quadword_count(); + logerror("%s: dmac_channel_r: SIF0_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc400/8: /* D6_CHCR */ + logerror("%s: dmac_channel_r: D6_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc410/8: /* D6_MADR */ + logerror("%s: dmac_channel_r: D6_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc420/8: /* D6_QWC */ + logerror("%s: dmac_channel_r: D6_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc430/8: /* D6_TADR */ + logerror("%s: dmac_channel_r: D6_TADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc800/8: /* D7_CHCR */ + logerror("%s: dmac_channel_r: D7_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc810/8: /* D7_MADR */ + logerror("%s: dmac_channel_r: D7_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xc820/8: /* D7_QWC */ + logerror("%s: dmac_channel_r: D7_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd000/8: /* D8_CHCR */ + logerror("%s: dmac_channel_r: D8_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd010/8: /* D8_MADR */ + logerror("%s: dmac_channel_r: D8_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd020/8: /* D8_QWC */ + logerror("%s: dmac_channel_r: D8_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd080/8: /* D8_SADR */ + logerror("%s: dmac_channel_r: D8_SADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd400/8: /* D9_CHCR */ + logerror("%s: dmac_channel_r: D9_CHCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd410/8: /* D9_MADR */ + logerror("%s: dmac_channel_r: D9_MADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd420/8: /* D9_QWC */ + logerror("%s: dmac_channel_r: D9_QWC (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd430/8: /* D9_TADR */ + logerror("%s: dmac_channel_r: D9_TADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + case 0xd480/8: /* D9_SADR */ + logerror("%s: dmac_channel_r: D9_SADR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); + break; + default: + logerror("%s: dmac_channel_r: Unknown offset %08x & %08x\n", machine().describe_context(), 0x10008000 + (offset << 3), mem_mask); + break; + } + return ret; +} + +WRITE32_MEMBER(ps2_dmac_device::channel_w) +{ + static const char* mode_strings[4] = { "Normal", "Chain", "Interleave", "Undefined" }; + + switch (offset + 0x8000/8) + { + case 0x8000/8: /* D0_CHCR */ + logerror("%s: dmac_channel_w: D0_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x8010/8: /* D0_MADR */ + logerror("%s: dmac_channel_w: D0_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x8020/8: /* D0_QWC */ + logerror("%s: dmac_channel_w: D0_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x8030/8: /* D0_TADR */ + logerror("%s: dmac_channel_w: D0_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x8040/8: /* D0_ASR0 */ + logerror("%s: dmac_channel_w: D0_ASR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x8050/8: /* D0_ASR1 */ + logerror("%s: dmac_channel_w: D0_ASR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x9000/8: /* D1_CHCR */ + logerror("%s: dmac_channel_w: D1_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x9010/8: /* D1_MADR */ + logerror("%s: dmac_channel_w: D1_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x9020/8: /* D1_QWC */ + logerror("%s: dmac_channel_w: D1_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x9030/8: /* D1_TADR */ + logerror("%s: dmac_channel_w: D1_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x9040/8: /* D1_ASR0 */ + logerror("%s: dmac_channel_w: D1_ASR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x9050/8: /* D1_ASR1 */ + logerror("%s: dmac_channel_w: D1_ASR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xa000/8: /* D2_CHCR */ + logerror("%s: dmac_channel_w: D2_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xa010/8: /* D2_MADR */ + logerror("%s: dmac_channel_w: D2_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xa020/8: /* D2_QWC */ + logerror("%s: dmac_channel_w: D2_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xa030/8: /* D2_TADR */ + logerror("%s: dmac_channel_w: D2_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xa040/8: /* D2_ASR0 */ + logerror("%s: dmac_channel_w: D2_ASR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xa050/8: /* D2_ASR1 */ + logerror("%s: dmac_channel_w: D2_ASR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xb000/8: /* D3_CHCR */ + logerror("%s: dmac_channel_w: D3_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xb010/8: /* D3_MADR */ + logerror("%s: dmac_channel_w: D3_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xb020/8: /* D3_QWC */ + logerror("%s: dmac_channel_w: D3_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xb400/8: /* D4_CHCR */ + logerror("%s: dmac_channel_w: D4_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xb410/8: /* D4_MADR */ + logerror("%s: dmac_channel_w: D4_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xb420/8: /* D4_QWC */ + logerror("%s: dmac_channel_w: D4_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xb430/8: /* D4_TADR */ + logerror("%s: dmac_channel_w: D4_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xc000/8: /* SIF0_CHCR */ + logerror("%s: dmac_channel_w: SIF0_CHCR = %08x & %08x (DIR=%s Memory, MOD=%s, ASP=%d, TTE=%s DMAtag, \n", machine().describe_context(), data, mem_mask, BIT(data, 0) ? "From" : "To", mode_strings[(data >> 2) & 3], (data >> 4) & 3, BIT(data, 6) ? "Transfers" : "Does not transfer"); + logerror("%s: TIE=%d, START=%d, TAG=%04x\n", machine().describe_context(), BIT(data, 7), BIT(data, 8), data >> 16); + m_channels[SIF0].set_chcr(data); + break; + case 0xc010/8: /* SIF0_MADR */ + logerror("%s: dmac_channel_w: SIF0_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_channels[SIF0].set_addr(data); + break; + case 0xc020/8: /* SIF0_QWC */ + logerror("%s: dmac_channel_w: SIF0_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_channels[SIF0].set_quadword_count(data); + break; + case 0xc400/8: /* D6_CHCR */ + logerror("%s: dmac_channel_w: D6_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xc410/8: /* D6_MADR */ + logerror("%s: dmac_channel_w: D6_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xc420/8: /* D6_QWC */ + logerror("%s: dmac_channel_w: D6_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xc430/8: /* D6_TADR */ + logerror("%s: dmac_channel_w: D6_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xc800/8: /* D7_CHCR */ + logerror("%s: dmac_channel_w: D7_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xc810/8: /* D7_MADR */ + logerror("%s: dmac_channel_w: D7_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xc820/8: /* D7_QWC */ + logerror("%s: dmac_channel_w: D7_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd000/8: /* D8_CHCR */ + logerror("%s: dmac_channel_w: D8_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd010/8: /* D8_MADR */ + logerror("%s: dmac_channel_w: D8_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd020/8: /* D8_QWC */ + logerror("%s: dmac_channel_w: D8_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd080/8: /* D8_SADR */ + logerror("%s: dmac_channel_w: D8_SADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd400/8: /* D9_CHCR */ + logerror("%s: dmac_channel_w: D9_CHCR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd410/8: /* D9_MADR */ + logerror("%s: dmac_channel_w: D9_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd420/8: /* D9_QWC */ + logerror("%s: dmac_channel_w: D9_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd430/8: /* D9_TADR */ + logerror("%s: dmac_channel_w: D9_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0xd480/8: /* D9_SADR */ + logerror("%s: dmac_channel_w: D9_SADR = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + default: + logerror("%s: dmac_channel_w: Unknown offset %08x = %08x & %08x\n", machine().describe_context(), 0x10008000 + (offset << 3), data, mem_mask); + break; + } +} + +READ32_MEMBER(ps2_dmac_device::disable_mask_r) +{ + uint32_t ret = m_disable_mask; + logerror("%s: m_disable_mask = %08x & %08x\n", machine().describe_context(), ret, mem_mask); + return ret; +} + +WRITE32_MEMBER(ps2_dmac_device::disable_mask_w) +{ + logerror("%s: m_disable_mask = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_disable_mask = data; +} + +void ps2_dmac_device::channel_t::set_chcr(uint32_t data) +{ + m_chcr = data; + m_mode = (data >> 2) & 3; + bool was_enabled = m_enabled; + m_enabled = BIT(m_chcr, 8); + if (!was_enabled && m_enabled) + { + m_end_tag = m_mode == 0; + } +} \ No newline at end of file diff --git a/src/mame/machine/ps2dma.h b/src/mame/machine/ps2dma.h new file mode 100644 index 00000000000..694b5713a21 --- /dev/null +++ b/src/mame/machine/ps2dma.h @@ -0,0 +1,117 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 DMAC device skeleton +* +* To Do: +* Everything +* +*/ + +#ifndef MAME_MACHINE_PS2DMAC_H +#define MAME_MACHINE_PS2DMAC_H + +#pragma once + +#include "emu.h" + +class ps2_dmac_device : public device_t, public device_execute_interface +{ +public: + template + ps2_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&ee_tag, U &&ram_tag, V &&sif_tag) + : ps2_dmac_device(mconfig, tag, owner, clock) + { + m_ee.set_tag(std::forward(ee_tag)); + m_ram.set_tag(std::forward(ram_tag)); + m_sif.set_tag(std::forward(sif_tag)); + } + + ps2_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + enum channel_type : uint32_t + { + VIF0 = 0, + VIF1, + IPU_OUT, + IPU_IN, + SIF0, + SIF1, + SIF2, + SPR_OUT, + SPR_IN + }; + + DECLARE_READ32_MEMBER(read); + DECLARE_WRITE32_MEMBER(write); + DECLARE_READ32_MEMBER(channel_r); + DECLARE_WRITE32_MEMBER(channel_w); + + DECLARE_READ32_MEMBER(disable_mask_r); + DECLARE_WRITE32_MEMBER(disable_mask_w); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void execute_run() override; + + class channel_t + { + friend class ps2_dmac_device; + + public: + channel_t() + : m_chcr(0), m_mode(0), m_enabled(false), m_end_tag(false), m_addr(0), m_qwc(0) + { + } + + void set_chcr(uint32_t data); + uint32_t chcr() const { return m_chcr; } + uint32_t mode() const { return m_mode; } + bool enabled() const { return m_enabled; } + bool end_tag() const { return m_end_tag; } + + uint32_t addr() const { return m_addr; } + void set_addr(uint32_t addr) { m_addr = addr; } + + uint32_t quadword_count() const { return m_qwc; } + void set_quadword_count(uint32_t qwc) { m_qwc = qwc; } + + protected: + uint32_t m_chcr; + uint32_t m_mode; + bool m_enabled; + bool m_end_tag; + + uint32_t m_addr; + uint32_t m_qwc; + }; + + void transfer_sif0(); + void transfer_finish(uint32_t chan); + void follow_tag(uint32_t channel); + void update_interrupts(); + + required_device m_ee; + required_shared_ptr m_ram; + required_device m_sif; + + int m_icount; + + uint32_t m_ctrl; + uint32_t m_mem_drain; + bool m_enabled; + + uint32_t m_disable_mask; + + uint32_t m_istat; + uint32_t m_imask; + + uint32_t m_last_serviced; + channel_t m_channels[10]; +}; + +DECLARE_DEVICE_TYPE(SONYPS2_DMAC, ps2_dmac_device) + +#endif // MAME_MACHINE_PS2DMAC_H \ No newline at end of file diff --git a/src/mame/machine/ps2intc.cpp b/src/mame/machine/ps2intc.cpp new file mode 100644 index 00000000000..0c9819ec6d8 --- /dev/null +++ b/src/mame/machine/ps2intc.cpp @@ -0,0 +1,79 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 EE interrupt controller device skeleton +* +* To Do: +* Everything +* +*/ + +#include "ps2intc.h" + +DEFINE_DEVICE_TYPE(SONYPS2_INTC, ps2_intc_device, "ps2intc", "Playstation 2 EE INTC") + +ps2_intc_device::ps2_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SONYPS2_INTC, tag, owner, clock) + , m_ee(*this, finder_base::DUMMY_TAG) +{ +} + +void ps2_intc_device::device_start() +{ + save_item(NAME(m_status)); + save_item(NAME(m_mask)); +} + +void ps2_intc_device::device_reset() +{ + m_status = 0; + m_mask = 0; +} + +READ32_MEMBER(ps2_intc_device::read) +{ + switch (offset) + { + case 0: // I_STAT + //logerror("%s: read: I_STAT %08x & %08x\n", machine().describe_context(), m_status, mem_mask); + return m_status; + case 2: // I_MASK + logerror("%s: read: I_MASK %08x & %08x\n", machine().describe_context(), m_mask, mem_mask); + return m_mask; + default: + logerror("%s: read: Unknown offset %08x & %08x\n", machine().describe_context(), 0x1000f000 + (offset << 2), mem_mask); + return 0; + } +} + +WRITE32_MEMBER(ps2_intc_device::write) +{ + switch (offset) + { + case 0: // I_STAT + logerror("%s: write: I_STAT = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_status &= ~data; + update_interrupts(); + break; + case 2: // I_MASK + logerror("%s: write: I_MASK = %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_mask ^= data & 0x7fff; + update_interrupts(); + break; + default: + logerror("%s: intc_w: Unknown offset %08x = %08x & %08x\n", machine().describe_context(), 0x1000f000 + (offset << 2), data, mem_mask); + break; + } +} + +void ps2_intc_device::update_interrupts() +{ + m_ee->set_input_line(MIPS3_IRQ0, (m_status & m_mask) ? ASSERT_LINE : CLEAR_LINE); +} + +void ps2_intc_device::raise_interrupt(uint32_t line) +{ + m_status |= (1 << line); + update_interrupts(); +} diff --git a/src/mame/machine/ps2intc.h b/src/mame/machine/ps2intc.h new file mode 100644 index 00000000000..952dcb8c748 --- /dev/null +++ b/src/mame/machine/ps2intc.h @@ -0,0 +1,70 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 EE interrupt controller device skeleton +* +* To Do: +* Everything +* +*/ + +#ifndef MAME_MACHINE_PS2INTC_H +#define MAME_MACHINE_PS2INTC_H + +#pragma once + +#include "emu.h" +#include "cpu/mips/mips3.h" + +class ps2_intc_device : public device_t +{ +public: + template + ps2_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&ee_tag) + : ps2_intc_device(mconfig, tag, owner, (uint32_t)0) + { + m_ee.set_tag(std::forward(ee_tag)); + } + + ps2_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ32_MEMBER(read); + DECLARE_WRITE32_MEMBER(write); + + void raise_interrupt(uint32_t line); + + enum + { + INT_GS = 0, + INT_SBUS, + INT_VB_ON, + INT_VB_OFF, + INT_VIF0, + INT_VIF1, + INT_VU0, + INT_VU1, + INT_IPU, + INT_TIMER0, + INT_TIMER1, + INT_TIMER2, + INT_TIMER3, + INT_SFIFO, + INT_VU0WD + }; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + void update_interrupts(); + + required_device m_ee; + + uint32_t m_status; + uint32_t m_mask; +}; + +DECLARE_DEVICE_TYPE(SONYPS2_INTC, ps2_intc_device) + +#endif // MAME_MACHINE_PS2SIF_H \ No newline at end of file diff --git a/src/mame/machine/ps2sif.cpp b/src/mame/machine/ps2sif.cpp new file mode 100644 index 00000000000..fbe5b3ba9a5 --- /dev/null +++ b/src/mame/machine/ps2sif.cpp @@ -0,0 +1,187 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 SIF device skeleton +* +* To Do: +* Everything +* +*/ + +#include "ps2sif.h" + +/*static*/ const size_t ps2_sif_device::MAX_FIFO_DEPTH = 0x20; + +DEFINE_DEVICE_TYPE(SONYPS2_SIF, ps2_sif_device, "ps2sif", "Playstation 2 SIF") + +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(MAX_FIFO_DEPTH); + m_fifo[1] = std::make_unique(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 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 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; + 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); + m_fifo_curr[channel]--; + return m_fifo[channel][m_fifo_curr[channel]]; +} + +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]++; +} diff --git a/src/mame/machine/ps2sif.h b/src/mame/machine/ps2sif.h new file mode 100644 index 00000000000..c0c02d30b83 --- /dev/null +++ b/src/mame/machine/ps2sif.h @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/****************************************************************************** +* +* Sony Playstation 2 SIF device skeleton +* +* To Do: +* Everything +* +*/ + +#ifndef MAME_MACHINE_PS2SIF_H +#define MAME_MACHINE_PS2SIF_H + +#pragma once + +#include "emu.h" +#include "ps2intc.h" + +class ps2_sif_device : public device_t +{ +public: + template + ps2_sif_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&intc_tag) + : ps2_sif_device(mconfig, tag, owner, (uint32_t)0) + { + m_intc.set_tag(std::forward(intc_tag)); + } + + ps2_sif_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ32_MEMBER(ee_r); + DECLARE_WRITE32_MEMBER(ee_w); + DECLARE_READ32_MEMBER(iop_r); + DECLARE_WRITE32_MEMBER(iop_w); + + uint32_t fifo_depth(uint32_t channel); + void fifo_push(uint32_t channel, uint32_t value); + uint32_t fifo_pop(uint32_t channel); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + required_device m_intc; + + uint32_t m_ms_mailbox; + uint32_t m_sm_mailbox; + uint32_t m_ms_flag; + uint32_t m_sm_flag; + uint32_t m_ctrl; + + std::unique_ptr m_fifo[2]; + uint32_t m_fifo_curr[2]; + + static const size_t MAX_FIFO_DEPTH; +}; + +DECLARE_DEVICE_TYPE(SONYPS2_SIF, ps2_sif_device) + +#endif // MAME_MACHINE_PS2SIF_H \ No newline at end of file diff --git a/src/mame/machine/ps2timer.cpp b/src/mame/machine/ps2timer.cpp index 01820d203c7..8e3327b2c26 100644 --- a/src/mame/machine/ps2timer.cpp +++ b/src/mame/machine/ps2timer.cpp @@ -201,23 +201,23 @@ READ32_MEMBER(ps2_timer_device::read) update_count(); ret = m_count; if (old != m_count) - logerror("%s: PS2 timer read: COUNT (%08x)\n", machine().describe_context(), ret); + logerror("%s: PS2 timer read: COUNT (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; } case 0x02: ret = m_mode; - logerror("%s: PS2 timer read: MODE (%08x)\n", machine().describe_context(), ret); + logerror("%s: PS2 timer read: MODE (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; case 0x04: ret = m_compare; - logerror("%s: PS2 timer read: COMP (%08x)\n", machine().describe_context(), ret); + logerror("%s: PS2 timer read: COMP (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; case 0x06: ret = m_hold; - logerror("%s: PS2 timer read: HOLD (%08x)\n", machine().describe_context(), ret); + logerror("%s: PS2 timer read: HOLD (%08x & %08x)\n", machine().describe_context(), ret, mem_mask); break; default: @@ -232,7 +232,7 @@ WRITE32_MEMBER(ps2_timer_device::write) { case 0x00: m_count = data; - logerror("%s: PS2 timer write: COUNT = %08x\n", machine().describe_context(), data); + logerror("%s: PS2 timer write: COUNT = %08x & %08x\n", machine().describe_context(), data, mem_mask); update_compare_timer(); update_overflow_timer(); break; @@ -243,7 +243,7 @@ WRITE32_MEMBER(ps2_timer_device::write) case 0x04: { - logerror("%s: PS2 timer write: COMP = %08x\n", machine().describe_context(), data); + logerror("%s: PS2 timer write: COMP = %08x & %08x\n", machine().describe_context(), data, mem_mask); if (m_compare == data) break; @@ -257,7 +257,7 @@ WRITE32_MEMBER(ps2_timer_device::write) if (!m_can_hold) break; - logerror("%s: PS2 timer write: HOLD = %08x\n", machine().describe_context(), data); + logerror("%s: PS2 timer write: HOLD = %08x & %08x\n", machine().describe_context(), data, mem_mask); if (m_hold == data) break; -- cgit v1.2.3