From 17024c439aff1171959f4e8df795a14267ada07b Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Wed, 9 Jun 2021 22:02:39 -0500 Subject: [PATCH] chore(ppu): emu now properly handles VRAM and OAM write guards --- src/bus.rs | 17 ++++++----------- src/ppu.rs | 33 ++++++++++++++++----------------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/bus.rs b/src/bus.rs index bd8180c..ca1bcf4 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -1,6 +1,5 @@ use crate::cartridge::Cartridge; use crate::high_ram::HighRam; -use crate::instruction::Cycle; use crate::interrupt::{Interrupt, InterruptFlag}; use crate::joypad::Joypad; use crate::ppu::{Ppu, PpuMode}; @@ -159,7 +158,7 @@ impl BusIo for Bus { 0x8000..=0x9FFF => { // 8KB Video RAM match self.ppu.stat.mode() { - PpuMode::VBlank => 0xFF, + PpuMode::Drawing => 0xFF, _ => self.ppu.read_byte(addr), } } @@ -266,14 +265,10 @@ impl BusIo for Bus { } 0x8000..=0x9FFF => { // 8KB Video RAM - - // TODO: Fix timing issues in the PPU - // match self.ppu.stat.mode() { - // PpuMode::VBlank => {} - // _ => self.ppu.write_byte(addr, byte), - // } - - self.ppu.write_byte(addr, byte) + match self.ppu.stat.mode() { + PpuMode::Drawing => {} + _ => self.ppu.write_byte(addr, byte), + } } 0xA000..=0xBFFF => { // 8KB External RAM @@ -365,7 +360,7 @@ impl BusIo for Bus { self.boot = None; } } - _ => {} // unimplemented!("Unable to write to {:#06X} in I/O Registers", addr), + _ => unimplemented!("Unable to write to {:#06X} in I/O Registers", addr), }; } 0xFF80..=0xFFFE => { diff --git a/src/ppu.rs b/src/ppu.rs index cc66c71..55d9378 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -67,6 +67,10 @@ impl BusIo for Ppu { impl Ppu { pub(crate) fn clock(&mut self) { + if !self.ctrl.lcd_enabled() { + return; + } + self.cycle += 1; match self.stat.mode() { @@ -78,7 +82,14 @@ impl Ppu { self.scan_oam(); } PpuMode::Drawing => { - if self.x_pos >= 160 { + if self.ctrl.lcd_enabled() { + // Only Draw when the LCD Is Enabled + self.draw(self.cycle.into()); + } else { + self.reset(); + } + + if self.x_pos == 160 { if self.stat.hblank_int() { // Enable HBlank LCDStat Interrupt self.int.set_lcd_stat(true); @@ -103,11 +114,6 @@ impl Ppu { self.fifo.obj.clear(); self.stat.set_mode(PpuMode::HBlank); - } else if self.ctrl.lcd_enabled() { - // Only Draw when the LCD Is Enabled - self.draw(self.cycle.into()); - } else { - self.reset(); } } PpuMode::HBlank => { @@ -413,19 +419,12 @@ impl Ppu { } fn reset(&mut self) { - // FIXME: Discover what actually is supposed to be reset here - - self.scan_state = Default::default(); - self.cycle = Cycle::new(0); - - self.x_pos = 0; - self.window_stat = Default::default(); - self.stat.set_mode(PpuMode::OamScan); self.pos.line_y = 0; + self.stat.set_mode(PpuMode::HBlank); - self.fetch.back.reset(); - self.fetch.obj.reset(); - self.obj_buffer.clear(); + // TODO: Is this an unnecessary performance hit? + let mut blank = WHITE.repeat(self.frame_buf.len() / 4); + self.frame_buf.swap_with_slice(&mut blank); } pub fn copy_to_gui(&self, frame: &mut [u8]) {