diff options
Diffstat (limited to 'lib/mips.cpp')
-rw-r--r-- | lib/mips.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/lib/mips.cpp b/lib/mips.cpp new file mode 100644 index 0000000..4956b9e --- /dev/null +++ b/lib/mips.cpp @@ -0,0 +1,162 @@ +#include "mips.h" + +Uint8 mips::Read8(Uint32 mem) { + if ((mem < 0x80000000) || (mem >= 0x80200000)) { + printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem); + return 0; + } + + mem -= 0x80000000; + + if (IsPatched(mem)) { + return patches[mem]; + } else { + return plainmemory[mem]; + } +} + +Uint16 mips::Read16(Uint32 mem) { + Uint8 a, b; + + if (mem & 1) { + printm(M_WARNING, "Read16 at a non 16-bits boundary: 0x%08x\n", mem); + } + + a = Read8(mem); + b = Read8(mem + 1); + + return a | (b << 8); +} + +Uint32 mips::Read32(Uint32 mem) { + Uint8 a, b, c, d; + + if (mem & 3) { + printm(M_WARNING, "Read32 at a non 32-bits boundary: 0x%08x\n", mem); + } + + a = Read8(mem); + b = Read8(mem + 1); + c = Read8(mem + 2); + d = Read8(mem + 3); + + return a | (b << 8) | (c << 16) | (d << 24); +} + +void mips::Write8(Uint32 mem, Uint8 value) { + if ((mem < 0x80000000) || (mem > (0x80200000 - 1))) { + printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem); + return; + } + + mem -= 0x80000000; + + patch(mem, 1); + patches[mem] = value; +} + +void mips::Write16(Uint32 mem, Uint16 value) { + if ((mem < 0x80000000) || (mem > (0x80200000 - 2))) { + printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem); + return; + } + + mem -= 0x80000000; + + patch(mem, 2); + patches[mem] = value & 0xff; + patches[mem + 1] = (value >> 8) & 0xff; +} + +void mips::Write32(Uint32 mem, Uint32 value) { + if ((mem < 0x80000000) || (mem > (0x80200000 - 4))) { + printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem); + return; + } + + mem -= 0x80000000; + + patch(mem, 4); + patches[mem] = value & 0xff; + patches[mem + 1] = (value >> 8) & 0xff; + patches[mem + 2] = (value >> 16) & 0xff; + patches[mem + 3] = (value >> 24) & 0xff; +} + +void mips::unpatch8(Uint32 mem) { + unpatch(mem, 1); +} + +void mips::unpatch16(Uint32 mem) { + unpatch(mem, 2); +} + +void mips::unpatch32(Uint32 mem) { + unpatch(mem, 4); +} + +bool mips::IsPatched(Uint32 mem) { + int mask, pos; + + pos = mem / 8; + mask = 1 << (mem % 8); + + return patchesmap[pos] &= mask; +} + +void mips::LoadEXE(Handle * h) { + h->read(psyqhead, 0x800); + memset(plainmemory, 0, 0x200000); + paddr = ((psyq*)psyqhead)->t_addr; + psize = ((psyq*)psyqhead)->t_size; + + printm(M_INFO, "Loading %i (%08x) bytes of data at %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr); + + h->read(plainmemory + paddr - 0x80000000, psize); +} + +void mips::SaveEXE(Handle * h) {\ + Uint32 i; + + if (!*((Uint32 *)psyqhead)) + return; + h->write(psyqhead, 0x800); + paddr = ((psyq*)psyqhead)->t_addr; + psize = ((psyq*)psyqhead)->t_size; + + printm(M_INFO, "Writing %i (%08x) bytes of data from %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr); + + for (i = paddr - 0x80000000; i < psize; i++) { + h->writeU8(Read8(i)); + } +} + +Uint32 mips::GetPC() { + return startpc; +} + +void mips::patch(Uint32 mem, int size) { + int mask, pos; + + pos = mem / 8; + mask = 1 << (mem % 8); + + patchesmap[pos] |= mask; + + if (size != 1) { + patch(mem + 1, size - 1); + } +} + +void mips::unpatch(Uint32 mem, int size) { + int mask, pos; + + pos = mem / 8; + mask = ~(1 << (mem % 8)); + + patchesmap[pos] &= mask; + + if (size != 1) { + unpatch(mem + 1, size - 1); + } +} |