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 bg(0, 8, 0x40, 0xa0);
321 bg(1, 4, 0x11, 0x71);
324 if(bitch[mode]++ == 0)
325 print("bg mode %d not implemented\n", mode);
334 u8int y, i, c, sx, sy;
339 u8int sx, i, c, pal, pri;
342 static u32int ch[34];
343 static u8int *p, q, over;
347 8, 8, 16, 16, 8, 8, 32, 32,
348 8, 8, 64, 64, 16, 16, 32, 32,
349 16, 16, 64, 64, 32, 32, 64, 64,
350 16, 32, 32, 64, 16, 32, 32, 32
352 static u16int base[2];
353 u8int dy, v, col, pri0, pri1, prio;
362 sz = szs + ((reg[OBSEL] & 0xe0) >> 3);
363 base[0] = (reg[OBSEL] & 0x07) << 14;
364 base[1] = base[0] + (((reg[OBSEL] & 0x18) + 8) << 10);
370 q = (oam[512 + (rx >> 3)] >> (rx & 6)) & 3;
373 sp->sy = sz[(q & 2) + 1];
379 if(sp->x < -(short)sp->sx && sp->x != -256)
389 sp->t1 = base[sp->c & 1];
398 if((reg[OAMADDH] & 0x80) != 0)
402 for(i = 0, tp = t; i < m; i++, tp++){
404 if(dx < 0 || dx >= tp->sx)
407 if((tp->c & 0x40) != 0){
408 v = w & 1 | w >> 7 & 2 | w >> 14 & 4 | w >> 21 & 8;
411 v = w >> 7 & 1 | w >> 14 & 2 | w >> 21 & 4 | w >> 28 & 8;
416 nt = (tp->i - prio) & 0x7f;
417 if(v != 0 && nt < pri1){
424 pixel(OBJ, col, pri0);
429 for(sp = s + n - 1, tp = t + n - 1; sp >= s; sp--, tp--){
433 tp->pal = 0x80 | sp->c << 3 & 0x70;
434 tp->pri = 3 * (0x10 + (sp->c & 0x30));
443 if((sp->c & 0x80) != 0)
444 dy = sp->sy - 1 - dy;
445 a = sp->t0 | (dy & 7) << 1;
448 if((sp->c & 0x40) != 0){
450 for(i = 0; i < nt; i++){
451 if(cp < ch + nelem(ch)){
452 w = vram[sp->t1 | (a -= 16) & 0x1fff] << 16;
453 w |= vram[sp->t1 | (a + 1) & 0x1fff] << 24;
454 w |= vram[sp->t1 | (a -= 16) & 0x1fff] << 0;
455 w |= vram[sp->t1 | (a + 1) & 0x1fff] << 8;
462 for(i = 0; i < nt; i++){
463 if(cp < ch + nelem(ch)){
464 w = vram[sp->t1 | a & 0x1fff];
465 w |= vram[sp->t1 | ++a & 0x1fff] << 8;
466 w |= vram[sp->t1 | (a += 15) & 0x1fff] << 16;
467 w |= vram[sp->t1 | ++a & 0x1fff] << 24;
482 u16int v, w, r, g, b;
490 default: v = 1; break;
491 case 1: v = cw = window(COL); break;
492 case 2: v = !(cw = window(COL)); break;
493 case 3: v = 0; break;
496 if((pixelcol[0] & 0x10000) != 0)
499 v = cgram[pixelcol[0] & 0xff];
501 if((m2 & (1 << (pixelpri[0] & 0xf))) == 0)
503 switch((m >> 4) & 3){
505 case 1: if(cw < 0) cw = window(COL); if(!cw) return v; break;
506 case 2: if(cw < 0) cw = window(COL); if(cw) return v; break;
510 if((pixelcol[1] & 0x10000) != 0)
513 w = cgram[pixelcol[1] & 0xff];
516 if((m2 & 0x80) != 0){
517 r = (v & 0x7c00) - (w & 0x7c00);
518 g = (v & 0x03e0) - (w & 0x03e0);
519 b = (v & 0x001f) - (w & 0x001f);
520 if((m2 & 0x40) != 0){
521 r = (r >> 1) & 0xfc00;
522 g = (g >> 1) & 0xffe0;
525 if(r > 0x7c00) r = 0;
526 if(g > 0x03e0) g = 0;
527 if(b > 0x001f) b = 0;
530 r = (v & 0x7c00) + (w & 0x7c00);
531 g = (v & 0x03e0) + (w & 0x03e0);
532 b = (v & 0x001f) + (w & 0x001f);
533 if((m2 & 0x40) != 0){
534 r = (r >> 1) & 0xfc00;
535 g = (g >> 1) & 0xffe0;
538 if(r > 0x7c00) r = 0x7c00;
539 if(g > 0x03e0) g = 0x03e0;
540 if(b > 0x001f) b = 0x001f;
550 mode = reg[BGMODE] & 7;
551 bright = reg[INIDISP] & 0xf;
552 yvbl = (reg[SETINI] & OVERSCAN) != 0 ? 0xf0 : 0xe1;
554 if(ppux >= XLEFT && ppux <= XRIGHT && ppuy < 0xf0){
556 if(ppuy < yvbl && (reg[INIDISP] & 0x80) == 0){
559 pixelcol[1] = 0x10000 | subcolor;
564 pixeldraw(rx, ppuy - 1, colormath());
566 pixeldraw(rx, ppuy - 1, ppuy >= yvbl ? 0x31c8 : 0);
569 if(ppux == 0x116 && ppuy <= yvbl)
571 if((reg[NMITIMEN] & HCNTIRQ) != 0 && htime == ppux && ((reg[NMITIMEN] & VCNTIRQ) == 0 || vtime == ppuy))
577 reg[RDNMI] &= ~VBLANK;
578 hdma = reg[0x420c]<<8;
582 reg[RDNMI] |= VBLANK;
583 if((reg[NMITIMEN] & VBLANK) != 0)
585 if((reg[NMITIMEN] & AUTOJOY) != 0){
588 reg[0x4218] = keylatch >> 16;
589 reg[0x4219] = keylatch >> 24;
590 keylatch = keylatch << 16 | 0xffff;
593 if((reg[NMITIMEN] & (HCNTIRQ|VCNTIRQ)) == VCNTIRQ && vtime == ppuy)