From aab3742158672b752360a85eff76db6715284b8a Mon Sep 17 00:00:00 2001 From: dogeystamp Date: Sun, 7 Jan 2024 22:13:14 -0500 Subject: [PATCH] add debugging print --- src/vm/instruction.rs | 19 +++++++++++++++--- src/vm/mod.rs | 46 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/vm/instruction.rs b/src/vm/instruction.rs index ee7f8cd..f11fed8 100644 --- a/src/vm/instruction.rs +++ b/src/vm/instruction.rs @@ -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); } } diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 08b551f..3632097 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -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!(); + } +}