boy-debug: misc improvements

This commit is contained in:
John 2024-07-09 01:39:57 -05:00
parent 6cee907f1c
commit f0733cde37

View File

@ -163,9 +163,7 @@ pub mod cli {
impl<T: Iterator<Item = char>> Lexible for T {
fn lex(self) -> Lexer<Self> {
Lexer {
text: self.peekable(),
}
Lexer { text: self.peekable() }
}
}
@ -175,6 +173,7 @@ pub mod cli {
}
impl<I: Iterator<Item = char>> Lexer<I> {
/// 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<T: Iterator<Item = Token>> Parser<T> {
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<I: Iterator<Item = Token>>(lexer: &mut Parser<I>) -> Option<Stmt> {
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,
}
@ -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<T: BusIO> {
@ -883,11 +879,7 @@ pub mod gameboy {
impl<T: BusIO> Gameboy<T> {
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
}
}