From f7ca3fcc25969680a9147381129ebad052a0c28d Mon Sep 17 00:00:00 2001 From: Franco Colmenarez Date: Sat, 6 Nov 2021 21:36:16 -0500 Subject: [PATCH] PPU optimization --- src/bus.rs | 2 +- src/cpu.rs | 4 ++-- src/emulator.rs | 6 +++--- src/ppu.rs | 20 ++++++-------------- src/rom.rs | 2 ++ src/timer.rs | 2 +- 6 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/bus.rs b/src/bus.rs index dec066b..f4b0075 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -57,7 +57,7 @@ pub struct Bus { impl Bus { pub fn new() -> Self { - let game_rom = match ROM::load_file("ignore/dr-mario.gb".to_string()) { + let game_rom = match ROM::load_file("ignore/tetris.gb".to_string()) { // let game_rom = match ROM::load_file("ignore/mooneye/emulator-only/mbc1/bits_bank1.gb".to_string()) { // let game_rom = match ROM::load_file("roms/cpu_instrs.gb".to_string()) { // let game_rom = match ROM::load_file("roms/cpu_instrs_individual/01-special.gb".to_string()) { diff --git a/src/cpu.rs b/src/cpu.rs index 8c2be69..3146f15 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -831,8 +831,8 @@ pub enum Opcode { pub struct Cycles(pub usize); impl Cycles { - pub fn to_t(&self) -> usize { - self.0 * 4 + pub fn to_t(&self) -> Self { + Self(self.0 * 4) } } diff --git a/src/emulator.rs b/src/emulator.rs index a6eea7a..56d4807 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -99,13 +99,13 @@ impl Emulator { pub fn run(&mut self, cpu_cycles: Cycles, frame_buffer: &mut [u8]) { self.cpu.reset_cycles(); - while self.cpu.get_cycles().to_t() <= cpu_cycles.0 { + while self.cpu.get_cycles().to_t().0 <= cpu_cycles.0 { self.cpu.run(&mut self.bus); if self.bus.reset_timer { self.bus.reset_timer = false; self.timer.reset(&mut self.bus); } - self.ppu.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles(), frame_buffer); + self.ppu.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles().to_t(), frame_buffer); self.timer.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles()); // 1 CPU cycle = 238.42ns @@ -123,7 +123,7 @@ impl Emulator { self.bus.reset_timer = false; self.timer.reset(&mut self.bus); } - self.ppu.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles(), &mut frame); + self.ppu.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles().to_t(), &mut frame); self.timer.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles()); // exit = self.cpu.get_exec_calls_count() >= 1258895; // log 1 diff --git a/src/ppu.rs b/src/ppu.rs index c62c647..84d4522 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -186,42 +186,34 @@ impl PPU { } pub fn do_cycles(&mut self, bus: &mut Bus, cycles: Cycles, frame_buffer: &mut [u8]) { - let mut count = 0; - while count < cycles.to_t() { - self.cycle(bus, frame_buffer); - count += 1; - } - } - - pub fn cycle(&mut self, bus: &mut Bus, frame_buffer: &mut [u8]) { if !PPU::get_lcd_control(bus, LCDControl::LCDEnable) { - self.increment_cycles(Cycles(1)); + self.increment_cycles(cycles); return; } if PPU::get_lcd_y(bus) < 144 { - if self.cycles.0 == 0 { + if self.cycles.0 <= 80 && !PPU::get_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::SearchingOAM)) { // Mode 2 OAM scan PPU::set_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::SearchingOAM), true); self.stat_interrupt(bus); self.oam_search(bus); - } else if self.cycles.0 == 80 + 1 { + } else if self.cycles.0 > 80 && self.cycles.0 <= 80 + 172 && !PPU::get_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::TransferringToLCD)) { // Mode 3 drawing pixel line. This could also last 289 cycles self.draw_line(bus, frame_buffer); PPU::set_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::TransferringToLCD), true); - } else if self.cycles.0 == 80 + 172 + 1 { + } else if self.cycles.0 > 80 + 172 && self.cycles.0 <= 80 + 172 + 204 && !PPU::get_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::HBlank)) { // Mode 0 Horizontal blank. This could last 87 or 204 cycles depending on the mode 3 PPU::set_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::HBlank), true); self.stat_interrupt(bus); } - } else if PPU::get_lcd_y(bus) == 144 && self.cycles.0 == 0 { + } else if PPU::get_lcd_y(bus) >= 144 && !PPU::get_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::VBlank)) { // Mode 1 Vertical blank bus.set_interrupt_flag(Interrupt::VBlank, true); PPU::set_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::VBlank), true); self.stat_interrupt(bus); } - self.increment_cycles(Cycles(1)); + self.increment_cycles(cycles); // Horizontal scan completed if self.cycles.0 > 456 { diff --git a/src/rom.rs b/src/rom.rs index 2f304eb..815e979 100644 --- a/src/rom.rs +++ b/src/rom.rs @@ -18,6 +18,7 @@ enum Region { NonJapanese, } +#[derive(Debug, Copy, Clone)] enum MBC { NoMBC, MBC1, @@ -159,6 +160,7 @@ impl ROM { let info = ROMInfo::from_bytes(&data); println!("has ram {}", info.has_ram); + println!("mbc {:?}", info.mbc); let ram = Vec::with_capacity(info.ram_size() as usize); Ok(Self { diff --git a/src/timer.rs b/src/timer.rs index 05bf168..f326253 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -31,7 +31,7 @@ impl Timer { pub fn do_cycles(&mut self, bus: &mut Bus, cycles: Cycles) { let mut count = 0; - while count < cycles.to_t() { + while count < cycles.to_t().0 { self.cycle(bus); count += 1; }