Fix 8/16-bit RSP accesses

This commit is contained in:
SimoneN64
2023-08-28 20:11:38 +02:00
parent ef4c662c60
commit 3d2c243d42

View File

@@ -188,10 +188,11 @@ u8 Mem::Read8(n64::Registers &regs, u32 paddr) {
return mmio.rdp.rdram[BYTE_ADDRESS(paddr)]; return mmio.rdp.rdram[BYTE_ADDRESS(paddr)];
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
if(mirrAddr >= 0x1000) { if(mirrAddr & 0x1000) {
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE]; mirrAddr -= 0x1000;
return mmio.rsp.imem[BYTE_ADDRESS(mirrAddr)];
} else { } else {
return mmio.rsp.dmem[BYTE_ADDRESS(paddr) & DMEM_DSIZE]; return mmio.rsp.dmem[BYTE_ADDRESS(mirrAddr)];
} }
} }
case 0x04040000 ... 0x040FFFFF: case 0x04040000 ... 0x040FFFFF:
@@ -257,10 +258,11 @@ u16 Mem::Read16(n64::Registers &regs, u32 paddr) {
return Util::ReadAccess<u16>(mmio.rdp.rdram, HALF_ADDRESS(paddr)); return Util::ReadAccess<u16>(mmio.rdp.rdram, HALF_ADDRESS(paddr));
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
if(mirrAddr >= 0x1000) { if(mirrAddr & 0x1000) {
return Util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE); mirrAddr -= 0x1000;
return Util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(mirrAddr));
} else { } else {
return Util::ReadAccess<u16>(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE); return Util::ReadAccess<u16>(mmio.rsp.dmem, HALF_ADDRESS(mirrAddr));
} }
} }
case MMIO_REGION: case MMIO_REGION:
@@ -297,10 +299,11 @@ u32 Mem::Read32(n64::Registers &regs, u32 paddr) {
return Util::ReadAccess<u32>(mmio.rdp.rdram, paddr); return Util::ReadAccess<u32>(mmio.rdp.rdram, paddr);
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
if(mirrAddr >= 0x1000) { if(mirrAddr & 0x1000) {
return Util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE); mirrAddr -= 0x1000;
return Util::ReadAccess<u32>(mmio.rsp.imem, mirrAddr);
} else { } else {
return Util::ReadAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE); return Util::ReadAccess<u32>(mmio.rsp.dmem, mirrAddr);
} }
} }
case MMIO_REGION: case MMIO_REGION:
@@ -343,10 +346,11 @@ u64 Mem::Read64(n64::Registers &regs, u32 paddr) {
return Util::ReadAccess<u64>(mmio.rdp.rdram, paddr); return Util::ReadAccess<u64>(mmio.rdp.rdram, paddr);
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
if(mirrAddr >= 0x1000) { if(mirrAddr & 0x1000) {
return Util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE); mirrAddr -= 0x1000;
return Util::ReadAccess<u64>(mmio.rsp.imem, mirrAddr);
} else { } else {
return Util::ReadAccess<u64>(mmio.rsp.dmem, paddr & DMEM_DSIZE); return Util::ReadAccess<u64>(mmio.rsp.dmem, mirrAddr);
} }
} }
case MMIO_REGION: case MMIO_REGION:
@@ -383,13 +387,12 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
break; break;
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
val = val << (8 * (3 - (paddr & 3))); val = val << (8 * (3 - (mirrAddr & 3)));
if(mirrAddr >= 0x1000) { mirrAddr = (mirrAddr & 0xFFF) & ~3;
paddr = (paddr & IMEM_SIZE) & ~3; if(mirrAddr & 0x1000) {
Util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val); Util::WriteAccess<u32>(mmio.rsp.imem, mirrAddr, val);
} else { } else {
paddr = (paddr & DMEM_SIZE) & ~3; Util::WriteAccess<u32>(mmio.rsp.dmem, mirrAddr, val);
Util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
} }
} break; } break;
case MMIO_REGION: case MMIO_REGION:
@@ -454,13 +457,12 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
break; break;
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
val = val << (16 * !(paddr & 2)); val = val << (16 * !(mirrAddr & 2));
if(mirrAddr >= 0x1000) { mirrAddr = (mirrAddr & 0xFFF) & ~3;
paddr = (paddr & IMEM_SIZE) & ~3; if(mirrAddr & 0x1000) {
Util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val); Util::WriteAccess<u32>(mmio.rsp.imem, mirrAddr, val);
} else { } else {
paddr = (paddr & DMEM_SIZE) & ~3; Util::WriteAccess<u32>(mmio.rsp.dmem, mirrAddr, val);
Util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
} }
} break; } break;
case MMIO_REGION: case MMIO_REGION:
@@ -504,7 +506,7 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
break; break;
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
if(mirrAddr >= 0x1000) { if(mirrAddr & 0x1000) {
Util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val); Util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
} else { } else {
Util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); Util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
@@ -571,7 +573,7 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
case RSP_MEM_REGION: { case RSP_MEM_REGION: {
u32 mirrAddr = paddr & 0x1FFF; u32 mirrAddr = paddr & 0x1FFF;
val >>= 32; val >>= 32;
if(mirrAddr >= 0x1000) { if(mirrAddr & 0x1000) {
Util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val); Util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
} else { } else {
Util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); Util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);