add debugging print
This commit is contained in:
parent
328291ae3e
commit
aab3742158
@ -8,8 +8,12 @@ use crate::vm::VM;
|
||||
// Main part
|
||||
////////////////
|
||||
|
||||
pub fn get_instruction(vm: &mut VM) -> u16 {
|
||||
return vm.mem.get_mem(vm.registers.pc);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum OpCode {
|
||||
pub enum OpCode {
|
||||
// branch
|
||||
BR = 0,
|
||||
// add
|
||||
@ -46,7 +50,7 @@ enum OpCode {
|
||||
NOOP,
|
||||
}
|
||||
|
||||
fn get_opcode(instruction: u16) -> OpCode {
|
||||
pub fn get_opcode(instruction: u16) -> OpCode {
|
||||
// the opcode is stored in the left 4 bits
|
||||
match instruction >> 12 {
|
||||
0 => OpCode::BR,
|
||||
@ -93,6 +97,10 @@ pub fn execute_instruction(vm: &mut VM, instr: u16) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Helpers
|
||||
////////////////
|
||||
|
||||
/// Sign extend a value, given the amount of bits it currently has
|
||||
fn sign_extend(x: u16, bits: usize) -> u16 {
|
||||
if (x >> (bits - 1) & 1) == 1 {
|
||||
@ -164,7 +172,12 @@ fn op_br(vm: &mut VM, instr: u16) {
|
||||
// therefore isolate the last 3 bits
|
||||
let cond = vm.registers.cond & 0x7;
|
||||
|
||||
if (instr >> 9) & 0x7 & cond != 0 {
|
||||
let need_cond = (instr >> 9) & 0x7;
|
||||
|
||||
// BRnzp is unconditional
|
||||
// if we haven't performed any instructions that set conditions,
|
||||
// COND might just be 0
|
||||
if need_cond & cond != 0 || need_cond == 0b111 {
|
||||
vm.registers.pc = vm.registers.pc.wrapping_add(offset);
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ pub struct VM<'a> {
|
||||
mem: memory::Memory<'a>,
|
||||
registers: Registers,
|
||||
running: bool,
|
||||
debug_state: DebugState,
|
||||
}
|
||||
|
||||
impl VM<'_> {
|
||||
@ -128,6 +129,7 @@ impl VM<'_> {
|
||||
mem: memory::Memory::new(keyboard_io),
|
||||
registers: Registers::new(),
|
||||
running: false,
|
||||
debug_state: DebugState::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +175,11 @@ impl VM<'_> {
|
||||
self.running = true;
|
||||
|
||||
while self.running {
|
||||
let instr = self.mem.get_mem(self.registers.pc);
|
||||
let instr = instruction::get_instruction(self);
|
||||
|
||||
if self.debug_state.debugging {
|
||||
DebugState::print_state(self);
|
||||
}
|
||||
|
||||
// NOTE
|
||||
// remember PC points to the *next* instruction at all times
|
||||
@ -189,3 +195,41 @@ impl VM<'_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// debugging
|
||||
////////////////
|
||||
|
||||
struct DebugState {
|
||||
debugging: bool,
|
||||
}
|
||||
|
||||
impl DebugState {
|
||||
fn new() -> DebugState {
|
||||
DebugState {
|
||||
debugging: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Print current VM state
|
||||
fn print_state(vm: &mut VM) {
|
||||
let instr = instruction::get_instruction(vm);
|
||||
let op_code = instruction::get_opcode(instr);
|
||||
|
||||
println!("PC: {:#x}, op: {:?}, params: {:#x}", vm.registers.pc, op_code, instr & 0x7ff);
|
||||
for i in 0..=7 {
|
||||
println!("R{}: {:#x}", i, vm.registers.get_reg(i));
|
||||
}
|
||||
|
||||
let mut condstr = String::new();
|
||||
let flags = ["P", "Z", "N"];
|
||||
for i in 0..=2 {
|
||||
if (1 << i) & vm.registers.cond == 1 {
|
||||
condstr.push_str(flags[i]);
|
||||
}
|
||||
}
|
||||
println!("COND: {:#x} ({})", vm.registers.cond, condstr);
|
||||
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user