summaryrefslogtreecommitdiff
path: root/src/formats/inhx32.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/formats/inhx32.rs')
-rw-r--r--src/formats/inhx32.rs39
1 files changed, 26 insertions, 13 deletions
diff --git a/src/formats/inhx32.rs b/src/formats/inhx32.rs
index fd7fd7b..8febeae 100644
--- a/src/formats/inhx32.rs
+++ b/src/formats/inhx32.rs
@@ -1,11 +1,19 @@
use crate::*;
-pub fn format_inhx32(words: &[Word]) -> String {
+pub fn format_inhx32(segments: &[Segment]) -> Result<Vec<u8>, FormatError> {
let mut records = Vec::new();
- records.push(extended_linear_address(0x0000));
- for (i, chunk) in words.chunks(8).enumerate() {
- records.push(data_record(chunk, (i * 8) as u16));
+ let mut address = 0;
+ records.push(extended_linear_address(0));
+ for segment in segments {
+ if (segment.address >> 16) != (address >> 16) {
+ records.push(extended_linear_address(segment.address));
+ }
+ address = segment.address;
+ for chunk in segment.words.chunks(8) {
+ records.push(data_record(chunk, address)?);
+ address += 8;
+ }
}
records.push(terminating_record());
@@ -13,24 +21,29 @@ pub fn format_inhx32(words: &[Word]) -> String {
for record in records {
output.push_str(&record.to_string());
}
- return output;
+ return Ok(output.as_bytes().to_vec());
}
-fn data_record(words: &[Word], address: u16) -> InhxRecord {
+fn data_record(words: &[Tracked<Word>], address: usize) -> Result<InhxRecord, FormatError> {
+ let Ok(address) = u32::try_from(address * 2) else {
+ return Err(FormatError::AddressTooLarge(u32::MAX as usize / 2, address));
+ };
+ let address = address as u16;
let mut record = InhxRecord::new();
record.byte((words.len() * 2) as u8);
- record.be_double(address * 2);
+ record.be_double(address);
record.byte(0x00);
for word in words {
- match word.bits <= 16 {
- true => record.le_double(word.value as u16),
- false => panic!("Word '{word}' has more than 16 bits."),
- };
+ if word.value.width > 16 {
+ return Err(FormatError::WordTooWide(16, word.width, word.source.clone()));
+ }
+ record.le_double(word.value.value as u16);
}
- return record;
+ return Ok(record);
}
-fn extended_linear_address(address: u16) -> InhxRecord {
+fn extended_linear_address(address: usize) -> InhxRecord {
+ let address = (address >> 16) as u16;
let mut record = InhxRecord::new();
record.byte(0x02);
record.be_double(0x0000);