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. // which is then ANDed with the value kk.
// The results are stored in Vx. // The results are stored in Vx.
let new_value: u8 = random(); 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) input.registers.poke(*x as u8, new_value & *byte as u8)
} }
Chip8CpuInstructions::DrawVxVyNibble(y, x, n) => { Chip8CpuInstructions::DrawVxVyNibble(y, x, n) => {
@ -674,23 +677,23 @@ impl Chip8CpuInstructions {
let x_offset = input.registers.peek(*x as u8); let x_offset = input.registers.peek(*x as u8);
let y_offset = input.registers.peek(*y 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; 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; 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 { for byte_index in 0..num_bytes_to_read {
let current_byte = input.memory.peek(byte_index as u16 + source_memory_offset); 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 { 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; let current_bit = (current_byte.shr(7 - bit_index) & 0x1u8) == 0x1u8;
input.video_memory.poke(data_offset, current_bit); 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; 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 // to the value of Vx. See section 2.4, Display, for more information on
// the Chip-8 hexadecimal font. // the Chip-8 hexadecimal font.
let to_offset = input.registers.peek(*x as u8) - 1; let x_value: u8 = input.registers.peek(*x);
let real_offset = to_offset as u16 * 5;
let real_offset = x_value as u16 * 5;
input.registers.poke_i(real_offset as u16); input.registers.poke_i(real_offset as u16);
} }
Chip8CpuInstructions::LdBVx(x) => { Chip8CpuInstructions::LdBVx(x) => {
@ -817,11 +821,11 @@ impl Chip8CpuInstructions {
let offset = input.registers.peek_i(); let offset = input.registers.peek_i();
debug!("STARTING TO READ AT {offset:03x}"); debug!("STARTING TO READ AT {offset:03x}");
let num_loops = x + 1; 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 { for index in 0..num_loops {
let src_value = input.memory.peek(index as u16 + offset); let src_value = input.memory.peek(index as u16 + offset);
input.registers.poke(index as u8, src_value); 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); input.registers.poke_i(offset + 1);
} }
@ -1553,4 +1557,13 @@ mod test {
assert_eq!(x.registers.peek(0x01), 0b01000000); assert_eq!(x.registers.peek(0x01), 0b01000000);
assert_eq!(x.registers.peek(0x0f), 0x01); 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)] #[derive(Clone, Copy)]
pub struct Keypad { pub struct Keypad {
keys: [bool; 0x10], keys: [bool; 0x10],
@ -7,13 +9,9 @@ impl Keypad {
pub fn format_as_string(&self) -> String { pub fn format_as_string(&self) -> String {
let mut return_value = String::new(); let mut return_value = String::new();
// draw a 4x4 grid showing the keys with * filling the cells that are depressed // draw a 4x4 grid showing the keys with * filling the cells that are depressed
let keys = [ for row in CHIP8_KEYBOARD.iter() {
[0x1, 0x2, 0x3, 0xc],[0x4, 0x5, 0x6, 0xd],[0x7, 0x8, 0x9, 0xe],[0xa, 0x0, 0xb, 0xf]
];
for row in keys.iter() {
for (index, key) in row.iter().enumerate() { 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 { match index {
3 => { 3 => {
// last in col // last in col

View File

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

View File

@ -31,14 +31,19 @@ impl Chip8Video {
pub fn poke(&mut self, address: u16, new_value: bool) -> Self { pub fn poke(&mut self, address: u16, new_value: bool) -> Self {
trace!("OFFSET: {address} - POKING {new_value}"); 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 { if old_value != new_value {
trace!("**VIDEO** TOGGLING"); trace!("**VIDEO** TOGGLING");
self.has_frame_changed = true; self.has_frame_changed = true;
} else { } else {
trace!("NOT TOGGLING"); trace!("NOT TOGGLING");
} }
self.memory[address as usize] = new_value; self.memory[effective_address as usize] = new_value;
self.to_owned() 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_HEIGHT: i32 = 32i32;
pub const CHIP8_VIDEO_MEMORY: usize = (CHIP8_VIDEO_HEIGHT * CHIP8_VIDEO_WIDTH) as usize; pub const CHIP8_VIDEO_MEMORY: usize = (CHIP8_VIDEO_HEIGHT * CHIP8_VIDEO_WIDTH) as usize;
pub const CHIP8_ROM_SIZE: usize = 512; 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]
];