diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-03-06 20:33:27 +1300 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-03-11 16:59:26 +1300 |
commit | 1ecee352f5844b0809d7ae66df52e34f42b44c8e (patch) | |
tree | 472b6fd57ff7f64ac3f8cd676cbe7a113ba01f05 /src/formats/raw.rs | |
parent | f2ed89083f5326a7a6f0a1720033d3388aa431fb (diff) | |
download | torque-asm-1ecee352f5844b0809d7ae66df52e34f42b44c8e.zip |
Rewrite entire assembler
The language is now more general, the code is better structured, error
reporting is more detailed, and many new language features have
been implemented:
- conditional blocks
- first-class strings
- more expression operators
- binary literals
- negative values
- invocations in constant expressions
Diffstat (limited to 'src/formats/raw.rs')
-rw-r--r-- | src/formats/raw.rs | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/formats/raw.rs b/src/formats/raw.rs new file mode 100644 index 0000000..ecc6473 --- /dev/null +++ b/src/formats/raw.rs @@ -0,0 +1,29 @@ +use crate::*; + + +pub fn format_raw(segments: &[Segment], width: Option<u32>) -> Result<Vec<u8>, FormatError> { + let Some(width) = width.or_else(|| calculate_fixed_width(&segments)) else { + return Err(FormatError::ExpectedFixedWidth); + }; + + let mut address = 0; + let bytes_per_word = ((width + 7) / 8) as usize; + let mut bytes = Vec::new(); + + for segment in segments { + // Pad to the segment start address. + let padding = segment.address.saturating_sub(address); + bytes.resize(bytes.len() + (padding * bytes_per_word), 0); + for word in &segment.words { + // Decompose word value into bytes. + let value = word.value.value; + for i in (0..bytes_per_word).rev() { + let byte = (value >> (i*8) & 0xff) as u8; + bytes.push(byte); + } + address += 1; + } + } + + return Ok(bytes); +} |