From 1a46bec3f957d738a99e0be879fc82f2587e6598 Mon Sep 17 00:00:00 2001 From: Michel Heily Date: Mon, 10 Feb 2020 22:08:28 +0200 Subject: [PATCH] feat: Fix & improve debugger, Add commands to save/load the state Former-commit-id: cfbead1ad64c8b029bf7265f7fd975014744b287 --- src/core/arm7tdmi/arm/display.rs | 2 +- src/debugger/command.rs | 47 +++++++++++++++++++++++--------- src/debugger/mod.rs | 8 ++++-- src/plat/sdl2/main.rs | 2 +- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/core/arm7tdmi/arm/display.rs b/src/core/arm7tdmi/arm/display.rs index 290090f..35dd8e4 100644 --- a/src/core/arm7tdmi/arm/display.rs +++ b/src/core/arm7tdmi/arm/display.rs @@ -127,7 +127,7 @@ impl ArmInstruction { } fn fmt_operand2(&self, f: &mut fmt::Formatter) -> Result, fmt::Error> { - let operand2 = self.operand2().unwrap(); + let operand2 = self.operand2(); match operand2 { BarrelShifterValue::RotatedImmediate(_, _) => { let value = operand2.decode_rotated_immediate().unwrap(); diff --git a/src/debugger/command.rs b/src/debugger/command.rs index bc789b2..c8f13dc 100644 --- a/src/debugger/command.rs +++ b/src/debugger/command.rs @@ -1,3 +1,5 @@ +use std::fs; +use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time; @@ -8,7 +10,7 @@ use crate::core::arm7tdmi::CpuState; use crate::core::GBAError; use crate::core::{Addr, Bus}; use crate::disass::Disassembler; -use crate::{AudioInterface, InputInterface, VideoInterface}; +use crate::util::{read_bin_file, write_bin_file}; // use super::palette_view::create_palette_view; // use super::tile_view::create_tile_view; @@ -61,6 +63,8 @@ pub enum Command { Reset, Quit, TraceToggle(TraceFlags), + SaveState(String), + LoadState(String), } impl Debugger { @@ -126,7 +130,7 @@ impl Debugger { self.gba.frame(); } let end = PreciseTime::now(); - println!("that took {} seconds", start.to(end)); + println!("that took {:?} seconds", start.to(end)); } HexDump(addr, nbytes) => { let bytes = self.gba.sysbus.get_bytes(addr..addr + nbytes); @@ -178,17 +182,6 @@ impl Debugger { println!("cpu is restarted!") } TraceToggle(flags) => { - if flags.contains(TraceFlags::TRACE_SYSBUS) { - self.gba.sysbus.trace_access = !self.gba.sysbus.trace_access; - println!( - "[*] sysbus tracing {}", - if self.gba.sysbus.trace_access { - "on" - } else { - "off" - } - ) - } if flags.contains(TraceFlags::TRACE_OPCODE) { self.gba.cpu.trace_opcodes = !self.gba.cpu.trace_opcodes; println!( @@ -218,6 +211,18 @@ impl Debugger { self.gba.sysbus.io.timers.trace = !self.gba.sysbus.io.timers.trace; } } + SaveState(save_path) => { + let state = self.gba.save_state().expect("failed to serialize"); + write_bin_file(&Path::new(&save_path), &state) + .expect("failed to save state to file"); + } + LoadState(load_path) => { + let save = read_bin_file(&Path::new(&load_path)) + .expect("failed to read save state from file"); + self.gba + .restore_state(&save) + .expect("failed to deserialize"); + } _ => println!("Not Implemented",), } } @@ -447,6 +452,22 @@ impl Debugger { } } } + "save" | "load" => { + let usage = DebuggerError::InvalidCommandFormat(String::from("save/load ")); + if args.len() != 1 { + Err(usage) + } else { + if let Value::Identifier(path) = &args[0] { + match command.as_ref() { + "save" => Ok(Command::SaveState(path.to_string())), + "load" => Ok(Command::LoadState(path.to_string())), + _ => unreachable!(), + } + } else { + Err(usage) + } + } + } _ => Err(DebuggerError::InvalidCommand(command)), } } diff --git a/src/debugger/mod.rs b/src/debugger/mod.rs index 1f51cd1..e1d8e97 100644 --- a/src/debugger/mod.rs +++ b/src/debugger/mod.rs @@ -203,8 +203,12 @@ impl Debugger { match readline { Ok(line) => { if line.is_empty() { - self.previous_command = None; - continue; + if let Some(Command::Step(1)) = self.previous_command { + self.run_command(Command::Step(1)); + } else { + self.previous_command = None; + continue; + } } rl.add_history_entry(line.as_str()); let expr = parse_expr(&line); diff --git a/src/plat/sdl2/main.rs b/src/plat/sdl2/main.rs index b2b607f..1f94153 100644 --- a/src/plat/sdl2/main.rs +++ b/src/plat/sdl2/main.rs @@ -155,7 +155,7 @@ fn main() -> Result<(), Box> { info!("starting debugger..."); debugger.repl(matches.value_of("script_file")).unwrap(); info!("ending debugger..."); - return; + return Ok(()); } #[cfg(not(feature = "debugger"))] {