aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/xixanta/src/assembler.rs38
1 files changed, 35 insertions, 3 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index 92f57cd..4fd8d92 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -1429,8 +1429,12 @@ impl Assembler {
"x" => {
// If the size == 2 but we can fit it on a single byte (i.e.
// because the second byte is just 0x00), then just "compress"
- // this instruction.
- if val.size == 1 || val.bytes[1] == 0x00 {
+ // this instruction. Note that this is only valid if the value
+ // is fully well-known (i.e. it's not yet to be resolved). When
+ // the value is not yet resolved, it usually revolves around an
+ // address being referenced, which is never on the zeropage
+ // section, so it wouldn't fit on a single byte anyways.
+ if val.size == 1 || (val.resolved && val.bytes[1] == 0x00) {
// Re-inforce the optimization when val.size == 2 by forcing
// the size to 1.
val.size = 1;
@@ -1441,7 +1445,7 @@ impl Assembler {
}
"y" => {
// Same optimization as with the "x" case.
- if val.size == 1 || val.bytes[1] == 0x00 {
+ if val.size == 1 || (val.resolved && val.bytes[1] == 0x00) {
val.size = 1;
Ok((AddressingMode::ZeropageIndexedY, val))
} else {
@@ -2528,6 +2532,34 @@ nop
}
#[test]
+ fn label_in_instruction_addressing() {
+ let mut asm = Assembler::new(EMPTY.to_vec());
+ asm.mappings[0].segments[0].bundles = minimal_header();
+ asm.mappings[0].offset = 6;
+ asm.current_mapping = 1;
+ let res = &asm
+ .assemble(
+ std::env::current_dir().unwrap().to_path_buf(),
+ r#"
+ ldx #0
+@load_palettes_loop:
+ lda palettes, x
+palettes:
+ .byte $0F, $12, $22, $32
+"#
+ .as_bytes(),
+ )
+ .unwrap()[0x10..];
+
+ assert_instruction("ldx #0", &res[0].bytes);
+ assert_instruction("lda $8005, x", &res[1].bytes);
+ assert_eq!(&res[2].bytes, &[0x0F, 0x00, 0x00]);
+ assert_eq!(&res[3].bytes, &[0x12, 0x00, 0x00]);
+ assert_eq!(&res[4].bytes, &[0x22, 0x00, 0x00]);
+ assert_eq!(&res[5].bytes, &[0x32, 0x00, 0x00]);
+ }
+
+ #[test]
fn full_to_zeropage_optimization() {
assert_instruction("sta $0020", &[0x85, 0x20]);
assert_instruction("sty $021, x", &[0x94, 0x21]);