boy-debug: misc improvements
This commit is contained in:
parent
6cee907f1c
commit
f0733cde37
@ -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,
|
||||
}
|
||||
@ -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<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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user