registers better integrated
more tests and docs to the executors
This commit is contained in:
parent
0075c5ef7d
commit
7b36061268
@ -63,7 +63,7 @@ fn main() {
|
||||
EmmaGui::system_controls(&mut system, ui);
|
||||
|
||||
EmmaGui::registers_view(&system, ui);
|
||||
let active_instruction = system.pc;
|
||||
let active_instruction = system.registers.peek_pc();
|
||||
EmmaGui::hex_memory_display(system.memory.clone(), (0x100, 0x10), active_instruction as i16, ui);
|
||||
EmmaGui::video_display(&system, ui);
|
||||
|
||||
|
||||
@ -69,18 +69,18 @@ impl EmmaGui {
|
||||
.build(|| {
|
||||
ui.text("Registers");
|
||||
for i in 0..0x10 {
|
||||
ui.text(format!("V{:X}: {}", i, system.registers[i as usize]));
|
||||
ui.text(format!("V{:X}: {}", i, system.registers.peek(i)));
|
||||
if i != 7 {
|
||||
ui.same_line();
|
||||
}
|
||||
}
|
||||
ui.text("");
|
||||
ui.text(format!("I: {:03X}", system.i_register));
|
||||
ui.text(format!("I: {:03X}", system.registers.peek_i()));
|
||||
ui.same_line();
|
||||
ui.text(format!("ST: {:02X}", system.sound_timer.current()));
|
||||
ui.same_line();
|
||||
ui.text(format!("DT: {:02X}", system.delay_timer.current()));
|
||||
ui.text(format!("PC: {:02X}", system.pc));
|
||||
ui.text(format!("PC: {:02X}", system.registers.peek_pc()));
|
||||
ui.text(format!("SP: {:02X}", system.sp));
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use log::{debug, error};
|
||||
use crate::chip8::delay_timer::DelayTimer;
|
||||
use crate::chip8::instructions::Chip8CpuInstructions::XXXXERRORINSTRUCTION;
|
||||
use crate::chip8::keypad::Keypad;
|
||||
use crate::chip8::registers::Chip8Registers;
|
||||
use crate::chip8::sound_timer::SoundTimer;
|
||||
use crate::chip8::util::InstructionUtil;
|
||||
@ -19,6 +20,7 @@ pub struct Chip8Computer {
|
||||
pub delay_timer: DelayTimer,
|
||||
pub video_memory: Chip8Video,
|
||||
pub state: Chip8CpuStates,
|
||||
pub keypad: Keypad
|
||||
}
|
||||
|
||||
impl Default for Chip8Computer {
|
||||
@ -31,6 +33,7 @@ impl Default for Chip8Computer {
|
||||
sound_timer: SoundTimer::new(),
|
||||
delay_timer: DelayTimer::new(),
|
||||
state: Chip8CpuStates::WaitingForInstruction,
|
||||
keypad: Keypad::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,21 +436,62 @@ impl Chip8CpuInstructions {
|
||||
let lhs = input.registers.peek(*x as u8);
|
||||
let rhs = input.registers.peek(*y as u8);
|
||||
|
||||
let working =(lhs + rhs) as i16;
|
||||
let working = (lhs as i16 + rhs as i16) as i16;
|
||||
if working > 255 {
|
||||
input.registers.poke(0xf, 0x01);
|
||||
}
|
||||
input.registers.poke(*x as u8, working as u8);
|
||||
}
|
||||
Chip8CpuInstructions::SubVxVy(x,y) => {
|
||||
// 8xy5 - SUB Vx, Vy
|
||||
// Set Vx = Vx - Vy, set VF = NOT borrow.
|
||||
//
|
||||
// If Vx > Vy, then VF is set to 1, otherwise 0. Then Vy is subtracted from Vx, and the results stored in Vx.
|
||||
let lhs = input.registers.peek(*x as u8);
|
||||
let rhs = input.registers.peek(*y as u8);
|
||||
input.registers.poke(*x as u8, lhs - rhs);
|
||||
}
|
||||
Chip8CpuInstructions::ShrVxVy(_, _) => {}
|
||||
Chip8CpuInstructions::SubnVxVy(_, _) => {}
|
||||
Chip8CpuInstructions::ShlVxVy(_, _) => {}
|
||||
Chip8CpuInstructions::ShrVxVy(x, y) => {
|
||||
// 8xy6 - SHR Vx {, Vy}
|
||||
// Set Vx = Vx SHR 1.
|
||||
//
|
||||
// If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then Vx is divided by 2.
|
||||
let initial_value = input.registers.peek(*x as u8);
|
||||
if 0xb1 & initial_value == 1 {
|
||||
input.registers.poke(0xf, 1);
|
||||
}
|
||||
input.registers(x, initial_value.rotate_left(1));
|
||||
}
|
||||
Chip8CpuInstructions::SubnVxVy(x,y) => {
|
||||
// 8xy7 - SUBN Vx, Vy
|
||||
// Set Vx = Vy - Vx, set VF = NOT borrow.
|
||||
//
|
||||
// If Vy > Vx, then VF is set to 1, otherwise 0. Then Vx is subtracted from Vy, and the results stored in Vx.
|
||||
let y_register = input.registers.peek(y);
|
||||
let x_register = input.registers.peek(x);
|
||||
let new_value = if y_register > x_register { 1 } else { 0 };
|
||||
input.registers.poke(0xf, new_value);
|
||||
input.registers.poke(x, x_register - y_register);
|
||||
}
|
||||
|
||||
Chip8CpuInstructions::ShlVxVy(x, y) => {
|
||||
// 8xyE - SHL Vx {, Vy}
|
||||
// Set Vx = Vx SHL 1.
|
||||
//
|
||||
// If the most-significant bit of Vx is 1, then VF is set to 1, otherwise to 0. Then Vx is multiplied by 2.
|
||||
|
||||
let initial_value = input.registers.peek(*x as u8);
|
||||
if 0x80 & initial_value == 0x80 {
|
||||
input.registers.poke(0xf, 1);
|
||||
}
|
||||
input.registers(x, initial_value.rotate_left(1));
|
||||
}
|
||||
Chip8CpuInstructions::SneVxVy(vx_register, vy_register) => {
|
||||
// 9xy0 - SNE Vx, Vy
|
||||
// Skip next instruction if Vx != Vy.
|
||||
//
|
||||
// The values of Vx and Vy are compared, and if they are not equal, the program counter is increased by 2.
|
||||
|
||||
let x_reg_value = input.registers.peek(*vx_register as u8);
|
||||
let y_reg_value = input.registers.peek(*vy_register as u8);
|
||||
if x_reg_value != y_reg_value {
|
||||
@ -458,15 +499,40 @@ impl Chip8CpuInstructions {
|
||||
}
|
||||
}
|
||||
Chip8CpuInstructions::LdIAddr(new_index) => {
|
||||
// Annn - LD I, addr
|
||||
// Set I = nnn.
|
||||
//
|
||||
// The value of register I is set to nnn.
|
||||
input.registers.poke_i(input.registers.peek(*new_index as u8) as u16);
|
||||
}
|
||||
// 0xBnnn Jump to nnn+V0
|
||||
Chip8CpuInstructions::JpV0Addr(_) => {}
|
||||
Chip8CpuInstructions::JpV0Addr(addr) => {
|
||||
// Bnnn - JP V0, addr
|
||||
// Jump to location nnn + V0.
|
||||
//
|
||||
// The program counter is set to nnn plus the value of V0.
|
||||
let x_reg = input.registers.peek(0);
|
||||
input.registers.poke_pc(x_reg + addr);
|
||||
}
|
||||
Chip8CpuInstructions::RndVxByte(x, byte) => {
|
||||
// Cxkk - RND Vx, byte
|
||||
// Set Vx = random byte AND kk.
|
||||
//
|
||||
// The interpreter generates a random number from 0 to 255, which is then ANDed with the value kk. The results are stored in Vx. See instruction 8xy2 for more information on AND.
|
||||
|
||||
let new_value: u8 = random() ;
|
||||
input.registers.poke(*x as u8, (new_value & *byte as u8))
|
||||
}
|
||||
Chip8CpuInstructions::DrawVxVyNibble(x, y, n) => {
|
||||
// Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
|
||||
// The interpreter reads n bytes from memory, starting at the address stored in I.
|
||||
// These bytes are then displayed as sprites on screen at coordinates (Vx, Vy).
|
||||
// Sprites are XORed onto the existing screen.
|
||||
// If this causes any pixels to be erased, VF is set to 1,
|
||||
// otherwise it is set to 0.
|
||||
// If the sprite is positioned so part of it is outside the coordinates of the display,
|
||||
// it wraps around to the opposite side of the screen.
|
||||
//
|
||||
// read nibble bytes from memory starting at I
|
||||
|
||||
let mut did_change: bool = false;
|
||||
@ -483,19 +549,89 @@ impl Chip8CpuInstructions {
|
||||
input.registers.poke(0x10, 0u8);
|
||||
}
|
||||
}
|
||||
Chip8CpuInstructions::SkpVx(_) => {}
|
||||
Chip8CpuInstructions::SnkpVx(_) => {}
|
||||
Chip8CpuInstructions::LdVxDt(_) => {}
|
||||
Chip8CpuInstructions::LdVxK(_) => {}
|
||||
Chip8CpuInstructions::LdDtVx(_) => {}
|
||||
Chip8CpuInstructions::LdStVx(_) => {}
|
||||
Chip8CpuInstructions::AddIVx(_) => {}
|
||||
Chip8CpuInstructions::LdFVx(_) => {}
|
||||
Chip8CpuInstructions::LdBVx(_) => {}
|
||||
Chip8CpuInstructions::LdIVx(x) => {
|
||||
input.registers.poke(*x as u8, input.registers.peek_i() as u8);
|
||||
Chip8CpuInstructions::SkpVx(x) => {
|
||||
// Ex9E - SKP Vx
|
||||
// Skip next instruction if key with the value of Vx is pressed.
|
||||
//
|
||||
// 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);
|
||||
|
||||
|
||||
}
|
||||
Chip8CpuInstructions::SnkpVx(x) => {
|
||||
|
||||
// ExA1 - SKNP Vx
|
||||
// Skip next instruction if key with the value of Vx is not pressed.
|
||||
//
|
||||
// Checks the keyboard, and if the key corresponding to the value of Vx is currently in the up position, PC is increased by 2.
|
||||
|
||||
|
||||
}
|
||||
Chip8CpuInstructions::LdVxDt(x) => {
|
||||
// Fx07 - LD Vx, DT
|
||||
// Set Vx = delay timer value.
|
||||
//
|
||||
// The value of DT is placed into Vx.
|
||||
input.registers.poke(x, input.delay_timer.current());
|
||||
}
|
||||
Chip8CpuInstructions::LdVxK(x) => {
|
||||
// Fx0A - LD Vx, K
|
||||
// Wait for a key press, store the value of the key in Vx.
|
||||
//
|
||||
// All execution stops until a key is pressed, then the value of that key is stored in Vx.
|
||||
}
|
||||
Chip8CpuInstructions::LdDtVx(new_time) => {
|
||||
// Fx15 - LD DT, Vx
|
||||
// Set delay timer = Vx.
|
||||
//
|
||||
// DT is set equal to the value of Vx.
|
||||
input.delay_timer.set_timer(new_time);
|
||||
}
|
||||
Chip8CpuInstructions::LdStVx(new_time) => {
|
||||
input.sound_timer.set_timer(new_time);
|
||||
}
|
||||
Chip8CpuInstructions::AddIVx(x) => {
|
||||
// Fx1E - ADD I, Vx
|
||||
// Set I = I + Vx.
|
||||
//
|
||||
// The values of I and Vx are added, and the results are stored in I.
|
||||
let base = input.registers.peek_i();
|
||||
let x_value = input.registers.peek(x);
|
||||
input.registers.poke_i( base + x_value);
|
||||
}
|
||||
Chip8CpuInstructions::LdFVx(x) => {
|
||||
// Fx29 - LD F, Vx
|
||||
// Set I = location of sprite for digit Vx.
|
||||
//
|
||||
// The value of I is set to the location for the hexadecimal sprite corresponding to the value of Vx. See section 2.4, Display, for more information on the Chip-8 hexadecimal font.
|
||||
|
||||
}
|
||||
Chip8CpuInstructions::LdBVx(x) => {
|
||||
// Fx33 - LD B, Vx
|
||||
// Store BCD representation of Vx in memory locations I, I+1, and I+2.
|
||||
//
|
||||
// The interpreter takes the decimal value of Vx, and places the hundreds digit in memory at location in I, the tens digit at location I+1, and the ones digit at location I+2.
|
||||
|
||||
}
|
||||
Chip8CpuInstructions::LdIVx(x) => {
|
||||
// Store registers V0 through Vx in memory starting at location I.
|
||||
//
|
||||
// The interpreter copies the values of registers V0 through Vx into memory, starting at the address in I.
|
||||
let offset = input.registers.peek_i();
|
||||
for i in 0..x {
|
||||
input.memory.poke(offset + i, input.registers.peek(i));
|
||||
}
|
||||
}
|
||||
Chip8CpuInstructions::LdVxI(x) => {
|
||||
// Read registers V0 through Vx from memory starting at location I.
|
||||
//
|
||||
// The interpreter reads values from memory starting at location I into registers V0 through Vx.
|
||||
let offset = input.registers.peek_i();
|
||||
let num_loops = input.registers.peek(x);
|
||||
for index in 0..num_loops {
|
||||
input.registers.poke(index, input.memory.peek(index + offset));
|
||||
}
|
||||
}
|
||||
Chip8CpuInstructions::LdVxI(_) => {}
|
||||
Chip8CpuInstructions::XXXXERRORINSTRUCTION => {}
|
||||
};
|
||||
*input
|
||||
@ -513,7 +649,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encoder_test() {
|
||||
fn encode_decode_test() {
|
||||
assert_eq!(Chip8CpuInstructions::CLS.encode(), 0x00E0);
|
||||
assert_eq!(Chip8CpuInstructions::RET.encode(), 0x00EE);
|
||||
assert_eq!(Chip8CpuInstructions::SysAddr(0x123).encode(), 0x0123);
|
||||
@ -549,10 +685,6 @@ mod test {
|
||||
assert_eq!(Chip8CpuInstructions::LdBVx(0xd).encode(), 0xfd33);
|
||||
assert_eq!(Chip8CpuInstructions::LdIVx(0xe).encode(), 0xfe55);
|
||||
assert_eq!(Chip8CpuInstructions::LdVxI(0x3).encode(), 0xf365);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decoder_test() {
|
||||
assert!(matches!( Chip8CpuInstructions::decode(0x00E0u16), Chip8CpuInstructions::CLS));
|
||||
assert!(matches!( Chip8CpuInstructions::decode(0x00EEu16), Chip8CpuInstructions::RET));
|
||||
assert!(matches!(Chip8CpuInstructions::decode(0x0123), Chip8CpuInstructions::SysAddr(0x123)));
|
||||
@ -703,20 +835,157 @@ mod test {
|
||||
#[test]
|
||||
fn AddVxByte_test() {
|
||||
// 0x7xkk Set Vx = Vx + kk
|
||||
let x = Chip8Computer::new();
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(0x01, 0x01).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(0x02, 0x02).execute(&mut x);
|
||||
assert_eq!(x.registers.peek_pc(), 0x204);
|
||||
Chip8CpuInstructions::AddVxVy(0x01, 0x02).execute(&mut x);
|
||||
assert_eq!(x.registers.peek(1), 0x03);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn LdVxVy_test() {
|
||||
// 0x8xy0 Set value of Vy in Vx
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(0x01, 0x01).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(0x02, 0x02).execute(&mut x);
|
||||
assert_eq!(x.registers.peek_pc(), 0x204);
|
||||
assert_eq!(x.registers.peek(1), 0x01);
|
||||
Chip8CpuInstructions::LdVxVy(0x01, 0x02).execute(&mut x);
|
||||
assert_eq!(x.registers.peek(1), 0x02);
|
||||
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn LdVxVy_test() {}
|
||||
fn OrVxVy_test() {
|
||||
// 0x8xy1 Set Vx = Vx OR Vy
|
||||
// 0b0101 0000 (0x50)
|
||||
// | 0b0000 1010 (0x0A)
|
||||
// 0b0101 1010 (0x5A)
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(1, 0x50).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(2, 0x0A).execute(&mut x);
|
||||
Chip8CpuInstructions::OrVxVy(1,2).execute(&mut x);
|
||||
assert_eq!(x.registers.peek(1), 0x5A);
|
||||
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn OrVxVy_test() {}
|
||||
fn AndVxVy_test() {
|
||||
// 0x8xy2 Set Vx = Vx AND Vy
|
||||
// 0b1111 1100 (0xFC)
|
||||
// & 0b1100 1010 (0xCA)
|
||||
// 0b1100 1000 (0xC8)
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(1, 0xFC).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(2, 0xCA).execute(&mut x);
|
||||
Chip8CpuInstructions::AndVxVy(1,2).execute(&mut x);
|
||||
assert_eq!(x.registers.peek(1), 0xC8);
|
||||
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn AndVxVy_test() {}
|
||||
fn XorVxVy_test() {
|
||||
// 0x8xy3 Set Vx = Vx XOR Vy
|
||||
// 0b1111 1100 (0xFC)
|
||||
// ^ 0b1100 1010 (0xCA)
|
||||
// 0b0011 0110 (0x36)
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(1, 0xFC).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(2, 0xCA).execute(&mut x);
|
||||
Chip8CpuInstructions::XorVxVy(1,2).execute(&mut x);
|
||||
assert_eq!(x.registers.peek(1), 0x36);
|
||||
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn XorVxVy_test() {}
|
||||
fn AddVxVy_test() {
|
||||
// 0x8xy4 Set Vx = Vx + Vy (SET VF on Carry)
|
||||
// T1 T2: Judgement Test
|
||||
// 0x01 0xFF
|
||||
// + 0x01 0x01
|
||||
// 0x02 F0 0x00 F1
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(0xf, 0x00).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(1, 0x01).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(2, 0x01).execute(&mut x);
|
||||
Chip8CpuInstructions::AddVxVy(1, 2).execute(&mut x);
|
||||
// T1
|
||||
assert_eq!(x.registers.peek(0xf), 0);
|
||||
assert_eq!(x.registers.peek(1), 2);
|
||||
assert_eq!(x.registers.peek_pc(), 0x208);
|
||||
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(0xf, 0x00).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(0x1, 0xff).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(0x2, 0x01).execute(&mut x);
|
||||
Chip8CpuInstructions::AddVxVy(1,2).execute(&mut x);
|
||||
// T2
|
||||
assert_eq!(x.registers.peek(0xf), 1);
|
||||
assert_eq!(x.registers.peek(1), 0);
|
||||
assert_eq!(x.registers.peek_pc(), 0x208)
|
||||
}
|
||||
#[test]
|
||||
fn SubVxVy_test() {
|
||||
/*
|
||||
todo: this test sucks. dont have the borrow concept in here.
|
||||
Set Vx = Vx - Vy, set VF = NOT borrow.
|
||||
If Vx > Vy, then VF is set to 1, otherwise 0.
|
||||
Then Vy is subtracted from Vx, and the results stored in Vx.
|
||||
*/
|
||||
let mut x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(1, 0x10).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(2, 0x01).execute(&mut x);
|
||||
Chip8CpuInstructions::LdVxByte(0xf, 0x00).execute(&mut x);
|
||||
Chip8CpuInstructions::SubVxVy(0x1, 0x2).execute(&mut x);
|
||||
|
||||
assert_eq!(x.registers.peek_pc(), 0x208);
|
||||
assert_eq!(x.registers.peek(1), 0xF);
|
||||
assert_eq!(x.registers.peek(0x10), 0);
|
||||
|
||||
}
|
||||
fn ShrVxVy_test() {
|
||||
/*
|
||||
Set Vx = Vx SHR 1.
|
||||
|
||||
If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then Vx is divided by 2.
|
||||
*/
|
||||
let x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(0xf, 0x00);
|
||||
Chip8CpuInstructions::LdVxByte(0x1, 0x08); // 0b0000 1000 (0x08)
|
||||
Chip8CpuInstructions::LdVxByte(0x2, 0x2);
|
||||
Chip8CpuInstructions::ShrVxVy(0x1, 0x2); // 0b0000 0010 (0x02) (Not Set)
|
||||
assert_eq!(x.registers.peek(1), 0x02);
|
||||
assert_eq!(x.registers.peek(0xf), 0);
|
||||
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||
|
||||
let x = Chip8Computer::new();
|
||||
Chip8CpuInstructions::LdVxByte(0xf, 0x00);
|
||||
Chip8CpuInstructions::LdVxByte(0x1, 0x09); // 0b0000 1001 (0x09)
|
||||
Chip8CpuInstructions::LdVxByte(0x2, 0x2);
|
||||
Chip8CpuInstructions::ShrVxVy(0x1, 0x2); // 0b0000 0010 (0x02) (Set)
|
||||
assert_eq!(x.registers.peek(1), 0x02);
|
||||
assert_eq!(x.registers.peek(0xf), 1);
|
||||
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||
}
|
||||
fn SneVxVy_test() {}
|
||||
fn LdiAddr_test() {}
|
||||
fn JpV0Addr_test() {}
|
||||
fn RndVxByte_test() {}
|
||||
fn DrawVxVyNibble_test() {}
|
||||
fn SkpVx_test() {
|
||||
|
||||
}
|
||||
fn SnKpVx_test() {
|
||||
|
||||
}
|
||||
fn LdVxDt() {
|
||||
|
||||
}
|
||||
|
||||
fn LdVxK_test() {}
|
||||
fn LdStVx_test() {}
|
||||
fn LdIVx_test() {}
|
||||
fn LdVxI_test() {}
|
||||
}
|
||||
@ -3,10 +3,19 @@ use ratatui::{
|
||||
widgets::Widget,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Keypad {
|
||||
keys: [bool; 0x10],
|
||||
}
|
||||
|
||||
impl Default for Keypad {
|
||||
fn default() -> Self {
|
||||
Keypad {
|
||||
keys: [ false; 16]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Keypad {
|
||||
pub fn push_key(&mut self, key_index: u8) {
|
||||
self.keys[key_index as usize] = true;
|
||||
|
||||
@ -43,7 +43,7 @@ impl Chip8Registers {
|
||||
self.registers[(register_number - 1) as usize] = value;
|
||||
}
|
||||
|
||||
pub fn peek_pc(&mut self) -> u16 {
|
||||
pub fn peek_pc(&self) -> u16 {
|
||||
self.pc
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user