mirror of
https://github.com/FranLMSP/rmg-001.git
synced 2024-11-23 10:12:11 +00:00
Refactor timer
This commit is contained in:
parent
c1dc14680e
commit
5acb3ba6d5
12
src/bus.rs
12
src/bus.rs
@ -13,7 +13,7 @@ use crate::ppu::{
|
|||||||
DMA_ADDRESS,
|
DMA_ADDRESS,
|
||||||
};
|
};
|
||||||
use crate::cpu::{Interrupt};
|
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};
|
use crate::joypad::{Joypad, JOYPAD_ADDRESS};
|
||||||
|
|
||||||
pub struct AddressRange {
|
pub struct AddressRange {
|
||||||
@ -53,12 +53,12 @@ pub const INTERRUPT_FLAG_ADDRESS: u16 = 0xFF0F;
|
|||||||
pub struct Bus {
|
pub struct Bus {
|
||||||
game_rom: ROM,
|
game_rom: ROM,
|
||||||
data: [u8; 0x10000],
|
data: [u8; 0x10000],
|
||||||
pub reset_timer: bool,
|
|
||||||
joypad: Rc<RefCell<Joypad>>,
|
joypad: Rc<RefCell<Joypad>>,
|
||||||
|
timer: Rc<RefCell<Timer>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bus {
|
impl Bus {
|
||||||
pub fn new(joypad: Rc<RefCell<Joypad>>) -> Self {
|
pub fn new(joypad: Rc<RefCell<Joypad>>, timer: Rc<RefCell<Timer>>) -> Self {
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
if args.len() < 2 {
|
if args.len() < 2 {
|
||||||
println!("Please, specify a ROM file");
|
println!("Please, specify a ROM file");
|
||||||
@ -98,8 +98,8 @@ impl Bus {
|
|||||||
Self {
|
Self {
|
||||||
data,
|
data,
|
||||||
game_rom,
|
game_rom,
|
||||||
reset_timer: false,
|
|
||||||
joypad,
|
joypad,
|
||||||
|
timer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +110,8 @@ impl Bus {
|
|||||||
return 0b11100000 | self.data[address as usize];
|
return 0b11100000 | self.data[address as usize];
|
||||||
} else if address == JOYPAD_ADDRESS {
|
} else if address == JOYPAD_ADDRESS {
|
||||||
return self.joypad.borrow().read(self.data[address as usize]);
|
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]
|
self.data[address as usize]
|
||||||
}
|
}
|
||||||
@ -137,7 +139,7 @@ impl Bus {
|
|||||||
self.data[address as usize] = data;
|
self.data[address as usize] = data;
|
||||||
self.data[(WORK_RAM_1.begin() + (address - ECHO_RAM.begin())) as usize] = data; // Copy to the working RAM
|
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 {
|
} else if address == TIMER_DIVIDER_REGISTER_ADDRESS {
|
||||||
self.reset_timer = true;
|
self.timer.borrow_mut().reset();
|
||||||
} else if address == LCD_CONTROL_ADDRESS {
|
} else if address == LCD_CONTROL_ADDRESS {
|
||||||
self.data[address as usize] = data;
|
self.data[address as usize] = data;
|
||||||
// Check if LCD is being turned on or off
|
// Check if LCD is being turned on or off
|
||||||
|
@ -14,19 +14,20 @@ pub struct Emulator {
|
|||||||
cpu: CPU,
|
cpu: CPU,
|
||||||
ppu: PPU,
|
ppu: PPU,
|
||||||
bus: Bus,
|
bus: Bus,
|
||||||
timer: Timer,
|
timer: Rc<RefCell<Timer>>,
|
||||||
joypad: Rc<RefCell<Joypad>>,
|
joypad: Rc<RefCell<Joypad>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Emulator {
|
impl Emulator {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let joypad = Rc::new(RefCell::new(Joypad::new()));
|
let joypad = Rc::new(RefCell::new(Joypad::new()));
|
||||||
|
let timer = Rc::new(RefCell::new(Timer::new()));
|
||||||
Self {
|
Self {
|
||||||
cpu: CPU::new(),
|
cpu: CPU::new(),
|
||||||
ppu: PPU::new(),
|
ppu: PPU::new(),
|
||||||
bus: Bus::new(Rc::clone(&joypad)),
|
bus: Bus::new(Rc::clone(&joypad), Rc::clone(&timer)),
|
||||||
timer: Timer::new(),
|
timer,
|
||||||
joypad: joypad,
|
joypad,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,12 +108,8 @@ impl Emulator {
|
|||||||
self.cpu.reset_cycles();
|
self.cpu.reset_cycles();
|
||||||
while self.cpu.get_cycles().to_t().0 <= cpu_cycles.0 {
|
while self.cpu.get_cycles().to_t().0 <= cpu_cycles.0 {
|
||||||
self.cpu.run(&mut self.bus);
|
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.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
|
// 1 CPU cycle = 238.42ns
|
||||||
// thread::sleep(time::Duration::from_nanos((self.cpu.get_last_op_cycles().0 * 238).try_into().unwrap()));
|
// 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];
|
let mut frame: [u8; 144 * 160 * 4] = [0; 144 * 160 * 4];
|
||||||
while !exit {
|
while !exit {
|
||||||
self.cpu.run(&mut self.bus);
|
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.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() >= 1258895; // log 1
|
||||||
exit = self.cpu.get_exec_calls_count() >= 161502; // log 2
|
exit = self.cpu.get_exec_calls_count() >= 161502; // log 2
|
||||||
|
@ -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;
|
self.divider = 0;
|
||||||
bus.force_write(TIMER_DIVIDER_REGISTER_ADDRESS, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_cycles(&mut self, bus: &mut Bus, cycles: Cycles) {
|
pub fn do_cycles(&mut self, bus: &mut Bus, cycles: Cycles) {
|
||||||
@ -41,7 +45,6 @@ impl Timer {
|
|||||||
self.cycle(bus);
|
self.cycle(bus);
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
bus.force_write(TIMER_DIVIDER_REGISTER_ADDRESS, self.divider.to_be_bytes()[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cycle(&mut self, bus: &mut Bus) {
|
fn cycle(&mut self, bus: &mut Bus) {
|
||||||
|
Loading…
Reference in New Issue
Block a user