diff --git a/src/backend/MemoryRegions.hpp b/src/backend/MemoryRegions.hpp index 9f6b1e21..64ac2028 100644 --- a/src/backend/MemoryRegions.hpp +++ b/src/backend/MemoryRegions.hpp @@ -24,6 +24,8 @@ #define DMEM_REGION_END (DMEM_REGION_START + DMEM_DSIZE) #define IMEM_REGION_START 0x4001000 #define IMEM_REGION_END (IMEM_REGION_START + IMEM_DSIZE) +#define PIF_ROM_REGION_START 0x1FC00000 +#define PIF_ROM_REGION_END 0x1FC007BF #define PIF_RAM_REGION_START 0x1FC007C0 #define PIF_RAM_REGION_END 0x1FC007FF #define CART_REGION_START_1_1 0x06000000 @@ -38,9 +40,12 @@ #define RDRAM_REGION RDRAM_REGION_START ... RDRAM_REGION_END #define DMEM_REGION DMEM_REGION_START ... DMEM_REGION_END #define IMEM_REGION IMEM_REGION_START ... IMEM_REGION_END -#define MMIO_REGION 0x04040000 ... 0x048FFFFF +#define MMIO_REGION 0x04040000 ... 0x041FFFFF: case 0x04300000 ... 0x048FFFFF #define SP_REGION 0x04040000 ... 0x040FFFFF #define DP_CMD_REGION 0x04100000 ... 0x041FFFFF +#define RSP_REGION 0x04040000 ... 0x040FFFFF +#define RDP_REGION 0x04100000 ... 0x041FFFFF +#define MI_REGION 0x04300000 ... 0x043FFFFF #define MI_REGION 0x04300000 ... 0x043FFFFF #define VI_REGION 0x04400000 ... 0x044FFFFF #define AI_REGION 0x04500000 ... 0x045FFFFF @@ -52,7 +57,7 @@ #define CART_REGION_1_2 (CART_REGION_START_1_2) ... (CART_REGION_END_1_2) #define CART_REGION_2_1 (CART_REGION_START_2_1) ... (CART_REGION_END_2_1) #define CART_REGION_2_2 (CART_REGION_START_2_2) ... (CART_REGION_END_2_2) -#define PIF_ROM_REGION 0x1FC00000 ... 0x1FC007BF +#define PIF_ROM_REGION PIF_ROM_REGION_START ... PIF_ROM_REGION_END #define PIF_RAM_REGION PIF_RAM_REGION_START ... PIF_RAM_REGION_END constexpr u64 operator""_kb(unsigned long long int x) { diff --git a/src/backend/core/MMIO.cpp b/src/backend/core/MMIO.cpp index a83a6ac2..229b6129 100644 --- a/src/backend/core/MMIO.cpp +++ b/src/backend/core/MMIO.cpp @@ -17,14 +17,14 @@ void MMIO::Reset() { u32 MMIO::Read(u32 addr) { switch (addr) { - case 0x04040000 ... 0x040FFFFF: return rsp.Read(addr); - case 0x04100000 ... 0x041FFFFF: return rdp.Read(addr); - case 0x04300000 ... 0x043FFFFF: return mi.Read(addr); - case 0x04400000 ... 0x044FFFFF: return vi.Read(addr); - case 0x04500000 ... 0x045FFFFF: return ai.Read(addr); - case 0x04600000 ... 0x046FFFFF: return pi.Read(mi, addr); - case 0x04700000 ... 0x047FFFFF: return ri.Read(addr); - case 0x04800000 ... 0x048FFFFF: return si.Read(mi, addr); + case RSP_REGION: return rsp.Read(addr); + case RDP_REGION: return rdp.Read(addr); + case MI_REGION: return mi.Read(addr); + case VI_REGION: return vi.Read(addr); + case AI_REGION: return ai.Read(addr); + case PI_REGION: return pi.Read(mi, addr); + case RI_REGION: return ri.Read(addr); + case SI_REGION: return si.Read(mi, addr); default: Util::panic("Unhandled mmio read at addr {:08X}", addr); } @@ -32,14 +32,14 @@ u32 MMIO::Read(u32 addr) { void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { switch (addr) { - case 0x04040000 ... 0x040FFFFF: rsp.Write(mem, regs, addr, val); break; - case 0x04100000 ... 0x041FFFFF: rdp.Write(mi, regs, rsp, addr, val); break; - case 0x04300000 ... 0x043FFFFF: mi.Write(regs, addr, val); break; - case 0x04400000 ... 0x044FFFFF: vi.Write(mi, regs, addr, val); break; - case 0x04500000 ... 0x045FFFFF: ai.Write(mem, regs, addr, val); break; - case 0x04600000 ... 0x046FFFFF: pi.Write(mem, regs, addr, val); break; - case 0x04700000 ... 0x047FFFFF: ri.Write(addr, val); break; - case 0x04800000 ... 0x048FFFFF: si.Write(mem, regs, addr, val); break; + case RSP_REGION: rsp.Write(mem, regs, addr, val); break; + case RDP_REGION: rdp.Write(mi, regs, rsp, addr, val); break; + case MI_REGION: mi.Write(regs, addr, val); break; + case VI_REGION: vi.Write(mi, regs, addr, val); break; + case AI_REGION: ai.Write(mem, regs, addr, val); break; + case PI_REGION: pi.Write(mem, regs, addr, val); break; + case RI_REGION: ri.Write(addr, val); break; + case SI_REGION: si.Write(mem, regs, addr, val); break; default: Util::panic("Unhandled mmio write at addr {:08X} with val {:08X}", addr, val); } diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index d797f253..d0df0a57 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -104,19 +104,18 @@ u8 Mem::Read8(n64::Registers ®s, u32 paddr) { return ((u8*)pointer)[BYTE_ADDRESS(offset)]; } else { switch (paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: return mmio.rdp.rdram[BYTE_ADDRESS(paddr)]; - case 0x04000000 ... 0x0403FFFF: - if (paddr & 0x1000) - return mmio.rsp.imem[BYTE_ADDRESS(paddr) - IMEM_REGION_START]; - else + case DMEM_REGION: return mmio.rsp.dmem[BYTE_ADDRESS(paddr) - DMEM_REGION_START]; + case IMEM_REGION: + return mmio.rsp.imem[BYTE_ADDRESS(paddr) - IMEM_REGION_START]; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04600000 ... 0x048FFFFF: case 0x04300000 ... 0x044FFFFF: - return 0xff; - case 0x04500000 ... 0x045FFFFF: { + Util::panic("MMIO Read8!\n"); + case AI_REGION: { u32 w = mmio.ai.Read(paddr & ~3); int offs = 3 - (paddr & 3); return (w >> (offs * 8)) & 0xff; @@ -124,14 +123,14 @@ u8 Mem::Read8(n64::Registers ®s, u32 paddr) { case CART_REGION_1_2: paddr = (paddr + 2) & ~2; return rom.cart[BYTE_ADDRESS(paddr) & rom.mask]; - case 0x1FC00000 ... 0x1FC007BF: - return si.pif.bootrom[BYTE_ADDRESS(paddr) - 0x1FC00000]; + case PIF_ROM_REGION: + return si.pif.bootrom[BYTE_ADDRESS(paddr) - PIF_ROM_REGION_START]; case PIF_RAM_REGION: return si.pif.ram[paddr - PIF_RAM_REGION_START]; - case 0x00800000 ... 0x03FFFFFF: - case 0x04200000 ... 0x042FFFFF: - case 0x04900000 ... 0x0FFFFFFF: - case 0x1FC00800 ... 0xFFFFFFFF: + case 0x00800000 ... 0x03FFFFFF: // unused + case 0x04200000 ... 0x042FFFFF: // unused + case 0x04900000 ... 0x0FFFFFFF: // unused + case 0x1FC00800 ... 0xFFFFFFFF: // unused return 0; default: Util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); @@ -149,23 +148,19 @@ u16 Mem::Read16(n64::Registers ®s, u32 paddr) { return Util::ReadAccess((u8*)pointer, HALF_ADDRESS(offset)); } else { switch (paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: return Util::ReadAccess(mmio.rdp.rdram, HALF_ADDRESS(paddr)); - case 0x04000000 ... 0x0403FFFF: - if (paddr & 0x1000) - return Util::ReadAccess(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE); - else + case DMEM_REGION: return Util::ReadAccess(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE); - case 0x04040000 ... 0x040FFFFF: - case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: - case 0x04500000 ... 0x048FFFFF: + case IMEM_REGION: + return Util::ReadAccess(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE); + case MMIO_REGION: return mmio.Read(paddr); case CART_REGION_1_2: paddr = (paddr + 2) & ~3; return Util::ReadAccess(rom.cart, HALF_ADDRESS(paddr) & rom.mask); - case 0x1FC00000 ... 0x1FC007BF: - return Util::ReadAccess(si.pif.bootrom, HALF_ADDRESS(paddr) - 0x1FC00000); + case PIF_ROM_REGION: + return Util::ReadAccess(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START); case PIF_RAM_REGION: return be16toh(Util::ReadAccess(si.pif.ram, paddr - PIF_RAM_REGION_START)); case 0x00800000 ... 0x03FFFFFF: @@ -189,20 +184,18 @@ u32 Mem::Read32(n64::Registers ®s, u32 paddr) { return Util::ReadAccess((u8*)pointer, offset); } else { switch(paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: return Util::ReadAccess(mmio.rdp.rdram, paddr); - case 0x04000000 ... 0x0403FFFF: - if(paddr & 0x1000) - return Util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); - else + case DMEM_REGION: return Util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); - case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: + case IMEM_REGION: + return Util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); + case MMIO_REGION: return mmio.Read(paddr); case CART_REGION_1_2: return Util::ReadAccess(rom.cart, paddr & rom.mask); - case 0x1FC00000 ... 0x1FC007BF: - return Util::ReadAccess(si.pif.bootrom, paddr - 0x1FC00000); + case PIF_ROM_REGION: + return Util::ReadAccess(si.pif.bootrom, paddr - PIF_ROM_REGION_START); case PIF_RAM_REGION: return be32toh(Util::ReadAccess(si.pif.ram, paddr - PIF_RAM_REGION_START)); case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: @@ -223,22 +216,18 @@ u64 Mem::Read64(n64::Registers ®s, u32 paddr) { return Util::ReadAccess((u8*)pointer, offset); } else { switch (paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: return Util::ReadAccess(mmio.rdp.rdram, paddr); - case 0x04000000 ... 0x0403FFFF: - if (paddr & 0x1000) - return Util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); - else - return Util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); - case 0x04040000 ... 0x040FFFFF: - case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: - case 0x04500000 ... 0x048FFFFF: + case DMEM_REGION: + return Util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); + case IMEM_REGION: + return Util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); + case MMIO_REGION: return mmio.Read(paddr); case CART_REGION_1_2: return Util::ReadAccess(rom.cart, paddr & rom.mask); - case 0x1FC00000 ... 0x1FC007BF: - return Util::ReadAccess(si.pif.bootrom, paddr - 0x1FC00000); + case PIF_ROM_REGION: + return Util::ReadAccess(si.pif.bootrom, paddr - PIF_ROM_REGION_START); case PIF_RAM_REGION: return be64toh(Util::ReadAccess(si.pif.ram, paddr - PIF_RAM_REGION_START)); case 0x00800000 ... 0x03FFFFFF: @@ -262,21 +251,20 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) { ((u8*)pointer)[BYTE_ADDRESS(offset)] = val; } else { switch (paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: mmio.rdp.rdram[BYTE_ADDRESS(paddr)] = val; break; - case 0x04000000 ... 0x0403FFFF: + case DMEM_REGION: val = val << (8 * (3 - (paddr & 3))); paddr = (paddr & DMEM_DSIZE) & ~3; - if (paddr & 0x1000) - Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); - else - Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; - case 0x04040000 ... 0x040FFFFF: - case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: - case 0x04500000 ... 0x048FFFFF: + case IMEM_REGION: + val = val << (8 * (3 - (paddr & 3))); + paddr = (paddr & IMEM_SIZE) & ~3; + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_SIZE, val); + break; + case MMIO_REGION: Util::panic("MMIO Write8!"); case CART_REGION_1_2: break; @@ -286,13 +274,12 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) { Util::WriteAccess(si.pif.ram, paddr, htobe32(val)); si.pif.ProcessCommands(*this); break; + case SRAM_REGION: + Util::panic("SRAM Write8!"); case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: - case 0x08000000 ... 0x0FFFFFFF: - Util::debug("SRAM 8 bit write {:02X}", val); - break; case 0x04900000 ... 0x07FFFFFF: - case 0x1FC00000 ... 0x1FC007BF: + case PIF_ROM_REGION: case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break; @@ -313,21 +300,20 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) { Util::WriteAccess((u8*)pointer, HALF_ADDRESS(offset), val); } else { switch (paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: Util::WriteAccess(mmio.rdp.rdram, HALF_ADDRESS(paddr), val); break; - case 0x04000000 ... 0x0403FFFF: + case DMEM_REGION: val = val << (16 * !(paddr & 2)); - paddr &= ~3; - if (paddr & 0x1000) - Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); - else - Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + paddr = (paddr & DMEM_SIZE) & ~3; + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; - case 0x04040000 ... 0x040FFFFF: - case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: - case 0x04500000 ... 0x048FFFFF: + case IMEM_REGION: + val = val << (16 * !(paddr & 2)); + paddr = (paddr & IMEM_SIZE) & ~3; + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_SIZE, val); + break; + case MMIO_REGION: Util::panic("MMIO Write16!"); case CART_REGION_1_2: break; @@ -337,11 +323,12 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) { Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(val)); si.pif.ProcessCommands(*this); break; + case SRAM_REGION: + Util::panic("SRAM Write16!"); case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: - case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: - case 0x1FC00000 ... 0x1FC007BF: + case PIF_ROM_REGION: case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break; @@ -362,17 +349,18 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) { Util::WriteAccess((u8*)pointer, offset, val); } else { switch(paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: Util::WriteAccess(mmio.rdp.rdram, paddr, val); break; - case 0x04000000 ... 0x0403FFFF: - if(paddr & 0x1000) - Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); - else - Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + case DMEM_REGION: + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + break; + case IMEM_REGION: + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_SIZE, val); + break; + case MMIO_REGION: + mmio.Write(*this, regs, paddr, val); break; - case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Write(*this, regs, paddr, val); break; case 0x10000000 ... 0x13FF0013: break; case 0x13FF0014: { if(val < ISVIEWER_SIZE) { @@ -390,10 +378,14 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) { Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(val)); si.pif.ProcessCommands(*this); break; - case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: - case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: - case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00800 ... 0x7FFFFFFF: + case 0x00800000 ... 0x03FFFFFF: + case 0x04200000 ... 0x042FFFFF: + case 0x04900000 ... 0x07FFFFFF: + case PIF_ROM_REGION: + case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break; + case 0x08000000 ... 0x0FFFFFFF: + Util::panic("SRAM Write32!"); default: Util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val, (u64)regs.pc); } } @@ -409,20 +401,18 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) { Util::WriteAccess((u8*)pointer, offset, val); } else { switch (paddr) { - case 0x00000000 ... 0x007FFFFF: + case RDRAM_REGION: Util::WriteAccess(mmio.rdp.rdram, paddr, val); break; - case 0x04000000 ... 0x0403FFFF: + case DMEM_REGION: val >>= 32; - if (paddr & 0x1000) - Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); - else - Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; - case 0x04040000 ... 0x040FFFFF: - case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: - case 0x04500000 ... 0x048FFFFF: + case IMEM_REGION: + val >>= 32; + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_SIZE, val); + break; + case MMIO_REGION: Util::panic("MMIO Write64!"); case CART_REGION_1_2: break; @@ -432,12 +422,12 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) { break; case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: - case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00800 ... 0x7FFFFFFF: - case 0x80000000 ... 0xFFFFFFFF: - break; + case 0x80000000 ... 0xFFFFFFFF: break; + case 0x08000000 ... 0x0FFFFFFF: + Util::panic("SRAM Write64!"); default: Util::panic("Unimplemented 64-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val, (u64) regs.pc);