[cpu] decode remaining alu instructions

This commit is contained in:
2024-03-04 18:38:48 +05:30
parent ffae4347b4
commit 7d1e684fc6

View File

@@ -84,22 +84,25 @@ impl Instruction {
Instruction::ConditionalInEqSkipNext(register as usize, val as u8)
}
0x5 => {
let registerx = (instruction & 0xf00) >> 8;
let registery = (instruction & 0xf0) >> 4;
let register_x = (instruction & 0xf00) >> 8;
let register_y = (instruction & 0xf0) >> 4;
Instruction::ConditionalEqRegisterSkipNext(registerx as usize, registery as usize)
Instruction::ConditionalEqRegisterSkipNext(register_x as usize, register_y as usize)
}
0x6 => {
Instruction::SetRegister(((instruction & 0x0f00) >> 8) as usize, (instruction & 0xff) as u8)
}
0x7 => {
Instruction::AddValueToRegister(((instruction & 0x0f00) >> 8) as usize, (instruction & 0xff) as u8)
},
0x8=>{
Self::decode_arithmetic_instruction(instruction)
}
0x9 =>{
let registerx = (instruction & 0xf00) >> 8;
let registery = (instruction & 0xf0) >> 4;
let register_x = (instruction & 0xf00) >> 8;
let register_y = (instruction & 0xf0) >> 4;
Instruction::ConditionalInEqRegisterSkipNext(registerx as usize, registery as usize)
Instruction::ConditionalInEqRegisterSkipNext(register_x as usize, register_y as usize)
}
0xA => {
Instruction::SetIndex(instruction & 0xfff)
@@ -110,14 +113,51 @@ impl Instruction {
let n = instruction & 0xf;
Instruction::Draw(x as usize, y as usize, n as u8)
}
0x8 => {
todo!("Arithmetic instructions pending")
}
_ => {
todo!("Unimplemented instruction")
}
}
}
fn decode_arithmetic_instruction(instruction: u16) ->Instruction{
assert_eq!(instruction&0xF000,0x8000);
let reg_x = ((instruction & 0xf00 )>>8) as usize;
let reg_y = ((instruction & 0xf0) >> 4) as usize;
let operation = instruction & 0xf;
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)
}
_=>{
log::error!("Encountered unexpected alu instruction {}",instruction);
Instruction::PassThrough
}
}
}
}
#[cfg(test)]
@@ -231,4 +271,59 @@ mod tests {
let ins = Instruction::decode_instruction(&instruction_bytes);
assert_eq!(ins, Draw(0xf, 0xa, 0xb))
}
#[test]
fn test_alu_set(){
let instruction_bytes = 0x8a50_u16.to_be_bytes();
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))
}
}