Basic ROM implementation

This commit is contained in:
2022-02-03 17:14:54 -05:00
parent 2dec06c433
commit 03756da4af
3 changed files with 72 additions and 3 deletions

View File

@@ -1,4 +1,5 @@
pub mod registers;
pub mod cpu;
pub mod mmu;
pub mod rom;
pub mod rdram;

View File

@@ -1,6 +1,7 @@
use std::ops::RangeInclusive;
use crate::rdram::RDRAM;
use crate::rom::ROM;
pub const KUSEG: RangeInclusive<i64> = 0x00000000..=0x7FFFFFFF;
pub const KSEG0: RangeInclusive<i64> = 0x80000000..=0x9FFFFFFF;
@@ -37,12 +38,27 @@ pub const EXTERNAL_SYSAD_DEVICE_BUS: RangeInclusive<i64> = 0x80000000..=0xFFF
pub struct MMU {
rdram: RDRAM,
rom: ROM,
}
impl MMU {
pub fn new() -> Self {
let args: Vec<String> = std::env::args().collect();
#[cfg(not(test))]
if args.len() < 2 {
eprintln!("Please, specify a ROM file");
std::process::exit(1);
}
let rom = match ROM::load_file(&args.get(1).unwrap_or(&"".to_string())) {
Ok(rom) => rom,
Err(err) => {
eprintln!("Could not read ROM: {}", err);
std::process::exit(1);
},
};
Self {
rdram: RDRAM::new(),
rom,
}
}
@@ -91,7 +107,7 @@ impl MMU {
} else if RDRAM2.contains(&address) {
return self.rdram.read8(address);
} else if RESERVED1.contains(&address) {
return 0;
return 0xFF;
} else if RDRAM_REGISTERS.contains(&address) {
return 0;
} else if RSP_DMEM.contains(&address) {
@@ -125,9 +141,9 @@ impl MMU {
} else if CARTRIDGE_DOMAIN_1_ADDRESS_1.contains(&address) {
return 0;
} else if CARTRIDGE_DOMAIN_2_ADDRESS_2.contains(&address) {
return 0;
return self.rom.read(address);
} else if CARTRIDGE_DOMAIN_1_ADDRESS_2.contains(&address) {
return 0;
return self.rom.read(address);
} else if PIF_ROM.contains(&address) {
return 0;
} else if PIF_RAM.contains(&address) {
@@ -165,7 +181,9 @@ impl MMU {
} else if CARTRIDGE_DOMAIN_2_ADDRESS_1.contains(&address) {
} else if CARTRIDGE_DOMAIN_1_ADDRESS_1.contains(&address) {
} else if CARTRIDGE_DOMAIN_2_ADDRESS_2.contains(&address) {
self.rom.write(address, data);
} else if CARTRIDGE_DOMAIN_1_ADDRESS_2.contains(&address) {
self.rom.write(address, data);
} else if PIF_ROM.contains(&address) {
} else if PIF_RAM.contains(&address) {
} else if RESERVED2.contains(&address) {

50
src/rom.rs Normal file
View File

@@ -0,0 +1,50 @@
use std::fs::File;
use std::io::Read;
use crate::mmu::CARTRIDGE_DOMAIN_2_ADDRESS_2;
use crate::mmu::CARTRIDGE_DOMAIN_1_ADDRESS_2;
pub struct ROM {
data: Vec<u8>,
ram: Vec<u8>,
}
impl ROM {
pub fn new() -> Self {
Self {
data: Vec::new(),
ram: Vec::new(),
}
}
pub fn load_file(filename: &str) -> std::io::Result<Self> {
let mut file = File::open(filename)?;
let mut data = vec![];
file.read_to_end(&mut data)?;
Ok(Self {
data,
ram: vec![0; 0xFC00000],
})
}
pub fn read(&self, address: i64) -> u8 {
if CARTRIDGE_DOMAIN_2_ADDRESS_2.contains(&address) {
return match self.ram.get((address - CARTRIDGE_DOMAIN_2_ADDRESS_2.min().unwrap()) as usize) {
Some(byte) => *byte,
None => 0xFF,
};
} else if CARTRIDGE_DOMAIN_1_ADDRESS_2.contains(&address) {
return match self.data.get((address - CARTRIDGE_DOMAIN_1_ADDRESS_2.min().unwrap()) as usize) {
Some(byte) => *byte,
None => 0xFF,
};
}
unreachable!("Invalid ROM access");
}
pub fn write(&mut self, address: i64, data: u8) {
if let Some(elem) = self.ram.get_mut((address - CARTRIDGE_DOMAIN_2_ADDRESS_2.min().unwrap()) as usize) {
*elem = data;
}
}
}