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 = 6 };
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;
235 bg(int n, int nb, int prilo, int prihi)
239 u16int tx, ty, tnx, tny;
250 p->szsh = (reg[BGMODE] & (1<<(4+n))) != 0 ? 4 : 3;
254 if(reg[MOSAIC] != 0 && (reg[MOSAIC] & (1<<n)) != 0){
255 p->msz = (reg[MOSAIC] >> 4) + 1;
257 sx -= p->mx = sx % p->msz;
263 p->tx = sx >> p->szsh;
264 p->tnx = sx & (p->sz - 1);
265 p->ty = sy >> p->szsh;
266 p->tny = sy & (p->sz - 1);
267 p->t = tile(n, p->tx, p->ty);
268 chr(n, nb, p->sz, p->t, p->tnx, p->tny, p->c);
269 p->pal = palette(n, p->t >> 10 & 7);
271 shift(p->c, nb, p->tnx, p->t & 0x4000);
272 if(p->msz != 1 && p->mx != 0 && sx % p->msz == 0){
273 p->mv = bgpixel(p->c, nb, p->t & 0x4000);
274 if(p->tnx + p->mx >= 8){
278 shift(p->c, nb, p->mx - 1, p->t & 0x4000);
281 v = bgpixel(p->c, nb, p->t & 0x4000);
291 pixel(n, p->pal + v, (p->t & 0x2000) != 0 ? prihi : prilo);
292 if(++p->tnx == p->sz){
295 p->t = tile(n, p->tx, p->ty);
296 p->pal = palette(n, p->t >> 10 & 7);
298 if((p->tnx & 7) == 0)
299 chr(n, nb, p->sz, p->t, p->tnx, p->tny, p->c);
309 bg(0, 2, 0x80, 0xb0);
310 bg(1, 2, 0x71, 0xa1);
311 bg(2, 2, 0x22, 0x52);
312 bg(3, 2, 0x13, 0x43);
315 bg(0, 4, 0x80, 0xb0);
316 bg(1, 4, 0x71, 0xa1);
317 bg(2, 2, 0x12, (reg[BGMODE] & 8) != 0 ? 0xd2 : 0x42);
320 if(bitch[mode]++ == 0)
321 print("bg mode %d not implemented\n", mode);
330 u8int y, i, c, sx, sy;
335 u8int sx, i, c, pal, pri;
338 static u32int ch[34];
339 static u8int *p, q, over;
343 8, 8, 16, 16, 8, 8, 32, 32,
344 8, 8, 64, 64, 16, 16, 32, 32,
345 16, 16, 64, 64, 32, 32, 64, 64,
346 16, 32, 32, 64, 16, 32, 32, 32
348 static u16int base[2];
349 u8int dy, v, col, pri0, pri1, prio;
358 sz = szs + ((reg[OBSEL] & 0xe0) >> 3);
359 base[0] = (reg[OBSEL] & 0x07) << 14;
360 base[1] = base[0] + (((reg[OBSEL] & 0x18) + 8) << 10);
366 q = (oam[512 + (rx >> 3)] >> (rx & 6)) & 3;
369 sp->sy = sz[(q & 2) + 1];
375 if(sp->x < -(short)sp->sx && sp->x != -256)
385 sp->t1 = base[sp->c & 1];
394 if((reg[OAMADDH] & 0x80) != 0)
398 for(i = 0, tp = t; i < m; i++, tp++){
400 if(dx < 0 || dx >= tp->sx)
403 if((tp->c & 0x40) != 0){
404 v = w & 1 | w >> 7 & 2 | w >> 14 & 4 | w >> 21 & 8;
407 v = w >> 7 & 1 | w >> 14 & 2 | w >> 21 & 4 | w >> 28 & 8;
412 nt = (tp->i - prio) & 0x7f;
413 if(v != 0 && nt < pri1){
420 pixel(OBJ, col, pri0);
425 for(sp = s + n - 1, tp = t + n - 1; sp >= s; sp--, tp--){
429 tp->pal = 0x80 | sp->c << 3 & 0x70;
430 tp->pri = 3 * (0x10 + (sp->c & 0x30));
439 if((sp->c & 0x80) != 0)
440 dy = sp->sy - 1 - dy;
441 a = sp->t0 | (dy & 7) << 1;
444 if((sp->c & 0x40) != 0){
446 for(i = 0; i < nt; i++){
447 if(cp < ch + nelem(ch)){
448 w = vram[sp->t1 | (a -= 16) & 0x1fff] << 16;
449 w |= vram[sp->t1 | (a + 1) & 0x1fff] << 24;
450 w |= vram[sp->t1 | (a -= 16) & 0x1fff] << 0;
451 w |= vram[sp->t1 | (a + 1) & 0x1fff] << 8;
458 for(i = 0; i < nt; i++){
459 if(cp < ch + nelem(ch)){
460 w = vram[sp->t1 | a & 0x1fff];
461 w |= vram[sp->t1 | ++a & 0x1fff] << 8;
462 w |= vram[sp->t1 | (a += 15) & 0x1fff] << 16;
463 w |= vram[sp->t1 | ++a & 0x1fff] << 24;
478 u16int v, w, r, g, b;
486 default: v = 1; break;
487 case 1: v = cw = window(COL); break;
488 case 2: v = !(cw = window(COL)); break;
489 case 3: v = 0; break;
492 if((pixelcol[0] & 0x10000) != 0)
495 v = cgram[pixelcol[0] & 0xff];
497 if((m2 & (1 << (pixelpri[0] & 0xf))) == 0)
499 switch((m >> 4) & 3){
501 case 1: if(cw < 0) cw = window(COL); if(!cw) return v; break;
502 case 2: if(cw < 0) cw = window(COL); if(cw) return v; break;
506 if((pixelcol[1] & 0x10000) != 0)
509 w = cgram[pixelcol[1] & 0xff];
512 if((m2 & 0x80) != 0){
513 r = (v & 0x7c00) - (w & 0x7c00);
514 g = (v & 0x03e0) - (w & 0x03e0);
515 b = (v & 0x001f) - (w & 0x001f);
516 if((m2 & 0x40) != 0){
517 r = (r >> 1) & 0xfc00;
518 g = (g >> 1) & 0xffe0;
521 if(r > 0x7c00) r = 0;
522 if(g > 0x03e0) g = 0;
523 if(b > 0x001f) b = 0;
526 r = (v & 0x7c00) + (w & 0x7c00);
527 g = (v & 0x03e0) + (w & 0x03e0);
528 b = (v & 0x001f) + (w & 0x001f);
529 if((m2 & 0x40) != 0){
530 r = (r >> 1) & 0xfc00;
531 g = (g >> 1) & 0xffe0;
534 if(r > 0x7c00) r = 0x7c00;
535 if(g > 0x03e0) g = 0x03e0;
536 if(b > 0x001f) b = 0x001f;
546 mode = reg[BGMODE] & 7;
547 bright = reg[INIDISP] & 0xf;
548 yvbl = (reg[SETINI] & OVERSCAN) != 0 ? 0xf0 : 0xe1;
550 if(ppux >= XLEFT && ppux <= XRIGHT && ppuy < 0xf0){
552 if(ppuy < yvbl && (reg[INIDISP] & 0x80) == 0){
555 pixelcol[1] = 0x10000 | subcolor;
560 pixeldraw(rx, ppuy - 1, colormath());
562 pixeldraw(rx, ppuy - 1, ppuy >= yvbl ? 0x31c8 : 0);
565 if(ppux == 0x116 && ppuy <= yvbl)
567 if((reg[NMITIMEN] & HCNTIRQ) != 0 && htime == ppux && ((reg[NMITIMEN] & VCNTIRQ) == 0 || vtime == ppuy))
573 reg[RDNMI] &= ~VBLANK;
574 hdma = reg[0x420c]<<8;
578 reg[RDNMI] |= VBLANK;
579 if((reg[NMITIMEN] & VBLANK) != 0)
581 if((reg[NMITIMEN] & AUTOJOY) != 0){
584 reg[0x4218] = keylatch >> 16;
585 reg[0x4219] = keylatch >> 24;
586 keylatch = keylatch << 16 | 0xffff;
589 if((reg[NMITIMEN] & (HCNTIRQ|VCNTIRQ)) == VCNTIRQ && vtime == ppuy)