@Override public final void cartWrite(final int addr, final int data) { if (addr < 0x8000 || addr > 0xffff) { super.cartWrite(addr, data); return; } final boolean bit0 = utils.getbit(addr, registers[0]); final boolean bit1 = utils.getbit(addr, registers[1]); switch (addr >> 12) { case 0x8: // 8000-8003: prg bank 0 select prgbank0 = data; setbanks(); break; case 0x9: case 0xa: // sound registers here sndchip.write((addr & 0xf000) + (bit1 ? 2 : 0) + (bit0 ? 1 : 0), data); break; case 0xc: // c000-c003: prg bank 1 select prgbank1 = data; setbanks(); break; case 0xb: if (bit0 && bit1) { // mirroring select switch ((data >> 2) & 3) { case 0: setmirroring(Mapper.MirrorType.V_MIRROR); break; case 1: setmirroring(Mapper.MirrorType.H_MIRROR); break; case 2: setmirroring(Mapper.MirrorType.SS_MIRROR0); break; case 3: setmirroring(Mapper.MirrorType.SS_MIRROR1); break; } } else { // expansion sound register here as well sndchip.write((addr & 0xf000) + (bit1 ? 2 : 0) + (bit0 ? 1 : 0), data); } break; case 0xd: // character bank selects chrbank[(bit1 ? 2 : 0) + (bit0 ? 1 : 0)] = data; setbanks(); break; case 0xe: chrbank[(bit1 ? 2 : 0) + (bit0 ? 1 : 0) + 4] = data; setbanks(); break; case 0xf: // irq control if (!bit1) { if (!bit0) { irqreload = data; } else { irqack = utils.getbit(data, 0); irqenable = utils.getbit(data, 1); irqmode = utils.getbit(data, 2); if (irqenable) { irqcounter = irqreload; prescaler = 341; } if (firedinterrupt) { --cpu.interrupt; } firedinterrupt = false; } } else { if (!bit0) { irqenable = irqack; if (firedinterrupt) { --cpu.interrupt; } firedinterrupt = false; } } } }