improve core to handle looping of video
This commit is contained in:
parent
c455175447
commit
ef0250b519
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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]
|
||||||
|
];
|
||||||
Loading…
x
Reference in New Issue
Block a user