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};
58 sysfatal("bad rom, too much prg rom for mmc1");
101 mirr = mirrs[mode & 3];
105 pr = s & 0x10 | pr & 0x0f;
116 pr = pr & 0x10 | s & 0x0f;
126 prgb[1] = prg + pr * 0x4000;
129 prgb[0] = prg + pr * 0x4000;
130 prgb[1] = prg + ((pr & 0x10 | 0x0f) % nprg) * 0x4000;
133 prgb[0] = prg + (pr & 0xfe) * 0x4000;
134 prgb[1] = prg + (pr | 1) * 0x4000;
137 if((mode & 0x10) != 0){
138 chrb[0] = chr + c0 * 0x1000;
139 chrb[1] = chr + c1 * 0x1000;
141 chrb[0] = chr + (c0 & 0xfe) * 0x1000;
142 chrb[1] = chr + (c0 | 1) * 0x1000;
147 uxrom(int p, u8int v)
156 prgb[1] = prg + (nprg - 1) * 0x4000;
173 prgb[0] = prg + b * 0x4000;
177 cnrom(int p, u8int v)
190 prgb[1] = prg + 0x4000;
206 chrb[0] = chr + b * 0x2000;
213 static u8int m, b[8], l, n, en;
222 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
223 prgb[3] = prgb[2] + 0x2000;
235 for(i = 0; i < 8; i++)
243 for(i = 0; i < 8; i++)
253 if(((m ^ v) & 0xc0) != 0){
275 case 0xC000: l = v; break;
276 case 0xC001: n = 0; break;
277 case 0xE000: en = 0; irq &= ~IRQMMC; break;
278 case 0xE001: en = 1; break;
283 prgb[0] = prg + (2 * nprg - 2) * 0x2000;
284 prgb[2] = prg + b[6] * 0x2000;
286 prgb[0] = prg + b[6] * 0x2000;
287 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
289 prgb[1] = prg + b[7] * 0x2000;
291 for(i = 0; i < 2; i++){
292 chrb[j = (i << 1) ^ c] = chr + (b[i] >> 1) * 0x800;
293 chrb[j+1] = chrb[j] + 0x400;
295 for(i = 2; i < 6; i++)
296 chrb[(i + 2) ^ c] = chr + b[i] * 0x400;
300 axrom(int p, u8int v)
324 prgb[0] = prg + (b & 3) * 0x8000;
325 prgb[1] = prgb[0] + 0x4000;
328 void (*mapper[256])(int, u8int) = {
343 if((mem[PPUCTRL] & VRAMINC) != 0)
348 if(mmc3hack && (old & (1<<12)) == 0 && (ppuv & (1<<12)) != 0)
349 mapper[map](SCAN, 0);
360 }else if(p < 0x6000){
366 mem[p] &= ~PPUVBLANK;
370 return oam[mem[0x2003]];
374 vrambuf = ppuread(ppuv);
378 vrambuf = ppuread(ppuv);
383 for(i = 0; i < 4; i++){
392 if((mem[p] & 1) != 0)
395 keylatch = (keylatch >> 1) | 0x80;
403 return prgb[p >> prgsh][p & ((1 << prgsh) - 1)];
409 memwrite(u16int p, u8int v)
411 extern u8int apulen[32];
412 extern u16int dmclen[16];
417 }else if(p < 0x6000){
422 if((mem[PPUCTRL] & PPUNMI) == 0 && (v & PPUNMI) != 0 &&
423 (mem[PPUSTATUS] & PPUVBLANK) != 0)
425 pput = (pput & 0xF3FF) | ((v & 3) << 10);
430 oam[mem[0x2003]++] = v;
435 pput = (pput & 0xFFE0) | (v >> 3);
437 pput = (pput & 0x0C1F) | ((v & 0xF8) << 2) | ((v & 7) << 12);
442 pput = (pput & 0xFF) | (v << 8) & 0x3F00;
444 pput = (pput & 0xFF00) | v;
445 if(mmc3hack && (ppuv & (1<<12)) == 0 && (pput & (1<<12)) != 0)
446 mapper[map](SCAN, 0);
465 if((mem[APUSTATUS] & (1<<i)) != 0){
466 apuctr[i] = apulen[v >> 3];
467 apuctr[10] |= (1<<i);
473 dmcfreq = 12 * dmclen[v & 0xf];
479 memcpy(oam, mem + (v<<8), sizeof(oam));
482 for(i = 0; i < 4; i++)
483 if((v & (1<<i)) == 0)
485 if((v & 0x10) != 0 && dmccnt == 0){
486 dmcaddr = mem[DMCADDR] * 0x40 + 0xC000;
487 dmccnt = mem[DMCLEN] * 0x10 + 1;
492 if((mem[p] & 1) != 0 && (v & 1) == 0)
505 }else if(p < 0x8000){
507 saveclock = SAVEFREQ;
509 if(mapper[map] != nil)
522 return ppuram + (p & 0x3F1F);
529 case MHORZ: if((p & 0x800) != 0) p |= 0x400; else p &= ~0x400; break;
530 case MVERT: if((p & 0x400) != 0) p |= 0x800; else p &= ~0x800; break;
531 case MSINGA: p &= ~0xC00; break;
532 case MSINGB: p |= 0xC00; break;
535 return chrb[p >> chrsh] + (p & ((1 << chrsh) - 1));
547 ppuwrite(u16int p, u8int v)