diff --git a/src/bus.rs b/src/bus.rs index 5d9fda0..816af4d 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -13,7 +13,7 @@ use crate::ppu::{ DMA_ADDRESS, }; use crate::cpu::{Interrupt}; -use crate::timer::{TIMER_DIVIDER_REGISTER_ADDRESS}; +use crate::timer::{Timer, TIMER_DIVIDER_REGISTER_ADDRESS}; use crate::joypad::{Joypad, JOYPAD_ADDRESS}; pub struct AddressRange { @@ -53,12 +53,12 @@ pub const INTERRUPT_FLAG_ADDRESS: u16 = 0xFF0F; pub struct Bus { game_rom: ROM, data: [u8; 0x10000], - pub reset_timer: bool, joypad: Rc>, + timer: Rc>, } impl Bus { - pub fn new(joypad: Rc>) -> Self { + pub fn new(joypad: Rc>, timer: Rc>) -> Self { let args: Vec = std::env::args().collect(); if args.len() < 2 { println!("Please, specify a ROM file"); @@ -98,8 +98,8 @@ impl Bus { Self { data, game_rom, - reset_timer: false, joypad, + timer, } } @@ -110,6 +110,8 @@ impl Bus { return 0b11100000 | self.data[address as usize]; } else if address == JOYPAD_ADDRESS { return self.joypad.borrow().read(self.data[address as usize]); + } else if address == TIMER_DIVIDER_REGISTER_ADDRESS { + return self.timer.borrow().read_divider(); } self.data[address as usize] } @@ -137,7 +139,7 @@ impl Bus { self.data[address as usize] = data; self.data[(WORK_RAM_1.begin() + (address - ECHO_RAM.begin())) as usize] = data; // Copy to the working RAM } else if address == TIMER_DIVIDER_REGISTER_ADDRESS { - self.reset_timer = true; + self.timer.borrow_mut().reset(); } else if address == LCD_CONTROL_ADDRESS { self.data[address as usize] = data; // Check if LCD is being turned on or off diff --git a/src/emulator.rs b/src/emulator.rs index d4cbe66..3d6336b 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -14,19 +14,20 @@ pub struct Emulator { cpu: CPU, ppu: PPU, bus: Bus, - timer: Timer, + timer: Rc>, joypad: Rc>, } impl Emulator { pub fn new() -> Self { let joypad = Rc::new(RefCell::new(Joypad::new())); + let timer = Rc::new(RefCell::new(Timer::new())); Self { cpu: CPU::new(), ppu: PPU::new(), - bus: Bus::new(Rc::clone(&joypad)), - timer: Timer::new(), - joypad: joypad, + bus: Bus::new(Rc::clone(&joypad), Rc::clone(&timer)), + timer, + joypad, } } @@ -107,12 +108,8 @@ impl Emulator { self.cpu.reset_cycles(); 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().to_t(), frame_buffer); - self.timer.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles().to_t()); + self.timer.borrow_mut().do_cycles(&mut self.bus, self.cpu.get_last_op_cycles().to_t()); // 1 CPU cycle = 238.42ns // thread::sleep(time::Duration::from_nanos((self.cpu.get_last_op_cycles().0 * 238).try_into().unwrap())); @@ -125,12 +122,8 @@ impl Emulator { let mut frame: [u8; 144 * 160 * 4] = [0; 144 * 160 * 4]; while !exit { 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().to_t(), &mut frame); - self.timer.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles().to_t()); + self.timer.borrow_mut().do_cycles(&mut self.bus, self.cpu.get_last_op_cycles().to_t()); // exit = self.cpu.get_exec_calls_count() >= 1258895; // log 1 exit = self.cpu.get_exec_calls_count() >= 161502; // log 2 diff --git a/src/timer.rs b/src/timer.rs index 0068221..854259d 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -28,9 +28,13 @@ impl Timer { } } - pub fn reset(&mut self, bus: &mut Bus) { + pub fn read_divider(&self) -> u8 { + self.divider.to_be_bytes()[0] + } + + pub fn reset(&mut self) { + println!("Reset divider"); self.divider = 0; - bus.force_write(TIMER_DIVIDER_REGISTER_ADDRESS, 0); } pub fn do_cycles(&mut self, bus: &mut Bus, cycles: Cycles) { @@ -41,7 +45,6 @@ impl Timer { self.cycle(bus); count += 1; } - bus.force_write(TIMER_DIVIDER_REGISTER_ADDRESS, self.divider.to_be_bytes()[0]); } fn cycle(&mut self, bus: &mut Bus) {