X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Pico%2Fcarthw%2Fsvp%2Fssp16.c;h=9f3ec31d515beb085b7f0b2a57b6a619f0597ac5;hb=8e5427a06854695302a879dba5f0cbb3886e7253;hp=0f385ba880730a80bcc11348c4e6cdbd513dc686;hpb=3554b0a44640c270d0a1650dbc7985f23da2fa92;p=picodrive.git diff --git a/Pico/carthw/svp/ssp16.c b/Pico/carthw/svp/ssp16.c index 0f385ba..9f3ec31 100644 --- a/Pico/carthw/svp/ssp16.c +++ b/Pico/carthw/svp/ssp16.c @@ -1,8 +1,16 @@ // basic, incomplete SSP160x (SSP1601?) interpreter +// with SVP memory controller + +// (c) Copyright 2008, Grazvydas "notaz" Ignotas +// Free for non-commercial use. + +// For commercial use, separate licencing terms must be obtained. + + +#include "../../PicoInt.h" /* * Register info - * most names taken from MAME code * * 0. "-" * size: 16 @@ -10,11 +18,11 @@ * * 1. "X" * size: 16 - * desc: Generic register. When set, updates P (P = X * Y * 2) ?? + * desc: Generic register. When set, updates P (P = X * Y * 2) * * 2. "Y" * size: 16 - * desc: Generic register. When set, updates P (P = X * Y * 2) ?? + * desc: Generic register. When set, updates P (P = X * Y * 2) * * 3. "A" * size: 32 @@ -58,8 +66,7 @@ * * 7. "P" * size: 32 - * desc: multiply result register. Updated after mp* instructions, - * or writes to X or Y (P = X * Y * 2) ?? + * desc: multiply result register. P = X * Y * 2 * probably affected by MACS bit in ST. * * 8. "PM0" (PM from PMAR name from Tasco's docs) @@ -102,10 +109,11 @@ * Reading the register also shifts it's state (from "waiting for * address" to "waiting for mode" and back). Reads always return * address related to last PMx register accressed. + * (note: addresses do not wrap). * * 15. "AL" * size: 16 - * desc: Accumulator Low. 16 least significant bits of accumulator (not 100% sure) + * desc: Accumulator Low. 16 least significant bits of accumulator. * (normally reading acc (ld X, A) you get 16 most significant bits). * * @@ -167,21 +175,15 @@ * 30fe06 - also sync related. * 30fe08 - job number [1-12] for SVP. 0 means no job. Set by 68k, read-cleared by SVP. * - * TODO: * + figure out if 'op A, P' is 32bit (nearly sure it is) - * * what exactly is AL? * * does mld, mpya load their operands into X and Y? * * OP simm * - * misc: - * pressing all buttons while resetting game will kick into test mode - * * Assumptions in this code * P is not directly writeable * flags correspond to full 32bit accumulator * only Z and N status flags are emulated (others unused by SVP) * modifiers for 'OP a, ri' are ignored (invalid?/not used by SVP) - * modifiers '+' and '+!' act the same (this is most likely wrong) * 'ld d, (a)' loads from program ROM */ @@ -250,7 +252,7 @@ case 0x00: cond = 1; break; /* always true */ \ case 0x50: cond = !((rST ^ (op<<5)) & SSP_FLAG_Z); break; /* Z matches f(?) bit */ \ case 0x70: cond = !((rST ^ (op<<7)) & SSP_FLAG_N); break; /* N matches f(?) bit */ \ - default:elprintf(EL_SVP, "ssp FIXME: unimplemented cond @ %04x", GET_PPC_OFFS()); break; \ + default:elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unimplemented cond @ %04x", GET_PPC_OFFS()); break; \ } // ops with accumulator. @@ -357,7 +359,7 @@ static void write_unknown(u32 d) static void write_ST(u32 d) { //if ((rST ^ d) & 0x0007) elprintf(EL_SVP, "ssp RPL %i -> %i @ %04x", rST&7, d&7, GET_PPC_OFFS()); - if ((rST ^ d) & 0x0f98) elprintf(EL_SVP, "ssp FIXME ST %04x -> %04x @ %04x", rST, d, GET_PPC_OFFS()); + if ((rST ^ d) & 0x0f98) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME ST %04x -> %04x @ %04x", rST, d, GET_PPC_OFFS()); rST = d; } @@ -462,7 +464,7 @@ static u32 pm_io(int reg, int write, u32 d) int mode = ssp->pmac_write[reg]&0xffff; int addr = ssp->pmac_write[reg]>>16; if ((mode & 0xb800) == 0xb800) - elprintf(EL_SVP, "ssp FIXME: mode %04x", mode); + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: mode %04x", mode); if ((mode & 0x43ff) == 0x0018) // DRAM { int inc = get_inc(mode); @@ -505,6 +507,8 @@ static u32 pm_io(int reg, int write, u32 d) { elprintf(EL_SVP, "ssp ROM r [%06x] %04x", CADDR, ((unsigned short *)Pico.rom)[addr|((mode&0xf)<<16)]); + if ((signed int)ssp->pmac_read[reg] >> 16 == -1) + ssp->pmac_read[reg]++; ssp->pmac_read[reg] += 1<<16; d = ((unsigned short *)Pico.rom)[addr|((mode&0xf)<<16)]; } @@ -560,7 +564,7 @@ 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_PPC_OFFS()); + elprintf(EL_SVP|EL_ANOMALY, "PM1 raw r %04x @ %04x", rPM1, GET_PPC_OFFS()); return rPM1; } @@ -569,7 +573,7 @@ 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_PPC_OFFS()); + elprintf(EL_SVP|EL_ANOMALY, "PM1 raw w %04x @ %04x", d, GET_PPC_OFFS()); rPM1 = d; } @@ -579,7 +583,7 @@ 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_PPC_OFFS()); + elprintf(EL_SVP|EL_ANOMALY, "PM2 raw r %04x @ %04x", rPM2, GET_PPC_OFFS()); return rPM2; } @@ -588,7 +592,7 @@ 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_PPC_OFFS()); + elprintf(EL_SVP|EL_ANOMALY, "PM2 raw w %04x @ %04x", d, GET_PPC_OFFS()); rPM2 = d; } @@ -626,7 +630,7 @@ static u32 read_PM4(void) } if (d != (u32)-1) return d; // can be removed? - elprintf(EL_SVP, "PM4 raw r %04x @ %04x", rPM4, GET_PPC_OFFS()); + elprintf(EL_SVP|EL_ANOMALY, "PM4 raw r %04x @ %04x", rPM4, GET_PPC_OFFS()); return rPM4; } @@ -635,7 +639,7 @@ static void write_PM4(u32 d) u32 r = pm_io(4, 1, d); if (r != (u32)-1) return; // can be removed? - elprintf(EL_SVP, "PM4 raw w %04x @ %04x", d, GET_PPC_OFFS()); + elprintf(EL_SVP|EL_ANOMALY, "PM4 raw w %04x @ %04x", d, GET_PPC_OFFS()); rPM4 = d; } @@ -675,7 +679,7 @@ static void write_PMC(u32 d) static u32 read_AL(void) { if (*(PC-1) == 0x000f) { - elprintf(EL_SVP|EL_ANOMALY, "ssp dummy PM assign %08x @ %04x", rPMC.v, GET_PPC_OFFS()); + elprintf(EL_SVP, "ssp dummy PM assign %08x @ %04x", rPMC.v, GET_PPC_OFFS()); ssp->emu_status &= ~(SSP_PMC_SET|SSP_PMC_HAVE_ADDR); // ? } return rAL; @@ -1074,29 +1078,26 @@ void ssp1601_run(int cycles) 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: elprintf(EL_SVP, "ssp FIXME: unhandled mod %i @ %04x", op&7, GET_PPC_OFFS()); + default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x", + op&7, GET_PPC_OFFS()); } UPD_ACC_ZN // ? } break; } - // ??? + // mpys? case 0x1b: -#if 0 - // very uncertain about this one. What about b? if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); read_P(); // update P - rA32 -= ssp->gr[SSP_P].v; // maybe only upper word? - // UPD_ACC_ZN // I've seen code checking flags after this + rA32 -= ssp->gr[SSP_P].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 -#endif break; // mpya (rj), (ri), b case 0x4b: - // dunno if this is correct. What about b? if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); read_P(); // update P rA32 += ssp->gr[SSP_P].v; // confirmed to be 32bit @@ -1107,7 +1108,6 @@ void ssp1601_run(int cycles) // mld (rj), (ri), b case 0x5b: - // dunno if this is correct. What about b? if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); rA32 = 0; rST &= 0x0fff; // ? @@ -1165,13 +1165,13 @@ void ssp1601_run(int cycles) case 0x79: tmpv = rIJ[IJind]; OP_EORA(tmpv); break; // OP simm - case 0x1c: OP_SUBA(op & 0xff); if (op&0x100) elprintf(EL_SVP, "FIXME: simm with upper bit set"); break; - case 0x3c: OP_CMPA(op & 0xff); if (op&0x100) elprintf(EL_SVP, "FIXME: simm with upper bit set"); break; - case 0x4c: OP_ADDA(op & 0xff); if (op&0x100) elprintf(EL_SVP, "FIXME: simm with upper bit set"); break; + case 0x1c: OP_SUBA(op & 0xff); if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); break; + case 0x3c: OP_CMPA(op & 0xff); if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); break; + case 0x4c: OP_ADDA(op & 0xff); if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); break; // MAME code only does LSB of top word, but this looks wrong to me. - case 0x5c: OP_ANDA(op & 0xff); if (op&0x100) elprintf(EL_SVP, "FIXME: simm with upper bit set"); break; - case 0x6c: OP_ORA (op & 0xff); if (op&0x100) elprintf(EL_SVP, "FIXME: simm with upper bit set"); break; - case 0x7c: OP_EORA(op & 0xff); if (op&0x100) elprintf(EL_SVP, "FIXME: simm with upper bit set"); break; + case 0x5c: OP_ANDA(op & 0xff); if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); break; + case 0x6c: OP_ORA (op & 0xff); if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); break; + case 0x7c: OP_EORA(op & 0xff); if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); break; default: elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME unhandled op %04x @ %04x", op, GET_PPC_OFFS());