PPU optimization

This commit is contained in:
Franco Colmenarez 2021-11-06 21:36:16 -05:00
parent d94b912ff6
commit f7ca3fcc25
6 changed files with 15 additions and 21 deletions

View File

@ -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()) {

View File

@ -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)
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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;
}