rmg-001/src/emulator.rs

144 lines
4.9 KiB
Rust
Raw Normal View History

2021-11-05 15:08:17 +00:00
// use std::{thread, time};
2021-11-01 02:02:09 +00:00
use winit_input_helper::WinitInputHelper;
use winit::event::{VirtualKeyCode};
2021-10-14 01:50:48 +00:00
2021-11-01 02:02:09 +00:00
use crate::cpu::{CPU, Cycles, Interrupt};
use crate::ppu::PPU;
use crate::bus::Bus;
2021-10-30 14:13:31 +00:00
use crate::timer::Timer;
2021-11-05 15:08:17 +00:00
use crate::joypad::{Button};
2021-10-26 22:34:59 +00:00
pub struct Emulator {
cpu: CPU,
ppu: PPU,
bus: Bus,
timer: Timer,
}
2021-10-26 22:34:59 +00:00
impl Emulator {
pub fn new() -> Self {
Self {
cpu: CPU::new(),
ppu: PPU::new(),
bus: Bus::new(),
timer: Timer::new(),
2021-11-01 02:02:09 +00:00
}
}
pub fn handle_input(&mut self, input: &WinitInputHelper) {
let mut change = false;
if input.key_pressed(VirtualKeyCode::K) {
change = true;
self.bus.joypad.press(Button::A);
2021-11-01 02:02:09 +00:00
}
if input.key_pressed(VirtualKeyCode::J) {
change = true;
self.bus.joypad.press(Button::B);
2021-11-01 02:02:09 +00:00
}
if input.key_pressed(VirtualKeyCode::W) {
change = true;
self.bus.joypad.press(Button::Up);
2021-11-01 02:02:09 +00:00
}
if input.key_pressed(VirtualKeyCode::S) {
change = true;
self.bus.joypad.press(Button::Down);
2021-11-01 02:02:09 +00:00
}
if input.key_pressed(VirtualKeyCode::A) {
change = true;
self.bus.joypad.press(Button::Left);
2021-11-01 02:02:09 +00:00
}
if input.key_pressed(VirtualKeyCode::D) {
change = true;
self.bus.joypad.press(Button::Right);
2021-11-01 02:02:09 +00:00
}
if input.key_pressed(VirtualKeyCode::N) {
change = true;
self.bus.joypad.press(Button::Start);
2021-11-01 02:02:09 +00:00
}
if input.key_pressed(VirtualKeyCode::B) {
change = true;
self.bus.joypad.press(Button::Select);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::K) {
change = true;
self.bus.joypad.release(Button::A);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::J) {
change = true;
self.bus.joypad.release(Button::B);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::W) {
change = true;
self.bus.joypad.release(Button::Up);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::S) {
change = true;
self.bus.joypad.release(Button::Down);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::A) {
change = true;
self.bus.joypad.release(Button::Left);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::D) {
change = true;
self.bus.joypad.release(Button::Right);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::N) {
change = true;
self.bus.joypad.release(Button::Start);
2021-11-01 02:02:09 +00:00
}
if input.key_released(VirtualKeyCode::B) {
change = true;
self.bus.joypad.release(Button::Select);
2021-11-01 02:02:09 +00:00
}
if change {
self.bus.set_interrupt_flag(Interrupt::Joypad, true);
}
}
2021-11-03 16:59:48 +00:00
pub fn run(&mut self, cpu_cycles: Cycles, frame_buffer: &mut [u8]) {
2021-10-26 22:34:59 +00:00
self.cpu.reset_cycles();
2021-11-04 18:13:22 +00:00
while self.cpu.get_cycles().to_t() <= cpu_cycles.0 {
2021-10-26 22:34:59 +00:00
self.cpu.run(&mut self.bus);
2021-11-02 03:22:43 +00:00
if self.bus.reset_timer {
self.bus.reset_timer = false;
self.timer.reset(&mut self.bus);
}
2021-11-03 16:59:48 +00:00
self.ppu.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles(), frame_buffer);
self.timer.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles());
2021-11-03 13:36:30 +00:00
// 1 CPU cycle = 238.42ns
// thread::sleep(time::Duration::from_nanos((self.cpu.get_last_op_cycles().0 * 238).try_into().unwrap()));
2021-10-26 22:34:59 +00:00
}
}
pub fn cpu_loop(&mut self) {
2021-10-14 01:50:48 +00:00
let mut exit = false;
2021-11-03 16:59:48 +00:00
let mut frame: [u8; 144 * 160] = [0; 144 * 160];
2021-10-14 01:50:48 +00:00
while !exit {
self.cpu.run(&mut self.bus);
2021-11-03 13:36:30 +00:00
if self.bus.reset_timer {
self.bus.reset_timer = false;
self.timer.reset(&mut self.bus);
}
2021-11-03 16:59:48 +00:00
self.ppu.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles(), &mut frame);
2021-11-03 13:36:30 +00:00
self.timer.do_cycles(&mut self.bus, self.cpu.get_last_op_cycles());
2021-10-14 01:50:48 +00:00
2021-10-20 02:55:35 +00:00
// exit = self.cpu.get_exec_calls_count() >= 1258895; // log 1
2021-11-03 13:36:30 +00:00
exit = self.cpu.get_exec_calls_count() >= 161502; // log 2
2021-10-20 02:55:35 +00:00
// exit = self.cpu.get_exec_calls_count() >= 1068422; // log 3
2021-10-20 03:36:10 +00:00
// exit = self.cpu.get_exec_calls_count() >= 1262766; // log 4
// exit = self.cpu.get_exec_calls_count() >= 1763388; // log 5
// exit = self.cpu.get_exec_calls_count() >= 1763388; // log 5
// exit = self.cpu.get_exec_calls_count() >= 243272; // log 6
2021-10-20 17:29:55 +00:00
// exit = self.cpu.get_exec_calls_count() >= 287416; // log 7
2021-10-20 18:39:39 +00:00
// exit = self.cpu.get_exec_calls_count() >= 223892; // log 8
2021-10-20 18:47:59 +00:00
// exit = self.cpu.get_exec_calls_count() >= 4420382; // log 9
2021-10-20 19:33:11 +00:00
// exit = self.cpu.get_exec_calls_count() >= 6714723; // log 10
// exit = self.cpu.get_exec_calls_count() >= 7429762; // log 11
2021-10-14 01:50:48 +00:00
}
}
}