they look correct if i dont change the scroll registers on $2006 writes. am i parsing the values correctly here?
Code: Select all
void writePPUregs(uint16_t addr, uint8_t value) {
PPU->regs[addr & 7] = value;
lastwritten = value;
switch (addr) {
case 0x2000:
if (value&128) PPU->nmivblank = 1; else PPU->nmivblank = 0;
if (value&32) PPU->sprsize = 16; else PPU->sprsize = 8;
if (value&16) PPU->bgtable = 0x1000; else PPU->bgtable = 0x0000;
if (value&8) PPU->sprtable = 0x1000; else PPU->sprtable = 0x0000;
if (value&4) PPU->addrinc = 32; else PPU->addrinc = 1;
PPU->nametable = value&3;
break;
case 0x2001:
if (value&16) PPU->sprvisible = 1; else PPU->sprvisible = 0;
if (value&8) PPU->bgvisible = 1; else PPU->bgvisible = 0;
if (value&4) PPU->sprclip = 0; else PPU->sprclip = 1;
if (value&2) PPU->bgclip = 0; else PPU->bgclip = 1;
break;
case 0x2003:
OAM->addr = value;
break;
case 0x2004:
OAM->RAM[OAM->addr++] = value;
break;
case 0x2005:
if (PPU->addrlatch == 0) {
PPU->xscroll = value;
PPU->addrlatch = 1;
} else {
PPU->yscroll = value;
PPU->addrlatch = 0;
}
break;
case 0x2006:
if (PPU->addrlatch == 0) {
PPU->r2006[1] = value;
PPU->nametable = ((value >> 2) & 3);
PPU->xscroll = (PPU->xscroll & 0x3F) | (((uint16_t)value & 3) << 6);
PPU->xscroll = (PPU->xscroll & 0xF8) | (((uint16_t)value >> 4) & 7);
PPU->addrlatch = 1;
} else {
PPU->r2006[0] = value;
PPU->yscroll = (PPU->yscroll & 7) | ((uint16_t)value << 3);
PPU->xscroll = (PPU->xscroll & 0xC7) | (((uint16_t)value >> 2) & 0x38);
PPU->addr = ((uint16_t)PPU->r2006[1] << 8) | (uint16_t)PPU->r2006[0];
PPU->addrlatch = 0;
}
break;
case 0x2007:
writePPU(PPU->addr, value);
PPU->addr = (PPU->addr + PPU->addrinc) & 0x3FFF;
break;
}
}