refactor printing + args
This commit is contained in:
parent
744f769728
commit
13bd9f0a1c
3 changed files with 113 additions and 46 deletions
100
src/main.rs
100
src/main.rs
|
@ -2,16 +2,36 @@
|
|||
|
||||
mod processor;
|
||||
|
||||
use clap::Parser;
|
||||
use clap::{ArgGroup, Parser};
|
||||
use processor::CPU;
|
||||
use std::{
|
||||
fs,
|
||||
io::{self, stdout, Write},
|
||||
sync::RwLock,
|
||||
};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! verbose_println {
|
||||
($($tts:tt)*) => {
|
||||
if crate::is_verbose() {
|
||||
println!($($tts)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! verbose_print {
|
||||
($($tts:tt)*) => {
|
||||
if crate::is_verbose() {
|
||||
print!($($tts)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Simple program to greet a person
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[command(group(ArgGroup::new("prints").args(["verbose","cycle_count"])))]
|
||||
struct Args {
|
||||
/// ROM path
|
||||
#[arg(short, long)]
|
||||
|
@ -25,6 +45,14 @@ struct Args {
|
|||
#[arg(long)]
|
||||
run_bootrom: bool,
|
||||
|
||||
/// Verbose print
|
||||
#[arg(short, long)]
|
||||
verbose: bool,
|
||||
|
||||
/// Show cycle count
|
||||
#[arg(short, long)]
|
||||
cycle_count: bool,
|
||||
|
||||
/// Step emulation by...
|
||||
#[arg(long)]
|
||||
step_by: Option<usize>,
|
||||
|
@ -130,7 +158,8 @@ impl Memory {
|
|||
}
|
||||
|
||||
fn set(&mut self, address: Address, data: u8) {
|
||||
println!("write addr: {:#X}, data: {:#X}", address, data);
|
||||
verbose_println!("write addr: {:#X}, data: {:#X}", address, data);
|
||||
|
||||
match address {
|
||||
0x0..0x100 => {
|
||||
if !self.bootrom_enabled {
|
||||
|
@ -162,7 +191,7 @@ impl Memory {
|
|||
// println!("empty space write: {:#X} to addr {:#X}", data, address);
|
||||
}
|
||||
0xFF00..0xFF4C => {
|
||||
print!("writing to addr {:#X}\r", address);
|
||||
verbose_print!("writing to addr {:#X}\r", address);
|
||||
stdout().flush().unwrap();
|
||||
|
||||
if address == 0xFF02 && data == 0x81 {
|
||||
|
@ -178,8 +207,8 @@ impl Memory {
|
|||
self.cpu_ram[(address - 0xFF80) as usize] = data;
|
||||
}
|
||||
0xFFFF => {
|
||||
println!("interrupts set to {:#b}", data);
|
||||
println!(" / {:#X}", data);
|
||||
verbose_println!("interrupts set to {:#b}", data);
|
||||
verbose_println!(" / {:#X}", data);
|
||||
self.interrupts = data;
|
||||
}
|
||||
}
|
||||
|
@ -247,9 +276,15 @@ fn swap_rom_endian(rom: &ROM) -> ROM {
|
|||
|
||||
static mut PAUSE_ENABLED: bool = false;
|
||||
static mut PAUSE_QUEUED: bool = false;
|
||||
// static mut VERBOSE: bool = false;
|
||||
static VERBOSE: RwLock<bool> = RwLock::new(false);
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
{
|
||||
let mut v = VERBOSE.write().unwrap();
|
||||
*v = args.verbose;
|
||||
}
|
||||
|
||||
let rom: ROM = fs::read(args.rom).expect("Could not load ROM");
|
||||
let bootrom: ROM = fs::read(args.bootrom).expect("Could not load BootROM");
|
||||
|
@ -269,15 +304,19 @@ fn main() {
|
|||
let mut cycle_num = 0;
|
||||
let mut instructions_seen = vec![];
|
||||
let mut last_state = cpu.state.clone();
|
||||
let mut next_state: State;
|
||||
let mut next_state = last_state;
|
||||
match args.step_by {
|
||||
Some(step_size) => loop {
|
||||
for _ in 0..step_size {
|
||||
cycle_num += 1;
|
||||
cpu.exec_next();
|
||||
println!(
|
||||
"exec {:#4X} from {:#4X}",
|
||||
cpu.last_instruction, cpu.last_instruction_addr
|
||||
if args.cycle_count {
|
||||
print_cycles(&cycle_num);
|
||||
}
|
||||
run_cycle(
|
||||
&mut cpu,
|
||||
&mut next_state,
|
||||
&mut last_state,
|
||||
&mut instructions_seen,
|
||||
);
|
||||
}
|
||||
print!(
|
||||
|
@ -285,24 +324,42 @@ fn main() {
|
|||
cycle_num
|
||||
);
|
||||
stdout().flush().unwrap();
|
||||
pause();
|
||||
pause_once();
|
||||
},
|
||||
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,
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn run_cycle(
|
||||
cpu: &mut CPU,
|
||||
next_state: &mut State,
|
||||
last_state: &mut State,
|
||||
instructions_seen: &mut Vec<u8>,
|
||||
) {
|
||||
let will_pause;
|
||||
unsafe {
|
||||
will_pause = PAUSE_QUEUED.clone();
|
||||
}
|
||||
cycle_num += 1;
|
||||
// print_cycles(&cycle_num);
|
||||
cpu.exec_next();
|
||||
unsafe {
|
||||
next_state = cpu.state;
|
||||
*next_state = cpu.state;
|
||||
if !PAUSE_ENABLED {
|
||||
if next_state.pc.as_u16 >= 0x100 {
|
||||
PAUSE_ENABLED = true;
|
||||
}
|
||||
}
|
||||
last_state = next_state;
|
||||
*last_state = *next_state;
|
||||
if will_pause {
|
||||
pause();
|
||||
}
|
||||
|
@ -314,8 +371,6 @@ fn main() {
|
|||
instructions_seen.push(cpu.last_instruction);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -328,6 +383,10 @@ fn pause() {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
fn pause_once() {
|
||||
io::stdin().read_line(&mut String::new()).unwrap();
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn print_cycles(cycles: &i32) {
|
||||
|
@ -342,3 +401,10 @@ fn print_cycles(cycles: &i32) {
|
|||
);
|
||||
stdout().flush().unwrap();
|
||||
}
|
||||
|
||||
fn is_verbose() -> bool {
|
||||
match VERBOSE.read() {
|
||||
Ok(v) => *v,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::{
|
|||
ops::{BitAnd, BitOr, BitXor},
|
||||
};
|
||||
|
||||
use crate::{Inner, Memory, Register, State};
|
||||
use crate::{verbose_println, Inner, Memory, Register, State};
|
||||
|
||||
mod opcodes;
|
||||
|
||||
|
@ -33,9 +33,10 @@ impl CPU {
|
|||
unsafe { self.last_instruction_addr = self.state.pc.as_u16 };
|
||||
let opcode = self.next_opcode();
|
||||
self.last_instruction = opcode;
|
||||
println!(
|
||||
verbose_println!(
|
||||
"exec {:#4X} from pc: {:#X}",
|
||||
opcode, self.last_instruction_addr
|
||||
opcode,
|
||||
self.last_instruction_addr
|
||||
);
|
||||
self.run_opcode(opcode);
|
||||
}
|
||||
|
@ -177,15 +178,15 @@ impl CPU {
|
|||
|
||||
fn set_flag(&mut self, flag: FLAGS) {
|
||||
if flag == FLAGS::Z {
|
||||
println!("setting z flag");
|
||||
verbose_println!("setting z flag");
|
||||
}
|
||||
unsafe {
|
||||
println!(
|
||||
verbose_println!(
|
||||
"setting flag: currently {0:#b} / {0:#X}",
|
||||
self.state.af.as_u8s.right
|
||||
);
|
||||
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitor(1 << flag as u8);
|
||||
println!(
|
||||
verbose_println!(
|
||||
" now {0:#b} / {0:#X}",
|
||||
self.state.af.as_u8s.right
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Inner, Register};
|
||||
use crate::{verbose_println, Inner, Register};
|
||||
use std::ops::{BitAnd, BitOr, BitXor};
|
||||
|
||||
use super::{as_signed, res, set, swap_nibbles, CPU, FLAGS};
|
||||
|
@ -84,7 +84,7 @@ impl CPU {
|
|||
0x20 => {
|
||||
let jump_size = self.ld_immediate_byte();
|
||||
if self.get_flag(FLAGS::Z) == 0 {
|
||||
println!("z flag is 0... so doing jump...");
|
||||
verbose_println!("z flag is 0... so doing jump...");
|
||||
unsafe {
|
||||
self.state.pc.as_u16 = self
|
||||
.state
|
||||
|
@ -94,7 +94,7 @@ impl CPU {
|
|||
}
|
||||
} else {
|
||||
unsafe {
|
||||
println!(
|
||||
verbose_println!(
|
||||
"not jumping! z flag is {0:#b}, flags are {1:#b} / {1:#X}",
|
||||
self.get_flag(FLAGS::Z),
|
||||
self.state.af.as_u8s.right
|
||||
|
@ -117,7 +117,7 @@ impl CPU {
|
|||
},
|
||||
0x26 => self.state.hl.as_u8s.left = self.ld_immediate_byte(),
|
||||
0x27 => unsafe {
|
||||
println!("Running DAA instruction (0x27) that I'm not too sure about...");
|
||||
verbose_println!("Running DAA instruction (0x27) that I'm not too sure about...");
|
||||
if self.get_flag(FLAGS::N) == 0 {
|
||||
if self.get_flag(FLAGS::C) == 1 || self.state.af.as_u8s.left > 0x99 {
|
||||
self.state.af.as_u8s.left += 0x60;
|
||||
|
@ -133,7 +133,7 @@ impl CPU {
|
|||
self.state.af.as_u8s.left -= 0x6;
|
||||
}
|
||||
}
|
||||
println!(
|
||||
verbose_println!(
|
||||
" ...this set register a to {:#X}...",
|
||||
self.state.af.as_u8s.left
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue