aboutsummaryrefslogtreecommitdiff
path: root/lib/xixanta
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-16 22:05:49 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-16 22:05:49 +0100
commitbc0f8fa2607f1ef570996baa88bb9a6de06cbd5a (patch)
tree6d539a1f46ce15baac4f68d93af63ce9d0348d63 /lib/xixanta
parent2455e2bbcfb4372b13a351471a49a585ceb1597c (diff)
downloadtools.nes-bc0f8fa2607f1ef570996baa88bb9a6de06cbd5a.tar.gz
tools.nes-bc0f8fa2607f1ef570996baa88bb9a6de06cbd5a.zip
Permit 16-bit decimal values
As a remnant of old code, the 'parse_decimal' function was not allowing for decimal values larger than 8-bits. This was not the case in other areas such as 'parse_hexadecimal', and in the rest of the code we already cover that immediates are not too big in instructions. Hence, this restriction can be lift up and allow up to 16-bit decimal literals. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib/xixanta')
-rw-r--r--lib/xixanta/src/assembler.rs27
1 files changed, 18 insertions, 9 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index 8699529..e189b08 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -1134,7 +1134,7 @@ impl<'a> Assembler<'a> {
let mut shift = 1;
for c in string.chars().rev() {
- if shift > 100 {
+ if shift > 10000 {
return Err(Error {
message: "decimal value is too big".to_string(),
line: node.value.line,
@@ -1181,7 +1181,7 @@ impl<'a> Assembler<'a> {
shift *= 10;
}
- if value > 255 {
+ if value > u16::MAX.into() {
return Err(Error {
message: "decimal value is too big".to_string(),
line: node.value.line,
@@ -1190,9 +1190,10 @@ impl<'a> Assembler<'a> {
});
}
+ let bytes = value.to_le_bytes();
Ok(Bundle {
- bytes: [value as u8, 0, 0],
- size: 1,
+ bytes: [bytes[0], bytes[1], 0],
+ size: if value > 255 { 2 } else { 1 },
address: 0,
cycles: 0,
affected_on_page: false,
@@ -2334,14 +2335,14 @@ mod tests {
#[test]
fn parse_decimal() {
- assert_error("adc #256", 1, false, "decimal value is too big");
- assert_error("adc #2000", 1, false, "decimal value is too big");
+ assert_error("adc #222256", 1, false, "decimal value is too big");
assert_error(
"adc #2A",
1, false,
"'A' is not a decimal value and could not find variable '2A' in the global scope either",
);
assert_instruction("adc #1", &[0x69, 0x01]);
+ assert_instruction("adc #.hibyte(61953)", &[0x69, 0xF2]);
}
// Variables
@@ -2656,6 +2657,7 @@ cpx #(4 * var2)"#,
false,
"left arm of instruction is neither an address nor an immediate",
);
+ assert_error("adc #10000", 1, false, "immediate is too big");
}
#[test]
@@ -3292,13 +3294,20 @@ jsr Movement::update
lda #<Var
lda #.hibyte(Var)
lda #>Var
+ lda #.hibyte(61953)
"#,
);
- assert_eq!(res.len(), 4);
- let instrs: Vec<[u8; 2]> = vec![[0xA9, 0x02], [0xA9, 0x02], [0xA9, 0x20], [0xA9, 0x20]];
+ assert_eq!(res.len(), 5);
+ let instrs: Vec<[u8; 2]> = vec![
+ [0xA9, 0x02],
+ [0xA9, 0x02],
+ [0xA9, 0x20],
+ [0xA9, 0x20],
+ [0xA9, 0xF2],
+ ];
- for i in 0..4 {
+ for i in 0..instrs.len() {
assert_eq!(res[i].size, 2);
assert_eq!(res[i].bytes[0], instrs[i][0]);
assert_eq!(res[i].bytes[1], instrs[i][1]);