in cores/genesis/core/cart_hw/svp/ssp16.c [1089:1332]
void ssp1601_run(int cycles)
{
SET_PC(rPC);
g_cycles = cycles;
do
{
int op;
u32 tmpv;
op = *PC++;
#ifdef USE_DEBUGGER
debug(GET_PC()-1, op);
#endif
switch (op >> 9)
{
/* ld d, s */
case 0x00:
if (op == 0) break; /* nop */
if (op == ((SSP_A<<4)|SSP_P)) { /* A <- P */
/* not sure. MAME claims that only hi word is transfered. */
read_P(); /* update P */
rA32 = rP.v;
}
else
{
tmpv = REG_READ(op & 0x0f);
REG_WRITE((op & 0xf0) >> 4, tmpv);
}
break;
/* ld d, (ri) */
case 0x01: tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); break;
/* ld (ri), s */
case 0x02: tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv); break;
/* ldi d, imm */
case 0x04: tmpv = *PC++; REG_WRITE((op & 0xf0) >> 4, tmpv); break;
/* ld d, ((ri)) */
case 0x05: tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); break;
/* ldi (ri), imm */
case 0x06: tmpv = *PC++; ptr1_write(op, tmpv); break;
/* ld adr, a */
case 0x07: ssp->mem.RAM[op & 0x1ff] = rA; break;
/* ld d, ri */
case 0x09: tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv); break;
/* ld ri, s */
case 0x0a: rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4); break;
/* ldi ri, simm */
case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f: rIJ[(op>>8)&7] = op; break;
/* call cond, addr */
case 0x24: {
int cond = 0;
COND_CHECK
if (cond) { int new_PC = *PC++; write_STACK(GET_PC()); write_PC(new_PC); }
else PC++;
break;
}
/* ld d, (a) */
case 0x25: tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv); break;
/* bra cond, addr */
case 0x26: {
int cond = 0;
COND_CHECK
if (cond) { int new_PC = *PC++; write_PC(new_PC); }
else PC++;
break;
}
/* mod cond, op */
case 0x48: {
int cond = 0;
COND_CHECK
if (cond) {
switch (op & 7) {
case 2: rA32 = (signed int)rA32 >> 1; break; /* shr (arithmetic) */
case 3: rA32 <<= 1; break; /* shl */
case 6: rA32 = -(signed int)rA32; break; /* neg */
case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; /* abs */
default:
#ifdef LOG_SVP
elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x",
op&7, GET_PPC_OFFS());
#endif
break;
}
UPD_ACC_ZN /* ? */
}
break;
}
/* mpys? */
case 0x1b:
#ifdef LOG_SVP
if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS());
#endif
read_P(); /* update P */
rA32 -= rP.v; /* maybe only upper word? */
UPD_ACC_ZN /* there checking flags after this */
rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */
rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */
break;
/* mpya (rj), (ri), b */
case 0x4b:
#ifdef LOG_SVP
if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS());
#endif
read_P(); /* update P */
rA32 += rP.v; /* confirmed to be 32bit */
UPD_ACC_ZN /* ? */
rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */
rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */
break;
/* mld (rj), (ri), b */
case 0x5b:
#ifdef LOG_SVP
if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS());
#endif
rA32 = 0;
rST &= 0x0fff; /* ? */
rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */
rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */
break;
/* OP a, s */
case 0x10: OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv); break;
case 0x30: OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv); break;
case 0x40: OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv); break;
case 0x50: OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv); break;
case 0x60: OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv); break;
case 0x70: OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv); break;
/* OP a, (ri) */
case 0x11: tmpv = ptr1_read(op); OP_SUBA(tmpv); break;
case 0x31: tmpv = ptr1_read(op); OP_CMPA(tmpv); break;
case 0x41: tmpv = ptr1_read(op); OP_ADDA(tmpv); break;
case 0x51: tmpv = ptr1_read(op); OP_ANDA(tmpv); break;
case 0x61: tmpv = ptr1_read(op); OP_ORA (tmpv); break;
case 0x71: tmpv = ptr1_read(op); OP_EORA(tmpv); break;
/* OP a, adr */
case 0x03: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_LDA (tmpv); break;
case 0x13: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_SUBA(tmpv); break;
case 0x33: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_CMPA(tmpv); break;
case 0x43: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ADDA(tmpv); break;
case 0x53: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ANDA(tmpv); break;
case 0x63: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ORA (tmpv); break;
case 0x73: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_EORA(tmpv); break;
/* OP a, imm */
case 0x14: tmpv = *PC++; OP_SUBA(tmpv); break;
case 0x34: tmpv = *PC++; OP_CMPA(tmpv); break;
case 0x44: tmpv = *PC++; OP_ADDA(tmpv); break;
case 0x54: tmpv = *PC++; OP_ANDA(tmpv); break;
case 0x64: tmpv = *PC++; OP_ORA (tmpv); break;
case 0x74: tmpv = *PC++; OP_EORA(tmpv); break;
/* OP a, ((ri)) */
case 0x15: tmpv = ptr2_read(op); OP_SUBA(tmpv); break;
case 0x35: tmpv = ptr2_read(op); OP_CMPA(tmpv); break;
case 0x45: tmpv = ptr2_read(op); OP_ADDA(tmpv); break;
case 0x55: tmpv = ptr2_read(op); OP_ANDA(tmpv); break;
case 0x65: tmpv = ptr2_read(op); OP_ORA (tmpv); break;
case 0x75: tmpv = ptr2_read(op); OP_EORA(tmpv); break;
/* OP a, ri */
case 0x19: tmpv = rIJ[IJind]; OP_SUBA(tmpv); break;
case 0x39: tmpv = rIJ[IJind]; OP_CMPA(tmpv); break;
case 0x49: tmpv = rIJ[IJind]; OP_ADDA(tmpv); break;
case 0x59: tmpv = rIJ[IJind]; OP_ANDA(tmpv); break;
case 0x69: tmpv = rIJ[IJind]; OP_ORA (tmpv); break;
case 0x79: tmpv = rIJ[IJind]; OP_EORA(tmpv); break;
/* OP simm */
case 0x1c:
OP_SUBA(op & 0xff);
#ifdef LOG_SVP
if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set");
#endif
break;
case 0x3c:
OP_CMPA(op & 0xff);
#ifdef LOG_SVP
if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set");
#endif
break;
case 0x4c:
OP_ADDA(op & 0xff);
#ifdef LOG_SVP
if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set");
#endif
break;
/* MAME code only does LSB of top word, but this looks wrong to me. */
case 0x5c:
OP_ANDA(op & 0xff);
#ifdef LOG_SVP
if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set");
#endif
break;
case 0x6c:
OP_ORA (op & 0xff);
#ifdef LOG_SVP
if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set");
#endif
break;
case 0x7c:
OP_EORA(op & 0xff);
#ifdef LOG_SVP
if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set");
#endif
break;
default:
#ifdef LOG_SVP
elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME unhandled op %04x @ %04x", op, GET_PPC_OFFS());
#endif
break;
}
}
while (--g_cycles > 0 && !(ssp->emu_status & SSP_WAIT_MASK));
read_P(); /* update P */
rPC = GET_PC();
#ifdef LOG_SVP
if (ssp->gr[SSP_GR0].v != 0xffff0000)
elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: REG 0 corruption! %08x", ssp->gr[SSP_GR0].v);
#endif
}