struct PPU : Thread, PPUcounter { alwaysinline auto interlace() const -> bool { return display.interlace; } alwaysinline auto overscan() const -> bool { return display.overscan; } alwaysinline auto vdisp() const -> uint { return r.overscan ? 240 : 225; } PPU(); ~PPU(); alwaysinline auto step(uint clocks) -> void; alwaysinline auto synchronizeCPU() -> void; static auto Enter() -> void; auto main() -> void; auto load(Markup::Node) -> bool; auto power() -> void; auto reset() -> void; auto serialize(serializer&) -> void; //memory.cpp alwaysinline auto getVramAddress() -> uint16; alwaysinline auto vramRead(bool chip, uint addr) -> uint8; alwaysinline auto vramWrite(bool chip, uint addr, uint8 data) -> void; alwaysinline auto oamRead(uint addr) -> uint8; alwaysinline auto oamWrite(uint addr, uint8 data) -> void; alwaysinline auto cgramRead(uint addr) -> uint8; alwaysinline auto cgramWrite(uint addr, uint8 data) -> void; //mmio.cpp auto read(uint24 addr, uint8 data) -> uint8; auto write(uint24 addr, uint8 data) -> void; auto latchCounters() -> void; auto updateVideoMode() -> void; privileged: struct VRAM { auto& operator[](uint offset) { return data[offset & mask]; } uint16 data[64 * 1024]; uint mask = 0x7fff; } vram; uint8 oam[544]; uint8 cgram[512]; uint32* output = nullptr; struct { bool interlace; bool overscan; } display; alwaysinline auto addClocks(uint) -> void; auto scanline() -> void; auto frame() -> void; auto refresh() -> void; struct { uint version; uint8 mdr; } ppu1, ppu2; struct Latches { uint16 vram; uint8 oam; uint8 cgram; uint8 bgofs; uint8 mode7; bool counters; bool hcounter; bool vcounter; uint10 oamAddress; uint9 cgramAddress; } latch; struct Registers { //$2100 INIDISP bool displayDisable; uint4 displayBrightness; //$2102 OAMADDL //$2103 OAMADDH uint10 oamBaseAddress; uint10 oamAddress; bool oamPriority; //$2105 BGMODE bool bgPriority; uint8 bgMode; //$210d BG1HOFS uint16 hoffsetMode7; //$210e BG1VOFS uint16 voffsetMode7; //$2115 VMAIN bool vramIncrementMode; uint2 vramMapping; uint8 vramIncrementSize; //$2116 VMADDL //$2117 VMADDH uint16 vramAddress; //$211a M7SEL uint2 repeatMode7; bool vflipMode7; bool hflipMode7; //$211b M7A uint16 m7a; //$211c M7B uint16 m7b; //$211d M7C uint16 m7c; //$211e M7D uint16 m7d; //$211f M7X uint16 m7x; //$2120 M7Y uint16 m7y; //$2121 CGADD uint9 cgramAddress; //$2133 SETINI bool extbg; bool pseudoHires; bool overscan; bool interlace; //$213c OPHCT uint16 hcounter; //$213d OPVCT uint16 vcounter; } r; #include "background/background.hpp" #include "object/object.hpp" #include "window/window.hpp" #include "screen/screen.hpp" Background bg1; Background bg2; Background bg3; Background bg4; Object obj; Window window; Screen screen; friend class PPU::Background; friend class PPU::Object; friend class PPU::Window; friend class PPU::Screen; friend class Scheduler; struct Debugger { hook void> vramRead; hook void> oamRead; hook void> cgramRead; hook void> vramWrite; hook void> oamWrite; hook void> cgramWrite; } debugger; }; extern PPU ppu;