void ssp1601_run()

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
}