implement rom loading
This commit is contained in:
parent
7ff993b15a
commit
811b4fa788
5 changed files with 69 additions and 10 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -6,6 +6,7 @@ version = 3
|
||||||
name = "Chip8Emulator"
|
name = "Chip8Emulator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
@ -68,6 +69,12 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
|
|
|
@ -6,3 +6,4 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
env_logger = "0.11.5"
|
env_logger = "0.11.5"
|
||||||
|
anyhow = "1.0.93"
|
BIN
roms/ibm-logo.ch8
Normal file
BIN
roms/ibm-logo.ch8
Normal file
Binary file not shown.
|
@ -1,17 +1,31 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
const MEMORY_SIZE: usize = 4096;
|
||||||
|
const NUMBER_OF_REGISTERS: usize = 16;
|
||||||
|
|
||||||
|
/// Emulator emulates the Chip8 CPU.
|
||||||
pub struct Emulator {
|
pub struct Emulator {
|
||||||
memory: [u8; 4096]
|
memory: [u8; MEMORY_SIZE],
|
||||||
|
registers: [u16; NUMBER_OF_REGISTERS],
|
||||||
|
program_counter: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Emulator {
|
impl Emulator {
|
||||||
|
/// Creates a new `Emulator` instance.
|
||||||
|
///
|
||||||
pub fn new() -> Emulator {
|
pub fn new() -> Emulator {
|
||||||
let mut emulator = Emulator {
|
let mut emulator = Emulator {
|
||||||
memory: [0; 4096],
|
memory: [0; 4096],
|
||||||
|
registers: [0; 16],
|
||||||
|
program_counter: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
emulator.load_font_data();
|
emulator.load_font_data();
|
||||||
|
|
||||||
emulator
|
emulator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,12 +47,45 @@ impl Emulator {
|
||||||
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
|
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
|
||||||
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
|
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
|
||||||
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
||||||
0xF0, 0x80, 0xF0, 0x80, 0x80 // F
|
0xF0, 0x80, 0xF0, 0x80, 0x80, // F
|
||||||
];
|
];
|
||||||
FONT_SPRITES.iter().enumerate().for_each(|i| {
|
FONT_SPRITES
|
||||||
self.memory[0xf0 + i.0] = *i.1
|
.iter()
|
||||||
});
|
.enumerate()
|
||||||
|
.for_each(|i| self.memory[0xf0 + i.0] = *i.1);
|
||||||
info!("Loaded font data...");
|
info!("Loaded font data...");
|
||||||
debug!("Memory:\n{}\n", format!("{:?}", self.memory))
|
debug!("Memory:\n{}\n", format!("{:?}", self.memory))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// Emulates the ROM specified at `path`.
|
||||||
|
pub fn emulate<T>(&mut self, path: T) -> Result<(), anyhow::Error>
|
||||||
|
where
|
||||||
|
T: AsRef<Path> + std::fmt::Display,
|
||||||
|
{
|
||||||
|
self.load_rom(path)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Loads the ROM found at the rom path in the emulator's RAM memory.
|
||||||
|
fn load_rom<T>(&mut self, rom_file: T) -> Result<(), anyhow::Error>
|
||||||
|
where
|
||||||
|
T: AsRef<Path> + std::fmt::Display,
|
||||||
|
{
|
||||||
|
let mut file = File::open(&rom_file)?;
|
||||||
|
|
||||||
|
// Check ROM length if it overflows max RAM size.
|
||||||
|
let rom_size = file.metadata()?.len();
|
||||||
|
debug!("Open ROM {} of size {} bytes.", &rom_file, rom_size);
|
||||||
|
if rom_size > MEMORY_SIZE as u64 - 0x200 {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"ROM at {} overflows emulator's RAM size of 4kB.",
|
||||||
|
&rom_file
|
||||||
|
));
|
||||||
|
}
|
||||||
|
file.read(&mut self.memory[0x200..])?;
|
||||||
|
|
||||||
|
debug!("Memory:\n{}\n", format!("{:?}", self.memory));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,12 @@ use env_logger;
|
||||||
|
|
||||||
mod emulator;
|
mod emulator;
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<(), anyhow::Error> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let emulator = Emulator::new();
|
let mut emulator = Emulator::new();
|
||||||
|
|
||||||
|
emulator.emulate(String::from("./roms/ibm-logo.ch8"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue