asm: fix relocations and dangling bytes
The 6502 assembler took a different approach to relocations, wherein jump values were stored in the subsequent byte. In this device, jump values are stored in the current word. Additionally, jumps only have a 1-word offset, not 2-bytes. This necessitates several changes, which are presented here. This includes not eating the subsequent byte, and only subtracting 1 from the current PC rather than 2. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
78a2fd2deb
commit
727d101adf
42
src/lib.rs
42
src/lib.rs
@ -100,7 +100,7 @@ macro_rules! lockstep_replace {
|
|||||||
// Position of a replacement reached (or: inside a replacement)
|
// Position of a replacement reached (or: inside a replacement)
|
||||||
// Coupled with a seek step
|
// Coupled with a seek step
|
||||||
lockstep_replace!(
|
lockstep_replace!(
|
||||||
[ $($result,)* $rep1 ],
|
[ $($result,)* $rep1 | $src1_replaced ],
|
||||||
[ $($src,)* ],
|
[ $($src,)* ],
|
||||||
[],
|
[],
|
||||||
[ $($rep_rest,)* ],
|
[ $($rep_rest,)* ],
|
||||||
@ -134,7 +134,12 @@ macro_rules! lockstep_replace {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
macro_rules! reloc {
|
macro_rules! reloc {
|
||||||
( { $($attr:tt)* } [ $( [ $($pos:expr),* ], [ $($rep:expr),* ] ),* ], $lblmap:ident, [ $($mcode:expr),* ], [/* empty relocation list */] ) => {
|
( { $($attr:tt)* }
|
||||||
|
[ $( [ $($pos:expr),* ],
|
||||||
|
[ $($rep:expr),* ] ),* ],
|
||||||
|
$lblmap:ident,
|
||||||
|
[ $($mcode:expr),* ],
|
||||||
|
[/* empty relocation list */] ) => {
|
||||||
lockstep_replace!([], [ $($mcode,)* ], $( [ $($pos,)* ], [ $($rep,)* ], )*)
|
lockstep_replace!([], [ $($mcode,)* ], $( [ $($pos,)* ], [ $($rep,)* ], )*)
|
||||||
};
|
};
|
||||||
( { start: $start:expr } [ $( [ $($pos:expr),* ], [ $($rep:expr),* ] ),* ], $lblmap:ident, [ $($mcode:expr),* ], [ { $lbl:ident as ABS16 @ [$($lockstepmcpos:expr),*] } $(,$reloc:tt)* ] ) => {
|
( { start: $start:expr } [ $( [ $($pos:expr),* ], [ $($rep:expr),* ] ),* ], $lblmap:ident, [ $($mcode:expr),* ], [ { $lbl:ident as ABS16 @ [$($lockstepmcpos:expr),*] } $(,$reloc:tt)* ] ) => {
|
||||||
@ -147,15 +152,14 @@ macro_rules! reloc {
|
|||||||
[ $($lockstepmcpos),* ], [ ($lblmap!($lbl) + $start) as u8, (($lblmap!($lbl) + $start) >> 8) as u8 ] ],
|
[ $($lockstepmcpos),* ], [ ($lblmap!($lbl) + $start) as u8, (($lblmap!($lbl) + $start) >> 8) as u8 ] ],
|
||||||
$lblmap, [ $($mcode),* ], [ $($reloc),* ])
|
$lblmap, [ $($mcode),* ], [ $($reloc),* ])
|
||||||
};
|
};
|
||||||
( { $($attr:tt)* } [ $( [ $($pos:expr),* ], [ $($rep:expr),* ] ),* ], $lblmap:ident, [ $($mcode:expr),* ], [ { $lbl:ident as PCREL @ [$($lockstepmcpos:expr),*] } $(,$reloc:tt)* ] ) => {
|
( { $($attr:tt)* } [ $( [ $($pos:expr),* ], [ $($rep:expr),* ] ),* ], $lblmap:ident, [ $($mcode:expr),* ], [ { $lbl:ident as PCREL @ [$($lockstepmcpos:expr,)*] } $(,$reloc:tt)* ] ) => {
|
||||||
// Replace 1 Byte with the PC relative address
|
// OR in the PC-relative address to the opcode
|
||||||
// PC is the program counter *after* the relocated offset (the length of the
|
|
||||||
// `$lockstepmcpos` array + 1), so we need to subtract 1 additional byte.
|
|
||||||
reloc!(
|
reloc!(
|
||||||
{ $($attr)* }
|
{ $($attr)* }
|
||||||
[ $( [ $($pos),* ], [ $($rep),* ] ,)*
|
[ $( [ $($pos),* ], [ $($rep),* ] ,)*
|
||||||
[ $($lockstepmcpos),* ], [ ((( $lblmap!($lbl) as i32 - codelen!($($lockstepmcpos),*) as i32 - 1 ) & 0x3FF ) << 23) ] ],
|
[ $($lockstepmcpos),* ], [ ((( $lblmap!($lbl) as i32 - (codelen!($($lockstepmcpos),*)) as i32 - 1 ) & 0x3FF ) << 23) ] ],
|
||||||
$lblmap, [ $($mcode),* ], [ $($reloc),* ])
|
$lblmap,
|
||||||
|
[ $($mcode),* ], [ $($reloc),* ])
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,17 +211,25 @@ macro_rules! asm_ {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// BRZ
|
// BRZ
|
||||||
// ( { $($attr:tt)* } [ $($mcode:expr),* ], [ $($lbl:ident => $lblval:expr),* ], [ $($reloc:tt),* ],
|
( { $($attr:tt)* } [ $($mcode:expr),* ], [ $($lbl:ident => $lblval:expr),* ], [ $($reloc:tt),* ],
|
||||||
// brz $label:ident , % $ra:tt
|
brz $label:ident , %$ra:tt
|
||||||
// $($rest:tt)* ) => {
|
$($rest:tt)* ) => {
|
||||||
// asm_!({ $($attr)* } [ $($mcode,)* 0x0 ],
|
asm_!({ $($attr)* } [ $($mcode,)* 0 << 23 | 0 << 11 | $ra << 6 | 0x9 ],
|
||||||
// [ $($lbl => $lblval),* ], [ $($reloc,)* { $label as PCREL @ [ $($mcode,)* ] } ], $($rest)*)
|
[ $($lbl => $lblval),* ], [ $($reloc,)* { $label as PCREL @ [$($mcode,)*] } ], $($rest)*)
|
||||||
// };
|
};
|
||||||
|
|
||||||
( { $($attr:tt)* } [ $($mcode:expr),* ], [ $($lbl:ident => $lblval:expr),* ], [ $($reloc:tt),* ],
|
( { $($attr:tt)* } [ $($mcode:expr),* ], [ $($lbl:ident => $lblval:expr),* ], [ $($reloc:tt),* ],
|
||||||
brz $label:ident , #$ra:tt
|
brz $label:ident , #$ra:tt
|
||||||
$($rest:tt)* ) => {
|
$($rest:tt)* ) => {
|
||||||
asm_!({ $($attr)* } [ $($mcode,)* 0 << 23 | 1 << 11 | $ra << 6 | 0x9 ],
|
asm_!({ $($attr)* } [ $($mcode,)* 0 << 23 | 1 << 11 | $ra << 6 | 0x9 ],
|
||||||
[ $($lbl => $lblval),* ], [ $($reloc,)* { $label as PCREL @ [$($mcode,)* 0 << 23 | 1 << 11 | $ra << 6 | 0x9] } ], $($rest)*)
|
[ $($lbl => $lblval),* ], [ $($reloc,)* { $label as PCREL @ [$($mcode,)*] } ], $($rest)*)
|
||||||
|
};
|
||||||
|
|
||||||
|
// UDF
|
||||||
|
( { $($attr:tt)* } [ $($mcode:expr),* ], [ $($lbl:ident => $lblval:expr),* ], [ $($reloc:tt),* ],
|
||||||
|
udf
|
||||||
|
$($rest:tt)* ) => {
|
||||||
|
asm_!({ $($attr)* } [ $($mcode,)* -0x7FFF_FFFF ], [ $($lbl => $lblval),* ], [ $($reloc),* ], $($rest)*)
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================================================================================
|
// ==================================================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user