summaryrefslogtreecommitdiff
path: root/src/formats/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/formats/mod.rs')
-rw-r--r--src/formats/mod.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/formats/mod.rs b/src/formats/mod.rs
index 82f19f1..132001a 100644
--- a/src/formats/mod.rs
+++ b/src/formats/mod.rs
@@ -1,8 +1,78 @@
mod inhx;
mod inhx32;
+mod raw;
+mod debug;
pub use inhx::*;
pub use inhx32::*;
+pub use raw::*;
+pub use debug::*;
+
+use crate::*;
+
+use log::*;
+
+
+#[derive(Clone, Copy, PartialEq)]
+pub enum Format {
+ Debug,
+ Inhx,
+ Inhx32,
+ Raw,
+ Source,
+}
+
+impl Format {
+ pub fn from_str(string: &str) -> Self {
+ match string {
+ "debug" => Self::Debug,
+ "inhx" => Self::Inhx,
+ "inhx32" => Self::Inhx32,
+ "raw" => Self::Raw,
+ "source" => Self::Source,
+ _ => fatal!("Unknown format '{string}', expected 'debug', 'inhx', 'inhx32', 'raw', or 'source'. "),
+ }
+ }
+}
+
+impl std::fmt::Display for Format {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+ let string = match self {
+ Self::Debug => "debug",
+ Self::Inhx => "inhx",
+ Self::Inhx32 => "inhx32",
+ Self::Raw => "raw",
+ Self::Source => "source",
+ };
+ write!(f, "{string}")
+ }
+}
+
+
+pub enum FormatError {
+ /// (expected, received)
+ AddressTooLarge(usize, usize),
+ /// (expected, received)
+ WordTooWide(u32, u32, SourceSpan),
+ ///
+ ExpectedFixedWidth,
+}
+
+pub fn report_format_error(error: &FormatError, format: Format, source_code: &str) {
+ match error {
+ FormatError::AddressTooLarge(expected, received) =>
+ error!("The {format} format requires that addresses do not exceed {expected}, but the address {received} was reached"),
+ FormatError::WordTooWide(expected, received, source) => {
+ let message = format!("The {format} format requires that words are no wider than {expected} bits, but a {received} bit word was found");
+ let context = Context { source_code, source };
+ report_source_issue(LogLevel::Error, &context, &message);
+ }
+ FormatError::ExpectedFixedWidth =>
+ error!("The {format} format requires all words to be the same width"),
+ }
+ std::process::exit(1);
+}
+
pub struct InhxRecord {
@@ -43,3 +113,20 @@ impl InhxRecord {
format!(":{output}{checksum:0>2X}\n")
}
}
+
+
+pub fn calculate_fixed_width(segments: &[Segment]) -> Option<u32> {
+ let mut width = None;
+ for segment in segments {
+ for word in &segment.words {
+ let word_width = word.value.width;
+ match width {
+ Some(width) => if word_width != width {
+ return None;
+ }
+ None => width = Some(word_width),
+ }
+ }
+ }
+ return width.or(Some(0));
+}