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}