aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/xixanta/src/assembler.rs23
-rwxr-xr-xscripts/test-e2e.sh7
-rw-r--r--tests/expected/indirect.nesbin0 -> 28 bytes
-rw-r--r--tests/expected/indirect.txt0
-rw-r--r--tests/indirect.s18
5 files changed, 37 insertions, 11 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index d5dc5fa..11a9409 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -2739,16 +2739,17 @@ impl<'a> Assembler<'a> {
}
None => {
let evaluated_node = left.left.as_ref().unwrap();
- let val = self.evaluate_node(evaluated_node)?;
- if val.size != 2 {
- return Err(Error {
- message: "expecting a full 16-bit address".to_string(),
- line: node.value.line,
- source: self.source_for(node),
- global: false,
- expanded_from: self.macro_context.clone(),
- });
- }
+ let mut val = self.evaluate_node(evaluated_node)?;
+
+ // If this is a valid pure indirect addressing, then we know
+ // for sure we are in a 'jmp' instruction. In this case, if
+ // a zero-page address was being used, expand it to an
+ // absolute address. We do this unconditionally just to be
+ // sure, just as like we set the high byte of the address to
+ // $00 just to sanitize things.
+ val.size = 3;
+ val.bytes[2] = 0x00;
+
self.asan_check_arm(evaluated_node, &val)?;
Ok((AddressingMode::Indirect, val))
}
@@ -3677,7 +3678,6 @@ cpx #(4 * var2)"#,
false,
"only the Y index is allowed on indirect Y addressing",
);
- assert_error("jmp ($20)", 1, false, "expecting a full 16-bit address");
assert_error("adc $20, z", 1, false, "can only use X and Y as indices");
assert_error(
"adc ($2000)",
@@ -3829,6 +3829,7 @@ cpx #(4 * var2)"#,
assert_instruction("jmp $2002", &[0x4C, 0x02, 0x20]);
assert_instruction("jmp ($2002)", &[0x6C, 0x02, 0x20]);
+ assert_instruction("jmp ($20)", &[0x6C, 0x20, 0x00]);
}
#[test]
diff --git a/scripts/test-e2e.sh b/scripts/test-e2e.sh
index 06545b8..02d1ca3 100755
--- a/scripts/test-e2e.sh
+++ b/scripts/test-e2e.sh
@@ -95,6 +95,13 @@ exit_code=$((exit_code + $?))
diff tests/out/avoid_bad_macro.nes tests/expected/avoid_bad_macro.nes
exit_code=$((exit_code + $?))
+echo "test: custom => indirect.nes"
+./target/debug/nasm -c empty --asan tests/indirect.s -o tests/out/indirect.nes 2>tests/out/indirect.txt
+diff tests/out/indirect.txt tests/expected/indirect.txt
+exit_code=$((exit_code + $?))
+diff tests/out/indirect.nes tests/expected/indirect.nes
+exit_code=$((exit_code + $?))
+
##
# code.nes
diff --git a/tests/expected/indirect.nes b/tests/expected/indirect.nes
new file mode 100644
index 0000000..68136c9
--- /dev/null
+++ b/tests/expected/indirect.nes
Binary files differ
diff --git a/tests/expected/indirect.txt b/tests/expected/indirect.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/expected/indirect.txt
diff --git a/tests/indirect.s b/tests/indirect.s
new file mode 100644
index 0000000..9629d5f
--- /dev/null
+++ b/tests/indirect.s
@@ -0,0 +1,18 @@
+.segment "HEADER"
+ .byte 'N', 'E', 'S', $1A
+ .byte $02, $01
+ .byte $00
+ .byte $00
+
+.segment "CODE"
+
+zp_something = $20 ; asan:reserve $02
+
+lda #<lala
+sta zp_something
+lda #>lala
+sta zp_something + 1
+jmp (zp_something)
+
+lala:
+ rts