shithub: riscv

Download patch

ref: f6a79e0acb5fc27ea4ac006300b7bd82a07fdd57
parent: d54a795c80421b015dc6d9e3adce25309875e87a
author: aiju <devnull@localhost>
date: Fri Mar 14 17:03:25 EDT 2014

games/snes: cpu bug fix and bg cleanup

--- a/sys/src/games/snes/cpu.c
+++ b/sys/src/games/snes/cpu.c
@@ -657,7 +657,7 @@
 		print("BRK PC=%.6x from PC=%.6x\n", curpc, lastpc);
 	lastpc = curpc;
 	if(trace)
-		print("%.6x %.2x A=%.4x X=%.4x Y=%.4x P=%.2x %.2x %x\n", curpc, op, rA, rX, rY, rP, rS, memread(0x05));
+		print("%.6x %.2x A=%.4x X=%.4x Y=%.4x P=%.2x %.2x\n", curpc, op, rA, rX, rY, rP, rS);
 	cyc = 0;
 	switch(op){
 	case 0x00: pc++; interrupt(BRK); return 8 - emu;
@@ -993,9 +993,10 @@
 			rX &= 0xff;
 			rY &= 0xff;
 			rS = rS & 0xff | 0x100;
+			rP |= 0x30;
 		}
 		rP &= ~1;
-		rP |= 0x30 | a;
+		rP |= a;
 		return 2;
 	case 0xFC: push16(pc+1); pc = absi(1); return 8+cyc;
 	case 0xFD: sbc(mem816(abso(0, 1), 0)); return 4+cyc;
--- a/sys/src/games/snes/ppu.c
+++ b/sys/src/games/snes/ppu.c
@@ -231,54 +231,68 @@
 	return v;
 }
 
+static struct bgctxt {
+	u8int sz, szsh, nb, pri[2];
+	u16int tx, ty, tnx, tny;
+	u16int t;
+	u32int c[2];
+	int pal;
+	u8int msz, mv, mx;
+} bgctxts[4];
+
 static void
-bg(int n, int nb, int prilo, int prihi)
+bginit(int n, int nb, int prilo, int prihi)
 {
-	static struct bg {
-		u8int sz, szsh;
-		u16int tx, ty, tnx, tny;
-		u16int t;
-		u32int c[2];
-		int pal;
-		u8int msz, mv, mx;
-	} bgs[4];
-	struct bg *p;
-	int v, sx, sy;
+	struct bgctxt *p;
+	int sx, sy;
 
-	p = bgs + n;
-	if(rx == 0){
-		p->szsh = (reg[BGMODE] & (1<<(4+n))) != 0 ? 4 : 3;
-		p->sz = 1<<p->szsh;
-		sx = hofs[n];
-		sy = vofs[n] + ppuy;
-		if(reg[MOSAIC] != 0 && (reg[MOSAIC] & (1<<n)) != 0){
-			p->msz = (reg[MOSAIC] >> 4) + 1;
-			if(p->msz != 1){
-				sx -= p->mx = sx % p->msz;
-				sy -= sy % p->msz;
-			}
-		}else
-			p->msz = 1;
-	redo:
-		p->tx = sx >> p->szsh;
-		p->tnx = sx & (p->sz - 1);
-		p->ty = sy >> p->szsh;
-		p->tny = sy & (p->sz - 1);
-		p->t = tile(n, p->tx, p->ty);
-		chr(n, nb, p->sz, p->t, p->tnx, p->tny, p->c);
-		p->pal = palette(n, p->t >> 10 & 7);
-		if(p->tnx != 0)
-			shift(p->c, nb, p->tnx, p->t & 0x4000);
-		if(p->msz != 1 && p->mx != 0 && sx % p->msz == 0){
-			p->mv = bgpixel(p->c, nb, p->t & 0x4000);
-			if(p->tnx + p->mx >= 8){
-				sx += p->mx;
-				goto redo;
-			}else if(p->mx > 1)
-				shift(p->c, nb, p->mx - 1, p->t & 0x4000);
+	p = bgctxts + n;
+	p->szsh = (reg[BGMODE] & (1<<(4+n))) != 0 ? 4 : 3;
+	p->sz = 1<<p->szsh;
+	p->nb = nb;
+	p->pri[0] = prilo;
+	p->pri[1] = prihi;
+	sx = hofs[n];
+	sy = vofs[n] + ppuy;
+	if(reg[MOSAIC] != 0 && (reg[MOSAIC] & (1<<n)) != 0){
+		p->msz = (reg[MOSAIC] >> 4) + 1;
+		if(p->msz != 1){
+			sx -= p->mx = sx % p->msz;
+			sy -= sy % p->msz;
 		}
+	}else
+		p->msz = 1;
+redo:
+	p->tx = sx >> p->szsh;
+	p->tnx = sx & (p->sz - 1);
+	p->ty = sy >> p->szsh;
+	p->tny = sy & (p->sz - 1);
+	p->t = tile(n, p->tx, p->ty);
+	chr(n, nb, p->sz, p->t, p->tnx, p->tny, p->c);
+	p->pal = palette(n, p->t >> 10 & 7);
+	if(p->tnx != 0)
+		shift(p->c, nb, p->tnx, p->t & 0x4000);
+	if(p->msz != 1 && p->mx != 0 && sx % p->msz == 0){
+		p->mv = bgpixel(p->c, nb, p->t & 0x4000);
+		if(p->tnx + p->mx >= 8){
+			sx += p->mx;
+			goto redo;
+		}else if(p->mx > 1)
+			shift(p->c, nb, p->mx - 1, p->t & 0x4000);
 	}
-	v = bgpixel(p->c, nb, p->t & 0x4000);
+
+}
+
+static void
+bg(int n)
+{
+	struct bgctxt *p;
+	u8int v;
+
+	p = bgctxts + n;
+	if(p->sz == 0)
+		return;
+	v = bgpixel(p->c, p->nb, p->t & 0x4000);
 	if(p->msz != 1)
 		if(p->mx++ == 0)
 			p->mv = v;
@@ -288,7 +302,7 @@
 			v = p->mv;
 		}
 	if(v != 0)
-		pixel(n, p->pal + v, (p->t & 0x2000) != 0 ? prihi : prilo);
+		pixel(n, p->pal + v, p->pri[(p->t & 0x2000) != 0]);
 	if(++p->tnx == p->sz){
 		p->tx++;
 		p->tnx = 0;
@@ -296,31 +310,36 @@
 		p->pal = palette(n, p->t >> 10 & 7);
 	}
 	if((p->tnx & 7) == 0)
-		chr(n, nb, p->sz, p->t, p->tnx, p->tny, p->c);
+		chr(n, p->nb, p->sz, p->t, p->tnx, p->tny, p->c);
 }
 
 static void
-bgs(void)
+bgsinit(void)
 {
 	static int bitch[8];
 
 	switch(mode){
 	case 0:
-		bg(0, 2, 0x80, 0xb0);
-		bg(1, 2, 0x71, 0xa1);
-		bg(2, 2, 0x22, 0x52);
-		bg(3, 2, 0x13, 0x43);
+		bginit(0, 2, 0x80, 0xb0);
+		bginit(1, 2, 0x71, 0xa1);
+		bginit(2, 2, 0x22, 0x52);
+		bginit(3, 2, 0x13, 0x43);
 		break;
 	case 1:
-		bg(0, 4, 0x80, 0xb0);
-		bg(1, 4, 0x71, 0xa1);
-		bg(2, 2, 0x12, (reg[BGMODE] & 8) != 0 ? 0xd2 : 0x42);
+		bginit(0, 4, 0x80, 0xb0);
+		bginit(1, 4, 0x71, 0xa1);
+		bginit(2, 2, 0x12, (reg[BGMODE] & 8) != 0 ? 0xd2 : 0x42);
 		break;
+	case 2:
+		bginit(0, 4, 0x40, 0xa0);
+		bginit(1, 4, 0x11, 0x71);
+		break;
 	case 3:
-		bg(0, 8, 0x40, 0xa0);
-		bg(1, 4, 0x11, 0x71);
+		bginit(0, 8, 0x40, 0xa0);
+		bginit(1, 4, 0x11, 0x71);
 		break;
 	default:
+		bgctxts[0].sz = bgctxts[1].sz = 0;
 		if(bitch[mode]++ == 0)
 			print("bg mode %d not implemented\n", mode);
 	}
@@ -327,6 +346,17 @@
 }
 
 static void
+bgs(void)
+{
+	bg(0);
+	bg(1);
+	if(mode <= 1){
+		bg(2);
+		bg(3);
+	}
+}
+
+static void
 sprites(void)
 {
 	static struct {
@@ -578,6 +608,8 @@
 			hdma = reg[0x420c]<<8;
 			flush();
 		}
+		if(ppuy < yvbl)
+			bgsinit();
 		if(ppuy == yvbl){
 			reg[RDNMI] |= VBLANK;
 			if((reg[NMITIMEN] & VBLANK) != 0)