more passing tests. almost have coverage of instructions back
This commit is contained in:
@@ -111,7 +111,8 @@ impl Chip8ComputerManager {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ pub enum Chip8CpuInstructions {
|
||||
///
|
||||
/// Checks the keyboard, and if the key corresponding to the value of Vx is currently in
|
||||
/// the up position, PC is increased by 2.
|
||||
/// On XO Chip, Skips 2 more bytes when the instruction is 4 bytes long
|
||||
SKNP(u8),
|
||||
/// Fx07
|
||||
/// The value of DT is placed into Vx.
|
||||
@@ -221,6 +222,7 @@ pub enum Chip8CpuInstructions {
|
||||
/// V0 through Vx.
|
||||
LDRI(u8),
|
||||
XXXXERRORINSTRUCTION,
|
||||
// 00Dn - CHIP8 - SCHIP * XOCHIP
|
||||
/* START OF SCHIP-8 */
|
||||
/// 00CN - CHIP8 * SCHIP * XOCHIP
|
||||
///
|
||||
@@ -261,7 +263,12 @@ pub enum Chip8CpuInstructions {
|
||||
/// 0xBxNN
|
||||
///
|
||||
/// 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 {
|
||||
@@ -313,6 +320,7 @@ impl Chip8CpuInstructions {
|
||||
Chip8CpuInstructions::ORY(_, _) => INST_ORY,
|
||||
JPX(_, _) => INST_JPX,
|
||||
XXXXERRORINSTRUCTION => "XX ERROR XX",
|
||||
SCU(_) => INST_SCU
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,6 +363,7 @@ impl Chip8CpuInstructions {
|
||||
format!("0x{x:02x}, 0x{y:02x}, 0x{nibble:02x}")
|
||||
}
|
||||
// Registers. 0-F
|
||||
Chip8CpuInstructions::SCU(x) |
|
||||
Chip8CpuInstructions::LDD(x) |
|
||||
Chip8CpuInstructions::LDIS(x) |
|
||||
Chip8CpuInstructions::ADDI(x) |
|
||||
@@ -597,7 +606,8 @@ impl Chip8CpuInstructions {
|
||||
Chip8CpuInstructions::LDF2(x_register) => 0xF030 | ((*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),
|
||||
XXXXERRORINSTRUCTION => 0xFFFF
|
||||
XXXXERRORINSTRUCTION => 0xFFFF,
|
||||
SCU(x_register) => 0x00D0 | (*x_register as u16),
|
||||
}
|
||||
}
|
||||
pub fn decode(input: u16, quirk_mode: &QuirkMode) -> Chip8CpuInstructions {
|
||||
@@ -1124,19 +1134,18 @@ impl Chip8CpuInstructions {
|
||||
Chip8CpuInstructions::SCD(x) => {
|
||||
match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
panic!("Attempt to execute SCD in Chip8 Mode");
|
||||
debug!("Attempt to execute SCD in Chip8 Mode");
|
||||
}
|
||||
QuirkMode::XOChip |
|
||||
QuirkMode::SChipModern => {
|
||||
input.video_memory.scroll_down(*x as i32);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Chip8CpuInstructions::SCR => {
|
||||
match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
// panic!("Attempt to execute SCR in Chip8 Mode");
|
||||
debug!("Attempt to execute SCR in Chip8 Mode");
|
||||
}
|
||||
QuirkMode::XOChip |
|
||||
QuirkMode::SChipModern => {
|
||||
@@ -1145,27 +1154,97 @@ impl Chip8CpuInstructions {
|
||||
}
|
||||
}
|
||||
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 => {
|
||||
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 => {
|
||||
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 => {
|
||||
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) => {
|
||||
println!("POINTING TO FONT AT {x:02x}");
|
||||
// base = 0x100 + 0x0A*X
|
||||
input.registers.poke_i(0x100 + (0xA * x) as u16);
|
||||
match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
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) => {
|
||||
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) => {
|
||||
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();
|
||||
|
||||
@@ -15,6 +15,12 @@ pub struct Chip8Video {
|
||||
current_res: Chip8VideoModes,
|
||||
}
|
||||
|
||||
impl Chip8Video {
|
||||
pub fn scroll_up(&self, how_far: &u8) {
|
||||
println!("Scrolling up {how_far} rows.");
|
||||
}
|
||||
}
|
||||
|
||||
impl Chip8Video {
|
||||
pub fn reset(&mut self) {
|
||||
self.cls();
|
||||
@@ -143,17 +149,23 @@ impl Chip8Video {
|
||||
}
|
||||
|
||||
pub fn scroll_right(&mut self) {
|
||||
println!("SCROLLRIGHTPRE:::[{}]", self.format_as_string());
|
||||
let (width, height) = self.get_resolution();
|
||||
|
||||
for current_row in 0..height {
|
||||
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() {
|
||||
let source_address = row_offset + current_column as usize;
|
||||
let target_address = source_address + 4;
|
||||
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);
|
||||
}
|
||||
println!("SCROLLRIGHTPOST:::[{}]", self.format_as_string());
|
||||
}
|
||||
|
||||
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_HIGH: &str = "HIGH";
|
||||
pub const INST_ORY: &str = "ORY";
|
||||
|
||||
pub const INST_SCU: &str = "SCU";
|
||||
pub const CHIP8_PROGRAM_LOAD_OFFSET: i32 = 0x200;
|
||||
pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0];
|
||||
pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70];
|
||||
|
||||
Reference in New Issue
Block a user