[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)]
|
#[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
|
||||||
}
|
}
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
src/main.rs
10
src/main.rs
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user