summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2018-07-07 15:50:20 +0200
committer mooglyguy <therealmogminer@gmail.com>2018-07-07 19:55:23 +0200
commit4134ea509bab34f27931186f66865ccf51ee00b2 (patch)
treee3daa1b5492cb895d15da8f6ee078a3e74497784
parent28ffb7fb9825207e8beb22ce6797c3a2da6f84a0 (diff)
ps2sony: checkpoint, nw
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/devices/cpu/mips/mips3.cpp20
-rw-r--r--src/devices/cpu/mips/mips3dsm.cpp18
-rw-r--r--src/devices/cpu/mips/r3000.cpp2
-rw-r--r--src/mame/audio/iopspu.cpp124
-rw-r--r--src/mame/audio/iopspu.h62
-rw-r--r--src/mame/drivers/ps2sony.cpp39
-rw-r--r--src/mame/machine/iopdma.cpp109
-rw-r--r--src/mame/machine/iopdma.h14
-rw-r--r--src/mame/machine/iopintc.h1
-rw-r--r--src/mame/machine/ps2dma.cpp6
11 files changed, 351 insertions, 46 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index f8b42f03e98..77bb1843125 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -3068,6 +3068,8 @@ files {
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/iopspu.cpp",
+ MAME_DIR .. "src/mame/machine/iopspu.h",
MAME_DIR .. "src/mame/machine/ioptimer.cpp",
MAME_DIR .. "src/mame/machine/ioptimer.h",
}
diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp
index 5cb9b147d05..ceaffbd97ce 100644
--- a/src/devices/cpu/mips/mips3.cpp
+++ b/src/devices/cpu/mips/mips3.cpp
@@ -1782,7 +1782,7 @@ void mips3_device::handle_cop0(uint32_t op)
break;
case 0x10: /* RFE */ invalid_instruction(op); break;
- case 0x18: /* ERET logerror("ERET\n"); */ m_core->pc = m_core->cpr[0][COP0_EPC]; SR &= ~SR_EXL; check_irqs(); m_lld_value ^= 0xffffffff; m_ll_value ^= 0xffffffff; break;
+ case 0x18: /* ERET */ m_core->pc = m_core->cpr[0][COP0_EPC]; SR &= ~SR_EXL; check_irqs(); m_lld_value ^= 0xffffffff; m_ll_value ^= 0xffffffff; break;
case 0x20: /* WAIT */ break;
default: handle_extra_cop0(op); break;
}
@@ -3417,9 +3417,21 @@ void r5900le_device::handle_idt(uint32_t op)
if (rd)
{
const uint64_t rsval = m_core->r[rs];
- const uint64_t hi = (uint32_t)(count_leading_zeros((uint32_t)(rsval >> 32)) - 1);
- const uint64_t lo = (uint32_t)(count_leading_zeros((uint32_t)rsval) - 1);
- m_core->r[rd] = (hi << 32) | lo;
+ uint32_t count[2] = { 0 };
+ for (uint32_t word = 0; word < 2; word++)
+ {
+ uint32_t value = (uint32_t)(rsval >> (word * 32));
+ const uint32_t compare = value & (1U << 31);
+ for (int bit = 30; bit > 0; bit--)
+ {
+ value <<= 1;
+ if ((value & (1U << 31)) == compare)
+ count[word]++;
+ else
+ break;
+ }
+ }
+ m_core->r[rd] = ((uint64_t)count[1] << 32) | count[0];
}
break;
case 0x08: /* MMI0 */
diff --git a/src/devices/cpu/mips/mips3dsm.cpp b/src/devices/cpu/mips/mips3dsm.cpp
index a0bb46456ec..e39bbab03c7 100644
--- a/src/devices/cpu/mips/mips3dsm.cpp
+++ b/src/devices/cpu/mips/mips3dsm.cpp
@@ -168,23 +168,23 @@ uint32_t mips3_disassembler::dasm_cop0(uint32_t pc, uint32_t op, std::ostream &s
case 0x1f: /* COP */
switch (op & 0x01ffffff)
{
- case 0x01: util::stream_format(stream, "tlbr"); break;
- case 0x02: util::stream_format(stream, "tlbwi"); break;
- case 0x06: util::stream_format(stream, "tlbwr"); break;
- case 0x08: util::stream_format(stream, "tlbp"); break;
- case 0x10: util::stream_format(stream, "rfe"); flags = STEP_OUT; break;
- case 0x18: util::stream_format(stream, "eret [invalid]"); break;
- default: util::stream_format(stream, "cop0 $%07x", op & 0x01ffffff); break;
+ case 0x01: util::stream_format(stream, "tlbr"); break;
+ case 0x02: util::stream_format(stream, "tlbwi"); break;
+ case 0x06: util::stream_format(stream, "tlbwr"); break;
+ case 0x08: util::stream_format(stream, "tlbp"); break;
+ case 0x10: util::stream_format(stream, "rfe"); flags = STEP_OUT; break;
+ case 0x18: util::stream_format(stream, "eret"); break;
+ default: dasm_extra_cop0(pc, op, stream); break;
}
break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
}
return flags;
}
uint32_t mips3_disassembler::dasm_extra_cop0(uint32_t pc, uint32_t op, std::ostream &stream)
{
- util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff);
+ util::stream_format(stream, "cop0 $%07x", op & 0x01ffffff);
return 0;
}
diff --git a/src/devices/cpu/mips/r3000.cpp b/src/devices/cpu/mips/r3000.cpp
index 8c458e5e6bc..b1e836311f0 100644
--- a/src/devices/cpu/mips/r3000.cpp
+++ b/src/devices/cpu/mips/r3000.cpp
@@ -1076,7 +1076,6 @@ 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];
@@ -1091,7 +1090,6 @@ void r3000_device::execute_run()
}
fflush(stdout);
}
- */
// instruction fetch
m_op = readop(m_pc);
diff --git a/src/mame/audio/iopspu.cpp b/src/mame/audio/iopspu.cpp
new file mode 100644
index 00000000000..0e04e1283d9
--- /dev/null
+++ b/src/mame/audio/iopspu.cpp
@@ -0,0 +1,124 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/******************************************************************************
+*
+* Sony Playstation 2 IOP SPU device skeleton
+*
+* To Do:
+* Everything
+*
+*/
+
+#include "iopspu.h"
+
+DEFINE_DEVICE_TYPE(SONYIOP_SPU, iop_spu_device, "iopspu", "Playstation 2 IOP SPU")
+
+iop_spu_device::iop_spu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SONYIOP_SPU, tag, owner, clock)
+ , m_iop(*this, finder_base::DUMMY_TAG)
+{
+}
+
+void iop_spu_device::device_start()
+{
+ m_ram = std::make_unique<uint16_t[]>(2 * 1024 * 1024); // ?
+}
+
+void iop_spu_device::device_reset()
+{
+ m_status = 0;
+ m_start_port_addr = 0;
+ m_curr_port_addr = 0;
+ m_unknown_0x19a = 0;
+}
+
+void iop_spu_device::dma_write(uint32_t data)
+{
+ //m_ram[m_curr_port_addr] = (uint16_t)(data >> 16);
+ m_curr_port_addr++;
+ //m_ram[m_curr_port_addr] = (uint16_t)data;
+ m_curr_port_addr++;
+
+ m_status &= ~STATUS_DMA_DONE;
+ m_status |= STATUS_DMA_ACTIVE;
+}
+
+void iop_spu_device::dma_done()
+{
+ m_status |= STATUS_DMA_DONE;
+ m_status &= ~STATUS_DMA_ACTIVE;
+}
+
+uint16_t iop_spu_device::port_read()
+{
+ uint16_t ret = m_ram[m_curr_port_addr];
+ m_curr_port_addr++;
+ return ret;
+}
+
+void iop_spu_device::port_write(uint16_t data)
+{
+ m_ram[m_curr_port_addr] = data;
+ m_curr_port_addr++;
+}
+
+READ16_MEMBER(iop_spu_device::read)
+{
+ uint32_t ret = 0;
+ switch (offset)
+ {
+ case 0x19a/2:
+ ret = m_unknown_0x19a;
+ logerror("%s: read: Unknown 0x19a (%04x & %04x)\n", machine().describe_context(), ret, mem_mask);
+ break;
+
+ case 0x1a8/2:
+ ret = (uint16_t)(m_start_port_addr >> 16);
+ logerror("%s: read: PORT_ADDR_HI: %04x & %04x\n", machine().describe_context(), ret, mem_mask);
+ break;
+
+ case 0x1aa/2:
+ ret = (uint16_t)m_start_port_addr;
+ logerror("%s: read: PORT_ADDR_LO: %04x & %04x\n", machine().describe_context(), ret, mem_mask);
+ break;
+
+ case 0x344/2:
+ ret = m_status;
+ logerror("%s: read: STATUS: %04x & %04x\n", machine().describe_context(), ret, mem_mask);
+ break;
+
+ default:
+ logerror("%s: read: Unknown %08x (%04x)\n", machine().describe_context(), 0x1f900000 + (offset << 1), mem_mask);
+ break;
+ }
+ return ret;
+}
+
+WRITE16_MEMBER(iop_spu_device::write)
+{
+ switch (offset)
+ {
+ case 0x19a/2:
+ logerror("%s: write: Unknown 0x19a = %04x & %04x\n", machine().describe_context(), data, mem_mask);
+ m_unknown_0x19a = data;
+ break;
+
+ case 0x1a8/2:
+ logerror("%s: write: PORT_ADDR_HI: %04x & %04x\n", machine().describe_context(), data, mem_mask);
+ m_start_port_addr &= ~0x000f0000;
+ m_start_port_addr |= ((uint32_t)data << 16) & 0x000f0000;
+ m_curr_port_addr = m_start_port_addr;
+ break;
+
+ case 0x1aa/2:
+ logerror("%s: write: PORT_ADDR_LO: %04x & %04x\n", machine().describe_context(), data, mem_mask);
+ m_start_port_addr &= ~0x0000ffff;
+ m_start_port_addr |= data;
+ m_curr_port_addr = m_start_port_addr;
+ break;
+
+ default:
+ logerror("%s: write: Unknown %08x = %04x & %04x\n", machine().describe_context(), 0x1f900000 + (offset << 1), data, mem_mask);
+ break;
+ }
+}
diff --git a/src/mame/audio/iopspu.h b/src/mame/audio/iopspu.h
new file mode 100644
index 00000000000..5c224669f21
--- /dev/null
+++ b/src/mame/audio/iopspu.h
@@ -0,0 +1,62 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/******************************************************************************
+*
+* Sony Playstation 2 IOP SPU device skeleton
+*
+* To Do:
+* Everything
+*
+*/
+
+#ifndef MAME_MACHINE_IOPSPU_H
+#define MAME_MACHINE_IOPSPU_H
+
+#pragma once
+
+#include "emu.h"
+#include "cpu/mips/r3000.h"
+
+class iop_spu_device : public device_t
+{
+public:
+ template <typename T>
+ iop_spu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&iop_tag)
+ : iop_spu_device(mconfig, tag, owner, clock)
+ {
+ m_iop.set_tag(std::forward<T>(iop_tag));
+ }
+
+ iop_spu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_READ16_MEMBER(read);
+ DECLARE_WRITE16_MEMBER(write);
+
+ uint16_t port_read();
+ void port_write(uint16_t data);
+
+ void dma_write(uint32_t data);
+ void dma_done();
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ enum
+ {
+ STATUS_DMA_DONE = (1 << 7),
+ STATUS_DMA_ACTIVE = (1 << 10)
+ };
+
+ required_device<iop_device> m_iop;
+ std::unique_ptr<uint16_t[]> m_ram;
+
+ uint32_t m_status;
+ uint32_t m_start_port_addr;
+ uint32_t m_curr_port_addr;
+ uint32_t m_unknown_0x19a;
+};
+
+DECLARE_DEVICE_TYPE(SONYIOP_SPU, iop_spu_device)
+
+#endif // MAME_MACHINE_IOPSPU_H \ No newline at end of file
diff --git a/src/mame/drivers/ps2sony.cpp b/src/mame/drivers/ps2sony.cpp
index 1b437a2ffd5..37718479825 100644
--- a/src/mame/drivers/ps2sony.cpp
+++ b/src/mame/drivers/ps2sony.cpp
@@ -156,6 +156,7 @@ iLinkSGUID=0x--------
(*) values are not detected
************************************************************************************************************************/
#include "emu.h"
+#include "audio/iopspu.h"
#include "cpu/mips/mips3.h"
#include "cpu/mips/r3000.h"
#include "machine/ioptimer.h"
@@ -182,6 +183,7 @@ public:
, m_iop_timer(*this, "iop_timer")
, m_iop_dma(*this, "iop_dma")
, m_iop_intc(*this, "iop_intc")
+ , m_iop_spu(*this, "iop_spu%u", 1U)
, m_screen(*this, "screen")
, m_ram(*this, "ram")
, m_iop_ram(*this, "iop_ram")
@@ -231,6 +233,10 @@ protected:
DECLARE_WRITE32_MEMBER(iop_debug_w);
DECLARE_READ32_MEMBER(unk_iop_r);
DECLARE_WRITE32_MEMBER(unk_iop_w);
+ DECLARE_WRITE16_MEMBER(iop_spu_w);
+ DECLARE_READ16_MEMBER(iop_spu_r);
+ DECLARE_WRITE16_MEMBER(iop_spu2_w);
+ DECLARE_READ16_MEMBER(iop_spu2_r);
DECLARE_WRITE_LINE_MEMBER(iop_timer_irq);
@@ -246,6 +252,7 @@ protected:
required_device<iop_timer_device> m_iop_timer;
required_device<iop_dma_device> m_iop_dma;
required_device<iop_intc_device> m_iop_intc;
+ required_device_array<iop_spu_device, 2> m_iop_spu;
required_device<screen_device> m_screen;
required_shared_ptr<uint64_t> m_ram;
required_shared_ptr<uint32_t> m_iop_ram;
@@ -533,7 +540,7 @@ WRITE_LINE_MEMBER(ps2sony_state::iop_timer_irq)
WRITE32_MEMBER(ps2sony_state::iop_debug_w)
{
- //printf("%08x ", data);
+ printf("%08x ", data);
}
READ32_MEMBER(ps2sony_state::unk_iop_r)
@@ -558,6 +565,28 @@ WRITE32_MEMBER(ps2sony_state::unk_iop_w)
logerror("%s; unk_iop_w: Unknown write: %08x = %08x & %08x\n", machine().describe_context(), 0x1f402000 + (offset << 2), data, mem_mask);
}
+WRITE16_MEMBER(ps2sony_state::iop_spu2_w)
+{
+ switch (offset)
+ {
+ default:
+ logerror("%s: iop_spu2_w: Unknown %08x = %04x & %04x\n", 0x1f900000 + (offset << 1), data, mem_mask);
+ break;
+ }
+}
+
+READ16_MEMBER(ps2sony_state::iop_spu2_r)
+{
+ uint32_t ret = 0;
+ switch (offset)
+ {
+ default:
+ logerror("%s: iop_spu2_r: Unknown %08x (%04x)\n", 0x1f900000 + (offset << 1), mem_mask);
+ break;
+ }
+ return ret;
+}
+
void ps2sony_state::machine_start()
{
save_item(NAME(m_gs_base_regs));
@@ -629,7 +658,7 @@ TIMER_CALLBACK_MEMBER(ps2sony_state::vblank)
WRITE8_MEMBER(ps2sony_state::debug_w)
{
- //printf("%c", (char)data);
+ printf("%c", (char)data);
}
WRITE64_MEMBER(ps2sony_state::ee_iop_ram_w)
@@ -880,6 +909,8 @@ void ps2sony_state::iop_map(address_map &map)
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(0x1f900000, 0x1f9003ff).rw(m_iop_spu[0], FUNC(iop_spu_device::read), FUNC(iop_spu_device::write));
+ map(0x1f900400, 0x1f9007ff).rw(m_iop_spu[1], FUNC(iop_spu_device::read), FUNC(iop_spu_device::write));
map(0x1fc00000, 0x1fffffff).rom().region("bios", 0);
map(0x1ffe0130, 0x1ffe0133).nopw();
}
@@ -912,8 +943,10 @@ MACHINE_CONFIG_START(ps2sony_state::ps2sony)
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_spu[0], SONYIOP_SPU, XTAL(67'737'600)/2, m_iop)
+ MCFG_DEVICE_ADD(m_iop_spu[1], SONYIOP_SPU, XTAL(67'737'600)/2, m_iop)
- MCFG_DEVICE_ADD(m_iop_dma, SONYIOP_DMA, XTAL(67'737'600)/2, m_iop_intc, m_iop_ram, m_sif)
+ MCFG_DEVICE_ADD(m_iop_dma, SONYIOP_DMA, XTAL(67'737'600)/2, m_iop_intc, m_iop_ram, m_sif, m_iop_spu[0], m_iop_spu[1])
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
diff --git a/src/mame/machine/iopdma.cpp b/src/mame/machine/iopdma.cpp
index 68b36f8527b..d619779011f 100644
--- a/src/mame/machine/iopdma.cpp
+++ b/src/mame/machine/iopdma.cpp
@@ -20,6 +20,8 @@ iop_dma_device::iop_dma_device(const machine_config &mconfig, const char *tag, d
, m_intc(*this, finder_base::DUMMY_TAG)
, m_ram(*this, finder_base::DUMMY_TAG)
, m_sif(*this, finder_base::DUMMY_TAG)
+ , m_spu(*this, finder_base::DUMMY_TAG)
+ , m_spu2(*this, finder_base::DUMMY_TAG)
, m_icount(0)
{
}
@@ -90,10 +92,14 @@ void iop_dma_device::execute_run()
{
switch (channel)
{
- case 10:
+ case SPU:
+ case SPU2:
+ transfer_spu(channel);
+ break;
+ case SIF0:
transfer_sif0(channel);
break;
- case 11:
+ case SIF1:
transfer_sif1(channel);
break;
default:
@@ -140,7 +146,7 @@ void iop_dma_device::transfer_sif0(uint32_t chan)
logerror("%s: following sif0 iop tag, full tag is %08x %08x %08x %08x\n", machine().describe_context(), iop_hi, iop_lo, ee_hi, ee_lo);
channel.set_addr(iop_hi & 0x00ffffff);
- channel.set_count(iop_lo + 2);
+ channel.set_count((iop_lo + 3) & ~3);
channel.set_tag_addr(tag_addr_bytes + 0x10);
m_sif->fifo_push(0, ee_hi);
@@ -148,7 +154,7 @@ void iop_dma_device::transfer_sif0(uint32_t chan)
if (iop_hi & 0xc0000000)
{
- logerror("%s: sif0 iop tag end\n", machine().describe_context());
+ //logerror("%s: sif0 iop tag end\n", machine().describe_context());
channel.m_end = true;
}
}
@@ -163,7 +169,7 @@ void iop_dma_device::transfer_sif1(uint32_t chan)
if (m_sif->fifo_depth(1))
{
const uint32_t data = m_sif->fifo_pop(1);
- logerror("%s: sif1 pop value: %08x\n", machine().describe_context(), (uint32_t)data);
+ //logerror("%s: sif1 pop value: %08x\n", machine().describe_context(), (uint32_t)data);
m_ram[channel.m_addr >> 2] = data;
channel.m_addr += 4;
@@ -189,13 +195,48 @@ void iop_dma_device::transfer_sif1(uint32_t chan)
if (iop_hi & 0xc0000000)
{
- logerror("%s: sif1 iop tag end\n", machine().describe_context());
+ //logerror("%s: sif1 iop tag end\n", machine().describe_context());
channel.m_end = true;
}
}
}
}
+void iop_dma_device::transfer_spu(uint32_t chan)
+{
+ channel_t &channel = m_channels[chan];
+ const uint32_t size = channel.size();
+ if (size)
+ {
+ printf("Size: %08x\n", size);
+ const uint32_t addr = channel.addr();
+
+ if (chan == SPU)
+ m_spu->dma_write(m_ram[addr >> 2]);
+ else
+ m_spu2->dma_write(m_ram[addr >> 2]);
+
+ channel.set_size(size - 1);
+ channel.set_addr(addr + 4);
+ }
+ else
+ {
+ channel.set_count(0);
+
+ if (chan == SPU)
+ m_spu->dma_done();
+ else
+ m_spu2->dma_done();
+
+ if (chan == SPU)
+ {
+ m_intc->raise_interrupt(iop_intc_device::INT_SPU);
+ }
+
+ transfer_finish(chan);
+ }
+}
+
void iop_dma_device::transfer_finish(uint32_t chan)
{
channel_t &channel = m_channels[chan];
@@ -210,18 +251,6 @@ void iop_dma_device::transfer_finish(uint32_t chan)
if (m_int_ctrl[index].m_status & m_int_ctrl[index].m_mask)
{
m_intc->raise_interrupt(iop_intc_device::INT_DMA);
- if (m_int_ctrl[index].m_enabled)
- {
- m_dicr[index] |= 0x80000000;
- }
- else
- {
- m_dicr[index] &= ~0x80000000;
- }
- }
- else
- {
- m_dicr[index] &= ~0x80000000;
}
}
@@ -230,16 +259,34 @@ READ32_MEMBER(iop_dma_device::bank0_r)
uint32_t ret = 0;
switch (offset)
{
+ case 0x00/4: case 0x10/4: case 0x20/4: case 0x30/4: case 0x40/4: case 0x50/4: case 0x60/4:
+ ret = m_channels[offset >> 2].addr();
+ logerror("%s: bank0_r: channel[%d].addr (%08x & %08x)\n", machine().describe_context(), offset >> 2, ret, mem_mask);
+ break;
+ case 0x04/4: case 0x14/4: case 0x24/4: case 0x34/4: case 0x44/4: case 0x54/4: case 0x64/4:
+ ret = (m_channels[offset >> 2].count() << 16) | m_channels[offset >> 2].size();
+ logerror("%s: bank0_r: channel[%d].block (%08x & %08x)\n", machine().describe_context(), offset >> 2, ret, mem_mask);
+ break;
+ case 0x08/4: case 0x18/4: case 0x28/4: case 0x38/4: case 0x48/4: case 0x58/4: case 0x68/4:
+ ret = m_channels[offset >> 2].ctrl();
+ logerror("%s: bank0_r: channel[%d].ctrl (%08x & %08x)\n", machine().describe_context(), offset >> 2, ret, mem_mask);
+ break;
+ case 0x0c/4: case 0x1c/4: case 0x2c/4: case 0x3c/4: case 0x4c/4: case 0x5c/4: case 0x6c/4:
+ ret = m_channels[offset >> 2].tag_addr();
+ logerror("%s: bank0_r: channel[%d].tag_addr (%08x & %08x)\n", machine().describe_context(), offset >> 2, ret, mem_mask);
+ break;
case 0x70/4: // 0x1f8010f0, DPCR
ret = m_dpcr[0];
logerror("%s: bank0_r: DPCR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
break;
case 0x74/4: // 0x1f8010f4, DICR
ret = m_dicr[0];
+ if ((m_int_ctrl[0].m_status & m_int_ctrl[0].m_mask) && m_int_ctrl[0].m_enabled)
+ ret |= 0x80000000;
logerror("%s: bank0_r: DICR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
break;
default:
- // Can't happen
+ logerror("%s: bank0_r: Unknown %08x & %08x\n", machine().describe_context(), 0x1f801080 + (offset << 2), mem_mask);
break;
}
return ret;
@@ -275,7 +322,7 @@ WRITE32_MEMBER(iop_dma_device::bank0_w)
set_dicr(data, 0);
break;
default:
- // Can't happen
+ logerror("%s: bank0_w: Unknown %08x = %08x & %08x\n", machine().describe_context(), 0x1f801080 + (offset << 2), data, mem_mask);
break;
}
}
@@ -285,16 +332,34 @@ READ32_MEMBER(iop_dma_device::bank1_r)
uint32_t ret = 0;
switch (offset)
{
+ case 0x00/4: case 0x10/4: case 0x20/4: case 0x30/4: case 0x40/4: case 0x50/4: case 0x60/4:
+ ret = m_channels[(offset >> 2) + 8].addr();
+ logerror("%s: bank1_r: channel[%d].addr (%08x & %08x)\n", machine().describe_context(), (offset >> 2) + 8, ret, mem_mask);
+ break;
+ case 0x04/4: case 0x14/4: case 0x24/4: case 0x34/4: case 0x44/4: case 0x54/4: case 0x64/4:
+ ret = (m_channels[(offset >> 2) + 8].count() << 16) | m_channels[(offset >> 2) + 8].size();
+ logerror("%s: bank1_r: channel[%d].block (%08x & %08x)\n", machine().describe_context(), (offset >> 2) + 8, ret, mem_mask);
+ break;
+ case 0x08/4: case 0x18/4: case 0x28/4: case 0x38/4: case 0x48/4: case 0x58/4: case 0x68/4:
+ ret = m_channels[(offset >> 2) + 8].ctrl();
+ logerror("%s: bank1_r: channel[%d].ctrl (%08x & %08x)\n", machine().describe_context(), (offset >> 2) + 8, ret, mem_mask);
+ break;
+ case 0x0c/4: case 0x1c/4: case 0x2c/4: case 0x3c/4: case 0x4c/4: case 0x5c/4: case 0x6c/4:
+ ret = m_channels[(offset >> 2) + 8].tag_addr();
+ logerror("%s: bank1_r: channel[%d].tag_addr (%08x & %08x)\n", machine().describe_context(), (offset >> 2) + 8, ret, mem_mask);
+ break;
case 0x70/4: // 0x1f801570, DPCR2
ret = m_dpcr[1];
logerror("%s: bank1_r: DPCR2 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
break;
case 0x74/4: // 0x1f801574, DICR2
ret = m_dicr[1];
+ if ((m_int_ctrl[1].m_status & m_int_ctrl[1].m_mask) && m_int_ctrl[1].m_enabled)
+ ret |= 0x80000000;
logerror("%s: bank1_r: DICR2 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
break;
default:
- // Can't happen
+ logerror("%s: bank1_r: Unknown %08x & %08x\n", machine().describe_context(), 0x1f801500 + (offset << 2), mem_mask);
break;
}
return ret;
@@ -330,7 +395,7 @@ WRITE32_MEMBER(iop_dma_device::bank1_w)
set_dicr(data, 1);
break;
default:
- // Can't happen
+ logerror("%s: bank1_w: Unknown %08x = %08x & %08x\n", machine().describe_context(), 0x1f801500 + (offset << 2), data, mem_mask);
break;
}
}
diff --git a/src/mame/machine/iopdma.h b/src/mame/machine/iopdma.h
index c95ec0bb799..1c17f324813 100644
--- a/src/mame/machine/iopdma.h
+++ b/src/mame/machine/iopdma.h
@@ -17,17 +17,20 @@
#include "emu.h"
#include "ps2sif.h"
#include "iopintc.h"
+#include "audio/iopspu.h"
class iop_dma_device : public device_t, public device_execute_interface
{
public:
- template <typename T, typename U, typename V>
- 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)
+ template <typename T, typename U, typename V, typename W, typename X>
+ 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, W &&spu_tag, X &&spu2_tag)
: iop_dma_device(mconfig, tag, owner, clock)
{
m_intc.set_tag(std::forward<T>(intc_tag));
m_ram.set_tag(std::forward<U>(ram_tag));
m_sif.set_tag(std::forward<V>(sif_tag));
+ m_spu.set_tag(std::forward<W>(spu_tag));
+ m_spu2.set_tag(std::forward<X>(spu2_tag));
}
iop_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@@ -78,6 +81,7 @@ protected:
void set_pri_ctrl(uint32_t pri_ctrl);
void set_addr(uint32_t addr) { m_addr = addr; }
void set_block(uint32_t block, uint32_t mem_mask);
+ void set_size(uint32_t size) { m_size = size; }
void set_count(uint32_t count) { m_count = count; }
void set_ctrl(uint32_t ctrl);
void set_tag_addr(uint32_t tag_addr) { m_tag_addr = tag_addr; }
@@ -86,10 +90,11 @@ protected:
bool busy() const { return m_busy; }
uint32_t addr() const { return m_addr; }
uint32_t block() const { return m_block; }
+ uint32_t size() const { return m_size; }
+ uint32_t count() const { return m_count; }
uint32_t ctrl() const { return m_ctrl; }
uint32_t tag_addr() const { return m_tag_addr; }
bool end() const { return m_end; }
- uint32_t count() const { return m_count; }
protected:
uint8_t m_priority;
@@ -116,11 +121,14 @@ protected:
void transfer_sif0(uint32_t chan);
void transfer_sif1(uint32_t chan);
+ void transfer_spu(uint32_t chan);
void transfer_finish(uint32_t chan);
required_device<iop_intc_device> m_intc;
required_shared_ptr<uint32_t> m_ram;
required_device<ps2_sif_device> m_sif;
+ required_device<iop_spu_device> m_spu;
+ required_device<iop_spu_device> m_spu2;
int m_icount;
diff --git a/src/mame/machine/iopintc.h b/src/mame/machine/iopintc.h
index 794936fad13..d2e4fb6bfbf 100644
--- a/src/mame/machine/iopintc.h
+++ b/src/mame/machine/iopintc.h
@@ -38,6 +38,7 @@ public:
{
INT_VB_ON = 0,
INT_DMA = 3,
+ INT_SPU = 9,
INT_VB_OFF = 11,
INT_TIMER = 16
};
diff --git a/src/mame/machine/ps2dma.cpp b/src/mame/machine/ps2dma.cpp
index 58624b959f6..90153ae44ac 100644
--- a/src/mame/machine/ps2dma.cpp
+++ b/src/mame/machine/ps2dma.cpp
@@ -115,7 +115,7 @@ void ps2_dmac_device::transfer_sif0()
{
if (m_sif->fifo_depth(0) >= 4)
{
- logerror("%s: SIF0 depth is %d\n", machine().describe_context(), m_sif->fifo_depth(0));
+ //logerror("%s: SIF0 depth is %d\n", machine().describe_context(), m_sif->fifo_depth(0));
uint32_t addr = channel.addr();
for (int word = 0; word < 4; word++)
{
@@ -126,7 +126,7 @@ void ps2_dmac_device::transfer_sif0()
}
channel.set_addr(addr);
channel.set_quadword_count(count - 1);
- logerror("%s: SIF0 remaining count: %08x\n", machine().describe_context(), channel.quadword_count());
+ //logerror("%s: SIF0 remaining count: %08x\n", machine().describe_context(), channel.quadword_count());
}
}
else if (channel.end_tag())
@@ -182,7 +182,7 @@ void ps2_dmac_device::transfer_sif1()
}
else
{
- //logerror("%s: DMAC SIF1 following source tag\n", machine().describe_context());
+ logerror("%s: DMAC SIF1 following source tag\n", machine().describe_context());
follow_source_tag(SIF1);
}
}