Skip to content

Commit

Permalink
Use Cart Header
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacMarovitz committed May 7, 2024
1 parent 0cd28ef commit 0a56aa9
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 21 deletions.
4 changes: 3 additions & 1 deletion src/components/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::process;
use crate::config::Config;
use crate::components::prelude::*;
use crate::Framebuffer;
use crate::mbc::header::Header;

pub struct CPU {
pub reg: Registers,
Expand All @@ -18,6 +19,7 @@ unsafe impl Send for CPU {}

impl CPU {
pub fn new(rom: Vec<u8>,
header: Header,
config: Config,
framebuffer: Framebuffer) -> Self {
let mut boot_rom: [u8; 0x900] = [0; 0x900];
Expand All @@ -41,7 +43,7 @@ impl CPU {

Self {
reg: Registers::new(config.mode),
mem: MMU::new(rom, config, boot_rom, framebuffer),
mem: MMU::new(rom, header, config, boot_rom, framebuffer),
halted: false,
ime: false,
ime_ask: false
Expand Down
13 changes: 5 additions & 8 deletions src/components/mmu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::mbc::prelude::*;
use crate::sound::apu::APU;
use crate::Framebuffer;
use bitflags::bitflags;
use num_traits::FromPrimitive;
use crate::components::prelude::ppu::PPU;
use crate::mbc::header::Header;

pub struct MMU {
mbc: Box<dyn MBC + 'static>,
Expand Down Expand Up @@ -37,16 +37,13 @@ bitflags! {

impl MMU {
pub fn new(rom: Vec<u8>,
header: Header,
config: Config,
boot_rom: [u8; 0x900],
framebuffer: Framebuffer) -> Self {
let cart_type: CartTypes = FromPrimitive::from_u8(rom[0x0147]).expect("Failed to get Cart Type!");
let mbc_mode = match cart_type.get_mbc() {
MBCMode::Unsupported => panic!("Unsupported Cart Type! {:}", cart_type),
v => {
println!("Cart Type: {:}, MBC Type: {:}", cart_type, v);
v
}
let mbc_mode = match header.cart_type.get_mbc() {
MBCMode::Unsupported => panic!("Unsupported Cart Type! {:}", header.cart_type),
v => v
};

let mbc: Box<dyn MBC> = match mbc_mode {
Expand Down
18 changes: 11 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use winit::event_loop::EventLoop;
use winit::application::ApplicationHandler;
use winit::window::{Window, WindowId};
use crate::components::prelude::ppu::FRAMEBUFFER_SIZE;
use crate::mbc::header::{CGBFlag, Header};

type Framebuffer = Arc<RwLock<[u8; FRAMEBUFFER_SIZE]>>;

Expand All @@ -42,7 +43,7 @@ struct Args {
}

struct App {
game_name: String,
header: Header,
context: Option<Arc<Mutex<Context>>>,
config: Config,
input_tx: Sender<(JoypadButton, bool)>,
Expand All @@ -52,7 +53,7 @@ struct App {
impl ApplicationHandler for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let window_attributes = Window::default_attributes()
.with_title(format!("tetsuyu - {:}", self.game_name))
.with_title(format!("tetsuyu - {:}", self.header.title))
.with_inner_size(winit::dpi::LogicalSize::new(
self.config.window_w,
self.config.window_h,
Expand Down Expand Up @@ -152,9 +153,12 @@ fn main() {
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).expect("Failed to read ROM!");

// Get game name
let game_name = String::from_utf8_lossy(&buffer[0x0134..=0x0143]);
println!("Starting \"{}\" in {:?} Mode...", game_name, config.mode);
let header = Header::new(buffer.clone());
println!("{}", header);

assert!((header.cgb_flag != CGBFlag::CGBOnly) || (config.mode != GBMode::DMG), "Cannot run CGB only game in DMG Mode!");
// TODO: DMG-on-CGB Compat Mode
assert!((header.cgb_flag != CGBFlag::DMGOnly) || (config.mode != GBMode::CGB), "Cannot run DMG only game in CGB Mode!");

let panic = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
Expand All @@ -169,7 +173,7 @@ fn main() {
let framebuffer: Framebuffer = Arc::new(RwLock::new([0xFF; FRAMEBUFFER_SIZE]));

let mut app = App {
game_name: String::from(game_name),
header: header.clone(),
context: None,
config: config.clone(),
input_tx,
Expand All @@ -178,7 +182,7 @@ fn main() {

// Start CPU
thread::spawn(move || {
let mut cpu = CPU::new(buffer, config, framebuffer);
let mut cpu = CPU::new(buffer, header, config, framebuffer);
let mut step_cycles = 0;
let mut step_zero = Instant::now();

Expand Down
85 changes: 85 additions & 0 deletions src/mbc/header.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use std::fmt;
use std::fmt::Formatter;
use num_traits::FromPrimitive;
use crate::mbc::licensee::Licensee;
use crate::mbc::mode::CartTypes;

#[derive(Clone)]
pub struct Header {
pub cart_type: CartTypes,
pub licensee: Licensee,
pub destination: Destination,
pub rom_size: u8,
pub ram_size: u8,
pub title: String,
pub manufacturer_code: String,
pub cgb_flag: CGBFlag,
pub sgb_flag: bool,
}

impl Header {
pub fn new(buffer: Vec<u8>) -> Self {
let cart_type: CartTypes = FromPrimitive::from_u8(buffer[0x0147]).expect("Failed to get cart type!");
let licensee = match Licensee::old_licensee(buffer[0x014B]) {
Some(code) => {
code
},
None => {
let string = String::from_utf8_lossy(&buffer[0x0144..=0x0145]);
let str = string.to_owned();
let code = Licensee::new_licensee(&str);
code
}
};
let destination = FromPrimitive::from_u8(buffer[0x014A]).expect("Failed to get cart destination!");

let rom_size = buffer[0x0148];
let ram_size = buffer[0x0149];

let title = String::from_utf8_lossy(&buffer[0x0134..=0x013E]).to_string();
let manufacturer_code = String::from_utf8_lossy(&buffer[0x013F..=0x0142]).to_string();

let cgb_flag = match FromPrimitive::from_u8(buffer[0x0143]) {
Some(flag) => {
flag
},
None => {
CGBFlag::DMGOnly
}
};
let sgb_flag = buffer[0x0146] == 0x03;

Self {
cart_type,
licensee,
destination,
rom_size,
ram_size,
title,
manufacturer_code,
cgb_flag,
sgb_flag
}
}
}

impl fmt::Display for Header {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
writeln!(f, "{} (Licensee: {}, Cart Type: {})", self.title, self.licensee, self.cart_type)?;
writeln!(f, "ROM: {}, RAM: {}, CGB: {:?}, SGB: {}", self.rom_size, self.ram_size, self.cgb_flag, self.sgb_flag)?;
Ok(())
}
}

#[derive(Clone, Copy, PartialEq, FromPrimitive, Debug)]
pub enum Destination {
Japan = 0x00,
Oveseas = 0x01
}

#[derive(Clone, Copy, PartialEq, FromPrimitive, Debug)]
pub enum CGBFlag {
BackwardsCompatible = 0x80,
CGBOnly = 0xC0,
DMGOnly
}
17 changes: 13 additions & 4 deletions src/mbc/licensee.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::fmt::{Display, Formatter};

#[derive(Clone)]
pub enum Licensee {
None,
Unknown,
Capcom,
ElectronicArts,
HudsonSoft,
Expand Down Expand Up @@ -134,6 +136,8 @@ pub enum Licensee {
IGS,
AWave,
ExtremeEntertainment,
MTO,
Kodansha
}

impl Licensee {
Expand Down Expand Up @@ -201,7 +205,9 @@ impl Licensee {
"99" => Licensee::PackInSoft,
"9H" => Licensee::BottomUp,
"A4" => Licensee::KonamiYuGiOh,
_ => Licensee::None,
"BL" => Licensee::MTO,
"DK" => Licensee::Kodansha,
_ => Licensee::Unknown,
}
}

Expand Down Expand Up @@ -355,7 +361,7 @@ impl Licensee {
0xF0 => Some(Licensee::AWave),
0xF3 => Some(Licensee::ExtremeEntertainment),
0xFF => Some(Licensee::LJN),
_ => Some(Licensee::None)
_ => Some(Licensee::Unknown)
}
}
}
Expand All @@ -364,6 +370,7 @@ impl Display for Licensee {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let name = match self {
Licensee::None => "None",
Licensee::Unknown => "Unknown",
Licensee::Capcom => "Capcom",
Licensee::ElectronicArts => "EA (Electronic Arts)",
Licensee::HudsonSoft => "Hudson Soft",
Expand Down Expand Up @@ -495,10 +502,12 @@ impl Display for Licensee {
Licensee::Epic => "Epic",
Licensee::IGS => "IGS",
Licensee::AWave => "A Wave",
Licensee::ExtremeEntertainment => "Extreme Entertainment"
Licensee::ExtremeEntertainment => "Extreme Entertainment",
Licensee::MTO => "MTO",
Licensee::Kodansha => "Kodansha"
};

writeln!(f, "{}", name)?;
write!(f, "{}", name)?;
Ok(())
}
}
3 changes: 2 additions & 1 deletion src/mbc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ pub mod mbc3;
pub mod mbc5;
pub mod mode;
pub mod rom_only;
mod licensee;
pub mod header;
pub mod licensee;

#[allow(unused_imports)]
pub mod prelude {
Expand Down

0 comments on commit 0a56aa9

Please sign in to comment.