[Args] Accept args for draw scale and new chip8 behaviour

This commit is contained in:
2024-03-05 20:15:09 +05:30
parent 62f33d5054
commit 9761f76c61
3 changed files with 19 additions and 15 deletions

View File

@@ -4,5 +4,9 @@ use clap::Parser;
#[command(version,about,author)] #[command(version,about,author)]
pub struct Porcel8ProgramArgs { pub struct Porcel8ProgramArgs {
#[arg(short,long,help = "Filename of ROM to load.")] #[arg(short,long,help = "Filename of ROM to load.")]
pub filename:Option<String> pub filename:Option<String>,
#[arg(short,long,help = "Draw scale of window",default_value_t=8f32)]
pub draw_scale: f32,
#[arg(short,long,help = "Emulate new behaviour of instructions (As seen in Chip-48 and SuperChip8)",default_value_t=true)]
pub new_chip8_behaviour: bool
} }

View File

@@ -17,7 +17,7 @@ pub struct Device {
pub timer: Timer, pub timer: Timer,
pub stack: Vec<u16>, pub stack: Vec<u16>,
pub frame_buffer: Arc<Mutex<Box<[bool; 64 * 32]>>>, pub frame_buffer: Arc<Mutex<Box<[bool; 64 * 32]>>>,
pub super_chip8_mode: bool, pub new_chip8_mode: bool,
pub device_keyboard: Keyboard, pub device_keyboard: Keyboard,
} }
@@ -26,7 +26,7 @@ impl Device {
pub const FRAME_BUFFER_WIDTH: usize = 64; pub const FRAME_BUFFER_WIDTH: usize = 64;
pub const FRAME_BUFFER_HEIGHT: usize = 32; pub const FRAME_BUFFER_HEIGHT: usize = 32;
pub const FRAME_BUFFER_SIZE: usize = Self::FRAME_BUFFER_WIDTH * Self::FRAME_BUFFER_HEIGHT; pub const FRAME_BUFFER_SIZE: usize = Self::FRAME_BUFFER_WIDTH * Self::FRAME_BUFFER_HEIGHT;
pub fn new(timer: Timer, fb: Arc<Mutex<Box<[bool; Device::FRAME_BUFFER_SIZE]>>>, device_keyboard: Keyboard) -> Device { pub fn new(timer: Timer, fb: Arc<Mutex<Box<[bool; Device::FRAME_BUFFER_SIZE]>>>, device_keyboard: Keyboard, new_chip8_mode: bool) -> Device {
let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE].into_boxed_slice().try_into().unwrap(); let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE].into_boxed_slice().try_into().unwrap();
log::trace!("Successfully initiated device memory"); log::trace!("Successfully initiated device memory");
Device { Device {
@@ -35,7 +35,7 @@ impl Device {
frame_buffer: fb, frame_buffer: fb,
stack: Vec::with_capacity(16), stack: Vec::with_capacity(16),
timer, timer,
super_chip8_mode: false, new_chip8_mode,
device_keyboard, device_keyboard,
} }
} }
@@ -140,7 +140,7 @@ impl Device {
} }
} }
Instruction::JumpWithOffset(x, num) => { Instruction::JumpWithOffset(x, num) => {
let regnum = if self.super_chip8_mode { x } else { 0 }; let regnum = if self.new_chip8_mode { x } else { 0 };
let new_pc = self.registers.v[regnum] as u16 + num; let new_pc = self.registers.v[regnum] as u16 + num;
self.registers.pc = new_pc; self.registers.pc = new_pc;
} }
@@ -190,7 +190,7 @@ impl Device {
self.set_flag_register(is_overflow); self.set_flag_register(is_overflow);
} }
Instruction::RShift(x, y) => { Instruction::RShift(x, y) => {
if (self.super_chip8_mode) { if (self.new_chip8_mode) {
self.registers.v[x] = self.registers.v[y]; self.registers.v[x] = self.registers.v[y];
} }
let (shift_res, did_overflow) = self.registers.v[x].overflowing_shr(1); let (shift_res, did_overflow) = self.registers.v[x].overflowing_shr(1);
@@ -198,7 +198,7 @@ impl Device {
self.set_flag_register(did_overflow); self.set_flag_register(did_overflow);
} }
Instruction::LShift(x, y) => { Instruction::LShift(x, y) => {
if (self.super_chip8_mode) { if (self.new_chip8_mode) {
self.registers.v[x] = self.registers.v[y]; self.registers.v[x] = self.registers.v[y];
} }
let (shift_res, did_overflow) = self.registers.v[x].overflowing_shl(1); let (shift_res, did_overflow) = self.registers.v[x].overflowing_shl(1);
@@ -221,7 +221,7 @@ impl Device {
let reg_value = self.registers.v[x]; let reg_value = self.registers.v[x];
let index_original = self.registers.i; let index_original = self.registers.i;
// newer instruction set requires wrapping on 12 bit overflow, and setting vf // newer instruction set requires wrapping on 12 bit overflow, and setting vf
let addn_res = if (self.super_chip8_mode) { let addn_res = if (self.new_chip8_mode) {
let overflowing = (reg_value as u16 + index_original) >= 0x1000; let overflowing = (reg_value as u16 + index_original) >= 0x1000;
self.set_flag_register(overflowing); self.set_flag_register(overflowing);
(reg_value as u16 + index_original) % 0x1000 (reg_value as u16 + index_original) % 0x1000
@@ -261,7 +261,7 @@ impl Device {
let index = self.registers.i as usize; let index = self.registers.i as usize;
self.memory[index..=(index+last_reg_to_store)].copy_from_slice(reg_slice); self.memory[index..=(index+last_reg_to_store)].copy_from_slice(reg_slice);
// Old Chip8 used to use i as a incrementing index // Old Chip8 used to use i as a incrementing index
if !self.super_chip8_mode { if !self.new_chip8_mode {
self.registers.i += last_reg_to_store as u16+ 1; self.registers.i += last_reg_to_store as u16+ 1;
} }
} }
@@ -270,7 +270,7 @@ impl Device {
let mem_slice = &self.memory[index..=(index+last_reg_to_load)]; let mem_slice = &self.memory[index..=(index+last_reg_to_load)];
self.registers.v[0..=last_reg_to_load].copy_from_slice(mem_slice); self.registers.v[0..=last_reg_to_load].copy_from_slice(mem_slice);
// Old Chip8 used to use i as a incrementing index // Old Chip8 used to use i as a incrementing index
if !self.super_chip8_mode { if !self.new_chip8_mode {
self.registers.i += last_reg_to_load as u16 + 1; self.registers.i += last_reg_to_load as u16 + 1;
} }
} }

View File

@@ -33,7 +33,7 @@ mod sdl_keyboard_adapter;
fn main() -> EmulatorResult<()> { fn main() -> EmulatorResult<()> {
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap(); SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap();
let Porcel8ProgramArgs { filename } = Porcel8ProgramArgs::parse(); let Porcel8ProgramArgs { filename, new_chip8_behaviour: new_chip_behaviour,draw_scale } = Porcel8ProgramArgs::parse();
log::info!("Started emulator"); log::info!("Started emulator");
let mut timer = Timer::new(); let mut timer = Timer::new();
@@ -46,10 +46,10 @@ fn main() -> EmulatorResult<()> {
let (termination_signal_sender, termination_signal_sender_receiver) = std::sync::mpsc::channel(); let (termination_signal_sender, termination_signal_sender_receiver) = std::sync::mpsc::channel();
let compute_handle = thread::Builder::new().name("Compute".to_string()).spawn(move || { let compute_handle = thread::Builder::new().name("Compute".to_string()).spawn(move || {
do_device_loop(timer, frame_buffer_for_device, termination_signal_sender_receiver, device_keyboard, filename); do_device_loop(timer, frame_buffer_for_device, termination_signal_sender_receiver, device_keyboard, filename, new_chip_behaviour);
})?; })?;
let (mut canvas, mut event_pump) = try_initiate_sdl(8f32)?; let (mut canvas, mut event_pump) = try_initiate_sdl(draw_scale)?;
let mut sdl_graphics_adapter = SdlGraphicsAdapter::new(); let mut sdl_graphics_adapter = SdlGraphicsAdapter::new();
@@ -96,8 +96,8 @@ fn main() -> EmulatorResult<()> {
Ok(()) Ok(())
} }
fn do_device_loop(mut timer: Timer, frame_buffer: Arc<Mutex<Box<[bool; 2048]>>>, receiver: Receiver<()>, device_keyboard: Keyboard, rom_file_location_option: Option<String>) { fn do_device_loop(mut timer: Timer, frame_buffer: Arc<Mutex<Box<[bool; 2048]>>>, receiver: Receiver<()>, device_keyboard: Keyboard, rom_file_location_option: Option<String>, new_chip_behaviour: bool) {
let mut device = Device::new(timer, frame_buffer, device_keyboard); let mut device = Device::new(timer, frame_buffer, device_keyboard, new_chip_behaviour);
device.set_default_font(); device.set_default_font();
if let Some(rom_file_location) = rom_file_location_option { if let Some(rom_file_location) = rom_file_location_option {