games/md: add save game support, fix cpu bug
This commit is contained in:
parent
e30fc1fbdf
commit
838163670c
4 changed files with 108 additions and 6 deletions
|
@ -509,7 +509,7 @@ step(void)
|
||||||
int n, m, d;
|
int n, m, d;
|
||||||
static int cnt;
|
static int cnt;
|
||||||
|
|
||||||
if(0 && pc == 0x23000000){
|
if(0 && pc == 0x59500){
|
||||||
trace++;
|
trace++;
|
||||||
print("%x\n", curpc);
|
print("%x\n", curpc);
|
||||||
}
|
}
|
||||||
|
@ -552,7 +552,7 @@ step(void)
|
||||||
tim += 20;
|
tim += 20;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if((op & 0x13f) == 0x108){ /* MOVEP */
|
if((op & 0x138) == 0x108){ /* MOVEP */
|
||||||
a = ra[op & 7] + (s16int)fetch16();
|
a = ra[op & 7] + (s16int)fetch16();
|
||||||
switch(s){
|
switch(s){
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -829,7 +829,7 @@ step(void)
|
||||||
v = op >> 4 & 0xf;
|
v = op >> 4 & 0xf;
|
||||||
n = op & 7;
|
n = op & 7;
|
||||||
if(v == 4){ /* TRAP */
|
if(v == 4){ /* TRAP */
|
||||||
trap(op & 0xf, curpc);
|
trap(0x20 | op & 0xf, pc);
|
||||||
break;
|
break;
|
||||||
}else if(v == 5){
|
}else if(v == 5){
|
||||||
if((op & 8) == 0){ /* LINK */
|
if((op & 8) == 0){ /* LINK */
|
||||||
|
|
|
@ -14,6 +14,9 @@ extern u16int spc, scurpc;
|
||||||
extern u16int ram[32768];
|
extern u16int ram[32768];
|
||||||
extern u16int *prg;
|
extern u16int *prg;
|
||||||
extern int nprg;
|
extern int nprg;
|
||||||
|
extern u8int *sram;
|
||||||
|
extern u32int sramctl, sram0, sram1;
|
||||||
|
extern int savefd, saveclock;
|
||||||
|
|
||||||
extern int keys, scale;
|
extern int keys, scale;
|
||||||
|
|
||||||
|
@ -77,6 +80,17 @@ enum {
|
||||||
Z80DIV = 15,
|
Z80DIV = 15,
|
||||||
RATE = 44100,
|
RATE = 44100,
|
||||||
SAMPDIV = FREQ / RATE,
|
SAMPDIV = FREQ / RATE,
|
||||||
|
SAVEFREQ = FREQ / 4,
|
||||||
MILLION = 1000 * 1000,
|
MILLION = 1000 * 1000,
|
||||||
BILLION = 1000 * 1000 * 1000,
|
BILLION = 1000 * 1000 * 1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SRAM = 0x01,
|
||||||
|
BATTERY = 0x02,
|
||||||
|
ADDRMASK = 0x0c,
|
||||||
|
ADDRBOTH = 0x00,
|
||||||
|
ADDREVEN = 0x08,
|
||||||
|
ADDRODD = 0x0c,
|
||||||
|
SRAMEN = 0x10,
|
||||||
|
};
|
||||||
|
|
|
@ -11,10 +11,13 @@ int debug;
|
||||||
|
|
||||||
u16int *prg;
|
u16int *prg;
|
||||||
int nprg;
|
int nprg;
|
||||||
|
u8int *sram;
|
||||||
|
u32int sramctl, nsram, sram0, sram1;
|
||||||
|
int savefd = -1;
|
||||||
|
|
||||||
int keys;
|
int keys;
|
||||||
|
|
||||||
int dmaclock, vdpclock, z80clock, audioclock, ymclock;
|
int dmaclock, vdpclock, z80clock, audioclock, ymclock, saveclock;
|
||||||
|
|
||||||
int scale, paused;
|
int scale, paused;
|
||||||
QLock pauselock;
|
QLock pauselock;
|
||||||
|
@ -23,6 +26,30 @@ Rectangle picr;
|
||||||
Image *tmp, *bg;
|
Image *tmp, *bg;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
flushram(void)
|
||||||
|
{
|
||||||
|
if(savefd >= 0)
|
||||||
|
pwrite(savefd, sram, nsram, 0);
|
||||||
|
saveclock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
loadbat(char *file)
|
||||||
|
{
|
||||||
|
static char buf[512];
|
||||||
|
|
||||||
|
strncpy(buf, file, sizeof buf - 5);
|
||||||
|
strcat(buf, ".sav");
|
||||||
|
savefd = create(buf, ORDWR | OEXCL, 0666);
|
||||||
|
if(savefd < 0)
|
||||||
|
savefd = open(buf, ORDWR);
|
||||||
|
if(savefd < 0)
|
||||||
|
print("open: %r\n");
|
||||||
|
else
|
||||||
|
readn(savefd, sram, nsram);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
loadrom(char *file)
|
loadrom(char *file)
|
||||||
{
|
{
|
||||||
static uchar hdr[512], buf[4096];
|
static uchar hdr[512], buf[4096];
|
||||||
|
@ -61,6 +88,28 @@ loadrom(char *file)
|
||||||
v -= rc;
|
v -= rc;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
if(hdr[0x1b0] == 0x52 && hdr[0x1b1] == 0x41){
|
||||||
|
sramctl = SRAM | hdr[0x1b2] >> 1 & ADDRMASK;
|
||||||
|
if((hdr[0x1b2] & 0x40) != 0)
|
||||||
|
sramctl |= BATTERY;
|
||||||
|
sram0 = hdr[0x1b4] << 24 | hdr[0x1b5] << 16 | hdr[0x1b6] << 8 | hdr[0x1b7] & 0xfe;
|
||||||
|
sram1 = hdr[0x1b8] << 24 | hdr[0x1b9] << 16 | hdr[0x1ba] << 8 | hdr[0x1bb] | 1;
|
||||||
|
if(sram1 <= sram0){
|
||||||
|
print("SRAM of size <= 0?\n");
|
||||||
|
sramctl = 0;
|
||||||
|
}else{
|
||||||
|
nsram = sram1 - sram0;
|
||||||
|
if((sramctl & ADDRMASK) != ADDRBOTH)
|
||||||
|
nsram >>= 1;
|
||||||
|
sram = malloc(nsram);
|
||||||
|
if(sram == nil)
|
||||||
|
sysfatal("malloc: %r");
|
||||||
|
if((sramctl & BATTERY) != 0){
|
||||||
|
loadbat(file);
|
||||||
|
atexit(flushram);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -195,6 +244,13 @@ threadmain(int argc, char **argv)
|
||||||
ymstep();
|
ymstep();
|
||||||
ymclock -= YMDIV;
|
ymclock -= YMDIV;
|
||||||
}
|
}
|
||||||
|
if(saveclock > 0){
|
||||||
|
saveclock -= t;
|
||||||
|
if(saveclock <= 0){
|
||||||
|
saveclock = 0;
|
||||||
|
flushram();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ regread(u16int a)
|
||||||
return ctl[0] & 0xc0 | v & 0x3f;
|
return ctl[0] & 0xc0 | v & 0x3f;
|
||||||
case 0x0005:
|
case 0x0005:
|
||||||
case 0x0007:
|
case 0x0007:
|
||||||
return ctl[1] & 0xc0 | 0x3f;
|
return ctl[a-3>>1] & 0xc0 | 0x3f;
|
||||||
case 0x0009: case 0x000b: case 0x000d:
|
case 0x0009: case 0x000b: case 0x000d:
|
||||||
return ctl[a-3>>1];
|
return ctl[a-3>>1];
|
||||||
case 0x1101:
|
case 0x1101:
|
||||||
|
@ -65,6 +65,14 @@ regwrite(u16int a, u16int v)
|
||||||
}else
|
}else
|
||||||
z80bus &= ~RESET;
|
z80bus &= ~RESET;
|
||||||
return;
|
return;
|
||||||
|
case 0x30f1:
|
||||||
|
if((v & 1) != 0)
|
||||||
|
sramctl |= SRAMEN;
|
||||||
|
else
|
||||||
|
sramctl &= ~SRAMEN;
|
||||||
|
return;
|
||||||
|
case 0x30f3: case 0x30f5: case 0x30f7: case 0x30f9: case 0x30fb:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
sysfatal("write to 0xa1%.4x (pc=%#.6ux)", a, curpc);
|
sysfatal("write to 0xa1%.4x (pc=%#.6ux)", a, curpc);
|
||||||
}
|
}
|
||||||
|
@ -112,7 +120,14 @@ memread(u32int a)
|
||||||
u16int v;
|
u16int v;
|
||||||
|
|
||||||
switch(a >> 21 & 7){
|
switch(a >> 21 & 7){
|
||||||
case 0: case 1: return prg[(a % nprg) / 2];
|
case 0: case 1:
|
||||||
|
if((sramctl & SRAMEN) != 0 && a >= sram0 && a <= sram1)
|
||||||
|
switch(sramctl & ADDRMASK){
|
||||||
|
case ADDREVEN: return sram[(a - sram0) >> 1] << 8;
|
||||||
|
case ADDRODD: return sram[(a - sram0) >> 1];
|
||||||
|
case ADDRBOTH: return sram[a - sram0] << 8 | sram[a - sram0 + 1];
|
||||||
|
}
|
||||||
|
return prg[(a % nprg) / 2];
|
||||||
case 5:
|
case 5:
|
||||||
switch(a >> 16 & 0xff){
|
switch(a >> 16 & 0xff){
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
|
@ -186,6 +201,23 @@ memwrite(u32int a, u16int v, u16int m)
|
||||||
if(0 && (a & 0xe0fffe) == 0xe0df46)
|
if(0 && (a & 0xe0fffe) == 0xe0df46)
|
||||||
print("%x %x %x\n", curpc, v, m);
|
print("%x %x %x\n", curpc, v, m);
|
||||||
switch((a >> 21) & 7){
|
switch((a >> 21) & 7){
|
||||||
|
case 0: case 1:
|
||||||
|
if((sramctl & SRAMEN) != 0 && a >= sram0 && a <= sram1){
|
||||||
|
switch(sramctl & ADDRMASK){
|
||||||
|
case ADDREVEN: sram[(a - sram0) >> 1] = v >> 8; break;
|
||||||
|
case ADDRODD: sram[(a - sram0) >> 1] = v; break;
|
||||||
|
case ADDRBOTH:
|
||||||
|
if((m & 0xff00) == 0xff00)
|
||||||
|
sram[a - sram0] = v >> 8;
|
||||||
|
if((m & 0xff) == 0xff)
|
||||||
|
sram[a + 1 - sram0] = v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(saveclock == 0)
|
||||||
|
saveclock = SAVEFREQ;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
goto invalid;
|
||||||
case 5:
|
case 5:
|
||||||
switch(a >> 16 & 0xff){
|
switch(a >> 16 & 0xff){
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
|
|
Loading…
Reference in a new issue