pub struct ROM { bytes: Vec, } impl From> for ROM { fn from(bytes: Vec) -> Self { ROM { bytes } } } impl ROM { pub fn read_byte(&self, addr: u32) -> u8 { // https://godbolt.org/z/decb18Yb5 self.bytes.get(addr as usize).copied().unwrap_or(0) } pub fn read_word(&self, addr: u32) -> u16 { ((self.read_byte(addr) as u16) << 8) | self.read_byte(addr + 1) as u16 } pub fn read_long(&self, addr: u32) -> u32 { ((self.read_word(addr) as u32) << 16) | self.read_word(addr + 2) as u32 } pub fn size(&self) -> usize { self.bytes.len() } pub fn read_string(&self, range: std::ops::Range) -> String { if range.end >= self.bytes.len() { return format!("end {} >= length {}", range.end, self.bytes.len()) } String::from_utf8_lossy(&self.bytes[range]).to_string() } pub fn stack_pointer(&self) -> u32 { self.read_long(0x0) } pub fn entry_point(&self) -> u32 { self.read_long(0x4) } pub fn system_type(&self) -> String { self.read_string(0x100..0x110) } pub fn copyright(&self) -> String { self.read_string(0x110..0x120) } pub fn domestic_name(&self) -> String { self.read_string(0x120..0x150) } pub fn overseas_name(&self) -> String { self.read_string(0x150..0x180) } pub fn serial_number(&self) -> String { self.read_string(0x180..0x18E) } pub fn checksum(&self) -> u16 { self.read_word(0x18E) } pub fn device_support(&self) -> String { self.read_string(0x190..0x1A0) } pub fn region(&self) -> String { self.read_string(0x1F0..0x1F3) } }