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;
143 static u8int m, b[8], l, n, en;
152 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
153 prgb[3] = prgb[2] + 0x2000;
165 for(i = 0; i < 8; i++)
173 for(i = 0; i < 8; i++)
183 if(((m ^ v) & 0xc0) != 0){
205 case 0xC000: l = v; break;
206 case 0xC001: n = 0; break;
207 case 0xE000: en = 0; irq &= ~2; break;
208 case 0xE001: en = 1; break;
213 prgb[0] = prg + (2 * nprg - 2) * 0x2000;
214 prgb[2] = prg + b[6] * 0x2000;
216 prgb[0] = prg + b[6] * 0x2000;
217 prgb[2] = prg + (2 * nprg - 2) * 0x2000;
219 prgb[1] = prg + b[7] * 0x2000;
221 for(i = 0; i < 2; i++){
222 chrb[j = (i << 1) ^ c] = chr + (b[i] >> 1) * 0x800;
223 chrb[j+1] = chrb[j] + 0x400;
225 for(i = 2; i < 6; i++)
226 chrb[(i + 2) ^ c] = chr + b[i] * 0x400;
252 prgb[0] = prg + (b & 3) * 0x8000;
253 prgb[1] = prgb[0] + 0x4000;
256 void (*mapper[256])(int, u8int) = {
269 if((mem[PPUCTRL] & VRAMINC) != 0)
274 if(mmc3hack && (old & (1<<12)) == 0 && (ppuv & (1<<12)) != 0)
275 mapper[map](SCAN, 0);
285 }else if(p < 0x6000){
291 mem[p] &= ~PPUVBLANK;
295 return oam[mem[0x2003]];
299 vrambuf = ppuread(ppuv);
303 vrambuf = ppuread(ppuv);
307 if((mem[p] & 1) != 0)
310 keylatch = (keylatch >> 1) | 0x80;
318 return prgb[p >> prgsh][p & ((1 << prgsh) - 1)];
324 memwrite(u16int p, u8int v)
328 }else if(p < 0x6000){
333 if((mem[PPUCTRL] & PPUNMI) == 0 && (v & PPUNMI) != 0 &&
334 (mem[PPUSTATUS] & PPUVBLANK) != 0)
336 pput = (pput & 0xF3FF) | ((v & 3) << 10);
341 oam[mem[0x2003]++] = v;
346 pput = (pput & 0xFFE0) | (v >> 3);
348 pput = (pput & 0x0C1F) | ((v & 0xF8) << 2) | ((v & 7) << 12);
353 pput = (pput & 0xFF) | (v << 8) & 0x3F00;
355 pput = (pput & 0xFF00) | v;
356 if(mmc3hack && (ppuv & (1<<12)) == 0 && (pput & (1<<12)) != 0)
357 mapper[map](SCAN, 0);
367 memcpy(oam, mem + (v<<8), sizeof(oam));
370 if((mem[p] & 1) != 0 && (v & 1) == 0)
374 }else if(p >= 0x8000){
375 if(mapper[map] != nil)
388 return ppuram + (p & 0x3F1F);
395 case MHORZ: if((p & 0x800) != 0) p |= 0x400; else p &= ~0x400; break;
396 case MVERT: if((p & 0x400) != 0) p |= 0x800; else p &= ~0x800; break;
397 case MSINGA: p &= ~0xC00; break;
398 case MSINGB: p |= 0xC00; break;
401 return chrb[p >> chrsh] + (p & ((1 << chrsh) - 1));
413 ppuwrite(u16int p, u8int v)