public void Render() { //Increment mode and set lock states if (ScheduledModeChange is not null) { PPU.Mode = (Mode)ScheduledModeChange; ScheduledModeChange = null; if (PPU.Mode == Mode.OAMSearch) { PPU.OAM.Locked = true; PPU.VRAM.Locked = false; } if (PPU.Mode == Mode.Transfer) { PPU.OAM.Locked = true; PPU.VRAM.Locked = true; } if (PPU.Mode == Mode.HBlank) { PPU.OAM.Locked = false; PPU.VRAM.Locked = false; } if (PPU.Mode == Mode.VBlank) { PPU.OAM.Locked = false; PPU.VRAM.Locked = false; //According to TCAGBD the OAM flag is also triggering on this if (PPU.Enable_VBlankInterrupt || PPU.Enable_OAM_Interrupt) { PPU.EnableLCDCStatusInterrupt(); } PPU.EnableVBlankInterrupt(); fs.Draw(); } } //We should be handling this during the transition from HBlank to OAMSearch if (PPU.Mode is Mode.OAMSearch or Mode.VBlank) { //We only want to increment the line register if we aren't on the very first line if (!SkippingLYIncrementBecauseStartingLineOne) { PPU.LY++; } else { SkippingLYIncrementBecauseStartingLineOne = false; } if (PPU.LY == PPU.LYC) { PPU.LYCInterrupt = true; } if (PPU.LY == 154) { PPU.LY = 0; fetcher.FrameFinished(); ScheduledModeChange = Mode.OAMSearch; SkippingLYIncrementBecauseStartingLineOne = true; return; } } ExecuteModeTick(); }