Skip to content

Commit

Permalink
feat: add .BREAK directive
Browse files Browse the repository at this point in the history
  • Loading branch information
dxrcy committed Nov 28, 2024
1 parent e7e1b94 commit c6551b9
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 18 deletions.
19 changes: 8 additions & 11 deletions src/air.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ pub struct Air {
orig: Option<u16>,
/// AIR
ast: Vec<AsmLine>,

pub breakpoints: Vec<u16>,
}

impl Air {
pub fn new() -> Self {
pub fn new(breakpoints: Vec<u16>) -> Self {
Air {
orig: None,
ast: Vec::new(),
breakpoints,
}
}

Expand Down Expand Up @@ -123,17 +126,11 @@ pub enum AirStmt {
offset: u8,
},
/// Push onto stack (extended dialect)
Push {
src_reg: Register,
},
Push { src_reg: Register },
/// Pop from stack (extended dialect)
Pop {
dest_reg: Register,
},
Pop { dest_reg: Register },
/// Jump to subroutine and push onto stack (extended dialect)
Call {
dest_label: Label,
},
Call { dest_label: Label },
/// Return from subroutine using stack (extended dialect)
Rets,
/// A raw value created during preprocessing
Expand Down Expand Up @@ -341,7 +338,7 @@ impl AsmLine {
// 6. Continued offset when call
//
// There are 10 bits of offset precision when using a call instruction.
// There also isn't really a way to work around this setup if other instructions
// There also isn't really a way to work around this setup if other instructions
// are to be left untouched.
AirStmt::Push { src_reg } => {
let mut raw = 0xD000;
Expand Down
8 changes: 6 additions & 2 deletions src/debugger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,18 @@ impl TryFrom<u16> for RelevantInstr {

impl Debugger {
/// Should only be called *once* per process
pub(super) fn new(opts: DebuggerOptions, initial_state: RunState) -> Self {
pub(super) fn new(
opts: DebuggerOptions,
initial_state: RunState,
breakpoints: Vec<u16>,
) -> Self {
print::set_is_minimal(opts.minimal);

Self {
status: Status::default(),
source: SourceMode::from(opts.command),
initial_state,
breakpoints: Vec::new(),
breakpoints,
current_breakpoint: None,
}
}
Expand Down
1 change: 1 addition & 0 deletions src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ impl Cursor<'_> {
".stringz" => Some(Dir(Stringz)),
".blkw" => Some(Dir(Blkw)),
".fill" => Some(Dir(Fill)),
".break" => Some(Dir(Break)),
_ => None,
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use crate::{
/// Replaces raw value directives .fill, .blkw, .stringz with equivalent raw bytes
/// Returns a 'final' vector of tokens. This is easier than working with an iterator that can
/// either return a single token or a Vec of tokens.
pub fn preprocess(src: &'static str) -> Result<Vec<Token>> {
pub fn preprocess(src: &'static str) -> Result<(Vec<Token>, Vec<u16>)> {
let mut res: Vec<Token> = Vec::new();
let mut breakpoints = Vec::new();
let mut cur = Cursor::new(src);

loop {
Expand Down Expand Up @@ -67,13 +68,16 @@ pub fn preprocess(src: &'static str) -> Result<Vec<Token>> {
_ => return Err(error::preproc_no_str(val.span, src)),
}
}
TokenKind::Dir(DirKind::Break) => {
breakpoints.push(res.len() as u16);
}
// Eliminated during preprocessing
TokenKind::Comment | TokenKind::Whitespace => continue,
TokenKind::Eof | TokenKind::Dir(DirKind::End) => break,
_ => res.push(dir),
}
}
Ok(res)
Ok((res, breakpoints))
}

fn unescape(s: &str) -> Cow<str> {
Expand Down Expand Up @@ -123,11 +127,11 @@ impl AsmParser {
/// Preprocesses tokens, otherwise will go into unreachable code. Input should
/// contain no whitespace or comments.
pub fn new(src: &'static str) -> Result<Self> {
let toks = preprocess(src)?;
let (toks, breakpoints) = preprocess(src)?;
Ok(AsmParser {
src,
toks: toks.into_iter().peekable(),
air: Air::new(),
air: Air::new(breakpoints),
line: 1,
})
}
Expand Down
8 changes: 7 additions & 1 deletion src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,14 @@ impl RunEnvironment {
air: Air,
debugger_opts: DebuggerOptions,
) -> Result<RunEnvironment> {
// TODO(opt): Remove clone
let mut breakpoints = air.breakpoints.clone();
for breakpoint in breakpoints.iter_mut() {
*breakpoint += air.orig().unwrap_or(0x3000);
}

let mut env = Self::try_from(air)?;
env.debugger = Some(Debugger::new(debugger_opts, env.state.clone()));
env.debugger = Some(Debugger::new(debugger_opts, env.state.clone(), breakpoints));
Ok(env)
}

Expand Down
1 change: 1 addition & 0 deletions src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ pub enum DirKind {
Stringz,
Blkw,
Fill,
Break,
}

/// Newtype representing an offset from a particular address.
Expand Down
1 change: 1 addition & 0 deletions tests/files/hw.asm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
; comment
lea r0 hw
puts
.BREAK
lea r0 hw
puts
puts
Expand Down

0 comments on commit c6551b9

Please sign in to comment.