From f0733cde37d07f03c82dbf3cd86d5943ee10a3d0 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 9 Jul 2024 01:39:57 -0500 Subject: [PATCH] boy-debug: misc improvements --- boy-debug/src/lib.rs | 75 ++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/boy-debug/src/lib.rs b/boy-debug/src/lib.rs index 3b7d144..9670e79 100644 --- a/boy-debug/src/lib.rs +++ b/boy-debug/src/lib.rs @@ -163,9 +163,7 @@ pub mod cli { impl> Lexible for T { fn lex(self) -> Lexer { - Lexer { - text: self.peekable(), - } + Lexer { text: self.peekable() } } } @@ -175,6 +173,7 @@ pub mod cli { } impl> Lexer { + /// Advances to the next non-whitespace character fn sync(&mut self) -> &mut Self { while self.peek().map(|c| c.is_whitespace()).unwrap_or(false) { self.take(); @@ -333,10 +332,9 @@ pub mod cli { impl> Parser { pub fn new(t: T) -> Self { - Self { - lexer: t.peekable(), - } + Self { lexer: t.peekable() } } + #[must_use] fn peek(&mut self) -> Option<&Token> { self.lexer.peek() @@ -374,10 +372,9 @@ pub mod cli { pub fn parse>(lexer: &mut Parser) -> Option { let verb = Verb::parse(lexer)?; let [dst, src] = match verb { - Verb::Set => [ - Expr::parse(lexer, 0)?, - Expr::parse(lexer.then(Token::Op(Op::Comma))?, 0)?, - ], + Verb::Set => { + [Expr::parse(lexer, 0)?, Expr::parse(lexer.then(Token::Op(Op::Eq))?, 0)?] + } Verb::Load | Verb::Get | Verb::Run @@ -440,7 +437,8 @@ pub mod cli { } Token::Op(Op::BrackOpen) => { let mut exprs = vec![]; - while p.then(Token::Op(Op::BrackClose)).is_none() { + while Some(&Token::Op(Op::BrackClose)) != p.peek() { + // while p.then(Token::Op(Op::BrackClose)).is_none() { exprs.push(Expr::parse(p, 0)?); if p.then(Token::Op(Op::Comma)).is_none() { break; @@ -510,8 +508,8 @@ pub mod cli { Range, Array, Bit, - Factor, Shift, + Factor, Term, Sign, } @@ -662,7 +660,7 @@ pub mod ast { /// Traverses the expression depth-first, calling function f() on every subexpression pub fn visit(&mut self, f: &impl Fn(&mut Expr)) { match self { - Expr::Int(_) | Expr::Bool(_) | Expr::Reg(_) | Expr::String(_)=> {} + Expr::Int(_) | Expr::Bool(_) | Expr::Reg(_) | Expr::String(_) => {} Expr::Array(v) => v.iter_mut().for_each(|e| e.visit(f)), Expr::Prefix(_, e) | Expr::Postfix(_, e) => e.visit(f), Expr::Binary(_, a, b) | Expr::Range(a, b) | Expr::Index(a, b) => { @@ -861,11 +859,6 @@ pub mod message { } pub mod gameboy { - use std::io::Write; - - use boy::cpu::CPU; - use boy::memory::io::*; - use boy_utils::*; use crate::{ ast::{Expr, Reg, Stmt, Verb}, @@ -873,6 +866,9 @@ pub mod gameboy { disassembler::Disassemble, message::{Request, Response}, }; + use boy::{cpu::CPU, error::Error, memory::io::*}; + use boy_utils::*; + use std::io::Write; #[derive(Clone, Debug)] pub struct Gameboy { @@ -883,11 +879,7 @@ pub mod gameboy { impl Gameboy { pub fn new(bus: T) -> Self { - Self { - trace: false, - cpu: CPU::new(), - bus, - } + Self { trace: false, cpu: CPU::new(), bus } } pub fn process(&mut self, message: Request) -> Response { match message { @@ -928,7 +920,7 @@ pub mod gameboy { (Verb::Load, Expr::String(file), ..) => { if let Err(e) = self.bus.read_file(file) { eprintln!("{e}"); - return Response::Failure + return Response::Failure; } } (Verb::Set, Expr::Int(addr), Expr::Int(data)) => { @@ -1060,6 +1052,7 @@ pub mod gameboy { } fn step(&mut self, steps: usize) -> Response { + use boy::error::ErrorKind as Eek; let Self { trace, cpu, bus } = self; for step in 1..=steps { let (loc, insn) = (cpu.pc(), cpu.ir()); @@ -1073,7 +1066,7 @@ pub mod gameboy { } if steps < 100 { print!( - "{loc:04x}: [{insn:?}]\x1b[23GTook {cycles} cycle{}\x1b[50G", + "{step:04x}: Took {cycles} cycle{}\x1b[38G", if cycles == 1 { "" } else { "s" } ); } @@ -1085,16 +1078,38 @@ pub mod gameboy { let _ = std::io::stdout().flush(); } } - Err(e) => { - println!( - "\n{loc:04x}: [{insn:?}]\x1b[23G{insn}\x1b[50G\x1b[31mStep {step:x}: {e}\x1b[0m" + Err(Error { kind: Eek::HitBreak(addr, cycles) }) => { + print!( + "\x1b[31m{addr:04x}\x1b[0m: Took {cycles} cycle{}\x1b[38G", + if cycles == 1 { "" } else { "s" } ); + + bus.read_iter_from(loc.wrapping_sub(1) as usize) + .disassemble() + .map(|(_, s)| println!("{:04x}: {s}", loc.wrapping_sub(1))) + .next(); + let _ = std::io::stdout().flush(); + break; + } + Err(Error { kind: Eek::UnimplementedInsn(_) }) => { + print!("{step:04x}: \x1b[91mNot yet implemented:\x1b[0m\x1b[38G"); + bus.read_iter_from(loc.wrapping_sub(1) as usize) + .disassemble() + .map(|(_, s)| println!("{:04x}: {s}", loc.wrapping_sub(1))) + .next(); + let _ = std::io::stdout().flush(); + } + Err(e) => { + print!("{step:04x}: {e}\x1b[38G{insn}"); + bus.read_iter_from(loc.wrapping_sub(1) as usize) + .disassemble() + .map(|(_, s)| println!("{:04x}: {s}", loc.wrapping_sub(1))) + .next(); + let _ = std::io::stdout().flush(); return Response::Failure; } } } - println!(); - bus.diag(0); Response::Success } }