}
}
+static void
+uxrom(int p, u8int v)
+{
+ static u8int b;
+
+ if(p < 0)
+ switch(p){
+ case INIT:
+ prgsh = 14;
+ chrsh = 13;
+ prgb[1] = prg + (nprg - 1) * 0x4000;
+ chrb[0] = chr;
+ break;
+ case SAVE:
+ put8(b);
+ return;
+ case RSTR:
+ b = get8();
+ break;
+ case SCAN:
+ return;
+ default:
+ nope(p);
+ return;
+ }
+ else
+ b = v % nprg;
+ prgb[0] = prg + b * 0x4000;
+}
+
+static void
+cnrom(int p, u8int v)
+{
+ static u8int b;
+
+ if(p < 0)
+ switch(p){
+ case INIT:
+ prgsh = 14;
+ chrsh = 13;
+ prgb[0] = prg;
+ if(nprg == 1)
+ prgb[1] = prg;
+ else
+ prgb[1] = prg + 0x4000;
+ break;
+ case SAVE:
+ put8(b);
+ return;
+ case RSTR:
+ b = get8();
+ break;
+ case SCAN:
+ return;
+ default:
+ nope(p);
+ return;
+ }
+ else
+ b = v % nchr;
+ chrb[0] = chr + b * 0x2000;
+
+}
+
static void
mmc3(int p, u8int v)
{
else
n--;
if(n == 0 && en)
- irq |= 2;
+ irq |= IRQMMC;
return;
case SAVE:
put8(m);
break;
case 0xC000: l = v; break;
case 0xC001: n = 0; break;
- case 0xE000: en = 0; irq &= ~2; break;
+ case 0xE000: en = 0; irq &= ~IRQMMC; break;
case 0xE001: en = 1; break;
}
return;
void (*mapper[256])(int, u8int) = {
[0] nrom,
[1] mmc1,
+ [2] uxrom,
+ [3] cnrom,
[4] mmc3,
[7] axrom,
};
memread(u16int p)
{
u8int v;
+ int i;
if(p < 0x2000){
p &= 0x7FF;
vrambuf = ppuread(ppuv);
incvram();
return vrambuf;
+ case APUSTATUS:
+ v = (irq & 3) << 6;
+ for(i = 0; i < 4; i++){
+ if(apuctr[i] != 0)
+ v |= (1<<i);
+ }
+ if(mem[0x4013] != 0)
+ v |= (1<<4);
+ irq &= ~IRQFRAME;
+ return v;
case 0x4016:
if((mem[p] & 1) != 0)
return keys & 1;
void
memwrite(u16int p, u8int v)
{
+ extern u8int apulen[32];
+ extern u16int dmclen[16];
+ int i;
+
if(p < 0x2000){
p &= 0x7FF;
}else if(p < 0x6000){
ppuwrite(ppuv, v);
incvram();
return;
+ case 0x4001:
+ case 0x4005:
+ i = (p & 0xC) >> 2;
+ apuctr[i+8] |= 0x80;
+ break;
+ case 0x4003:
+ case 0x4007:
+ case 0x400B:
+ case 0x400F:
+ i = (p & 0xC) >> 2;
+ if((mem[APUSTATUS] & (1<<i)) != 0){
+ apuctr[i] = apulen[v >> 3];
+ apuctr[10] |= (1<<i);
+ }
+ break;
+ case DMCCTRL:
+ if((v & 0x80) == 0)
+ irq &= ~IRQDMC;
+ dmcfreq = 12 * dmclen[v & 0xf];
+ break;
+ case DMCBUF:
+ v &= ~0x80;
+ break;
case 0x4014:
memcpy(oam, mem + (v<<8), sizeof(oam));
return;
+ case APUSTATUS:
+ for(i = 0; i < 4; i++)
+ if((v & (1<<i)) == 0)
+ apuctr[i] = 0;
+ if((v & 0x10) != 0 && dmccnt == 0){
+ dmcaddr = mem[DMCADDR] * 0x40 + 0xC000;
+ dmccnt = mem[DMCLEN] * 0x10 + 1;
+ }
+ irq &= ~IRQDMC;
+ break;
case 0x4016:
if((mem[p] & 1) != 0 && (v & 1) == 0)
keylatch = keys;
break;
+ case APUFRAME:
+ apuseq = 0;
+ if((v & 0x80) != 0)
+ apuclock = APUDIV;
+ else
+ apuclock = 0;
+ if((v & 0x40) != 0)
+ irq &= ~IRQFRAME;
+ break;
}
- }else if(p >= 0x8000){
+ }else if(p < 0x8000){
+ if(saveclock == 0)
+ saveclock = SAVEFREQ;
+ }else{
if(mapper[map] != nil)
mapper[map](p, v);
return;