shithub: riscv

Download patch

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();
 		}
 	}