#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
int ppux, ppuy, rx;
-static u8int mode, bright, pixelpri[2];
+static u8int mode, bright, pixelpri[2], hires;
static u32int pixelcol[2];
-u16int vtime = 0x1ff, htime = 0x1ff, subcolor, mosatop;
-uchar pic[256*239*2*9];
-u16int m7[6], hofs[4], vofs[4];
+u16int vtime = 0x1ff, htime = 0x1ff, subcolor;
+u16int hofs[5], vofs[5];
+s16int m7[6];
-enum { OBJ = 4, COL = 5, OBJNC = 6 };
+enum {
+ M7A,
+ M7B,
+ M7C,
+ M7D,
+ M7X,
+ M7Y
+};
+
+enum { OBJ = 4, COL = 5, OBJNC = 8 };
static u16int
darken(u16int v)
}
static void
-pixeldraw(int x, int y, u16int v)
+pixeldraw(int x, int y, u16int v, int s)
{
- uchar *p;
- u16int *q;
+ u16int *p;
union { u16int w; u8int b[2]; } u;
- int i;
- if(bright != 0xf)
+ if(bright != 0xf && s >= 0)
v = darken(v);
- if(scale == 1){
- p = pic + (x + y * 256) * 2;
- *p++ = v;
- *p = v >> 8;
- return;
- }
+ p = (u16int *)pic + (x + y * 256) * scale;
u.b[0] = v;
u.b[1] = v >> 8;
- if(scale == 2){
- q = (u16int*)pic + (x + y * 256 * 2) * 2;
- *q++ = u.w;
- *q = u.w;
- q += 256 * 2 - 1;
- *q++ = u.w;
- *q = u.w;
- }else{
- q = (u16int*)pic + (x + y * 256 * 3) * 3;
- for(i = 0; i < 3; i++){
- *q++ = u.w;
- *q++ = u.w;
- *q = u.w;
- q += 256 * 3 - 2;
- }
+ switch(scale){
+ case 16: *p++ = u.w;
+ case 15: *p++ = u.w;
+ case 14: *p++ = u.w;
+ case 13: *p++ = u.w;
+ case 12: *p++ = u.w;
+ case 11: *p++ = u.w;
+ case 10: *p++ = u.w;
+ case 9: *p++ = u.w;
+ case 8: *p++ = u.w;
+ case 7: *p++ = u.w;
+ case 6: *p++ = u.w;
+ case 5: *p++ = u.w;
+ case 4: *p++ = u.w;
+ case 3: *p++ = u.w;
+ case 2: if(s < 1) *p++ = u.w;
+ default: *p = u.w;
}
}
}
static void
-pixel(int n, int v, int pri)
+npixel(int n, int v, int pri)
{
int a;
}
}
+static void
+spixel(int n, int v, int pri)
+{
+ int a;
+
+ a = 1<<n;
+ if((reg[TS] & a) != 0 && pri > pixelpri[1] && ((reg[TSW] & a) == 0 || !window(n))){
+ pixelcol[1] = v;
+ pixelpri[1] = pri;
+ }
+}
+
+static void
+mpixel(int n, int v, int pri)
+{
+ int a;
+
+ a = 1<<n;
+ if((reg[TM] & a) != 0 && pri > pixelpri[0] && ((reg[TMW] & a) == 0 || !window(n))){
+ pixelcol[0] = v;
+ pixelpri[0] = pri;
+ }
+}
+
+static void (*pixel)(int, int, int) = npixel;
+
static u16int
tile(int n, int tx, int ty)
{
}
static void
-chr(int n, int nb, int sz, u16int t, int x, int y, u32int c[])
+chr(int n, int nb, int w, int h, u16int t, int x, int y, u32int c[])
{
u16int a;
- if(sz == 16){
+ if(w == 16)
+ t += (x >> 3 ^ t >> 14) & 1;
+ if(h == 16){
if(y >= 8){
- t += ((x >> 3 ^ t >> 14) & 1) + ((~t >> 11) & 16);
+ t += (~t >> 11) & 16;
y -= 8;
}else
- t += ((x >> 3 ^ t >> 14) & 1) + ((t >> 11) & 16);
+ t += (t >> 11) & 16;
}
if((t & 0x8000) != 0)
y = 7 - y;
return v;
}
+static struct bgctxt {
+ u8int w, h, wsh, hsh, nb, pri[2];
+ u16int tx, ty, tnx, tny;
+ u16int t;
+ u32int c[2];
+ int pal;
+ u8int msz, mv, mx;
+ u16int otx, oty, otny;
+} 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;
-
- 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);
+ struct bgctxt *p;
+ int sx, sy;
+
+ p = bgctxts + n;
+ p->hsh = ((reg[BGMODE] & (1<<(4+n))) != 0) ? 4 : 3;
+ p->wsh = mode >= 5 ? 4 : p->hsh;
+ p->h = 1<<p->hsh;
+ p->w = 1<<p->wsh;
+ 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;
+ if(mode >= 5)
+ sx <<= 1;
+redo:
+ p->tx = sx >> p->wsh;
+ p->tnx = sx & (p->w - 1);
+ p->ty = sy >> p->hsh;
+ p->tny = sy & (p->h - 1);
+ p->t = tile(n, p->tx, p->ty);
+ chr(n, nb, p->w, p->h, p->t, p->tnx, p->tny, p->c);
+ p->pal = palette(n, p->t >> 10 & 7);
+ if((p->tnx & 7) != 0)
+ shift(p->c, nb, p->tnx & 7, 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;
+ v = bgpixel(p->c, p->nb, p->t & 0x4000);
if(p->msz != 1)
if(p->mx++ == 0)
p->mv = v;
v = p->mv;
}
if(v != 0)
- pixel(n, p->pal + v, (p->t & 0x2000) != 0 ? prihi : prilo);
- if(++p->tnx == p->sz){
+ pixel(n, p->pal + v, p->pri[(p->t & 0x2000) != 0]);
+ if(++p->tnx == p->w){
p->tx++;
p->tnx = 0;
p->t = tile(n, p->tx, p->ty);
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->w, p->h, p->t, p->tnx, p->tny, p->c);
}
static void
-bgs(void)
+optinit(void)
+{
+ struct bgctxt *p;
+
+ p = bgctxts + 2;
+ p->hsh = (reg[BGMODE] & (1<<6)) != 0 ? 4 : 3;
+ p->wsh = mode >= 5 ? 4 : p->hsh;
+ p->w = 1<<p->wsh;
+ p->h = 1<<p->hsh;
+ p->tnx = hofs[2] & (p->w - 1);
+ p->tx = hofs[2] >> p->wsh;
+ bgctxts[0].otx = bgctxts[1].otx = 0xffff;
+ bgctxts[0].oty = bgctxts[0].ty;
+ bgctxts[0].otny = bgctxts[0].tny;
+ bgctxts[1].oty = bgctxts[1].ty;
+ bgctxts[1].otny = bgctxts[1].tny;
+}
+
+static void
+opt(void)
+{
+ struct bgctxt *p;
+ u16int hval, vval;
+ int sx, sy;
+
+ p = bgctxts + 2;
+ if(++p->tnx == p->w){
+ if(mode == 4){
+ hval = tile(2, p->tx, vofs[2] >> p->hsh);
+ if((hval & 0x8000) != 0){
+ vval = hval;
+ hval = 0;
+ }else
+ vval = 0;
+ }else{
+ hval = tile(2, p->tx, vofs[2] >> p->hsh);
+ vval = tile(2, p->tx, (vofs[2]+8) >> p->hsh);
+ }
+ sx = (rx & ~7) + (hval & 0x1ff8);
+ sy = ppuy + (vval & 0x1fff);
+ if((vval & 0x2000) != 0){
+ bgctxts[0].oty = sy >> bgctxts[0].hsh;
+ bgctxts[0].otny = sy & (bgctxts[0].h - 1);
+ }else{
+ bgctxts[0].oty = bgctxts[0].ty;
+ bgctxts[0].otny = bgctxts[0].tny;
+ }
+ if((vval & 0x4000) != 0){
+ bgctxts[1].oty = sy >> bgctxts[1].hsh;
+ bgctxts[1].otny = sy & (bgctxts[1].h - 1);
+ }else{
+ bgctxts[1].oty = bgctxts[1].ty;
+ bgctxts[1].otny = bgctxts[1].tny;
+ }
+ if((hval & 0x2000) != 0)
+ bgctxts[0].otx = sx >> bgctxts[0].wsh;
+ else
+ bgctxts[0].otx = 0xffff;
+ if((hval & 0x4000) != 0)
+ bgctxts[1].otx = sx >> bgctxts[1].wsh;
+ else
+ bgctxts[1].otx = 0xffff;
+ p->tnx = 0;
+ p->tx++;
+ }
+}
+
+static void
+bgopt(int n)
+{
+ struct bgctxt *p;
+ u8int v;
+
+ p = bgctxts + n;
+ v = bgpixel(p->c, p->nb, p->t & 0x4000);
+ if(p->msz != 1)
+ if(p->mx++ == 0)
+ p->mv = v;
+ else{
+ if(p->mx == p->msz)
+ p->mx = 0;
+ v = p->mv;
+ }
+ if(v != 0)
+ pixel(n, p->pal + v, p->pri[(p->t & 0x2000) != 0]);
+ if(++p->tnx == p->w){
+ p->tx++;
+ p->tnx = 0;
+ }
+ if((p->tnx & 7) == 0){
+ p->t = tile(n, p->otx == 0xffff ? p->tx : p->otx, p->oty);
+ p->pal = palette(n, p->t >> 10 & 7);
+ chr(n, p->nb, p->w, p->h, p->t, p->tnx, p->otny, p->c);
+ }
+}
+
+struct bg7ctxt {
+ int x, y, x0, y0;
+ u8int msz, mx, mv;
+} b7[2];
+
+void
+calc7(void)
+{
+ s16int t;
+
+ if((reg[0x2105] & 7) != 7)
+ return;
+ t = hofs[4] - m7[M7X];
+ if((t & 0x2000) != 0)
+ t |= ~0x3ff;
+ else
+ t &= 0x3ff;
+ b7->x0 = (t * m7[M7A]) & ~63;
+ b7->y0 = (t * m7[M7C]) & ~63;
+ t = vofs[4] - m7[M7Y];
+ if((t & 0x2000) != 0)
+ t |= ~0x3ff;
+ else
+ t &= 0x3ff;
+ b7->x0 += (t * m7[M7B]) & ~63;
+ b7->y0 += (t * m7[M7D]) & ~63;
+ b7->x0 += m7[M7X] << 8;
+ b7->y0 += m7[M7Y] << 8;
+}
+
+static void
+bg7init(int n)
+{
+ u8int m, y;
+ struct bg7ctxt *p;
+
+ p = b7 + n;
+ m = reg[M7SEL];
+ y = ppuy;
+ p->msz = 1;
+ if((reg[MOSAIC] & 1) != 0){
+ p->msz = (reg[MOSAIC] >> 4) + 1;
+ if(p->msz != 1)
+ y -= y % p->msz;
+ }
+ if(n == 1)
+ if((reg[MOSAIC] & 2) != 0)
+ p->msz = (reg[MOSAIC] >> 4) + 1;
+ else
+ p->msz = 1;
+ if((m & 2) != 0)
+ y = 255 - y;
+ p->x = b7->x0 + ((m7[M7B] * y) & ~63);
+ p->y = b7->y0 + ((m7[M7D] * y) & ~63);
+ if((m & 1) != 0){
+ p->x += 255 * m7[M7A];
+ p->y += 255 * m7[M7C];
+ }
+}
+
+static void
+bg7(int n)
+{
+ u16int x, y;
+ u8int m, v, t;
+ struct bg7ctxt *p;
+
+ p = b7 + n;
+ m = reg[M7SEL];
+ x = p->x >> 8;
+ y = p->y >> 8;
+ if((m & 0x80) == 0){
+ x &= 1023;
+ y &= 1023;
+ }else if(x > 1023 || y > 1023){
+ if((m & 0x40) != 0){
+ t = 0;
+ goto lookup;
+ }
+ v = 0;
+ goto end;
+ }
+ t = vram[x >> 2 & 0xfe | y << 5 & 0x7f00];
+lookup:
+ v = vram[t << 7 | y << 4 & 0x70 | x << 1 & 0x0e | 1];
+end:
+ if(p->msz != 1){
+ if(p->mx == 0)
+ p->mv = v;
+ else
+ v = p->mv;
+ if(++p->mx == p->msz)
+ p->mx = 0;
+ }
+ if(n == 1){
+ if((v & 0x7f) != 0)
+ if((v & 0x80) != 0)
+ pixel(1, v & 0x7f, 0x71);
+ else
+ pixel(1, v, 0x11);
+ }else if(v != 0)
+ pixel(0, v, 0x40);
+ if((m & 1) != 0){
+ p->x -= m7[M7A];
+ p->y -= m7[M7C];
+ }else{
+ p->x += m7[M7A];
+ p->y += m7[M7C];
+ }
+}
+
+static void
+bgsinit(void)
{
static int bitch[8];
+ pixel = npixel;
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);
+ optinit();
break;
case 3:
- bg(0, 8, 0x40, 0xa0);
- bg(1, 4, 0x11, 0x71);
+ bginit(0, 8, 0x40, 0xa0);
+ bginit(1, 4, 0x11, 0x71);
+ break;
+ case 4:
+ bginit(0, 8, 0x40, 0xa0);
+ bginit(1, 2, 0x11, 0x71);
+ optinit();
+ break;
+ case 5:
+ bginit(0, 4, 0x40, 0xa0);
+ bginit(1, 2, 0x11, 0x71);
+ break;
+ case 6:
+ bginit(0, 4, 0x40, 0xa0);
+ optinit();
+ break;
+ case 7:
+ bg7init(0);
+ if((reg[SETINI] & EXTBG) != 0)
+ bg7init(1);
break;
default:
+ bgctxts[0].w = bgctxts[1].w = 0;
if(bitch[mode]++ == 0)
print("bg mode %d not implemented\n", mode);
}
}
+static void
+bgs(void)
+{
+ switch(mode){
+ case 0:
+ bg(0);
+ bg(1);
+ bg(2);
+ bg(3);
+ break;
+ case 1:
+ bg(0);
+ bg(1);
+ bg(2);
+ break;
+ case 2:
+ case 4:
+ opt();
+ bgopt(0);
+ bgopt(1);
+ break;
+ case 3:
+ bg(0);
+ bg(1);
+ break;
+ case 5:
+ pixel = spixel;
+ bg(0);
+ bg(1);
+ pixel = mpixel;
+ bg(0);
+ bg(1);
+ pixel = npixel;
+ break;
+ case 6:
+ opt();
+ pixel = spixel;
+ bgopt(0);
+ pixel = mpixel;
+ bgopt(0);
+ pixel = npixel;
+ break;
+ case 7:
+ bg7(0);
+ if((reg[SETINI] & EXTBG) != 0)
+ bg7(1);
+ break;
+ }
+}
+
static void
sprites(void)
{
u32int *ch;
} t[32], *tp;
static u32int ch[34];
- static u8int *p, q, over;
+ static u8int *p, q;
static int n, m;
static int *sz;
static int szs[] = {
if(rx == 0){
n = 0;
- over = 1;
sp = s;
sz = szs + ((reg[OBSEL] & 0xe0) >> 3);
base[0] = (reg[OBSEL] & 0x07) << 14;
sp->x = p[0];
if((q & 1) != 0)
sp->x |= 0xff00;
- if(sp->x < -(short)sp->sx && sp->x != -256)
+ if(sp->x <= -(short)sp->sx && sp->x != -256)
goto nope;
if(n == 32){
- over |= 0x40;
+ reg[0x213e] |= 0x40;
goto nope;
}
sp->i = rx >> 1;
a = sp->t0 | (dy & 7) << 1;
if(dy >= 8)
a += (dy & ~7) << 6;
+ if(sp->x < 0 && (i = (-sp->x >> 3)) != 0){
+ if((sp->c & 0x40) != 0)
+ a -= i << 5;
+ else
+ a += i << 5;
+ nt -= i;
+ tp->sx += i << 3;
+ }
if((sp->c & 0x40) != 0){
a += sp->sx * 4;
for(i = 0; i < nt; i++){
*cp++ = w;
tp->sx += 8;
}else
- over |= 0x80;
+ reg[0x213e] |= 0x80;
}
}else
for(i = 0; i < nt; i++){
tp->sx += 8;
a += 15;
}else
- over |= 0x80;
+ reg[0x213e] |= 0x80;
}
+ if(sp->x < 0 && (i = (-sp->x) & 7) != 0)
+ if((sp->c & 0x40) != 0)
+ *tp->ch >>= i;
+ else
+ *tp->ch <<= i;
}
- reg[0x213e] = over;
}
}
static u16int
-colormath(void)
+colormath(int n)
{
u16int v, w, r, g, b;
- u8int m, m2;
+ u8int m, m2, div;
int cw;
m = reg[CGWSEL];
case 3: v = 0; break;
}
if(v){
- if((pixelcol[0] & 0x10000) != 0)
- v = pixelcol[0];
+ if((pixelcol[n] & 0x10000) != 0)
+ v = pixelcol[n];
else
- v = cgram[pixelcol[0] & 0xff];
+ v = cgram[pixelcol[n] & 0xff];
}
- if((m2 & (1 << (pixelpri[0] & 0xf))) == 0)
+ if((m2 & (1 << (pixelpri[n] & 0xf))) == 0)
return v;
switch((m >> 4) & 3){
case 0: break;
case 2: if(cw < 0) cw = window(COL); if(cw) return v; break;
default: return v;
}
+ div = (m2 & 0x40) != 0;
if((m & 2) != 0){
- if((pixelcol[1] & 0x10000) != 0)
- w = pixelcol[1];
+ if((pixelcol[1-n] & 0x10000) != 0)
+ w = pixelcol[1-n];
else
- w = cgram[pixelcol[1] & 0xff];
+ w = cgram[pixelcol[1-n] & 0xff];
+ div = div && (pixelpri[1-n] & 0xf) != COL;
}else
w = subcolor;
if((m2 & 0x80) != 0){
r = (v & 0x7c00) - (w & 0x7c00);
g = (v & 0x03e0) - (w & 0x03e0);
b = (v & 0x001f) - (w & 0x001f);
- if((m2 & 0x40) != 0){
+ if(r > 0x7c00) r = 0;
+ if(g > 0x03e0) g = 0;
+ if(b > 0x001f) b = 0;
+ if(div){
r = (r >> 1) & 0xfc00;
g = (g >> 1) & 0xffe0;
b >>= 1;
}
- if(r > 0x7c00) r = 0;
- if(g > 0x03e0) g = 0;
- if(b > 0x001f) b = 0;
return r | g | b;
}else{
r = (v & 0x7c00) + (w & 0x7c00);
g = (v & 0x03e0) + (w & 0x03e0);
b = (v & 0x001f) + (w & 0x001f);
- if((m2 & 0x40) != 0){
+ if(div){
r = (r >> 1) & 0xfc00;
g = (g >> 1) & 0xffe0;
b >>= 1;
mode = reg[BGMODE] & 7;
bright = reg[INIDISP] & 0xf;
+ hires = mode >= 5 && mode < 7 || (reg[SETINI] & 8) != 0;
yvbl = (reg[SETINI] & OVERSCAN) != 0 ? 0xf0 : 0xe1;
if(ppux >= XLEFT && ppux <= XRIGHT && ppuy < 0xf0){
bgs();
sprites();
if(ppuy != 0)
- pixeldraw(rx, ppuy - 1, colormath());
+ if(hires){
+ pixeldraw(rx, ppuy - 1, colormath(1), 0);
+ pixeldraw(rx, ppuy - 1, colormath(0), 1);
+ }else
+ pixeldraw(rx, ppuy - 1, colormath(0), 0);
}else if(ppuy != 0)
- pixeldraw(rx, ppuy - 1, ppuy >= yvbl ? 0x31c8 : 0);
+ pixeldraw(rx, ppuy - 1, ppuy >= yvbl ? 0x6739 : 0, -1);
}
+ if(ppux == 134)
+ cpupause = 1;
if(ppux == 0x116 && ppuy <= yvbl)
hdma |= reg[0x420c];
- if((reg[NMITIMEN] & HCNTIRQ) != 0 && htime == ppux && ((reg[NMITIMEN] & VCNTIRQ) == 0 || vtime == ppuy))
+ if((reg[NMITIMEN] & HCNTIRQ) != 0 && htime+4 == ppux && ((reg[NMITIMEN] & VCNTIRQ) == 0 || vtime == ppuy))
irq |= IRQPPU;
if(++ppux >= 340){
ppux = 0;
if(++ppuy >= 262){
ppuy = 0;
reg[RDNMI] &= ~VBLANK;
+ reg[0x213e] = 1;
+ reg[0x213f] ^= 0x80;
hdma = reg[0x420c]<<8;
flush();
}
+ if(ppuy < yvbl)
+ bgsinit();
if(ppuy == yvbl){
reg[RDNMI] |= VBLANK;
if((reg[NMITIMEN] & VBLANK) != 0)
nmi = 2;
+ if((reg[INIDISP] & 0x80) == 0)
+ oamaddr = reg[0x2102] << 1 | (reg[0x2103] & 1) << 9;
if((reg[NMITIMEN] & AUTOJOY) != 0){
memwrite(0x4016, 1);
memwrite(0x4016, 0);