diff --git a/src/args.rs b/src/args.rs index 31ed9fa..0439ae0 100644 --- a/src/args.rs +++ b/src/args.rs @@ -4,5 +4,9 @@ use clap::Parser; #[command(version,about,author)] pub struct Porcel8ProgramArgs { #[arg(short,long,help = "Filename of ROM to load.")] - pub filename:Option + pub filename:Option, + #[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 } \ No newline at end of file diff --git a/src/device/device.rs b/src/device/device.rs index 3707207..5e05f67 100644 --- a/src/device/device.rs +++ b/src/device/device.rs @@ -17,7 +17,7 @@ pub struct Device { pub timer: Timer, pub stack: Vec, pub frame_buffer: Arc>>, - pub super_chip8_mode: bool, + pub new_chip8_mode: bool, pub device_keyboard: Keyboard, } @@ -26,7 +26,7 @@ impl Device { pub const FRAME_BUFFER_WIDTH: usize = 64; pub const FRAME_BUFFER_HEIGHT: usize = 32; pub const FRAME_BUFFER_SIZE: usize = Self::FRAME_BUFFER_WIDTH * Self::FRAME_BUFFER_HEIGHT; - pub fn new(timer: Timer, fb: Arc>>, device_keyboard: Keyboard) -> Device { + pub fn new(timer: Timer, fb: Arc>>, device_keyboard: Keyboard, new_chip8_mode: bool) -> Device { let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE].into_boxed_slice().try_into().unwrap(); log::trace!("Successfully initiated device memory"); Device { @@ -35,7 +35,7 @@ impl Device { frame_buffer: fb, stack: Vec::with_capacity(16), timer, - super_chip8_mode: false, + new_chip8_mode, device_keyboard, } } @@ -140,7 +140,7 @@ impl Device { } } 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; self.registers.pc = new_pc; } @@ -190,7 +190,7 @@ impl Device { self.set_flag_register(is_overflow); } Instruction::RShift(x, y) => { - if (self.super_chip8_mode) { + if (self.new_chip8_mode) { self.registers.v[x] = self.registers.v[y]; } let (shift_res, did_overflow) = self.registers.v[x].overflowing_shr(1); @@ -198,7 +198,7 @@ impl Device { self.set_flag_register(did_overflow); } Instruction::LShift(x, y) => { - if (self.super_chip8_mode) { + if (self.new_chip8_mode) { self.registers.v[x] = self.registers.v[y]; } 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 index_original = self.registers.i; // 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; self.set_flag_register(overflowing); (reg_value as u16 + index_original) % 0x1000 @@ -261,7 +261,7 @@ impl Device { let index = self.registers.i as usize; self.memory[index..=(index+last_reg_to_store)].copy_from_slice(reg_slice); // 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; } } @@ -270,7 +270,7 @@ impl Device { let mem_slice = &self.memory[index..=(index+last_reg_to_load)]; self.registers.v[0..=last_reg_to_load].copy_from_slice(mem_slice); // 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; } } diff --git a/src/main.rs b/src/main.rs index 719ab5e..6274c83 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,7 @@ mod sdl_keyboard_adapter; fn main() -> EmulatorResult<()> { 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"); 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 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(); @@ -96,8 +96,8 @@ fn main() -> EmulatorResult<()> { Ok(()) } -fn do_device_loop(mut timer: Timer, frame_buffer: Arc>>, receiver: Receiver<()>, device_keyboard: Keyboard, rom_file_location_option: Option) { - let mut device = Device::new(timer, frame_buffer, device_keyboard); +fn do_device_loop(mut timer: Timer, frame_buffer: Arc>>, receiver: Receiver<()>, device_keyboard: Keyboard, rom_file_location_option: Option, new_chip_behaviour: bool) { + let mut device = Device::new(timer, frame_buffer, device_keyboard, new_chip_behaviour); device.set_default_font(); if let Some(rom_file_location) = rom_file_location_option {