+// -----------------------------------------------------
+// pointer register handlers
+
+//
+#define ptr1_read(op) ptr1_read_(op&3,(op>>6)&4,(op<<1)&0x18)
+
+static u32 ptr1_read_(int ri, int isj2, int modi3)
+{
+ //int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18);
+ u32 mask, add = 0, t = ri | isj2 | modi3;
+ unsigned char *rp = NULL;
+ switch (t)
+ {
+ // mod=0 (00)
+ case 0x00:
+ case 0x01:
+ case 0x02: return ssp->RAM0[ssp->r0[t&3]];
+ case 0x03: return ssp->RAM0[0];
+ case 0x04:
+ case 0x05:
+ case 0x06: return ssp->RAM1[ssp->r1[t&3]];
+ case 0x07: return ssp->RAM1[0];
+ // mod=1 (01), "+!"
+ case 0x08:
+ case 0x09:
+ case 0x0a: return ssp->RAM0[ssp->r0[t&3]++];
+ case 0x0b: return ssp->RAM0[1];
+ case 0x0c:
+ case 0x0d:
+ case 0x0e: return ssp->RAM1[ssp->r1[t&3]++];
+ case 0x0f: return ssp->RAM1[1];
+ // mod=2 (10), "-"
+ case 0x10:
+ case 0x11:
+ case 0x12: rp = &ssp->r0[t&3]; t = ssp->RAM0[*rp];
+ if (!(rST&7)) { (*rp)--; return t; }
+ add = -1; goto modulo;
+ case 0x13: return ssp->RAM0[2];
+ case 0x14:
+ case 0x15:
+ case 0x16: rp = &ssp->r1[t&3]; t = ssp->RAM1[*rp];
+ if (!(rST&7)) { (*rp)--; return t; }
+ add = -1; goto modulo;
+ case 0x17: return ssp->RAM1[2];
+ // mod=3 (11), "+"
+ case 0x18:
+ case 0x19:
+ case 0x1a: rp = &ssp->r0[t&3]; t = ssp->RAM0[*rp];
+ if (!(rST&7)) { (*rp)++; return t; }
+ add = 1; goto modulo;
+ case 0x1b: return ssp->RAM0[3];
+ case 0x1c:
+ case 0x1d:
+ case 0x1e: rp = &ssp->r1[t&3]; t = ssp->RAM1[*rp];
+ if (!(rST&7)) { (*rp)++; return t; }
+ add = 1; goto modulo;
+ case 0x1f: return ssp->RAM1[3];
+ }
+
+ return 0;
+
+modulo:
+ mask = (1 << (rST&7)) - 1;
+ *rp = (*rp & ~mask) | ((*rp + add) & mask);
+ return t;
+}
+
+static void ptr1_write(int op, u32 d)
+{
+ int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18);
+ switch (t)
+ {
+ // mod=0 (00)
+ case 0x00:
+ case 0x01:
+ case 0x02: ssp->RAM0[ssp->r0[t&3]] = d; return;
+ case 0x03: ssp->RAM0[0] = d; return;
+ case 0x04:
+ case 0x05:
+ case 0x06: ssp->RAM1[ssp->r1[t&3]] = d; return;
+ case 0x07: ssp->RAM1[0] = d; return;
+ // mod=1 (01), "+!"
+ // mod=3, "+"
+ case 0x08:
+ case 0x09:
+ case 0x0a: ssp->RAM0[ssp->r0[t&3]++] = d; return;
+ case 0x0b: ssp->RAM0[1] = d; return;
+ case 0x0c:
+ case 0x0d:
+ case 0x0e: ssp->RAM1[ssp->r1[t&3]++] = d; return;
+ case 0x0f: ssp->RAM1[1] = d; return;
+ // mod=2 (10), "-"
+ case 0x10:
+ case 0x11:
+ case 0x12: ssp->RAM0[ssp->r0[t&3]--] = d; CHECK_RPL(); return;
+ case 0x13: ssp->RAM0[2] = d; return;
+ case 0x14:
+ case 0x15:
+ case 0x16: ssp->RAM1[ssp->r1[t&3]--] = d; CHECK_RPL(); return;
+ case 0x17: ssp->RAM1[2] = d; return;
+ // mod=3 (11), "+"
+ case 0x18:
+ case 0x19:
+ case 0x1a: ssp->RAM0[ssp->r0[t&3]++] = d; CHECK_RPL(); return;
+ case 0x1b: ssp->RAM0[3] = d; return;
+ case 0x1c:
+ case 0x1d:
+ case 0x1e: ssp->RAM1[ssp->r1[t&3]++] = d; CHECK_RPL(); return;
+ case 0x1f: ssp->RAM1[3] = d; return;
+ }
+}
+
+static u32 ptr2_read(int op)
+{
+ int mv = 0, t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18);
+ switch (t)
+ {
+ // mod=0 (00)
+ case 0x00:
+ case 0x01:
+ case 0x02: mv = ssp->RAM0[ssp->r0[t&3]]++; break;
+ case 0x03: mv = ssp->RAM0[0]++; break;
+ case 0x04:
+ case 0x05:
+ case 0x06: mv = ssp->RAM1[ssp->r1[t&3]]++; break;
+ case 0x07: mv = ssp->RAM1[0]++; break;
+ // mod=1 (01)
+ case 0x0b: mv = ssp->RAM0[1]++; break;
+ case 0x0f: mv = ssp->RAM1[1]++; break;
+ // mod=2 (10)
+ case 0x13: mv = ssp->RAM0[2]++; break;
+ case 0x17: mv = ssp->RAM1[2]++; break;
+ // mod=3 (11)
+ case 0x1b: mv = ssp->RAM0[3]++; break;
+ case 0x1f: mv = ssp->RAM1[3]++; break;
+ default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: invalid mod in ((rX))? @ %04x", GET_PPC_OFFS());
+ return 0;
+ }
+
+ return ((unsigned short *)svp->iram_rom)[mv];
+}
+
+
+// -----------------------------------------------------
+
+#if defined(USE_DEBUGGER)
+static void debug_dump2file(const char *fname, void *mem, int len)
+{
+ FILE *f = fopen(fname, "wb");
+ unsigned short *p = mem;
+ int i;
+ if (f) {
+ for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8);
+ fwrite(mem, 1, len, f);
+ fclose(f);
+ for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8);
+ printf("dumped to %s\n", fname);
+ }
+ else
+ printf("dump failed\n");
+}
+#endif
+
+#ifdef USE_DEBUGGER
+static void debug_dump(void)
+{
+ printf("GR0: %04x X: %04x Y: %04x A: %08x\n", ssp->gr[SSP_GR0].h, rX, rY, ssp->gr[SSP_A].v);
+ printf("PC: %04x (%04x) P: %08x\n", GET_PC(), GET_PC() << 1, rP.v);
+ printf("PM0: %04x PM1: %04x PM2: %04x\n", rPM0, rPM1, rPM2);
+ printf("XST: %04x PM4: %04x PMC: %08x\n", rXST, rPM4, rPMC.v);
+ printf(" ST: %04x %c%c%c%c, GP0_0 %i, GP0_1 %i\n", rST, rST&SSP_FLAG_N?'N':'n', rST&SSP_FLAG_V?'V':'v',
+ rST&SSP_FLAG_Z?'Z':'z', rST&SSP_FLAG_L?'L':'l', (rST>>5)&1, (rST>>6)&1);
+ printf("STACK: %i %04x %04x %04x %04x %04x %04x\n", rSTACK, ssp->stack[0], ssp->stack[1],
+ ssp->stack[2], ssp->stack[3], ssp->stack[4], ssp->stack[5]);
+ printf("r0-r2: %02x %02x %02x r4-r6: %02x %02x %02x\n", rIJ[0], rIJ[1], rIJ[2], rIJ[4], rIJ[5], rIJ[6]);
+ elprintf(EL_SVP, "cycles: %i, emu_status: %x", g_cycles, ssp->emu_status);
+}
+
+static void debug_dump_mem(void)
+{
+ int h, i;
+ printf("RAM0\n");
+ for (h = 0; h < 32; h++)
+ {
+ if (h == 16) printf("RAM1\n");
+ printf("%03x:", h*16);
+ for (i = 0; i < 16; i++)
+ printf(" %04x", ssp->RAM[h*16+i]);
+ printf("\n");
+ }
+}
+
+static int bpts[10] = { 0, };
+
+static void debug(unsigned int pc, unsigned int op)
+{
+ static char buffo[64] = {0,};
+ char buff[64] = {0,};
+ int i;
+
+ if (running) {
+ for (i = 0; i < 10; i++)
+ if (pc != 0 && bpts[i] == pc) {
+ printf("breakpoint %i\n", i);
+ running = 0;
+ break;
+ }
+ }
+ if (running) return;
+
+ printf("%04x (%02x) @ %04x\n", op, op >> 9, pc<<1);
+
+ while (1)
+ {
+ printf("dbg> ");
+ fflush(stdout);
+ fgets(buff, sizeof(buff), stdin);
+ if (buff[0] == '\n') strcpy(buff, buffo);
+ else strcpy(buffo, buff);
+
+ switch (buff[0]) {
+ case 0: exit(0);
+ case 'c':
+ case 'r': running = 1; return;
+ case 's':
+ case 'n': return;
+ case 'x': debug_dump(); break;
+ case 'm': debug_dump_mem(); break;
+ case 'b': {
+ char *baddr = buff + 2;
+ i = 0;
+ if (buff[3] == ' ') { i = buff[2] - '0'; baddr = buff + 4; }
+ bpts[i] = strtol(baddr, NULL, 16) >> 1;
+ printf("breakpoint %i set @ %04x\n", i, bpts[i]<<1);
+ break;
+ }
+ case 'd':
+ sprintf(buff, "iramrom_%04x.bin", last_iram);
+ debug_dump2file(buff, svp->iram_rom, sizeof(svp->iram_rom));
+ debug_dump2file("dram.bin", svp->dram, sizeof(svp->dram));
+ break;
+ default: printf("unknown command\n"); break;
+ }
+ }
+}
+#endif // USE_DEBUGGER
+
+