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)