diff options
Diffstat (limited to 'lib/xixanta')
| -rw-r--r-- | lib/xixanta/src/assembler.rs | 38 |
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]); |
