#pragma once #include enum PpuRegister { PPUCTRL = 0x00, PPUMASK = 0x01, PPUSTATUS = 0x02, OAMADDR = 0x03, OAMDATA = 0x04, PPUSCROLL = 0x05, PPUADDR = 0x06, PPUDATA = 0x07, }; struct PpuRegisterCTRL { void SetByte(uint8_t byte) { nmiEnable = (byte & 0x80u) >> 7u; masterSlaveSelect = (byte & 0x40u) >> 6u; spriteSize = (byte & 0x20u) >> 5u; bgPatternTableAddr = (byte & 0x10u) >> 4u; spritePatternTableAddr = (byte & 0x08u) >> 3u; vramAddrIncrement = (byte & 0x04u) >> 2u; nametableBaseAddr = ((byte & 0x02u) >> 1u | (byte & 0x01u)); } uint8_t GetByte() { return nmiEnable << 7u | masterSlaveSelect << 6u | spriteSize << 5u | bgPatternTableAddr << 4u | spritePatternTableAddr << 3u | vramAddrIncrement << 2u | (nametableBaseAddr & 0xFF00u) << 1u | (nametableBaseAddr & 0xFFu); } uint16_t nametableBaseAddr; uint8_t vramAddrIncrement; uint8_t spritePatternTableAddr; uint8_t bgPatternTableAddr; uint8_t spriteSize; uint8_t masterSlaveSelect; uint8_t nmiEnable; }; struct PpuRegisterMask { void SetByte(uint8_t byte) { blueEmphasis = (byte & 0x80u) >> 7u; greenEmphasis = (byte & 0x40u) >> 6u; redEmphasis = (byte & 0x20u) >> 5u; showSprites = (byte & 0x10u) >> 4u; showBackground = (byte & 0x08u) >> 3u; showSpritesLeft = (byte & 0x04u) >> 2u; showBackgroundLeft = (byte & 0x02u) >> 1u; grayscale = byte & 0x01u; } uint8_t GetByte() { return blueEmphasis << 7u | greenEmphasis << 6u | redEmphasis << 5u | showSprites << 4u | showBackground << 3u | showSpritesLeft << 2u | showBackgroundLeft << 1u | grayscale; } uint8_t grayscale; uint8_t showBackgroundLeft; uint8_t showSpritesLeft; uint8_t showBackground; uint8_t showSprites; uint8_t redEmphasis; uint8_t greenEmphasis; uint8_t blueEmphasis; }; struct PpuRegisterStatus { void SetByte(uint8_t byte) { vblankStarted = (byte & 0x80u) >> 7u; sprite0Hit = (byte & 0x40u) >> 6u; spriteOverflow = (byte & 0x20u) >> 5u; previousLsb = byte & 0x1Fu; } uint8_t GetByte() { uint8_t byte = vblankStarted << 7u | sprite0Hit << 6u | spriteOverflow << 5u | previousLsb; vblankStarted = 0u; return byte; } uint8_t vblankStarted; uint8_t sprite0Hit; uint8_t spriteOverflow; uint8_t previousLsb; };