···
1
+
mod cartridge_header;
4
+
use crate::cartridge_header::CartridgeHeader;
use crate::enums::CartridgeHeaderAddress::OldLicenseeCode;
CGBFlag, CartridgeHeaderAddress, CartridgeType, DestinationCode, Error, RamSize, RomSize,
···
// const ROM_NAME: &str = "OtherLegallyObtainedRom.gb";
const ROM_NAME: &str = "LegallyObtainedRom.gb";
31
-
struct CartridgeHeader {
32
-
//Should be 80 bytes (0x014F(335) - 0x0100(256)) + 1 to include the last address
35
-
manufacturer_code: [char; 4],
37
-
// https://gbdev.io/pandocs/The_Cartridge_Header.html#01440145--new-licensee-code
38
-
license_code: [char; 2],
40
-
cart_type: CartridgeType,
43
-
old_licensee_code: Option<u8>,
44
-
destination_code: DestinationCode,
46
-
header_checksum: u8,
47
-
global_checksum: u16,
50
-
impl CartridgeHeader {
51
-
fn bytes_to_chars<const N: usize>(bytes: &[u8], break_on_null: bool) -> [char; N] {
52
-
let mut chars = [0x000 as char; N];
53
-
for (i, byte) in bytes.iter().enumerate() {
54
-
if break_on_null && *byte == 0x00 {
57
-
chars[i] = *byte as char;
62
-
fn parse(rom_bytes: &[u8]) -> Result<Self, Error> {
63
-
let start = CartridgeHeaderAddress::CartridgeHeaderStart as usize;
64
-
let end = start + 80;
65
-
let header_buffer: &[u8] = rom_bytes[start..end]
67
-
.map_err(|_| Error::CartridgeReadError)?;
69
-
//Checks if the Nintendo logo matches the device's version. Early anti piracy feature. Neat to take note of
70
-
let nintendo_logo_from_rom = &rom_bytes[CartridgeHeaderAddress::NintendoLogoStart as usize
71
-
..CartridgeHeaderAddress::NintendoLogoEnd as usize + 1];
72
-
for (i, true_logo_byte) in NINTENDO_LOGO.iter().enumerate() {
73
-
let rom_byte = nintendo_logo_from_rom[i];
74
-
if rom_byte != *true_logo_byte {
75
-
return Err(Error::CartridgeReadError);
79
-
let title = &rom_bytes[CartridgeHeaderAddress::TitleStart as usize
80
-
..CartridgeHeaderAddress::TitleEnd as usize + 1];
81
-
let title_chars = Self::bytes_to_chars::<16>(title, true);
83
-
let manufacturer_code = &rom_bytes[CartridgeHeaderAddress::ManufacturerCodeStart as usize
84
-
..CartridgeHeaderAddress::ManufacturerCodeEnd as usize + 1];
85
-
let man_code_chars = Self::bytes_to_chars::<4>(manufacturer_code, false);
87
-
let cgb_flag_byte = rom_bytes[0x0143];
88
-
let cgb_flag = match cgb_flag_byte {
89
-
0x80 => CGBFlag::SupportsColorBackwardCompatiable,
90
-
0xC0 => CGBFlag::ColorOnly,
91
-
_ => CGBFlag::NotSet,
94
-
let license_code = &rom_bytes[CartridgeHeaderAddress::NewLicenseStart as usize
95
-
..CartridgeHeaderAddress::NewLicenseEnd as usize + 1];
96
-
let license_code_chars = Self::bytes_to_chars::<2>(license_code, false);
98
-
// https://gbdev.io/pandocs/The_Cartridge_Header.html#0146--sgb-flag
99
-
let sgb_flag = rom_bytes[CartridgeHeaderAddress::SgbFlag as usize] == 0x03;
102
-
CartridgeType::from_byte(rom_bytes[CartridgeHeaderAddress::CartType as usize]);
104
-
let rom_size = RomSize::from_byte(rom_bytes[CartridgeHeaderAddress::RomSize as usize]);
105
-
let ram_size = RamSize::from_byte(rom_bytes[CartridgeHeaderAddress::RamSize as usize]);
107
-
let mut old_licensee_code = None;
109
-
old_licensee_code = Some(rom_bytes[CartridgeHeaderAddress::OldLicenseeCode as usize])
112
-
let destination_code =
113
-
DestinationCode::from_byte(rom_bytes[CartridgeHeaderAddress::DestinationCode as usize]);
115
-
let version = rom_bytes[CartridgeHeaderAddress::MaskRomVersion as usize];
116
-
let header_checksum = rom_bytes[CartridgeHeaderAddress::HeaderChecksum as usize];
117
-
let global_checksum = u16::from_le_bytes([
118
-
rom_bytes[CartridgeHeaderAddress::GlobalChecksumStart as usize],
119
-
rom_bytes[CartridgeHeaderAddress::CartridgeHeaderEnd as usize],
123
-
buffer: header_buffer
125
-
.map_err(|_| Error::CartridgeReadError)?,
126
-
title: title_chars,
127
-
manufacturer_code: man_code_chars,
129
-
license_code: license_code_chars,
130
-
support_gb: sgb_flag,
142
-
fn print_test(&self) {
143
-
for byte in self.buffer.iter() {
144
-
print!("{} ", *byte as char);
fn main() -> std::io::Result<()> {
let mut rom_file = File::open(ROM_NAME)?;