Compare commits
No commits in common. "b829f05a34213fd8e43b1847e973a3a6d7e20bfe" and "1f8fa4816820a899620bf99789ac407f10b7ba24" have entirely different histories.
b829f05a34
...
1f8fa48168
|
@ -33,24 +33,23 @@ impl Cartridge {
|
|||
}
|
||||
|
||||
fn detect_mbc(memory: &[u8]) -> Box<dyn MBCIo> {
|
||||
let ram_size = Self::detect_ram_info(memory);
|
||||
let rom_size = Self::detect_rom_info(memory);
|
||||
let ram_info = Self::detect_ram_info(memory);
|
||||
let rom_info = Self::detect_rom_info(memory);
|
||||
let mbc_kind = Self::find_mbc(memory);
|
||||
let ram_cap = ram_size.capacity();
|
||||
let rom_cap = rom_size.capacity();
|
||||
let ram_size = ram_info.size();
|
||||
|
||||
eprintln!("Cartridge Ram Size: {} bytes", ram_cap);
|
||||
eprintln!("Cartridge ROM Size: {} bytes", rom_size.capacity());
|
||||
eprintln!("Cartridge Ram Size: {} bytes", ram_size);
|
||||
eprintln!("Cartridge ROM Size: {} bytes", rom_info.size());
|
||||
eprintln!("MBC Type: {:?}", mbc_kind);
|
||||
|
||||
match mbc_kind {
|
||||
MBCKind::None => Box::new(NoMBC),
|
||||
MBCKind::MBC1 => Box::new(MBC1::new(ram_size, rom_size)),
|
||||
MBCKind::MBC1WithBattery => Box::new(MBC1::new(ram_size, rom_size)), // TODO: Implement Saving
|
||||
MBCKind::MBC3 => Box::new(MBC3::new(ram_cap)),
|
||||
MBCKind::MBC3WithBattery => Box::new(MBC3::new(ram_cap)), // TODO: Implement Saving
|
||||
MBCKind::MBC5 => Box::new(MBC5::new(ram_cap, rom_cap)),
|
||||
MBCKind::MBC5WithBattery => Box::new(MBC5::new(ram_cap, rom_cap)), // TDO: Implement Saving
|
||||
MBCKind::MBC1 => Box::new(MBC1::new(ram_info, rom_info)),
|
||||
MBCKind::MBC1WithBattery => Box::new(MBC1::new(ram_info, rom_info)), // TODO: Implement Saving
|
||||
MBCKind::MBC3 => Box::new(MBC3::new(ram_size)),
|
||||
MBCKind::MBC3WithBattery => Box::new(MBC3::new(ram_size)), // TODO: Implement Saving
|
||||
MBCKind::MBC5 => Box::new(MBC5::new(ram_size)),
|
||||
MBCKind::MBC5WithBattery => Box::new(MBC5::new(ram_size)), // TDO: Implement Saving
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,12 +68,12 @@ impl Cartridge {
|
|||
self.title.as_deref()
|
||||
}
|
||||
|
||||
fn detect_ram_info(memory: &[u8]) -> RamSize {
|
||||
fn detect_ram_info(memory: &[u8]) -> RamInfo {
|
||||
let id = memory[RAM_SIZE_ADDRESS];
|
||||
id.into()
|
||||
}
|
||||
|
||||
fn detect_rom_info(memory: &[u8]) -> RomSize {
|
||||
fn detect_rom_info(memory: &[u8]) -> RomInfo {
|
||||
let id = dbg!(memory[ROM_SIZE_ADDRESS]);
|
||||
id.into()
|
||||
}
|
||||
|
@ -115,17 +114,17 @@ struct MBC1 {
|
|||
/// 2-bit number
|
||||
ram_bank: u8,
|
||||
mode: bool,
|
||||
ram_size: RamSize,
|
||||
ram_size: RamInfo,
|
||||
memory: Vec<u8>,
|
||||
rom_size: RomSize,
|
||||
rom_size: RomInfo,
|
||||
mem_enabled: bool,
|
||||
}
|
||||
|
||||
impl MBC1 {
|
||||
fn new(ram_size: RamSize, rom_size: RomSize) -> Self {
|
||||
fn new(ram_size: RamInfo, rom_size: RomInfo) -> Self {
|
||||
Self {
|
||||
rom_bank: 0x01,
|
||||
memory: vec![0; ram_size.capacity() as usize],
|
||||
memory: vec![0; ram_size.size() as usize],
|
||||
ram_size,
|
||||
rom_size,
|
||||
ram_bank: Default::default(),
|
||||
|
@ -135,7 +134,7 @@ impl MBC1 {
|
|||
}
|
||||
|
||||
fn zero_bank(&self) -> u8 {
|
||||
use RomSize::*;
|
||||
use RomInfo::*;
|
||||
|
||||
match self.rom_size {
|
||||
None | Four | Eight | Sixteen | ThirtyTwo => 0x00,
|
||||
|
@ -146,7 +145,7 @@ impl MBC1 {
|
|||
}
|
||||
|
||||
fn _mbcm_zero_bank(&self) -> u8 {
|
||||
use RomSize::*;
|
||||
use RomInfo::*;
|
||||
|
||||
match self.rom_size {
|
||||
None | Four | Eight | Sixteen | ThirtyTwo => 0x00,
|
||||
|
@ -157,7 +156,7 @@ impl MBC1 {
|
|||
}
|
||||
|
||||
fn high_bank(&self) -> u8 {
|
||||
use RomSize::*;
|
||||
use RomInfo::*;
|
||||
|
||||
let base = self.rom_bank & self.rom_size_mask();
|
||||
|
||||
|
@ -170,7 +169,7 @@ impl MBC1 {
|
|||
}
|
||||
|
||||
fn rom_size_mask(&self) -> u8 {
|
||||
use RomSize::*;
|
||||
use RomInfo::*;
|
||||
|
||||
match self.rom_size {
|
||||
None => 0b00000001,
|
||||
|
@ -183,10 +182,10 @@ impl MBC1 {
|
|||
}
|
||||
|
||||
fn ram_addr(&self, addr: u16) -> u16 {
|
||||
use RamSize::*;
|
||||
use RamInfo::*;
|
||||
|
||||
match self.ram_size {
|
||||
Unused | One => (addr - 0xA000) % self.ram_size.capacity() as u16,
|
||||
Unused | One => (addr - 0xA000) % self.ram_size.size() as u16,
|
||||
Four => {
|
||||
if self.mode {
|
||||
0x2000 * self.ram_bank as u16 + (addr - 0xA000)
|
||||
|
@ -271,9 +270,9 @@ struct MBC3 {
|
|||
}
|
||||
|
||||
impl MBC3 {
|
||||
fn new(ram_cap: usize) -> Self {
|
||||
fn new(ram_size: usize) -> Self {
|
||||
Self {
|
||||
memory: vec![0; ram_cap],
|
||||
memory: vec![0; ram_size],
|
||||
rom_bank: Default::default(),
|
||||
ram_bank: Default::default(),
|
||||
devs_enabled: Default::default(),
|
||||
|
@ -353,26 +352,19 @@ struct MBC5 {
|
|||
/// 4-bit number
|
||||
ram_bank: u8,
|
||||
|
||||
rom_cap: usize,
|
||||
|
||||
memory: Vec<u8>,
|
||||
mem_enabled: bool,
|
||||
}
|
||||
|
||||
impl MBC5 {
|
||||
fn new(ram_cap: usize, rom_cap: usize) -> Self {
|
||||
fn new(ram_size: usize) -> Self {
|
||||
Self {
|
||||
rom_bank: 0x01,
|
||||
memory: vec![0; ram_cap],
|
||||
rom_cap,
|
||||
memory: vec![0; ram_size],
|
||||
ram_bank: Default::default(),
|
||||
mem_enabled: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn bank_addr(&self, addr: u16) -> usize {
|
||||
(0x4000 * self.rom_bank as usize + (addr as usize - 0x4000)) % self.rom_cap
|
||||
}
|
||||
}
|
||||
|
||||
impl MBCIo for MBC5 {
|
||||
|
@ -381,7 +373,9 @@ impl MBCIo for MBC5 {
|
|||
|
||||
match addr {
|
||||
0x0000..=0x3FFF => Address(addr as usize),
|
||||
0x4000..=0x7FFF => Address(self.bank_addr(addr)),
|
||||
0x4000..=0x7FFF => {
|
||||
Address(0x4000u16.wrapping_mul(self.rom_bank) as usize + (addr as usize - 0x4000))
|
||||
}
|
||||
0xA000..=0xBFFF if self.mem_enabled => {
|
||||
Value(self.memory[0x2000 * self.ram_bank as usize + (addr as usize - 0xA000)])
|
||||
}
|
||||
|
@ -447,7 +441,7 @@ impl Default for MBCKind {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum RamSize {
|
||||
enum RamInfo {
|
||||
None = 0x00,
|
||||
Unused = 0x01,
|
||||
One = 0x02,
|
||||
|
@ -456,9 +450,9 @@ enum RamSize {
|
|||
Eight = 0x05,
|
||||
}
|
||||
|
||||
impl RamSize {
|
||||
fn capacity(&self) -> usize {
|
||||
use RamSize::*;
|
||||
impl RamInfo {
|
||||
fn size(&self) -> usize {
|
||||
use RamInfo::*;
|
||||
|
||||
match *self {
|
||||
None => 0,
|
||||
|
@ -471,15 +465,15 @@ impl RamSize {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for RamSize {
|
||||
impl Default for RamInfo {
|
||||
fn default() -> Self {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for RamSize {
|
||||
impl From<u8> for RamInfo {
|
||||
fn from(byte: u8) -> Self {
|
||||
use RamSize::*;
|
||||
use RamInfo::*;
|
||||
|
||||
match byte {
|
||||
0x00 => None,
|
||||
|
@ -494,7 +488,7 @@ impl From<u8> for RamSize {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum RomSize {
|
||||
enum RomInfo {
|
||||
None = 0x00, // 32KB (also called Two)
|
||||
Four = 0x01, // 64KB
|
||||
Eight = 0x02, // 128KB
|
||||
|
@ -509,10 +503,10 @@ enum RomSize {
|
|||
NinetySix = 0x54, // 1.5MB
|
||||
}
|
||||
|
||||
impl RomSize {
|
||||
impl RomInfo {
|
||||
// https://hacktix.github.io/GBEDG/mbcs/#rom-size
|
||||
fn capacity(&self) -> usize {
|
||||
use RomSize::*;
|
||||
fn size(&self) -> u32 {
|
||||
use RomInfo::*;
|
||||
|
||||
match self {
|
||||
SeventyTwo => 0x120000,
|
||||
|
@ -523,9 +517,9 @@ impl RomSize {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<u8> for RomSize {
|
||||
impl From<u8> for RomInfo {
|
||||
fn from(byte: u8) -> Self {
|
||||
use RomSize::*;
|
||||
use RomInfo::*;
|
||||
|
||||
match byte {
|
||||
0x00 => None,
|
||||
|
|
Loading…
Reference in New Issue