11 uchar *prgb[2], *chrb[2];
12 extern uchar *prg, *chr;
13 extern int nprg, nchr;
16 static int vramlatch = 1, keylatch = 0xFF;
17 extern int keys, nmi, map, mirr;
27 prgb[1] = prg + 0x4000;
29 chrb[1] = chr + 0x1000;
37 static u8int n, s, mode, c0, c1, pr;
39 static int mirrs[] = {MSINGB, MSINGA, MVERT, MHORZ};
63 mirr = mirrs[mode & 3];
74 if((mode & 0x10) != 0)
88 prgb[1] = prg + pr * 0x4000;
91 prgb[0] = prg + pr * 0x4000;
92 prgb[1] = prg + (0x0f % nprg) * 0x4000;
95 prgb[0] = prg + (pr & 0xfe) * 0x4000;
96 prgb[1] = prg + (pr | 1) * 0x4000;
100 if((mode & 0x10) != 0){
101 chrb[0] = chr + c0 * 0x1000;
102 chrb[1] = chr + c1 * 0x1000;
104 chrb[0] = chr + (c0 & 0xfe) * 0x1000;
105 chrb[1] = chr + (c0 | 1) * 0x1000;
111 void (*mapper[256])(int, u8int) = {
119 if((mem[PPUCTRL] & VRAMINC) != 0)
129 static u8int vrambuf;
134 }else if(p < 0x6000){
140 mem[p] &= ~PPUVBLANK;
144 return oam[mem[0x2003]];
148 vrambuf = ppuread(ppuv);
152 vrambuf = ppuread(ppuv);
156 if((mem[p] & 1) != 0)
159 keylatch = (keylatch >> 1) | 0x80;
166 if((p & 0x4000) != 0)
167 return prgb[1][p - 0xC000];
169 return prgb[0][p - 0x8000];
175 memwrite(u16int p, u8int v)
179 }else if(p < 0x6000){
184 if((v & PPUNMI) != 0 && (mem[PPUSTATUS] & PPUVBLANK) != 0)
186 pput = (pput & 0xF3FF) | ((v & 3) << 10);
191 oam[mem[0x2003]++] = v;
196 pput = (pput & 0xFFE0) | (v >> 3);
198 pput = (pput & 0x0C1F) | ((v & 0xF8) << 2) | ((v & 7) << 12);
203 pput = (pput & 0xFF) | (v << 8) & 0x3F00;
205 pput = (pput & 0xFF00) | v;
215 memcpy(oam, mem + (v<<8), sizeof(oam));
218 if((mem[p] & 1) != 0 && (v & 1) == 0)
222 }else if(p >= 0x8000){
223 if(mapper[map] != nil)
236 return ppuram + (p & 0x3F1F);
243 case MHORZ: if((p & 0x800) != 0) p |= 0x400; else p &= ~0x400; break;
244 case MVERT: if((p & 0x400) != 0) p |= 0x800; else p &= ~0x800; break;
245 case MSINGA: p &= ~0xC00; break;
246 case MSINGB: p |= 0xC00; break;
251 return chrb[1] + p - 0x1000;
263 ppuwrite(u16int p, u8int v)