From a978ddc41eca31c007835ab85ef476297dfddbb0 Mon Sep 17 00:00:00 2001 From: Trevor Merritt Date: Wed, 23 Oct 2024 09:08:20 -0400 Subject: [PATCH] adding SChip features --- gemma/src/chip8/video.rs | 63 +++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/gemma/src/chip8/video.rs b/gemma/src/chip8/video.rs index 5bb55d6..7d458c6 100644 --- a/gemma/src/chip8/video.rs +++ b/gemma/src/chip8/video.rs @@ -1,6 +1,6 @@ use log::{debug}; use crate::chip8::video::Chip8VideoModes::{HighRes, LowRes}; -use crate::constants::{CHIP8_VIDEO_MEMORY, CHIP8_VIDEO_WIDTH}; +use crate::constants::{CHIP8_VIDEO_MEMORY, CHIP8_VIDEO_WIDTH, SCHIP_VIDE_MEMORY}; #[derive(Clone, Copy)] enum Chip8VideoModes { @@ -21,6 +21,11 @@ impl Chip8Video { self.start_frame(); } + + pub fn is_highres(&self) -> bool { + matches!(self.current_res, HighRes) + } + pub fn set_highres(&mut self) { self.current_res = HighRes } @@ -58,17 +63,26 @@ impl Chip8Video { } pub fn peek(self, address: u16) -> bool { - let effective_address = if address >= 2048 { - address % 2048 + let loop_value: u16 = if self.is_highres() { + SCHIP_VIDE_MEMORY as u16 + } else { + CHIP8_VIDEO_MEMORY as u16 + }; + let effective_address = if address >= loop_value { + address % loop_value } else { address }; self.memory[effective_address as usize] } pub fn poke(&mut self, address: u16, new_value: bool) { // println!("OFFSET: {address} - POKING {new_value}"); - + let loop_value: u16 = if self.is_highres() { + SCHIP_VIDE_MEMORY as u16 + } else { + CHIP8_VIDEO_MEMORY as u16 + }; // Loop the address - let effective_address = address % 2048; + let effective_address = address % loop_value; let old_value = self.memory[effective_address as usize]; let xored_value = new_value ^ old_value; // XOR of the video @@ -82,13 +96,20 @@ impl Chip8Video { self.memory[effective_address as usize] = xored_value; } - pub fn poke_byte(&mut self, first_address: u16, to_write: u8) { for i in (0..8).rev() { self.poke(first_address + (7 - i), (to_write & (1 << i)) != 0); } } + pub fn poke_2byte(&mut self, first_address: u16, to_write: [u8; 2]) { + for (idx, _) in to_write.iter().enumerate() { + for i in (0..8).rev() { + self.poke(first_address + (idx * 8) as u16 + (7 - i), (to_write[idx] & (1 << i)) != 0); + } + } + } + pub fn format_as_string(self) -> String { let mut output = String::new(); for row in 0..32 { @@ -207,7 +228,7 @@ mod test { } #[test] - fn poke_byte() { + fn poke_byte_test() { let to_poke = 0b11001111; let mut x = Chip8Video::default(); x.poke_byte(0x05, to_poke); @@ -219,6 +240,30 @@ mod test { assert_eq!(x.format_as_string(), expected); } + #[test] + fn poke_2byte_test() { + let to_poke: [u8; 2] = [ + 0b11001111, + 0b00111100 + ]; + + let mut x = Chip8Video::default(); + x.poke_2byte(0x00, to_poke); + + let mut expected = String::new(); + expected = "** **** **** ".to_string() + &*" ".repeat(64 - 16).to_string() + "\n"; + for i in 0..31 { + expected += &*((&*" ".repeat(64)).to_string() + "\n"); + } + + assert_eq!(expected, x.format_as_string()); + } + + #[test] + fn poke_multirow_2_byte_sprite() { + // take 2 rows of 16bits and write them to memory + } + #[test] fn cls() { let mut initial_memory = [false; CHIP8_VIDEO_MEMORY]; @@ -240,7 +285,7 @@ mod test { } #[test] - fn poke_byte_test() { + fn poke_byte_test_2() { let to_poke = 0b10101010; let mut v = Chip8Video::default(); v.poke_byte(0x00, to_poke); @@ -435,4 +480,6 @@ mod test { // if we got here we didn't panic assert!(true); } + + }