+#define GET_PC_OFFS() ((unsigned int)PC - (unsigned int)Pico.rom)
+#define SET_PC(d) PC = (unsigned short *)Pico.rom + d
+
+#define REG_READ(r) (((r) <= 4) ? ssp->gr[r].h : read_handlers[r]())
+#define REG_WRITE(r,d) { \
+ int r1 = r; \
+ if (r1 > 4) write_handlers[r1](d); \
+ else if (r1 > 0) ssp->gr[r1].h = d; \
+}
+
+static ssp1601_t *ssp = NULL;
+static unsigned short *PC;
+static int g_cycles;
+
+// -----------------------------------------------------
+// register i/o handlers
+
+// 0-4, 13
+static u32 read_unknown(void)
+{
+ elprintf(EL_ANOMALY|EL_SVP, "ssp16: unknown read @ %04x", GET_PC_OFFS());
+ return 0;
+}
+
+static void write_unknown(u32 d)
+{
+ elprintf(EL_ANOMALY|EL_SVP, "ssp16: unknown write @ %04x", GET_PC_OFFS());
+}
+
+// 5
+static u32 read_STACK(void)
+{
+ u32 d = 0;
+ if (rSTACK < 6) {
+ d = ssp->stack[rSTACK];
+ rSTACK++;
+ } else
+ elprintf(EL_ANOMALY|EL_SVP, "ssp16: stack underflow! (%i) @ %04x", rSTACK, GET_PC_OFFS());
+ return d;
+}
+
+static void write_STACK(u32 d)
+{
+ if (rSTACK > 0) {
+ rSTACK--;
+ ssp->stack[rSTACK] = d;
+ } else
+ elprintf(EL_ANOMALY|EL_SVP, "ssp16: stack overflow! (%i) @ %04x", rSTACK, GET_PC_OFFS());
+}
+
+// 6
+static u32 read_PC(void)
+{
+ return GET_PC();
+}
+
+static void write_PC(u32 d)
+{
+ SET_PC(d);
+ g_cycles--;
+}
+
+// 7
+static u32 read_P(void)
+{
+ rP.v = (u32)rX * rY * 2;
+ return rP.h;
+}
+
+static u32 pm_io(int reg, int write, u32 d)
+{
+ if (ssp->emu_status & SSP_PMC_SET) {
+ elprintf(EL_SVP, "PM%i (%c) set to %08x @ %04x", reg, write ? 'w' : 'r', rPMC.v, GET_PC_OFFS());
+ ssp->pmac_read[write ? reg + 6 : reg] = rPMC.v;
+ ssp->emu_status &= ~SSP_PMC_SET;
+ return 0;
+ }
+
+ if (ssp->pmac_read[reg] != 0) {
+ elprintf(EL_SVP, "PM%i %c @ %04x", reg, write ? 'w' : 'r', GET_PC_OFFS());
+ // do something depending on mode
+ return 0;
+ }
+
+ return (u32)-1;
+}
+
+// 8
+static u32 read_PM0(void)
+{
+ u32 d = pm_io(0, 0, 0);
+ if (d != (u32)-1) return d;
+ elprintf(EL_SVP, "PM0 raw r %04x @ %04x", rPM0, GET_PC_OFFS());
+ return rPM0;
+}
+
+static void write_PM0(u32 d)
+{
+ u32 r = pm_io(0, 1, d);
+ if (r != (u32)-1) return;
+ elprintf(EL_SVP, "PM0 raw w %04x @ %04x", d, GET_PC_OFFS());
+ rPM0 = d;
+}
+
+// 9
+static u32 read_PM1(void)
+{
+ u32 d = pm_io(1, 0, 0);
+ if (d != (u32)-1) return d;
+ // can be removed?
+ elprintf(EL_SVP, "PM1 raw r %04x @ %04x", rPM1, GET_PC_OFFS());
+ return rPM0;
+}
+
+static void write_PM1(u32 d)
+{
+ u32 r = pm_io(1, 1, d);
+ if (r != (u32)-1) return;
+ // can be removed?
+ elprintf(EL_SVP, "PM1 raw w %04x @ %04x", d, GET_PC_OFFS());
+ rPM0 = d;
+}
+
+// 10
+static u32 read_PM2(void)
+{
+ u32 d = pm_io(2, 0, 0);
+ if (d != (u32)-1) return d;
+ // can be removed?
+ elprintf(EL_SVP, "PM2 raw r %04x @ %04x", rPM2, GET_PC_OFFS());
+ return rPM0;
+}
+
+static void write_PM2(u32 d)
+{
+ u32 r = pm_io(2, 1, d);
+ if (r != (u32)-1) return;
+ // can be removed?
+ elprintf(EL_SVP, "PM2 raw w %04x @ %04x", d, GET_PC_OFFS());
+ rPM0 = d;
+}
+
+// 11
+static u32 read_XST(void)
+{
+ // can be removed?
+ u32 d = pm_io(3, 0, 0);
+ if (d != (u32)-1) return d;
+
+ elprintf(EL_SVP, "XST raw r %04x @ %04x", rXST, GET_PC_OFFS());
+ return rPM0;
+}