use crate::*; pub fn format_inhx32(segments: &[Segment]) -> Result, FormatError> { let mut records = Vec::new(); 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()); let mut output = String::new(); for record in records { output.push_str(&record.to_string()); } return Ok(output.into_bytes()); } fn data_record(words: &[Tracked], address: usize) -> Result { 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); record.byte(0x00); for word in words { if word.value.width > 16 { return Err(FormatError::WordTooWide(16, word.width, word.source.clone())); } record.le_double(word.value.value as u16); } return Ok(record); } 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); record.byte(0x04); record.be_double(address); return record; } fn terminating_record() -> InhxRecord { let mut record = InhxRecord::new(); record.byte(0x00); record.be_double(0x0000); record.byte(0x01); return record; }