diff options
Diffstat (limited to 'lib/xixanta/src')
| -rw-r--r-- | lib/xixanta/src/assembler.rs | 58 | ||||
| -rw-r--r-- | lib/xixanta/src/mapping.rs | 530 | ||||
| -rw-r--r-- | lib/xixanta/src/mappings/empty.toml | 12 | ||||
| -rw-r--r-- | lib/xixanta/src/mappings/nrom.toml | 27 | ||||
| -rw-r--r-- | lib/xixanta/src/mappings/nrom65.toml | 27 | ||||
| -rw-r--r-- | lib/xixanta/src/mappings/unrom.toml | 69 |
6 files changed, 348 insertions, 375 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index e6f3396..d24a555 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -82,8 +82,6 @@ pub struct Assembler { impl Assembler { pub fn new(mappings: Vec<Mapping>) -> Self { - crate::mapping::assert(&mappings); - Self { context: Context::new(), literal_mode: None, @@ -1557,7 +1555,7 @@ impl Assembler { #[cfg(test)] mod tests { use super::*; - use crate::mapping::{SectionType, Segment, EMPTY}; + use crate::mapping::{get_mapping_configuration, SectionType, Segment}; fn one_two() -> Vec<Mapping> { vec![ @@ -1600,6 +1598,10 @@ mod tests { ] } + fn empty() -> Vec<Mapping> { + get_mapping_configuration("empty").unwrap() + } + fn minimal_header() -> Vec<Bundle> { vec![ Bundle::fill(0x4E), // N @@ -1615,7 +1617,7 @@ mod tests { // Set up the empty mapper, but we have to push a minimal header // (otherwise an early assertion will fail), and we need to point to the // "CODE" segment (which is in the mapping indexed by 1). - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -1636,7 +1638,7 @@ mod tests { } fn assert_error(line: &str, line_num: usize, global: bool, message: &str) { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -1668,7 +1670,7 @@ mod tests { #[test] fn empty_line() { for line in vec!["", " ", ";; Comment", " ;; Comment"].into_iter() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -1771,7 +1773,7 @@ adc $Four #[test] fn scoped_variable() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -1811,7 +1813,7 @@ adc #Another::Variable #[test] fn bare_variables() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -1836,7 +1838,7 @@ adc Variable #[test] fn reference_outer_variables() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -1930,7 +1932,7 @@ lda #Scope::Variable #[test] fn operations_with_variables() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -1970,7 +1972,7 @@ ldx #~Value #[test] fn signed_with_variables() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2003,7 +2005,7 @@ ldx #+Value #[test] fn divide_by_zero() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2025,7 +2027,7 @@ ldx #(2 / Value) #[test] fn bad_shift() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2343,7 +2345,7 @@ ldx #(2 << Value) #[test] fn same_segment_labels() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2379,7 +2381,7 @@ nop #[test] fn anonymous_relative_jumps() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2448,7 +2450,7 @@ nop #[test] fn anonymous_relative_branches() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2513,7 +2515,7 @@ nop #[test] fn conditional_branch_to_labels() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2547,7 +2549,7 @@ nop #[test] fn jsr_to_proc() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2584,7 +2586,7 @@ nop #[test] fn label_in_instruction_addressing() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2624,7 +2626,7 @@ palettes: #[test] fn byte_literals() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2663,7 +2665,7 @@ palettes: #[test] fn hi_lo_byte() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2695,7 +2697,7 @@ lda #>Var #[test] fn macro_no_arguments() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2728,7 +2730,7 @@ MACRO #[test] fn macro_not_enough_arguments() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2757,7 +2759,7 @@ MACRO #[test] fn macro_too_many_arguments() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2786,7 +2788,7 @@ MACRO(1, 2) #[test] fn macro_with_one_argument() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2819,7 +2821,7 @@ MACRO(2) #[test] fn macro_unknown_arguments() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -2849,7 +2851,7 @@ MACRO(1) #[test] fn macro_multiple_arguments() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; @@ -3132,7 +3134,7 @@ code: #[test] fn cannot_switch_to_segment_inside_of_scope() { - let mut asm = Assembler::new(EMPTY.to_vec()); + let mut asm = Assembler::new(empty()); asm.mappings[0].segments[0].bundles = minimal_header(); asm.mappings[0].offset = 6; asm.current_mapping = 1; diff --git a/lib/xixanta/src/mapping.rs b/lib/xixanta/src/mapping.rs index 8cf752d..a196c8e 100644 --- a/lib/xixanta/src/mapping.rs +++ b/lib/xixanta/src/mapping.rs @@ -1,327 +1,11 @@ use crate::errors::EvalError; use crate::object::Bundle; +use toml::{Table, Value}; -lazy_static! { - /// An empty mapper used for testing purposes. - pub static ref EMPTY: Vec<Mapping> = vec![ - Mapping { - name: String::from("HEADER"), - start: 0x0000, - size: 0x0010, - offset: 0, - fill: Some(0x00), - section_type: SectionType::Header, - segments: vec![Segment { - name: String::from("HEADER"), - len: 0, - offset: 0, - bundles: vec![], - }] - }, - Mapping { - name: String::from("ROM0"), - start: 0x8000, - size: 0x8000, - offset: 0, - fill: None, - section_type: SectionType::PrgRom, - segments: vec![Segment { - name: String::from("CODE"), - len: 0, - offset: 0, - bundles: vec![], - },] - }, - ]; - - // Mapper for a simple NROM setup (e.g. Super Mario Bros). - pub static ref NROM: Vec<Mapping> = vec![ - Mapping { - name: String::from("HEADER"), - start: 0x0000, - size: 0x0010, - offset: 0, - fill: Some(0x00), - section_type: SectionType::Header, - segments: vec![Segment { - name: String::from("HEADER"), - len: 0, - offset: 0, - bundles: vec![], - }] - }, - Mapping { - name: String::from("ROM0"), - start: 0x8000, - size: 0x7FFA, - offset: 0, - fill: Some(0x00), - section_type: SectionType::PrgRom, - segments: vec![Segment { - name: String::from("CODE"), - len: 0, - offset: 0, - bundles: vec![], - },] - }, - Mapping { - name: String::from("ROMV"), - start: 0xFFFA, - size: 0x0006, - offset: 0, - fill: Some(0x00), - section_type: SectionType::PrgRom, - segments: vec![Segment { - name: String::from("VECTORS"), - len: 0, - offset: 0, - bundles: vec![], - },] - }, - Mapping { - name: String::from("ROM2"), - start: 0x0000, - size: 0x2000, - offset: 0, - fill: Some(0x00), - section_type: SectionType::ChrRom, - segments: vec![Segment { - name: String::from("CHARS"), - len: 0, - offset: 0, - bundles: vec![], - },] - }, - ]; - - // Mapper for UxROM boards (UxROM (NES-UNROM, NES-UOROM, HVC-UN1ROM their - // HVC counterparts, and clone boards). - pub static ref UXROM: Vec<Mapping> = vec![ - Mapping { - name: String::from("HEADER"), - start: 0x0000, - size: 0x0010, - offset: 0, - fill: Some(0x00), - section_type: SectionType::Header, - segments: vec![Segment { - name: String::from("HEADER"), - len: 0, - offset: 0, - bundles: vec![], - }] - }, - Mapping { - name: String::from("PRG0"), - start: 0x8000, - size: 0x4000, - offset: 0, - fill: Some(0xF8), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("BANK0"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("PRG1"), - start: 0x8000, - size: 0x4000, - offset: 0, - fill: Some(0xF9), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("BANK1"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("PRG2"), - start: 0x8000, - size: 0x4000, - offset: 0, - fill: Some(0xFA), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("BANK2"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("PRG3"), - start: 0x8000, - size: 0x4000, - offset: 0, - fill: Some(0xFB), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("BANK3"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("PRG4"), - start: 0x8000, - size: 0x4000, - offset: 0, - fill: Some(0xFC), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("BANK4"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("PRG5"), - start: 0x8000, - size: 0x4000, - offset: 0, - fill: Some(0xFD), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("BANK5"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("PRG6"), - start: 0x8000, - size: 0x4000, - offset: 0, - fill: Some(0xFE), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("BANK6"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("PRG"), - start: 0xC000, - size: 0x3FFA, - offset: 0, - fill: Some(0xFF), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("FIXED"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("ROMV"), - start: 0xFFFA, - size: 0x0006, - offset: 0, - fill: Some(0x00), - section_type: SectionType::PrgRom, - segments: vec![Segment { - name: String::from("VECTORS"), - len: 0, - offset: 0, - bundles: vec![], - },] - }, - ]; - - pub static ref NROM65: Vec<Mapping> = vec![ - Mapping { - name: String::from("HEADER"), - start: 0x0000, - size: 0x0010, - offset: 0, - fill: Some(0x00), - section_type: SectionType::Header, - segments: vec![Segment { - name: String::from("HEADER"), - len: 0, - offset: 0, - bundles: vec![], - }] - }, - Mapping { - name: String::from("ROM0"), - start: 0x8000, - size: 0x7FFA, - offset: 0, - fill: Some(0x00), - section_type: SectionType::PrgRom, - segments: vec![ - Segment { - name: String::from("STARTUP"), - len: 0, - offset: 0, - bundles: vec![], - }, - Segment { - name: String::from("CODE"), - len: 0, - offset: 0, - bundles: vec![], - }, - ] - }, - Mapping { - name: String::from("ROMV"), - start: 0xFFFA, - size: 0x0006, - offset: 0, - fill: Some(0x00), - section_type: SectionType::PrgRom, - segments: vec![Segment { - name: String::from("VECTORS"), - len: 0, - offset: 0, - bundles: vec![], - },] - }, - Mapping { - name: String::from("ROM2"), - start: 0x0000, - size: 0x2000, - offset: 0, - fill: Some(0x00), - section_type: SectionType::ChrRom, - segments: vec![Segment { - name: String::from("CHARS"), - len: 0, - offset: 0, - bundles: vec![], - },] - }, - ]; -} +const EMPTY_CONFIG: &str = include_str!("mappings/empty.toml"); +const NROM_CONFIG: &str = include_str!("mappings/nrom.toml"); +const NROM65_CONFIG: &str = include_str!("mappings/nrom65.toml"); +const UXROM_CONFIG: &str = include_str!("mappings/unrom.toml"); /// The type of section that a Mapping represents. #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] @@ -353,6 +37,17 @@ pub struct Segment { pub bundles: Vec<Bundle>, } +impl From<&str> for Segment { + fn from(name: &str) -> Self { + Segment { + name: name.to_string(), + offset: 0, + len: 0, + bundles: vec![], + } + } +} + impl Segment { /// Returns the length of the segment by counting the bundles that have been // pushed so far into the segment. @@ -401,39 +96,180 @@ pub struct Mapping { pub section_type: SectionType, } -/// Assert that the given mappings conform to a minimum standard. -pub fn assert(mappings: &[Mapping]) { - assert!( - !mappings.is_empty(), - "We need at least one segment defined, the header" - ); - assert!( - !mappings.first().unwrap().segments.is_empty(), - "We need at least one segment defined, the header" - ); - assert_eq!( - mappings.first().unwrap().section_type, - SectionType::Header, - "First mapping section must be the header" - ); - assert_eq!( - mappings.first().unwrap().size, - 0x10, - "The header must be exactly 16 bytes long" - ); +/// Returns a vector corresponding to the configuration of mappings that is +/// expected for the given `name`. Returns an error if the configuration cannot +/// be parsed or there's something wrong about it. +pub fn get_mapping_configuration(name: &str) -> Result<Vec<Mapping>, String> { + let text = match name.to_lowercase().as_str() { + "empty" => EMPTY_CONFIG, + "nrom" => NROM_CONFIG, + "nrom65" => NROM65_CONFIG, + "uxrom" | "unrom" => UXROM_CONFIG, + _ => return Err("mapper configuration is not known".to_string()), + }; + + let configuration = load_configuration_for(text)?; + validate_configuration(&configuration)?; + + Ok(configuration) +} + +// Returns the integer value for the mandatory integer contained in `value` that +// is named `prop_name` under the `section_name` section. This integer has to be +// lesser or equal to the `max` value. +fn get_integer( + section_name: &String, + prop_name: &str, + value: Option<&Value>, + max: usize, +) -> Result<usize, String> { + if value.is_none() { + return Err(format!( + "you have to define a value for '{}' in '{}'", + section_name, prop_name + )); + } + if !value.unwrap().is_integer() { + return Err(format!( + "value for '{}' in '{}' has to be an integer value", + section_name, prop_name + )); + } + + let val = value.unwrap().as_integer().unwrap() as usize; + if val > max { + return Err(format!( + "value for '{}' in '{}' is too big", + prop_name, section_name + )); + } + Ok(val) +} + +// Get a `SectionType` out of the given mandatory `value` which is under the +// `section_name`. +fn parse_section_type(section_name: &String, value: Option<&Value>) -> Result<SectionType, String> { + match value { + Some(v) => { + if !v.is_str() { + return Err(format!( + "'section_type' in '{}' has to be a string", + section_name + )); + } + match v.as_str().unwrap().to_lowercase().as_str() { + "header" => Ok(SectionType::Header), + "prgrom" => Ok(SectionType::PrgRom), + "chrrom" => Ok(SectionType::ChrRom), + _ => Err(format!( + "bad value for 'section_type' in '{}'", + section_name + )), + } + } + None => Err(format!( + "you have to define 'section_type' in '{}'", + section_name + )), + } +} + +// Returns a vector of segments which are contained inside of the mandatory +// `value`. +fn get_segments(section_name: &String, value: Option<&Value>) -> Result<Vec<Segment>, String> { + if value.is_none() { + return Err(format!( + "you have to define a value for 'segments' in '{}'", + section_name + )); + } + if !value.unwrap().is_array() { + return Err(format!( + "value for 'segments' in '{}' has to be an array value", + section_name + )); + } + + let mut res = vec![]; + for item in value.unwrap().as_array().unwrap() { + if !item.is_str() { + return Err(format!( + "every item in 'segments' has to be a string ({})", + section_name + )); + } + res.push(Segment::from(item.as_str().unwrap())); + } + + Ok(res) +} + +// Returns a vector of mappings that is retrieved by parsing the given text. +fn load_configuration_for(text: &str) -> Result<Vec<Mapping>, String> { + // Obtain the raw data by parsing the given text as a toml::Table. + let table = match text.parse::<Table>() { + Ok(t) => t, + Err(e) => return Err(format!("could not parse configuration file: {}", e)), + }; + + // Each section of the configuration file is a mapping, where the title is + // simply the name of it. + let mut mappings = vec![]; + for (name, value) in table { + let start = get_integer(&name, "start", value.get("start"), u16::MAX as usize)? as u16; + let size = get_integer(&name, "size", value.get("size"), u16::MAX as usize)?; + let fill = match value.get("fill") { + Some(_) => Some(get_integer(&name, "fill", value.get("fill"), u8::MAX as usize)? as u8), + None => None, + }; + let section_type = parse_section_type(&name, value.get("section_type"))?; + let segments = get_segments(&name, value.get("segments"))?; + + mappings.push(Mapping { + name, + start, + size, + offset: 0, + fill, + section_type, + segments, + }); + } + + Ok(mappings) +} + +// Ensure that the given mappings conform to a minimum standard. +fn validate_configuration(mappings: &[Mapping]) -> Result<(), String> { + if mappings.is_empty() { + return Err("We need at least one segment defined, the header".to_string()); + } + if mappings.first().unwrap().segments.is_empty() { + return Err("We need at least one segment defined, the header".to_string()); + } + if mappings.first().unwrap().section_type != SectionType::Header { + return Err("First mapping section must be the header".to_string()); + } + if mappings.first().unwrap().size != 0x10 { + return Err("The header must be exactly 16 bytes long".to_string()); + } let prg_rom_len = mappings .iter() .filter(|m| m.section_type == SectionType::PrgRom) .fold(0, |acc, x| acc + x.size); - assert!(prg_rom_len >= 0x4000, "PRG ROM must be at least 8KB long"); - assert!( - prg_rom_len % 0x4000 == 0, - "PRG ROM must be formed by banks of exactly 8KB" - ); + + if prg_rom_len < 0x4000 { + return Err("PRG ROM must be at least 8KB long".to_string()); + } + if prg_rom_len % 0x4000 != 0 { + return Err("PRG ROM must be formed by banks of exactly 8KB".to_string()); + } + + Ok(()) } -/// Validate some sanity checks on the given `mappings`. Only call this function +/// Perform some sanity checks on the given `mappings`. Only call this function /// after all bundles have been produced. pub fn validate(mappings: &[Mapping]) -> Result<(), EvalError> { // Guaranteed by `crate::mapping::assert` to be the header. diff --git a/lib/xixanta/src/mappings/empty.toml b/lib/xixanta/src/mappings/empty.toml new file mode 100644 index 0000000..ae6312c --- /dev/null +++ b/lib/xixanta/src/mappings/empty.toml @@ -0,0 +1,12 @@ +[HEADER] +start = 0x0000 +size = 0x0010 +fill = 0x00 +section_type = "Header" +segments = ["HEADER"] + +[ROM0] +start = 0x8000 +size = 0x8000 +section_type = "PRGROM" +segments = ["CODE"] diff --git a/lib/xixanta/src/mappings/nrom.toml b/lib/xixanta/src/mappings/nrom.toml new file mode 100644 index 0000000..18711a6 --- /dev/null +++ b/lib/xixanta/src/mappings/nrom.toml @@ -0,0 +1,27 @@ +[HEADER] +start = 0x0000 +size = 0x0010 +fill = 0x00 +section_type = "Header" +segments = ["HEADER"] + +[ROM0] +start = 0x8000 +size = 0x7FFA +fill = 0x00 +section_type = "PRGROM" +segments = ["CODE"] + +[ROMV] +start = 0xFFFA +size = 0x0006 +fill = 0x00 +section_type = "PRGROM" +segments = ["VECTORS"] + +[ROM2] +start = 0x0000 +size = 0x2000 +fill = 0x00 +section_type = "CHRROM" +segments = ["CHARS"] diff --git a/lib/xixanta/src/mappings/nrom65.toml b/lib/xixanta/src/mappings/nrom65.toml new file mode 100644 index 0000000..d4775e4 --- /dev/null +++ b/lib/xixanta/src/mappings/nrom65.toml @@ -0,0 +1,27 @@ +[HEADER] +start = 0x0000 +size = 0x0010 +fill = 0x00 +section_type = "Header" +segments = ["HEADER"] + +[ROM0] +start = 0x8000 +size = 0x7FFA +fill = 0x00 +section_type = "PRGROM" +segments = ["STARTUP", "CODE"] + +[ROMV] +start = 0xFFFA +size = 0x0006 +fill = 0x00 +section_type = "PRGROM" +segments = ["VECTORS"] + +[ROM2] +start = 0x0000 +size = 0x2000 +fill = 0x00 +section_type = "CHRROM" +segments = ["CHARS"] diff --git a/lib/xixanta/src/mappings/unrom.toml b/lib/xixanta/src/mappings/unrom.toml new file mode 100644 index 0000000..070cfd1 --- /dev/null +++ b/lib/xixanta/src/mappings/unrom.toml @@ -0,0 +1,69 @@ +[HEADER] +start = 0x0000 +size = 0x0010 +fill = 0x00 +section_type = "Header" +segments = ["HEADER"] + +[PRG0] +start = 0x8000 +size = 0x4000 +fill = 0xF8 +section_type = "PRGROM" +segments = ["BANK0"] + +[PRG1] +start = 0x8000 +size = 0x4000 +fill = 0xF9 +section_type = "PRGROM" +segments = ["BANK1"] + +[PRG2] +start = 0x8000 +size = 0x4000 +fill = 0xFA +section_type = "PRGROM" +segments = ["BANK2"] + +[PRG3] +start = 0x8000 +size = 0x4000 +fill = 0xFB +section_type = "PRGROM" +segments = ["BANK3"] + +[PRG4] +start = 0x8000 +size = 0x4000 +fill = 0xFC +section_type = "PRGROM" +segments = ["BANK4"] + +[PRG5] +start = 0x8000 +size = 0x4000 +fill = 0xFD +section_type = "PRGROM" +segments = ["BANK5"] + +[PRG6] +start = 0x8000 +size = 0x4000 +fill = 0xFE +section_type = "PRGROM" +segments = ["BANK6"] + +[PRG] +start = 0xC000 +size = 0x3FFA +fill = 0xFF +section_type = "PRGROM" +segments = ["FIXED"] + +[ROMV] +start = 0xFFFA +size = 0x0006 +fill = 0x00 +section_type = "PRGROM" +segments = ["VECTORS"] |
