aboutsummaryrefslogtreecommitdiff
path: root/lib/xixanta
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2024-12-24 15:59:39 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2024-12-24 15:59:53 +0100
commit56683e97bff9f3dff5c10b0c524d650a5f6b11d6 (patch)
tree47568cbec978358a0c97d83f2c320617e1e062e8 /lib/xixanta
parente611f38c9d056da01b2cc3a532f9013ad1ee567a (diff)
downloadtools.nes-56683e97bff9f3dff5c10b0c524d650a5f6b11d6.tar.gz
tools.nes-56683e97bff9f3dff5c10b0c524d650a5f6b11d6.zip
Add a test on jumps and labels inside of procs
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib/xixanta')
-rw-r--r--lib/xixanta/src/assembler.rs63
1 files changed, 61 insertions, 2 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index 4978ee6..e9d2025 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -519,6 +519,7 @@ impl Assembler {
}
}
+ // Consume a node which contains a macro call by pushing its bundles now.
fn bundle_call(&mut self, node: &PNode, nodes: &[PNode]) -> Result<(), Vec<Error>> {
// Get the macro object for the given identifier.
let mcr = self
@@ -2674,8 +2675,6 @@ palettes:
assert_instruction("stx $020, y", &[0x96, 0x20]);
}
- // TODO: labels and jumps inside of proc's, etc.
-
// Control statements
#[test]
@@ -3358,6 +3357,66 @@ code:
}
#[test]
+ fn jumps_and_labels_inside_proc() {
+ let mut asm = Assembler::new(one_two().to_vec());
+ asm.mappings[0].segments[0].bundles = minimal_header();
+ asm.mappings[0].offset = 6;
+ let bundles = &asm
+ .assemble(
+ std::env::current_dir().unwrap().to_path_buf(),
+ r#".segment "ONE"
+nop
+.segment "TWO"
+.proc Foo
+ lda #$10
+:
+ beq :-
+ jmp @label
+ nop
+@label:
+ rts
+.endproc
+
+jsr Foo
+"#
+ .as_bytes(),
+ )
+ .unwrap()[0x11..]; // Ignoring HEADER + first nop
+
+ assert_eq!(bundles.len(), 6);
+
+ // lda #$10
+ assert_eq!(bundles[0].size, 2);
+ assert_eq!(bundles[0].bytes[0], 0xA9);
+ assert_eq!(bundles[0].bytes[1], 0x10);
+
+ // beq :-
+ assert_eq!(bundles[1].size, 2);
+ assert_eq!(bundles[1].bytes[0], 0xF0);
+ assert_eq!(bundles[1].bytes[1], 0xFE);
+
+ // jmp @label
+ assert_eq!(bundles[2].size, 3);
+ assert_eq!(bundles[2].bytes[0], 0x4C);
+ assert_eq!(bundles[2].bytes[1], 0x09);
+ assert_eq!(bundles[2].bytes[2], 0x80);
+
+ // nop
+ assert_eq!(bundles[3].size, 1);
+ assert_eq!(bundles[3].bytes[0], 0xEA);
+
+ // rts
+ assert_eq!(bundles[4].size, 1);
+ assert_eq!(bundles[4].bytes[0], 0x60);
+
+ // jsr Foo
+ assert_eq!(bundles[5].size, 3);
+ assert_eq!(bundles[5].bytes[0], 0x20);
+ assert_eq!(bundles[5].bytes[1], 0x01);
+ assert_eq!(bundles[5].bytes[2], 0x80);
+ }
+
+ #[test]
fn proc_reference_another_segment() {
let mut asm = Assembler::new(one_two().to_vec());
asm.mappings[0].segments[0].bundles = minimal_header();