Playing around with reading gameboy roms, and maybe emulation
1mod cartridge_header; 2mod enums; 3 4use crate::cartridge_header::CartridgeHeader; 5use crate::enums::CartridgeHeaderAddress::OldLicenseeCode; 6use crate::enums::{ 7 CGBFlag, CartridgeHeaderAddress, CartridgeType, DestinationCode, Error, RamSize, RomSize, 8}; 9use std::fs::File; 10use std::io::Read; 11 12// https://github.com/ISSOtm/gb-bootroms/blob/2dce25910043ce2ad1d1d3691436f2c7aabbda00/src/dmg.asm#L259-L269 13// Each tile is encoded using 2 (!) bytes 14// The tiles are represented below 15// XX.. .XX. XX.. .... .... .... .... .... .... ...X X... .... 16// XXX. .XX. XX.. .... ..XX .... .... .... .... ...X X... .... 17// XXX. .XX. .... .... .XXX X... .... .... .... ...X X... .... 18// XX.X .XX. XX.X X.XX ..XX ..XX XX.. XX.X X... XXXX X..X XXX. 19// XX.X .XX. XX.X XX.X X.XX .XX. .XX. XXX. XX.X X..X X.XX ..XX 20// XX.. XXX. XX.X X..X X.XX .XXX XXX. XX.. XX.X X..X X.XX ..XX 21// XX.. XXX. XX.X X..X X.XX .XX. .... XX.. XX.X X..X X.XX ..XX 22// XX.. .XX. XX.X X..X X.XX ..XX XXX. XX.. XX.. XXXX X..X XXX. 23const NINTENDO_LOGO: [u8; 48] = [ 24 0x0CE, 0x0ED, 0x066, 0x066, 0x0CC, 0x00D, 0x000, 0x00B, 0x003, 0x073, 0x000, 0x083, 0x000, 25 0x00C, 0x000, 0x00D, 0x000, 0x008, 0x011, 0x01F, 0x088, 0x089, 0x000, 0x00E, 0x0DC, 0x0CC, 26 0x06E, 0x0E6, 0x0DD, 0x0DD, 0x0D9, 0x099, 0x0BB, 0x0BB, 0x067, 0x063, 0x06E, 0x00E, 0x0EC, 27 0x0CC, 0x0DD, 0x0DC, 0x099, 0x09F, 0x0BB, 0x0B9, 0x033, 0x03E, 28]; 29 30// const ROM_NAME: &str = "OtherLegallyObtainedRom.gb"; 31const ROM_NAME: &str = "LegallyObtainedRom.gb"; 32 33fn main() -> std::io::Result<()> { 34 let mut rom_file = File::open(ROM_NAME)?; 35 let mut rom_buffer: Vec<u8> = Vec::new(); 36 rom_file.read_to_end(&mut rom_buffer)?; 37 let cart_header = match CartridgeHeader::parse(&*rom_buffer) { 38 Ok(header) => header, 39 Err(err) => { 40 return Err(std::io::Error::new( 41 std::io::ErrorKind::Other, 42 "Rom failed to parse", 43 )); 44 } 45 }; 46 // cart_header.print_test(); 47 48 let title: String = String::from_iter(cart_header.title); 49 println!("Title: {}", title); 50 let manufacturer_code = String::from_iter(cart_header.manufacturer_code); 51 println!("Manufacturer Code: {}", manufacturer_code); 52 53 match cart_header.old_licensee_code { 54 Some(code) => println!("Uses Old Licensee Code: {:#X}", code), 55 None => println!( 56 "Uses New Licensee Code: {}", 57 String::from_iter(cart_header.license_code) 58 ), 59 } 60 61 println!("CGB Flag: {:?}", cart_header.cgb_flag); 62 println!("Supports SGB: {:?}", cart_header.support_gb); 63 println!("Cartridge Type: {:?}", cart_header.cart_type); 64 println!("ROM Size: {:?}", cart_header.rom_size); 65 println!("RAM Size: {:?}", cart_header.ram_size); 66 match cart_header.destination_code { 67 DestinationCode::Japan => println!("Destination Code: Japan"), 68 DestinationCode::NotJapan => println!("Destination Code: Not Japan"), 69 } 70 println!("Version: {:?}", cart_header.version); 71 println!("Header Checksum: {:#X}", cart_header.header_checksum); 72 println!("Global Checksum: {:#X}", cart_header.global_checksum); 73 74 Ok(()) 75}