improve core to handle looping of video

This commit is contained in:
Trevor Merritt 2024-10-11 13:12:13 -04:00
parent c455175447
commit ef0250b519
5 changed files with 43 additions and 19 deletions

View File

@ -654,6 +654,9 @@ impl Chip8CpuInstructions {
// which is then ANDed with the value kk.
// The results are stored in Vx.
let new_value: u8 = random();
let and_value: u8 = *byte;
let result = new_value & and_value;
println!("RANDOM: [{new_value:02x}] AND: [{and_value:02x} Result: [{result:02x}]");
input.registers.poke(*x as u8, new_value & *byte as u8)
}
Chip8CpuInstructions::DrawVxVyNibble(y, x, n) => {
@ -674,23 +677,23 @@ impl Chip8CpuInstructions {
let x_offset = input.registers.peek(*x as u8);
let y_offset = input.registers.peek(*y as u8);
println!("X_OFFSET = {x_offset} / y_offset = {y_offset}");
debug!("X_OFFSET = {x_offset} / y_offset = {y_offset}");
let target_memory_offset = x_offset as u16 * 64 + y_offset as u16;
println!("CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> STARTING AT {source_memory_offset} WRITING TO {target_memory_offset}");
debug!("CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> STARTING AT {source_memory_offset} WRITING TO {target_memory_offset}");
let num_bytes_to_read = *n;
println!("CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> PREPARING TO READ {num_bytes_to_read} BYTES FROM MEMORY TO VIDEO");
debug!("CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> PREPARING TO READ {num_bytes_to_read} BYTES FROM MEMORY TO VIDEO");
for byte_index in 0..num_bytes_to_read {
let current_byte = input.memory.peek(byte_index as u16 + source_memory_offset);
println!("CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> READ BYTE [0x{byte_index:2x}]\t{current_byte:02x}\t{current_byte:08b}");
debug!("CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> READ BYTE [0x{byte_index:2x}]\t{current_byte:02x}\t{current_byte:08b}");
for bit_index in 0..8 {
let data_offset = ((x_offset as u16 + byte_index as u16) * 64) + (y_offset + bit_index) as u16;
let data_offset = ((x_offset as u16 + byte_index as u16) * 64) + (y_offset as u16 + bit_index as u16) as u16;
let current_bit = (current_byte.shr(7 - bit_index) & 0x1u8) == 0x1u8;
input.video_memory.poke(data_offset, current_bit);
}
}
println!("PPOOSSTT -> CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> {}", input.video_memory.format_as_string());
debug!("PPOOSSTT -> CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> {}", input.video_memory.format_as_string());
let mut did_change: bool = false;
@ -770,8 +773,9 @@ impl Chip8CpuInstructions {
// to the value of Vx. See section 2.4, Display, for more information on
// the Chip-8 hexadecimal font.
let to_offset = input.registers.peek(*x as u8) - 1;
let real_offset = to_offset as u16 * 5;
let x_value: u8 = input.registers.peek(*x);
let real_offset = x_value as u16 * 5;
input.registers.poke_i(real_offset as u16);
}
Chip8CpuInstructions::LdBVx(x) => {
@ -817,11 +821,11 @@ impl Chip8CpuInstructions {
let offset = input.registers.peek_i();
debug!("STARTING TO READ AT {offset:03x}");
let num_loops = x + 1;
println!("WILL READ {num_loops:x} BYTES");
debug!("WILL READ {num_loops:x} BYTES");
for index in 0..num_loops {
let src_value = input.memory.peek(index as u16 + offset);
input.registers.poke(index as u8, src_value);
println!("POKING Register 0x{index:02x} with 0x{src_value:04x} using offset 0x{offset:04x}");
debug!("POKING Register 0x{index:02x} with 0x{src_value:04x} using offset 0x{offset:04x}");
}
input.registers.poke_i(offset + 1);
}
@ -1553,4 +1557,13 @@ mod test {
assert_eq!(x.registers.peek(0x01), 0b01000000);
assert_eq!(x.registers.peek(0x0f), 0x01);
}
#[test]
fn random_produces_different_numbers() {
let mut x = Chip8Computer::new();
x.registers.poke(0x01, 0x00);
let first_number = Chip8CpuInstructions::RndVxByte(0x01, 0xff).execute(&mut x).registers.peek(0x01);
let second_number = Chip8CpuInstructions::RndVxByte(0x01, 0xff).execute(&mut x).registers.peek(0x01);
assert_ne!(first_number, second_number);
}
}

View File

@ -1,3 +1,5 @@
use crate::constants::CHIP8_KEYBOARD;
#[derive(Clone, Copy)]
pub struct Keypad {
keys: [bool; 0x10],
@ -7,13 +9,9 @@ impl Keypad {
pub fn format_as_string(&self) -> String {
let mut return_value = String::new();
// draw a 4x4 grid showing the keys with * filling the cells that are depressed
let keys = [
[0x1, 0x2, 0x3, 0xc],[0x4, 0x5, 0x6, 0xd],[0x7, 0x8, 0x9, 0xe],[0xa, 0x0, 0xb, 0xf]
];
for row in keys.iter() {
for row in CHIP8_KEYBOARD.iter() {
for (index, key) in row.iter().enumerate() {
let is_lit = if self.keys[*key] { "*".to_string() } else { char::from_digit(*key as u32, 16).unwrap_or(' ').to_string() };
let is_lit = if self.keys[*key as usize] { "*".to_string() } else { char::from_digit(*key as u32, 16).unwrap_or(' ').to_string() };
match index {
3 => {
// last in col

View File

@ -14,7 +14,8 @@ impl Default for Chip8Stack {
impl Chip8Stack {
pub fn push(&mut self, new_value: &u16) {
if self.depth() == 16 {
panic!("Stack Overflow");
println!("Deep deep stack?");
// panic!("Stack Overflow");
}
self.items.push(*new_value );
}

View File

@ -31,14 +31,19 @@ impl Chip8Video {
pub fn poke(&mut self, address: u16, new_value: bool) -> Self {
trace!("OFFSET: {address} - POKING {new_value}");
let old_value = self.memory[address as usize];
let effective_address = if address > 2048 {
address - 2048
} else {
address
};
let old_value = self.memory[effective_address as usize];
if old_value != new_value {
trace!("**VIDEO** TOGGLING");
self.has_frame_changed = true;
} else {
trace!("NOT TOGGLING");
}
self.memory[address as usize] = new_value;
self.memory[effective_address as usize] = new_value;
self.to_owned()
}

View File

@ -4,3 +4,10 @@ pub const CHIP8_VIDEO_WIDTH: i32 = 64i32;
pub const CHIP8_VIDEO_HEIGHT: i32 = 32i32;
pub const CHIP8_VIDEO_MEMORY: usize = (CHIP8_VIDEO_HEIGHT * CHIP8_VIDEO_WIDTH) as usize;
pub const CHIP8_ROM_SIZE: usize = 512;
pub const CHIP8_KEYBOARD: [[u8; 4]; 4] = [
[0x01, 0x02, 0x03, 0x0C],
[0x04, 0x05, 0x06, 0x0D],
[0x07, 0x08, 0x09, 0x0E],
[0x0A, 0x00, 0x0B, 0x0F]
];