make things neater :)

This commit is contained in:
Alex Janka 2023-02-12 08:51:23 +11:00
parent d6276a1478
commit ab3cba1ec0
4 changed files with 89 additions and 101 deletions

View file

@ -6,7 +6,7 @@ use clap::{ArgGroup, Parser};
use minifb::{Window, WindowOptions}; use minifb::{Window, WindowOptions};
use processor::{ use processor::{
memory::{rom::ROM, Memory}, memory::{rom::ROM, Memory},
Registers, CPU, CPU,
}; };
use std::{ use std::{
fs, fs,
@ -66,32 +66,6 @@ struct Args {
step_by: Option<usize>, step_by: Option<usize>,
} }
fn cpu_ram_init(cpu: &mut CPU) {
cpu.memory.set(0xFF04, 0xAD);
cpu.memory.set(0xFF10, 0x80);
cpu.memory.set(0xFF11, 0xBF);
cpu.memory.set(0xFF12, 0xF3);
cpu.memory.set(0xFF14, 0xBF);
cpu.memory.set(0xFF16, 0x3F);
cpu.memory.set(0xFF19, 0xBF);
cpu.memory.set(0xFF1A, 0x7F);
cpu.memory.set(0xFF1B, 0xFF);
cpu.memory.set(0xFF1C, 0x9F);
cpu.memory.set(0xFF1E, 0xBF);
cpu.memory.set(0xFF20, 0xFF);
cpu.memory.set(0xFF23, 0xBF);
cpu.memory.set(0xFF24, 0x77);
cpu.memory.set(0xFF25, 0xF3);
cpu.memory.set(0xFF26, 0xF1);
cpu.memory.set(0xFF40, 0x91);
cpu.memory.set(0xFF47, 0xFC);
cpu.memory.set(0xFF48, 0xFF);
cpu.memory.set(0xFF49, 0xFF);
for i in 0xC000..0xE000 {
cpu.memory.set(i, if rand::random() { 0xFF } else { 0x00 });
}
}
static mut PAUSE_ENABLED: bool = false; static mut PAUSE_ENABLED: bool = false;
static mut PAUSE_QUEUED: bool = false; static mut PAUSE_QUEUED: bool = false;
// static mut VERBOSE: bool = false; // static mut VERBOSE: bool = false;
@ -111,14 +85,14 @@ fn main() {
let rom: ROM = match fs::read(args.rom) { let rom: ROM = match fs::read(args.rom) {
Ok(data) => ROM::load(data), Ok(data) => ROM::load(data),
Err(e) => { Err(e) => {
println!("Error reading ROM: {}", e.to_string()); println!("Error reading ROM: {e}");
return; return;
} }
}; };
let bootrom: Vec<u8> = match fs::read(args.bootrom) { let bootrom: Vec<u8> = match fs::read(args.bootrom) {
Ok(data) => data, Ok(data) => data,
Err(e) => { Err(e) => {
println!("Error reading bootROM: {}", e.to_string()); println!("Error reading bootROM: {e}");
return; return;
} }
}; };
@ -130,7 +104,7 @@ fn main() {
WindowOptions::default(), WindowOptions::default(),
) )
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
panic!("{}", e); panic!("{e}");
}); });
window.set_position(500, 50); window.set_position(500, 50);
@ -141,17 +115,10 @@ fn main() {
Memory::init(bootrom, args.run_bootrom, rom), Memory::init(bootrom, args.run_bootrom, rom),
window, window,
args.tile_window, args.tile_window,
args.run_bootrom,
); );
if !args.run_bootrom {
cpu.reg.pc = 0x0100;
cpu_ram_init(&mut cpu);
}
let mut cycle_num = 0; let mut cycle_num = 0;
let mut instructions_seen = vec![];
let mut last_state = cpu.reg.clone();
let mut next_state = last_state;
verbose_println!("\n\n Begin execution...\n"); verbose_println!("\n\n Begin execution...\n");
match args.step_by { match args.step_by {
@ -161,80 +128,57 @@ fn main() {
if args.cycle_count { if args.cycle_count {
print_cycles(&cycle_num); print_cycles(&cycle_num);
} }
run_cycle( run_cycle(&mut cpu);
&mut cpu,
&mut next_state,
&mut last_state,
&mut instructions_seen,
);
} }
print!( print!(" ...{cycle_num} cycles - press enter to continue\r");
" ...{} cycles - press enter to continue\r",
cycle_num
);
stdout().flush().unwrap(); stdout().flush().unwrap();
pause_once(); pause();
}, },
None => loop { None => loop {
cycle_num += 1; cycle_num += 1;
if args.cycle_count { if args.cycle_count {
print_cycles(&cycle_num); print_cycles(&cycle_num);
} }
run_cycle( run_cycle(&mut cpu);
&mut cpu,
&mut next_state,
&mut last_state,
&mut instructions_seen,
);
}, },
} }
} }
fn run_cycle( fn run_cycle(cpu: &mut CPU) {
cpu: &mut CPU, let will_pause = unsafe { PAUSE_QUEUED };
next_state: &mut Registers, let pause_enabled = unsafe { PAUSE_ENABLED };
last_state: &mut Registers,
instructions_seen: &mut Vec<u8>,
) {
let will_pause;
unsafe {
will_pause = PAUSE_QUEUED.clone();
}
cpu.exec_next(); cpu.exec_next();
unsafe { if !pause_enabled {
*next_state = cpu.reg; if cpu.reg.pc >= 0x100 {
if !PAUSE_ENABLED { unsafe { PAUSE_ENABLED = true };
if next_state.pc >= 0x100 {
PAUSE_ENABLED = true;
} }
} }
*last_state = *next_state;
if will_pause { if will_pause {
pause(); pause_then_step();
}
}
match instructions_seen.contains(&cpu.last_instruction) {
true => {}
false => {
// println!("new instruction enountered: {:#X}", cpu.last_instruction);
instructions_seen.push(cpu.last_instruction);
}
} }
} }
fn pause() { fn pause_then_step() {
unsafe { unsafe {
if PAUSE_ENABLED { if PAUSE_ENABLED {
let line = &mut String::new(); let line = pause();
io::stdin().read_line(line).unwrap();
PAUSE_QUEUED = !line.contains("continue"); PAUSE_QUEUED = !line.contains("continue");
} }
} }
} }
#[allow(dead_code)]
fn pause_once() { fn pause_once() {
println!("paused..."); println!("paused...");
io::stdin().read_line(&mut String::new()).unwrap(); pause();
}
fn pause() -> String {
let mut line = String::new();
match io::stdin().read_line(&mut line) {
Ok(_) => line,
Err(_) => String::from(""),
}
} }
fn print_cycles(cycles: &i32) { fn print_cycles(cycles: &i32) {

View file

@ -41,7 +41,7 @@ impl GPU {
WindowOptions::default(), WindowOptions::default(),
) )
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
panic!("{}", e); panic!("{e}");
}); });
window.set_position((550 + (WIDTH * FACTOR)) as isize, 50); window.set_position((550 + (WIDTH * FACTOR)) as isize, 50);

View file

@ -287,4 +287,30 @@ impl Memory {
self.joypad.b = keys.contains(&Key::Semicolon); self.joypad.b = keys.contains(&Key::Semicolon);
self.joypad != old self.joypad != old
} }
pub(super) fn cpu_ram_init(&mut self) {
self.set(0xFF04, 0xAD);
self.set(0xFF10, 0x80);
self.set(0xFF11, 0xBF);
self.set(0xFF12, 0xF3);
self.set(0xFF14, 0xBF);
self.set(0xFF16, 0x3F);
self.set(0xFF19, 0xBF);
self.set(0xFF1A, 0x7F);
self.set(0xFF1B, 0xFF);
self.set(0xFF1C, 0x9F);
self.set(0xFF1E, 0xBF);
self.set(0xFF20, 0xFF);
self.set(0xFF23, 0xBF);
self.set(0xFF24, 0x77);
self.set(0xFF25, 0xF3);
self.set(0xFF26, 0xF1);
self.set(0xFF40, 0x91);
self.set(0xFF47, 0xFC);
self.set(0xFF48, 0xFF);
self.set(0xFF49, 0xFF);
for i in 0xC000..0xE000 {
self.set(i, if rand::random() { 0xFF } else { 0x00 });
}
}
} }

View file

@ -26,9 +26,9 @@ pub struct CPU {
pub memory: Memory, pub memory: Memory,
pub reg: Registers, pub reg: Registers,
pub last_instruction: u8, pub last_instruction: u8,
pub last_instruction_addr: u16, last_instruction_addr: u16,
pub window: Window, window: Window,
pub gpu: GPU, gpu: GPU,
halted: bool, halted: bool,
} }
@ -38,10 +38,18 @@ const SPEEDUP: f64 = 1.;
const FF04_SPEED: f64 = 16384.; const FF04_SPEED: f64 = 16384.;
impl CPU { impl CPU {
pub fn new(memory: Memory, window: Window, enable_tile_window: bool) -> Self { pub fn new(
mut memory: Memory,
window: Window,
enable_tile_window: bool,
run_bootrom: bool,
) -> Self {
if run_bootrom {
memory.cpu_ram_init();
}
Self { Self {
memory, memory,
reg: Registers::default(), reg: Registers::init(run_bootrom),
last_instruction: 0x0, last_instruction: 0x0,
last_instruction_addr: 0x0, last_instruction_addr: 0x0,
window, window,
@ -196,16 +204,26 @@ pub struct Registers {
pub pc: u16, pub pc: u16,
} }
impl Default for Registers { impl Registers {
fn default() -> Self { fn init(run_bootrom: bool) -> Self {
// default post-bootrom values if run_bootrom {
Self {
af: 0,
bc: 0,
de: 0,
hl: 0,
sp: 0xFFFE,
pc: 0,
}
} else {
Self { Self {
af: 0x01B0, af: 0x01B0,
bc: 0x0013, bc: 0x0013,
de: 0x00D8, de: 0x00D8,
hl: 0x014D, hl: 0x014D,
sp: 0xFFFE, sp: 0xFFFE,
pc: 0x0000, pc: 0x0100,
}
} }
} }
} }