[cpu] Add Decode for keypress instructions
This commit is contained in:
@@ -103,9 +103,32 @@ impl Device {
|
||||
let toggle_state = self.draw_sprite_at_location(x, y, n);
|
||||
self.set_flag_register(toggle_state);
|
||||
},
|
||||
remaining=>{
|
||||
log::error!("Unimplemented instruction {:?}",remaining);
|
||||
Instruction::JumpAndLink(jump_location) => {
|
||||
self.stack.push(self.registers.pc);
|
||||
self.registers.pc = jump_location;
|
||||
}
|
||||
Instruction::ReturnFromProcedure =>{
|
||||
let old_pc = self.stack.pop().expect("Expected value on stack pop");
|
||||
self.registers.pc = old_pc;
|
||||
}
|
||||
|
||||
Instruction::ConditionalEqSkipNext(_, _) => {}
|
||||
Instruction::ConditionalInEqSkipNext(_, _) => {}
|
||||
Instruction::ConditionalEqRegisterSkipNext(_, _) => {}
|
||||
Instruction::ConditionalInEqRegisterSkipNext(_, _) => {}
|
||||
Instruction::JumpWithOffset(_, _) => {}
|
||||
Instruction::RandomOr(_, _) => {}
|
||||
Instruction::SkipIfKeyPressed(_) => {}
|
||||
Instruction::SkipIfKeyNotPressed(_) => {}
|
||||
Instruction::Set(_, _) => {}
|
||||
Instruction::Or(_, _) => {}
|
||||
Instruction::And(_, _) => {}
|
||||
Instruction::Xor(_, _) => {}
|
||||
Instruction::Add(_, _) => {}
|
||||
Instruction::Sub(_, _) => {}
|
||||
Instruction::RShift(_, _) => {}
|
||||
Instruction::RSub(_, _) => {}
|
||||
Instruction::LShift(_, _) => {}
|
||||
};
|
||||
}
|
||||
///
|
||||
|
@@ -33,6 +33,10 @@ pub enum Instruction {
|
||||
/// DXYN - Draw pixels at xy pointed by register for n bytes long
|
||||
Draw(usize, usize, u8),
|
||||
|
||||
/// EX9E - Check if key is pressed
|
||||
SkipIfKeyPressed(usize),
|
||||
/// EXA1 - Check if key is not pressed
|
||||
SkipIfKeyNotPressed(usize),
|
||||
|
||||
// ALU operations going ahead
|
||||
/// 8XY0 - x=y
|
||||
@@ -98,7 +102,7 @@ impl Instruction {
|
||||
}
|
||||
0x7 => {
|
||||
Instruction::AddValueToRegister(((instruction & 0x0f00) >> 8) as usize, (instruction & 0xff) as u8)
|
||||
},
|
||||
}
|
||||
0x8 => {
|
||||
Self::decode_arithmetic_instruction(instruction)
|
||||
}
|
||||
@@ -127,6 +131,14 @@ impl Instruction {
|
||||
let n = instruction & 0xf;
|
||||
Instruction::Draw(x as usize, y as usize, n as u8)
|
||||
}
|
||||
0xE if (instruction & 0xff) == 0x9e => {
|
||||
let x = (instruction & 0xf00) >> 8;
|
||||
Instruction::SkipIfKeyPressed(x as usize)
|
||||
},
|
||||
0xE if (instruction & 0xff) == 0xa1 => {
|
||||
let x = (instruction & 0xf00) >> 8;
|
||||
Instruction::SkipIfKeyNotPressed(x as usize)
|
||||
}
|
||||
_ => {
|
||||
todo!("Unimplemented instruction")
|
||||
}
|
||||
@@ -141,28 +153,28 @@ impl Instruction {
|
||||
match operation {
|
||||
0 => {
|
||||
Instruction::Set(reg_x, reg_y)
|
||||
},
|
||||
}
|
||||
1 => {
|
||||
Instruction::Or(reg_x, reg_y)
|
||||
},
|
||||
}
|
||||
2 => {
|
||||
Instruction::And(reg_x, reg_y)
|
||||
},
|
||||
}
|
||||
3 => {
|
||||
Instruction::Xor(reg_x, reg_y)
|
||||
},
|
||||
}
|
||||
4 => {
|
||||
Instruction::Add(reg_x, reg_y)
|
||||
},
|
||||
}
|
||||
5 => {
|
||||
Instruction::Sub(reg_x, reg_y)
|
||||
},
|
||||
}
|
||||
6 => {
|
||||
Instruction::RShift(reg_x, reg_y)
|
||||
}
|
||||
7 => {
|
||||
Instruction::RSub(reg_x, reg_y)
|
||||
},
|
||||
}
|
||||
0xe => {
|
||||
Instruction::LShift(reg_x, reg_y)
|
||||
}
|
||||
@@ -265,6 +277,7 @@ mod tests {
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, AddValueToRegister(15, 0x23));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conditional_register_in_equal_skip() {
|
||||
let instruction_bytes = 0x9af0_u16.to_be_bytes();
|
||||
@@ -278,6 +291,7 @@ mod tests {
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, SetIndex(0xfaf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_jump_with_offset() {
|
||||
let instruction_bytes = 0xbfae_u16.to_be_bytes();
|
||||
@@ -293,8 +307,6 @@ mod tests {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_draw() {
|
||||
let instruction_bytes = 0xdfab_u16.to_be_bytes();
|
||||
@@ -308,52 +320,73 @@ mod tests {
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, Set(0xa, 0x5))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_or() {
|
||||
let instruction_bytes = 0x85a1_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, Or(0x5, 0xa))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_and() {
|
||||
let instruction_bytes = 0x8ba2_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, And(0xb, 0xa))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_xor() {
|
||||
let instruction_bytes = 0x8ab3_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, Xor(0xa, 0xb))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_add() {
|
||||
let instruction_bytes = 0x8ed4_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, Add(0xe, 0xd))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_sub() {
|
||||
let instruction_bytes = 0x8ed5_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, Sub(0xe, 0xd))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_r_sub() {
|
||||
let instruction_bytes = 0x8517_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, RSub(0x5, 0x1))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_right_shift() {
|
||||
let instruction_bytes = 0x89a6_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, RShift(0x9, 0xa))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alu_left_shift() {
|
||||
let instruction_bytes = 0x812e_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, LShift(0x1, 0x2))
|
||||
}
|
||||
#[test]
|
||||
fn test_skip_if_keypress(){
|
||||
let instruction_bytes = 0xef9e_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, SkipIfKeyPressed(0xf))
|
||||
}
|
||||
#[test]
|
||||
fn test_skip_if_not_keypress(){
|
||||
let instruction_bytes = 0xeba1_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, SkipIfKeyNotPressed(0xb))
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user