core: debugger: Use mut references for GameBoyAdvance

Former-commit-id: e1490c0777537e7d8eee4e9d1fbb53f8c957fdc7
Former-commit-id: f6be5b7940c4f3d517fa564830be607321ade534
This commit is contained in:
Michel Heily 2021-06-09 01:24:31 +03:00
parent f140e0f83b
commit ff472db249
3 changed files with 106 additions and 88 deletions

View file

@ -11,6 +11,7 @@ use crate::util::{read_bin_file, write_bin_file};
// use super::palette_view::create_palette_view; // use super::palette_view::create_palette_view;
// use super::tile_view::create_tile_view; // use super::tile_view::create_tile_view;
use super::GameBoyAdvance;
use super::{parser::Value, Debugger, DebuggerError, DebuggerResult}; use super::{parser::Value, Debugger, DebuggerError, DebuggerResult};
use ansi_term::Colour; use ansi_term::Colour;
@ -92,32 +93,32 @@ fn find_nearest_symbol(addr: u32, symbols: &HashMap<String, u32>) -> Option<(Str
} }
impl Debugger { impl Debugger {
pub fn run_command(&mut self, command: Command) { pub fn run_command(&mut self, gba: &mut GameBoyAdvance, command: Command) {
use Command::*; use Command::*;
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
match command { match command {
Info => { Info => {
let pc = self.gba.cpu.pc; let pc = gba.cpu.pc;
if let Some((sym, addr)) = find_nearest_symbol(pc, &self.symbols) { if let Some((sym, addr)) = find_nearest_symbol(pc, &self.symbols) {
println!("PC at {}+{:#x} ({:08x})", sym, addr - pc, pc); println!("PC at {}+{:#x} ({:08x})", sym, addr - pc, pc);
} else { } else {
println!("PC at {:08x}", pc); println!("PC at {:08x}", pc);
} }
println!("{}", self.gba.cpu); println!("{}", gba.cpu);
println!("IME={}", self.gba.io_devs.intc.interrupt_master_enable); // println!("IME={}", gba.io_devs.intc.interrupt_master_enable);
println!("IE={:#?}", self.gba.io_devs.intc.interrupt_enable); // println!("IE={:#?}", gba.io_devs.intc.interrupt_enable);
println!("IF={:#?}", self.gba.io_devs.intc.interrupt_flags); // println!("IF={:#?}", gba.io_devs.intc.interrupt_flags);
} }
GpuInfo => println!("GPU: {:#?}", self.gba.io_devs.gpu), GpuInfo => println!("GPU: {:#?}", gba.io_devs.gpu),
GpioInfo => println!("GPIO: {:#?}", self.gba.sysbus.cartridge.get_gpio()), GpioInfo => println!("GPIO: {:#?}", gba.sysbus.cartridge.get_gpio()),
Step(count) => { Step(count) => {
for _ in 0..count { for _ in 0..count {
self.gba.step_debugger(); gba.step_debugger();
while self.gba.cpu.dbg.last_executed.is_none() { while gba.cpu.dbg.last_executed.is_none() {
self.gba.step_debugger(); gba.step_debugger();
} }
if let Some(last_executed) = &self.gba.cpu.dbg.last_executed { if let Some(last_executed) = &gba.cpu.dbg.last_executed {
let pc = last_executed.get_pc(); let pc = last_executed.get_pc();
let symbol = let symbol =
self.symbols self.symbols
@ -138,19 +139,19 @@ impl Debugger {
"{}", "{}",
Colour::Purple.dimmed().italic().paint(format!( Colour::Purple.dimmed().italic().paint(format!(
"\t\t/// Next instruction at @0x{:08x}", "\t\t/// Next instruction at @0x{:08x}",
self.gba.cpu.get_next_pc() gba.cpu.get_next_pc()
)) ))
); );
} }
} }
println!("cycles: {}", self.gba.scheduler.timestamp()); println!("cycles: {}", gba.scheduler.timestamp());
println!("{}\n", self.gba.cpu); println!("{}\n", gba.cpu);
} }
Continue => 'running: loop { Continue => 'running: loop {
self.gba.key_poll(); gba.key_poll();
if let Some(breakpoint) = self.gba.step_debugger() { if let Some(breakpoint) = gba.step_debugger() {
let mut bp_sym = None; let mut bp_sym = None;
if let Some(symbols) = self.gba.sysbus.cartridge.get_symbols() { if let Some(symbols) = gba.sysbus.cartridge.get_symbols() {
for s in symbols.keys() { for s in symbols.keys() {
if symbols.get(s).unwrap() == &breakpoint { if symbols.get(s).unwrap() == &breakpoint {
bp_sym = Some(s.clone()); bp_sym = Some(s.clone());
@ -168,22 +169,22 @@ impl Debugger {
Frame(count) => { Frame(count) => {
let start = time::Instant::now(); let start = time::Instant::now();
for _ in 0..count { for _ in 0..count {
self.gba.frame(); gba.frame();
} }
let end = time::Instant::now(); let end = time::Instant::now();
println!("that took {:?} seconds", end - start); println!("that took {:?} seconds", end - start);
} }
HexDump(addr, nbytes) => { HexDump(addr, nbytes) => {
let bytes = self.gba.sysbus.debug_get_bytes(addr..addr + nbytes); let bytes = gba.sysbus.debug_get_bytes(addr..addr + nbytes);
hexdump::hexdump(&bytes); hexdump::hexdump(&bytes);
} }
MemWrite(size, addr, val) => match size { MemWrite(size, addr, val) => match size {
MemWriteCommandSize::Byte => self.gba.sysbus.write_8(addr, val as u8), MemWriteCommandSize::Byte => gba.sysbus.write_8(addr, val as u8),
MemWriteCommandSize::Half => self.gba.sysbus.write_16(addr, val as u16), MemWriteCommandSize::Half => gba.sysbus.write_16(addr, val as u16),
MemWriteCommandSize::Word => self.gba.sysbus.write_32(addr, val as u32), MemWriteCommandSize::Word => gba.sysbus.write_32(addr, val as u32),
}, },
Disass(mode, addr, n) => { Disass(mode, addr, n) => {
let bytes = self.gba.sysbus.debug_get_bytes(addr..addr + n); let bytes = gba.sysbus.debug_get_bytes(addr..addr + n);
match mode { match mode {
DisassMode::ModeArm => { DisassMode::ModeArm => {
let disass = Disassembler::<ArmInstruction>::new(addr, &bytes); let disass = Disassembler::<ArmInstruction>::new(addr, &bytes);
@ -203,31 +204,31 @@ impl Debugger {
print!("Quitting!"); print!("Quitting!");
self.stop(); self.stop();
} }
AddBreakpoint(addr) => match self.gba.add_breakpoint(addr) { AddBreakpoint(addr) => match gba.add_breakpoint(addr) {
Some(index) => println!("Added breakpoint [{}] 0x{:08x}", index, addr), Some(index) => println!("Added breakpoint [{}] 0x{:08x}", index, addr),
None => println!("Breakpint already exists."), None => println!("Breakpint already exists."),
}, },
DelBreakpoint(addr) => self.delete_breakpoint(addr), DelBreakpoint(addr) => self.delete_breakpoint(gba, addr),
ClearBreakpoints => self.gba.cpu.dbg.breakpoints.clear(), ClearBreakpoints => gba.cpu.dbg.breakpoints.clear(),
ListBreakpoints => { ListBreakpoints => {
println!("breakpoint list:"); println!("breakpoint list:");
for (i, b) in self.gba.cpu.dbg.breakpoints.iter().enumerate() { for (i, b) in gba.cpu.dbg.breakpoints.iter().enumerate() {
println!("[{}] 0x{:08x}", i, b) println!("[{}] 0x{:08x}", i, b)
} }
} }
// PaletteView => create_palette_view(&self.gba.sysbus.palette_ram.mem), // PaletteView => create_palette_view(&gba.sysbus.palette_ram.mem),
// TileView(bg) => create_tile_view(bg, &self.gba), // TileView(bg) => create_tile_view(bg, &gba),
Reset => { Reset => {
println!("resetting cpu..."); println!("resetting cpu...");
self.gba.cpu.reset(); gba.cpu.reset();
println!("cpu is restarted!") println!("cpu is restarted!")
} }
TraceToggle(flags) => { TraceToggle(flags) => {
if flags.contains(TraceFlags::TRACE_OPCODE) { if flags.contains(TraceFlags::TRACE_OPCODE) {
self.gba.cpu.dbg.trace_opcodes = !self.gba.cpu.dbg.trace_opcodes; gba.cpu.dbg.trace_opcodes = !gba.cpu.dbg.trace_opcodes;
println!( println!(
"[*] opcode tracing {}", "[*] opcode tracing {}",
if self.gba.cpu.dbg.trace_opcodes { if gba.cpu.dbg.trace_opcodes {
"on" "on"
} else { } else {
"off" "off"
@ -235,10 +236,10 @@ impl Debugger {
) )
} }
if flags.contains(TraceFlags::TRACE_EXCEPTIONS) { if flags.contains(TraceFlags::TRACE_EXCEPTIONS) {
self.gba.cpu.dbg.trace_exceptions = !self.gba.cpu.dbg.trace_exceptions; gba.cpu.dbg.trace_exceptions = !gba.cpu.dbg.trace_exceptions;
println!( println!(
"[*] exception tracing {}", "[*] exception tracing {}",
if self.gba.cpu.dbg.trace_exceptions { if gba.cpu.dbg.trace_exceptions {
"on" "on"
} else { } else {
"off" "off"
@ -249,20 +250,18 @@ impl Debugger {
println!("[*] dma tracing not implemented"); println!("[*] dma tracing not implemented");
} }
if flags.contains(TraceFlags::TRACE_TIMERS) { if flags.contains(TraceFlags::TRACE_TIMERS) {
self.gba.sysbus.io.timers.trace = !self.gba.sysbus.io.timers.trace; gba.sysbus.io.timers.trace = !gba.sysbus.io.timers.trace;
} }
} }
SaveState(save_path) => { SaveState(save_path) => {
let state = self.gba.save_state().expect("failed to serialize"); let state = gba.save_state().expect("failed to serialize");
write_bin_file(&Path::new(&save_path), &state) write_bin_file(&Path::new(&save_path), &state)
.expect("failed to save state to file"); .expect("failed to save state to file");
} }
LoadState(load_path) => { LoadState(load_path) => {
let save = read_bin_file(&Path::new(&load_path)) let save = read_bin_file(&Path::new(&load_path))
.expect("failed to read save state from file"); .expect("failed to read save state from file");
self.gba gba.restore_state(&save).expect("failed to deserialize");
.restore_state(&save)
.expect("failed to deserialize");
} }
ListSymbols(Some(pattern)) => { ListSymbols(Some(pattern)) => {
let matcher = SkimMatcherV2::default(); let matcher = SkimMatcherV2::default();
@ -305,16 +304,20 @@ impl Debugger {
} }
} }
fn get_disassembler_args(&self, args: Vec<Value>) -> DebuggerResult<(Addr, u32)> { fn get_disassembler_args(
&self,
gba: &GameBoyAdvance,
args: Vec<Value>,
) -> DebuggerResult<(Addr, u32)> {
match args.len() { match args.len() {
2 => { 2 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
let n = self.val_number(&args[1])?; let n = self.val_number(&args[1])?;
Ok((addr, n)) Ok((addr, n))
} }
1 => { 1 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
Ok((addr, 10)) Ok((addr, 10))
} }
@ -322,7 +325,7 @@ impl Debugger {
if let Some(Command::Disass(_mode, addr, n)) = &self.previous_command { if let Some(Command::Disass(_mode, addr, n)) = &self.previous_command {
Ok((*addr + (4 * (*n as u32)), 10)) Ok((*addr + (4 * (*n as u32)), 10))
} else { } else {
Ok((self.gba.cpu.get_next_pc(), 10)) Ok((gba.cpu.get_next_pc(), 10))
} }
} }
_ => { _ => {
@ -333,7 +336,12 @@ impl Debugger {
} }
} }
pub fn eval_command(&self, command: Value, args: Vec<Value>) -> DebuggerResult<Command> { pub fn eval_command(
&self,
gba: &GameBoyAdvance,
command: Value,
args: Vec<Value>,
) -> DebuggerResult<Command> {
let command = match command { let command = match command {
Value::Identifier(command) => command, Value::Identifier(command) => command,
_ => { _ => {
@ -373,13 +381,13 @@ impl Debugger {
"x" | "hexdump" => { "x" | "hexdump" => {
let (addr, n) = match args.len() { let (addr, n) = match args.len() {
2 => { 2 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
let n = self.val_number(&args[1])?; let n = self.val_number(&args[1])?;
(addr, n) (addr, n)
} }
1 => { 1 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
(addr, 0x100) (addr, 0x100)
} }
@ -387,7 +395,7 @@ impl Debugger {
if let Some(Command::HexDump(addr, n)) = self.previous_command { if let Some(Command::HexDump(addr, n)) = self.previous_command {
(addr + (4 * n as u32), 0x100) (addr + (4 * n as u32), 0x100)
} else { } else {
(self.gba.cpu.get_reg(15), 0x100) (gba.cpu.get_reg(15), 0x100)
} }
} }
_ => { _ => {
@ -401,7 +409,7 @@ impl Debugger {
"mwb" => { "mwb" => {
let (addr, val) = match args.len() { let (addr, val) = match args.len() {
2 => { 2 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
let val = self.val_number(&args[1])? as u8; let val = self.val_number(&args[1])? as u8;
(addr, val) (addr, val)
@ -421,7 +429,7 @@ impl Debugger {
"mwh" => { "mwh" => {
let (addr, val) = match args.len() { let (addr, val) = match args.len() {
2 => { 2 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
let val = self.val_number(&args[1])? as u16; let val = self.val_number(&args[1])? as u16;
(addr, val) (addr, val)
@ -441,7 +449,7 @@ impl Debugger {
"mww" => { "mww" => {
let (addr, val) = match args.len() { let (addr, val) = match args.len() {
2 => { 2 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
let val = self.val_number(&args[1])? as u32; let val = self.val_number(&args[1])? as u32;
(addr, val) (addr, val)
@ -459,21 +467,21 @@ impl Debugger {
)) ))
} }
"d" | "disass" => { "d" | "disass" => {
let (addr, n) = self.get_disassembler_args(args)?; let (addr, n) = self.get_disassembler_args(gba, args)?;
let m = match self.gba.cpu.get_cpu_state() { let m = match gba.cpu.get_cpu_state() {
CpuState::ARM => DisassMode::ModeArm, CpuState::ARM => DisassMode::ModeArm,
CpuState::THUMB => DisassMode::ModeThumb, CpuState::THUMB => DisassMode::ModeThumb,
}; };
Ok(Command::Disass(m, addr, n)) Ok(Command::Disass(m, addr, n))
} }
"da" | "disass-arm" => { "da" | "disass-arm" => {
let (addr, n) = self.get_disassembler_args(args)?; let (addr, n) = self.get_disassembler_args(gba, args)?;
Ok(Command::Disass(DisassMode::ModeArm, addr, n)) Ok(Command::Disass(DisassMode::ModeArm, addr, n))
} }
"dt" | "disass-thumb" => { "dt" | "disass-thumb" => {
let (addr, n) = self.get_disassembler_args(args)?; let (addr, n) = self.get_disassembler_args(gba, args)?;
Ok(Command::Disass(DisassMode::ModeThumb, addr, n)) Ok(Command::Disass(DisassMode::ModeThumb, addr, n))
} }
@ -483,14 +491,14 @@ impl Debugger {
"break <addr>".to_string(), "break <addr>".to_string(),
)) ))
} else { } else {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
Ok(Command::AddBreakpoint(addr)) Ok(Command::AddBreakpoint(addr))
} }
} }
"bd" | "breakdel" => match args.len() { "bd" | "breakdel" => match args.len() {
0 => Ok(Command::ClearBreakpoints), 0 => Ok(Command::ClearBreakpoints),
1 => { 1 => {
let addr = self.val_address(&args[0])?; let addr = self.val_address(gba, &args[0])?;
Ok(Command::DelBreakpoint(addr)) Ok(Command::DelBreakpoint(addr))
} }
_ => Err(DebuggerError::InvalidCommandFormat(String::from( _ => Err(DebuggerError::InvalidCommandFormat(String::from(

View file

@ -37,25 +37,23 @@ impl From<::std::io::Error> for DebuggerError {
type DebuggerResult<T> = Result<T, DebuggerError>; type DebuggerResult<T> = Result<T, DebuggerError>;
pub struct Debugger { pub struct Debugger {
pub gba: GameBoyAdvance,
running: bool, running: bool,
pub previous_command: Option<Command>, pub previous_command: Option<Command>,
pub symbols: HashMap<String, u32>, pub symbols: HashMap<String, u32>,
} }
impl Debugger { impl Debugger {
pub fn new(gba: GameBoyAdvance) -> Debugger { pub fn new() -> Debugger {
Debugger { Debugger {
gba: gba,
running: false, running: false,
previous_command: None, previous_command: None,
symbols: HashMap::new(), symbols: HashMap::new(),
} }
} }
pub fn check_breakpoint(&self) -> Option<u32> { pub fn check_breakpoint(&self, gba: &GameBoyAdvance) -> Option<u32> {
let next_pc = self.gba.cpu.get_next_pc(); let next_pc = gba.cpu.get_next_pc();
for bp in &self.gba.cpu.dbg.breakpoints { for bp in &gba.cpu.dbg.breakpoints {
if *bp == next_pc { if *bp == next_pc {
return Some(next_pc); return Some(next_pc);
} }
@ -64,8 +62,8 @@ impl Debugger {
None None
} }
pub fn delete_breakpoint(&mut self, addr: u32) { pub fn delete_breakpoint(&mut self, gba: &mut GameBoyAdvance, addr: u32) {
self.gba.cpu.dbg.breakpoints.retain(|&a| a != addr); gba.cpu.dbg.breakpoints.retain(|&a| a != addr);
} }
fn decode_reg(&self, s: &str) -> DebuggerResult<usize> { fn decode_reg(&self, s: &str) -> DebuggerResult<usize> {
@ -104,11 +102,11 @@ impl Debugger {
} }
} }
fn val_address(&self, arg: &Value) -> DebuggerResult<Addr> { fn val_address(&self, gba: &GameBoyAdvance, arg: &Value) -> DebuggerResult<Addr> {
match arg { match arg {
Value::Num(n) => Ok(*n), Value::Num(n) => Ok(*n),
Value::Identifier(ident) => { Value::Identifier(ident) => {
let symbol = if let Some(symbols) = self.gba.sysbus.cartridge.get_symbols() { let symbol = if let Some(symbols) = gba.sysbus.cartridge.get_symbols() {
symbols.get(ident) symbols.get(ident)
} else { } else {
None None
@ -119,7 +117,7 @@ impl Debugger {
} else { } else {
// otherwise, decode as register (TODO special token to separate symbol and register) // otherwise, decode as register (TODO special token to separate symbol and register)
let reg = self.decode_reg(&ident)?; let reg = self.decode_reg(&ident)?;
Ok(self.gba.cpu.get_reg(reg)) Ok(gba.cpu.get_reg(reg))
} }
} }
v => Err(DebuggerError::InvalidArgument(format!( v => Err(DebuggerError::InvalidArgument(format!(
@ -129,29 +127,34 @@ impl Debugger {
} }
} }
fn eval_assignment(&mut self, lvalue: Value, rvalue: Value) -> DebuggerResult<()> { fn eval_assignment(
&mut self,
gba: &mut GameBoyAdvance,
lvalue: Value,
rvalue: Value,
) -> DebuggerResult<()> {
let lvalue = self.val_reg(&lvalue)?; let lvalue = self.val_reg(&lvalue)?;
let rvalue = match rvalue { let rvalue = match rvalue {
Value::Deref(addr_value, deref_type) => { Value::Deref(addr_value, deref_type) => {
let addr = self.val_address(&addr_value)?; let addr = self.val_address(gba, &addr_value)?;
match deref_type { match deref_type {
DerefType::Word => self.gba.sysbus.read_32(addr), DerefType::Word => gba.sysbus.read_32(addr),
DerefType::HalfWord => self.gba.sysbus.read_16(addr) as u32, DerefType::HalfWord => gba.sysbus.read_16(addr) as u32,
DerefType::Byte => self.gba.sysbus.read_8(addr) as u32, DerefType::Byte => gba.sysbus.read_8(addr) as u32,
} }
} }
_ => self.val_address(&rvalue)?, _ => self.val_address(gba, &rvalue)?,
}; };
self.gba.cpu.set_reg(lvalue, rvalue); gba.cpu.set_reg(lvalue, rvalue);
Ok(()) Ok(())
} }
fn eval_expr(&mut self, expr: Expr) { fn eval_expr(&mut self, gba: &mut GameBoyAdvance, expr: Expr) {
match expr { match expr {
Expr::Command(c, a) => match self.eval_command(c, a) { Expr::Command(c, a) => match self.eval_command(gba, c, a) {
Ok(cmd) => { Ok(cmd) => {
self.previous_command = Some(cmd.clone()); self.previous_command = Some(cmd.clone());
self.run_command(cmd) self.run_command(gba, cmd)
} }
Err(DebuggerError::InvalidCommand(c)) => { Err(DebuggerError::InvalidCommand(c)) => {
println!("{}: {:?}", "invalid command".red(), c) println!("{}: {:?}", "invalid command".red(), c)
@ -164,7 +167,7 @@ impl Debugger {
} }
Err(e) => println!("{} {:?}", "failed to build command".red(), e), Err(e) => println!("{} {:?}", "failed to build command".red(), e),
}, },
Expr::Assignment(lvalue, rvalue) => match self.eval_assignment(lvalue, rvalue) { Expr::Assignment(lvalue, rvalue) => match self.eval_assignment(gba, lvalue, rvalue) {
Err(DebuggerError::InvalidArgument(m)) => { Err(DebuggerError::InvalidArgument(m)) => {
println!("{}: {}", "assignment error".red(), m) println!("{}: {}", "assignment error".red(), m)
} }
@ -178,7 +181,11 @@ impl Debugger {
self.running = false; self.running = false;
} }
pub fn repl(&mut self, script_file: Option<&str>) -> DebuggerResult<()> { pub fn repl(
&mut self,
gba: &mut GameBoyAdvance,
script_file: Option<&str>,
) -> DebuggerResult<()> {
println!("Welcome to rustboyadvance-NG debugger 😎!\n"); println!("Welcome to rustboyadvance-NG debugger 😎!\n");
self.running = true; self.running = true;
let mut rl = Editor::<()>::new(); let mut rl = Editor::<()>::new();
@ -189,7 +196,7 @@ impl Debugger {
let reader = BufReader::new(file); let reader = BufReader::new(file);
for line in reader.lines() { for line in reader.lines() {
let expr = parse_expr(&line.unwrap())?; let expr = parse_expr(&line.unwrap())?;
self.eval_expr(expr); self.eval_expr(gba, expr);
} }
} }
while self.running { while self.running {
@ -198,7 +205,7 @@ impl Debugger {
Ok(line) => { Ok(line) => {
if line.is_empty() { if line.is_empty() {
if let Some(Command::Step(1)) = self.previous_command { if let Some(Command::Step(1)) = self.previous_command {
self.run_command(Command::Step(1)); self.run_command(gba, Command::Step(1));
} else { } else {
self.previous_command = None; self.previous_command = None;
continue; continue;
@ -207,7 +214,7 @@ impl Debugger {
rl.add_history_entry(line.as_str()); rl.add_history_entry(line.as_str());
let expr = parse_expr(&line); let expr = parse_expr(&line);
match expr { match expr {
Ok(expr) => self.eval_expr(expr), Ok(expr) => self.eval_expr(gba, expr),
Err(DebuggerError::ParsingError(msg)) => println!("Parsing error: {}", msg), Err(DebuggerError::ParsingError(msg)) => println!("Parsing error: {}", msg),
_ => (), _ => (),
} }

View file

@ -223,9 +223,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
#[cfg(feature = "debugger")] #[cfg(feature = "debugger")]
{ {
gba.cpu.set_verbose(true); gba.cpu.set_verbose(true);
let mut debugger = Debugger::new(gba); let mut debugger = Debugger::new();
info!("starting debugger..."); info!("starting debugger...");
debugger.repl(matches.value_of("script_file")).unwrap(); debugger
.repl(&mut gba, matches.value_of("script_file"))
.unwrap();
info!("ending debugger..."); info!("ending debugger...");
return Ok(()); return Ok(());
} }
@ -259,10 +261,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} => match scancode { } => match scancode {
#[cfg(feature = "debugger")] #[cfg(feature = "debugger")]
Scancode::F1 => { Scancode::F1 => {
let mut debugger = Debugger::new(gba); let mut debugger = Debugger::new();
info!("starting debugger..."); info!("starting debugger...");
debugger.repl(matches.value_of("script_file")).unwrap(); debugger
gba = debugger.gba; .repl(&mut gba, matches.value_of("script_file"))
.unwrap();
info!("ending debugger...") info!("ending debugger...")
} }
#[cfg(feature = "gdb")] #[cfg(feature = "gdb")]