notaz.gp2x.de
/
picodrive.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
added PicoGetStat() for win32
[picodrive.git]
/
Pico
/
carthw
/
svp
/
ssp16.c
diff --git
a/Pico/carthw/svp/ssp16.c
b/Pico/carthw/svp/ssp16.c
index
0f385ba
..
9f3ec31
100644
(file)
--- a/
Pico/carthw/svp/ssp16.c
+++ b/
Pico/carthw/svp/ssp16.c
@@
-1,8
+1,16
@@
// basic, incomplete SSP160x (SSP1601?) interpreter
// 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
/*
* Register info
- * most names taken from MAME code
*
* 0. "-"
* size: 16
*
* 0. "-"
* size: 16
@@
-10,11
+18,11
@@
*
* 1. "X"
* size: 16
*
* 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
*
* 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
*
* 3. "A"
* size: 32
@@
-58,8
+66,7
@@
*
* 7. "P"
* size: 32
*
* 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)
* 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.
* 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
*
* 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).
*
*
* (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.
*
* 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)
* + 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
*
* * 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)
* 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
*/
* '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 */ \
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.
}
// 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());
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;
}
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)
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);
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)]);
{
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)];
}
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?
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;
}
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?
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;
}
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?
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;
}
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?
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;
}
rPM2 = d;
}
@@
-626,7
+630,7
@@
static u32 read_PM4(void)
}
if (d != (u32)-1) return d;
// can be removed?
}
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;
}
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?
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;
}
rPM4 = d;
}
@@
-675,7
+679,7
@@
static void write_PMC(u32 d)
static u32 read_AL(void)
{
if (*(PC-1) == 0x000f) {
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;
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
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;
}
}
UPD_ACC_ZN // ?
}
break;
}
- //
??
?
+ //
mpys
?
case 0x1b:
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
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 cod
e checking flags after this
+ rA32 -= ssp->gr[SSP_P].v;
// maybe only upper word?
+
UPD_ACC_ZN // ther
e 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
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:
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
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:
// 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; // ?
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 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.
// 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());
default:
elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME unhandled op %04x @ %04x", op, GET_PPC_OFFS());