9 u8int oam[544], vram[65536];
11 u16int oamaddr, vramlatch;
12 u32int keylatch, lastkeys;
25 extern void calc7(void);
30 switch(reg[0x2115] & 12){
31 default: return a << 1;
32 case 4: return a << 1 & 0xfe00 | a << 4 & 0x01f0 | a >> 4 & 0x000e;
33 case 8: return a << 1 & 0xfc00 | a << 4 & 0x03f0 | a >> 5 & 0x000e;
34 case 12: return a << 1 & 0xf800 | a << 4 & 0x07f0 | a >> 6 & 0x000e;
47 a = reg[0x2116] | reg[0x2117] << 8;
50 vramlatch = vram[b++];
51 vramlatch |= vram[b] << 8;
55 case 1: a += 32; break;
56 default: a += 128; break;
59 reg[0x2117] = (a >> 8) & 0x7f;
65 if(++reg[0x2181] == 0)
66 if(++reg[0x2182] == 0)
74 reg[OPHCTH] = ppux >> 8;
76 reg[OPVCTH] = ppuy >> 8;
77 reg[OPCTLATCH] |= 0x40;
83 return (a & 0x83e0) | (a & 0x7c00) >> 10 | (a & 0x001f) << 10;
92 v = keys & 0xffff0000;
93 x = (keys & 0xff) - (lastkeys & 0xff);
94 y = (keys >> 8 & 0xff) - (lastkeys >> 8 & 0xff);
107 keylatch = v | x | y << 8;
121 case 0x2134: case 0x2135: case 0x2136:
122 r = ((signed short)m7[0] * (signed char)reg[0x211c]) & 0xffffff;
123 return r >> 8 * (p - 0x2134);
125 if((reg[0x4201] & 0x80) != 0)
132 v = oam[oamaddr & 0x21f];
133 oamaddr = (oamaddr + 1) & 0x3ff;
144 a = swaprb(cgram[reg[0x2121]]);
153 if((reg[OPCTLATCH] & 1) == 0)
158 if((reg[OPCTLATCH] & 2) == 0)
162 v = 2 | reg[OPCTLATCH] & 0x40;
163 if((reg[0x4201] & 0x80) != 0)
164 reg[OPCTLATCH] &= ~0x43;
166 reg[OPCTLATCH] &= ~3;
169 v = memread(0x7e0000 | reg[0x2181] | reg[0x2182] << 8 | (reg[0x2183] & 1) << 16);
173 if((reg[0x4016] & 1) != 0){
175 if((keys & 0x300000) == 0x300000)
182 keylatch = (keylatch << 1) | 1;
192 if(ppux >= 274 || ppux == 0)
194 a = (reg[SETINI] & OVERSCAN) != 0 ? 0xf0 : 0xe1;
197 if(ppuy <= a + 2 && (reg[NMITIMEN] & AUTOJOY) != 0)
202 if((p & 0xff40) == 0x2140)
203 return spcmem[0xf4 | p & 3];
208 regwrite(u16int p, u8int v)
218 oamaddr = (reg[0x2103] & 1) << 9 | v << 1;
221 oamaddr = (v & 1) << 9 | reg[0x2102];
224 if((oamaddr & 1) == 0)
227 if((oamaddr & 1) != 0){
228 oam[oamaddr - 1] = reg[OAMLATCH];
232 oam[oamaddr & 0x21f] = v;
233 oamaddr = (oamaddr + 1) & 0x3ff;
240 hofs[4] = (v & 0x1f) << 8 | reg[M7PREV];
245 case 0x210f: case 0x2111: case 0x2113:
246 a = (p - 0x210d) >> 1;
247 hofs[a] = v << 8 | reg[OFSPREV] & ~7 | (hofs[a] >> 8) & 7;
251 vofs[4] = (v & 0x1f) << 8 | reg[M7PREV];
256 case 0x2110: case 0x2112: case 0x2114:
257 vofs[(p - 0x210e) >> 1] = v << 8 | reg[OFSPREV];
266 a = vrammap(reg[0x2116] | reg[0x2117] << 8);
271 a = vrammap(reg[0x2116] | reg[0x2117] << 8);
275 case 0x211b: case 0x211c: case 0x211d:
276 case 0x211e: case 0x211f: case 0x2120:
277 m7[p - 0x211b] = v << 8 | reg[M7PREV];
280 m7[p - 0x211b] |= 0xe000;
282 m7[p - 0x211b] &= 0x1fff;
293 cgram[reg[0x2121]++] = swaprb(reg[CGLATCH] | v << 8);
297 if((v & 0x80) != 0) subcolor = subcolor & 0x7fe0 | v & 0x1f;
298 if((v & 0x40) != 0) subcolor = subcolor & 0x7c1f | (v & 0x1f) << 5;
299 if((v & 0x20) != 0) subcolor = subcolor & 0x03ff | (v & 0x1f) << 10;
304 memwrite(0x7e0000 | reg[0x2181] | reg[0x2182] << 8 | (reg[0x2183] & 1) << 16, v);
308 if((reg[0x4016] & 1) != 0 && (v & 1) == 0){
316 if((reg[0x4200] & 0x80) == 0 && (v & 0x80) != 0 && (reg[RDNMI] & 0x80) != 0)
318 if((v & (HCNTIRQ|VCNTIRQ)) == 0)
322 if((reg[0x4201] & 0x80) == 0 && (v & 0x80) != 0)
328 reg[0x4217] = a >> 8;
334 reg[0x4216] = reg[0x4204];
335 reg[0x4217] = reg[0x4205];
337 a = reg[0x4204] | reg[0x4205] << 8;
339 reg[0x4215] = (a / v) >> 8;
341 reg[0x4217] = (a % v) >> 8;
345 htime = htime & 0x100 | v;
348 htime = htime & 0xff | (v & 1) << 8;
351 vtime = vtime & 0x100 | v;
354 vtime = vtime & 0xff | (v & 1) << 8;
357 dma |= v & ~(reg[0x420c] & ~hdma >> 24);
364 case 0x4216: case 0x4217:
365 case 0x4218: case 0x4219: case 0x421a: case 0x421b:
366 case 0x421c: case 0x421d: case 0x421e: case 0x421f:
369 if((p & 0xff40) == 0x2140)
384 if(hirom && al >= 0x6000 && nsram != 0)
385 return sram[(b << 13 | al & 0x1ffff) & (nsram - 1)];
388 if(!hirom && (b & 0xf8) == 0x70 && nsram != 0){
389 if(a < 0x800000 || (reg[MEMSEL] & 1) == 0)
391 return sram[a & 0x07ffff & (nsram - 1)];
394 if(b >= 0x7e && (a & (1<<23)) == 0){
396 return mem[a - 0x7e0000];
398 if(a < 0x800000 || (reg[MEMSEL] & 1) == 0)
401 return prg[((b & 0x3f) % nprg) << 16 | al];
402 return prg[(b%nprg) << 15 | al & 0x7fff];
406 memwrite(u32int a, u8int v)
413 if(b >= 0x7e && a < 0x800000){
415 mem[a - 0x7e0000] = v;
419 if(hirom && al >= 0x6000 && nsram != 0){
420 sram[(b << 13 | al & 0x1fff) & (nsram - 1)] = v;
426 if(!hirom && (b & 0xf8) == 0x70 && nsram != 0){
427 sram[a & 0x07ffff & (nsram - 1)] = v;
429 if(a < 0x800000 || (reg[MEMSEL] & 1) == 0)
432 saveclock = SAVEFREQ;
438 static u8int nbytes[] = {1, 2, 2, 4, 4, 4, 2, 4};
439 static u8int modes[] = {0x00, 0x04, 0x00, 0x50, 0xe4, 0x44, 0x00, 0x50};
442 dmavalid(int a, int b)
446 if((a & 0x400000) != 0)
450 case 0x42: return a != 0x420b && a != 0x420c;
465 for(i = 0; i < 8; i++)
466 if((dma & (1<<i)) != 0)
470 p = reg + 0x4300 + (i << 4);
474 for(j = 0; j < n; j++){
475 a = p[2] | p[3] << 8 | p[4] << 16;
478 v = dmavalid(b, 1) ? memread(0x2100 | b) : 0;
482 v = dmavalid(a, 0) ? memread(a) : 0;
484 memwrite(0x2100 | b, v);
500 }else if(--p[5] == 0 && p[6] == 0){
513 a = p[8] | p[9] << 8 | p[4] << 16;
514 p[10] = dmavalid(a, 0) ? memread(a) : 0;
516 if((p[0] & 0x40) != 0){
517 p[5] = dmavalid(a, 0) ? memread(a) : 0;
519 p[6] = dmavalid(a, 0) ? memread(a) : 0;
524 return (p[0] & 0x40) != 0 ? 3 : 1;
531 u8int *p, *q, n, m, b, v, c;
536 dma &= ~((hdma & 0xff00) >> 8 | (hdma & 0xff));
537 if((hdma & 0xff) == 0)
540 for(i = 0; i < 8; i++){
541 if(((hdma >> i) & (1<<24|1)) != 1)
543 p = reg + 0x4300 + (i << 4);
545 if((hdma & (1<<(16+i))) != 0){
555 for(j = 0; j < n; j++){
556 a = q[0] | q[1] << 8 | br;
559 v = dmavalid(b, 1) ? memread(0x2100 | b) : 0;
563 v = dmavalid(a, 0) ? memread(a) : 0;
565 memwrite(0x2100 | b, v);
574 hdma = (hdma & ~(1<<(16+i))) | ((p[10] & 0x80) << (9+i));
576 if((p[10] & 0x7f) == 0){
577 cyc += hdmaload(p)-1;
584 if((hdma & 0xff00) == 0)
587 for(i = 0; i < 8; i++){
588 if((hdma & (1<<(8+i))) == 0)
590 p = reg + 0x4300 + (i << 4);