Skip to content

Commit

Permalink
Implement the hibyte/lobyte functions
Browse files Browse the repository at this point in the history
Signed-off-by: Miquel Sabaté Solà <[email protected]>
  • Loading branch information
mssola committed Oct 21, 2024
1 parent 98016fb commit 5cb4a00
Showing 1 changed file with 60 additions and 2 deletions.
62 changes: 60 additions & 2 deletions lib/xixanta/src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,42 @@ impl Assembler {
}

fn evaluate_control(&mut self, node: &PNode) -> Result<Bundle, EvalError> {
println!("NODE: {:#?}", node);
Ok(Bundle::default())
let function = node.value.value.as_str();

match function {
".hibyte" => self.evaluate_byte(node, true),
".lobyte" => self.evaluate_byte(node, false),
_ => Err(EvalError {
line: node.value.line,
message: format!(
"cannot handle control statement '{}' in this context",
function
),
}),
}
}

fn evaluate_byte(&mut self, node: &PNode, high: bool) -> Result<Bundle, EvalError> {
// The parser actually guarantees that the ".hibyte" and ".lobyte"
// functions have exactly one argument. Hence, if this is not the case,
// it's fine to let "unwrap" panic: it's a sign that's something is
// wrong elsewhere.
let arg = node.args.as_ref().unwrap().first().unwrap();

// Get the bundle from the argument
let mut bundle = self.evaluate_node(arg)?;

// The bundle we got is going to be shuffled if we wanted the high byte.
// After that, just zero out the rest (not mandatory but let's do it out
// of consistency) and set the size to just one byte.
if high {
bundle.bytes[0] = bundle.bytes[1];
}
bundle.bytes[1] = 0x00;
bundle.bytes[2] = 0x00;
bundle.size = 1;

Ok(bundle)
}

fn evaluate_variable(&mut self, id: &PString) -> Result<Bundle, EvalError> {
Expand Down Expand Up @@ -1290,6 +1324,30 @@ lda #Scope::Variable
// Control statements
// TODO: .byte, .word, variables in between (e.g. `.byte Variable::Value`, `lda #.hibyte(Variable)`)

#[test]
fn hi_lo_byte() {
let mut asm = Assembler::new(EMPTY.to_vec());
let res = asm
.assemble(
r#"
Var = $2002
lda #.lobyte(Var)
lda #.hibyte(Var)
"#
.as_bytes(),
)
.unwrap();

assert_eq!(res.len(), 2);
let instrs: Vec<[u8; 2]> = vec![[0xA9, 0x02], [0xA9, 0x20]];

for i in 0..2 {
assert_eq!(res[i].size, 2);
assert_eq!(res[i].bytes[0], instrs[i][0]);
assert_eq!(res[i].bytes[1], instrs[i][1]);
}
}

// Macros

#[test]
Expand Down

0 comments on commit 5cb4a00

Please sign in to comment.