8 static u8int mode, bright, pixelpri[2];
9 static u32int pixelcol[2];
10 u16int vtime = 0x1ff, htime = 0x1ff, subcolor, mosatop;
11 uchar pic[256*239*2*9];
12 u16int m7[6], hofs[4], vofs[4];
14 enum { OBJ = 4, COL = 5, OBJNC = 8 };
27 return r << 10 | g << 5 | b;
31 pixeldraw(int x, int y, u16int v)
35 union { u16int w; u8int b[2]; } u;
41 p = pic + (x + y * 256) * 2;
49 q = (u16int*)pic + (x + y * 256 * 2) * 2;
56 q = (u16int*)pic + (x + y * 256 * 3) * 3;
57 for(i = 0; i < 3; i++){
71 a = reg[0x2123 + (n >> 1)];
74 if((a & (WIN1|WIN2)) == 0)
76 w1 = rx >= reg[0x2126] && rx <= reg[0x2127];
77 w2 = rx >= reg[0x2128] && rx <= reg[0x2129];
82 if((a & (WIN1|WIN2)) != (WIN1|WIN2))
83 return (a & WIN1) != 0 ? w1 : w2;
84 a = reg[0x212a + (n >> 2)] >> ((n & 3) << 1);
86 case 1: return w1 & w2;
87 case 2: return w1 ^ w2;
88 case 3: return w1 ^ w2 ^ 1;
94 pixel(int n, int v, int pri)
99 if((reg[TM] & a) != 0 && pri > pixelpri[0] && ((reg[TMW] & a) == 0 || !window(n))){
103 if((reg[TS] & a) != 0 && pri > pixelpri[1] && ((reg[TSW] & a) == 0 || !window(n))){
110 tile(int n, int tx, int ty)
117 ta = ((a & ~3) << 9) + ((tx & 0x1f) << 1) + ((ty & 0x1f) << 6);
119 ta += (tx & 0x20) << 6;
121 ta += (ty & 0x20) << (6 + (a & 1));
123 return t | vram[ta] << 8;
127 chr(int n, int nb, int sz, u16int t, int x, int y, u32int c[])
133 t += ((x >> 3 ^ t >> 14) & 1) + ((~t >> 11) & 16);
136 t += ((x >> 3 ^ t >> 14) & 1) + ((t >> 11) & 16);
138 if((t & 0x8000) != 0)
140 a = reg[0x210b + (n >> 1)];
145 a = (a << 13) + (t & 0x3ff) * 8 * nb + y * 2;
147 c[0] |= vram[a] << 8;
150 c[0] |= vram[a++] << 16;
151 c[0] |= vram[a] << 24;
155 c[1] |= vram[a] << 8;
157 c[1] |= vram[a++] << 16;
158 c[1] |= vram[a] << 24;
164 palette(int n, int p)
168 return p << 2 | n << 5;
185 if((reg[CGWSEL] & DIRCOL) != 0)
192 shift(u32int *c, int nb, int n, int d)
206 bgpixel(u32int *c, int nb, int d)
211 v = c[0] & 1 | c[0] >> 7 & 2;
213 v |= c[0] >> 14 & 4 | c[0] >> 21 & 8;
215 v |= c[1] << 4 & 16 | c[1] >> 3 & 32 | c[1] >> 10 & 64 | c[1] >> 17 & 128;
221 v = c[0] >> 7 & 1 | c[0] >> 14 & 2;
223 v |= c[0] >> 21 & 4 | c[0] >> 28 & 8;
225 v |= c[1] >> 3 & 16 | c[1] >> 10 & 32 | c[1] >> 17 & 64 | c[1] >> 24 & 128;
234 static struct bgctxt {
235 u8int sz, szsh, nb, pri[2];
236 u16int tx, ty, tnx, tny;
244 bginit(int n, int nb, int prilo, int prihi)
250 p->szsh = (reg[BGMODE] & (1<<(4+n))) != 0 ? 4 : 3;
257 if(reg[MOSAIC] != 0 && (reg[MOSAIC] & (1<<n)) != 0){
258 p->msz = (reg[MOSAIC] >> 4) + 1;
260 sx -= p->mx = sx % p->msz;
266 p->tx = sx >> p->szsh;
267 p->tnx = sx & (p->sz - 1);
268 p->ty = sy >> p->szsh;
269 p->tny = sy & (p->sz - 1);
270 p->t = tile(n, p->tx, p->ty);
271 chr(n, nb, p->sz, p->t, p->tnx, p->tny, p->c);
272 p->pal = palette(n, p->t >> 10 & 7);
274 shift(p->c, nb, p->tnx, p->t & 0x4000);
275 if(p->msz != 1 && p->mx != 0 && sx % p->msz == 0){
276 p->mv = bgpixel(p->c, nb, p->t & 0x4000);
277 if(p->tnx + p->mx >= 8){
281 shift(p->c, nb, p->mx - 1, p->t & 0x4000);
293 v = bgpixel(p->c, p->nb, p->t & 0x4000);
303 pixel(n, p->pal + v, p->pri[(p->t & 0x2000) != 0]);
304 if(++p->tnx == p->sz){
307 p->t = tile(n, p->tx, p->ty);
308 p->pal = palette(n, p->t >> 10 & 7);
310 if((p->tnx & 7) == 0)
311 chr(n, p->nb, p->sz, p->t, p->tnx, p->tny, p->c);
321 bginit(0, 2, 0x80, 0xb0);
322 bginit(1, 2, 0x71, 0xa1);
323 bginit(2, 2, 0x22, 0x52);
324 bginit(3, 2, 0x13, 0x43);
327 bginit(0, 4, 0x80, 0xb0);
328 bginit(1, 4, 0x71, 0xa1);
329 bginit(2, 2, 0x12, (reg[BGMODE] & 8) != 0 ? 0xd2 : 0x42);
332 bginit(0, 4, 0x40, 0xa0);
333 bginit(1, 4, 0x11, 0x71);
336 bginit(0, 8, 0x40, 0xa0);
337 bginit(1, 4, 0x11, 0x71);
340 bgctxts[0].sz = bgctxts[1].sz = 0;
341 if(bitch[mode]++ == 0)
342 print("bg mode %d not implemented\n", mode);
374 u8int y, i, c, sx, sy;
379 u8int sx, i, c, pal, pri;
382 static u32int ch[34];
383 static u8int *p, q, over;
387 8, 8, 16, 16, 8, 8, 32, 32,
388 8, 8, 64, 64, 16, 16, 32, 32,
389 16, 16, 64, 64, 32, 32, 64, 64,
390 16, 32, 32, 64, 16, 32, 32, 32
392 static u16int base[2];
393 u8int dy, v, col, pri0, pri1, prio;
402 sz = szs + ((reg[OBSEL] & 0xe0) >> 3);
403 base[0] = (reg[OBSEL] & 0x07) << 14;
404 base[1] = base[0] + (((reg[OBSEL] & 0x18) + 8) << 10);
410 q = (oam[512 + (rx >> 3)] >> (rx & 6)) & 3;
413 sp->sy = sz[(q & 2) + 1];
419 if(sp->x < -(short)sp->sx && sp->x != -256)
429 sp->t1 = base[sp->c & 1];
438 if((reg[OAMADDH] & 0x80) != 0)
442 for(i = 0, tp = t; i < m; i++, tp++){
444 if(dx < 0 || dx >= tp->sx)
447 if((tp->c & 0x40) != 0){
448 v = w & 1 | w >> 7 & 2 | w >> 14 & 4 | w >> 21 & 8;
451 v = w >> 7 & 1 | w >> 14 & 2 | w >> 21 & 4 | w >> 28 & 8;
456 nt = (tp->i - prio) & 0x7f;
457 if(v != 0 && nt < pri1){
464 pixel(OBJ, col, pri0);
469 for(sp = s + n - 1, tp = t + n - 1; sp >= s; sp--, tp--){
473 tp->pal = 0x80 | sp->c << 3 & 0x70;
474 tp->pri = 3 * (0x10 + (sp->c & 0x30));
483 if((sp->c & 0x80) != 0)
484 dy = sp->sy - 1 - dy;
485 a = sp->t0 | (dy & 7) << 1;
488 if((sp->c & 0x40) != 0){
490 for(i = 0; i < nt; i++){
491 if(cp < ch + nelem(ch)){
492 w = vram[sp->t1 | (a -= 16) & 0x1fff] << 16;
493 w |= vram[sp->t1 | (a + 1) & 0x1fff] << 24;
494 w |= vram[sp->t1 | (a -= 16) & 0x1fff] << 0;
495 w |= vram[sp->t1 | (a + 1) & 0x1fff] << 8;
502 for(i = 0; i < nt; i++){
503 if(cp < ch + nelem(ch)){
504 w = vram[sp->t1 | a & 0x1fff];
505 w |= vram[sp->t1 | ++a & 0x1fff] << 8;
506 w |= vram[sp->t1 | (a += 15) & 0x1fff] << 16;
507 w |= vram[sp->t1 | ++a & 0x1fff] << 24;
522 u16int v, w, r, g, b;
530 default: v = 1; break;
531 case 1: v = cw = window(COL); break;
532 case 2: v = !(cw = window(COL)); break;
533 case 3: v = 0; break;
536 if((pixelcol[0] & 0x10000) != 0)
539 v = cgram[pixelcol[0] & 0xff];
541 if((m2 & (1 << (pixelpri[0] & 0xf))) == 0)
543 switch((m >> 4) & 3){
545 case 1: if(cw < 0) cw = window(COL); if(!cw) return v; break;
546 case 2: if(cw < 0) cw = window(COL); if(cw) return v; break;
549 div = (m2 & 0x40) != 0;
551 if((pixelcol[1] & 0x10000) != 0)
554 w = cgram[pixelcol[1] & 0xff];
555 div = div && (pixelpri[1] & 0xf) != COL;
558 if((m2 & 0x80) != 0){
559 r = (v & 0x7c00) - (w & 0x7c00);
560 g = (v & 0x03e0) - (w & 0x03e0);
561 b = (v & 0x001f) - (w & 0x001f);
562 if(r > 0x7c00) r = 0;
563 if(g > 0x03e0) g = 0;
564 if(b > 0x001f) b = 0;
566 r = (r >> 1) & 0xfc00;
567 g = (g >> 1) & 0xffe0;
572 r = (v & 0x7c00) + (w & 0x7c00);
573 g = (v & 0x03e0) + (w & 0x03e0);
574 b = (v & 0x001f) + (w & 0x001f);
576 r = (r >> 1) & 0xfc00;
577 g = (g >> 1) & 0xffe0;
580 if(r > 0x7c00) r = 0x7c00;
581 if(g > 0x03e0) g = 0x03e0;
582 if(b > 0x001f) b = 0x001f;
592 mode = reg[BGMODE] & 7;
593 bright = reg[INIDISP] & 0xf;
594 yvbl = (reg[SETINI] & OVERSCAN) != 0 ? 0xf0 : 0xe1;
596 if(ppux >= XLEFT && ppux <= XRIGHT && ppuy < 0xf0){
598 if(ppuy < yvbl && (reg[INIDISP] & 0x80) == 0){
601 pixelcol[1] = 0x10000 | subcolor;
606 pixeldraw(rx, ppuy - 1, colormath());
608 pixeldraw(rx, ppuy - 1, ppuy >= yvbl ? 0x31c8 : 0);
611 if(ppux == 0x116 && ppuy <= yvbl)
613 if((reg[NMITIMEN] & HCNTIRQ) != 0 && htime == ppux && ((reg[NMITIMEN] & VCNTIRQ) == 0 || vtime == ppuy))
619 reg[RDNMI] &= ~VBLANK;
620 hdma = reg[0x420c]<<8;
626 reg[RDNMI] |= VBLANK;
627 if((reg[NMITIMEN] & VBLANK) != 0)
629 if((reg[NMITIMEN] & AUTOJOY) != 0){
632 reg[0x4218] = keylatch >> 16;
633 reg[0x4219] = keylatch >> 24;
634 keylatch = keylatch << 16 | 0xffff;
637 if((reg[NMITIMEN] & (HCNTIRQ|VCNTIRQ)) == VCNTIRQ && vtime == ppuy)