public void Update(int cpuCycles) { byte controlRegister = memory.ReadByte(0xFF40); if (controlRegister.IsBitSet(7) == false) { // Disabling LCD can be only done during VBlank CurrentMode = Mode.VBlank; cycles = 456; CurrentLine = 0; windowLine = 0; return; } cycles += cpuCycles; switch (CurrentMode) { case Mode.OamSearch: if (cycles >= 80) { CurrentMode = Mode.PixelTransfer; cycles -= 80; } break; case Mode.PixelTransfer: if (cycles >= 172) { CurrentMode = Mode.HBlank; cycles -= 172; RenderScanLine(controlRegister); } break; case Mode.HBlank: if (cycles >= 204) { CurrentLine++; cycles -= 204; if (CurrentLine == HEIGHT) { CurrentMode = Mode.VBlank; CPU.RequestInterrupt(memory, CPU.Interrupt.VBlank); RenderEvent?.Invoke(); } else { CurrentMode = Mode.OamSearch; } } break; case Mode.VBlank: if (cycles >= 456) { cycles -= 456; // Not really rendering anything but the line counter keeps updating during the V-Blank period if (CurrentLine == 153) { CurrentMode = Mode.OamSearch; CurrentLine = 0; windowLine = 0; } else { CurrentLine++; } } break; } }