10 u8int oam[544], vram[65536];
12 u16int oamaddr, vramlatch;
13 u32int keylatch, lastkeys;
26 u8int mdr, mdr1, mdr2;
28 extern void calc7(void);
33 switch(reg[0x2115] & 12){
34 default: return a << 1;
35 case 4: return a << 1 & 0xfe00 | a << 4 & 0x01f0 | a >> 4 & 0x000e;
36 case 8: return a << 1 & 0xfc00 | a << 4 & 0x03f0 | a >> 5 & 0x000e;
37 case 12: return a << 1 & 0xf800 | a << 4 & 0x07f0 | a >> 6 & 0x000e;
46 b = vrammap(reg[0x2116] | reg[0x2117] << 8);
47 vramlatch = vram[b++];
48 vramlatch |= vram[b] << 8;
60 a = reg[0x2116] | reg[0x2117] << 8;
65 case 1: a += 32; break;
66 default: a += 128; break;
69 reg[0x2117] = (a >> 8) & 0x7f;
75 if(++reg[0x2181] == 0)
76 if(++reg[0x2182] == 0)
84 reg[OPHCTH] = ppux >> 8;
86 reg[OPVCTH] = ppuy >> 8;
87 reg[OPCTLATCH] |= 0x40;
93 return (a & 0x83e0) | (a & 0x7c00) >> 10 | (a & 0x001f) << 10;
102 v = keys & 0xffff0000;
103 x = (keys & 0xff) - (lastkeys & 0xff);
104 y = (keys >> 8 & 0xff) - (lastkeys >> 8 & 0xff);
117 keylatch = v | x | y << 8;
133 if((p & 0xfe00) == 0x4000)
136 case 0x2134: case 0x2135: case 0x2136:
137 r = ((signed short)m7[0] * (signed char)reg[0x211c]) & 0xffffff;
138 return mdr1 = r >> 8 * (p - 0x2134);
140 if((reg[0x4201] & 0x80) != 0)
147 v = oam[oamaddr & 0x21f];
148 oamaddr = (oamaddr + 1) & 0x3ff;
159 a = swaprb(cgram[reg[0x2121]]);
169 if((reg[OPCTLATCH] & 1) == 0)
170 return mdr2 = reg[OPHCTH] | mdr2 & 0xfe;
171 return mdr2 = reg[p];
174 if((reg[OPCTLATCH] & 2) == 0)
175 return reg[OPVCTH] | mdr2 & 0xfe;
176 return mdr2 = reg[p];
178 return mdr1 = reg[p] | mdr1 & 0x10;
180 v = reg[OPCTLATCH] & 0x40;
181 if((reg[0x4201] & 0x80) != 0)
182 reg[OPCTLATCH] &= ~0x43;
184 reg[OPCTLATCH] &= ~3;
185 return mdr2 = reg[p] | v | mdr2 & 0x20;
187 v = mem[reg[0x2181] | reg[0x2182] << 8 | (reg[0x2183] & 1) << 16];
191 if((reg[0x4016] & 1) != 0){
193 if((keys & 0x300000) == 0x300000)
200 keylatch = (keylatch << 1) | 1;
201 return v | mdr & 0xfc;
203 return 0x1f | mdr & 0xe0;
207 return v | mdr & 0x70;
211 return v | mdr & 0x7f;
214 if(ppux >= 274 || ppux == 0)
216 a = (reg[SETINI] & OVERSCAN) != 0 ? 0xf0 : 0xe1;
219 if(ppuy <= a + 2 && (reg[NMITIMEN] & AUTOJOY) != 0)
222 return v | mdr & 0x3e;
223 case 0x4214: case 0x4215: case 0x4216: case 0x4217: case 0x4218:
224 case 0x4219: case 0x421a: case 0x421b: case 0x421c: case 0x421d:
225 case 0x421e: case 0x421f:
227 case 0x2104: case 0x2105: case 0x2106: case 0x2108: case 0x2109: case 0x210a:
228 case 0x2114: case 0x2115: case 0x2116: case 0x2118: case 0x2119: case 0x211a:
229 case 0x2124: case 0x2125: case 0x2126: case 0x2128: case 0x2129: case 0x212a:
232 if((p & 0xff80) == 0x4300)
234 if((p & 0xffc0) == 0x2140)
235 return spcmem[0xf4 | p & 3];
240 regwrite(u16int p, u8int v)
250 if((p & 0xfe00) == 0x4000)
254 oamaddr = (reg[0x2103] & 1) << 9 | v << 1;
257 oamaddr = (v & 1) << 9 | reg[0x2102] << 1;
260 if((oamaddr & 1) == 0)
263 if((oamaddr & 1) != 0){
264 oam[oamaddr - 1] = reg[OAMLATCH];
268 oam[oamaddr & 0x21f] = v;
269 oamaddr = (oamaddr + 1) & 0x3ff;
276 hofs[4] = (v & 0x1f) << 8 | reg[M7PREV];
281 case 0x210f: case 0x2111: case 0x2113:
282 a = (p - 0x210d) >> 1;
283 hofs[a] = v << 8 | reg[OFSPREV] & ~7 | (hofs[a] >> 8) & 7;
287 vofs[4] = (v & 0x1f) << 8 | reg[M7PREV];
292 case 0x2110: case 0x2112: case 0x2114:
293 vofs[(p - 0x210e) >> 1] = v << 8 | reg[OFSPREV];
303 a = vrammap(reg[0x2116] | reg[0x2117] << 8);
308 a = vrammap(reg[0x2116] | reg[0x2117] << 8);
312 case 0x211b: case 0x211c: case 0x211d:
313 case 0x211e: case 0x211f: case 0x2120:
314 m7[p - 0x211b] = v << 8 | reg[M7PREV];
317 m7[p - 0x211b] |= 0xe000;
319 m7[p - 0x211b] &= 0x1fff;
330 cgram[reg[0x2121]++] = swaprb(reg[CGLATCH] | v << 8);
334 if((v & 0x80) != 0) subcolor = subcolor & 0x7fe0 | v & 0x1f;
335 if((v & 0x40) != 0) subcolor = subcolor & 0x7c1f | (v & 0x1f) << 5;
336 if((v & 0x20) != 0) subcolor = subcolor & 0x03ff | (v & 0x1f) << 10;
341 mem[reg[0x2181] | reg[0x2182] << 8 | (reg[0x2183] & 1) << 16] = v;
345 if((reg[0x4016] & 1) != 0 && (v & 1) == 0){
349 keylatch = keys | 0xffff;
353 if((reg[0x4200] & 0x80) == 0 && (v & 0x80) != 0 && (reg[RDNMI] & 0x80) != 0)
355 if((v & (HCNTIRQ|VCNTIRQ)) == 0)
359 if((reg[0x4201] & 0x80) == 0 && (v & 0x80) != 0)
365 reg[0x4217] = a >> 8;
371 reg[0x4216] = reg[0x4204];
372 reg[0x4217] = reg[0x4205];
374 a = reg[0x4204] | reg[0x4205] << 8;
376 reg[0x4215] = (a / v) >> 8;
378 reg[0x4217] = (a % v) >> 8;
382 htime = htime & 0x100 | v;
385 htime = htime & 0xff | (v & 1) << 8;
388 vtime = vtime & 0x100 | v;
391 vtime = vtime & 0xff | (v & 1) << 8;
394 dma |= v & ~(reg[0x420c] & ~hdma >> 24);
401 case 0x4216: case 0x4217:
402 case 0x4218: case 0x4219: case 0x421a: case 0x421b:
403 case 0x421c: case 0x421d: case 0x421e: case 0x421f:
406 if((p & 0xff40) == 0x2140)
420 speed = a < 0x800000 || (reg[MEMSEL] & 1) == 0 ? 8 : 6;
425 if(hirom && nsram != 0)
426 return mdr = sram[(b << 13 | al & 0x1ffff) & (nsram - 1)];
429 return mdr = regread(al);
431 if(!hirom && (b & 0xf8) == 0x70 && nsram != 0){
433 return mdr = sram[a & 0x07ffff & (nsram - 1)];
436 if(b >= 0x7e && (a & (1<<23)) == 0){
438 return mdr = mem[a - 0x7e0000];
442 return mdr = prg[((b & 0x3f) % nprg) << 16 | al];
443 return mdr = prg[(b%nprg) << 15 | al & 0x7fff];
447 memwrite(u32int a, u8int v)
455 speed = a < 0x800000 || (reg[MEMSEL] & 1) == 0 ? 8 : 6;
456 if(b >= 0x7e && a < 0x800000){
458 mem[a - 0x7e0000] = v;
464 if(hirom && nsram != 0){
465 sram[(b << 13 | al & 0x1fff) & (nsram - 1)] = v;
472 if(!hirom && (b & 0xf8) == 0x70 && nsram != 0){
473 sram[a & 0x07ffff & (nsram - 1)] = v;
477 saveclock = SAVEFREQ;
484 static u8int nbytes[] = {1, 2, 2, 4, 4, 4, 2, 4};
485 static u8int modes[] = {0x00, 0x04, 0x00, 0x50, 0xe4, 0x44, 0x00, 0x50};
488 dmavalid(int a, int b)
492 if((a & 0x400000) != 0)
496 case 0x42: return a != 0x420b && a != 0x420c;
505 int i, j, n, m, cycl;
511 for(i = 0; i < 8; i++)
512 if((dma & (1<<i)) != 0)
516 p = reg + 0x4300 + (i << 4);
520 for(j = 0; j < n; j++){
521 a = p[2] | p[3] << 8 | p[4] << 16;
524 v = dmavalid(b, 1) ? memread(0x2100 | b) : 0;
528 v = dmavalid(a, 0) ? memread(a) : 0;
530 memwrite(0x2100 | b, v);
546 }else if(--p[5] == 0 && p[6] == 0){
559 a = p[8] | p[9] << 8 | p[4] << 16;
560 p[10] = dmavalid(a, 0) ? memread(a) : 0;
562 if((p[0] & 0x40) != 0){
563 p[5] = dmavalid(a, 0) ? memread(a) : 0;
565 p[6] = dmavalid(a, 0) ? memread(a) : 0;
570 return (p[0] & 0x40) != 0 ? 24 : 8;
577 u8int *p, *q, n, m, b, v, c;
582 dma &= ~((hdma & 0xff00) >> 8 | (hdma & 0xff));
583 if((hdma & 0xff) == 0)
586 for(i = 0; i < 8; i++){
587 if(((hdma >> i) & (1<<24|1)) != 1)
589 p = reg + 0x4300 + (i << 4);
591 if((hdma & (1<<(16+i))) != 0){
601 for(j = 0; j < n; j++){
602 a = q[0] | q[1] << 8 | br;
605 v = dmavalid(b, 1) ? memread(0x2100 | b) : 0;
609 v = dmavalid(a, 0) ? memread(a) : 0;
611 memwrite(0x2100 | b, v);
620 hdma = (hdma & ~(1<<(16+i))) | ((p[10] & 0x80) << (9+i));
622 if((p[10] & 0x7f) == 0){
623 cycl += hdmaload(p) - 8;
630 if((hdma & 0xff00) == 0)
633 for(i = 0; i < 8; i++){
634 if((hdma & (1<<(8+i))) == 0)
636 p = reg + 0x4300 + (i << 4);