11 uchar *prgb[16], *chrb[16];
14 int vramlatch = 1, keylatch = 0xFF;
15 int prgsh, chrsh, mmc3hack;
20 print("unimplemented mapper function %d (mapper %d)\n", p, map);
35 prgb[1] = prg + 0x4000;
51 static u8int n, s, mode, c0, c1, pr;
52 static int mirrs[] = {MSINGB, MSINGA, MVERT, MHORZ};
99 mirr = mirrs[mode & 3];
120 prgb[1] = prg + pr * 0x4000;
123 prgb[0] = prg + pr * 0x4000;
124 prgb[1] = prg + (0x0f % nprg) * 0x4000;
127 prgb[0] = prg + (pr & 0xfe) * 0x4000;
128 prgb[1] = prg + (pr | 1) * 0x4000;
131 if((mode & 0x10) != 0){
132 chrb[0] = chr + c0 * 0x1000;
133 chrb[1] = chr + c1 * 0x1000;
135 chrb[0] = chr + (c0 & 0xfe) * 0x1000;
136 chrb[1] = chr + (c0 | 1) * 0x1000;
141 uxrom(int p, u8int v)
150 prgb[1] = prg + (nprg - 1) * 0x4000;
167 prgb[0] = prg + b * 0x4000;
171 cnrom(int p, u8int v)
184 prgb[1] = prg + 0x4000;
200 chrb[0] = chr + b * 0x2000;
207 static u8int m, b[8], l, n, en;
216 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
217 prgb[3] = prgb[2] + 0x2000;
229 for(i = 0; i < 8; i++)
237 for(i = 0; i < 8; i++)
247 if(((m ^ v) & 0xc0) != 0){
269 case 0xC000: l = v; break;
270 case 0xC001: n = 0; break;
271 case 0xE000: en = 0; irq &= ~IRQMMC; break;
272 case 0xE001: en = 1; break;
277 prgb[0] = prg + (2 * nprg - 2) * 0x2000;
278 prgb[2] = prg + b[6] * 0x2000;
280 prgb[0] = prg + b[6] * 0x2000;
281 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
283 prgb[1] = prg + b[7] * 0x2000;
285 for(i = 0; i < 2; i++){
286 chrb[j = (i << 1) ^ c] = chr + (b[i] >> 1) * 0x800;
287 chrb[j+1] = chrb[j] + 0x400;
289 for(i = 2; i < 6; i++)
290 chrb[(i + 2) ^ c] = chr + b[i] * 0x400;
294 axrom(int p, u8int v)
318 prgb[0] = prg + (b & 3) * 0x8000;
319 prgb[1] = prgb[0] + 0x4000;
322 void (*mapper[256])(int, u8int) = {
337 if((mem[PPUCTRL] & VRAMINC) != 0)
342 if(mmc3hack && (old & (1<<12)) == 0 && (ppuv & (1<<12)) != 0)
343 mapper[map](SCAN, 0);
354 }else if(p < 0x6000){
360 mem[p] &= ~PPUVBLANK;
364 return oam[mem[0x2003]];
368 vrambuf = ppuread(ppuv);
372 vrambuf = ppuread(ppuv);
377 for(i = 0; i < 4; i++){
386 if((mem[p] & 1) != 0)
389 keylatch = (keylatch >> 1) | 0x80;
397 return prgb[p >> prgsh][p & ((1 << prgsh) - 1)];
403 memwrite(u16int p, u8int v)
405 extern u8int apulen[32];
406 extern u16int dmclen[16];
411 }else if(p < 0x6000){
416 if((mem[PPUCTRL] & PPUNMI) == 0 && (v & PPUNMI) != 0 &&
417 (mem[PPUSTATUS] & PPUVBLANK) != 0)
419 pput = (pput & 0xF3FF) | ((v & 3) << 10);
424 oam[mem[0x2003]++] = v;
429 pput = (pput & 0xFFE0) | (v >> 3);
431 pput = (pput & 0x0C1F) | ((v & 0xF8) << 2) | ((v & 7) << 12);
436 pput = (pput & 0xFF) | (v << 8) & 0x3F00;
438 pput = (pput & 0xFF00) | v;
439 if(mmc3hack && (ppuv & (1<<12)) == 0 && (pput & (1<<12)) != 0)
440 mapper[map](SCAN, 0);
459 if((mem[APUSTATUS] & (1<<i)) != 0){
460 apuctr[i] = apulen[v >> 3];
461 apuctr[10] |= (1<<i);
467 dmcfreq = 12 * dmclen[v & 0xf];
473 memcpy(oam, mem + (v<<8), sizeof(oam));
476 for(i = 0; i < 4; i++)
477 if((v & (1<<i)) == 0)
479 if((v & 0x10) != 0 && dmccnt == 0){
480 dmcaddr = mem[DMCADDR] * 0x40 + 0xC000;
481 dmccnt = mem[DMCLEN] * 0x10 + 1;
486 if((mem[p] & 1) != 0 && (v & 1) == 0)
499 }else if(p < 0x8000){
501 saveclock = SAVEFREQ;
503 if(mapper[map] != nil)
516 return ppuram + (p & 0x3F1F);
523 case MHORZ: if((p & 0x800) != 0) p |= 0x400; else p &= ~0x400; break;
524 case MVERT: if((p & 0x400) != 0) p |= 0x800; else p &= ~0x800; break;
525 case MSINGA: p &= ~0xC00; break;
526 case MSINGB: p |= 0xC00; break;
529 return chrb[p >> chrsh] + (p & ((1 << chrsh) - 1));
541 ppuwrite(u16int p, u8int v)