summaryrefslogtreecommitdiff
path: root/lib/mips.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mips.cpp')
-rw-r--r--lib/mips.cpp162
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);
+ }
+}