[Args] Accept args for draw scale and new chip8 behaviour
This commit is contained in:
@@ -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<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
|
||||
}
|
@@ -17,7 +17,7 @@ pub struct Device {
|
||||
pub timer: Timer,
|
||||
pub stack: Vec<u16>,
|
||||
pub frame_buffer: Arc<Mutex<Box<[bool; 64 * 32]>>>,
|
||||
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<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();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
10
src/main.rs
10
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<Mutex<Box<[bool; 2048]>>>, receiver: Receiver<()>, device_keyboard: Keyboard, rom_file_location_option: Option<String>) {
|
||||
let mut device = Device::new(timer, frame_buffer, device_keyboard);
|
||||
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, new_chip_behaviour);
|
||||
device.set_default_font();
|
||||
|
||||
if let Some(rom_file_location) = rom_file_location_option {
|
||||
|
Reference in New Issue
Block a user