12 uchar *prgb[16], *chrb[16];
15 int vramlatch = 1, keylatch = 0xFF, keylatch2 = 0xFF;
16 int prgsh, chrsh, mmc3hack;
21 print("unimplemented mapper function %d (mapper %d)\n", p, map);
36 prgb[1] = prg + 0x4000;
52 static u8int n, s, mode, c0, c1, pr;
53 static int mirrs[] = {MSINGB, MSINGA, MVERT, MHORZ};
59 sysfatal("bad rom, too much prg rom for mmc1");
102 mirr = mirrs[mode & 3];
106 pr = s & 0x10 | pr & 0x0f;
117 pr = pr & 0x10 | s & 0x0f;
127 prgb[1] = prg + pr * 0x4000;
130 prgb[0] = prg + pr * 0x4000;
131 prgb[1] = prg + ((pr & 0x10 | 0x0f) % nprg) * 0x4000;
134 prgb[0] = prg + (pr & 0xfe) * 0x4000;
135 prgb[1] = prg + (pr | 1) * 0x4000;
138 if((mode & 0x10) != 0){
139 chrb[0] = chr + c0 * 0x1000;
140 chrb[1] = chr + c1 * 0x1000;
142 chrb[0] = chr + (c0 & 0xfe) * 0x1000;
143 chrb[1] = chr + (c0 | 1) * 0x1000;
148 uxrom(int p, u8int v)
157 prgb[1] = prg + (nprg - 1) * 0x4000;
174 prgb[0] = prg + b * 0x4000;
178 cnrom(int p, u8int v)
191 prgb[1] = prg + 0x4000;
207 chrb[0] = chr + b * 0x2000;
214 static u8int m, b[8], l, n, en;
223 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
224 prgb[3] = prgb[2] + 0x2000;
236 for(i = 0; i < 8; i++)
244 for(i = 0; i < 8; i++)
254 if(((m ^ v) & 0xc0) != 0){
276 case 0xC000: l = v; break;
277 case 0xC001: n = 0; break;
278 case 0xE000: en = 0; irq &= ~IRQMMC; break;
279 case 0xE001: en = 1; break;
284 prgb[0] = prg + (2 * nprg - 2) * 0x2000;
285 prgb[2] = prg + b[6] * 0x2000;
287 prgb[0] = prg + b[6] * 0x2000;
288 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
290 prgb[1] = prg + b[7] * 0x2000;
292 for(i = 0; i < 2; i++){
293 chrb[j = (i << 1) ^ c] = chr + (b[i] >> 1) * 0x800;
294 chrb[j+1] = chrb[j] + 0x400;
296 for(i = 2; i < 6; i++)
297 chrb[(i + 2) ^ c] = chr + b[i] * 0x400;
301 axrom(int p, u8int v)
325 prgb[0] = prg + (b & 3) * 0x8000;
326 prgb[1] = prgb[0] + 0x4000;
329 void (*mapper[256])(int, u8int) = {
344 if((mem[PPUCTRL] & VRAMINC) != 0)
349 if(mmc3hack && (old & (1<<12)) == 0 && (ppuv & (1<<12)) != 0)
350 mapper[map](SCAN, 0);
361 }else if(p < 0x6000){
367 mem[p] &= ~PPUVBLANK;
371 return oam[mem[0x2003]];
375 vrambuf = ppuread(ppuv);
379 vrambuf = ppuread(ppuv);
384 for(i = 0; i < 4; i++){
393 if((mem[p] & 1) != 0)
396 keylatch = (keylatch >> 1) | 0x80;
399 if((mem[p] & 1) != 0)
402 keylatch2 = (keylatch2 >> 1) | 0x80;
408 return prgb[p >> prgsh][p & ((1 << prgsh) - 1)];
414 memwrite(u16int p, u8int v)
416 extern u8int apulen[32];
417 extern u16int dmclen[16];
422 }else if(p < 0x6000){
427 if((mem[PPUCTRL] & PPUNMI) == 0 && (v & PPUNMI) != 0 &&
428 (mem[PPUSTATUS] & PPUVBLANK) != 0)
430 pput = (pput & 0xF3FF) | ((v & 3) << 10);
435 oam[mem[0x2003]++] = v;
440 pput = (pput & 0xFFE0) | (v >> 3);
442 pput = (pput & 0x0C1F) | ((v & 0xF8) << 2) | ((v & 7) << 12);
447 pput = (pput & 0xFF) | (v << 8) & 0x3F00;
449 pput = (pput & 0xFF00) | v;
450 if(mmc3hack && (ppuv & (1<<12)) == 0 && (pput & (1<<12)) != 0)
451 mapper[map](SCAN, 0);
470 if((mem[APUSTATUS] & (1<<i)) != 0){
471 apuctr[i] = apulen[v >> 3];
472 apuctr[10] |= (1<<i);
478 dmcfreq = 12 * dmclen[v & 0xf];
484 memcpy(oam, mem + (v<<8), sizeof(oam));
487 for(i = 0; i < 4; i++)
488 if((v & (1<<i)) == 0)
490 if((v & 0x10) != 0 && dmccnt == 0){
491 dmcaddr = mem[DMCADDR] * 0x40 + 0xC000;
492 dmccnt = mem[DMCLEN] * 0x10 + 1;
497 if((mem[p] & 1) != 0 && (v & 1) == 0){
512 }else if(p < 0x8000){
514 saveclock = SAVEFREQ;
516 if(mapper[map] != nil)
529 return ppuram + (p & 0x3F1F);
536 case MHORZ: if((p & 0x800) != 0) p |= 0x400; else p &= ~0x400; break;
537 case MVERT: if((p & 0x400) != 0) p |= 0x800; else p &= ~0x800; break;
538 case MSINGA: p &= ~0xC00; break;
539 case MSINGB: p |= 0xC00; break;
542 return chrb[p >> chrsh] + (p & ((1 << chrsh) - 1));
554 ppuwrite(u16int p, u8int v)