Skip to content

Commit

Permalink
cartridge-refactor (#10)
Browse files Browse the repository at this point in the history
* refactor

* update dir structure
  • Loading branch information
JakubG-git authored Dec 7, 2024
1 parent daaed26 commit 287b991
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 123 deletions.
109 changes: 0 additions & 109 deletions emulator/src/cartridge.rs

This file was deleted.

103 changes: 103 additions & 0 deletions emulator/src/cartridge/cartridge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use crate::cartridge::common::consts::NES_FILE_MAGIC_BYTES;
use crate::cartridge::common::enums::Nes;
use crate::cartridge::file_loader::{FileLoadable, NesRomReadError};
use crate::cartridge::formats::i_nes::Ines;
use crate::cartridge::formats::nes_2::Nes2;
use crate::cartridge::registers::chr_rom::ChrRom;
use crate::cartridge::registers::prg_rom::PrgRom;
use byteorder::ReadBytesExt;
use std::fs::File;
use std::io::{BufReader, Read, Seek, SeekFrom};
use std::path::Path;

pub trait CartridgeData {
fn prg_rom(&self) -> &PrgRom;
fn chr_rom(&self) -> &ChrRom;
}

pub struct Cartridge {
data: Box<dyn CartridgeData>,
}

impl Cartridge {
// prepare cartridge with FileLoadable trait

pub fn from_file<P: AsRef<Path>>(path: P) -> anyhow::Result<Cartridge> {
let mut file = BufReader::new(File::open(&path)?);
let nes_type = Cartridge::nes_type_from_file(&mut file)?;
// reset file pointer
file.seek(SeekFrom::Start(0))?;
match nes_type {
Nes::Ines => {
let ines = Ines::from_file(path)?;
Ok(Cartridge {
data: Box::new(ines),
})
}
Nes::Nes2 => {
let nes2 = Nes2::from_file(path)?;
Ok(Cartridge {
data: Box::new(nes2),
})
}
}
}

fn nes_type_from_file<R: Read + Seek>(file: &mut R) -> anyhow::Result<Nes> {
let mut header = [0; 16];
file.read_exact(&mut header)?;
// Is it a NES file?
if header[0..4] != NES_FILE_MAGIC_BYTES {
return Err(NesRomReadError::MissingMagicBytes.into());
}
// NES 2.0
if (header[7] & 0x0C) == 0x08 {
// reset file pointer
file.seek(SeekFrom::Start(0))?;
return Ok(Nes::Nes2);
}
Ok(Nes::Ines)
}
}

impl CartridgeData for Cartridge {
fn prg_rom(&self) -> &PrgRom {
self.data.prg_rom()
}

fn chr_rom(&self) -> &ChrRom {
self.data.chr_rom()
}
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_file() {
// Super Mario Bros
// check if the file is in the resources folder
let is_file = std::path::Path::new("resources/smb.nes").exists();
// issue a warning if the file is not found
if !is_file {
println!("resources/smb.nes not found");
return;
}
let cartridge = Cartridge::from_file("resources/smb.nes");
assert!(cartridge.is_ok());
let cartridge = cartridge.unwrap();

let prg_rom = cartridge.prg_rom();

let chr_rom = cartridge.chr_rom();

assert_eq!(
prg_rom.size(),
2 * crate::cartridge::file_loader::PRG_UNIT_SIZE as usize
);
assert_eq!(
chr_rom.size(),
1 * crate::cartridge::file_loader::CHR_UNIT_SIZE as usize
);
}
}
3 changes: 3 additions & 0 deletions emulator/src/cartridge/common/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub const NES_FILE_MAGIC_BYTES: [u8; 4] = ['N' as u8, 'E' as u8, 'S' as u8, 0x1A];
pub const PRG_UNIT_SIZE: u16 = 16;
pub const CHR_UNIT_SIZE: u16 = 8;
File renamed without changes.
2 changes: 2 additions & 0 deletions emulator/src/cartridge/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod consts;
pub mod enums;
File renamed without changes.
22 changes: 16 additions & 6 deletions emulator/src/i_nes.rs → emulator/src/cartridge/formats/i_nes.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::chr_rom::ChrRom;
use crate::enums::Mirroring;
use crate::file_loader::read_banks;
use crate::file_loader::{
use crate::cartridge::cartridge::CartridgeData;
use crate::cartridge::common::enums::Mirroring;
use crate::cartridge::file_loader::read_banks;
use crate::cartridge::file_loader::{
FileLoadable, NesRomReadError, CHR_UNIT_SIZE, NES_FILE_MAGIC_BYTES, PRG_UNIT_SIZE,
};
use crate::prg_rom::PrgRom;
use crate::cartridge::registers::chr_rom::ChrRom;
use crate::cartridge::registers::prg_rom::PrgRom;
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;
Expand Down Expand Up @@ -148,10 +149,19 @@ impl FileLoadable for Ines {
}
}

impl CartridgeData for Ines {
fn prg_rom(&self) -> &PrgRom {
&self.prg_rom
}

fn chr_rom(&self) -> &ChrRom {
self.chr_rom.as_ref().unwrap()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::i_nes::FileLoadable;
use crate::cartridge::formats::i_nes::FileLoadable;
use std::io::Cursor;

#[test]
Expand Down
2 changes: 2 additions & 0 deletions emulator/src/cartridge/formats/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod i_nes;
pub mod nes_2;
16 changes: 14 additions & 2 deletions emulator/src/nes_2.rs → emulator/src/cartridge/formats/nes_2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::file_loader::{FileLoadable, NesRomReadError, NES_FILE_MAGIC_BYTES};
use crate::cartridge::cartridge::CartridgeData;
use crate::cartridge::file_loader::{FileLoadable, NesRomReadError, NES_FILE_MAGIC_BYTES};
use crate::cartridge::registers::chr_rom::ChrRom;
use crate::cartridge::registers::prg_rom::PrgRom;
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;
Expand All @@ -8,7 +11,6 @@ struct Nes2Header {}
pub struct Nes2 {
header: Nes2Header,
}

impl Nes2 {
fn header_from_file<R: Read>(file: &mut R) -> anyhow::Result<Nes2Header> {
let mut header = [0; 16];
Expand All @@ -26,6 +28,16 @@ impl Nes2 {
}
}

impl CartridgeData for Nes2 {
fn prg_rom(&self) -> &PrgRom {
unimplemented!()
}

fn chr_rom(&self) -> &ChrRom {
unimplemented!()
}
}

impl FileLoadable for Nes2 {
fn from_file<P: AsRef<Path>>(path: P) -> anyhow::Result<Nes2> {
let mut file = BufReader::new(File::open(path)?);
Expand Down
6 changes: 6 additions & 0 deletions emulator/src/cartridge/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod cartridge;

pub mod common;
pub mod file_loader;
mod formats;
mod registers;
File renamed without changes.
2 changes: 2 additions & 0 deletions emulator/src/cartridge/registers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod chr_rom;
pub mod prg_rom;
File renamed without changes.
6 changes: 0 additions & 6 deletions emulator/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
pub mod addressing;
pub mod bus;
pub mod cartridge;
mod chr_rom;
pub mod cpu;
pub mod empty_device;
mod enums;
mod file_loader;
mod i_nes;
pub mod logging;
pub mod memory;
mod mirroring;
mod nes_2;
pub mod ppu;
mod prg_rom;

0 comments on commit 287b991

Please sign in to comment.