mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
ps2sony: Checkpoint. Adds a bunch of vector and parallel ops to the EE core, and skeleton GIF VIF1, and GS devices.
This commit is contained in:
parent
1d987e9f2a
commit
cf34ccd3b4
@ -3060,14 +3060,22 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/pve500.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/smc777.cpp",
|
||||
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/ps2dma.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2dma.h",
|
||||
MAME_DIR .. "src/mame/machine/ps2gif.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2gif.h",
|
||||
MAME_DIR .. "src/mame/machine/ps2intc.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2intc.h",
|
||||
MAME_DIR .. "src/mame/machine/ps2mc.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2mc.h",
|
||||
MAME_DIR .. "src/mame/machine/ps2pad.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2pad.h",
|
||||
MAME_DIR .. "src/mame/machine/ps2sif.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2sif.h",
|
||||
MAME_DIR .. "src/mame/machine/ps2timer.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2timer.h",
|
||||
MAME_DIR .. "src/mame/machine/ps2vif1.cpp",
|
||||
MAME_DIR .. "src/mame/machine/ps2vif1.h",
|
||||
MAME_DIR .. "src/mame/machine/iopcdvd.cpp",
|
||||
MAME_DIR .. "src/mame/machine/iopcdvd.h",
|
||||
MAME_DIR .. "src/mame/machine/iopdma.cpp",
|
||||
@ -3080,6 +3088,8 @@ files {
|
||||
MAME_DIR .. "src/mame/machine/ioptimer.h",
|
||||
MAME_DIR .. "src/mame/audio/iopspu.cpp",
|
||||
MAME_DIR .. "src/mame/audio/iopspu.h",
|
||||
MAME_DIR .. "src/mame/video/ps2gs.cpp",
|
||||
MAME_DIR .. "src/mame/video/ps2gs.h",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "sord")
|
||||
|
@ -283,7 +283,8 @@ void mips3_device::generate_exception(int exception, int backup)
|
||||
/* most exceptions go to offset 0x180, except for TLB stuff */
|
||||
if (exception >= EXCEPTION_TLBMOD && exception <= EXCEPTION_TLBSTORE)
|
||||
{
|
||||
osd_printf_debug("TLB miss @ %08X\n", (uint32_t)m_core->cpr[0][COP0_BadVAddr]);
|
||||
//printf("TLB miss @ %08X\n", (uint32_t)m_core->cpr[0][COP0_BadVAddr]);
|
||||
//machine().debug_break();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -313,7 +314,7 @@ void mips3_device::generate_tlb_exception(int exception, offs_t address)
|
||||
|
||||
void mips3_device::invalid_instruction(uint32_t op)
|
||||
{
|
||||
printf("Invalid instruction! %08x\n", op);
|
||||
fatalerror("Invalid instruction! %08x\n", op);
|
||||
generate_exception(EXCEPTION_INVALIDOP, 1);
|
||||
}
|
||||
|
||||
@ -345,9 +346,6 @@ void mips3_device::device_start()
|
||||
|
||||
/* initialize based on the config */
|
||||
memset(m_core, 0, sizeof(internal_mips3_state));
|
||||
m_core->vfr[0][3] = 1.0f;
|
||||
m_core->vfmem = &m_core->vumem[0];
|
||||
m_core->vimem = reinterpret_cast<uint32_t*>(m_core->vfmem);
|
||||
|
||||
m_cpu_clock = clock();
|
||||
m_program = &space(AS_PROGRAM);
|
||||
@ -1072,6 +1070,13 @@ void mips3_device::device_reset()
|
||||
m_core->mode = (MODE_KERNEL << 1) | 0;
|
||||
m_cache_dirty = true;
|
||||
m_interrupt_cycles = 0;
|
||||
|
||||
m_core->vfr[0][3] = 1.0f;
|
||||
m_core->vfmem = &m_core->vumem[0];
|
||||
m_core->vimem = reinterpret_cast<uint32_t*>(m_core->vfmem);
|
||||
m_core->vr = &m_core->vcr[20];
|
||||
m_core->i = reinterpret_cast<float*>(&m_core->vcr[21]);
|
||||
m_core->q = reinterpret_cast<float*>(&m_core->vcr[22]);
|
||||
}
|
||||
|
||||
|
||||
@ -2929,6 +2934,7 @@ void mips3_device::handle_extra_cop2(uint32_t op)
|
||||
|
||||
void r5900le_device::handle_extra_cop2(uint32_t op)
|
||||
{
|
||||
// TODO: Flags, rounding...
|
||||
const int rd = (op >> 6) & 31;
|
||||
const int rs = (op >> 11) & 31;
|
||||
const int rt = (op >> 16) & 31;
|
||||
@ -2936,25 +2942,136 @@ void r5900le_device::handle_extra_cop2(uint32_t op)
|
||||
|
||||
switch (op & 0x3f)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
printf("Unsupported instruction: VADDbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
printf("Unsupported instruction: VSUBbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
printf("Unsupported instruction: VMADDbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: /* VADDbc */
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] + ft[bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x04: case 0x05: case 0x06: case 0x07: /* VSUBbc */
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] - ft[bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b: /* VMADDbc */
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = m_core->vacc[field] + fs[field] + ft[bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
||||
printf("Unsupported instruction: VMSUBbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
printf("Unsupported instruction: VMAXbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
printf("Unsupported instruction: VMINIbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x18: case 0x19: case 0x1a: case 0x1b:
|
||||
printf("Unsupported instruction: VMULbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x1c: printf("Unsupported instruction: VMULq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: /* VMAXbc */
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = std::fmax(fs[field], ft[bc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x14: case 0x15: case 0x16: case 0x17: /* VMINIbc */
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = std::fmin(fs[field], ft[bc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x18: case 0x19: case 0x1a: case 0x1b: /* VMULbc */
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] * ft[bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x1c: /* VMULq */
|
||||
if (rd)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] * ft[field];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x1d: printf("Unsupported instruction: VMAXi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x1e: printf("Unsupported instruction: VMULi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x1f: printf("Unsupported instruction: VMINIi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x20: printf("Unsupported instruction: VADDq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x20: /* VADDq */
|
||||
if (rd)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] + *(m_core->q);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x21: printf("Unsupported instruction: VMADDq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x22: printf("Unsupported instruction: VADDi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x23: printf("Unsupported instruction: VMADDi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
@ -2962,26 +3079,67 @@ void r5900le_device::handle_extra_cop2(uint32_t op)
|
||||
case 0x25: printf("Unsupported instruction: VMSUBq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x26: printf("Unsupported instruction: VSUBi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x27: printf("Unsupported instruction: VMSUBi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x28: printf("Unsupported instruction: VADD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x29: printf("Unsupported instruction: VMADD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2a: printf("Unsupported instruction: VMUL @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2b: printf("Unsupported instruction: VMAX @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2c:
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rt];
|
||||
for (int field = 0; field < 4; field++)
|
||||
case 0x28: /* VADD */
|
||||
if (rd)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
fd[field] = fs[field] - ft[field];
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] + ft[field];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x29: printf("Unsupported instruction: VMADD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2a: /* VMUL */
|
||||
if (rd)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] * ft[field];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2b: printf("Unsupported instruction: VMAX @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2c: /* VSUB */
|
||||
{
|
||||
if (rd)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = fs[field] - ft[field];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x2d: printf("Unsupported instruction: VMSUB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2e: printf("Unsupported instruction: VOPMSUB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2e: /* VOPMSUB */
|
||||
if (rd)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
fd[0] = m_core->vacc[0] - fs[1] * ft[2];
|
||||
fd[1] = m_core->vacc[1] - fs[2] * ft[0];
|
||||
fd[2] = m_core->vacc[2] - fs[0] * ft[1];
|
||||
}
|
||||
break;
|
||||
case 0x2f: printf("Unsupported instruction: VMINI @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x30:
|
||||
if (rd)
|
||||
@ -3002,20 +3160,72 @@ void r5900le_device::handle_extra_cop2(uint32_t op)
|
||||
printf("Unsupported instruction: VADDAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
printf("Unsupported instruction: VSUBAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
printf("Unsupported instruction: VMADDAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b: /* VMADDAbc */
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
float *fd = m_core->vfr[rd];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
fd[field] = m_core->vacc[field] + fs[field] * ft[bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
||||
printf("Unsupported instruction: VMSUBAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x10: printf("Unsupported instruction: VITOF0 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x11: printf("Unsupported instruction: VITOF4 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x12: printf("Unsupported instruction: VITOF12 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x13: printf("Unsupported instruction: VITOF15 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x14: printf("Unsupported instruction: VFTOI0 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x15: printf("Unsupported instruction: VFTOI4 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x14: /* VFTOI0 */
|
||||
if (rt)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
int32_t *ft = reinterpret_cast<int32_t*>(m_core->vfr[rt]);
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
ft[field] = (int32_t)(fs[field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x15: /* VFTOI4 */
|
||||
if (rt)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
int32_t *ft = reinterpret_cast<int32_t*>(m_core->vfr[rt]);
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
ft[field] = (int32_t)(fs[field] * 16.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x16: printf("Unsupported instruction: VFTOI12 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x17: printf("Unsupported instruction: VFTOI15 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x18: case 0x19: case 0x1a: case 0x1b:
|
||||
printf("Unsupported instruction: VMULAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x18: case 0x19: case 0x1a: case 0x1b: /* VMULAbc */
|
||||
{
|
||||
const uint32_t bc = op & 3;
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
m_core->vacc[field] = fs[field] * ft[bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x1c: printf("Unsupported instruction: VMULAq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x1d: printf("Unsupported instruction: VABS @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x1e: printf("Unsupported instruction: VMULAi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
@ -3034,16 +3244,51 @@ void r5900le_device::handle_extra_cop2(uint32_t op)
|
||||
// 2b?
|
||||
case 0x2c: printf("Unsupported instruction: VSUBA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2d: printf("Unsupported instruction: VMSUBA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2e: printf("Unsupported instruction: VOPMULA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2f: printf("Unsupported instruction: VNOP @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x30: printf("Unsupported instruction: VMOVE @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x31: printf("Unsupported instruction: VMR32 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x2e: /* VOPMULA */
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
m_core->vacc[0] = fs[1] * ft[2];
|
||||
m_core->vacc[1] = fs[2] * ft[0];
|
||||
m_core->vacc[2] = fs[0] * ft[1];
|
||||
}
|
||||
break;
|
||||
case 0x2f: /* VNOP */
|
||||
break;
|
||||
case 0x30: /* VMOVE */
|
||||
if (rt)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
ft[field] = fs[field];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x31: /* VMR32 */
|
||||
if (rt)
|
||||
{
|
||||
float *fs = m_core->vfr[rs];
|
||||
float *ft = m_core->vfr[rt];
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
ft[field] = fs[(field + 3) & 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
// 32?
|
||||
// 33?
|
||||
case 0x34: printf("Unsupported instruction: VLQI @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x35:
|
||||
case 0x35: /* VSQI */
|
||||
{
|
||||
uint32_t *base = &m_core->vimem[m_core->vcr[rt] << 2];
|
||||
uint32_t *base = &m_core->vimem[(m_core->vcr[rt] << 2) & 0xfff];
|
||||
uint32_t *fs = reinterpret_cast<uint32_t*>(m_core->vfr[rs]);
|
||||
for (int field = 0; field < 4; field++)
|
||||
{
|
||||
@ -3061,10 +3306,27 @@ void r5900le_device::handle_extra_cop2(uint32_t op)
|
||||
}
|
||||
case 0x36: printf("Unsupported instruction: VLQD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x37: printf("Unsupported instruction: VSQD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x38: printf("Unsupported instruction: VDIV @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x39: printf("Unsupported instruction: VSQRT @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x38: /* VDIV */
|
||||
{
|
||||
const uint32_t fsf = (op >> 21) & 3;
|
||||
const uint32_t ftf = (op >> 23) & 3;
|
||||
const float *fs = m_core->vfr[rs];
|
||||
const float *ft = m_core->vfr[rt];
|
||||
const float ftval = ft[ftf];
|
||||
if (ftval)
|
||||
*(m_core->q) = fs[fsf] / ft[ftf];
|
||||
}
|
||||
break;
|
||||
case 0x39: /* VSQRT */
|
||||
{
|
||||
const uint32_t ftf = (op >> 23) & 3;
|
||||
*(m_core->q) = (float)sqrt(m_core->vfr[rt][ftf]);
|
||||
}
|
||||
break;
|
||||
case 0x3a: printf("Unsupported instruction: VRSQRT @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x3b: printf("Unsupported instruction: VWAITQ @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x3b: /* VWAITQ */
|
||||
// TODO: We assume Q is instantly available. Fix this!
|
||||
break;
|
||||
case 0x3c: printf("Unsupported instruction: VMTIR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x3d: printf("Unsupported instruction: VMFIR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
case 0x3e: printf("Unsupported instruction: VILWR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
|
||||
@ -3076,7 +3338,7 @@ void r5900le_device::handle_extra_cop2(uint32_t op)
|
||||
{
|
||||
if (BIT(op, 24-field))
|
||||
{
|
||||
m_core->vimem[base + field] = val;
|
||||
m_core->vimem[(base + field) & 0xfff] = val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3408,8 +3670,15 @@ void r5900le_device::handle_idt(uint32_t op)
|
||||
switch (op & 0x3f)
|
||||
{
|
||||
case 0x00: /* MADD */
|
||||
printf("Unsupported instruction: MADD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
{
|
||||
uint64_t temp64 = (int64_t)(int32_t)RSVAL32 * (int64_t)(int32_t)RTVAL32;
|
||||
m_core->r[REG_LO] += (int32_t)temp64;
|
||||
m_core->r[REG_HI] += (int32_t)(temp64 >> 32);
|
||||
if (rd)
|
||||
m_core->r[rd] = m_core->r[REG_LO];
|
||||
m_core->icount -= 3; // ?
|
||||
break;
|
||||
}
|
||||
case 0x01: /* MADDU */
|
||||
printf("Unsupported instruction: MADDU @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
break;
|
||||
@ -3537,7 +3806,18 @@ void r5900le_device::handle_mmi0(uint32_t op)
|
||||
printf("Unsupported instruction: PADDW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
break;
|
||||
case 0x01: /* PSUBW */
|
||||
printf("Unsupported instruction: PSUBW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
if (rd)
|
||||
{
|
||||
const uint32_t rsval[4] = { (uint32_t)(m_core->rh[rs] >> 32), (uint32_t)m_core->rh[rs], (uint32_t)(m_core->r[rs] >> 32), (uint32_t)m_core->r[rs] };
|
||||
const uint32_t rtval[4] = { (uint32_t)(m_core->rh[rt] >> 32), (uint32_t)m_core->rh[rt], (uint32_t)(m_core->r[rt] >> 32), (uint32_t)m_core->r[rt] };
|
||||
uint32_t rdval[4] = { 0, 0, 0, 0 };
|
||||
for (int word_idx = 0; word_idx < 4; word_idx++)
|
||||
{
|
||||
rdval[word_idx] = rsval[word_idx] - rtval[word_idx];
|
||||
}
|
||||
m_core->rh[rd] = ((uint64_t)rdval[0] << 32) | rdval[1];
|
||||
m_core->r[rd] = ((uint64_t)rdval[2] << 32) | rdval[3];
|
||||
}
|
||||
break;
|
||||
case 0x02: /* PCGTW */
|
||||
printf("Unsupported instruction: PCGTW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
@ -3673,27 +3953,32 @@ void r5900le_device::handle_mmi1(uint32_t op)
|
||||
printf("Unsupported instruction: PCEQB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
break;
|
||||
case 0x10: /* PADDUW */
|
||||
{
|
||||
if (rd == 0) break;
|
||||
|
||||
uint32_t rsval[4] = { (uint32_t)m_core->r[rs], (uint32_t)(m_core->r[rs] >> 32), (uint32_t)m_core->rh[rs], (uint32_t)(m_core->rh[rs] >> 32) };
|
||||
uint32_t rtval[4] = { (uint32_t)m_core->r[rt], (uint32_t)(m_core->r[rt] >> 32), (uint32_t)m_core->rh[rt], (uint32_t)(m_core->rh[rt] >> 32) };
|
||||
uint64_t rdval[4] = { 0 };
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (rd)
|
||||
{
|
||||
uint64_t sum = (uint64_t)rsval[i] + (uint64_t)rtval[i];
|
||||
rdval[i] = (sum >= 0x100000000ULL) ? 0xffffffffULL : sum;
|
||||
}
|
||||
m_core->r[rd] = rdval[0] | (rdval[1] << 32);
|
||||
m_core->rh[rd] = rdval[2] | (rdval[3] << 32);
|
||||
break;
|
||||
}
|
||||
uint32_t rsval[4] = { (uint32_t)m_core->r[rs], (uint32_t)(m_core->r[rs] >> 32), (uint32_t)m_core->rh[rs], (uint32_t)(m_core->rh[rs] >> 32) };
|
||||
uint32_t rtval[4] = { (uint32_t)m_core->r[rt], (uint32_t)(m_core->r[rt] >> 32), (uint32_t)m_core->rh[rt], (uint32_t)(m_core->rh[rt] >> 32) };
|
||||
uint64_t rdval[4] = { 0 };
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
uint64_t sum = (uint64_t)rsval[i] + (uint64_t)rtval[i];
|
||||
rdval[i] = (sum >= 0x100000000ULL) ? 0xffffffffULL : sum;
|
||||
}
|
||||
m_core->r[rd] = rdval[0] | (rdval[1] << 32);
|
||||
m_core->rh[rd] = rdval[2] | (rdval[3] << 32);
|
||||
}
|
||||
break;
|
||||
case 0x11: /* PSUBUW */
|
||||
printf("Unsupported instruction: PSUBUW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
break;
|
||||
case 0x12: /* PEXTUW */
|
||||
printf("Unsupported instruction: PEXTUW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
if (rd)
|
||||
{
|
||||
uint64_t rsval = m_core->rh[rs];
|
||||
uint64_t rtval = m_core->rh[rt];
|
||||
m_core->rh[rd] = (rsval & 0xffffffff00000000ULL) | (rtval >> 32);
|
||||
m_core->r[rd] = (rtval & 0x00000000ffffffffULL) | (rsval << 32);
|
||||
}
|
||||
break;
|
||||
case 0x14: /* PADDUH */
|
||||
printf("Unsupported instruction: PADDUH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
|
||||
|
@ -366,11 +366,17 @@ protected:
|
||||
float acc;
|
||||
|
||||
/* VU0 registers (R5900 only) */
|
||||
float vfr[32][4];
|
||||
float vfr[32][4]; // 0..3 = w..x
|
||||
uint32_t vcr[32];
|
||||
float vumem[0x1000];
|
||||
float* vfmem;
|
||||
uint32_t* vimem;
|
||||
float vacc[4];
|
||||
float p;
|
||||
|
||||
uint32_t* vr;
|
||||
float* i;
|
||||
float* q;
|
||||
|
||||
uint32_t mode; /* current global mode */
|
||||
|
||||
|
@ -170,9 +170,15 @@ iLinkSGUID=0x--------
|
||||
#include "machine/ioptimer.h"
|
||||
|
||||
#include "machine/ps2dma.h"
|
||||
#include "machine/ps2gif.h"
|
||||
#include "machine/ps2intc.h"
|
||||
#include "machine/ps2mc.h"
|
||||
#include "machine/ps2pad.h"
|
||||
#include "machine/ps2sif.h"
|
||||
#include "machine/ps2timer.h"
|
||||
#include "machine/ps2vif1.h"
|
||||
|
||||
#include "video/ps2gs.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
@ -194,6 +200,11 @@ public:
|
||||
, m_iop_spu(*this, "iop_spu")
|
||||
, m_iop_cdvd(*this, "iop_cdvd")
|
||||
, m_iop_sio2(*this, "iop_sio2")
|
||||
, m_gif(*this, "gif")
|
||||
, m_gs(*this, "gs")
|
||||
, m_vif1(*this, "vif1")
|
||||
, m_pad(*this, "pad%u", 0U)
|
||||
, m_mc(*this, "mc")
|
||||
, m_screen(*this, "screen")
|
||||
, m_ram(*this, "ram")
|
||||
, m_iop_ram(*this, "iop_ram")
|
||||
@ -215,17 +226,10 @@ protected:
|
||||
|
||||
TIMER_CALLBACK_MEMBER(vblank);
|
||||
|
||||
DECLARE_READ64_MEMBER(gs_regs0_r);
|
||||
DECLARE_WRITE64_MEMBER(gs_regs0_w);
|
||||
DECLARE_READ64_MEMBER(gs_regs1_r);
|
||||
DECLARE_WRITE64_MEMBER(gs_regs1_w);
|
||||
|
||||
DECLARE_READ32_MEMBER(ipu_r);
|
||||
DECLARE_WRITE32_MEMBER(ipu_w);
|
||||
DECLARE_READ64_MEMBER(vif0_fifo_r);
|
||||
DECLARE_WRITE64_MEMBER(vif0_fifo_w);
|
||||
DECLARE_READ64_MEMBER(vif1_fifo_r);
|
||||
DECLARE_WRITE64_MEMBER(vif1_fifo_w);
|
||||
DECLARE_READ64_MEMBER(gif_fifo_r);
|
||||
DECLARE_WRITE64_MEMBER(gif_fifo_w);
|
||||
DECLARE_READ64_MEMBER(ipu_fifo_r);
|
||||
@ -259,6 +263,11 @@ protected:
|
||||
required_device<iop_spu_device> m_iop_spu;
|
||||
required_device<iop_cdvd_device> m_iop_cdvd;
|
||||
required_device<iop_sio2_device> m_iop_sio2;
|
||||
required_device<ps2_gif_device> m_gif;
|
||||
required_device<ps2_gs_device> m_gs;
|
||||
required_device<ps2_vif1_device> m_vif1;
|
||||
required_device_array<ps2_pad_device, 2> m_pad;
|
||||
required_device<ps2_mc_device> m_mc;
|
||||
required_device<screen_device> m_screen;
|
||||
required_shared_ptr<uint64_t> m_ram;
|
||||
required_shared_ptr<uint32_t> m_iop_ram;
|
||||
@ -268,12 +277,6 @@ protected:
|
||||
required_shared_ptr<uint64_t> m_vu1_imem;
|
||||
required_shared_ptr<uint64_t> m_vu1_dmem;
|
||||
|
||||
uint64_t m_gs_base_regs[15];
|
||||
uint64_t m_gs_csr;
|
||||
uint64_t m_gs_imr;
|
||||
uint64_t m_gs_busdir;
|
||||
uint64_t m_gs_sig_label_id;
|
||||
|
||||
uint32_t m_unk_f430_reg;
|
||||
uint32_t m_unk_f440_counter;
|
||||
uint32_t m_unk_f440_reg;
|
||||
@ -320,32 +323,6 @@ WRITE64_MEMBER(ps2sony_state::vif0_fifo_w)
|
||||
}
|
||||
}
|
||||
|
||||
READ64_MEMBER(ps2sony_state::vif1_fifo_r)
|
||||
{
|
||||
uint64_t ret = 0ULL;
|
||||
if (offset)
|
||||
{
|
||||
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 & %08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(ps2sony_state::vif1_fifo_w)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
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 & %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
}
|
||||
}
|
||||
|
||||
READ64_MEMBER(ps2sony_state::gif_fifo_r)
|
||||
{
|
||||
uint64_t ret = 0ULL;
|
||||
@ -545,12 +522,6 @@ WRITE32_MEMBER(ps2sony_state::iop_debug_w)
|
||||
|
||||
void ps2sony_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_gs_base_regs));
|
||||
save_item(NAME(m_gs_csr));
|
||||
save_item(NAME(m_gs_imr));
|
||||
save_item(NAME(m_gs_busdir));
|
||||
save_item(NAME(m_gs_sig_label_id));
|
||||
|
||||
save_item(NAME(m_unk_f430_reg));
|
||||
save_item(NAME(m_unk_f440_counter));
|
||||
save_item(NAME(m_unk_f440_reg));
|
||||
@ -579,12 +550,6 @@ void ps2sony_state::machine_reset()
|
||||
memset(m_ipu_out_fifo, 0, sizeof(uint64_t)*0x1000);
|
||||
m_ipu_out_fifo_index = 0;
|
||||
|
||||
memset(m_gs_base_regs, 0, sizeof(uint64_t) * 15);
|
||||
m_gs_csr = 0ULL;
|
||||
m_gs_imr = 0ULL;
|
||||
m_gs_busdir = 0ULL;
|
||||
m_gs_sig_label_id = 0ULL;
|
||||
|
||||
m_vblank_timer->adjust(m_screen->time_until_pos(480), 1);
|
||||
}
|
||||
|
||||
@ -596,13 +561,15 @@ TIMER_CALLBACK_MEMBER(ps2sony_state::vblank)
|
||||
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);
|
||||
m_gs->vblank_start();
|
||||
}
|
||||
else
|
||||
{
|
||||
// VBlank exit
|
||||
m_intc->raise_interrupt(ps2_intc_device::INT_VB_OFF);
|
||||
//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);
|
||||
m_gs->vblank_end();
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,109 +670,6 @@ WRITE32_MEMBER(ps2sony_state::unk_f440_w)
|
||||
*
|
||||
*/
|
||||
|
||||
READ64_MEMBER(ps2sony_state::gs_regs0_r)
|
||||
{
|
||||
uint64_t ret = m_gs_base_regs[offset >> 1];
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: logerror("%s: gs_regs0_r: PMODE (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x02: logerror("%s: gs_regs0_r: SMODE1 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x04: logerror("%s: gs_regs0_r: SMODE2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x06: logerror("%s: gs_regs0_r: SRFSH (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x08: logerror("%s: gs_regs0_r: SYNCH1 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x0a: logerror("%s: gs_regs0_r: SYNCH2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x0c: logerror("%s: gs_regs0_r: SYNCV (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x0e: logerror("%s: gs_regs0_r: DISPFB1 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x10: logerror("%s: gs_regs0_r: DISPLAY1 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x12: logerror("%s: gs_regs0_r: DISPFB2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x14: logerror("%s: gs_regs0_r: DISPLAY2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x16: logerror("%s: gs_regs0_r: EXTBUF (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x18: logerror("%s: gs_regs0_r: EXTDATA (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x1a: logerror("%s: gs_regs0_r: EXTWRITE (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x1c: logerror("%s: gs_regs0_r: BGCOLOR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
default: logerror("%s: gs_regs0_r: Unknown (%08x)\n", machine().describe_context(), 0x12000000 + (offset << 3)); break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(ps2sony_state::gs_regs0_w)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: logerror("%s: gs_regs0_w: PMODE = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x02: logerror("%s: gs_regs0_w: SMODE1 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x04: logerror("%s: gs_regs0_w: SMODE2 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x06: logerror("%s: gs_regs0_w: SRFSH = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x08: logerror("%s: gs_regs0_w: SYNCH1 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x0a: logerror("%s: gs_regs0_w: SYNCH2 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x0c: logerror("%s: gs_regs0_w: SYNCV = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x0e: logerror("%s: gs_regs0_w: DISPFB1 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x10: logerror("%s: gs_regs0_w: DISPLAY1 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x12: logerror("%s: gs_regs0_w: DISPFB2 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x14: logerror("%s: gs_regs0_w: DISPLAY2 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x16: logerror("%s: gs_regs0_w: EXTBUF = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x18: logerror("%s: gs_regs0_w: EXTDATA = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x1a: logerror("%s: gs_regs0_w: EXTWRITE = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x1c: logerror("%s: gs_regs0_w: BGCOLOR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
default: logerror("%s: gs_regs0_w: Unknown %08x = %08x%08x\n", machine().describe_context(), 0x12000000 + (offset << 3), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
}
|
||||
COMBINE_DATA(&m_gs_base_regs[offset >> 1]);
|
||||
}
|
||||
|
||||
READ64_MEMBER(ps2sony_state::gs_regs1_r)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
ret = m_gs_csr;
|
||||
logerror("%s: gs_regs1_r: CSR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = m_gs_imr;
|
||||
logerror("%s: gs_regs1_r: IMR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
case 0x08:
|
||||
ret = m_gs_busdir;
|
||||
logerror("%s: gs_regs1_r: BUSDIR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
case 0x10:
|
||||
ret = m_gs_sig_label_id;
|
||||
logerror("%s: gs_regs1_r: SIGLBLID (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: gs_regs1_r: Unknown (%08x)\n", machine().describe_context(), 0x12000000 + (offset << 3));
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(ps2sony_state::gs_regs1_w)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
logerror("%s: gs_regs1_w: CSR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
COMBINE_DATA(&m_gs_csr);
|
||||
break;
|
||||
case 0x02:
|
||||
logerror("%s: gs_regs1_w: IMR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
COMBINE_DATA(&m_gs_imr);
|
||||
break;
|
||||
case 0x08:
|
||||
logerror("%s: gs_regs1_w: BUSDIR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
COMBINE_DATA(&m_gs_busdir);
|
||||
break;
|
||||
case 0x10:
|
||||
logerror("%s: gs_regs1_w: SIGLBLID = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
COMBINE_DATA(&m_gs_sig_label_id);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: gs_regs1_w: Unknown %08x = %08x%08x\n", machine().describe_context(), 0x12000000 + (offset << 3), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ps2sony_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
return 0;
|
||||
@ -819,8 +683,9 @@ void ps2sony_state::mem_map(address_map &map)
|
||||
map(0x10001000, 0x100017ff).rw(m_timer[2], FUNC(ps2_timer_device::read), FUNC(ps2_timer_device::write)).umask64(0x00000000ffffffff);
|
||||
map(0x10001800, 0x10001fff).rw(m_timer[3], FUNC(ps2_timer_device::read), FUNC(ps2_timer_device::write)).umask64(0x00000000ffffffff);
|
||||
map(0x10002000, 0x10002fff).rw(FUNC(ps2sony_state::ipu_r), FUNC(ps2sony_state::ipu_w)).umask64(0x00000000ffffffff);
|
||||
map(0x10003000, 0x100030af).rw(m_gif, FUNC(ps2_gif_device::read), FUNC(ps2_gif_device::write));
|
||||
map(0x10004000, 0x1000400f).mirror(0xff0).rw(FUNC(ps2sony_state::vif0_fifo_r), FUNC(ps2sony_state::vif0_fifo_w));
|
||||
map(0x10005000, 0x1000500f).mirror(0xff0).rw(FUNC(ps2sony_state::vif1_fifo_r), FUNC(ps2sony_state::vif1_fifo_w));
|
||||
map(0x10005000, 0x1000500f).mirror(0xff0).rw(m_vif1, FUNC(ps2_vif1_device::mmio_r), FUNC(ps2_vif1_device::mmio_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(m_dmac, FUNC(ps2_dmac_device::channel_r), FUNC(ps2_dmac_device::channel_w)).umask64(0x00000000ffffffff);;
|
||||
@ -837,8 +702,8 @@ void ps2sony_state::mem_map(address_map &map)
|
||||
map(0x11004000, 0x11004fff).mirror(0x3000).ram().share(m_vu0_dmem);
|
||||
map(0x11008000, 0x1100bfff).ram().share(m_vu1_imem);
|
||||
map(0x1100c000, 0x1100ffff).ram().share(m_vu1_dmem);
|
||||
map(0x12000000, 0x120003ff).mirror(0xc00).rw(FUNC(ps2sony_state::gs_regs0_r), FUNC(ps2sony_state::gs_regs0_w));
|
||||
map(0x12001000, 0x120013ff).mirror(0xc00).rw(FUNC(ps2sony_state::gs_regs1_r), FUNC(ps2sony_state::gs_regs1_w));
|
||||
map(0x12000000, 0x120003ff).mirror(0xc00).rw(m_gs, FUNC(ps2_gs_device::priv_regs0_r), FUNC(ps2_gs_device::priv_regs0_w));
|
||||
map(0x12001000, 0x120013ff).mirror(0xc00).rw(m_gs, FUNC(ps2_gs_device::priv_regs1_r), FUNC(ps2_gs_device::priv_regs1_w));
|
||||
map(0x1c000000, 0x1c1fffff).rw(FUNC(ps2sony_state::ee_iop_ram_r), FUNC(ps2sony_state::ee_iop_ram_w)); // IOP has 2MB EDO RAM per Wikipedia, and writes go up to this point
|
||||
map(0x1f803800, 0x1f803807).r(FUNC(ps2sony_state::board_id_r));
|
||||
map(0x1fc00000, 0x1fffffff).rom().region("bios", 0);
|
||||
@ -875,14 +740,18 @@ MACHINE_CONFIG_START(ps2sony_state::ps2sony)
|
||||
MCFG_MIPS3_DCACHE_SIZE(16384)
|
||||
MCFG_DEVICE_PROGRAM_MAP(mem_map)
|
||||
|
||||
MCFG_DEVICE_ADD(m_vif1, SONYPS2_VIF1, 294912000/2, m_gif)
|
||||
|
||||
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_gs, SONYPS2_GS, 294912000/2)
|
||||
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_dmac, SONYPS2_DMAC, 294912000/2, m_maincpu, m_ram, m_sif, m_gif, m_vif1)
|
||||
MCFG_DEVICE_ADD(m_sif, SONYPS2_SIF, m_intc)
|
||||
MCFG_DEVICE_ADD(m_gif, SONYPS2_GIF, m_gs)
|
||||
|
||||
MCFG_DEVICE_ADD(m_iop, SONYPS2_IOP, XTAL(67'737'600)/2)
|
||||
MCFG_DEVICE_PROGRAM_MAP(iop_map)
|
||||
@ -890,8 +759,12 @@ MACHINE_CONFIG_START(ps2sony_state::ps2sony)
|
||||
MCFG_QUANTUM_PERFECT_CPU("maincpu")
|
||||
MCFG_QUANTUM_PERFECT_CPU("iop")
|
||||
|
||||
MCFG_DEVICE_ADD(m_pad[0], SONYPS2_PAD)
|
||||
MCFG_DEVICE_ADD(m_pad[1], SONYPS2_PAD)
|
||||
MCFG_DEVICE_ADD(m_mc, SONYPS2_MC)
|
||||
|
||||
MCFG_DEVICE_ADD(m_iop_intc, SONYIOP_INTC, m_iop)
|
||||
MCFG_DEVICE_ADD(m_iop_sio2, SONYIOP_SIO2, m_iop_intc)
|
||||
MCFG_DEVICE_ADD(m_iop_sio2, SONYIOP_SIO2, m_iop_intc, m_pad[0], m_pad[1], m_mc)
|
||||
MCFG_DEVICE_ADD(m_iop_cdvd, SONYIOP_CDVD, m_iop_intc)
|
||||
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))
|
||||
|
@ -139,7 +139,7 @@ void iop_dma_device::transfer_sif0(uint32_t chan)
|
||||
{
|
||||
if (channel.end())
|
||||
{
|
||||
logerror("sif0.end\n");
|
||||
//logerror("sif0.end\n");
|
||||
transfer_finish(SIF0);
|
||||
}
|
||||
else if (m_sif->fifo_depth(0) < ps2_sif_device::MAX_FIFO_DEPTH - 2)
|
||||
@ -151,7 +151,7 @@ void iop_dma_device::transfer_sif0(uint32_t chan)
|
||||
const uint32_t ee_hi = m_ram[tag_addr + 2];
|
||||
const uint32_t ee_lo = m_ram[tag_addr + 3];
|
||||
|
||||
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);
|
||||
//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 + 3) & ~3);
|
||||
channel.set_tag_addr(tag_addr_bytes + 0x10);
|
||||
@ -189,7 +189,7 @@ void iop_dma_device::transfer_sif1(uint32_t chan)
|
||||
{
|
||||
if (channel.end())
|
||||
{
|
||||
logerror("sif1.end\n");
|
||||
//logerror("sif1.end\n");
|
||||
transfer_finish(SIF1);
|
||||
}
|
||||
else if (m_sif->fifo_depth(1) >= 4)
|
||||
@ -198,7 +198,7 @@ void iop_dma_device::transfer_sif1(uint32_t chan)
|
||||
const uint32_t iop_lo = m_sif->fifo_pop(1);
|
||||
m_sif->fifo_pop(1); // ee_hi - ignored
|
||||
m_sif->fifo_pop(1); // ee_lo - ignored
|
||||
logerror("%s: following sif1 iop tag, tag is %08x %08x\n", machine().describe_context(), iop_hi, iop_lo);
|
||||
//logerror("%s: following sif1 iop tag, tag is %08x %08x\n", machine().describe_context(), iop_hi, iop_lo);
|
||||
channel.set_addr(iop_hi & 0x00ffffff);
|
||||
channel.set_count(iop_lo);
|
||||
|
||||
@ -249,10 +249,10 @@ void iop_dma_device::transfer_to_sio2(uint32_t chan)
|
||||
{
|
||||
const uint32_t addr = channel.addr();
|
||||
const uint32_t data = m_ram[addr >> 2];
|
||||
m_sio2->receive((data >> 24) & 0xff);
|
||||
m_sio2->receive((data >> 16) & 0xff);
|
||||
m_sio2->receive((data >> 8) & 0xff);
|
||||
m_sio2->receive(data & 0xff);
|
||||
m_sio2->transmit(data & 0xff);
|
||||
m_sio2->transmit((data >> 8) & 0xff);
|
||||
m_sio2->transmit((data >> 16) & 0xff);
|
||||
m_sio2->transmit((data >> 24) & 0xff);
|
||||
channel.set_count(count - 1);
|
||||
channel.set_addr(addr + 4);
|
||||
}
|
||||
@ -272,10 +272,10 @@ void iop_dma_device::transfer_from_sio2(uint32_t chan)
|
||||
if (count)
|
||||
{
|
||||
const uint32_t addr = channel.addr();
|
||||
uint32_t data = m_sio2->transmit() << 24;
|
||||
data |= m_sio2->transmit() << 16;
|
||||
data |= m_sio2->transmit() << 8;
|
||||
data |= m_sio2->transmit();
|
||||
uint32_t data = m_sio2->receive();
|
||||
data |= m_sio2->receive() << 8;
|
||||
data |= m_sio2->receive() << 16;
|
||||
data |= m_sio2->receive() << 24;
|
||||
m_ram[addr >> 2] = data;
|
||||
channel.set_count(count - 1);
|
||||
channel.set_addr(addr + 4);
|
||||
@ -312,29 +312,29 @@ READ32_MEMBER(iop_dma_device::bank0_r)
|
||||
{
|
||||
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);
|
||||
//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].block();
|
||||
logerror("%s: bank0_r: channel[%d].block (%08x & %08x)\n", machine().describe_context(), offset >> 2, ret, mem_mask);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//logerror("%s: bank0_r: DICR (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: bank0_r: Unknown %08x & %08x\n", machine().describe_context(), 0x1f801080 + (offset << 2), mem_mask);
|
||||
@ -348,28 +348,28 @@ WRITE32_MEMBER(iop_dma_device::bank0_w)
|
||||
switch (offset)
|
||||
{
|
||||
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);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//logerror("%s: bank0_w: DPCR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
set_dpcr(data, 0);
|
||||
break;
|
||||
case 0x74/4: // 0x1f8010f4, DICR
|
||||
logerror("%s: bank0_w: DICR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
//logerror("%s: bank0_w: DICR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
set_dicr(data, 0);
|
||||
break;
|
||||
default:
|
||||
@ -385,29 +385,30 @@ READ32_MEMBER(iop_dma_device::bank1_r)
|
||||
{
|
||||
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);
|
||||
//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].block();
|
||||
logerror("%s: bank1_r: channel[%d].block (%08x & %08x)\n", machine().describe_context(), (offset >> 2) + 8, ret, mem_mask);
|
||||
//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);
|
||||
//if ((offset >> 2) != 2)
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//logerror("%s: bank1_r: DICR2 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: bank1_r: Unknown %08x & %08x\n", machine().describe_context(), 0x1f801500 + (offset << 2), mem_mask);
|
||||
@ -421,28 +422,28 @@ WRITE32_MEMBER(iop_dma_device::bank1_w)
|
||||
switch (offset & 0x1f)
|
||||
{
|
||||
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);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//logerror("%s: bank1_w: DPCR2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
set_dpcr(data, 1);
|
||||
break;
|
||||
case 0x74/4: // 0x1f801574, DICR2
|
||||
logerror("%s: bank1_w: DICR2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
//logerror("%s: bank1_w: DICR2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
set_dicr(data, 1);
|
||||
break;
|
||||
default:
|
||||
|
@ -40,11 +40,11 @@ READ32_MEMBER(iop_intc_device::read)
|
||||
{
|
||||
case 0: // I_STAT
|
||||
ret = m_status;
|
||||
logerror("%s: read: I_STAT %08x & %08x\n", machine().describe_context(), ret, mem_mask);
|
||||
//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);
|
||||
//logerror("%s: read: I_MASK %08x & %08x\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
case 2: // I_ENABLE
|
||||
ret = m_enabled ? 1 : 0;
|
||||
@ -64,12 +64,12 @@ 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);
|
||||
//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);
|
||||
//logerror("%s: write: I_MASK = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_mask = data;
|
||||
update_interrupts();
|
||||
break;
|
||||
@ -86,7 +86,7 @@ WRITE32_MEMBER(iop_intc_device::write)
|
||||
|
||||
void iop_intc_device::raise_interrupt(uint32_t line)
|
||||
{
|
||||
logerror("%s: raise_interrupt: %d\n", machine().describe_context(), line);
|
||||
//logerror("%s: raise_interrupt: %d\n", machine().describe_context(), line);
|
||||
m_status |= (1 << line);
|
||||
update_interrupts();
|
||||
}
|
||||
|
@ -11,38 +11,61 @@
|
||||
|
||||
#include "iopsio2.h"
|
||||
|
||||
/*static*/ const size_t iop_sio2_device::BUFFER_SIZE = 64; // total guess
|
||||
/*static*/ const size_t iop_sio2_device::BUFFER_SIZE = 512; // total guess based on memcard block size
|
||||
|
||||
DEFINE_DEVICE_TYPE(SONYIOP_SIO2, iop_sio2_device, "iopsio2", "Playstation 2 SIO2")
|
||||
|
||||
iop_sio2_device::iop_sio2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SONYIOP_SIO2, tag, owner, clock)
|
||||
, m_intc(*this, finder_base::DUMMY_TAG)
|
||||
, m_pad0(*this, finder_base::DUMMY_TAG)
|
||||
, m_pad1(*this, finder_base::DUMMY_TAG)
|
||||
, m_mc0(*this, finder_base::DUMMY_TAG)
|
||||
{
|
||||
}
|
||||
|
||||
void iop_sio2_device::device_start()
|
||||
{
|
||||
if (!m_response_timer)
|
||||
m_response_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(iop_sio2_device::response_timer), this));
|
||||
|
||||
save_item(NAME(m_buffer));
|
||||
save_item(NAME(m_curr_byte));
|
||||
save_item(NAME(m_end_byte));
|
||||
save_item(NAME(m_ctrl));
|
||||
save_item(NAME(m_receive_buf));
|
||||
save_item(NAME(m_receive_curr));
|
||||
save_item(NAME(m_receive_end));
|
||||
save_item(NAME(m_transmit_buf));
|
||||
save_item(NAME(m_transmit_curr));
|
||||
save_item(NAME(m_transmit_end));
|
||||
|
||||
save_item(NAME(m_unknown_0x6c));
|
||||
save_item(NAME(m_unknown_0x70));
|
||||
save_item(NAME(m_unknown_0x74));
|
||||
|
||||
save_item(NAME(m_cmdbuf));
|
||||
save_item(NAME(m_curr_port));
|
||||
save_item(NAME(m_cmd_size));
|
||||
save_item(NAME(m_cmd_length));
|
||||
save_item(NAME(m_databuf[0]));
|
||||
save_item(NAME(m_databuf[1]));
|
||||
|
||||
save_item(NAME(m_target_device));
|
||||
}
|
||||
|
||||
void iop_sio2_device::device_reset()
|
||||
{
|
||||
memset(m_buffer, 0, BUFFER_SIZE);
|
||||
m_curr_byte = 0;
|
||||
m_end_byte = 0;
|
||||
m_ctrl = 0;
|
||||
|
||||
memset(m_receive_buf, 0, BUFFER_SIZE);
|
||||
m_receive_curr = 0;
|
||||
m_receive_end = 0;
|
||||
m_unknown_0x6c = 0;
|
||||
m_unknown_0x70 = 0xf;
|
||||
m_unknown_0x74 = 0;
|
||||
|
||||
memset(m_transmit_buf, 0, BUFFER_SIZE);
|
||||
m_transmit_curr = 0;
|
||||
m_transmit_end = 0;
|
||||
memset(m_cmdbuf, 0, sizeof(uint32_t) * 16);
|
||||
m_curr_port = 0;
|
||||
m_cmd_size = 0;
|
||||
m_cmd_length = 0;
|
||||
memset(m_databuf, 0, sizeof(uint32_t) * 4 * 2);
|
||||
|
||||
m_target_device = 0;
|
||||
}
|
||||
|
||||
READ32_MEMBER(iop_sio2_device::read)
|
||||
@ -50,8 +73,28 @@ READ32_MEMBER(iop_sio2_device::read)
|
||||
uint32_t ret = 0;
|
||||
switch (offset)
|
||||
{
|
||||
case 0x64/4:
|
||||
ret = receive();
|
||||
//logerror("%s: read: FIFO RECV %08x & %08x\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
case 0x68/4: // Control?
|
||||
logerror("%s: read: CTRL %08x & %08x\n", machine().describe_context(), ret, mem_mask);
|
||||
ret = m_ctrl;
|
||||
//logerror("%s: read: CTRL %08x & %08x\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
case 0x6c/4:
|
||||
ret = m_unknown_0x6c;
|
||||
//logerror("%s: read: Unknown 0x6c (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
case 0x70/4:
|
||||
ret = m_unknown_0x70;
|
||||
//logerror("%s: read: Unknown 0x70 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
case 0x74/4:
|
||||
ret = m_unknown_0x74;
|
||||
//logerror("%s: read: Unknown 0x74 (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
case 0x80/4:
|
||||
// Unknown. Case is here to prevent log spam.
|
||||
break;
|
||||
default:
|
||||
logerror("%s: read: Unknown offset %08x & %08x\n", machine().describe_context(), 0x1f808200 + (offset << 2), mem_mask);
|
||||
@ -64,39 +107,203 @@ WRITE32_MEMBER(iop_sio2_device::write)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/4: case 0x04/4: case 0x08/4: case 0x0c/4: case 0x10/4: case 0x14/4: case 0x18/4: case 0x1c/4:
|
||||
case 0x20/4: case 0x24/4: case 0x28/4: case 0x2c/4: case 0x30/4: case 0x34/4: case 0x38/4: case 0x3c/4:
|
||||
//logerror("%s: write: CMDBUF[%d] = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask);
|
||||
COMBINE_DATA(&m_cmdbuf[offset]);
|
||||
break;
|
||||
case 0x40/4: case 0x44/4:
|
||||
//logerror("%s: write: DATABUF[0][%d] = %08x & %08x\n", machine().describe_context(), offset - 0x40/4, data, mem_mask);
|
||||
COMBINE_DATA(&m_databuf[0][offset - 0x40/4]);
|
||||
break;
|
||||
case 0x48/4: case 0x4c/4:
|
||||
//logerror("%s: write: DATABUF[1][%d] = %08x & %08x\n", machine().describe_context(), offset - 0x48/4, data, mem_mask);
|
||||
COMBINE_DATA(&m_databuf[1][offset - 0x48/4]);
|
||||
break;
|
||||
case 0x50/4: case 0x54/4:
|
||||
//logerror("%s: write: DATABUF[2][%d] = %08x & %08x\n", machine().describe_context(), offset - 0x50/4, data, mem_mask);
|
||||
COMBINE_DATA(&m_databuf[2][offset - 0x50/4]);
|
||||
break;
|
||||
case 0x58/4: case 0x5c/4:
|
||||
//logerror("%s: write: DATABUF[3][%d] = %08x & %08x\n", machine().describe_context(), offset - 0x58/4, data, mem_mask);
|
||||
COMBINE_DATA(&m_databuf[3][offset - 0x58/4]);
|
||||
break;
|
||||
case 0x60/4:
|
||||
//logerror("%s: write: XMIT %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
transmit_to_device_hack((uint8_t)data);
|
||||
break;
|
||||
case 0x68/4: // Control?
|
||||
{
|
||||
uint32_t old_ctrl = m_ctrl;
|
||||
m_ctrl = data & CTRL_IRQ;
|
||||
if (old_ctrl != m_ctrl && (m_ctrl & CTRL_IRQ))
|
||||
//logerror("%s: write: Control? %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
//uint32_t old_ctrl = m_ctrl;
|
||||
m_ctrl = data & ~CTRL_IRQ;
|
||||
if (data & CTRL_IRQ)
|
||||
{
|
||||
m_intc->raise_interrupt(iop_intc_device::INT_SIO2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_curr_port = 0;
|
||||
m_cmd_size = 0;
|
||||
m_cmd_length = 0;
|
||||
m_end_byte = 0;
|
||||
m_curr_byte = 0;
|
||||
m_target_device = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x80/4:
|
||||
// Unknown. Case is here to prevent log spam.
|
||||
break;
|
||||
default:
|
||||
logerror("%s: write: Unknown offset %08x = %08x & %08x\n", machine().describe_context(), 0x1f808200 + (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t iop_sio2_device::transmit()
|
||||
uint8_t iop_sio2_device::receive()
|
||||
{
|
||||
if (m_transmit_curr == m_transmit_end)
|
||||
if (m_curr_byte >= m_end_byte)
|
||||
{
|
||||
//logerror("D:%d == E:%d, returning 0\n", m_curr_byte, m_end_byte);
|
||||
return 0;
|
||||
}
|
||||
uint8_t ret = m_transmit_buf[m_transmit_curr];
|
||||
m_transmit_curr = (m_transmit_curr + 1) & (BUFFER_SIZE-1);
|
||||
const uint8_t ret = m_buffer[m_curr_byte];
|
||||
//logerror("buf[%d] = %02x\n", m_curr_byte, ret);
|
||||
m_curr_byte++;
|
||||
if (m_curr_byte >= m_end_byte)
|
||||
{
|
||||
//logerror("Reached end of buffer, resetting to 0\n");
|
||||
m_curr_byte = 0;
|
||||
m_end_byte = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iop_sio2_device::receive(uint8_t data)
|
||||
void iop_sio2_device::transmit(uint8_t data)
|
||||
{
|
||||
if (m_receive_end >= BUFFER_SIZE)
|
||||
//logerror("%s: Transmitting: %02x\n", machine().describe_context(), data);
|
||||
if (!m_cmd_size && m_cmdbuf[m_curr_port])
|
||||
{
|
||||
m_cmd_size = (m_cmdbuf[m_curr_port++] & 0x0001ff00) >> 8;
|
||||
m_cmd_length = m_cmd_size;
|
||||
}
|
||||
|
||||
// TODO: Transmit serially to actual slot device at 250kHz-2MHz as needed
|
||||
transmit_to_device_hack(data);
|
||||
}
|
||||
|
||||
ps2_pad_device* iop_sio2_device::pad(uint8_t port)
|
||||
{
|
||||
return (port == 0) ? m_pad0.target() : m_pad1.target();
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(iop_sio2_device::response_timer)
|
||||
{
|
||||
if (param < 2)
|
||||
{
|
||||
pad(param)->process_fifos();
|
||||
while (pad(param)->xmit_fifo_depth() && m_end_byte < BUFFER_SIZE)
|
||||
{
|
||||
receive_from_device_hack(pad(param)->xmit_fifo_pop());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void iop_sio2_device::transmit_to_device_hack(uint8_t data)
|
||||
{
|
||||
if (m_target_device == 0)
|
||||
{
|
||||
select_device_hack(data);
|
||||
}
|
||||
|
||||
//bool cmd_complete = false;
|
||||
if (m_cmd_size)
|
||||
{
|
||||
m_cmd_size--;
|
||||
if (!m_cmd_size)
|
||||
{
|
||||
//cmd_complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (m_target_device)
|
||||
{
|
||||
case ps2_pad_device::SIO_DEVICE_ID:
|
||||
m_unknown_0x6c = 0x0001d100; // TODO: As above
|
||||
receive_from_device_hack(0);
|
||||
|
||||
/*m_unknown_0x6c = 0x00001100; // TODO: What do these bits mean and why does the code expect them?
|
||||
pad(m_curr_port)->recv_fifo_push(data);
|
||||
|
||||
if (!m_cmd_size)
|
||||
{
|
||||
m_response_timer->adjust(attotime::from_ticks(8*pad(m_curr_port)->xmit_fifo_depth(), 250'000), m_curr_port);
|
||||
m_curr_port++;
|
||||
}*/
|
||||
break;
|
||||
|
||||
case ps2_mc_device::SIO_DEVICE_ID:
|
||||
/*if (m_cmd_size || cmd_complete)
|
||||
{
|
||||
logerror("Pushing %02x to memory card, m_cmd_size is %d\n", data, m_cmd_size);
|
||||
m_mc0->recv_fifo_push(data);
|
||||
}
|
||||
|
||||
if (cmd_complete)
|
||||
{
|
||||
logerror("Command is complete, processing fifos\n");
|
||||
m_unknown_0x6c = 0x00001100;
|
||||
m_mc0->process_fifos();
|
||||
while (m_mc0->xmit_fifo_depth() && m_end_byte < BUFFER_SIZE)
|
||||
{
|
||||
logerror("xmit fifo is %d, end byte is %d\n", m_mc0->xmit_fifo_depth(), m_end_byte);
|
||||
receive_from_device_hack(m_mc0->xmit_fifo_pop());
|
||||
}
|
||||
m_unknown_0x74 = m_cmd_length;
|
||||
}*/
|
||||
m_unknown_0x6c = 0x0001d100; // TODO: As above
|
||||
receive_from_device_hack(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
m_unknown_0x6c = 0x0001d100; // TODO: As above
|
||||
receive_from_device_hack(0);
|
||||
logerror("%s: Unknown device selected, can't write data %02x\n", machine().describe_context(), data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void iop_sio2_device::select_device_hack(uint8_t data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case ps2_pad_device::SIO_DEVICE_ID:
|
||||
m_target_device = data;
|
||||
// TODO: Select transmit frequency, etc.
|
||||
//logerror("%s: Selecting transmit device: Pad\n", machine().describe_context());
|
||||
break;
|
||||
case ps2_mc_device::SIO_DEVICE_ID:
|
||||
m_target_device = data;
|
||||
//logerror("%s: Selecting transmit device: Memcard\n", machine().describe_context());
|
||||
break;
|
||||
|
||||
default:
|
||||
m_target_device = 0xff;
|
||||
//logerror("%s: Selecting transmit device: Unknown\n", machine().describe_context());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void iop_sio2_device::receive_from_device_hack(uint8_t data)
|
||||
{
|
||||
if (m_end_byte == BUFFER_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_receive_buf[m_receive_end] = data;
|
||||
m_receive_end++;
|
||||
m_buffer[m_end_byte++] = data;
|
||||
//logerror("%s: Receiving byte from device (new top: %d)\n", machine().describe_context(), m_end_byte);
|
||||
}
|
||||
|
@ -16,15 +16,20 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "iopintc.h"
|
||||
#include "ps2pad.h"
|
||||
#include "ps2mc.h"
|
||||
|
||||
class iop_sio2_device : public device_t
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
iop_sio2_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&intc_tag)
|
||||
template <typename T, typename U, typename V, typename W>
|
||||
iop_sio2_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&intc_tag, U &&pad0_tag, V &&pad1_tag, W &&mc0_tag)
|
||||
: iop_sio2_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
m_intc.set_tag(std::forward<T>(intc_tag));
|
||||
m_pad0.set_tag(std::forward<U>(pad0_tag));
|
||||
m_pad1.set_tag(std::forward<V>(pad1_tag));
|
||||
m_mc0.set_tag(std::forward<W>(mc0_tag));
|
||||
}
|
||||
|
||||
iop_sio2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -32,29 +37,51 @@ public:
|
||||
DECLARE_READ32_MEMBER(read);
|
||||
DECLARE_WRITE32_MEMBER(write);
|
||||
|
||||
void receive(uint8_t data);
|
||||
uint8_t transmit();
|
||||
void transmit(uint8_t data);
|
||||
uint8_t receive();
|
||||
|
||||
void receive_from_device_hack(uint8_t data); // TODO: Turn me into a bus interface!
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
enum
|
||||
TIMER_CALLBACK_MEMBER(response_timer);
|
||||
|
||||
void select_device_hack(uint8_t data);
|
||||
void transmit_to_device_hack(uint8_t data); // TODO: Turn me into a bus interface!
|
||||
ps2_pad_device* pad(uint8_t port);
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
CTRL_IRQ = 0x01,
|
||||
};
|
||||
|
||||
required_device<iop_intc_device> m_intc;
|
||||
required_device<ps2_pad_device> m_pad0;
|
||||
required_device<ps2_pad_device> m_pad1;
|
||||
required_device<ps2_mc_device> m_mc0;
|
||||
|
||||
// HACK: Buffer sizes are guesses.
|
||||
uint8_t m_receive_buf[64];
|
||||
uint8_t m_receive_curr;
|
||||
uint8_t m_receive_end;
|
||||
uint8_t m_transmit_buf[64];
|
||||
uint8_t m_transmit_curr;
|
||||
uint8_t m_transmit_end;
|
||||
// HACK: Buffer size is a guess.
|
||||
uint8_t m_buffer[512];
|
||||
uint32_t m_curr_byte;
|
||||
uint32_t m_end_byte;
|
||||
uint32_t m_ctrl;
|
||||
|
||||
uint32_t m_unknown_0x6c; // Device status?
|
||||
uint32_t m_unknown_0x70;
|
||||
uint32_t m_unknown_0x74;
|
||||
|
||||
uint32_t m_cmdbuf[16];
|
||||
uint32_t m_curr_port;
|
||||
uint32_t m_cmd_size;
|
||||
uint32_t m_cmd_length;
|
||||
uint32_t m_databuf[4][2];
|
||||
|
||||
uint32_t m_target_device;
|
||||
|
||||
emu_timer *m_response_timer;
|
||||
|
||||
static const size_t BUFFER_SIZE;
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,8 @@ ps2_dmac_device::ps2_dmac_device(const machine_config &mconfig, const char *tag,
|
||||
, m_ee(*this, finder_base::DUMMY_TAG)
|
||||
, m_ram(*this, finder_base::DUMMY_TAG)
|
||||
, m_sif(*this, finder_base::DUMMY_TAG)
|
||||
, m_gif(*this, finder_base::DUMMY_TAG)
|
||||
, m_vif1(*this, finder_base::DUMMY_TAG)
|
||||
, m_icount(0)
|
||||
{
|
||||
}
|
||||
@ -91,6 +93,12 @@ void ps2_dmac_device::execute_run()
|
||||
|
||||
switch (m_last_serviced)
|
||||
{
|
||||
case VIF1:
|
||||
transfer_vif1();
|
||||
break;
|
||||
case GIF:
|
||||
transfer_gif();
|
||||
break;
|
||||
case SIF0:
|
||||
transfer_sif0();
|
||||
break;
|
||||
@ -107,6 +115,97 @@ void ps2_dmac_device::execute_run()
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_dmac_device::transfer_vif1()
|
||||
{
|
||||
if (m_mem_drain)
|
||||
{
|
||||
logerror("%s: transfer_vif1: Not yet implemented: memory drain bit. HACK: Disabling channel.\n", machine().describe_context());
|
||||
transfer_finish(VIF1);
|
||||
return;
|
||||
}
|
||||
|
||||
channel_t &channel = m_channels[VIF1];
|
||||
const uint32_t count = channel.quadword_count();
|
||||
if (count)
|
||||
{
|
||||
//logerror("%s: DMAC VIF1 quadword count: %08x\n", machine().describe_context(), count);
|
||||
uint32_t addr = channel.addr();
|
||||
if (BIT(addr, 31))
|
||||
addr -= 0x10000000;
|
||||
address_space &space = m_ee->space(AS_PROGRAM);
|
||||
uint32_t words[4] = { 0, 0, 0, 0 };
|
||||
for (int word = 0; word < 4; word++)
|
||||
{
|
||||
words[word] = space.read_dword(addr);
|
||||
addr += 4;
|
||||
}
|
||||
m_vif1->dma_write(((uint64_t)words[3] << 32) | words[2], ((uint64_t)words[1] << 32) | words[0]);
|
||||
channel.set_addr(channel.addr() + 0x10);
|
||||
channel.set_quadword_count(count - 1);
|
||||
}
|
||||
else if (channel.end_tag())
|
||||
{
|
||||
logerror("%s: DMAC VIF1 end tag\n", machine().describe_context());
|
||||
transfer_finish(VIF1);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%s: DMAC VIF1 following source tag\n", machine().describe_context());
|
||||
uint32_t tag_addr = channel.tag_addr();
|
||||
if (BIT(tag_addr, 31))
|
||||
tag_addr -= 0x10000000;
|
||||
address_space &space = m_ee->space(AS_PROGRAM);
|
||||
uint32_t words[4] = { 0, 0, 0, 0 };
|
||||
for (int word = 0; word < 4; word++)
|
||||
{
|
||||
words[word] = space.read_dword(tag_addr);
|
||||
tag_addr += 4;
|
||||
}
|
||||
m_vif1->tag_write(words);
|
||||
follow_source_tag(VIF1);
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_dmac_device::transfer_gif()
|
||||
{
|
||||
if (m_mem_drain)
|
||||
{
|
||||
logerror("%s: Not yet implemented: memory drain bit. HACK: Disabling channel.\n", machine().describe_context());
|
||||
transfer_finish(GIF);
|
||||
return;
|
||||
}
|
||||
|
||||
channel_t &channel = m_channels[GIF];
|
||||
const uint32_t count = channel.quadword_count();
|
||||
if (count)
|
||||
{
|
||||
//logerror("%s: DMAC GIF quadword count: %08x\n", machine().describe_context(), count);
|
||||
uint32_t addr = channel.addr();
|
||||
if (BIT(addr, 31))
|
||||
addr -= 0x10000000;
|
||||
address_space &space = m_ee->space(AS_PROGRAM);
|
||||
uint32_t words[4] = { 0, 0, 0, 0 };
|
||||
for (int word = 0; word < 4; word++)
|
||||
{
|
||||
words[word] = space.read_dword(addr);
|
||||
addr += 4;
|
||||
}
|
||||
m_gif->write_path3(((uint64_t)words[3] << 32) | words[2], ((uint64_t)words[1] << 32) | words[0]);
|
||||
channel.set_addr(channel.addr() + 0x10);
|
||||
channel.set_quadword_count(count - 1);
|
||||
}
|
||||
else if (channel.end_tag())
|
||||
{
|
||||
logerror("%s: DMAC GIF end tag\n", machine().describe_context());
|
||||
transfer_finish(GIF);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%s: DMAC GIF following source tag\n", machine().describe_context());
|
||||
follow_source_tag(GIF);
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_dmac_device::transfer_sif0()
|
||||
{
|
||||
channel_t &channel = m_channels[SIF0];
|
||||
@ -117,6 +216,8 @@ void ps2_dmac_device::transfer_sif0()
|
||||
{
|
||||
//logerror("%s: SIF0 depth is %d\n", machine().describe_context(), m_sif->fifo_depth(0));
|
||||
uint32_t addr = channel.addr();
|
||||
if (BIT(addr, 31))
|
||||
addr -= 0x10000000;
|
||||
for (int word = 0; word < 4; word++)
|
||||
{
|
||||
const uint32_t data = m_sif->fifo_pop(0);
|
||||
@ -124,7 +225,7 @@ void ps2_dmac_device::transfer_sif0()
|
||||
m_ee->space(AS_PROGRAM).write_dword(addr, data);
|
||||
addr += 4;
|
||||
}
|
||||
channel.set_addr(addr);
|
||||
channel.set_addr(channel.addr() + 0x10);
|
||||
channel.set_quadword_count(count - 1);
|
||||
//logerror("%s: SIF0 remaining count: %08x\n", machine().describe_context(), channel.quadword_count());
|
||||
}
|
||||
@ -163,6 +264,8 @@ void ps2_dmac_device::transfer_sif1()
|
||||
if (m_sif->fifo_depth(1) < (ps2_sif_device::MAX_FIFO_DEPTH - 4))
|
||||
{
|
||||
uint32_t addr = channel.addr();
|
||||
if (BIT(addr, 31))
|
||||
addr -= 0x10000000;
|
||||
address_space &space = m_ee->space(AS_PROGRAM);
|
||||
for (int word = 0; word < 4; word++)
|
||||
{
|
||||
@ -171,7 +274,7 @@ void ps2_dmac_device::transfer_sif1()
|
||||
addr += 4;
|
||||
m_sif->fifo_push(1, data);
|
||||
}
|
||||
channel.set_addr(addr);
|
||||
channel.set_addr(channel.addr() + 0x10);
|
||||
channel.set_quadword_count(count - 1);
|
||||
}
|
||||
}
|
||||
@ -190,9 +293,12 @@ void ps2_dmac_device::transfer_sif1()
|
||||
void ps2_dmac_device::follow_source_tag(uint32_t chan)
|
||||
{
|
||||
channel_t &channel = m_channels[chan];
|
||||
const uint32_t tag_addr = channel.tag_addr() >> 3;
|
||||
const uint64_t hi = m_ram[tag_addr];
|
||||
const uint64_t lo = m_ram[tag_addr + 1];
|
||||
uint32_t tag_addr = channel.tag_addr();
|
||||
if (BIT(tag_addr, 31))
|
||||
tag_addr -= 0x10000000;
|
||||
address_space &space = m_ee->space(AS_PROGRAM);
|
||||
const uint64_t hi = space.read_qword(tag_addr);
|
||||
const uint64_t lo = space.read_dword(tag_addr + 8);
|
||||
const uint32_t tag = (uint32_t)hi;
|
||||
const uint32_t addr = (uint32_t)(hi >> 32) & ~0xf;
|
||||
logerror("Trying to follow tag: %08x|%08x %08x|%08x\n", (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo);
|
||||
@ -204,17 +310,30 @@ void ps2_dmac_device::follow_source_tag(uint32_t chan)
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case ID_CNT:
|
||||
channel.set_addr(channel.tag_addr() + 0x10);
|
||||
channel.set_tag_addr(channel.addr() + (channel.quadword_count() << 4));
|
||||
break;
|
||||
case ID_REFE:
|
||||
channel.set_end_tag(true);
|
||||
// Intentional fall-through
|
||||
case ID_REF:
|
||||
channel.set_addr(addr);
|
||||
channel.set_tag_addr(channel.tag_addr() + 0x10);
|
||||
break;
|
||||
case ID_REFS:
|
||||
// We don't handle stalls yet, just act the same as REF for now
|
||||
channel.set_addr(addr);
|
||||
channel.set_tag_addr(channel.tag_addr() + 0x10);
|
||||
break;
|
||||
case ID_NEXT:
|
||||
channel.set_addr(channel.tag_addr() + 0x10);
|
||||
channel.set_tag_addr(addr);
|
||||
break;
|
||||
case ID_END:
|
||||
channel.set_addr(channel.tag_addr() + 0x10);
|
||||
channel.set_end_tag(true);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: Unknown DMAtag ID: %d\n", machine().describe_context(), id);
|
||||
break;
|
||||
@ -281,6 +400,7 @@ WRITE32_MEMBER(ps2_dmac_device::write)
|
||||
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_ctrl = data;
|
||||
m_enabled = BIT(data, 0);
|
||||
m_mem_drain = (data >> 2) & 3;
|
||||
break;
|
||||
@ -334,41 +454,49 @@ READ32_MEMBER(ps2_dmac_device::channel_r)
|
||||
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);
|
||||
case 0x9000/8: /* VIF1_CHCR */
|
||||
ret = m_channels[VIF1].chcr();
|
||||
//logerror("%s: dmac_channel_r: VIF1_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);
|
||||
case 0x9010/8: /* VIF1_MADR */
|
||||
ret = m_channels[VIF1].addr();
|
||||
logerror("%s: dmac_channel_r: VIF1_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);
|
||||
case 0x9020/8: /* VIF1_QWC */
|
||||
ret = m_channels[VIF1].quadword_count();
|
||||
logerror("%s: dmac_channel_r: VIF1_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);
|
||||
case 0x9030/8: /* VIF1_TADR */
|
||||
ret = m_channels[VIF1].tag_addr();
|
||||
logerror("%s: dmac_channel_r: VIF1_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);
|
||||
case 0x9040/8: /* VIF1_ASR0 */
|
||||
logerror("%s: dmac_channel_r: VIF1_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);
|
||||
case 0x9050/8: /* VIF1_ASR1 */
|
||||
logerror("%s: dmac_channel_r: VIF1_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);
|
||||
case 0xa000/8: /* GIF_CHCR */
|
||||
ret = m_channels[GIF].chcr();
|
||||
//logerror("%s: dmac_channel_r: GIF_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);
|
||||
case 0xa010/8: /* GIF_MADR */
|
||||
ret = m_channels[GIF].addr();
|
||||
logerror("%s: dmac_channel_r: GIF_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);
|
||||
case 0xa020/8: /* GIF_QWC */
|
||||
ret = m_channels[GIF].quadword_count();
|
||||
logerror("%s: dmac_channel_r: GIF_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);
|
||||
case 0xa030/8: /* GIF_TADR */
|
||||
ret = m_channels[GIF].tag_addr();
|
||||
logerror("%s: dmac_channel_r: GIF_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);
|
||||
case 0xa040/8: /* GIF_ASR0 */
|
||||
logerror("%s: dmac_channel_r: GIF_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);
|
||||
case 0xa050/8: /* GIF_ASR1 */
|
||||
logerror("%s: dmac_channel_r: GIF_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);
|
||||
@ -486,41 +614,51 @@ WRITE32_MEMBER(ps2_dmac_device::channel_w)
|
||||
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);
|
||||
case 0x9000/8: /* VIF1_CHCR */
|
||||
logerror("%s: dmac_channel_w: VIF1_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[VIF1].set_chcr(data);
|
||||
break;
|
||||
case 0x9010/8: /* D1_MADR */
|
||||
logerror("%s: dmac_channel_w: D1_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0x9010/8: /* VIF1_MADR */
|
||||
logerror("%s: dmac_channel_w: VIF1_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_channels[VIF1].set_addr(data);
|
||||
break;
|
||||
case 0x9020/8: /* D1_QWC */
|
||||
logerror("%s: dmac_channel_w: D1_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0x9020/8: /* VIF1_QWC */
|
||||
logerror("%s: dmac_channel_w: VIF1_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_channels[VIF1].set_quadword_count(data);
|
||||
break;
|
||||
case 0x9030/8: /* D1_TADR */
|
||||
logerror("%s: dmac_channel_w: D1_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0x9030/8: /* VIF1_TADR */
|
||||
logerror("%s: dmac_channel_w: VIF1_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_channels[VIF1].set_tag_addr(data);
|
||||
break;
|
||||
case 0x9040/8: /* D1_ASR0 */
|
||||
logerror("%s: dmac_channel_w: D1_ASR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0x9040/8: /* VIF1_ASR0 */
|
||||
logerror("%s: dmac_channel_w: VIF1_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);
|
||||
case 0x9050/8: /* VIF1_ASR1 */
|
||||
logerror("%s: dmac_channel_w: VIF1_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);
|
||||
case 0xa000/8: /* GIF_CHCR */
|
||||
logerror("%s: dmac_channel_w: GIF_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[GIF].set_chcr(data);
|
||||
break;
|
||||
case 0xa010/8: /* D2_MADR */
|
||||
logerror("%s: dmac_channel_w: D2_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0xa010/8: /* GIF_MADR */
|
||||
logerror("%s: dmac_channel_w: GIF_MADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_channels[GIF].set_addr(data);
|
||||
break;
|
||||
case 0xa020/8: /* D2_QWC */
|
||||
logerror("%s: dmac_channel_w: D2_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0xa020/8: /* GIF_QWC */
|
||||
logerror("%s: dmac_channel_w: GIF_QWC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_channels[GIF].set_quadword_count(data);
|
||||
break;
|
||||
case 0xa030/8: /* D2_TADR */
|
||||
logerror("%s: dmac_channel_w: D2_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0xa030/8: /* GIF_TADR */
|
||||
logerror("%s: dmac_channel_w: GIF_TADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_channels[GIF].set_tag_addr(data);
|
||||
break;
|
||||
case 0xa040/8: /* D2_ASR0 */
|
||||
logerror("%s: dmac_channel_w: D2_ASR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
case 0xa040/8: /* GIF_ASR0 */
|
||||
logerror("%s: dmac_channel_w: GIF_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);
|
||||
case 0xa050/8: /* GIF_ASR1 */
|
||||
logerror("%s: dmac_channel_w: GIF_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);
|
||||
|
@ -15,17 +15,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "emu.h"
|
||||
#include "ps2gif.h"
|
||||
#include "ps2vif1.h"
|
||||
|
||||
class ps2_dmac_device : public device_t, public device_execute_interface
|
||||
{
|
||||
public:
|
||||
template <typename T, typename U, typename V>
|
||||
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)
|
||||
template <typename T, typename U, typename V, typename W, typename X>
|
||||
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, W &&gif_tag, X &&vif1_tag)
|
||||
: ps2_dmac_device(mconfig, tag, owner, clock)
|
||||
{
|
||||
m_ee.set_tag(std::forward<T>(ee_tag));
|
||||
m_ram.set_tag(std::forward<U>(ram_tag));
|
||||
m_sif.set_tag(std::forward<V>(sif_tag));
|
||||
m_gif.set_tag(std::forward<W>(gif_tag));
|
||||
m_vif1.set_tag(std::forward<X>(vif1_tag));
|
||||
}
|
||||
|
||||
ps2_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -113,6 +117,8 @@ protected:
|
||||
uint32_t m_tag_addr;
|
||||
};
|
||||
|
||||
void transfer_vif1();
|
||||
void transfer_gif();
|
||||
void transfer_sif0();
|
||||
void transfer_sif1();
|
||||
void transfer_finish(uint32_t chan);
|
||||
@ -122,6 +128,8 @@ protected:
|
||||
required_device<cpu_device> m_ee;
|
||||
required_shared_ptr<uint64_t> m_ram;
|
||||
required_device<ps2_sif_device> m_sif;
|
||||
required_device<ps2_gif_device> m_gif;
|
||||
required_device<ps2_vif1_device> m_vif1;
|
||||
|
||||
int m_icount;
|
||||
|
||||
|
256
src/mame/machine/ps2gif.cpp
Normal file
256
src/mame/machine/ps2gif.cpp
Normal file
@ -0,0 +1,256 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 GS interface (GIF) device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ps2gif.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SONYPS2_GIF, ps2_gif_device, "ps2gif", "Playstation 2 GIF")
|
||||
|
||||
ps2_gif_device::ps2_gif_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SONYPS2_GIF, tag, owner, clock)
|
||||
, m_gs(*this, finder_base::DUMMY_TAG)
|
||||
{
|
||||
}
|
||||
|
||||
ps2_gif_device::tag_t::tag_t(const uint64_t hi, const uint64_t lo)
|
||||
: m_nloop(lo & 0x7fffULL)
|
||||
, m_end((lo >> 15) & 1)
|
||||
, m_prim_enable((lo >> 46) & 1)
|
||||
, m_prim_output(false)
|
||||
, m_prim((lo >> 47) & 0x7ff)
|
||||
, m_format((format_t)((lo >> 58) & 3))
|
||||
, m_reg_count((uint8_t)(lo >> 60))
|
||||
, m_curr_reg(0)
|
||||
{
|
||||
if (!m_reg_count)
|
||||
m_reg_count = 16;
|
||||
|
||||
for (uint32_t shift = 0, index = 0; shift < 64; shift += 4, index++)
|
||||
{
|
||||
m_regs[index] = (uint8_t)(hi >> shift) & 0xf;
|
||||
}
|
||||
|
||||
m_words[0] = (uint32_t)(hi >> 32);
|
||||
m_words[1] = (uint32_t)hi;
|
||||
m_words[2] = (uint32_t)(lo >> 32);
|
||||
m_words[3] = (uint32_t)lo;
|
||||
}
|
||||
|
||||
void ps2_gif_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_ctrl));
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_stat));
|
||||
save_item(NAME(m_cnt));
|
||||
save_item(NAME(m_p3cnt));
|
||||
save_item(NAME(m_p3tag));
|
||||
save_item(NAME(m_p3mask));
|
||||
|
||||
// TODO: Save current tag
|
||||
}
|
||||
|
||||
void ps2_gif_device::device_reset()
|
||||
{
|
||||
gif_reset();
|
||||
}
|
||||
|
||||
void ps2_gif_device::gif_reset()
|
||||
{
|
||||
m_ctrl = CTRL_RST;
|
||||
m_mode = 0;
|
||||
m_stat = 0;
|
||||
m_cnt = 0;
|
||||
m_p3cnt = 0;
|
||||
m_p3tag = 0;
|
||||
m_p3mask = false;
|
||||
m_current_tag = tag_t();
|
||||
}
|
||||
|
||||
READ32_MEMBER(ps2_gif_device::read)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/4: // GIF_CTRL
|
||||
if (BIT(m_ctrl, 3))
|
||||
{
|
||||
ret = m_ctrl;
|
||||
logerror("%s: Read: GIF_CTRL (%08x)\n", machine().describe_context(), ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%s: Read: GIF_CTRL (00000000) (read-only; actual value %08x)\n", machine().describe_context(), m_ctrl);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x10/4: // GIF_MODE
|
||||
ret = m_mode;
|
||||
logerror("%s: Read: GIF_MODE (00000000) (read-only; actual value %08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0x20/4: // GIF_STAT
|
||||
ret = m_stat;
|
||||
logerror("%s: Read: GIF_STAT (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0x40/4: // GIF_TAG0
|
||||
ret = m_current_tag.word(0);
|
||||
logerror("%s: Read: GIF_TAG0 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0x50/4: // GIF_TAG1
|
||||
ret = m_current_tag.word(1);
|
||||
logerror("%s: Read: GIF_TAG1 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0x60/4: // GIF_TAG2
|
||||
ret = m_current_tag.word(2);
|
||||
logerror("%s: Read: GIF_TAG2 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0x70/4: // GIF_TAG3
|
||||
ret = m_current_tag.word(0);
|
||||
logerror("%s: Read: GIF_TAG3 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0x80/4: // GIF_CNT
|
||||
ret = m_cnt;
|
||||
logerror("%s: Read: GIF_CNT (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0x90/4: // GIF_P3CNT
|
||||
ret = m_p3cnt;
|
||||
logerror("%s: Read: GIF_P3CNT (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
case 0xa0/4: // GIF_P3TAG
|
||||
ret = m_p3tag;
|
||||
logerror("%s: Read: GIF_P3TAG (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("%s: Read: Unknown %08x\n", machine().describe_context(), 0x10003000 + (offset << 2));
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(ps2_gif_device::write)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/4: // GIF_CTRL
|
||||
m_ctrl = data;
|
||||
if (BIT(data, 0))
|
||||
{
|
||||
gif_reset();
|
||||
}
|
||||
logerror("%s: Write: GIF_CTRL = %08x: STOP=%d, RESET=%d\n", machine().describe_context(), data, BIT(data, 3), BIT(data, 0));
|
||||
break;
|
||||
|
||||
case 0x10/4: // GIF_MODE
|
||||
m_mode = data;
|
||||
logerror("%s: Write: GIF_MODE = %08x: IMT=%s, MASK=%s\n", machine().describe_context(), data, BIT(data, 2) ? "Intermittent" : "Continuous", BIT(data, 0) ? "Yes" : "No");
|
||||
break;
|
||||
|
||||
case 0x20/4: // GIF_STAT
|
||||
logerror("%s: Write: GIF_STAT = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
case 0x40/4: // GIF_TAG0
|
||||
logerror("%s: Write: GIF_TAG0 = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
case 0x50/4: // GIF_TAG1
|
||||
logerror("%s: Write: GIF_TAG1 = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
case 0x60/4: // GIF_TAG2
|
||||
logerror("%s: Write: GIF_TAG2 = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
case 0x70/4: // GIF_TAG3
|
||||
logerror("%s: Write: GIF_TAG3 = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
case 0x80/4: // GIF_CNT
|
||||
logerror("%s: Write: GIF_CNT = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
case 0x90/4: // GIF_P3CNT
|
||||
logerror("%s: Write: GIF_P3CNT = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
case 0xa0/4: // GIF_P3TAG
|
||||
logerror("%s: Write: GIF_P3TAG = %08x (ignored)\n", machine().describe_context(), data);
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("%s: Write: Unknown %08x = %08x\n", machine().describe_context(), 0x10003000 + (offset << 2), data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_gif_device::write_path3(uint64_t hi, uint64_t lo)
|
||||
{
|
||||
if (m_p3mask)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_current_tag.valid())
|
||||
{
|
||||
m_current_tag = tag_t(hi, lo);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_current_tag.format())
|
||||
{
|
||||
case tag_t::format_t::FMT_PACKED:
|
||||
if (m_current_tag.is_prim() && !m_current_tag.is_prim_output())
|
||||
{
|
||||
m_current_tag.set_prim_output();
|
||||
logerror("%s: PATH3: PACKED: Not yet implemented: PRIM\n", machine().describe_context());
|
||||
}
|
||||
else if (m_current_tag.nloop())
|
||||
{
|
||||
const uint8_t reg = m_current_tag.reg();
|
||||
m_gs->write_packed(reg, hi, lo);
|
||||
m_current_tag.next_reg();
|
||||
}
|
||||
break;
|
||||
case tag_t::format_t::FMT_REGLIST:
|
||||
logerror("%s: PATH3: Not yet implemented: REGLIST (%08x%08x%08x%08x)\n", machine().describe_context(), (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo);
|
||||
m_current_tag.loop();
|
||||
break;
|
||||
default:
|
||||
//logerror("%s: PATH3: Not yet implemented: IMAGE (%08x%08x%08x%08x)\n", machine().describe_context(), (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo);
|
||||
m_gs->regs_w(machine().dummy_space(), 0x54, lo);
|
||||
m_gs->regs_w(machine().dummy_space(), 0x54, hi);
|
||||
m_current_tag.loop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_gif_device::tag_t::next_reg()
|
||||
{
|
||||
m_curr_reg++;
|
||||
if (m_curr_reg == m_reg_count)
|
||||
{
|
||||
m_curr_reg = 0;
|
||||
loop();
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_gif_device::set_path3_mask(bool masked)
|
||||
{
|
||||
m_p3mask = masked;
|
||||
}
|
||||
|
109
src/mame/machine/ps2gif.h
Normal file
109
src/mame/machine/ps2gif.h
Normal file
@ -0,0 +1,109 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 GS Interface (GIF) device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAME_MACHINE_PS2GIF_H
|
||||
#define MAME_MACHINE_PS2GIF_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "emu.h"
|
||||
#include "video/ps2gs.h"
|
||||
|
||||
class ps2_gif_device : public device_t
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
ps2_gif_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gs_tag)
|
||||
: ps2_gif_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
m_gs.set_tag(std::forward<T>(gs_tag));
|
||||
}
|
||||
|
||||
ps2_gif_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_READ32_MEMBER(read);
|
||||
DECLARE_WRITE32_MEMBER(write);
|
||||
|
||||
void write_path3(uint64_t hi, uint64_t lo);
|
||||
void set_path3_mask(bool masked);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
void gif_reset();
|
||||
|
||||
class tag_t
|
||||
{
|
||||
public:
|
||||
tag_t() : m_nloop(0), m_end(false), m_prim_enable(false), m_prim_output(false), m_prim(0), m_format(FMT_DISABLE), m_reg_count(0), m_curr_reg(0)
|
||||
{
|
||||
memset(m_regs, 0, 16);
|
||||
memset(m_words, 0, sizeof(uint32_t) * 4);
|
||||
}
|
||||
tag_t(uint64_t lo, uint64_t hi);
|
||||
|
||||
enum format_t : uint8_t
|
||||
{
|
||||
FMT_PACKED = 0,
|
||||
FMT_REGLIST,
|
||||
FMT_IMAGE,
|
||||
FMT_DISABLE
|
||||
};
|
||||
|
||||
bool valid() const { return m_nloop != 0; }
|
||||
uint16_t nloop() const { return m_nloop; }
|
||||
bool end() const { return m_end; }
|
||||
bool is_prim() const { return m_prim_enable; }
|
||||
bool is_prim_output() const { return m_prim_output; }
|
||||
void set_prim_output() { m_prim_output = true; }
|
||||
uint16_t prim() const { return m_prim; }
|
||||
format_t format() const { return m_format; }
|
||||
uint32_t word(offs_t index) const { return m_words[index]; }
|
||||
uint32_t reg() const { return m_regs[m_curr_reg]; }
|
||||
|
||||
void loop() { m_nloop--; }
|
||||
void next_reg();
|
||||
|
||||
protected:
|
||||
uint16_t m_nloop;
|
||||
bool m_end;
|
||||
bool m_prim_enable;
|
||||
bool m_prim_output;
|
||||
uint16_t m_prim;
|
||||
format_t m_format;
|
||||
uint8_t m_reg_count;
|
||||
uint8_t m_curr_reg;
|
||||
uint8_t m_regs[16];
|
||||
uint32_t m_words[4];
|
||||
};
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
CTRL_RST = (1 << 0),
|
||||
CTRL_PSE = (1 << 3)
|
||||
};
|
||||
|
||||
required_device<ps2_gs_device> m_gs;
|
||||
|
||||
uint32_t m_ctrl;
|
||||
uint32_t m_mode;
|
||||
uint32_t m_stat;
|
||||
tag_t m_current_tag; // tag0..3
|
||||
uint32_t m_cnt;
|
||||
uint32_t m_p3cnt;
|
||||
uint32_t m_p3tag;
|
||||
bool m_p3mask;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SONYPS2_GIF, ps2_gif_device)
|
||||
|
||||
#endif // MAME_MACHINE_PS2GIF_H
|
@ -67,4 +67,4 @@ protected:
|
||||
|
||||
DECLARE_DEVICE_TYPE(SONYPS2_INTC, ps2_intc_device)
|
||||
|
||||
#endif // MAME_MACHINE_PS2SIF_H
|
||||
#endif // MAME_MACHINE_PS2INTC_H
|
197
src/mame/machine/ps2mc.cpp
Normal file
197
src/mame/machine/ps2mc.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 memory card skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ps2mc.h"
|
||||
|
||||
/*static*/ const size_t ps2_mc_device::BUFFER_SIZE = 512; // Total guess
|
||||
/*static*/ const uint8_t ps2_mc_device::DEFAULT_TERMINATOR = 0x55;
|
||||
|
||||
DEFINE_DEVICE_TYPE(SONYPS2_MC, ps2_mc_device, "ps2mc", "PlayStation 2 Memory Card")
|
||||
|
||||
ps2_mc_device::ps2_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SONYPS2_MC, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void ps2_mc_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_recv_buf));
|
||||
save_item(NAME(m_xmit_buf));
|
||||
save_item(NAME(m_curr_recv));
|
||||
save_item(NAME(m_curr_xmit));
|
||||
save_item(NAME(m_end_recv));
|
||||
save_item(NAME(m_end_xmit));
|
||||
save_item(NAME(m_cmd));
|
||||
save_item(NAME(m_cmd_size));
|
||||
save_item(NAME(m_terminator));
|
||||
save_item(NAME(m_status));
|
||||
}
|
||||
|
||||
void ps2_mc_device::device_reset()
|
||||
{
|
||||
memset(m_recv_buf, 0, BUFFER_SIZE);
|
||||
memset(m_xmit_buf, 0, BUFFER_SIZE);
|
||||
|
||||
m_curr_recv = 0;
|
||||
m_curr_xmit = 0;
|
||||
|
||||
m_end_recv = 0;
|
||||
m_end_xmit = 0;
|
||||
|
||||
m_cmd = 0;
|
||||
m_cmd_size = 0;
|
||||
m_terminator = DEFAULT_TERMINATOR;
|
||||
m_status = 0;
|
||||
}
|
||||
|
||||
void ps2_mc_device::recv_fifo_push(uint8_t data)
|
||||
{
|
||||
if (m_end_recv >= BUFFER_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_recv_buf[m_end_recv++] = data;
|
||||
|
||||
//logerror("%s: Receiving %02x from SIO2, new top: %d\n", machine().describe_context(), data, m_end_recv);
|
||||
}
|
||||
|
||||
void ps2_mc_device::xmit_fifo_push(uint8_t data)
|
||||
{
|
||||
if (m_end_xmit >= BUFFER_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//logerror("%s: Pushing %02x onto transmit FIFO\n", machine().describe_context(), data);
|
||||
|
||||
m_xmit_buf[m_end_xmit++] = data;
|
||||
}
|
||||
|
||||
uint8_t ps2_mc_device::xmit_fifo_pop()
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
if (m_curr_xmit < m_end_xmit)
|
||||
{
|
||||
ret = m_xmit_buf[m_curr_xmit++];
|
||||
}
|
||||
if (m_curr_xmit >= m_end_xmit)
|
||||
{
|
||||
m_curr_xmit = 0;
|
||||
m_end_xmit = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t ps2_mc_device::recv_fifo_pop()
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
if (m_curr_recv < m_end_recv)
|
||||
{
|
||||
ret = m_recv_buf[m_curr_recv++];
|
||||
}
|
||||
if (m_curr_recv >= m_end_recv)
|
||||
{
|
||||
m_curr_recv = 0;
|
||||
m_end_recv = 0;
|
||||
}
|
||||
//logerror("recv_fifo_pop %02x, %d/%d\n", ret, m_curr_recv, m_end_recv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ps2_mc_device::process_fifos()
|
||||
{
|
||||
m_status = 0;
|
||||
m_cmd_size = 0;
|
||||
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
const uint8_t data = recv_fifo_pop();
|
||||
m_cmd_size++;
|
||||
|
||||
if (m_cmd_size == 1)
|
||||
{
|
||||
if (data == SIO_DEVICE_ID)
|
||||
{
|
||||
xmit_fifo_push(0x2b);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%s: Unknkown command byte 1: %02x\n", machine().describe_context(), data);
|
||||
}
|
||||
}
|
||||
else if (m_cmd_size == 2)
|
||||
{
|
||||
process_command(data);
|
||||
}
|
||||
}
|
||||
|
||||
m_curr_recv = 0;
|
||||
m_end_recv = 0;
|
||||
}
|
||||
|
||||
void ps2_mc_device::process_command(uint8_t data)
|
||||
{
|
||||
m_cmd = data;
|
||||
|
||||
switch (m_cmd)
|
||||
{
|
||||
case CMD_UNKNOWN_F3:
|
||||
//logerror("%s: MC command: Unknown 0xf3\n", machine().describe_context());
|
||||
cmd_init();
|
||||
m_status = 0;
|
||||
break;
|
||||
case CMD_INIT:
|
||||
//logerror("%s: MC command: Init (%02x)\n", machine().describe_context(), m_cmd);
|
||||
cmd_init();
|
||||
break;
|
||||
case CMD_GET_TERM:
|
||||
//logerror("%s: MC command: Get Terminator\n", machine().describe_context());
|
||||
cmd_get_term();
|
||||
break;
|
||||
default:
|
||||
logerror("%s: Unknown MC command: %02x\n", machine().describe_context(), m_cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_mc_device::cmd_init()
|
||||
{
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 2)
|
||||
{
|
||||
m_status = 0x8c;
|
||||
xmit_fifo_push(m_terminator);
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_mc_device::cmd_get_term()
|
||||
{
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 2)
|
||||
{
|
||||
m_status = 0x8b;
|
||||
xmit_fifo_push(m_terminator);
|
||||
xmit_fifo_push(0x55);
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
75
src/mame/machine/ps2mc.h
Normal file
75
src/mame/machine/ps2mc.h
Normal file
@ -0,0 +1,75 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 memory card skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAME_MACHINE_PS2MC_H
|
||||
#define MAME_MACHINE_PS2MC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
class ps2_mc_device : public device_t
|
||||
{
|
||||
public:
|
||||
ps2_mc_device(const machine_config &mconfig, const char *tag, device_t *owner)
|
||||
: ps2_mc_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
}
|
||||
|
||||
ps2_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void recv_fifo_push(uint8_t data); // TODO: Turn me into a bus interface!
|
||||
uint8_t xmit_fifo_pop();
|
||||
uint8_t xmit_fifo_depth() const { return m_end_xmit - m_curr_xmit; }
|
||||
void process_fifos();
|
||||
|
||||
uint8_t status() const { return m_status; }
|
||||
|
||||
static const uint8_t SIO_DEVICE_ID = 0x81;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
void xmit_fifo_push(uint8_t data);
|
||||
uint8_t recv_fifo_pop();
|
||||
uint8_t recv_fifo_depth() const { return m_end_recv - m_curr_recv; }
|
||||
void process_command(uint8_t data);
|
||||
|
||||
void cmd_init();
|
||||
void cmd_get_term();
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
CMD_INIT = 0x11,
|
||||
CMD_GET_TERM = 0x28,
|
||||
CMD_UNKNOWN_F3 = 0xf3,
|
||||
};
|
||||
|
||||
uint8_t m_recv_buf[512]; // Buffer size is a guess
|
||||
uint8_t m_xmit_buf[512];
|
||||
uint32_t m_curr_recv;
|
||||
uint32_t m_curr_xmit;
|
||||
uint32_t m_end_recv;
|
||||
uint32_t m_end_xmit;
|
||||
|
||||
uint8_t m_cmd;
|
||||
uint32_t m_cmd_size;
|
||||
uint8_t m_terminator;
|
||||
uint8_t m_status;
|
||||
|
||||
static const size_t BUFFER_SIZE;
|
||||
static const uint8_t DEFAULT_TERMINATOR;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SONYPS2_MC, ps2_mc_device)
|
||||
|
||||
#endif // MAME_MACHINE_PS2MC_H
|
328
src/mame/machine/ps2pad.cpp
Normal file
328
src/mame/machine/ps2pad.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 DualShock 2 ('pad') device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ps2pad.h"
|
||||
|
||||
/*static*/ const size_t ps2_pad_device::BUFFER_SIZE = 64; // Total guess
|
||||
|
||||
DEFINE_DEVICE_TYPE(SONYPS2_PAD, ps2_pad_device, "ps2pad", "DualShock 2")
|
||||
|
||||
ps2_pad_device::ps2_pad_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SONYPS2_PAD, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void ps2_pad_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_recv_buf));
|
||||
save_item(NAME(m_xmit_buf));
|
||||
save_item(NAME(m_curr_recv));
|
||||
save_item(NAME(m_curr_xmit));
|
||||
save_item(NAME(m_end_recv));
|
||||
save_item(NAME(m_end_xmit));
|
||||
save_item(NAME(m_cmd));
|
||||
save_item(NAME(m_cmd_size));
|
||||
save_item(NAME(m_configuring));
|
||||
}
|
||||
|
||||
void ps2_pad_device::device_reset()
|
||||
{
|
||||
memset(m_recv_buf, 0, BUFFER_SIZE);
|
||||
memset(m_xmit_buf, 0, BUFFER_SIZE);
|
||||
|
||||
m_curr_recv = 0;
|
||||
m_curr_xmit = 0;
|
||||
|
||||
m_end_recv = 0;
|
||||
m_end_xmit = 0;
|
||||
|
||||
m_cmd = 0;
|
||||
m_cmd_size = 0;
|
||||
m_configuring = false;
|
||||
}
|
||||
|
||||
void ps2_pad_device::recv_fifo_push(uint8_t data)
|
||||
{
|
||||
if (m_end_recv >= BUFFER_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//logerror("%s: Receiving %02x from SIO2\n", machine().describe_context(), data);
|
||||
|
||||
m_recv_buf[m_end_recv++] = data;
|
||||
}
|
||||
|
||||
void ps2_pad_device::xmit_fifo_push(uint8_t data)
|
||||
{
|
||||
if (m_end_xmit >= BUFFER_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//logerror("%s: Pushing %02x onto transmit FIFO\n", machine().describe_context(), data);
|
||||
|
||||
m_xmit_buf[m_end_xmit++] = data;
|
||||
}
|
||||
|
||||
uint8_t ps2_pad_device::xmit_fifo_pop()
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
if (m_curr_xmit < m_end_xmit)
|
||||
{
|
||||
ret = m_xmit_buf[m_curr_xmit++];
|
||||
}
|
||||
if (m_curr_xmit == m_end_xmit)
|
||||
{
|
||||
m_curr_xmit = 0;
|
||||
m_end_xmit = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t ps2_pad_device::recv_fifo_pop()
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
if (m_curr_recv < m_end_recv)
|
||||
{
|
||||
ret = m_recv_buf[m_curr_recv++];
|
||||
}
|
||||
if (m_curr_recv == m_end_recv)
|
||||
{
|
||||
m_curr_recv = 0;
|
||||
m_end_recv = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ps2_pad_device::process_fifos()
|
||||
{
|
||||
m_cmd_size = 0;
|
||||
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
const uint8_t data = recv_fifo_pop();
|
||||
m_cmd_size++;
|
||||
|
||||
if (m_cmd_size == 1)
|
||||
{
|
||||
if (data == SIO_DEVICE_ID)
|
||||
{
|
||||
xmit_fifo_push(0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%s: Unknkown command byte 1: %02x\n", machine().describe_context(), data);
|
||||
}
|
||||
}
|
||||
else if (m_cmd_size == 2)
|
||||
{
|
||||
process_command(data);
|
||||
}
|
||||
}
|
||||
|
||||
m_curr_recv = 0;
|
||||
m_end_recv = 0;
|
||||
}
|
||||
|
||||
void ps2_pad_device::process_command(uint8_t data)
|
||||
{
|
||||
m_cmd = data;
|
||||
|
||||
switch (m_cmd)
|
||||
{
|
||||
case CMD_READ_BUTTONS:
|
||||
//logerror("%s: Pad command: Read Buttons\n", machine().describe_context());
|
||||
cmd_read_buttons();
|
||||
break;
|
||||
case CMD_CONFIG:
|
||||
//logerror("%s: Pad command: Config\n", machine().describe_context());
|
||||
cmd_config();
|
||||
break;
|
||||
case CMD_GET_MODEL:
|
||||
//logerror("%s: Pad command: Get Model\n", machine().describe_context());
|
||||
cmd_get_model();
|
||||
break;
|
||||
case CMD_GET_ACT:
|
||||
//logerror("%s: Pad command: Get Act\n", machine().describe_context());
|
||||
cmd_get_act();
|
||||
break;
|
||||
case CMD_GET_COMB:
|
||||
//logerror("%s: Pad command: Get Comb\n", machine().describe_context());
|
||||
cmd_get_comb();
|
||||
break;
|
||||
case CMD_GET_MODE:
|
||||
//logerror("%s: Pad command: Get Mode\n", machine().describe_context());
|
||||
cmd_get_comb();
|
||||
break;
|
||||
default:
|
||||
logerror("%s: Unknown pad command: %02x, forcing idle\n", machine().describe_context(), m_cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_pad_device::cmd_read_buttons()
|
||||
{
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 2)
|
||||
{
|
||||
xmit_fifo_push(0x41);
|
||||
xmit_fifo_push(0x5a);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_pad_device::cmd_config()
|
||||
{
|
||||
if (m_configuring)
|
||||
{
|
||||
xmit_fifo_push(0xf3);
|
||||
xmit_fifo_push(0x5a);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
return;
|
||||
}
|
||||
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
const uint8_t data = recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 2)
|
||||
{
|
||||
xmit_fifo_push(0x41);
|
||||
xmit_fifo_push(0x5a);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
}
|
||||
else if (m_cmd_size == 3)
|
||||
{
|
||||
m_configuring = BIT(data, 0);
|
||||
//logerror("%s: Entering config mode? %c\n", machine().describe_context(), m_configuring ? 'Y' : 'N');
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_pad_device::cmd_get_model()
|
||||
{
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 2)
|
||||
{
|
||||
xmit_fifo_push(0xf3);
|
||||
xmit_fifo_push(0x5a);
|
||||
xmit_fifo_push(0x01);
|
||||
xmit_fifo_push(0x02);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x02);
|
||||
xmit_fifo_push(0x01);
|
||||
xmit_fifo_push(0x00);
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_pad_device::cmd_get_act()
|
||||
{
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
const uint8_t data = recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 3)
|
||||
{
|
||||
xmit_fifo_push(0xf3);
|
||||
xmit_fifo_push(0x5a);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x01);
|
||||
if (data < 2)
|
||||
{
|
||||
xmit_fifo_push(0x01);
|
||||
xmit_fifo_push(0x01);
|
||||
xmit_fifo_push(0x14);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmit_fifo_push(0x02);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x0a);
|
||||
}
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_pad_device::cmd_get_comb()
|
||||
{
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 2)
|
||||
{
|
||||
xmit_fifo_push(0xf3);
|
||||
xmit_fifo_push(0x5a);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x02);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x01);
|
||||
xmit_fifo_push(0x00);
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_pad_device::cmd_get_mode()
|
||||
{
|
||||
while (recv_fifo_depth())
|
||||
{
|
||||
const uint8_t data = recv_fifo_pop();
|
||||
|
||||
if (m_cmd_size == 3)
|
||||
{
|
||||
xmit_fifo_push(0xf3);
|
||||
xmit_fifo_push(0x5a);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
if (data < 2)
|
||||
{
|
||||
xmit_fifo_push(4 + data * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmit_fifo_push(0x00);
|
||||
}
|
||||
xmit_fifo_push(0x00);
|
||||
xmit_fifo_push(0x00);
|
||||
}
|
||||
|
||||
m_cmd_size++;
|
||||
}
|
||||
}
|
78
src/mame/machine/ps2pad.h
Normal file
78
src/mame/machine/ps2pad.h
Normal file
@ -0,0 +1,78 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 DualShock 2 ('pad') device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAME_MACHINE_PS2PAD_H
|
||||
#define MAME_MACHINE_PS2PAD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
class ps2_pad_device : public device_t
|
||||
{
|
||||
public:
|
||||
ps2_pad_device(const machine_config &mconfig, const char *tag, device_t *owner)
|
||||
: ps2_pad_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
}
|
||||
|
||||
ps2_pad_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void recv_fifo_push(uint8_t data); // TODO: Turn me into a bus interface!
|
||||
uint8_t xmit_fifo_pop();
|
||||
uint8_t xmit_fifo_depth() const { return m_end_xmit - m_curr_xmit; }
|
||||
void process_fifos();
|
||||
|
||||
static const uint8_t SIO_DEVICE_ID = 0x01;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
void xmit_fifo_push(uint8_t data);
|
||||
uint8_t recv_fifo_pop();
|
||||
uint8_t recv_fifo_depth() const { return m_end_recv - m_curr_recv; }
|
||||
void process_command(uint8_t data);
|
||||
|
||||
void cmd_read_buttons();
|
||||
void cmd_config();
|
||||
void cmd_get_model();
|
||||
void cmd_get_act();
|
||||
void cmd_get_comb();
|
||||
void cmd_get_mode();
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
CMD_READ_BUTTONS = 0x42,
|
||||
CMD_CONFIG = 0x43,
|
||||
CMD_GET_MODEL = 0x45,
|
||||
CMD_GET_ACT = 0x46,
|
||||
CMD_GET_COMB = 0x47,
|
||||
CMD_GET_MODE = 0x4c,
|
||||
};
|
||||
|
||||
uint8_t m_recv_buf[64]; // Buffer size is a guess
|
||||
uint8_t m_xmit_buf[64];
|
||||
uint8_t m_curr_recv;
|
||||
uint8_t m_curr_xmit;
|
||||
uint8_t m_end_recv;
|
||||
uint8_t m_end_xmit;
|
||||
|
||||
uint8_t m_cmd;
|
||||
uint8_t m_cmd_size;
|
||||
bool m_configuring;
|
||||
|
||||
static const size_t BUFFER_SIZE;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SONYPS2_PAD, ps2_pad_device)
|
||||
|
||||
#endif // MAME_MACHINE_PS2PAD_H
|
@ -54,15 +54,15 @@ READ32_MEMBER(ps2_sif_device::ee_r)
|
||||
{
|
||||
case 0:
|
||||
ret = m_ms_mailbox;
|
||||
logerror("%s: ee_r: SIF master->slave mailbox (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
//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);
|
||||
//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);
|
||||
//logerror("%s: ee_r: SIF master->slave flag (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
break;
|
||||
case 6:
|
||||
ret = m_sm_flag;
|
||||
@ -71,7 +71,7 @@ READ32_MEMBER(ps2_sif_device::ee_r)
|
||||
break;
|
||||
case 8:
|
||||
ret = m_ctrl | 0xF0000102;
|
||||
logerror("%s: ee_r: SIF control (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
//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);
|
||||
@ -85,19 +85,19 @@ 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);
|
||||
//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);
|
||||
//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);
|
||||
//logerror("%s: ee_w: SIF clear slave->master flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask);
|
||||
m_sm_flag &= ~data;
|
||||
break;
|
||||
case 8:
|
||||
logerror("%s: ee_w: SIF set control = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
//logerror("%s: ee_w: SIF set control = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
if (BIT(data, 8))
|
||||
m_ctrl |= (1 << 8);
|
||||
else
|
||||
@ -117,24 +117,24 @@ READ32_MEMBER(ps2_sif_device::iop_r)
|
||||
{
|
||||
case 0:
|
||||
ret = m_ms_mailbox;
|
||||
logerror("%s: iop_r: SIF master->slave mailbox (%08x & %08x)\n", machine().describe_context(), ret, mem_mask);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
//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);
|
||||
@ -148,19 +148,19 @@ 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);
|
||||
//logerror("%s: iop_w: SIF slave->master mailbox (%08x & %08x)\n", machine().describe_context(), data, mem_mask);
|
||||
m_sm_mailbox = data;
|
||||
break;
|
||||
case 8:
|
||||
logerror("%s: iop_w: SIF clear master->slave flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask);
|
||||
//logerror("%s: iop_w: SIF clear master->slave flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask);
|
||||
m_ms_flag &= ~data;
|
||||
break;
|
||||
case 12:
|
||||
logerror("%s: iop_w: SIF set slave->master flag (%08x & %08x)\n", machine().describe_context(), data, mem_mask);
|
||||
//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);
|
||||
//logerror("%s: iop_w: SIF set control (%08x & %08x)\n", machine().describe_context(), data, mem_mask);
|
||||
m_ctrl ^= data & 0xf0;
|
||||
if (data & 0x80 || data & 0x20)
|
||||
{
|
||||
|
571
src/mame/machine/ps2vif1.cpp
Normal file
571
src/mame/machine/ps2vif1.cpp
Normal file
@ -0,0 +1,571 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 VU1 interface (VIF1) device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
* Note: STAT mode bit twiddling is a total guess
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ps2vif1.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SONYPS2_VIF1, ps2_vif1_device, "ps2vif1", "Playstation 2 VIF1")
|
||||
|
||||
/*static*/ const size_t ps2_vif1_device::BUFFER_SIZE = 0x40;
|
||||
/*static*/ const uint32_t ps2_vif1_device::FORMAT_SIZE[] = {
|
||||
1, 1, 1, 1,
|
||||
2, 1, 1, 1,
|
||||
3, 2, 1, 1,
|
||||
4, 2, 1, 2
|
||||
};
|
||||
|
||||
ps2_vif1_device::ps2_vif1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SONYPS2_VIF1, tag, owner, clock)
|
||||
, device_execute_interface(mconfig, *this)
|
||||
, m_gif(*this, finder_base::DUMMY_TAG)
|
||||
{
|
||||
}
|
||||
|
||||
void ps2_vif1_device::device_start()
|
||||
{
|
||||
set_icountptr(m_icount);
|
||||
|
||||
save_item(NAME(m_icount));
|
||||
|
||||
save_item(NAME(m_buffer));
|
||||
save_item(NAME(m_curr));
|
||||
save_item(NAME(m_end));
|
||||
|
||||
save_item(NAME(m_status));
|
||||
save_item(NAME(m_control));
|
||||
save_item(NAME(m_err));
|
||||
save_item(NAME(m_mark));
|
||||
save_item(NAME(m_cycle));
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_num));
|
||||
save_item(NAME(m_mask));
|
||||
save_item(NAME(m_code));
|
||||
save_item(NAME(m_itops));
|
||||
save_item(NAME(m_base));
|
||||
save_item(NAME(m_offset));
|
||||
save_item(NAME(m_tops));
|
||||
save_item(NAME(m_itop));
|
||||
save_item(NAME(m_top));
|
||||
|
||||
save_item(NAME(m_row_fill));
|
||||
save_item(NAME(m_col_fill));
|
||||
|
||||
save_item(NAME(m_data_needed));
|
||||
save_item(NAME(m_data_index));
|
||||
save_item(NAME(m_command));
|
||||
save_item(NAME(m_alignment));
|
||||
|
||||
save_item(NAME(m_mpg_count));
|
||||
save_item(NAME(m_mpg_addr));
|
||||
save_item(NAME(m_mpg_insn));
|
||||
|
||||
save_item(NAME(m_unpack_count));
|
||||
save_item(NAME(m_unpack_addr));
|
||||
save_item(NAME(m_unpack_last));
|
||||
save_item(NAME(m_unpack_bits_remaining));
|
||||
save_item(NAME(m_unpack_signed));
|
||||
save_item(NAME(m_unpack_add_tops));
|
||||
save_item(NAME(m_unpack_format));
|
||||
}
|
||||
|
||||
void ps2_vif1_device::device_reset()
|
||||
{
|
||||
m_icount = 0;
|
||||
|
||||
memset(m_buffer, 0, sizeof(uint32_t) * BUFFER_SIZE);
|
||||
m_curr = 0;
|
||||
m_end = 0;
|
||||
|
||||
m_status = 0;
|
||||
m_control = 0;
|
||||
m_err = 0;
|
||||
m_mark = 0;
|
||||
m_cycle = 0;
|
||||
m_mode = 0;
|
||||
m_num = 0;
|
||||
m_mask = 0;
|
||||
m_code = 0;
|
||||
m_itops = 0;
|
||||
m_base = 0;
|
||||
m_offset = 0;
|
||||
m_tops = 0;
|
||||
m_itop = 0;
|
||||
m_top = 0;
|
||||
|
||||
memset(m_row_fill, 0, sizeof(uint32_t) * 4);
|
||||
memset(m_col_fill, 0, sizeof(uint32_t) * 4);
|
||||
|
||||
m_data_needed = 0;
|
||||
m_data_index = 0;
|
||||
m_command = 0;
|
||||
m_alignment = 0;
|
||||
|
||||
m_mpg_count = 0;
|
||||
m_mpg_addr = 0;
|
||||
m_mpg_insn = 0;
|
||||
|
||||
m_unpack_count = 0;
|
||||
m_unpack_addr = 0;
|
||||
m_unpack_last = 0;
|
||||
m_unpack_bits_remaining = 0;
|
||||
m_unpack_signed = false;
|
||||
m_unpack_add_tops = false;
|
||||
m_unpack_format = FMT_S32;
|
||||
}
|
||||
|
||||
READ32_MEMBER(ps2_vif1_device::regs_r)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/4:
|
||||
ret = m_status;
|
||||
logerror("%s: Read: VIF1_STAT (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x10/4:
|
||||
ret = m_control;
|
||||
logerror("%s: Read: VIF1_FBRST (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x20/4:
|
||||
ret = m_err;
|
||||
logerror("%s: Read: VIF1_ERR (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x30/4:
|
||||
ret = m_mark;
|
||||
logerror("%s: Read: VIF1_MARK (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x40/4:
|
||||
ret = m_cycle;
|
||||
logerror("%s: Read: VIF1_CYCLE (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x50/4:
|
||||
ret = m_mode;
|
||||
logerror("%s: Read: VIF1_MODE (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x60/4:
|
||||
ret = m_num;
|
||||
logerror("%s: Read: VIF1_NUM (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x70/4:
|
||||
ret = m_mask;
|
||||
logerror("%s: Read: VIF1_MASK (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x80/4:
|
||||
ret = m_code;
|
||||
logerror("%s: Read: VIF1_CODE (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x90/4:
|
||||
ret = m_itops;
|
||||
logerror("%s: Read: VIF1_ITOPS (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0xa0/4:
|
||||
ret = m_base;
|
||||
logerror("%s: Read: VIF1_BASE (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0xb0/4:
|
||||
ret = m_offset;
|
||||
logerror("%s: Read: VIF1_OFST (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0xc0/4:
|
||||
ret = m_tops;
|
||||
logerror("%s: Read: VIF1_TOPS (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0xd0/4:
|
||||
ret = m_itop;
|
||||
logerror("%s: Read: VIF1_ITOP (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0xe0/4:
|
||||
ret = m_top;
|
||||
logerror("%s: Read: VIF1_TOP (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x100/4:
|
||||
ret = m_row_fill[0];
|
||||
logerror("%s: Read: VIF1_R0 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x110/4:
|
||||
ret = m_row_fill[1];
|
||||
logerror("%s: Read: VIF1_R1 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x120/4:
|
||||
ret = m_row_fill[2];
|
||||
logerror("%s: Read: VIF1_R2 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x130/4:
|
||||
ret = m_row_fill[3];
|
||||
logerror("%s: Read: VIF1_R3 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x140/4:
|
||||
ret = m_col_fill[0];
|
||||
logerror("%s: Read: VIF1_C0 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x150/4:
|
||||
ret = m_col_fill[1];
|
||||
logerror("%s: Read: VIF1_C1 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x160/4:
|
||||
ret = m_col_fill[2];
|
||||
logerror("%s: Read: VIF1_C2 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
case 0x170/4:
|
||||
ret = m_col_fill[3];
|
||||
logerror("%s: Read: VIF1_C3 (%08x)\n", machine().describe_context(), ret);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: Read: Unknown (%08x)\n", machine().describe_context(), 0x10003c00 + (offset << 2));
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(ps2_vif1_device::regs_w)
|
||||
{
|
||||
logerror("%s: Write: Unknown %08x = %08x\n", machine().describe_context(), 0x10003c00 + (offset << 2), data);
|
||||
}
|
||||
|
||||
READ64_MEMBER(ps2_vif1_device::mmio_r)
|
||||
{
|
||||
uint64_t ret = 0ULL;
|
||||
if (offset)
|
||||
{
|
||||
logerror("%s: mmio_r [127..64]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%s: mmio_r [63..0]: (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(ps2_vif1_device::mmio_w)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
logerror("%s: mmio_w [127..64]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
fifo_push((uint32_t)data);
|
||||
fifo_push((uint32_t)(data >> 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%s: mmio_w [63..0]: %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
fifo_push((uint32_t)data);
|
||||
fifo_push((uint32_t)(data >> 32));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ps2_vif1_device::dma_write(const uint64_t hi, const uint64_t lo)
|
||||
{
|
||||
logerror("%s: dma_write: %08x%08x%08x%08x\n", machine().describe_context(), (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo);
|
||||
fifo_push((uint32_t)(hi >> 32));
|
||||
fifo_push((uint32_t)hi);
|
||||
fifo_push((uint32_t)(lo >> 32));
|
||||
fifo_push((uint32_t)lo);
|
||||
}
|
||||
|
||||
void ps2_vif1_device::tag_write(uint32_t *data)
|
||||
{
|
||||
logerror("%s: tag_write: %08x%08x\n", machine().describe_context(), data[2], data[3]);
|
||||
fifo_push(data[2]);
|
||||
fifo_push(data[3]);
|
||||
}
|
||||
|
||||
void ps2_vif1_device::fifo_push(uint32_t value)
|
||||
{
|
||||
if (m_end >= BUFFER_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_buffer[m_end++] = value;
|
||||
}
|
||||
|
||||
uint32_t ps2_vif1_device::fifo_pop()
|
||||
{
|
||||
m_alignment = (m_alignment + 1) & 3;
|
||||
|
||||
if (m_curr >= m_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint32_t ret = m_buffer[m_curr++];
|
||||
if (m_curr >= m_end)
|
||||
{
|
||||
m_curr = 0;
|
||||
m_end = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ps2_vif1_device::execute_run()
|
||||
{
|
||||
while (m_icount > 0)
|
||||
{
|
||||
if (m_status & (STAT_E_WAIT | STAT_GS_WAIT | STAT_STALL_STOP | STAT_STALL_FBRK | STAT_STALL_INT))
|
||||
{
|
||||
m_icount = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (m_status & STAT_MODE_MASK)
|
||||
{
|
||||
case STAT_MODE_IDLE:
|
||||
if (fifo_depth())
|
||||
{
|
||||
m_code = fifo_pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_icount = 0;
|
||||
break;
|
||||
}
|
||||
// Intentional fall-through
|
||||
case STAT_MODE_DECODE:
|
||||
decode_vifcode();
|
||||
break;
|
||||
case STAT_MODE_WAIT:
|
||||
if (fifo_depth() == 0)
|
||||
{
|
||||
m_icount = 0;
|
||||
break;
|
||||
}
|
||||
// Intentional fall-through
|
||||
case STAT_MODE_DATA:
|
||||
transfer_vifcode_data();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_vif1_device::transfer_vifcode_data()
|
||||
{
|
||||
m_status &= ~STAT_MODE_MASK;
|
||||
if (fifo_depth() < m_data_needed)
|
||||
{
|
||||
m_status |= STAT_MODE_WAIT;
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_command)
|
||||
{
|
||||
case 0x20: /* STMASK */
|
||||
m_mask = fifo_pop();
|
||||
m_data_needed = 0;
|
||||
break;
|
||||
case 0x30: /* STROW */
|
||||
m_row_fill[m_data_index] = fifo_pop();
|
||||
m_data_needed = 0;
|
||||
break;
|
||||
case 0x31: /* STCOL */
|
||||
m_col_fill[m_data_index] = fifo_pop();
|
||||
m_data_needed = 0;
|
||||
break;
|
||||
case 0x4a: /* MPG */
|
||||
transfer_mpg();
|
||||
break;
|
||||
default:
|
||||
if ((m_command & 0x60) == 0x60)
|
||||
{
|
||||
transfer_unpack();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_data_needed)
|
||||
{
|
||||
if (fifo_depth() == 0)
|
||||
{
|
||||
m_status |= STAT_MODE_WAIT;
|
||||
m_icount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status |= STAT_MODE_DATA;
|
||||
m_icount--;
|
||||
}
|
||||
}
|
||||
else if (fifo_depth() > 0)
|
||||
{
|
||||
m_code = fifo_pop();
|
||||
m_status |= STAT_MODE_DECODE;
|
||||
m_icount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status |= STAT_MODE_IDLE;
|
||||
m_icount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_vif1_device::transfer_unpack()
|
||||
{
|
||||
switch (m_unpack_format)
|
||||
{
|
||||
case FMT_V4_32:
|
||||
logerror("%s: Unpacking V4-32.\n", machine().describe_context());
|
||||
for (int element = 0; element < 4; element++)
|
||||
{
|
||||
fifo_pop();
|
||||
//const uint32_t data = fifo_pop();
|
||||
//m_vu->write_data(m_unpack_addr, data);
|
||||
m_unpack_addr += 4;
|
||||
}
|
||||
m_unpack_count--;
|
||||
break;
|
||||
default:
|
||||
logerror("%s: Unsupported unpack format: %02x\n", machine().describe_context(), m_unpack_format);
|
||||
break;
|
||||
}
|
||||
|
||||
m_data_needed = FORMAT_SIZE[m_unpack_format] - (m_unpack_bits_remaining ? 1 : 0);
|
||||
}
|
||||
|
||||
void ps2_vif1_device::transfer_mpg()
|
||||
{
|
||||
while (m_data_needed > 2)
|
||||
{
|
||||
fifo_pop();
|
||||
m_data_needed--;
|
||||
}
|
||||
|
||||
m_mpg_insn = fifo_pop();
|
||||
m_mpg_insn |= (uint64_t)fifo_pop() << 32;
|
||||
m_mpg_addr += 8;
|
||||
m_mpg_count--;
|
||||
m_data_needed = m_mpg_count ? 2 : 0;
|
||||
|
||||
logerror("%s: MPG, VU insn: %08x%08x, %d remaining\n", machine().describe_context(), (uint32_t)(m_mpg_insn >> 32), (uint32_t)m_mpg_insn, m_mpg_count);
|
||||
|
||||
//m_vu->write_instruction(m_mpg_addr, m_mpg_insn);
|
||||
}
|
||||
|
||||
void ps2_vif1_device::decode_vifcode()
|
||||
{
|
||||
//bool trigger_interrupt = BIT(m_code, 31);
|
||||
m_command = (m_code >> 24) & 0x7f;
|
||||
m_status &= ~STAT_MODE_MASK;
|
||||
|
||||
switch (m_command)
|
||||
{
|
||||
case 0x00: /* NOP */
|
||||
break;
|
||||
case 0x01: /* STCYCL */
|
||||
m_cycle = (uint16_t)m_code;
|
||||
logerror("%s: STCYCL: %04x\n", machine().describe_context(), (uint16_t)m_cycle);
|
||||
break;
|
||||
case 0x02: /* OFFSET */
|
||||
m_offset = m_code & 0x3ff;
|
||||
logerror("%s: OFFSET: %03x\n", machine().describe_context(), m_offset);
|
||||
break;
|
||||
case 0x03: /* BASE */
|
||||
m_base = m_code & 0x3ff;
|
||||
logerror("%s: BASE: %03x\n", machine().describe_context(), m_base);
|
||||
break;
|
||||
case 0x04: /* ITOP */
|
||||
m_itops = m_code & 0x3ff;
|
||||
logerror("%s: ITOP: %03x\n", machine().describe_context(), m_itops);
|
||||
break;
|
||||
case 0x05: /* STMOD */
|
||||
m_mode = m_code & 3;
|
||||
logerror("%s: MODE: %03x\n", machine().describe_context(), m_mode);
|
||||
break;
|
||||
case 0x06: /* MSKPATH3 */
|
||||
m_gif->set_path3_mask(BIT(m_code, 15));
|
||||
logerror("%s: MSKPATH3: %d\n", machine().describe_context(), BIT(m_code, 15));
|
||||
break;
|
||||
case 0x07: /* Oh hi, MARK */
|
||||
m_mark = (uint16_t)m_code;
|
||||
logerror("%s: MARK: %04x\n", machine().describe_context(), (uint16_t)m_mark);
|
||||
break;
|
||||
case 0x20: /* STMASK */
|
||||
m_data_needed = 1;
|
||||
m_data_index = 0;
|
||||
logerror("%s: STMASK\n", machine().describe_context());
|
||||
break;
|
||||
case 0x30: /* STROW */
|
||||
m_data_needed = 4;
|
||||
m_data_index = 0;
|
||||
logerror("%s: STROW\n", machine().describe_context());
|
||||
break;
|
||||
case 0x31: /* STCOL */
|
||||
m_data_needed = 4;
|
||||
m_data_index = 0;
|
||||
logerror("%s: STCOL\n", machine().describe_context());
|
||||
break;
|
||||
case 0x4a: /* MPG */
|
||||
m_data_needed = 2 + (m_alignment & 1);
|
||||
m_data_index = 0;
|
||||
m_mpg_count = (m_code >> 16) & 0xff;
|
||||
if (!m_mpg_count)
|
||||
m_mpg_count = 0x100;
|
||||
m_mpg_addr = m_code & 0xffff;
|
||||
logerror("%s: MPG\n", machine().describe_context());
|
||||
break;
|
||||
default:
|
||||
if ((m_command & 0x60) == 0x60)
|
||||
{ /* UNPACK */
|
||||
m_unpack_count = calculate_unpack_count();
|
||||
m_unpack_signed = BIT(m_code, 14);
|
||||
m_unpack_add_tops = BIT(m_code, 15);
|
||||
m_unpack_format = (uint8_t)(m_command & 0xf);
|
||||
m_data_needed = FORMAT_SIZE[m_unpack_format];
|
||||
}
|
||||
else
|
||||
{ /* unknown */
|
||||
logerror("%s: decode_vifcode: Unknown command %02x\n", machine().describe_context(), m_command);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_data_needed > 0)
|
||||
{
|
||||
if (fifo_depth())
|
||||
{
|
||||
m_status |= STAT_MODE_DATA;
|
||||
m_icount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status |= STAT_MODE_WAIT;
|
||||
m_icount = 0;
|
||||
}
|
||||
}
|
||||
else if (fifo_depth())
|
||||
{
|
||||
m_code = fifo_pop();
|
||||
m_status |= STAT_MODE_DECODE;
|
||||
m_icount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status |= STAT_MODE_IDLE;
|
||||
m_icount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ps2_vif1_device::calculate_unpack_count()
|
||||
{
|
||||
const uint32_t wl = (m_cycle >> 8) & 0xff;
|
||||
const uint32_t cl = m_cycle & 0xff;
|
||||
const uint32_t vl = m_command & 3;
|
||||
const uint32_t vn = (m_command >> 2) & 3;
|
||||
|
||||
uint32_t num = (m_code >> 16) & 0xff;
|
||||
if (wl > cl)
|
||||
{
|
||||
const uint32_t mod = num % wl;
|
||||
num = cl * (num / wl) + ((mod > cl) ? cl : mod);
|
||||
}
|
||||
|
||||
return (uint32_t)std::ceil(((32 >> vl) * (vn + 1) * num) / 32.0f);
|
||||
}
|
155
src/mame/machine/ps2vif1.h
Normal file
155
src/mame/machine/ps2vif1.h
Normal file
@ -0,0 +1,155 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 VU1 interface (VIF1) device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAME_MACHINE_PS2VIF1_H
|
||||
#define MAME_MACHINE_PS2VIF1_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "emu.h"
|
||||
#include "ps2gif.h"
|
||||
|
||||
class ps2_vif1_device : public device_t, public device_execute_interface
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
ps2_vif1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&gif_tag)
|
||||
: ps2_vif1_device(mconfig, tag, owner, clock)
|
||||
{
|
||||
m_gif.set_tag(std::forward<T>(gif_tag));
|
||||
}
|
||||
|
||||
ps2_vif1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_READ64_MEMBER(mmio_r);
|
||||
DECLARE_WRITE64_MEMBER(mmio_w);
|
||||
|
||||
DECLARE_READ32_MEMBER(regs_r);
|
||||
DECLARE_WRITE32_MEMBER(regs_w);
|
||||
|
||||
void dma_write(const uint64_t hi, const uint64_t lo);
|
||||
void tag_write(uint32_t *data);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void execute_run() override;
|
||||
|
||||
uint32_t calculate_unpack_count();
|
||||
|
||||
void decode_vifcode();
|
||||
|
||||
void transfer_vifcode_data();
|
||||
void transfer_mpg();
|
||||
void transfer_unpack();
|
||||
|
||||
void fifo_push(uint32_t value);
|
||||
uint32_t fifo_pop();
|
||||
uint32_t fifo_depth() const { return m_end - m_curr; }
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
STAT_MODE_MASK = (3 << 0),
|
||||
STAT_MODE_IDLE = 0,
|
||||
STAT_MODE_WAIT = 1,
|
||||
STAT_MODE_DECODE = 2,
|
||||
STAT_MODE_DATA = 3,
|
||||
|
||||
STAT_E_WAIT = (1 << 2),
|
||||
STAT_GS_WAIT = (1 << 3),
|
||||
STAT_MARK = (1 << 6),
|
||||
STAT_DBUF = (1 << 7),
|
||||
STAT_STALL_STOP = (1 << 8),
|
||||
STAT_STALL_FBRK = (1 << 9),
|
||||
STAT_STALL_INT = (1 << 10),
|
||||
STAT_INT = (1 << 11),
|
||||
STAT_BAD_TAG = (1 << 12),
|
||||
STAT_BAD_CODE = (1 << 13),
|
||||
STAT_FDR_TO_HOST = (1 << 23)
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
CMD_INT = 0x80,
|
||||
CMD_UNPACK_MASK = 0x10
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
FMT_S32 = 0x00,
|
||||
FMT_S16 = 0x01,
|
||||
FMT_S8 = 0x02,
|
||||
//FMT_UNK0 = 0x03,
|
||||
FMT_V2_32 = 0x04,
|
||||
FMT_V2_16 = 0x05,
|
||||
FMT_V2_8 = 0x06,
|
||||
//FMT_UNK1 = 0x07,
|
||||
FMT_V3_32 = 0x08,
|
||||
FMT_V3_16 = 0x09,
|
||||
FMT_V3_8 = 0x0a,
|
||||
//FMT_UNK2 = 0x0b,
|
||||
FMT_V4_32 = 0x0c,
|
||||
FMT_V4_16 = 0x0d,
|
||||
FMT_V4_8 = 0x0e,
|
||||
FMT_V4_5 = 0x0f,
|
||||
};
|
||||
|
||||
required_device<ps2_gif_device> m_gif;
|
||||
|
||||
int m_icount;
|
||||
|
||||
uint32_t m_buffer[0x40];
|
||||
uint32_t m_curr;
|
||||
uint32_t m_end;
|
||||
|
||||
uint32_t m_status;
|
||||
uint32_t m_control;
|
||||
uint32_t m_err;
|
||||
uint32_t m_mark;
|
||||
uint32_t m_cycle;
|
||||
uint32_t m_mode;
|
||||
uint32_t m_num;
|
||||
uint32_t m_mask;
|
||||
uint32_t m_code;
|
||||
uint32_t m_itops;
|
||||
uint32_t m_base;
|
||||
uint32_t m_offset;
|
||||
uint32_t m_tops;
|
||||
uint32_t m_itop;
|
||||
uint32_t m_top;
|
||||
|
||||
uint32_t m_row_fill[4];
|
||||
uint32_t m_col_fill[4];
|
||||
|
||||
uint32_t m_data_needed;
|
||||
uint32_t m_data_index;
|
||||
uint8_t m_command;
|
||||
uint8_t m_alignment;
|
||||
|
||||
uint32_t m_mpg_count;
|
||||
uint32_t m_mpg_addr;
|
||||
uint64_t m_mpg_insn;
|
||||
|
||||
uint32_t m_unpack_count;
|
||||
uint32_t m_unpack_addr;
|
||||
uint32_t m_unpack_last;
|
||||
uint32_t m_unpack_bits_remaining;
|
||||
bool m_unpack_signed;
|
||||
bool m_unpack_add_tops;
|
||||
uint8_t m_unpack_format;
|
||||
|
||||
static const size_t BUFFER_SIZE;
|
||||
static const uint32_t FORMAT_SIZE[0x10];
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SONYPS2_VIF1, ps2_vif1_device)
|
||||
|
||||
#endif // MAME_MACHINE_PS2VIF1_H
|
730
src/mame/video/ps2gs.cpp
Normal file
730
src/mame/video/ps2gs.cpp
Normal file
@ -0,0 +1,730 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 Graphics Synthesizer device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ps2gs.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SONYPS2_GS, ps2_gs_device, "ps2gs", "Playstation 2 GS")
|
||||
|
||||
/*static*/ const size_t ps2_gs_device::FORMAT_PIXEL_WIDTHS[] = {
|
||||
32, 24, 16, 0, 0, 0, 0, 0,
|
||||
0, 0, 16, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 8, 4, 0, 0, 0,
|
||||
0, 0, 0, 8, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 4, 0, 0, 0,
|
||||
0, 0, 0, 0, 4, 0, 0, 0,
|
||||
32, 24, 16, 0, 0, 0, 0, 0,
|
||||
0, 0, 16, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*static*/ const char* ps2_gs_device::FORMAT_NAMES[] = {
|
||||
"PSMCT32", "PSMCT24", "PSMCT16", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
|
||||
"Unknown", "Unknown", "PCMCT16S", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
|
||||
"Unknown", "Unknown", "Unknown", "PSMT8", "PSMT4", "Unknown", "Unknown", "Unknown",
|
||||
"Unknown", "Unknown", "Unknown", "PSMT8H", "Unknown", "Unknown", "Unknown", "Unknown",
|
||||
"Unknown", "Unknown", "Unknown", "Unknown", "PSMT4HL", "Unknown", "Unknown", "Unknown",
|
||||
"Unknown", "Unknown", "Unknown", "Unknown", "PSMT4HH", "Unknown", "Unknown", "Unknown",
|
||||
"PSMZ32", "PSMZ24", "PSMZ16", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
|
||||
"Unknown", "Unknown", "PSMZ16S", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown"
|
||||
};
|
||||
|
||||
/*static*/ const uint32_t ps2_gs_device::KICK_COUNTS[] = {
|
||||
1, 2, 2, 3, 3, 3, 2, 1
|
||||
};
|
||||
|
||||
ps2_gs_device::ps2_gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SONYPS2_GS, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void ps2_gs_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_bitbltbuf));
|
||||
save_item(NAME(m_src_buf_base));
|
||||
save_item(NAME(m_src_buf_width));
|
||||
save_item(NAME(m_src_buf_fmt));
|
||||
save_item(NAME(m_dst_buf_base));
|
||||
save_item(NAME(m_dst_buf_width));
|
||||
save_item(NAME(m_dst_buf_fmt));
|
||||
|
||||
save_item(NAME(m_trx_pos));
|
||||
save_item(NAME(m_src_ul_x));
|
||||
save_item(NAME(m_src_ul_y));
|
||||
save_item(NAME(m_dst_ul_x));
|
||||
save_item(NAME(m_dst_ul_y));
|
||||
save_item(NAME(m_copy_dir));
|
||||
|
||||
save_item(NAME(m_trx_reg));
|
||||
save_item(NAME(m_trx_width));
|
||||
save_item(NAME(m_trx_height));
|
||||
|
||||
save_item(NAME(m_trx_dir));
|
||||
|
||||
save_item(NAME(m_base_regs));
|
||||
|
||||
save_item(NAME(m_pmode));
|
||||
save_item(NAME(m_read_circuit_enable));
|
||||
save_item(NAME(m_use_fixed_alpha));
|
||||
save_item(NAME(m_alpha_out_select));
|
||||
save_item(NAME(m_blend_to_background));
|
||||
save_item(NAME(m_fixed_alpha));
|
||||
|
||||
save_item(NAME(m_smode2));
|
||||
save_item(NAME(m_interlace));
|
||||
save_item(NAME(m_frame_interlace));
|
||||
save_item(NAME(m_dpms_mode));
|
||||
|
||||
save_item(NAME(m_dispfb));
|
||||
save_item(NAME(m_dispfb_base));
|
||||
save_item(NAME(m_dispfb_width));
|
||||
save_item(NAME(m_dispfb_format));
|
||||
save_item(NAME(m_dispfb_x));
|
||||
save_item(NAME(m_dispfb_y));
|
||||
|
||||
save_item(NAME(m_display));
|
||||
save_item(NAME(m_display_xpos));
|
||||
save_item(NAME(m_display_ypos));
|
||||
save_item(NAME(m_magh));
|
||||
save_item(NAME(m_magv));
|
||||
save_item(NAME(m_display_width));
|
||||
save_item(NAME(m_display_height));
|
||||
|
||||
save_item(NAME(m_bgcolor));
|
||||
save_item(NAME(m_bg_r));
|
||||
save_item(NAME(m_bg_g));
|
||||
save_item(NAME(m_bg_b));
|
||||
|
||||
save_item(NAME(m_csr));
|
||||
save_item(NAME(m_imr));
|
||||
save_item(NAME(m_busdir));
|
||||
save_item(NAME(m_sig_label_id));
|
||||
|
||||
save_item(NAME(m_vertex_count));
|
||||
save_item(NAME(m_kick_count));
|
||||
|
||||
save_item(NAME(m_context[0].m_xyoffset));
|
||||
save_item(NAME(m_context[0].m_offset_x));
|
||||
save_item(NAME(m_context[0].m_offset_y));
|
||||
|
||||
save_item(NAME(m_context[0].m_scissor));
|
||||
save_item(NAME(m_context[0].m_scissor_x0));
|
||||
save_item(NAME(m_context[0].m_scissor_x1));
|
||||
save_item(NAME(m_context[0].m_scissor_y0));
|
||||
save_item(NAME(m_context[0].m_scissor_y1));
|
||||
|
||||
save_item(NAME(m_context[0].m_test));
|
||||
save_item(NAME(m_context[0].m_alpha_test));
|
||||
save_item(NAME(m_context[0].m_alpha_func));
|
||||
save_item(NAME(m_context[0].m_alpha_ref));
|
||||
save_item(NAME(m_context[0].m_alpha_fail));
|
||||
save_item(NAME(m_context[0].m_dstalpha_test));
|
||||
save_item(NAME(m_context[0].m_dstalpha_pass1));
|
||||
save_item(NAME(m_context[0].m_depth_test));
|
||||
save_item(NAME(m_context[0].m_depth_func));
|
||||
|
||||
save_item(NAME(m_context[0].m_frame));
|
||||
save_item(NAME(m_context[0].m_fb_base));
|
||||
save_item(NAME(m_context[0].m_fb_format));
|
||||
save_item(NAME(m_context[0].m_fb_width));
|
||||
save_item(NAME(m_context[0].m_fb_mask));
|
||||
|
||||
save_item(NAME(m_context[0].m_zbuf));
|
||||
save_item(NAME(m_context[0].m_z_base));
|
||||
save_item(NAME(m_context[0].m_z_format));
|
||||
save_item(NAME(m_context[0].m_z_mask));
|
||||
|
||||
save_item(NAME(m_context[1].m_xyoffset));
|
||||
save_item(NAME(m_context[1].m_offset_x));
|
||||
save_item(NAME(m_context[1].m_offset_y));
|
||||
|
||||
save_item(NAME(m_context[1].m_scissor));
|
||||
save_item(NAME(m_context[1].m_scissor_x0));
|
||||
save_item(NAME(m_context[1].m_scissor_x1));
|
||||
save_item(NAME(m_context[1].m_scissor_y0));
|
||||
save_item(NAME(m_context[1].m_scissor_y1));
|
||||
|
||||
save_item(NAME(m_context[1].m_test));
|
||||
save_item(NAME(m_context[1].m_alpha_test));
|
||||
save_item(NAME(m_context[1].m_alpha_func));
|
||||
save_item(NAME(m_context[1].m_alpha_ref));
|
||||
save_item(NAME(m_context[1].m_alpha_fail));
|
||||
save_item(NAME(m_context[1].m_dstalpha_test));
|
||||
save_item(NAME(m_context[1].m_dstalpha_pass1));
|
||||
save_item(NAME(m_context[1].m_depth_test));
|
||||
save_item(NAME(m_context[1].m_depth_func));
|
||||
|
||||
save_item(NAME(m_context[1].m_frame));
|
||||
save_item(NAME(m_context[1].m_fb_base));
|
||||
save_item(NAME(m_context[1].m_fb_format));
|
||||
save_item(NAME(m_context[1].m_fb_width));
|
||||
save_item(NAME(m_context[1].m_fb_mask));
|
||||
|
||||
save_item(NAME(m_context[1].m_zbuf));
|
||||
save_item(NAME(m_context[1].m_z_base));
|
||||
save_item(NAME(m_context[1].m_z_format));
|
||||
save_item(NAME(m_context[1].m_z_mask));
|
||||
|
||||
m_ram = std::make_unique<uint32_t[]>(0x400000/4);
|
||||
m_vertices = std::make_unique<vertex_t[]>(0x10000); // Arbitrary count
|
||||
}
|
||||
|
||||
void ps2_gs_device::device_reset()
|
||||
{
|
||||
m_bitbltbuf = 0;
|
||||
m_src_buf_base = 0;
|
||||
m_src_buf_width = 0;
|
||||
m_src_buf_fmt = PSMCT32;
|
||||
m_dst_buf_base = 0;
|
||||
m_dst_buf_width = 0;
|
||||
m_dst_buf_fmt = PSMCT32;
|
||||
|
||||
m_trx_pos = 0;
|
||||
m_src_ul_x = 0;
|
||||
m_src_ul_y = 0;
|
||||
m_dst_ul_x = 0;
|
||||
m_dst_ul_y = 0;
|
||||
m_copy_dir = 0;
|
||||
|
||||
m_trx_reg = 0;
|
||||
m_trx_width = 0;
|
||||
m_trx_height = 0;
|
||||
|
||||
m_trx_dir = 0;
|
||||
|
||||
memset(m_base_regs, 0, sizeof(uint64_t) * 15);
|
||||
|
||||
m_pmode = 0;
|
||||
memset(m_read_circuit_enable, 0, 2);
|
||||
m_use_fixed_alpha = 0;
|
||||
m_alpha_out_select = 0;
|
||||
m_blend_to_background = 0;
|
||||
m_fixed_alpha = 0;
|
||||
|
||||
m_smode2 = 0;
|
||||
m_interlace = 0;
|
||||
m_frame_interlace = 0;
|
||||
m_dpms_mode = 0;
|
||||
|
||||
memset(m_dispfb, 0, sizeof(uint64_t) * 2);
|
||||
memset(m_dispfb_base, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_dispfb_width, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_dispfb_format, 0, sizeof(uint8_t) * 2);
|
||||
memset(m_dispfb_x, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_dispfb_y, 0, sizeof(uint32_t) * 2);
|
||||
|
||||
memset(m_display, 0, sizeof(uint64_t) * 2);
|
||||
memset(m_display_xpos, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_display_ypos, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_magh, 0, sizeof(uint8_t) * 2);
|
||||
memset(m_magv, 0, sizeof(uint8_t) * 2);
|
||||
memset(m_display_width, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_display_height, 0, sizeof(uint32_t) * 2);
|
||||
|
||||
m_bgcolor = 0;
|
||||
m_bg_r = 0;
|
||||
m_bg_g = 0;
|
||||
m_bg_b = 0;
|
||||
|
||||
m_csr = 0;
|
||||
m_imr = 0;
|
||||
m_busdir = 0;
|
||||
m_sig_label_id = 0;
|
||||
|
||||
memset(m_context, 0, sizeof(context_t) * 2);
|
||||
m_vertex_count = 0;
|
||||
m_kick_count = 0;
|
||||
}
|
||||
|
||||
READ64_MEMBER(ps2_gs_device::priv_regs0_r)
|
||||
{
|
||||
uint64_t ret = m_base_regs[offset >> 1];
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
ret = m_pmode;
|
||||
logerror("%s: regs0_r: PMODE (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
ret = m_smode2;
|
||||
logerror("%s: regs0_r: SMODE2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
case 0x12:
|
||||
ret = m_dispfb[(offset - 0x0e) / 4];
|
||||
logerror("%s: regs0_r: DISPFB2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
case 0x14:
|
||||
ret = m_display[(offset - 0x10) / 4];
|
||||
logerror("%s: regs0_r: DISPLAY2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
|
||||
case 0x1c:
|
||||
ret = m_bgcolor;
|
||||
logerror("%s: regs0_r: BGCOLOR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
|
||||
case 0x02: logerror("%s: regs0_r: SMODE1 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x06: logerror("%s: regs0_r: SRFSH (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x08: logerror("%s: regs0_r: SYNCH1 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x0a: logerror("%s: regs0_r: SYNCH2 (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x0c: logerror("%s: regs0_r: SYNCV (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x16: logerror("%s: regs0_r: EXTBUF (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x18: logerror("%s: regs0_r: EXTDATA (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
case 0x1a: logerror("%s: regs0_r: EXTWRITE (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret); break;
|
||||
default: logerror("%s: regs0_r: Unknown (%08x)\n", machine().describe_context(), 0x12000000 + (offset << 3)); break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(ps2_gs_device::priv_regs0_w)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: // PMODE
|
||||
m_pmode = data;
|
||||
m_read_circuit_enable[0] = BIT(data, 0);
|
||||
m_read_circuit_enable[1] = BIT(data, 1);
|
||||
m_use_fixed_alpha = BIT(data, 5);
|
||||
m_alpha_out_select = BIT(data, 6);
|
||||
m_blend_to_background = BIT(data, 7);
|
||||
m_fixed_alpha = (data >> 8) & 0xff;
|
||||
logerror("%s: regs0_w: PMODE = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
|
||||
case 0x04: // SMODE2
|
||||
m_smode2 = data;
|
||||
m_interlace = BIT(data, 0);
|
||||
m_frame_interlace = BIT(data, 1);
|
||||
m_dpms_mode = (data >> 2) & 3;
|
||||
logerror("%s: regs0_w: SMODE2 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
|
||||
case 0x0e: // DISPFB1
|
||||
case 0x12: // DISPFB2
|
||||
{
|
||||
const uint8_t index = (offset - 0x0e) / 4;
|
||||
m_dispfb[index] = data;
|
||||
m_dispfb_base[index] = (data & 0x1ff) << 11;
|
||||
m_dispfb_width[index] = (data & 0x7e00) >> 3;
|
||||
m_dispfb_format[index] = (data >> 15) & 0x1f;
|
||||
m_dispfb_x[index] = (data >> 32) & 0x7ff;
|
||||
m_dispfb_y[index] = (data >> 42) & 0x7ff;
|
||||
logerror("%s: regs0_w: DISPFB%d = %08x%08x\n", machine().describe_context(), index + 1, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10: // DISPLAY1
|
||||
case 0x14: // DISPLAY2
|
||||
{
|
||||
const uint8_t index = (offset - 0x10) / 4;
|
||||
m_display[index] = data;
|
||||
m_display_xpos[index] = data & 0xfff;
|
||||
m_display_ypos[index] = (data >> 12) & 0x7ff;
|
||||
m_magh[index] = (data >> 23) & 0xf;
|
||||
m_magv[index] = (data >> 27) & 3;
|
||||
m_display_width[index] = (data >> 32) & 0xfff;
|
||||
m_display_height[index] = (data >> 44) & 0x7ff;
|
||||
logerror("%s: regs0_w: DISPLAY%d = %08x%08x\n", machine().describe_context(), index + 1, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x1c: // BGCOLOR
|
||||
m_bgcolor = data;
|
||||
m_bg_r = data & 0xff;
|
||||
m_bg_g = (data >> 8) & 0xff;
|
||||
m_bg_b = (data >> 16) & 0xff;
|
||||
logerror("%s: regs0_w: BGCOLOR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
|
||||
case 0x02: logerror("%s: regs0_w: SMODE1 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x06: logerror("%s: regs0_w: SRFSH = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x08: logerror("%s: regs0_w: SYNCH1 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x0a: logerror("%s: regs0_w: SYNCH2 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x0c: logerror("%s: regs0_w: SYNCV = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x16: logerror("%s: regs0_w: EXTBUF = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x18: logerror("%s: regs0_w: EXTDATA = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
case 0x1a: logerror("%s: regs0_w: EXTWRITE = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
default: logerror("%s: regs0_w: Unknown %08x = %08x%08x\n", machine().describe_context(), 0x12000000 + (offset << 3), (uint32_t)(data >> 32), (uint32_t)data); break;
|
||||
}
|
||||
m_base_regs[offset >> 1] = data;
|
||||
}
|
||||
|
||||
READ64_MEMBER(ps2_gs_device::priv_regs1_r)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
ret = m_csr;
|
||||
logerror("%s: regs1_r: CSR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = m_imr;
|
||||
logerror("%s: regs1_r: IMR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
case 0x08:
|
||||
ret = m_busdir;
|
||||
logerror("%s: regs1_r: BUSDIR (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
case 0x10:
|
||||
ret = m_sig_label_id;
|
||||
logerror("%s: regs1_r: SIGLBLID (%08x%08x)\n", machine().describe_context(), (uint32_t)(ret >> 32), (uint32_t)ret);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: regs1_r: Unknown (%08x)\n", machine().describe_context(), 0x12000000 + (offset << 3));
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(ps2_gs_device::priv_regs1_w)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
logerror("%s: regs1_w: CSR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
m_csr = data &~ CSR_RESET;
|
||||
break;
|
||||
case 0x02:
|
||||
logerror("%s: regs1_w: IMR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
m_imr = data;
|
||||
break;
|
||||
case 0x08:
|
||||
logerror("%s: regs1_w: BUSDIR = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
m_busdir = data;
|
||||
break;
|
||||
case 0x10:
|
||||
logerror("%s: regs1_w: SIGLBLID = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
m_sig_label_id = data;
|
||||
break;
|
||||
default:
|
||||
logerror("%s: regs1_w: Unknown %08x = %08x%08x\n", machine().describe_context(), 0x12000000 + (offset << 3), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_gs_device::write_packed(const uint8_t reg, const uint64_t hi, const uint64_t lo)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x0e:
|
||||
regs_w(machine().dummy_space(), (uint32_t)hi, lo, ~0ULL);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: write_packed: Unknown register %02x = %08x%08x%08x%08x\n", machine().describe_context(), reg, (uint32_t)(hi >> 32), (uint32_t)hi, (uint32_t)(lo >> 32), (uint32_t)lo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(ps2_gs_device::regs_w)
|
||||
{
|
||||
static const char* dir_strs[4] = {
|
||||
"Host->Local", "Local->Host", "Local->Local", "None"
|
||||
};
|
||||
static const char* prim_strs[8] = {
|
||||
"Point", "Line", "Line Strip", "Tri", "Tri Strip", "Tri Fan", "Sprite", "Invalid"
|
||||
};
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: // PRIM
|
||||
m_prim = data;
|
||||
m_prim_type = data & 7;
|
||||
m_gouraud_enable = BIT(data, 3);
|
||||
m_texture_enable = BIT(data, 4);
|
||||
m_fog_enable = BIT(data, 5);
|
||||
m_blend_enable = BIT(data, 6);
|
||||
m_aa_enable = BIT(data, 7);
|
||||
m_no_perspective = BIT(data, 8);
|
||||
m_curr_context = (data >> 9) & 1;
|
||||
m_fix_fragments = BIT(data, 10);
|
||||
m_kick_count = KICK_COUNTS[m_prim_type];
|
||||
logerror("%s: regs_w: PRIM = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s TYPE=%s GOUR=%d TEX=%d FOG=%d BLEND=%d\n", machine().describe_context(), prim_strs[m_prim_type], BIT(data, 3), BIT(data, 4), BIT(data, 5), BIT(data, 6));
|
||||
logerror("%s AA=%d NOPERSP=%d CONTEXT=%d FIXFRAG=%d\n", machine().describe_context(), BIT(data, 7), BIT(data, 8), BIT(data, 9), BIT(data, 10));
|
||||
break;
|
||||
|
||||
case 0x01: // RGBAQ
|
||||
{
|
||||
m_rgbaq = data;
|
||||
m_vc_r = data & 0xff;
|
||||
m_vc_g = (data >> 8) & 0xff;
|
||||
m_vc_b = (data >> 16) & 0xff;
|
||||
m_vc_a = (data >> 24) & 0xff;
|
||||
uint32_t q = (uint32_t)(data >> 32);
|
||||
m_q = *reinterpret_cast<float*>(&q);
|
||||
logerror("%s: regs_w: RGBAQ = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s R=%02x G=%02x B=%02x A=%02x Q=%f\n", machine().describe_context(), m_vc_r, m_vc_g, m_vc_b, m_vc_a, m_q);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x05: // XYZ2
|
||||
{
|
||||
uint16_t x = (uint16_t)data;
|
||||
uint16_t y = (uint16_t)(data >> 16);
|
||||
uint32_t z = (uint32_t)(data >> 32);
|
||||
|
||||
m_vertices[m_vertex_count] = {
|
||||
x, y, z,
|
||||
m_vc_r, m_vc_g, m_vc_b, m_vc_a, m_q,
|
||||
0, 0, 0 // TODO: U/S, V/T, fog
|
||||
};
|
||||
|
||||
m_vertex_count++;
|
||||
|
||||
logerror("%s: regs_w: XYZ2 = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s: X=%f Y=%f Z=%08x\n", machine().describe_context(), x / 16.0f, y / 16.0f, z);
|
||||
if (m_vertex_count >= m_kick_count)
|
||||
{
|
||||
logerror("%s: Should begin primitive drawing...\n", machine().describe_context());
|
||||
switch (m_prim_type & 7)
|
||||
{
|
||||
case PRIM_TYPE_LINE_STRIP:
|
||||
m_vertices[0] = m_vertices[m_vertex_count - 1];
|
||||
m_vertex_count = 1;
|
||||
m_kick_count = 1;
|
||||
break;
|
||||
case PRIM_TYPE_TRI_STRIP:
|
||||
case PRIM_TYPE_TRI_FAN:
|
||||
m_vertices[0] = m_vertices[m_vertex_count - 2];
|
||||
m_vertices[1] = m_vertices[m_vertex_count - 1];
|
||||
m_vertex_count = 2;
|
||||
m_kick_count = 1;
|
||||
break;
|
||||
case PRIM_TYPE_POINT:
|
||||
case PRIM_TYPE_LINE:
|
||||
case PRIM_TYPE_TRI:
|
||||
case PRIM_TYPE_SPRITE:
|
||||
case PRIM_TYPE_INVALID:
|
||||
default:
|
||||
m_vertex_count = 0;
|
||||
m_kick_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x18: // XYOFFSET1
|
||||
case 0x19: // XYOFFSET2
|
||||
{
|
||||
const uint8_t index = offset - 0x18;
|
||||
m_context[index].m_xyoffset = data;
|
||||
m_context[index].m_offset_x = data & 0xffff;
|
||||
m_context[index].m_offset_y = (data >> 32) & 0xffff;
|
||||
logerror("%s: regs_w: XYFOFFSET%d = %08x%08x\n", machine().describe_context(), index + 1, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s X=%f Y=%f\n", machine().describe_context(), m_context[index].m_offset_x / 16.0f, m_context[index].m_offset_y / 16.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x1a: // PRMODECONT
|
||||
m_prmodecont = data;
|
||||
m_use_prim_for_attrs = BIT(data, 0);
|
||||
logerror("%s: regs_w: PRMODECONT = %08x%08x, %s\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, m_use_prim_for_attrs ? "Use PRIM" : "Use PRMODE");
|
||||
break;
|
||||
|
||||
case 0x40: // SCISSOR1
|
||||
case 0x41: // SCISSOR2
|
||||
{
|
||||
const uint8_t index = offset - 0x40;
|
||||
m_context[index].m_scissor = data;
|
||||
m_context[index].m_scissor_x0 = data & 0x7ff;
|
||||
m_context[index].m_scissor_x1 = (data >> 16) & 0x7ff;
|
||||
m_context[index].m_scissor_y0 = (data >> 32) & 0x7ff;
|
||||
m_context[index].m_scissor_y1 = (data >> 48) & 0x7ff;
|
||||
logerror("%s: regs_w: SCISSOR%d = %08x%08x\n", machine().describe_context(), index + 1, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s X0=d Y0=%d X1=%d Y1=%d\n", machine().describe_context(), m_context[index].m_scissor_x0, m_context[index].m_scissor_y0, m_context[index].m_scissor_x1, m_context[index].m_scissor_y1);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x45: // DTHE
|
||||
m_dthe = data;
|
||||
m_dither = BIT(data, 0);
|
||||
logerror("%s: regs_w: DTHE = %08x%08x, %s\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, m_clamp_color ? "Dither" : "No Dither");
|
||||
break;
|
||||
|
||||
case 0x46: // COLCLAMP
|
||||
m_colclamp = data;
|
||||
m_clamp_color = BIT(data, 0);
|
||||
logerror("%s: regs_w: COLCLAMP = %08x%08x, %s\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, m_clamp_color ? "Clamp Color" : "Wrap Color");
|
||||
break;
|
||||
|
||||
case 0x47: // TEST1
|
||||
case 0x48: // TEST2
|
||||
{
|
||||
const uint8_t index = offset - 0x47;
|
||||
m_context[index].m_test = data;
|
||||
m_context[index].m_alpha_test = BIT(data, 0);
|
||||
m_context[index].m_alpha_func = (data >> 1) & 7;
|
||||
m_context[index].m_alpha_ref = (data >> 4) & 0xff;
|
||||
m_context[index].m_alpha_fail = (data >> 12) & 3;
|
||||
m_context[index].m_dstalpha_test = BIT(data, 14);
|
||||
m_context[index].m_dstalpha_pass1 = BIT(data, 15);
|
||||
m_context[index].m_depth_test = BIT(data, 16);
|
||||
m_context[index].m_depth_func = (data >> 17) & 3;
|
||||
logerror("%s: regs_w: SCISSOR%d = %08x%08x\n", machine().describe_context(), index + 1, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s X0=d Y0=%d X1=%d Y1=%d\n", machine().describe_context(), m_context[index].m_scissor_x0, m_context[index].m_scissor_y0, m_context[index].m_scissor_x1, m_context[index].m_scissor_y1);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4c: // FRAME1
|
||||
case 0x4d: // FRAME2
|
||||
{
|
||||
const uint8_t index = offset - 0x4c;
|
||||
m_context[index].m_frame = data;
|
||||
m_context[index].m_fb_base = (data & 0x1ff) << 11;
|
||||
m_context[index].m_fb_width = (data >> 10) & 0xfc0;
|
||||
m_context[index].m_fb_format = (data >> 24) & 0x3f;
|
||||
m_context[index].m_fb_mask = (uint32_t)(data >> 32);
|
||||
logerror("%s: regs_w: FRAME%d = %08x%08x\n", machine().describe_context(), index + 1, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s BASE=%08x WIDTH=%d FORMAT=%d MASK=%08x\n", machine().describe_context(), m_context[index].m_fb_base, m_context[index].m_fb_width, m_context[index].m_fb_format, m_context[index].m_fb_mask);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4e: // ZBUF1
|
||||
case 0x4f: // ZBUF2
|
||||
{
|
||||
const uint8_t index = offset - 0x4e;
|
||||
m_context[index].m_zbuf = data;
|
||||
m_context[index].m_z_base = (data & 0x1ff) << 11;
|
||||
m_context[index].m_z_format = (data >> 24) & 0xf;
|
||||
m_context[index].m_z_mask = BIT(data, 32);
|
||||
logerror("%s: regs_w: ZBUF%d = %08x%08x\n", machine().describe_context(), index + 1, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s BASE=%08x FORMAT=%d MASK=%d\n", machine().describe_context(), m_context[index].m_z_base, m_context[index].m_z_format, BIT(data, 32));
|
||||
break;
|
||||
}
|
||||
case 0x50: // BITBLTBUF
|
||||
m_bitbltbuf = data;
|
||||
m_src_buf_base = ((uint32_t)m_bitbltbuf & 0x7fff) << 6;
|
||||
m_src_buf_width = ((uint32_t)(m_bitbltbuf >> 16) & 0x3f) << 6;
|
||||
m_src_buf_fmt = (uint8_t)((m_bitbltbuf >> 24) & 0x3f);
|
||||
m_dst_buf_base = ((uint32_t)(m_bitbltbuf >> 32) & 0x7fff) << 6;
|
||||
m_dst_buf_width = ((uint32_t)(m_bitbltbuf >> 48) & 0x3f) << 6;
|
||||
m_dst_buf_fmt = (uint8_t)((m_bitbltbuf >> 56) & 0x3f);
|
||||
logerror("%s: regs_w: BITBLTBUF = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
logerror("%s: SRCBASE=%08x SRCWIDTH=%d SRCFMT=%s\n", machine().describe_context(), m_src_buf_base, m_src_buf_width, FORMAT_NAMES[m_src_buf_fmt]);
|
||||
logerror("%s: DSTBASE=%08x DSTWIDTH=%d DSTFMT=%s\n", machine().describe_context(), m_dst_buf_base, m_dst_buf_width, FORMAT_NAMES[m_dst_buf_fmt]);
|
||||
break;
|
||||
case 0x51: // TRXPOS
|
||||
m_trx_pos = data;
|
||||
m_src_ul_x = (uint32_t)m_trx_pos & 0x7ff;
|
||||
m_src_ul_y = (uint32_t)(m_trx_pos >> 16) & 0x7ff;
|
||||
m_dst_ul_x = (uint32_t)(m_trx_pos >> 32) & 0x7ff;
|
||||
m_dst_ul_y = (uint32_t)(m_trx_pos >> 48) & 0x7ff;
|
||||
m_copy_dir = (uint8_t)(m_trx_pos >> 59) & 3;
|
||||
logerror("%s: regs_w: TRXPOS = %08x%08x, SRCUL=%d,%d DSTUL=%d,%d, DIR=%d\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, m_src_ul_x, m_src_ul_y, m_dst_ul_x, m_dst_ul_y, m_copy_dir);
|
||||
break;
|
||||
case 0x52: // TRXREG
|
||||
m_trx_reg = data;
|
||||
m_trx_width = (uint32_t)m_trx_reg & 0xfff;
|
||||
m_trx_height = (uint32_t)(m_trx_reg >> 32) & 0xfff;
|
||||
logerror("%s: regs_w: TRXREG = %08x%08x, DIMS=%dx%d\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, m_trx_width, m_trx_height);
|
||||
break;
|
||||
case 0x53: // TRXDIR
|
||||
m_trx_dir = data & 3;
|
||||
logerror("%s: regs_w: TRXDIR = %08x%08x, %s\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data, dir_strs[m_trx_dir]);
|
||||
break;
|
||||
case 0x54: // HWREG
|
||||
logerror("%s: regs_w: HWREG = %08x%08x\n", machine().describe_context(), (uint32_t)(data >> 32), (uint32_t)data);
|
||||
copy_dword_from_host(data);
|
||||
break;
|
||||
default:
|
||||
logerror("%s: regs_w: Unknown register %02x = %08x%08x\n", machine().describe_context(), offset, (uint32_t)(data >> 32), (uint32_t)data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_gs_device::copy_dword_from_host(uint64_t data)
|
||||
{
|
||||
if (m_src_buf_fmt == PSMCT24 || m_src_buf_fmt == PSMZ24)
|
||||
{
|
||||
// Special-case for unevenly-sized data.
|
||||
// TODO: What do we do with leftover data, if any, when an IMAGE transfer finishes?
|
||||
logerror("%s: Unsupported src format: PSMCT24/PSMZ24\n", machine().describe_context());
|
||||
return;
|
||||
}
|
||||
const size_t bpp = FORMAT_PIXEL_WIDTHS[m_src_buf_fmt];
|
||||
offs_t dst_offset = (m_dst_buf_base + m_dst_ul_y * m_dst_buf_width + m_dst_ul_x) >> 2;
|
||||
for (size_t shift = 0, index = 0; shift < 64; shift += bpp, index++)
|
||||
{
|
||||
uint64_t src = (data >> shift) & ((1ULL << bpp) - 1ULL);
|
||||
switch (m_dst_buf_fmt)
|
||||
{
|
||||
case PSMCT32:
|
||||
case PSMZ32:
|
||||
{
|
||||
m_ram[dst_offset + index] = (uint32_t)src;
|
||||
break;
|
||||
}
|
||||
case PSMCT24:
|
||||
case PSMZ24:
|
||||
logerror("%s: Unsupported dst format: PSMCT24/PSMZ24\n", machine().describe_context());
|
||||
break;
|
||||
case PSMCT16:
|
||||
case PSMCT16S:
|
||||
case PSMZ16:
|
||||
case PSMZ16S:
|
||||
{
|
||||
const offs_t dst_shift = ((index & 1) << 4);
|
||||
m_ram[dst_offset + (index >> 1)] &= ~(0x0000ffff << dst_shift);
|
||||
m_ram[dst_offset + (index >> 1)] |= (uint32_t)src << dst_shift;
|
||||
break;
|
||||
}
|
||||
case PSMT8:
|
||||
{
|
||||
const offs_t dst_shift = ((index & 3) << 3);
|
||||
m_ram[dst_offset + (index >> 2)] &= ~(0x000000ff << dst_shift);
|
||||
m_ram[dst_offset + (index >> 2)] |= (uint32_t)src << dst_shift;
|
||||
break;
|
||||
}
|
||||
case PSMT8H:
|
||||
{
|
||||
m_ram[dst_offset + index] &= 0x00ffffff;
|
||||
m_ram[dst_offset + index] |= (uint32_t)src << 24;
|
||||
break;
|
||||
}
|
||||
case PSMT4:
|
||||
{
|
||||
const offs_t dst_shift = ((index & 7) << 2);
|
||||
m_ram[dst_offset + (index >> 3)] &= ~(0x0000000f << dst_shift);
|
||||
m_ram[dst_offset + (index >> 3)] |= (uint32_t)src << dst_shift;
|
||||
break;
|
||||
}
|
||||
case PSMT4HL:
|
||||
m_ram[dst_offset + index] &= 0xf0ffffff;
|
||||
m_ram[dst_offset + index] |= (uint32_t)src << 24;
|
||||
break;
|
||||
case PSMT4HH:
|
||||
m_ram[dst_offset + index] &= 0x0fffffff;
|
||||
m_ram[dst_offset + index] |= (uint32_t)src << 28;
|
||||
break;
|
||||
default:
|
||||
logerror("%s: copy_dword_from_host: Unknown format %02x\n", machine().describe_context(), m_dst_buf_fmt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ps2_gs_device::vblank_start()
|
||||
{
|
||||
}
|
||||
|
||||
void ps2_gs_device::vblank_end()
|
||||
{
|
||||
m_curr_field ^= 1;
|
||||
if (m_curr_field)
|
||||
m_csr |= CSR_FIELD_ODD;
|
||||
else
|
||||
m_csr &= ~CSR_FIELD_ODD;
|
||||
}
|
279
src/mame/video/ps2gs.h
Normal file
279
src/mame/video/ps2gs.h
Normal file
@ -0,0 +1,279 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
*
|
||||
* Sony Playstation 2 Graphics Synthesizer device skeleton
|
||||
*
|
||||
* To Do:
|
||||
* Everything
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAME_MACHINE_PS2GS_H
|
||||
#define MAME_MACHINE_PS2GS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
class ps2_gs_device : public device_t
|
||||
{
|
||||
public:
|
||||
ps2_gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_READ64_MEMBER(priv_regs0_r);
|
||||
DECLARE_WRITE64_MEMBER(priv_regs0_w);
|
||||
DECLARE_READ64_MEMBER(priv_regs1_r);
|
||||
DECLARE_WRITE64_MEMBER(priv_regs1_w);
|
||||
|
||||
DECLARE_WRITE64_MEMBER(regs_w);
|
||||
|
||||
void reg_write(const uint8_t reg, const uint64_t value);
|
||||
void write_packed(const uint8_t reg, const uint64_t hi, const uint64_t lo);
|
||||
|
||||
void vblank_start();
|
||||
void vblank_end();
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
void copy_dword_from_host(uint64_t data);
|
||||
|
||||
enum : uint64_t
|
||||
{
|
||||
HOST_TO_LOCAL,
|
||||
LOCAL_TO_HOST,
|
||||
LOCAL_TO_LOCAL,
|
||||
NO_TRANSFER
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
UL_TO_BR,
|
||||
BL_TO_UR,
|
||||
UR_TO_BL,
|
||||
BR_TO_UL
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
PSMCT32 = 0x00,
|
||||
PSMCT24 = 0x01,
|
||||
PSMCT16 = 0x02,
|
||||
PSMCT16S = 0x0a,
|
||||
PSMT8 = 0x13,
|
||||
PSMT4 = 0x14,
|
||||
PSMT8H = 0x1b,
|
||||
PSMT4HL = 0x24,
|
||||
PSMT4HH = 0x2c,
|
||||
PSMZ32 = 0x30,
|
||||
PSMZ24 = 0x31,
|
||||
PSMZ16 = 0x32,
|
||||
PSMZ16S = 0x3a
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
ALPHA_FUNC_NEVER,
|
||||
ALPHA_FUNC_ALWAYS,
|
||||
ALPHA_FUNC_LESS,
|
||||
ALPHA_FUNC_LEQUAL,
|
||||
ALPHA_FUNC_EQUAL,
|
||||
ALPHA_FUNC_GEQUAL,
|
||||
ALPHA_FUNC_GREATER,
|
||||
ALPHA_FUNC_NOTEQUAL
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
ALPHA_FAIL_KEEP,
|
||||
ALPHA_FAIL_UPDATE_FB,
|
||||
ALPHA_FAIL_UPDATE_ZB,
|
||||
ALPHA_FAIL_UPDATE_RGB
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
DEPTH_FUNC_NEVER,
|
||||
DEPTH_FUNC_ALWAYS,
|
||||
DEPTH_FUNC_GEQUAL,
|
||||
DEPTH_FUNC_GREATER
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
PRIM_TYPE_POINT,
|
||||
PRIM_TYPE_LINE,
|
||||
PRIM_TYPE_LINE_STRIP,
|
||||
PRIM_TYPE_TRI,
|
||||
PRIM_TYPE_TRI_STRIP,
|
||||
PRIM_TYPE_TRI_FAN,
|
||||
PRIM_TYPE_SPRITE,
|
||||
PRIM_TYPE_INVALID
|
||||
};
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
CSR_RESET = 0x00000200,
|
||||
CSR_FIELD_ODD = 0x00002000
|
||||
};
|
||||
|
||||
struct vertex_t
|
||||
{
|
||||
uint16_t m_x;
|
||||
uint16_t m_y;
|
||||
uint32_t m_z;
|
||||
|
||||
uint8_t m_r;
|
||||
uint8_t m_g;
|
||||
uint8_t m_b;
|
||||
uint8_t m_a;
|
||||
float m_q;
|
||||
|
||||
uint32_t m_us;
|
||||
uint32_t m_vt;
|
||||
|
||||
uint8_t m_fog;
|
||||
};
|
||||
|
||||
std::unique_ptr<uint32_t[]> m_ram;
|
||||
std::unique_ptr<vertex_t[]> m_vertices;
|
||||
|
||||
struct context_t
|
||||
{
|
||||
uint64_t m_xyoffset; // 0x18, 0x19
|
||||
uint32_t m_offset_x;
|
||||
uint32_t m_offset_y;
|
||||
|
||||
uint64_t m_scissor; // 0x40, 0x41
|
||||
uint16_t m_scissor_x0;
|
||||
uint16_t m_scissor_x1;
|
||||
uint16_t m_scissor_y0;
|
||||
uint16_t m_scissor_y1;
|
||||
|
||||
uint64_t m_test; // 0x47, 0x48
|
||||
bool m_alpha_test;
|
||||
uint8_t m_alpha_func;
|
||||
uint8_t m_alpha_ref;
|
||||
uint8_t m_alpha_fail;
|
||||
bool m_dstalpha_test;
|
||||
bool m_dstalpha_pass1;
|
||||
bool m_depth_test;
|
||||
uint8_t m_depth_func;
|
||||
|
||||
uint64_t m_frame; // 0x4c, 0x4d
|
||||
uint32_t m_fb_base;
|
||||
uint32_t m_fb_width;
|
||||
uint8_t m_fb_format;
|
||||
uint32_t m_fb_mask;
|
||||
|
||||
uint64_t m_zbuf; // 0x4e, 0x4f
|
||||
uint32_t m_z_base;
|
||||
uint8_t m_z_format;
|
||||
bool m_z_mask;
|
||||
};
|
||||
|
||||
context_t m_context[2];
|
||||
|
||||
uint64_t m_prim; // 0x00
|
||||
uint8_t m_prim_type;
|
||||
bool m_gouraud_enable;
|
||||
bool m_texture_enable;
|
||||
bool m_fog_enable;
|
||||
bool m_blend_enable;
|
||||
bool m_aa_enable;
|
||||
bool m_no_perspective;
|
||||
uint8_t m_curr_context;
|
||||
bool m_fix_fragments;
|
||||
|
||||
uint64_t m_rgbaq; // 0x01
|
||||
uint8_t m_vc_r;
|
||||
uint8_t m_vc_g;
|
||||
uint8_t m_vc_b;
|
||||
uint8_t m_vc_a;
|
||||
float m_q;
|
||||
|
||||
uint64_t m_prmodecont; // 0x1a
|
||||
bool m_use_prim_for_attrs;
|
||||
|
||||
uint64_t m_dthe; // 0x45
|
||||
bool m_dither;
|
||||
|
||||
uint64_t m_colclamp; // 0x46
|
||||
bool m_clamp_color;
|
||||
|
||||
uint64_t m_bitbltbuf; // 0x50
|
||||
uint32_t m_src_buf_base;
|
||||
uint32_t m_src_buf_width;
|
||||
uint8_t m_src_buf_fmt;
|
||||
uint32_t m_dst_buf_base;
|
||||
uint32_t m_dst_buf_width;
|
||||
uint8_t m_dst_buf_fmt;
|
||||
|
||||
uint64_t m_trx_pos; // 0x51
|
||||
uint32_t m_src_ul_x;
|
||||
uint32_t m_src_ul_y;
|
||||
uint32_t m_dst_ul_x;
|
||||
uint32_t m_dst_ul_y;
|
||||
uint8_t m_copy_dir;
|
||||
|
||||
uint64_t m_trx_reg; // 0x52
|
||||
uint32_t m_trx_width;
|
||||
uint32_t m_trx_height;
|
||||
|
||||
uint64_t m_trx_dir; // 0x53
|
||||
|
||||
// Privileged regs
|
||||
uint64_t m_base_regs[15];
|
||||
|
||||
uint64_t m_pmode; // Privileged 0x00
|
||||
bool m_read_circuit_enable[2];
|
||||
bool m_use_fixed_alpha;
|
||||
uint8_t m_alpha_out_select;
|
||||
bool m_blend_to_background;
|
||||
uint8_t m_fixed_alpha;
|
||||
|
||||
uint64_t m_smode2; // Privileged 0x02
|
||||
bool m_interlace;
|
||||
bool m_frame_interlace;
|
||||
uint8_t m_dpms_mode;
|
||||
|
||||
uint64_t m_dispfb[2]; // Privileged 0x07, 0x09
|
||||
uint32_t m_dispfb_base[2];
|
||||
uint32_t m_dispfb_width[2];
|
||||
uint8_t m_dispfb_format[2];
|
||||
uint32_t m_dispfb_x[2];
|
||||
uint32_t m_dispfb_y[2];
|
||||
|
||||
uint64_t m_display[2]; // Privileged 0x08, 0x0a
|
||||
uint32_t m_display_xpos[2];
|
||||
uint32_t m_display_ypos[2];
|
||||
uint8_t m_magh[2];
|
||||
uint8_t m_magv[2];
|
||||
uint32_t m_display_width[2];
|
||||
uint32_t m_display_height[2];
|
||||
|
||||
uint64_t m_bgcolor; // Privileged 0x0e
|
||||
uint8_t m_bg_r;
|
||||
uint8_t m_bg_g;
|
||||
uint8_t m_bg_b;
|
||||
|
||||
uint64_t m_csr;
|
||||
uint64_t m_imr;
|
||||
uint64_t m_busdir;
|
||||
uint64_t m_sig_label_id;
|
||||
|
||||
uint32_t m_vertex_count;
|
||||
uint32_t m_kick_count;
|
||||
|
||||
uint8_t m_curr_field;
|
||||
|
||||
static const size_t FORMAT_PIXEL_WIDTHS[0x40];
|
||||
static const char* FORMAT_NAMES[0x40];
|
||||
static const uint32_t KICK_COUNTS[8];
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SONYPS2_GS, ps2_gs_device)
|
||||
|
||||
#endif // MAME_MACHINE_PS2GS_H
|
Loading…
Reference in New Issue
Block a user