ref: 142858b176c3b3a256389e1c700b78ba89e85e69
parent: 88405371b1bcdc2e03eb7559ff2e993949c9b5a7
author: aiju <devnull@localhost>
date: Sun Mar 2 07:24:07 EST 2014
games/nes: SUROM support, subtle NMI timing bug fixed
--- a/sys/src/games/nes/cpu.c
+++ b/sys/src/games/nes/cpu.c
@@ -244,11 +244,12 @@
u16int a, v;
int c;
- if(nmi){
- interrupt(1, 0);
- nmi = 0;
- return 7;
- }
+ if(nmi)
+ if(--nmi == 0){
+ interrupt(1, 0);
+ nmi = 0;
+ return 7;
+ }
if(irq && (rP & 4) == 0){
interrupt(0, 0);
return 7;
@@ -256,7 +257,7 @@
curpc = pc;
op = fetch8();
if(trace)
- print("%x %x %x %x %x %x %x %x\n", curpc, op, rA, rX, rY, rS, rP, memread(0x2c));
+ print("%x %x %x %x %x %x %x\n", curpc, op, rA, rX, rY, rS, rP);
switch(op){
case 0x00: pc++; interrupt(0, 1); return 7;
case 0x01: nz(rA |= indX()); return 6;
--- a/sys/src/games/nes/mem.c
+++ b/sys/src/games/nes/mem.c
@@ -54,6 +54,8 @@
if(v < 0){
switch(v){
case INIT:
+ if(nprg > 32)
+ sysfatal("bad rom, too much prg rom for mmc1");
mode = 0x0C;
prgsh = 14;
chrsh = 12;
@@ -99,6 +101,10 @@
mirr = mirrs[mode & 3];
break;
case 0xA000:
+ if(nprg > 16){
+ pr = s & 0x10 | pr & 0x0f;
+ pr %= nprg;
+ }
c0 = s & 0x1f;
c0 %= 2*nchr;
break;
@@ -107,7 +113,7 @@
c1 %= 2*nchr;
break;
case 0xE000:
- pr = s & 0x0f;
+ pr = pr & 0x10 | s & 0x0f;
pr %= nprg;
break;
}
@@ -121,7 +127,7 @@
break;
case 0x0C:
prgb[0] = prg + pr * 0x4000;
- prgb[1] = prg + (0x0f % nprg) * 0x4000;
+ prgb[1] = prg + ((pr & 0x10 | 0x0f) % nprg) * 0x4000;
break;
default:
prgb[0] = prg + (pr & 0xfe) * 0x4000;
--- a/sys/src/games/nes/nes.c
+++ b/sys/src/games/nes/nes.c
@@ -93,7 +93,7 @@
if(readn(fd, chr, nchr * CHRSZ) < nchr * CHRSZ)
sysfatal("read: %r");
}else{
- nchr = 16;
+ nchr = 1;
chr = malloc(nchr * CHRSZ);
if(chr == nil)
sysfatal("malloc: %r");
--- a/sys/src/games/nes/ppu.c
+++ b/sys/src/games/nes/ppu.c
@@ -326,7 +326,7 @@
if(ppux == 1){
mem[PPUSTATUS] |= PPUVBLANK;
if((mem[PPUCTRL] & PPUNMI) != 0)
- nmi = 1;
+ nmi = 2;
flush();
}
}