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 {
|
impl<T: Iterator<Item = char>> Lexible for T {
|
||||||
fn lex(self) -> Lexer<Self> {
|
fn lex(self) -> Lexer<Self> {
|
||||||
Lexer {
|
Lexer { text: self.peekable() }
|
||||||
text: self.peekable(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +173,7 @@ pub mod cli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator<Item = char>> Lexer<I> {
|
impl<I: Iterator<Item = char>> Lexer<I> {
|
||||||
|
/// Advances to the next non-whitespace character
|
||||||
fn sync(&mut self) -> &mut Self {
|
fn sync(&mut self) -> &mut Self {
|
||||||
while self.peek().map(|c| c.is_whitespace()).unwrap_or(false) {
|
while self.peek().map(|c| c.is_whitespace()).unwrap_or(false) {
|
||||||
self.take();
|
self.take();
|
||||||
@ -333,10 +332,9 @@ pub mod cli {
|
|||||||
|
|
||||||
impl<T: Iterator<Item = Token>> Parser<T> {
|
impl<T: Iterator<Item = Token>> Parser<T> {
|
||||||
pub fn new(t: T) -> Self {
|
pub fn new(t: T) -> Self {
|
||||||
Self {
|
Self { lexer: t.peekable() }
|
||||||
lexer: t.peekable(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn peek(&mut self) -> Option<&Token> {
|
fn peek(&mut self) -> Option<&Token> {
|
||||||
self.lexer.peek()
|
self.lexer.peek()
|
||||||
@ -374,10 +372,9 @@ pub mod cli {
|
|||||||
pub fn parse<I: Iterator<Item = Token>>(lexer: &mut Parser<I>) -> Option<Stmt> {
|
pub fn parse<I: Iterator<Item = Token>>(lexer: &mut Parser<I>) -> Option<Stmt> {
|
||||||
let verb = Verb::parse(lexer)?;
|
let verb = Verb::parse(lexer)?;
|
||||||
let [dst, src] = match verb {
|
let [dst, src] = match verb {
|
||||||
Verb::Set => [
|
Verb::Set => {
|
||||||
Expr::parse(lexer, 0)?,
|
[Expr::parse(lexer, 0)?, Expr::parse(lexer.then(Token::Op(Op::Eq))?, 0)?]
|
||||||
Expr::parse(lexer.then(Token::Op(Op::Comma))?, 0)?,
|
}
|
||||||
],
|
|
||||||
Verb::Load
|
Verb::Load
|
||||||
| Verb::Get
|
| Verb::Get
|
||||||
| Verb::Run
|
| Verb::Run
|
||||||
@ -440,7 +437,8 @@ pub mod cli {
|
|||||||
}
|
}
|
||||||
Token::Op(Op::BrackOpen) => {
|
Token::Op(Op::BrackOpen) => {
|
||||||
let mut exprs = vec![];
|
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)?);
|
exprs.push(Expr::parse(p, 0)?);
|
||||||
if p.then(Token::Op(Op::Comma)).is_none() {
|
if p.then(Token::Op(Op::Comma)).is_none() {
|
||||||
break;
|
break;
|
||||||
@ -510,8 +508,8 @@ pub mod cli {
|
|||||||
Range,
|
Range,
|
||||||
Array,
|
Array,
|
||||||
Bit,
|
Bit,
|
||||||
Factor,
|
|
||||||
Shift,
|
Shift,
|
||||||
|
Factor,
|
||||||
Term,
|
Term,
|
||||||
Sign,
|
Sign,
|
||||||
}
|
}
|
||||||
@ -662,7 +660,7 @@ pub mod ast {
|
|||||||
/// Traverses the expression depth-first, calling function f() on every subexpression
|
/// Traverses the expression depth-first, calling function f() on every subexpression
|
||||||
pub fn visit(&mut self, f: &impl Fn(&mut Expr)) {
|
pub fn visit(&mut self, f: &impl Fn(&mut Expr)) {
|
||||||
match self {
|
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::Array(v) => v.iter_mut().for_each(|e| e.visit(f)),
|
||||||
Expr::Prefix(_, e) | Expr::Postfix(_, 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) => {
|
Expr::Binary(_, a, b) | Expr::Range(a, b) | Expr::Index(a, b) => {
|
||||||
@ -861,11 +859,6 @@ pub mod message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod gameboy {
|
pub mod gameboy {
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
use boy::cpu::CPU;
|
|
||||||
use boy::memory::io::*;
|
|
||||||
use boy_utils::*;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Expr, Reg, Stmt, Verb},
|
ast::{Expr, Reg, Stmt, Verb},
|
||||||
@ -873,6 +866,9 @@ pub mod gameboy {
|
|||||||
disassembler::Disassemble,
|
disassembler::Disassemble,
|
||||||
message::{Request, Response},
|
message::{Request, Response},
|
||||||
};
|
};
|
||||||
|
use boy::{cpu::CPU, error::Error, memory::io::*};
|
||||||
|
use boy_utils::*;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Gameboy<T: BusIO> {
|
pub struct Gameboy<T: BusIO> {
|
||||||
@ -883,11 +879,7 @@ pub mod gameboy {
|
|||||||
|
|
||||||
impl<T: BusIO> Gameboy<T> {
|
impl<T: BusIO> Gameboy<T> {
|
||||||
pub fn new(bus: T) -> Self {
|
pub fn new(bus: T) -> Self {
|
||||||
Self {
|
Self { trace: false, cpu: CPU::new(), bus }
|
||||||
trace: false,
|
|
||||||
cpu: CPU::new(),
|
|
||||||
bus,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub fn process(&mut self, message: Request) -> Response {
|
pub fn process(&mut self, message: Request) -> Response {
|
||||||
match message {
|
match message {
|
||||||
@ -928,7 +920,7 @@ pub mod gameboy {
|
|||||||
(Verb::Load, Expr::String(file), ..) => {
|
(Verb::Load, Expr::String(file), ..) => {
|
||||||
if let Err(e) = self.bus.read_file(file) {
|
if let Err(e) = self.bus.read_file(file) {
|
||||||
eprintln!("{e}");
|
eprintln!("{e}");
|
||||||
return Response::Failure
|
return Response::Failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Verb::Set, Expr::Int(addr), Expr::Int(data)) => {
|
(Verb::Set, Expr::Int(addr), Expr::Int(data)) => {
|
||||||
@ -1060,6 +1052,7 @@ pub mod gameboy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn step(&mut self, steps: usize) -> Response {
|
fn step(&mut self, steps: usize) -> Response {
|
||||||
|
use boy::error::ErrorKind as Eek;
|
||||||
let Self { trace, cpu, bus } = self;
|
let Self { trace, cpu, bus } = self;
|
||||||
for step in 1..=steps {
|
for step in 1..=steps {
|
||||||
let (loc, insn) = (cpu.pc(), cpu.ir());
|
let (loc, insn) = (cpu.pc(), cpu.ir());
|
||||||
@ -1073,7 +1066,7 @@ pub mod gameboy {
|
|||||||
}
|
}
|
||||||
if steps < 100 {
|
if steps < 100 {
|
||||||
print!(
|
print!(
|
||||||
"{loc:04x}: [{insn:?}]\x1b[23GTook {cycles} cycle{}\x1b[50G",
|
"{step:04x}: Took {cycles} cycle{}\x1b[38G",
|
||||||
if cycles == 1 { "" } else { "s" }
|
if cycles == 1 { "" } else { "s" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1085,16 +1078,38 @@ pub mod gameboy {
|
|||||||
let _ = std::io::stdout().flush();
|
let _ = std::io::stdout().flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(Error { kind: Eek::HitBreak(addr, cycles) }) => {
|
||||||
println!(
|
print!(
|
||||||
"\n{loc:04x}: [{insn:?}]\x1b[23G{insn}\x1b[50G\x1b[31mStep {step:x}: {e}\x1b[0m"
|
"\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;
|
return Response::Failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!();
|
|
||||||
bus.diag(0);
|
|
||||||
Response::Success
|
Response::Success
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user