more passing tests. almost have coverage of instructions back
This commit is contained in:
parent
d8b14fa084
commit
13ceb61c97
File diff suppressed because one or more lines are too long
@ -111,7 +111,8 @@ impl Chip8ComputerManager {
|
|||||||
self.computer.num_cycles
|
self.computer.num_cycles
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_bytes_to_system_memory(&mut self, bytes_to_load: Vec<u8>) {
|
pub fn load_new_program_to_system_memory(&mut self, bytes_to_load: Vec<u8>) {
|
||||||
|
self.reset();
|
||||||
self.computer.load_bytes_to_memory(0x200, &bytes_to_load);
|
self.computer.load_bytes_to_memory(0x200, &bytes_to_load);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -170,6 +170,7 @@ pub enum Chip8CpuInstructions {
|
|||||||
///
|
///
|
||||||
/// Checks the keyboard, and if the key corresponding to the value of Vx is currently in
|
/// Checks the keyboard, and if the key corresponding to the value of Vx is currently in
|
||||||
/// the up position, PC is increased by 2.
|
/// the up position, PC is increased by 2.
|
||||||
|
/// On XO Chip, Skips 2 more bytes when the instruction is 4 bytes long
|
||||||
SKNP(u8),
|
SKNP(u8),
|
||||||
/// Fx07
|
/// Fx07
|
||||||
/// The value of DT is placed into Vx.
|
/// The value of DT is placed into Vx.
|
||||||
@ -221,6 +222,7 @@ pub enum Chip8CpuInstructions {
|
|||||||
/// V0 through Vx.
|
/// V0 through Vx.
|
||||||
LDRI(u8),
|
LDRI(u8),
|
||||||
XXXXERRORINSTRUCTION,
|
XXXXERRORINSTRUCTION,
|
||||||
|
// 00Dn - CHIP8 - SCHIP * XOCHIP
|
||||||
/* START OF SCHIP-8 */
|
/* START OF SCHIP-8 */
|
||||||
/// 00CN - CHIP8 * SCHIP * XOCHIP
|
/// 00CN - CHIP8 * SCHIP * XOCHIP
|
||||||
///
|
///
|
||||||
@ -261,7 +263,12 @@ pub enum Chip8CpuInstructions {
|
|||||||
/// 0xBxNN
|
/// 0xBxNN
|
||||||
///
|
///
|
||||||
/// Jump to Address XNN+Vx
|
/// Jump to Address XNN+Vx
|
||||||
JPX(u8, u16)
|
JPX(u8, u16),
|
||||||
|
/// 0x00Cn
|
||||||
|
///
|
||||||
|
/// scroll screen content down N pixel, in XO-CHIP only selected bit
|
||||||
|
/// planes are scrolled (Quirks are HP48 specific)
|
||||||
|
SCU(u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chip8CpuInstructions {
|
impl Chip8CpuInstructions {
|
||||||
@ -313,6 +320,7 @@ impl Chip8CpuInstructions {
|
|||||||
Chip8CpuInstructions::ORY(_, _) => INST_ORY,
|
Chip8CpuInstructions::ORY(_, _) => INST_ORY,
|
||||||
JPX(_, _) => INST_JPX,
|
JPX(_, _) => INST_JPX,
|
||||||
XXXXERRORINSTRUCTION => "XX ERROR XX",
|
XXXXERRORINSTRUCTION => "XX ERROR XX",
|
||||||
|
SCU(_) => INST_SCU
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,6 +363,7 @@ impl Chip8CpuInstructions {
|
|||||||
format!("0x{x:02x}, 0x{y:02x}, 0x{nibble:02x}")
|
format!("0x{x:02x}, 0x{y:02x}, 0x{nibble:02x}")
|
||||||
}
|
}
|
||||||
// Registers. 0-F
|
// Registers. 0-F
|
||||||
|
Chip8CpuInstructions::SCU(x) |
|
||||||
Chip8CpuInstructions::LDD(x) |
|
Chip8CpuInstructions::LDD(x) |
|
||||||
Chip8CpuInstructions::LDIS(x) |
|
Chip8CpuInstructions::LDIS(x) |
|
||||||
Chip8CpuInstructions::ADDI(x) |
|
Chip8CpuInstructions::ADDI(x) |
|
||||||
@ -597,7 +606,8 @@ impl Chip8CpuInstructions {
|
|||||||
Chip8CpuInstructions::LDF2(x_register) => 0xF030 | ((*x_register as u16) << 8),
|
Chip8CpuInstructions::LDF2(x_register) => 0xF030 | ((*x_register as u16) << 8),
|
||||||
Chip8CpuInstructions::STR(x_register) => 0xF075 | ((*x_register as u16) << 8),
|
Chip8CpuInstructions::STR(x_register) => 0xF075 | ((*x_register as u16) << 8),
|
||||||
Chip8CpuInstructions::LIDR(x_register) => 0xF085 | ((*x_register as u16) << 8),
|
Chip8CpuInstructions::LIDR(x_register) => 0xF085 | ((*x_register as u16) << 8),
|
||||||
XXXXERRORINSTRUCTION => 0xFFFF
|
XXXXERRORINSTRUCTION => 0xFFFF,
|
||||||
|
SCU(x_register) => 0x00D0 | (*x_register as u16),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn decode(input: u16, quirk_mode: &QuirkMode) -> Chip8CpuInstructions {
|
pub fn decode(input: u16, quirk_mode: &QuirkMode) -> Chip8CpuInstructions {
|
||||||
@ -1124,19 +1134,18 @@ impl Chip8CpuInstructions {
|
|||||||
Chip8CpuInstructions::SCD(x) => {
|
Chip8CpuInstructions::SCD(x) => {
|
||||||
match input.quirk_mode {
|
match input.quirk_mode {
|
||||||
QuirkMode::Chip8 => {
|
QuirkMode::Chip8 => {
|
||||||
panic!("Attempt to execute SCD in Chip8 Mode");
|
debug!("Attempt to execute SCD in Chip8 Mode");
|
||||||
}
|
}
|
||||||
QuirkMode::XOChip |
|
QuirkMode::XOChip |
|
||||||
QuirkMode::SChipModern => {
|
QuirkMode::SChipModern => {
|
||||||
input.video_memory.scroll_down(*x as i32);
|
input.video_memory.scroll_down(*x as i32);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::SCR => {
|
Chip8CpuInstructions::SCR => {
|
||||||
match input.quirk_mode {
|
match input.quirk_mode {
|
||||||
QuirkMode::Chip8 => {
|
QuirkMode::Chip8 => {
|
||||||
// panic!("Attempt to execute SCR in Chip8 Mode");
|
debug!("Attempt to execute SCR in Chip8 Mode");
|
||||||
}
|
}
|
||||||
QuirkMode::XOChip |
|
QuirkMode::XOChip |
|
||||||
QuirkMode::SChipModern => {
|
QuirkMode::SChipModern => {
|
||||||
@ -1145,27 +1154,97 @@ impl Chip8CpuInstructions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::SCL => {
|
Chip8CpuInstructions::SCL => {
|
||||||
input.video_memory.scroll_left();
|
match input.quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
debug!("Attempt to execute SCL in Chip8 Mode");
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip |
|
||||||
|
QuirkMode::SChipModern => {
|
||||||
|
input.video_memory.scroll_left();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::LOW => {
|
Chip8CpuInstructions::LOW => {
|
||||||
input.video_memory.set_lowres();
|
match input.quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
debug!("ATTEMPT TO SET LOWRES IN CHIP8MODE");
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip | QuirkMode::SChipModern => {
|
||||||
|
input.video_memory.set_lowres();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::HIGH => {
|
Chip8CpuInstructions::HIGH => {
|
||||||
input.video_memory.set_highres();
|
match input.quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
debug!("ATTEMPT TO SET HIGHRES IN CHIP8MODE");
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip | QuirkMode::SChipModern => {
|
||||||
|
input.video_memory.set_highres();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::EXIT => {
|
Chip8CpuInstructions::EXIT => {
|
||||||
println!("EXIT INTERPRETER");
|
match input.quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
debug!("ATTEMPT TO EXIT FROM CHIP8 INTERPRETER");
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip |
|
||||||
|
QuirkMode::SChipModern => {
|
||||||
|
println!("EXIT INTERPRETER");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::LDF2(x) => {
|
Chip8CpuInstructions::LDF2(x) => {
|
||||||
println!("POINTING TO FONT AT {x:02x}");
|
match input.quirk_mode {
|
||||||
// base = 0x100 + 0x0A*X
|
QuirkMode::Chip8 => {
|
||||||
input.registers.poke_i(0x100 + (0xA * x) as u16);
|
debug!("ATTEMPT TO LDF2 IN CHIP8MODE");
|
||||||
|
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip | QuirkMode::SChipModern => {
|
||||||
|
println!("POINTING TO FONT AT {x:02x}");
|
||||||
|
// base = 0x100 + 0x0A*X
|
||||||
|
input.registers.poke_i(0x100 + (0xA * x) as u16);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::STR(x) => {
|
Chip8CpuInstructions::STR(x) => {
|
||||||
println!("STORING FROM RPL FOR {x}");
|
match input.quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
debug!("ATTEMPT TO STORE RPL IN CHIP8MODE");
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip |
|
||||||
|
QuirkMode::SChipModern => {
|
||||||
|
println!("STORING FROM RPL FOR {x}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::LIDR(x) => {
|
Chip8CpuInstructions::LIDR(x) => {
|
||||||
println!("LOADING FROM RPL FOR {x}");
|
match input.quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
debug!("ATTEMPT TO LOAD RPL IN CHIP8MODE");
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip |
|
||||||
|
QuirkMode::SChipModern => {
|
||||||
|
println!("LOADING FROM RPL FOR {x}");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SCU(x) => {
|
||||||
|
println!("SCROLL SCREEN UP {x} ROWS");
|
||||||
|
match input.quirk_mode {
|
||||||
|
QuirkMode::Chip8 |
|
||||||
|
QuirkMode::SChipModern => {
|
||||||
|
debug!("Attempt to run SCU outside XO mode");
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip => {
|
||||||
|
input.video_memory.scroll_up(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let cycle_time = Instant::now().duration_since(start_time).as_nanos();
|
let cycle_time = Instant::now().duration_since(start_time).as_nanos();
|
||||||
|
|||||||
@ -15,6 +15,12 @@ pub struct Chip8Video {
|
|||||||
current_res: Chip8VideoModes,
|
current_res: Chip8VideoModes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Chip8Video {
|
||||||
|
pub fn scroll_up(&self, how_far: &u8) {
|
||||||
|
println!("Scrolling up {how_far} rows.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Chip8Video {
|
impl Chip8Video {
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.cls();
|
self.cls();
|
||||||
@ -143,17 +149,23 @@ impl Chip8Video {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_right(&mut self) {
|
pub fn scroll_right(&mut self) {
|
||||||
|
println!("SCROLLRIGHTPRE:::[{}]", self.format_as_string());
|
||||||
let (width, height) = self.get_resolution();
|
let (width, height) = self.get_resolution();
|
||||||
|
|
||||||
for current_row in 0..height {
|
for current_row in 0..height {
|
||||||
let row_offset: usize = (current_row * width) as usize;
|
let row_offset: usize = (current_row * width) as usize;
|
||||||
|
|
||||||
|
// Shift pixels to the right by 4 in the current row
|
||||||
for current_column in (0..(width - 4)).rev() {
|
for current_column in (0..(width - 4)).rev() {
|
||||||
let source_address = row_offset + current_column as usize;
|
let source_address = row_offset + current_column as usize;
|
||||||
let target_address = source_address + 4;
|
let target_address = source_address + 4;
|
||||||
self.memory[target_address] = self.memory[source_address];
|
self.memory[target_address] = self.memory[source_address];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear the first 4 pixels in the current row
|
||||||
self.memory[row_offset..row_offset + 4].fill(false);
|
self.memory[row_offset..row_offset + 4].fill(false);
|
||||||
}
|
}
|
||||||
|
println!("SCROLLRIGHTPOST:::[{}]", self.format_as_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_left(&mut self) {
|
pub fn scroll_left(&mut self) {
|
||||||
|
|||||||
@ -64,7 +64,7 @@ pub const INST_SYS: &str = "SYS";
|
|||||||
pub const INST_LOW: &str = "LOW";
|
pub const INST_LOW: &str = "LOW";
|
||||||
pub const INST_HIGH: &str = "HIGH";
|
pub const INST_HIGH: &str = "HIGH";
|
||||||
pub const INST_ORY: &str = "ORY";
|
pub const INST_ORY: &str = "ORY";
|
||||||
|
pub const INST_SCU: &str = "SCU";
|
||||||
pub const CHIP8_PROGRAM_LOAD_OFFSET: i32 = 0x200;
|
pub const CHIP8_PROGRAM_LOAD_OFFSET: i32 = 0x200;
|
||||||
pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0];
|
pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0];
|
||||||
pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70];
|
pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70];
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use gemma::chip8::computer::Chip8Computer;
|
|||||||
use gemma::chip8::delay_timer::DelayTimer;
|
use gemma::chip8::delay_timer::DelayTimer;
|
||||||
use gemma::chip8::instructions::Chip8CpuInstructions;
|
use gemma::chip8::instructions::Chip8CpuInstructions;
|
||||||
use gemma::chip8::keypad::Keypad;
|
use gemma::chip8::keypad::Keypad;
|
||||||
use gemma::chip8::quirk_modes::QuirkMode::Chip8;
|
use gemma::chip8::quirk_modes::QuirkMode::{Chip8, SChipModern, XOChip};
|
||||||
use gemma::chip8::registers::Chip8Registers;
|
use gemma::chip8::registers::Chip8Registers;
|
||||||
use gemma::chip8::sound_timer::SoundTimer;
|
use gemma::chip8::sound_timer::SoundTimer;
|
||||||
use gemma::chip8::stack::Chip8Stack;
|
use gemma::chip8::stack::Chip8Stack;
|
||||||
@ -72,54 +72,54 @@ fn encode_decode_test() {
|
|||||||
assert_eq!(Chip8CpuInstructions::LIDR(1).encode(), 0xF185);
|
assert_eq!(Chip8CpuInstructions::LIDR(1).encode(), 0xF185);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xF175), Chip8CpuInstructions::STR(1)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xF175), Chip8CpuInstructions::STR(1)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xF185), Chip8CpuInstructions::LIDR(1)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xF185), Chip8CpuInstructions::LIDR(1)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00C1u16), Chip8CpuInstructions::SDN(0x01)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00C1u16), Chip8CpuInstructions::SDN(0x01)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00FCu16), Chip8CpuInstructions::SLF));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00FCu16), Chip8CpuInstructions::SLF));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00FBu16), Chip8CpuInstructions::SRT));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00FBu16), Chip8CpuInstructions::SRT));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00FDu16), Chip8CpuInstructions::EXIT));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00FDu16), Chip8CpuInstructions::EXIT));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00FEu16), Chip8CpuInstructions::DIS));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00FEu16), Chip8CpuInstructions::DIS));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00FFu16), Chip8CpuInstructions::ENA));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00FFu16), Chip8CpuInstructions::ENA));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xF030u16), Chip8CpuInstructions::LDF2(0)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xF030u16), Chip8CpuInstructions::LDF2(0)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00E0u16), Chip8CpuInstructions::CLS));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00E0u16), Chip8CpuInstructions::CLS));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00EEu16), Chip8CpuInstructions::RET));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00EEu16), Chip8CpuInstructions::RET));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x0123), Chip8CpuInstructions::SYS(0x123)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x0123), Chip8CpuInstructions::SYS(0x123)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x0FFF), Chip8CpuInstructions::SYS(0xfff)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x0FFF), Chip8CpuInstructions::SYS(0xfff)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x1002), Chip8CpuInstructions::JPA(0x2)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x1002), Chip8CpuInstructions::JPA(0x2)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x1FF0), Chip8CpuInstructions::JPA(0xFF0)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x1FF0), Chip8CpuInstructions::JPA(0xFF0)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x2002), Chip8CpuInstructions::CALL(0x2)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x2002), Chip8CpuInstructions::CALL(0x2)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x3123), Chip8CpuInstructions::SEX(0x1, 0x23)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x3123), Chip8CpuInstructions::SEX(0x1, 0x23)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x4abc), Chip8CpuInstructions::SNEB(0xa, 0xbc)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x4abc), Chip8CpuInstructions::SNEB(0xa, 0xbc)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x5ab0), Chip8CpuInstructions::SEY(0xa, 0xb)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x5ab0), Chip8CpuInstructions::SEY(0xa, 0xb)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x6aff), Chip8CpuInstructions::LDR(0xa, 0xff)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x6aff), Chip8CpuInstructions::LDR(0xa, 0xff)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x7abc), Chip8CpuInstructions::ADD(0xa, 0xbc)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x7abc), Chip8CpuInstructions::ADD(0xa, 0xbc)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8ab0), Chip8CpuInstructions::LDR_Y(0xa, 0xb)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8ab0), Chip8CpuInstructions::LDR_Y(0xa, 0xb)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8ba1), Chip8CpuInstructions::OR(0xb, 0xa)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8ba1), Chip8CpuInstructions::OR(0xb, 0xa)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8cd2), Chip8CpuInstructions::AND(0xc, 0xd)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8cd2), Chip8CpuInstructions::AND(0xc, 0xd)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8de3), Chip8CpuInstructions::ORY(0xd, 0xe)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8de3), Chip8CpuInstructions::ORY(0xd, 0xe)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8ef4), Chip8CpuInstructions::ADDR(0xe, 0xf)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8ef4), Chip8CpuInstructions::ADDR(0xe, 0xf)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8f05), Chip8CpuInstructions::SUB(0xf, 0x0)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8f05), Chip8CpuInstructions::SUB(0xf, 0x0)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8016), Chip8CpuInstructions::SHR(0x0, 0x1)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8016), Chip8CpuInstructions::SHR(0x0, 0x1)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x8127), Chip8CpuInstructions::SUBC(0x1, 0x2)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x8127), Chip8CpuInstructions::SUBC(0x1, 0x2)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x834e), Chip8CpuInstructions::SHL(0x3, 0x4)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x834e), Chip8CpuInstructions::SHL(0x3, 0x4)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x9ab0), Chip8CpuInstructions::SNEY(0xa, 0xb)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x9ab0), Chip8CpuInstructions::SNEY(0xa, 0xb)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xa123), Chip8CpuInstructions::LDIA(0x123)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xa123), Chip8CpuInstructions::LDIA(0x123)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xb234), Chip8CpuInstructions::JPI(0x234)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xb234), Chip8CpuInstructions::JPI(0x234)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xcaca), Chip8CpuInstructions::RND(0xa, 0xca)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xcaca), Chip8CpuInstructions::RND(0xa, 0xca)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xdab4), Chip8CpuInstructions::DRW(0xa, 0xb, 0x4)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xdab4), Chip8CpuInstructions::DRW(0xa, 0xb, 0x4)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xe19e), Chip8CpuInstructions::SKP(0x1)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xe19e), Chip8CpuInstructions::SKP(0x1)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xe2a1), Chip8CpuInstructions::SKNP(0x2)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xe2a1), Chip8CpuInstructions::SKNP(0x2)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xf107), Chip8CpuInstructions::LDRD(0x1)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xf107), Chip8CpuInstructions::LDRD(0x1)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xf40a), Chip8CpuInstructions::LDRK(0x4)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xf40a), Chip8CpuInstructions::LDRK(0x4)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xf615), Chip8CpuInstructions::LDD(0x6)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xf615), Chip8CpuInstructions::LDD(0x6)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xfb18), Chip8CpuInstructions::LDIS(0xb)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xfb18), Chip8CpuInstructions::LDIS(0xb)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xfd1e), Chip8CpuInstructions::ADDI(0xd)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xfd1e), Chip8CpuInstructions::ADDI(0xd)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xfc29), Chip8CpuInstructions::LDFX(0xc)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xfc29), Chip8CpuInstructions::LDFX(0xc)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xfd33), Chip8CpuInstructions::BCD(0xd)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xfd33), Chip8CpuInstructions::BCD(0xd)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xfe55), Chip8CpuInstructions::LDIX(0xe)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xfe55), Chip8CpuInstructions::LDIX(0xe)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xf365), Chip8CpuInstructions::LDRI(0x3)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xf365), Chip8CpuInstructions::LDRI(0x3)));
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1342,38 +1342,46 @@ fn instructions_operands_tests() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn instruction_ena_dis_tests() {
|
fn instruction_ena_dis_tests() {
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
assert!(!x.video_memory.is_highres());
|
for quirk in [SChipModern, XOChip] {
|
||||||
Chip8CpuInstructions::HIGH.execute(&mut x);
|
x.quirk_mode = quirk;
|
||||||
assert!(x.video_memory.is_highres());
|
assert!(!x.video_memory.is_highres());
|
||||||
Chip8CpuInstructions::HIGH.execute(&mut x);
|
Chip8CpuInstructions::HIGH.execute(&mut x);
|
||||||
assert!(x.video_memory.is_highres());
|
assert!(x.video_memory.is_highres());
|
||||||
Chip8CpuInstructions::LOW.execute(&mut x);
|
Chip8CpuInstructions::HIGH.execute(&mut x);
|
||||||
assert!(!x.video_memory.is_highres());
|
assert!(x.video_memory.is_highres());
|
||||||
|
Chip8CpuInstructions::LOW.execute(&mut x);
|
||||||
|
assert!(!x.video_memory.is_highres());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instruction_test_scrolling_lowres() {
|
fn instruction_test_scrolling_lowres() {
|
||||||
let mut x = Chip8Computer::new();
|
for quirk in [SChipModern, XOChip] {
|
||||||
x.video_memory = build_checkerboard();
|
let mut x = Chip8Computer::new();
|
||||||
Chip8CpuInstructions::SCR.execute(&mut x);
|
x.video_memory = build_checkerboard();
|
||||||
|
x.quirk_mode = quirk.clone();
|
||||||
|
Chip8CpuInstructions::SCR.execute(&mut x);
|
||||||
|
assert_eq!(read_test_result("test_scroll_right_4.asc"), x.dump_video_to_string());
|
||||||
|
|
||||||
assert_eq!(read_test_result("test_scroll_right_4.asc"), x.dump_video_to_string());
|
x = Chip8Computer::new();
|
||||||
|
x.video_memory = build_checkerboard();
|
||||||
|
x.quirk_mode = quirk.clone();
|
||||||
|
Chip8CpuInstructions::SCL.execute(&mut x);
|
||||||
|
|
||||||
x = Chip8Computer::new();
|
assert_eq!(read_test_result("test_scroll_left_4.asc"), x.dump_video_to_string());
|
||||||
x.video_memory = build_checkerboard();
|
|
||||||
Chip8CpuInstructions::SCL.execute(&mut x);
|
|
||||||
|
|
||||||
assert_eq!(read_test_result("test_scroll_left_4.asc"), x.dump_video_to_string());
|
x = Chip8Computer::new();
|
||||||
|
x.video_memory = build_checkerboard();
|
||||||
|
x.quirk_mode = quirk.clone();
|
||||||
|
Chip8CpuInstructions::SCD(0x01).execute(&mut x);
|
||||||
|
assert_eq!(read_test_result("test_video_scroll_down_1.asc"), x.dump_video_to_string());
|
||||||
|
|
||||||
x = Chip8Computer::new();
|
x = Chip8Computer::new();
|
||||||
x.video_memory = build_checkerboard();
|
x.video_memory = build_checkerboard();
|
||||||
Chip8CpuInstructions::SCD(0x01).execute(&mut x);
|
x.quirk_mode = quirk.clone();
|
||||||
assert_eq!(read_test_result("test_video_scroll_down_1.asc"), x.dump_video_to_string());
|
Chip8CpuInstructions::SCD(0xA).execute(&mut x);
|
||||||
|
assert_eq!(read_test_result("test_video_scroll_down_10.asc"), x.dump_video_to_string());
|
||||||
x = Chip8Computer::new();
|
}
|
||||||
x.video_memory = build_checkerboard();
|
|
||||||
Chip8CpuInstructions::SCD(0xA).execute(&mut x);
|
|
||||||
assert_eq!(read_test_result("test_video_scroll_down_10.asc"), x.dump_video_to_string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1388,10 +1396,10 @@ fn computer_dump_keypad_to_string() {
|
|||||||
fn computer_dump_registers_to_string() {
|
fn computer_dump_registers_to_string() {
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
let values_to_set = [0x0b, 0xad, 0xbe, 0xef,
|
let values_to_set = [0x0b, 0xad, 0xbe, 0xef,
|
||||||
0xca, 0xb0,
|
0xca, 0xb0,
|
||||||
0x7a, 0xc0, 0xca, 0x70,
|
0x7a, 0xc0, 0xca, 0x70,
|
||||||
0xba, 0xdb, 0xed, 0x00,
|
0xba, 0xdb, 0xed, 0x00,
|
||||||
0x00, 0x00
|
0x00, 0x00
|
||||||
];
|
];
|
||||||
let expected_value = "Vx: 0x0b 0xad 0xbe 0xef 0xca 0xb0 0x7a 0xc0\n 0xca 0x70 0xba 0xdb 0xed 0x00 0x00 0x00\nI: 0x0000\tPC: 0x0200";
|
let expected_value = "Vx: 0x0b 0xad 0xbe 0xef 0xca 0xb0 0x7a 0xc0\n 0xca 0x70 0xba 0xdb 0xed 0x00 0x00 0x00\nI: 0x0000\tPC: 0x0200";
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use gemma::constants::*;
|
|||||||
struct InstructionTestQuirks {
|
struct InstructionTestQuirks {
|
||||||
chip8: Chip8CpuInstructions,
|
chip8: Chip8CpuInstructions,
|
||||||
schip: Chip8CpuInstructions,
|
schip: Chip8CpuInstructions,
|
||||||
xochip: Chip8CpuInstructions
|
xochip: Chip8CpuInstructions,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -17,7 +17,7 @@ struct InstructionTest {
|
|||||||
operands: String,
|
operands: String,
|
||||||
asm: String,
|
asm: String,
|
||||||
encoded: u16,
|
encoded: u16,
|
||||||
quirks: InstructionTestQuirks
|
quirks: InstructionTestQuirks,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -191,7 +191,6 @@ fn instructions_encode_decode_tests_with_quirks() {
|
|||||||
xochip: Chip8CpuInstructions::SEX(0x1, 0xfa)
|
xochip: Chip8CpuInstructions::SEX(0x1, 0xfa)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
InstructionTest {
|
InstructionTest {
|
||||||
name: INST_SNEB.to_string(),
|
name: INST_SNEB.to_string(),
|
||||||
instruction: Chip8CpuInstructions::SNEB(0x01, 0xab),
|
instruction: Chip8CpuInstructions::SNEB(0x01, 0xab),
|
||||||
@ -241,17 +240,343 @@ fn instructions_encode_decode_tests_with_quirks() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
InstructionTest {
|
InstructionTest {
|
||||||
name: INST_LDRK.to_string(),
|
name: INST_LDRK.to_string(),
|
||||||
instruction: Chip8CpuInstructions::LDRK(0x6),
|
instruction: Chip8CpuInstructions::LDRK(0x6),
|
||||||
operands: "0x06".to_string(),
|
operands: "0x06".to_string(),
|
||||||
asm: "LDRK 0x06".to_string(),
|
asm: "LDRK 0x06".to_string(),
|
||||||
encoded: 0xF60A,
|
encoded: 0xF60A,
|
||||||
quirks: InstructionTestQuirks {
|
quirks: InstructionTestQuirks {
|
||||||
chip8: Chip8CpuInstructions::LDRK(0x6),
|
chip8: Chip8CpuInstructions::LDRK(0x6),
|
||||||
schip: Chip8CpuInstructions::LDRK(0x6),
|
schip: Chip8CpuInstructions::LDRK(0x6),
|
||||||
xochip: Chip8CpuInstructions::LDRK(0x6),
|
xochip: Chip8CpuInstructions::LDRK(0x6),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ADDI.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::ADDI(0x02),
|
||||||
|
operands: "0x02".to_string(),
|
||||||
|
asm: "ADDI 0x02".to_string(),
|
||||||
|
encoded: 0xF21E,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: ADDI(0x02),
|
||||||
|
schip: ADDI(0x02),
|
||||||
|
xochip: ADDI(0x02),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ADD.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::ADD(0x02, 0x12),
|
||||||
|
operands: "0x02, 0x12".to_string(),
|
||||||
|
asm: "ADD 0x02, 0x12".to_string(),
|
||||||
|
encoded: 0x7212,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: ADD(0x02, 0x12),
|
||||||
|
schip: ADD(0x02, 0x12),
|
||||||
|
xochip: ADD(0x02, 0x12),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SCU.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SCU(0x04),
|
||||||
|
operands: "0x04".to_string(),
|
||||||
|
asm: "SCU 0x04".to_string(),
|
||||||
|
encoded: 0x00D4,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: XXXXERRORINSTRUCTION,
|
||||||
|
schip: XXXXERRORINSTRUCTION,
|
||||||
|
xochip: SCU(0x04)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ADDR.to_string(),
|
||||||
|
instruction: ADDR(0x01, 0x02),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "ADDR 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8124,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: ADDR(0x01, 0x02),
|
||||||
|
schip: ADDR(0x01, 0x02),
|
||||||
|
xochip: ADDR(0x01, 0x02),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_AND.to_string(),
|
||||||
|
instruction: AND(0x1, 0x2),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "AND 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8122,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: AND(0x1, 0x2),
|
||||||
|
schip: AND(0x1, 0x2),
|
||||||
|
xochip: AND(0x1, 0x2),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_JPA.to_string(),
|
||||||
|
instruction: JPA(0x345),
|
||||||
|
operands: "0x0345".to_string(),
|
||||||
|
asm: "JPA 0x0345".to_string(),
|
||||||
|
encoded: 0x1345,
|
||||||
|
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: JPA(0x345),
|
||||||
|
schip: JPA(0x345),
|
||||||
|
xochip: JPA(0x345),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_BCD.to_string(),
|
||||||
|
instruction: BCD(0xc),
|
||||||
|
operands: "0x0c".to_string(),
|
||||||
|
asm: "BCD 0x0c".to_string(),
|
||||||
|
encoded: 0xfc33,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: BCD(0xcd),
|
||||||
|
schip: BCD(0xcd),
|
||||||
|
xochip: BCD(0xcd)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDD.to_string(),
|
||||||
|
instruction: LDD(0xfc),
|
||||||
|
operands: "0xfc".to_string(),
|
||||||
|
asm: "LDD 0xfc".to_string(),
|
||||||
|
encoded: 0xfc15,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: LDD(0xfc),
|
||||||
|
schip: LDD(0xfc),
|
||||||
|
xochip: LDD(0xfc),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ORY.to_string(),
|
||||||
|
instruction: ORY(0x01, 0x3),
|
||||||
|
operands: "0x1, 0x3".to_string(),
|
||||||
|
asm: "ORY 0x1, 0x3".to_string(),
|
||||||
|
encoded: 0x8133,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: ORY(0x01, 0x3),
|
||||||
|
schip: ORY(0x01, 0x3),
|
||||||
|
xochip: ORY(0x01, 0x3),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SUBC.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SUBC(0x1, 0x2),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "SUBC 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8127,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: Chip8CpuInstructions::SUBC(0x1, 0x2),
|
||||||
|
schip: Chip8CpuInstructions::SUBC(0x1, 0x2),
|
||||||
|
xochip: Chip8CpuInstructions::SUBC(0x1, 0x2),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SUB.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SUB(0x1, 0x2),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "SUB 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8125,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: Chip8CpuInstructions::SUB(0x1, 0x2),
|
||||||
|
schip: Chip8CpuInstructions::SUB(0x1, 0x2),
|
||||||
|
xochip: Chip8CpuInstructions::SUB(0x1, 0x2),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_STR.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::STR(0x06),
|
||||||
|
operands: "0x06".to_string(),
|
||||||
|
asm: "STR 0x06".to_string(),
|
||||||
|
encoded: 0xf675,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: XXXXERRORINSTRUCTION,
|
||||||
|
schip: Chip8CpuInstructions::STR(0x06),
|
||||||
|
xochip: Chip8CpuInstructions::STR(0x06),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_OR.to_string(),
|
||||||
|
instruction: OR(0x01, 0x02),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "OR 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8121,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: OR(0x01, 0x02),
|
||||||
|
schip: OR(0x01, 0x02),
|
||||||
|
xochip: OR(0x01, 0x02),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SHR.to_string(),
|
||||||
|
instruction: SHR(0x04, 0x4),
|
||||||
|
operands: "0x4, 0x4".to_string(),
|
||||||
|
asm: "SHR 0x4, 0x4".to_string(),
|
||||||
|
encoded: 0x8446,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: SHR(0x04, 0x4),
|
||||||
|
schip: SHR(0x04, 0x4),
|
||||||
|
xochip: SHR(0x04, 0x4)
|
||||||
|
}
|
||||||
|
}, InstructionTest {
|
||||||
|
name: INST_SHL.to_string(),
|
||||||
|
instruction: SHL(0x04, 0x4),
|
||||||
|
operands: "0x4, 0x4".to_string(),
|
||||||
|
asm: "SHL 0x4, 0x4".to_string(),
|
||||||
|
encoded: 0x844e,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: SHL(0x04, 0x4),
|
||||||
|
schip: SHL(0x04, 0x4),
|
||||||
|
xochip: SHL(0x04, 0x4)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_RND.to_string(),
|
||||||
|
instruction: RND(0x01, 0xff),
|
||||||
|
operands: "0x01, 0xff".to_string(),
|
||||||
|
asm: "RND 0x01, 0xff".to_string(),
|
||||||
|
encoded: 0xc1ff,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: RND(0x01, 0xff),
|
||||||
|
schip: RND(0x01, 0xff),
|
||||||
|
xochip: RND(0x01, 0xff),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDRY.to_string(),
|
||||||
|
instruction: LDR_Y(0x01, 0x02),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "LDRY 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8120,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: LDR_Y(0x01, 0x02),
|
||||||
|
schip: LDR_Y(0x01, 0x02),
|
||||||
|
xochip: LDR_Y(0x01, 0x02)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDIS.to_string(),
|
||||||
|
instruction: LDIS(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LDIS 0x01".to_string(),
|
||||||
|
encoded: 0xf118,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: LDIS(0x01),
|
||||||
|
schip: LDIS(0x01),
|
||||||
|
xochip: LDIS(0x01),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LIDR.to_string(),
|
||||||
|
instruction: LIDR(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LIDR 0x01".to_string(),
|
||||||
|
encoded: 0xf185,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: XXXXERRORINSTRUCTION,
|
||||||
|
schip: LIDR(0x01),
|
||||||
|
xochip: LIDR(0x01),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDF2.to_string(),
|
||||||
|
instruction: LDF2(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LDF2 0x01".to_string(),
|
||||||
|
encoded: 0xf130,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: XXXXERRORINSTRUCTION,
|
||||||
|
schip: LDF2(0x01),
|
||||||
|
xochip: LDF2(0x01)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDF.to_string(),
|
||||||
|
instruction: LDFX(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LDF 0x01".to_string(),
|
||||||
|
encoded: 0xf129,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: LDFX(0x01),
|
||||||
|
schip: LDFX(0x01),
|
||||||
|
xochip: LDFX(0x01)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDIA.to_string(),
|
||||||
|
instruction: LDIA(0x01),
|
||||||
|
operands: "0x0001".to_string(),
|
||||||
|
asm: "LDIA 0x0001".to_string(),
|
||||||
|
encoded: 0xa001,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: LDIA(0x01),
|
||||||
|
schip: LDIA(0x01),
|
||||||
|
xochip: LDIA(0x01),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDIX.to_string(),
|
||||||
|
instruction: LDIX(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LDIX 0x01".to_string(),
|
||||||
|
encoded: 0xf155,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: LDIX(0x01),
|
||||||
|
schip: LDIX(0x01),
|
||||||
|
xochip: LDIX(0x01),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDRD.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDRD(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LDRD 0x01".to_string(),
|
||||||
|
encoded: 0xf107,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: Chip8CpuInstructions::LDRD(0x01),
|
||||||
|
schip: Chip8CpuInstructions::LDRD(0x01),
|
||||||
|
xochip: Chip8CpuInstructions::LDRD(0x01),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDRI.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDRI(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LDRI 0x01".to_string(),
|
||||||
|
encoded: 0xf165,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: Chip8CpuInstructions::LDRI(0x01),
|
||||||
|
schip: Chip8CpuInstructions::LDRI(0x01),
|
||||||
|
xochip: Chip8CpuInstructions::LDRI(0x01),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SKP.to_string(),
|
||||||
|
instruction: SKP(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "SKP 0x01".to_string(),
|
||||||
|
encoded: 0xe19e,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: SKP(0x01),
|
||||||
|
schip: SKP(0x01),
|
||||||
|
xochip: SKP(0x01),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SNEY.to_string(),
|
||||||
|
instruction: SNEY(0x01, 0x1),
|
||||||
|
operands: "0x01, 0x01".to_string(),
|
||||||
|
asm: "SNEY 0x01, 0x01".to_string(),
|
||||||
|
encoded: 0x0000,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: SNEY(0x01, 0x1),
|
||||||
|
schip: SNEY(0x01, 0x1),
|
||||||
|
xochip: SNEY(0x01, 0x1),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
for current in it {
|
for current in it {
|
||||||
|
|||||||
@ -96,7 +96,7 @@ fn main() -> eframe::Result {
|
|||||||
if ui.button(format!("Load {}", state.selected_filename)).clicked() {
|
if ui.button(format!("Load {}", state.selected_filename)).clicked() {
|
||||||
// println!("Should load the bin now");
|
// println!("Should load the bin now");
|
||||||
let read_bin = std::fs::read(PathBuf::from(format!("resources/roms/{}", state.selected_filename))).unwrap();
|
let read_bin = std::fs::read(PathBuf::from(format!("resources/roms/{}", state.selected_filename))).unwrap();
|
||||||
computer.load_bytes_to_system_memory(read_bin);
|
computer.load_new_program_to_system_memory(read_bin);
|
||||||
};
|
};
|
||||||
EGuiFileList::display_path(PathBuf::from("resources/roms"), &mut state.selected_filename, ui);
|
EGuiFileList::display_path(PathBuf::from("resources/roms"), &mut state.selected_filename, ui);
|
||||||
ctx.input(|input| {
|
ctx.input(|input| {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use gemma::constants::CHIP8_KEYBOARD;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use imgui::{Condition, ImColor32, Ui};
|
use imgui::{CollapsingHeader, Condition, ImColor32, Ui};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use gemma::chip8::computer::Chip8Computer;
|
use gemma::chip8::computer::Chip8Computer;
|
||||||
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
||||||
@ -46,44 +46,44 @@ impl GemmaImguiSupport {
|
|||||||
let cell_width = ((draw_area_size[0] as i32 / width) * 6) / 10;
|
let cell_width = ((draw_area_size[0] as i32 / width) * 6) / 10;
|
||||||
let cell_height = ((draw_area_size[1] as i32 / height) * 6) / 10;
|
let cell_height = ((draw_area_size[1] as i32 / height) * 6) / 10;
|
||||||
|
|
||||||
let origin = ui.cursor_pos();
|
let origin = ui.cursor_pos();
|
||||||
let fg = ui.get_foreground_draw_list();
|
let fg = ui.get_foreground_draw_list();
|
||||||
if system_to_control.video_memory.is_highres() {
|
if system_to_control.video_memory.is_highres() {
|
||||||
// ui.text("High Def Video here");
|
// ui.text("High Def Video here");
|
||||||
for current_row in 0..=height {
|
for current_row in 0..=height {
|
||||||
let y_offset = origin[1] as i32 + (current_row * cell_height);
|
let y_offset = origin[1] as i32 + (current_row * cell_height);
|
||||||
for current_column in 0..=width {
|
for current_column in 0..=width {
|
||||||
let x_offset = origin[0] as i32 + (current_column * cell_width);
|
let x_offset = origin[0] as i32 + (current_column * cell_width);
|
||||||
let current_origin = [x_offset as f32, y_offset as f32];
|
let current_origin = [x_offset as f32, y_offset as f32];
|
||||||
let current_limit = [(x_offset + cell_width) as f32, (y_offset + cell_height) as f32];
|
let current_limit = [(x_offset + cell_width) as f32, (y_offset + cell_height) as f32];
|
||||||
let memory_offset = (current_row * width + current_column) as u16;
|
let memory_offset = (current_row * width + current_column) as u16;
|
||||||
let to_render = system_to_control.video_memory.peek(memory_offset);
|
let to_render = system_to_control.video_memory.peek(memory_offset);
|
||||||
let color: ImColor32 = if to_render {
|
let color: ImColor32 = if to_render {
|
||||||
gui_state.on_colour
|
gui_state.on_colour
|
||||||
} else {
|
} else {
|
||||||
gui_state.off_colour
|
gui_state.off_colour
|
||||||
};
|
};
|
||||||
fg.add_rect_filled_multicolor(current_origin, current_limit, color, color, color, color);
|
fg.add_rect_filled_multicolor(current_origin, current_limit, color, color, color, color);
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for current_row in 0..height {
|
|
||||||
let y_offset = origin[1] as i32 + (current_row * cell_height);
|
|
||||||
for current_column in 0..width {
|
|
||||||
let x_offset = origin[0] as i32 + (current_column * cell_width);
|
|
||||||
let current_origin = [x_offset as f32, y_offset as f32];
|
|
||||||
let current_limit = [(x_offset + cell_width) as f32, (y_offset + cell_height) as f32];
|
|
||||||
let memory_offset = (current_row * width + current_column) as u16;
|
|
||||||
let to_render = system_to_control.video_memory.peek(memory_offset);
|
|
||||||
let color: ImColor32 = if to_render {
|
|
||||||
gui_state.on_colour
|
|
||||||
} else {
|
|
||||||
gui_state.off_colour
|
|
||||||
};
|
|
||||||
fg.add_rect_filled_multicolor(current_origin, current_limit, color, color, color, color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for current_row in 0..height {
|
||||||
|
let y_offset = origin[1] as i32 + (current_row * cell_height);
|
||||||
|
for current_column in 0..width {
|
||||||
|
let x_offset = origin[0] as i32 + (current_column * cell_width);
|
||||||
|
let current_origin = [x_offset as f32, y_offset as f32];
|
||||||
|
let current_limit = [(x_offset + cell_width) as f32, (y_offset + cell_height) as f32];
|
||||||
|
let memory_offset = (current_row * width + current_column) as u16;
|
||||||
|
let to_render = system_to_control.video_memory.peek(memory_offset);
|
||||||
|
let color: ImColor32 = if to_render {
|
||||||
|
gui_state.on_colour
|
||||||
|
} else {
|
||||||
|
gui_state.off_colour
|
||||||
|
};
|
||||||
|
fg.add_rect_filled_multicolor(current_origin, current_limit, color, color, color, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn system_controls(system_to_control: &mut Chip8ComputerManager, gui_state: &mut ImGuiUiState, ui: &Ui) {
|
pub fn system_controls(system_to_control: &mut Chip8ComputerManager, gui_state: &mut ImGuiUiState, ui: &Ui) {
|
||||||
// let mut state: Chip8Computer = system_to_control;
|
// let mut state: Chip8Computer = system_to_control;
|
||||||
@ -94,58 +94,71 @@ impl GemmaImguiSupport {
|
|||||||
ui.text(format!("Step {:04x}", system_to_control.num_cycles()).as_str());
|
ui.text(format!("Step {:04x}", system_to_control.num_cycles()).as_str());
|
||||||
|
|
||||||
/* ROM Lister */
|
/* ROM Lister */
|
||||||
let new_filename = GuiFileList::display_path(PathBuf::from(ROM_ROOT), &gui_state.filename_to_load, ui);
|
if CollapsingHeader::new("Roms").build(ui) {
|
||||||
if !new_filename.is_empty() {
|
let new_filename = GuiFileList::display_path(PathBuf::from(ROM_ROOT), &gui_state.filename_to_load, ui);
|
||||||
if new_filename != gui_state.filename_to_load {
|
if !new_filename.is_empty() {
|
||||||
debug!("NEW FILENAME SELECTED -> {new_filename}");
|
if new_filename != gui_state.filename_to_load {
|
||||||
gui_state.filename_to_load = new_filename;
|
debug!("NEW FILENAME SELECTED -> {new_filename}");
|
||||||
}
|
gui_state.filename_to_load = new_filename;
|
||||||
if ui.button("Load Program") {
|
}
|
||||||
let mut buffer = Vec::new();
|
if ui.button("Load Program") {
|
||||||
debug!("PREPARING TO LOAD {}", gui_state.filename_to_load);
|
let mut buffer = Vec::new();
|
||||||
// let mut input_file = File::open(Path::new("./1-chip8-logo.ch8")).expect("put 1-chip8-logo.ch8 in this directory");
|
debug!("PREPARING TO LOAD {}", gui_state.filename_to_load);
|
||||||
let mut input_file = File::open(Path::new(&(ROM_ROOT.to_string() + "/" + &gui_state.filename_to_load))).expect("put 1-chip8-logo.ch8 in this directory");
|
// let mut input_file = File::open(Path::new("./1-chip8-logo.ch8")).expect("put 1-chip8-logo.ch8 in this directory");
|
||||||
input_file.read_to_end(&mut buffer).expect("unable to read file");
|
let mut input_file = File::open(Path::new(&(ROM_ROOT.to_string() + "/" + &gui_state.filename_to_load))).expect("put 1-chip8-logo.ch8 in this directory");
|
||||||
system_to_control.load_bytes_to_system_memory((&*buffer).into());
|
input_file.read_to_end(&mut buffer).expect("unable to read file");
|
||||||
|
system_to_control.load_new_program_to_system_memory((&*buffer).into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ui.separator();
|
|
||||||
// if the system has no program loaded hide the buttons.
|
|
||||||
if system_to_control.state().memory.peek(0x200) != 0x00 {
|
|
||||||
if ui.button("Step") {
|
|
||||||
system_to_control.step();
|
|
||||||
};
|
|
||||||
ui.same_line();
|
|
||||||
if ui.button("Run") {
|
|
||||||
system_to_control.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui.same_line();
|
|
||||||
if ui.button("Stop") {
|
|
||||||
system_to_control.stop();
|
|
||||||
}
|
|
||||||
ui.same_line();
|
|
||||||
if ui.button("Reset") {
|
|
||||||
system_to_control.reset();
|
|
||||||
}
|
|
||||||
if ui.button("Dump Video Memory") {
|
|
||||||
println!("{}", system_to_control.dump_to_string(Video));
|
|
||||||
}
|
|
||||||
ui.same_line();
|
|
||||||
if ui.button("Dump Keypad State") {
|
|
||||||
debug!("{}", system_to_control.dump_to_string(Keyboard));
|
|
||||||
}
|
|
||||||
ui.same_line();
|
|
||||||
if ui.button("Dump Registers") {
|
|
||||||
debug!("{}", system_to_control.dump_to_string(Registers));
|
|
||||||
}
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
ui.checkbox("Show Memory", &mut gui_state.show_memory);
|
if CollapsingHeader::new("Controls").build(ui) {
|
||||||
ui.same_line();
|
// if the system has no program loaded hide the buttons.
|
||||||
ui.checkbox("Show Video", &mut gui_state.show_video);
|
let bytes: [u8; 2] = [
|
||||||
ui.same_line();
|
system_to_control.state().memory.peek(0x200),
|
||||||
ui.checkbox("Show Registers", &mut gui_state.show_registers);
|
system_to_control.state().memory.peek(0x201)
|
||||||
|
];
|
||||||
|
let mut show_buttons = bytes[0] != 0 || bytes[1] == 0xe0;
|
||||||
|
|
||||||
|
if show_buttons {
|
||||||
|
if ui.button("Step") {
|
||||||
|
system_to_control.step();
|
||||||
|
};
|
||||||
|
ui.same_line();
|
||||||
|
if ui.button("Run") {
|
||||||
|
system_to_control.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.same_line();
|
||||||
|
if ui.button("Stop") {
|
||||||
|
system_to_control.stop();
|
||||||
|
}
|
||||||
|
ui.same_line();
|
||||||
|
if ui.button("Reset") {
|
||||||
|
system_to_control.reset();
|
||||||
|
}
|
||||||
|
if ui.button("Dump Video Memory") {
|
||||||
|
println!("{}", system_to_control.dump_to_string(Video));
|
||||||
|
}
|
||||||
|
ui.same_line();
|
||||||
|
if ui.button("Dump Keypad State") {
|
||||||
|
debug!("{}", system_to_control.dump_to_string(Keyboard));
|
||||||
|
}
|
||||||
|
ui.same_line();
|
||||||
|
if ui.button("Dump Registers") {
|
||||||
|
debug!("{}", system_to_control.dump_to_string(Registers));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if CollapsingHeader::new("Options").build(ui) {
|
||||||
|
ui.checkbox("Show Memory", &mut gui_state.show_memory);
|
||||||
|
ui.same_line();
|
||||||
|
ui.checkbox("Show Video", &mut gui_state.show_video);
|
||||||
|
ui.same_line();
|
||||||
|
ui.checkbox("Show Registers", &mut gui_state.show_registers);
|
||||||
|
ui.same_line();
|
||||||
|
ui.checkbox("Show Keypad", &mut gui_state.show_keypad);
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,53 +190,53 @@ impl GemmaImguiSupport {
|
|||||||
ui.window("System Memory")
|
ui.window("System Memory")
|
||||||
.position([100.0, 640.0], Condition::FirstUseEver)
|
.position([100.0, 640.0], Condition::FirstUseEver)
|
||||||
.build(|| {
|
.build(|| {
|
||||||
let mut current_x_hover: i32 = 0;
|
let mut current_x_hover: i32 = 0;
|
||||||
let mut current_y_hover: i32 = 0;
|
let mut current_y_hover: i32 = 0;
|
||||||
// display a block of data
|
// display a block of data
|
||||||
for current_row in 0..rows {
|
for current_row in 0..rows {
|
||||||
ui.text(format!("{:02x}", current_row * cols));
|
ui.text(format!("{:02x}", current_row * cols));
|
||||||
ui.same_line();
|
ui.same_line();
|
||||||
for current_column in 0..cols {
|
for current_column in 0..cols {
|
||||||
let data_offset = current_row * cols + current_column;
|
let data_offset = current_row * cols + current_column;
|
||||||
let formatted_text = format!("{:02x}", bytes.peek(data_offset as u16));
|
let formatted_text = format!("{:02x}", bytes.peek(data_offset as u16));
|
||||||
let text_location = ui.cursor_screen_pos();
|
let text_location = ui.cursor_screen_pos();
|
||||||
let text_size = ui.calc_text_size(formatted_text.clone());
|
let text_size = ui.calc_text_size(formatted_text.clone());
|
||||||
let bounding_box = imgui::sys::ImVec2 {
|
let bounding_box = imgui::sys::ImVec2 {
|
||||||
x: text_location[0] + text_size[0],
|
x: text_location[0] + text_size[0],
|
||||||
y: text_location[1] + text_size[1],
|
y: text_location[1] + text_size[1],
|
||||||
};
|
};
|
||||||
|
|
||||||
let hovering = ui.is_mouse_hovering_rect(text_location, [bounding_box.x, bounding_box.y]);
|
let hovering = ui.is_mouse_hovering_rect(text_location, [bounding_box.x, bounding_box.y]);
|
||||||
let is_active = data_offset == active as i32;
|
let is_active = data_offset == active as i32;
|
||||||
|
|
||||||
ui.text_colored(if hovering {
|
ui.text_colored(if hovering {
|
||||||
[0., 1., 1., 1.]
|
[0., 1., 1., 1.]
|
||||||
} else if is_active {
|
} else if is_active {
|
||||||
[1., 0., 1., 1.]
|
[1., 0., 1., 1.]
|
||||||
} else {
|
} else {
|
||||||
[1., 1., 0., 1.]
|
[1., 1., 0., 1.]
|
||||||
}, formatted_text.clone());
|
}, formatted_text.clone());
|
||||||
|
|
||||||
// if we are hovering show that at the bottom...
|
// if we are hovering show that at the bottom...
|
||||||
if hovering {
|
if hovering {
|
||||||
// Optionally change the text color to indicate it's interactable
|
// Optionally change the text color to indicate it's interactable
|
||||||
current_x_hover = current_column;
|
current_x_hover = current_column;
|
||||||
current_y_hover = current_row;
|
current_y_hover = current_row;
|
||||||
|
|
||||||
// Check if the left mouse button is clicked while hovering over the text
|
// Check if the left mouse button is clicked while hovering over the text
|
||||||
if ui.is_mouse_clicked(imgui::MouseButton::Left) {
|
if ui.is_mouse_clicked(imgui::MouseButton::Left) {
|
||||||
debug!("Offset: [{}] [0x{:02x}] Value: [{}]", data_offset, data_offset, formatted_text.clone());
|
debug!("Offset: [{}] [0x{:02x}] Value: [{}]", data_offset, data_offset, formatted_text.clone());
|
||||||
// Perform any action here, e.g., call a function, trigger an event, etc.
|
// Perform any action here, e.g., call a function, trigger an event, etc.
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// are we on the same line?
|
|
||||||
if current_column != (cols - 1) {
|
|
||||||
ui.same_line();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// are we on the same line?
|
||||||
|
if current_column != (cols - 1) {
|
||||||
|
ui.same_line();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ui.text(format!("Offset 0x{:03x}", current_x_hover * cols + current_y_hover));
|
}
|
||||||
|
ui.text(format!("Offset 0x{:03x}", current_x_hover * cols + current_y_hover));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ impl GuiFileList {
|
|||||||
|
|
||||||
let mut known_files: Vec<OsString> = vec![];
|
let mut known_files: Vec<OsString> = vec![];
|
||||||
|
|
||||||
println!("STARTING AT {:?}", std::env::current_dir());
|
// println!("STARTING AT {:?}", std::env::current_dir());
|
||||||
for entry in read_dir(root.as_path()).unwrap() {
|
for entry in read_dir(root.as_path()).unwrap() {
|
||||||
known_files.push(entry.unwrap().file_name());
|
known_files.push(entry.unwrap().file_name());
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user