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 processor::{
memory::{rom::ROM, Memory},
Registers, CPU,
CPU,
};
use std::{
fs,
@ -66,32 +66,6 @@ struct Args {
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_QUEUED: bool = false;
// static mut VERBOSE: bool = false;
@ -111,14 +85,14 @@ fn main() {
let rom: ROM = match fs::read(args.rom) {
Ok(data) => ROM::load(data),
Err(e) => {
println!("Error reading ROM: {}", e.to_string());
println!("Error reading ROM: {e}");
return;
}
};
let bootrom: Vec<u8> = match fs::read(args.bootrom) {
Ok(data) => data,
Err(e) => {
println!("Error reading bootROM: {}", e.to_string());
println!("Error reading bootROM: {e}");
return;
}
};
@ -130,7 +104,7 @@ fn main() {
WindowOptions::default(),
)
.unwrap_or_else(|e| {
panic!("{}", e);
panic!("{e}");
});
window.set_position(500, 50);
@ -141,17 +115,10 @@ fn main() {
Memory::init(bootrom, args.run_bootrom, rom),
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 instructions_seen = vec![];
let mut last_state = cpu.reg.clone();
let mut next_state = last_state;
verbose_println!("\n\n Begin execution...\n");
match args.step_by {
@ -161,80 +128,57 @@ fn main() {
if args.cycle_count {
print_cycles(&cycle_num);
}
run_cycle(
&mut cpu,
&mut next_state,
&mut last_state,
&mut instructions_seen,
);
run_cycle(&mut cpu);
}
print!(
" ...{} cycles - press enter to continue\r",
cycle_num
);
print!(" ...{cycle_num} cycles - press enter to continue\r");
stdout().flush().unwrap();
pause_once();
pause();
},
None => loop {
cycle_num += 1;
if args.cycle_count {
print_cycles(&cycle_num);
}
run_cycle(
&mut cpu,
&mut next_state,
&mut last_state,
&mut instructions_seen,
);
run_cycle(&mut cpu);
},
}
}
fn run_cycle(
cpu: &mut CPU,
next_state: &mut Registers,
last_state: &mut Registers,
instructions_seen: &mut Vec<u8>,
) {
let will_pause;
unsafe {
will_pause = PAUSE_QUEUED.clone();
}
fn run_cycle(cpu: &mut CPU) {
let will_pause = unsafe { PAUSE_QUEUED };
let pause_enabled = unsafe { PAUSE_ENABLED };
cpu.exec_next();
unsafe {
*next_state = cpu.reg;
if !PAUSE_ENABLED {
if next_state.pc >= 0x100 {
PAUSE_ENABLED = true;
}
}
*last_state = *next_state;
if will_pause {
pause();
if !pause_enabled {
if cpu.reg.pc >= 0x100 {
unsafe { PAUSE_ENABLED = true };
}
}
match instructions_seen.contains(&cpu.last_instruction) {
true => {}
false => {
// println!("new instruction enountered: {:#X}", cpu.last_instruction);
instructions_seen.push(cpu.last_instruction);
}
if will_pause {
pause_then_step();
}
}
fn pause() {
fn pause_then_step() {
unsafe {
if PAUSE_ENABLED {
let line = &mut String::new();
io::stdin().read_line(line).unwrap();
let line = pause();
PAUSE_QUEUED = !line.contains("continue");
}
}
}
#[allow(dead_code)]
fn pause_once() {
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) {

View file

@ -41,7 +41,7 @@ impl GPU {
WindowOptions::default(),
)
.unwrap_or_else(|e| {
panic!("{}", e);
panic!("{e}");
});
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 != 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 reg: Registers,
pub last_instruction: u8,
pub last_instruction_addr: u16,
pub window: Window,
pub gpu: GPU,
last_instruction_addr: u16,
window: Window,
gpu: GPU,
halted: bool,
}
@ -38,10 +38,18 @@ const SPEEDUP: f64 = 1.;
const FF04_SPEED: f64 = 16384.;
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 {
memory,
reg: Registers::default(),
reg: Registers::init(run_bootrom),
last_instruction: 0x0,
last_instruction_addr: 0x0,
window,
@ -196,16 +204,26 @@ pub struct Registers {
pub pc: u16,
}
impl Default for Registers {
fn default() -> Self {
// default post-bootrom values
Self {
af: 0x01B0,
bc: 0x0013,
de: 0x00D8,
hl: 0x014D,
sp: 0xFFFE,
pc: 0x0000,
impl Registers {
fn init(run_bootrom: bool) -> Self {
if run_bootrom {
Self {
af: 0,
bc: 0,
de: 0,
hl: 0,
sp: 0xFFFE,
pc: 0,
}
} else {
Self {
af: 0x01B0,
bc: 0x0013,
de: 0x00D8,
hl: 0x014D,
sp: 0xFFFE,
pc: 0x0100,
}
}
}
}