use Read trait for emulating roms

This commit is contained in:
Denis-Cosmin Nutiu 2024-12-11 00:44:48 +02:00
parent 5085ea096b
commit 0fbb74b431
2 changed files with 17 additions and 25 deletions

View file

@ -5,11 +5,9 @@ use crate::instruction::{Instruction, ProcessorInstruction};
use crate::sound::SoundModule; use crate::sound::SoundModule;
use crate::stack::Stack; use crate::stack::Stack;
use anyhow::anyhow; use anyhow::anyhow;
use log::{debug, info, trace, warn}; use log::{info, trace, warn};
use rand::Rng; use rand::Rng;
use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::Path;
use std::sync::mpsc; use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender}; use std::sync::mpsc::{Receiver, Sender};
use std::thread; use std::thread;
@ -112,12 +110,12 @@ where
info!("Loaded font data into memory at 0xf0."); info!("Loaded font data into memory at 0xf0.");
} }
/// Emulates the ROM specified at `path`. /// Emulates the ROM.
pub fn emulate<T>(&mut self, path: T) -> Result<(), anyhow::Error> pub fn emulate<T>(&mut self, rom: T) -> Result<(), anyhow::Error>
where where
T: AsRef<Path> + std::fmt::Display, T: Read,
{ {
self.load_rom(path)?; self.load_rom(rom)?;
self.emulation_loop::<T>()?; self.emulation_loop::<T>()?;
Ok(()) Ok(())
} }
@ -463,22 +461,11 @@ where
} }
/// Loads the ROM found at the rom path in the emulator's RAM memory. /// 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> fn load_rom<T>(&mut self, mut rom: T) -> Result<(), anyhow::Error>
where where
T: AsRef<Path> + std::fmt::Display, T: Read,
{ {
let mut file = File::open(&rom_file)?; rom.read(&mut self.memory[0x200..])?;
// 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..])?;
// Set program counter to start of memory // Set program counter to start of memory
self.program_counter = 0x200; self.program_counter = 0x200;
@ -493,6 +480,8 @@ mod tests {
use crate::input::NoInput; use crate::input::NoInput;
use crate::sound::TerminalSound; use crate::sound::TerminalSound;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use std::fs::File;
use std::io::{Seek, SeekFrom};
#[test] #[test]
fn test_load_font_data() { fn test_load_font_data() {
@ -508,11 +497,11 @@ mod tests {
file.read(&mut rom_file_data) file.read(&mut rom_file_data)
.expect("Failed to read test ROM"); .expect("Failed to read test ROM");
let _ = file.seek(SeekFrom::Start(0));
// Test // Test
let mut emulator = Emulator::new(TerminalDisplay::new(), TerminalSound, NoInput); let mut emulator = Emulator::new(TerminalDisplay::new(), TerminalSound, NoInput);
emulator emulator.load_rom(file).expect("failed to load ROM");
.load_rom("roms/ibm-logo.ch8")
.expect("failed to load ROM");
// Assert // Assert
assert_eq!(emulator.memory[0x200..0x200 + 132], rom_file_data) assert_eq!(emulator.memory[0x200..0x200 + 132], rom_file_data)

View file

@ -4,6 +4,7 @@ use crate::input::CrossTermInput;
use crate::sound::TerminalSound; use crate::sound::TerminalSound;
use clap::Parser; use clap::Parser;
use env_logger; use env_logger;
use std::fs::File;
mod display; mod display;
mod emulator; mod emulator;
@ -27,8 +28,10 @@ fn main() -> Result<(), anyhow::Error> {
env_logger::init(); env_logger::init();
let args = CliArgs::parse(); let args = CliArgs::parse();
let file = File::open(&args.rom_path)?;
let mut emulator = Emulator::new(RatatuiDisplay::new(), TerminalSound, CrossTermInput::new()); let mut emulator = Emulator::new(RatatuiDisplay::new(), TerminalSound, CrossTermInput::new());
emulator.emulate(args.rom_path)?; emulator.emulate(file)?;
Ok(()) Ok(())
} }