emmagui isnt rendering correctly.
backend isnt writing a sprite correctly and attempting to poke outside memory
This commit is contained in:
parent
d4273dfb13
commit
b4383436aa
@ -16,18 +16,23 @@ const CELL_HEIGHT: i32 = 5i32;
|
|||||||
|
|
||||||
impl EmmaGui {
|
impl EmmaGui {
|
||||||
pub fn video_display(system_to_control: &Chip8Computer, ui: &Ui) {
|
pub fn video_display(system_to_control: &Chip8Computer, ui: &Ui) {
|
||||||
ui.window("Display")
|
// draw area size
|
||||||
|
let draw_area_size = ui.window_size();
|
||||||
|
let cell_width = draw_area_size[0] as i32 / 64;
|
||||||
|
let cell_height = draw_area_size[1] as i32 / 32;
|
||||||
|
|
||||||
|
ui.window(format!("Display {cell_width}x{cell_height}"))
|
||||||
.size([300.0, 300.0], Condition::FirstUseEver)
|
.size([300.0, 300.0], Condition::FirstUseEver)
|
||||||
.build(|| {
|
.build(|| {
|
||||||
let origin = ui.cursor_screen_pos();
|
let origin = ui.cursor_screen_pos();
|
||||||
let fg = ui.get_window_draw_list();
|
let fg = ui.get_window_draw_list();
|
||||||
ui.text("This is the video display.");
|
ui.text("This is the video display.");
|
||||||
for current_row in 0..31 {
|
for current_row in 0..31 {
|
||||||
for current_column in 0..64 {
|
for current_column in 0..63 {
|
||||||
let x_offset = origin[0] as i32 + (current_column * 5);
|
let x_offset = origin[0] as i32 + (current_column * cell_width);
|
||||||
let y_offset = origin[1] as i32 + (current_row * 5);
|
let y_offset = origin[1] as i32 + (current_row * cell_height);
|
||||||
let current_origin = [x_offset as f32, y_offset as f32];
|
let current_origin = [x_offset as f32, y_offset as f32];
|
||||||
let current_limit = [(x_offset + 5) as f32, (y_offset + 5) as f32];
|
let current_limit = [(x_offset + cell_width) as f32, (y_offset + cell_height) as f32];
|
||||||
let memory_offset = (current_row * 64 + current_column) as u16;
|
let memory_offset = (current_row * 64 + current_column) as u16;
|
||||||
let to_render = system_to_control.video_memory.peek(memory_offset);
|
let to_render = system_to_control.video_memory.peek(memory_offset);
|
||||||
let color: ImColor32 = if to_render {
|
let color: ImColor32 = if to_render {
|
||||||
@ -82,7 +87,7 @@ impl EmmaGui {
|
|||||||
ui.same_line();
|
ui.same_line();
|
||||||
ui.text(format!("DT: {:02X}", system.delay_timer.current()));
|
ui.text(format!("DT: {:02X}", system.delay_timer.current()));
|
||||||
ui.text(format!("PC: {:02X}", system.registers.peek_pc()));
|
ui.text(format!("PC: {:02X}", system.registers.peek_pc()));
|
||||||
ui.text(format!("SP: {:02X}", system.sp));
|
ui.text(format!("SP: {:02X}", system.stack.depth()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::chip8::instructions::Chip8CpuInstructions::XXXXERRORINSTRUCTION;
|
|||||||
use crate::chip8::keypad::Keypad;
|
use crate::chip8::keypad::Keypad;
|
||||||
use crate::chip8::registers::Chip8Registers;
|
use crate::chip8::registers::Chip8Registers;
|
||||||
use crate::chip8::sound_timer::SoundTimer;
|
use crate::chip8::sound_timer::SoundTimer;
|
||||||
|
use crate::chip8::stack::Chip8Stack;
|
||||||
use crate::chip8::util::InstructionUtil;
|
use crate::chip8::util::InstructionUtil;
|
||||||
use crate::constants::{CHIP8_MEMORY_SIZE, CHIP8_REGISTER_COUNT};
|
use crate::constants::{CHIP8_MEMORY_SIZE, CHIP8_REGISTER_COUNT};
|
||||||
|
|
||||||
@ -11,28 +12,30 @@ use super::{
|
|||||||
cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video,
|
cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
const STACK_POINTER_DEFAULT: i16 = 0x100;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Chip8Computer {
|
pub struct Chip8Computer {
|
||||||
pub sp: u8,
|
|
||||||
pub memory: Chip8SystemMemory,
|
pub memory: Chip8SystemMemory,
|
||||||
pub registers: Chip8Registers,
|
pub registers: Chip8Registers,
|
||||||
pub sound_timer: SoundTimer,
|
pub sound_timer: SoundTimer,
|
||||||
pub delay_timer: DelayTimer,
|
pub delay_timer: DelayTimer,
|
||||||
pub video_memory: Chip8Video,
|
pub video_memory: Chip8Video,
|
||||||
pub state: Chip8CpuStates,
|
pub state: Chip8CpuStates,
|
||||||
pub keypad: Keypad
|
pub keypad: Keypad,
|
||||||
|
pub stack: Chip8Stack
|
||||||
}
|
}
|
||||||
impl Default for Chip8Computer {
|
impl Default for Chip8Computer {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
sp: 0x00,
|
|
||||||
memory: Chip8SystemMemory::default(),
|
memory: Chip8SystemMemory::default(),
|
||||||
video_memory: Chip8Video::default(),
|
video_memory: Chip8Video::default(),
|
||||||
registers: Chip8Registers::default(),
|
registers: Chip8Registers::default(),
|
||||||
sound_timer: SoundTimer::new(),
|
sound_timer: SoundTimer::new(),
|
||||||
delay_timer: DelayTimer::new(),
|
delay_timer: DelayTimer::new(),
|
||||||
state: Chip8CpuStates::WaitingForInstruction,
|
state: Chip8CpuStates::default(),
|
||||||
keypad: Keypad::default()
|
keypad: Keypad::default(),
|
||||||
|
stack: Chip8Stack::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,10 +89,8 @@ impl Chip8Computer {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -103,23 +104,5 @@ mod test {
|
|||||||
assert!(true)
|
assert!(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn new_with_program() {
|
|
||||||
// set a known program that sets some registers...
|
|
||||||
let new_program = Box::new(vec![
|
|
||||||
Chip8CpuInstructions::LdVxI(0x10).encode(),
|
|
||||||
Chip8CpuInstructions::LdVxVy(0x1, 0x1).encode(),
|
|
||||||
Chip8CpuInstructions::LdStVx(0xff).encode()
|
|
||||||
]);
|
|
||||||
|
|
||||||
// ...then load it...
|
|
||||||
let test_computer = Chip8Computer::new_with_program(new_program);
|
|
||||||
|
|
||||||
// ...and check the registers
|
|
||||||
// let (high, low) = InstructionUtil::split_bytes(Chip8CpuInstructions::LdVxI(0x10).encode());
|
|
||||||
// assert_eq!(test_computer.memory.peek(0x200), high);
|
|
||||||
// assert_eq!(test_computer.memory.peek(0x201), low);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -613,7 +613,8 @@ 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);
|
||||||
|
|
||||||
let target_memory_offset = x_offset * 64 + y_offset;
|
println!("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}");
|
println!("CHIP8CPUINSTRUCTION:DRAWVXNIBBLE -> STARTING AT {source_memory_offset} WRITING TO {target_memory_offset}");
|
||||||
let num_bytes_to_read = *n;
|
let num_bytes_to_read = *n;
|
||||||
@ -644,6 +645,10 @@ impl Chip8CpuInstructions {
|
|||||||
//
|
//
|
||||||
// Checks the keyboard, and if the key corresponding to the value of Vx is currently in the down position, PC is increased by 2.
|
// Checks the keyboard, and if the key corresponding to the value of Vx is currently in the down position, PC is increased by 2.
|
||||||
let key_to_check = input.registers.peek(*x as u8);
|
let key_to_check = input.registers.peek(*x as u8);
|
||||||
|
let is_pressed = input.keypad.pressed(key_to_check);
|
||||||
|
if is_pressed {
|
||||||
|
input.registers.advance_pc();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::SnkpVx(x) => {
|
Chip8CpuInstructions::SnkpVx(x) => {
|
||||||
// ExA1 - SKNP Vx
|
// ExA1 - SKNP Vx
|
||||||
@ -656,7 +661,7 @@ impl Chip8CpuInstructions {
|
|||||||
let target_key = input.registers.peek(*x as u8);
|
let target_key = input.registers.peek(*x as u8);
|
||||||
let is_pressed = input.keypad.pressed(target_key);
|
let is_pressed = input.keypad.pressed(target_key);
|
||||||
debug!("SnKpVx [{x:1x}]");
|
debug!("SnKpVx [{x:1x}]");
|
||||||
if is_pressed {
|
if !is_pressed {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,11 +765,10 @@ impl Chip8CpuInstructions {
|
|||||||
}
|
}
|
||||||
Chip8CpuInstructions::XXXXERRORINSTRUCTION => {}
|
Chip8CpuInstructions::XXXXERRORINSTRUCTION => {}
|
||||||
};
|
};
|
||||||
*input
|
input.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use dimensioned::typenum::assert_type;
|
use dimensioned::typenum::assert_type;
|
||||||
@ -1367,7 +1371,7 @@ mod test {
|
|||||||
x.keypad.push_key(0x5);
|
x.keypad.push_key(0x5);
|
||||||
x.registers.poke(0x1, 0x5);
|
x.registers.poke(0x1, 0x5);
|
||||||
Chip8CpuInstructions::SnkpVx(0x1).execute(&mut x);
|
Chip8CpuInstructions::SnkpVx(0x1).execute(&mut x);
|
||||||
assert_eq!(x.registers.peek_pc(), 0x204);
|
assert_eq!(x.registers.peek_pc(), 0x202);
|
||||||
|
|
||||||
x.keypad.release_key(0x5);
|
x.keypad.release_key(0x5);
|
||||||
Chip8CpuInstructions::SnkpVx(0x1).execute(&mut x);
|
Chip8CpuInstructions::SnkpVx(0x1).execute(&mut x);
|
||||||
@ -1384,11 +1388,11 @@ mod test {
|
|||||||
x.keypad.push_key(0x5);
|
x.keypad.push_key(0x5);
|
||||||
x.registers.poke(0x1, 0x5);
|
x.registers.poke(0x1, 0x5);
|
||||||
Chip8CpuInstructions::SkpVx(0x1).execute(&mut x);
|
Chip8CpuInstructions::SkpVx(0x1).execute(&mut x);
|
||||||
assert_eq!(x.registers.peek_pc(), 0x202);
|
assert_eq!(x.registers.peek_pc(), 0x204);
|
||||||
|
|
||||||
x.keypad.release_key(0x5);
|
x.keypad.release_key(0x5);
|
||||||
Chip8CpuInstructions::SkpVx(0x1).execute(&mut x);
|
Chip8CpuInstructions::SkpVx(0x1).execute(&mut x);
|
||||||
assert_eq!(x.registers.peek_pc(), 0x204);
|
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -6,7 +6,8 @@ use log::debug;
|
|||||||
pub struct Chip8Registers {
|
pub struct Chip8Registers {
|
||||||
registers: [u8; 16],
|
registers: [u8; 16],
|
||||||
i_register: u16,
|
i_register: u16,
|
||||||
pc: u16
|
pc: u16,
|
||||||
|
sp: u16
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chip8Registers {
|
impl Chip8Registers {
|
||||||
@ -20,7 +21,8 @@ impl Default for Chip8Registers {
|
|||||||
Chip8Registers {
|
Chip8Registers {
|
||||||
registers: [0x00; 16],
|
registers: [0x00; 16],
|
||||||
i_register: 0x00,
|
i_register: 0x00,
|
||||||
pc: 0x200
|
pc: 0x200,
|
||||||
|
sp: 0x100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +55,6 @@ impl Chip8Registers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::chip8::registers::Chip8Registers;
|
use crate::chip8::registers::Chip8Registers;
|
||||||
@ -77,5 +78,4 @@ mod test {
|
|||||||
x.set_pc(0x300);
|
x.set_pc(0x300);
|
||||||
assert_eq!(x.peek_pc(), 0x300);
|
assert_eq!(x.peek_pc(), 0x300);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
49
emma/src/chip8/stack.rs
Normal file
49
emma/src/chip8/stack.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Chip8Stack {
|
||||||
|
items: Vec<u16>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Chip8Stack {
|
||||||
|
fn default() -> Self {
|
||||||
|
Chip8Stack {
|
||||||
|
items: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Chip8Stack {
|
||||||
|
pub fn push(&mut self, new_value: &u16) {
|
||||||
|
self.items.push(*new_value );
|
||||||
|
}
|
||||||
|
pub fn pop(&mut self) -> u16 {
|
||||||
|
self.items.pop().unwrap_or(0)
|
||||||
|
}
|
||||||
|
pub fn depth(&self) -> u16 {
|
||||||
|
self.items.len() as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Chip8Stack {
|
||||||
|
items: vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn smoke() { assert!(true) }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn push_pop_test() {
|
||||||
|
let mut x = Chip8Stack::new();
|
||||||
|
|
||||||
|
// lets see if we can push and pop a bunch
|
||||||
|
x.push(&0xabcu16);
|
||||||
|
x.push(&0xcdeu16);
|
||||||
|
x.pop();
|
||||||
|
assert_eq!(x.depth(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -46,6 +46,12 @@ const cell_width: i32 = 5i32;
|
|||||||
const cell_height: i32 = 5i32;
|
const cell_height: i32 = 5i32;
|
||||||
|
|
||||||
impl Chip8SystemMemory {
|
impl Chip8SystemMemory {
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Chip8SystemMemory {
|
||||||
|
memory: [0x00; CHIP8_MEMORY_SIZE as usize],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn peek(self, address: u16) -> u8 {
|
pub fn peek(self, address: u16) -> u8 {
|
||||||
trace!("PEEK: {} / {}", address, self.memory[address as usize].clone());
|
trace!("PEEK: {} / {}", address, self.memory[address as usize].clone());
|
||||||
@ -122,4 +128,14 @@ mod test {
|
|||||||
assert_eq!(x.peek(0), 0x01);
|
assert_eq!(x.peek(0), 0x01);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn verify_load_program() {
|
||||||
|
// first line of 1-chip-logo.ch8
|
||||||
|
let program_to_load = [0x00e0, 0x6101, 0x6008, 0xa250, 0xd01f, 0x6010, 0xa25f, 0xd01f];
|
||||||
|
|
||||||
|
let mut x = Chip8SystemMemory::new();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,20 +6,25 @@ use crate::constants::CHIP8_VIDEO_MEMORY;
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Chip8Video {
|
pub struct Chip8Video {
|
||||||
memory: [bool; CHIP8_VIDEO_MEMORY]
|
memory: [bool; CHIP8_VIDEO_MEMORY],
|
||||||
|
pub has_frame_changed: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chip8Video {
|
impl Chip8Video {
|
||||||
|
|
||||||
pub fn cls(&mut self) {
|
pub fn cls(&mut self) {
|
||||||
for i in 0..CHIP8_VIDEO_MEMORY {
|
for i in 0..CHIP8_VIDEO_MEMORY {
|
||||||
self.memory[i] = false;
|
self.memory[i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn start_frame(&mut self) {
|
||||||
|
self.has_frame_changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(initial_configuration: [bool; CHIP8_VIDEO_MEMORY]) -> Self {
|
pub fn new(initial_configuration: [bool; CHIP8_VIDEO_MEMORY]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
memory: initial_configuration
|
memory: initial_configuration,
|
||||||
|
has_frame_changed: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,9 +35,12 @@ impl Chip8Video {
|
|||||||
pub fn poke(&mut self, address: u16, new_value: bool) -> Self {
|
pub fn poke(&mut self, address: u16, new_value: bool) -> Self {
|
||||||
let col = address % 64;
|
let col = address % 64;
|
||||||
let row = address / 32;
|
let row = address / 32;
|
||||||
|
let offset = col * 64 + row;
|
||||||
|
println!("OFFSET: {offset} - POKING {new_value} to {address} at {col} x {row}");
|
||||||
let old_value = self.memory[address as usize];
|
let old_value = self.memory[address as usize];
|
||||||
if old_value != new_value {
|
if old_value != new_value {
|
||||||
println!("**VIDEO** TOGGLING {new_value} TO {address} / {col}x{row}");
|
println!("**VIDEO** TOGGLING {new_value} TO {address} / {col}x{row}");
|
||||||
|
self.has_frame_changed = true;
|
||||||
}
|
}
|
||||||
self.memory[address as usize] = new_value;
|
self.memory[address as usize] = new_value;
|
||||||
self.to_owned()
|
self.to_owned()
|
||||||
@ -81,12 +89,15 @@ impl Chip8Video {
|
|||||||
|
|
||||||
impl Default for Chip8Video {
|
impl Default for Chip8Video {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { memory: [false; CHIP8_VIDEO_MEMORY as usize] }
|
Self { memory: [false; CHIP8_VIDEO_MEMORY as usize], has_frame_changed: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use crate::chip8::system_memory::CHIP8FONT_0;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -314,4 +325,45 @@ mod test {
|
|||||||
assert!(!v.peek(0xC6));
|
assert!(!v.peek(0xC6));
|
||||||
assert!(v.peek(0xC7));
|
assert!(v.peek(0xC7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn verify_change_registered() {
|
||||||
|
let mut v = Chip8Video::default();
|
||||||
|
v.poke(0x01, true);
|
||||||
|
assert!(v.has_frame_changed);
|
||||||
|
|
||||||
|
v.start_frame();
|
||||||
|
assert!(!v.has_frame_changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn write_checkboard() {
|
||||||
|
let mut v = Chip8Video::default();
|
||||||
|
for i in 0..(CHIP8_VIDEO_MEMORY / 8) {
|
||||||
|
v.poke_byte((i * 8) as u16, 0b10101010);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", v.format_as_string());
|
||||||
|
println!("fsck is a cool tool");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn zero_test() {
|
||||||
|
let mut x = Chip8Video::default();
|
||||||
|
|
||||||
|
x.poke_byte(0x00, CHIP8FONT_0[0]);
|
||||||
|
x.poke_byte(0x08, CHIP8FONT_0[1]);
|
||||||
|
x.poke_byte(0x10, CHIP8FONT_0[2]);
|
||||||
|
x.poke_byte(0x18, CHIP8FONT_0[3]);
|
||||||
|
x.poke_byte(0x20, CHIP8FONT_0[4]);
|
||||||
|
|
||||||
|
println!("SHOULD HAVE 0 AT ORIGIN");
|
||||||
|
println!("{}", x.format_as_string());
|
||||||
|
|
||||||
|
let mut buf: Vec<u8> = vec![];
|
||||||
|
// let read_file_size = File::open("../resources/test/test_video_zero.asc").unwrap().read_to_end(&mut buf).unwrap();
|
||||||
|
|
||||||
|
// println!("READ {read_file_size} bytes.");
|
||||||
|
// assert_eq!(String::from_utf8_lossy(&buf), x.format_as_string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,8 @@ pub mod chip8 {
|
|||||||
pub mod cpu_states;
|
pub mod cpu_states;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod registers;
|
pub mod registers;
|
||||||
|
|
||||||
|
pub mod stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
32
resources/test/test_video_zero.asc
Normal file
32
resources/test/test_video_zero.asc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
*****
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
*****
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user