trevors_chip8_toy/gemma/tests/unit_tests_instructions.rs

629 lines
21 KiB
Rust

use gemma::chip8::instructions::Chip8CpuInstructions;
use gemma::chip8::instructions::Chip8CpuInstructions::*;
use gemma::chip8::quirk_modes::QuirkMode::{Chip8, SChipModern, XOChip};
use gemma::constants::*;
#[derive(Clone)]
struct InstructionTestQuirks {
chip8: Chip8CpuInstructions,
schip: Chip8CpuInstructions,
xochip: Chip8CpuInstructions,
}
#[derive(Clone)]
struct InstructionTest {
name: String,
instruction: Chip8CpuInstructions,
operands: String,
asm: String,
encoded: u16,
quirks: InstructionTestQuirks,
}
#[test]
fn instructions_encode_decode_tests_with_quirks() {
let it = vec![
InstructionTest {
name: INST_SYS.to_string(),
instruction: SYS(0x123),
operands: "0x0123".to_string(),
asm: "SYS 0x0123".to_string(),
encoded: 0x0123,
quirks: InstructionTestQuirks {
chip8: SYS(0x123),
schip: XXXXERRORINSTRUCTION,
xochip: XXXXERRORINSTRUCTION,
},
},
InstructionTest {
name: INST_CLS.to_string(),
instruction: CLS,
asm: "CLS".to_string(),
operands: "".to_string(),
encoded: 0x00E0,
quirks: InstructionTestQuirks {
chip8: CLS,
schip: CLS,
xochip: CLS,
},
},
InstructionTest {
name: INST_RET.to_string(),
instruction: RET,
asm: "RET".to_string(),
operands: "".to_string(),
encoded: 0x00ee,
quirks: InstructionTestQuirks {
chip8: RET,
schip: RET,
xochip: RET,
},
},
InstructionTest {
name: INST_JPX.to_string(),
instruction: JPX(0x1, 0xab),
operands: "0x01, 0x01ab".to_string(),
asm: "JPX 0x01, 0x01ab".to_string(),
encoded: 0xb1ab,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: JPX(0x1, 0xab),
xochip: XXXXERRORINSTRUCTION,
},
},
InstructionTest {
name: INST_CALL.to_string(),
instruction: CALL(0x123),
asm: "CALL 0x0123".to_string(),
encoded: 0x2123,
operands: "0x0123".to_string(),
quirks: InstructionTestQuirks {
chip8: CALL(0x123),
schip: CALL(0x123),
xochip: CALL(0x123),
},
},
InstructionTest {
name: INST_DRW.to_string(),
instruction: DRW(0x01, 0x02, 0x03),
operands: "0x01, 0x02, 0x03".to_string(),
asm: "DRW 0x01, 0x02, 0x03".to_string(),
encoded: 0xd123,
quirks: InstructionTestQuirks {
chip8: DRW(0x1, 0x2, 0x3),
schip: DRW(0x1, 0x2, 0x3),
xochip: DRW(0x1, 0x2, 0x3),
},
},
InstructionTest {
name: INST_JPI.to_string(),
instruction: JPI(0x321),
operands: "0x0321".to_string(),
asm: "JPI 0x0321".to_string(),
encoded: 0xb321,
quirks: InstructionTestQuirks {
chip8: JPI(0x321),
schip: XXXXERRORINSTRUCTION,
xochip: JPI(0x321),
},
},
InstructionTest {
name: INST_SCD.to_string(),
instruction: SCD(0x01),
operands: "0x01".to_string(),
asm: "SCD 0x01".to_string(),
encoded: 0x00c1,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: SCD(0x1),
xochip: SCD(0x1),
},
},
InstructionTest {
name: INST_SCR.to_string(),
instruction: Chip8CpuInstructions::SCR,
operands: "".to_string(),
asm: "SCR".to_string(),
encoded: 0x00FB,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: SCR,
xochip: SCR,
},
},
InstructionTest {
name: INST_SCL.to_string(),
instruction: SCL,
operands: "".to_string(),
asm: "SCL".to_string(),
encoded: 0x00FC,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: SCL,
xochip: SCL,
},
},
InstructionTest {
name: INST_EXIT.to_string(),
instruction: EXIT,
operands: "".to_string(),
asm: "EXIT".to_string(),
encoded: 0x00FD,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: EXIT,
xochip: EXIT,
},
},
InstructionTest {
name: INST_LOW.to_string(),
instruction: LOW,
operands: "".to_string(),
asm: "LOW".to_string(),
encoded: 0x00FE,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: LOW,
xochip: LOW,
},
},
InstructionTest {
name: INST_HIGH.to_string(),
instruction: HIGH,
operands: "".to_string(),
asm: "HIGH".to_string(),
encoded: 0x00FF,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: HIGH,
xochip: HIGH,
},
},
InstructionTest {
name: INST_SEX.to_string(),
instruction: Chip8CpuInstructions::SEX(0x01, 0xfa),
operands: "0x01, 0xfa".to_string(),
asm: "SEX 0x01, 0xfa".to_string(),
encoded: 0x31fa,
quirks: InstructionTestQuirks {
chip8: Chip8CpuInstructions::SEX(0x1, 0xfa),
schip: Chip8CpuInstructions::SEX(0x1, 0xfa),
xochip: Chip8CpuInstructions::SEX(0x1, 0xfa),
},
},
InstructionTest {
name: INST_SNEB.to_string(),
instruction: Chip8CpuInstructions::SNEB(0x01, 0xab),
operands: "0x01, 0xab".to_string(),
asm: "SNEB 0x01, 0xab".to_string(),
encoded: 0x41ab,
quirks: InstructionTestQuirks {
chip8: SNEB(0x01, 0xab),
schip: SNEB(0x01, 0xab),
xochip: SNEB(0x01, 0xab),
},
},
InstructionTest {
name: INST_SEY.to_string(),
instruction: Chip8CpuInstructions::SEY(0x1, 0x2),
operands: "0x1, 0x2".to_string(),
asm: "SEY 0x1, 0x2".to_string(),
encoded: 0x5120,
quirks: InstructionTestQuirks {
chip8: SEY(0x1, 0x2),
schip: SEY(0x1, 0x2),
xochip: SEY(0x1, 0x2),
},
},
InstructionTest {
name: INST_LDR.to_string(),
instruction: LDR(0xa, 0xbe),
operands: "0x0a, 0xbe".to_string(),
asm: "LDR 0x0a, 0xbe".to_string(),
encoded: 0x6abe,
quirks: InstructionTestQuirks {
chip8: LDR(0xa, 0xbe),
schip: LDR(0xa, 0xbe),
xochip: LDR(0xa, 0xbe),
},
},
InstructionTest {
name: INST_ADD.to_string(),
instruction: Chip8CpuInstructions::ADD(0x01, 0xab),
operands: "0x01, 0xab".to_string(),
asm: "ADD 0x01, 0xab".to_string(),
encoded: 0x71ab,
quirks: InstructionTestQuirks {
chip8: ADD(0x01, 0xab),
schip: ADD(0x01, 0xab),
xochip: ADD(0x01, 0xab),
},
},
InstructionTest {
name: INST_LDRK.to_string(),
instruction: Chip8CpuInstructions::LDRK(0x6),
operands: "0x06".to_string(),
asm: "LDRK 0x06".to_string(),
encoded: 0xF60A,
quirks: InstructionTestQuirks {
chip8: Chip8CpuInstructions::LDRK(0x6),
schip: Chip8CpuInstructions::LDRK(0x6),
xochip: Chip8CpuInstructions::LDRK(0x6),
},
},
InstructionTest {
name: INST_ADDI.to_string(),
instruction: Chip8CpuInstructions::ADDI(0x02),
operands: "0x02".to_string(),
asm: "ADDI 0x02".to_string(),
encoded: 0xF21E,
quirks: InstructionTestQuirks {
chip8: ADDI(0x02),
schip: ADDI(0x02),
xochip: ADDI(0x02),
},
},
InstructionTest {
name: INST_ADD.to_string(),
instruction: Chip8CpuInstructions::ADD(0x02, 0x12),
operands: "0x02, 0x12".to_string(),
asm: "ADD 0x02, 0x12".to_string(),
encoded: 0x7212,
quirks: InstructionTestQuirks {
chip8: ADD(0x02, 0x12),
schip: ADD(0x02, 0x12),
xochip: ADD(0x02, 0x12),
},
},
InstructionTest {
name: INST_SCU.to_string(),
instruction: Chip8CpuInstructions::SCU(0x04),
operands: "0x04".to_string(),
asm: "SCU 0x04".to_string(),
encoded: 0x00D4,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: XXXXERRORINSTRUCTION,
xochip: SCU(0x04),
},
},
InstructionTest {
name: INST_ADDR.to_string(),
instruction: ADDR(0x01, 0x02),
operands: "0x1, 0x2".to_string(),
asm: "ADDR 0x1, 0x2".to_string(),
encoded: 0x8124,
quirks: InstructionTestQuirks {
chip8: ADDR(0x01, 0x02),
schip: ADDR(0x01, 0x02),
xochip: ADDR(0x01, 0x02),
},
},
InstructionTest {
name: INST_AND.to_string(),
instruction: AND(0x1, 0x2),
operands: "0x1, 0x2".to_string(),
asm: "AND 0x1, 0x2".to_string(),
encoded: 0x8122,
quirks: InstructionTestQuirks {
chip8: AND(0x1, 0x2),
schip: AND(0x1, 0x2),
xochip: AND(0x1, 0x2),
},
},
InstructionTest {
name: INST_JPA.to_string(),
instruction: JPA(0x345),
operands: "0x0345".to_string(),
asm: "JPA 0x0345".to_string(),
encoded: 0x1345,
quirks: InstructionTestQuirks {
chip8: JPA(0x345),
schip: JPA(0x345),
xochip: JPA(0x345),
},
},
InstructionTest {
name: INST_BCD.to_string(),
instruction: BCD(0xc),
operands: "0x0c".to_string(),
asm: "BCD 0x0c".to_string(),
encoded: 0xfc33,
quirks: InstructionTestQuirks {
chip8: BCD(0xcd),
schip: BCD(0xcd),
xochip: BCD(0xcd),
},
},
InstructionTest {
name: INST_LDD.to_string(),
instruction: LDD(0xfc),
operands: "0xfc".to_string(),
asm: "LDD 0xfc".to_string(),
encoded: 0xfc15,
quirks: InstructionTestQuirks {
chip8: LDD(0xfc),
schip: LDD(0xfc),
xochip: LDD(0xfc),
},
},
InstructionTest {
name: INST_ORY.to_string(),
instruction: ORY(0x01, 0x3),
operands: "0x1, 0x3".to_string(),
asm: "ORY 0x1, 0x3".to_string(),
encoded: 0x8133,
quirks: InstructionTestQuirks {
chip8: ORY(0x01, 0x3),
schip: ORY(0x01, 0x3),
xochip: ORY(0x01, 0x3),
},
},
InstructionTest {
name: INST_SUBC.to_string(),
instruction: Chip8CpuInstructions::SUBC(0x1, 0x2),
operands: "0x1, 0x2".to_string(),
asm: "SUBC 0x1, 0x2".to_string(),
encoded: 0x8127,
quirks: InstructionTestQuirks {
chip8: Chip8CpuInstructions::SUBC(0x1, 0x2),
schip: Chip8CpuInstructions::SUBC(0x1, 0x2),
xochip: Chip8CpuInstructions::SUBC(0x1, 0x2),
},
},
InstructionTest {
name: INST_SUB.to_string(),
instruction: Chip8CpuInstructions::SUB(0x1, 0x2),
operands: "0x1, 0x2".to_string(),
asm: "SUB 0x1, 0x2".to_string(),
encoded: 0x8125,
quirks: InstructionTestQuirks {
chip8: Chip8CpuInstructions::SUB(0x1, 0x2),
schip: Chip8CpuInstructions::SUB(0x1, 0x2),
xochip: Chip8CpuInstructions::SUB(0x1, 0x2),
},
},
InstructionTest {
name: INST_STR.to_string(),
instruction: Chip8CpuInstructions::STR(0x06),
operands: "0x06".to_string(),
asm: "STR 0x06".to_string(),
encoded: 0xf675,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: Chip8CpuInstructions::STR(0x06),
xochip: Chip8CpuInstructions::STR(0x06),
},
},
InstructionTest {
name: INST_OR.to_string(),
instruction: OR(0x01, 0x02),
operands: "0x1, 0x2".to_string(),
asm: "OR 0x1, 0x2".to_string(),
encoded: 0x8121,
quirks: InstructionTestQuirks {
chip8: OR(0x01, 0x02),
schip: OR(0x01, 0x02),
xochip: OR(0x01, 0x02),
},
},
InstructionTest {
name: INST_SHR.to_string(),
instruction: SHR(0x04, 0x4),
operands: "0x4, 0x4".to_string(),
asm: "SHR 0x4, 0x4".to_string(),
encoded: 0x8446,
quirks: InstructionTestQuirks {
chip8: SHR(0x04, 0x4),
schip: SHR(0x04, 0x4),
xochip: SHR(0x04, 0x4),
},
},
InstructionTest {
name: INST_SHL.to_string(),
instruction: SHL(0x04, 0x4),
operands: "0x4, 0x4".to_string(),
asm: "SHL 0x4, 0x4".to_string(),
encoded: 0x844e,
quirks: InstructionTestQuirks {
chip8: SHL(0x04, 0x4),
schip: SHL(0x04, 0x4),
xochip: SHL(0x04, 0x4),
},
},
InstructionTest {
name: INST_RND.to_string(),
instruction: RND(0x01, 0xff),
operands: "0x01, 0xff".to_string(),
asm: "RND 0x01, 0xff".to_string(),
encoded: 0xc1ff,
quirks: InstructionTestQuirks {
chip8: RND(0x01, 0xff),
schip: RND(0x01, 0xff),
xochip: RND(0x01, 0xff),
},
},
InstructionTest {
name: INST_LDRY.to_string(),
instruction: LDRY(0x01, 0x02),
operands: "0x1, 0x2".to_string(),
asm: "LDRY 0x1, 0x2".to_string(),
encoded: 0x8120,
quirks: InstructionTestQuirks {
chip8: LDRY(0x01, 0x02),
schip: LDRY(0x01, 0x02),
xochip: LDRY(0x01, 0x02),
},
},
InstructionTest {
name: INST_LDIS.to_string(),
instruction: LDIS(0x01),
operands: "0x01".to_string(),
asm: "LDIS 0x01".to_string(),
encoded: 0xf118,
quirks: InstructionTestQuirks {
chip8: LDIS(0x01),
schip: LDIS(0x01),
xochip: LDIS(0x01),
},
},
InstructionTest {
name: INST_LIDR.to_string(),
instruction: LIDR(0x01),
operands: "0x01".to_string(),
asm: "LIDR 0x01".to_string(),
encoded: 0xf185,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: LIDR(0x01),
xochip: LIDR(0x01),
},
},
InstructionTest {
name: INST_LDF2.to_string(),
instruction: LDF2(0x01),
operands: "0x01".to_string(),
asm: "LDF2 0x01".to_string(),
encoded: 0xf130,
quirks: InstructionTestQuirks {
chip8: XXXXERRORINSTRUCTION,
schip: LDF2(0x01),
xochip: LDF2(0x01),
},
},
InstructionTest {
name: INST_LDF.to_string(),
instruction: LDFX(0x01),
operands: "0x01".to_string(),
asm: "LDF 0x01".to_string(),
encoded: 0xf129,
quirks: InstructionTestQuirks {
chip8: LDFX(0x01),
schip: LDFX(0x01),
xochip: LDFX(0x01),
},
},
InstructionTest {
name: INST_LDIA.to_string(),
instruction: LDIA(0x01),
operands: "0x0001".to_string(),
asm: "LDIA 0x0001".to_string(),
encoded: 0xa001,
quirks: InstructionTestQuirks {
chip8: LDIA(0x01),
schip: LDIA(0x01),
xochip: LDIA(0x01),
},
},
InstructionTest {
name: INST_LDIX.to_string(),
instruction: LDIX(0x01),
operands: "0x01".to_string(),
asm: "LDIX 0x01".to_string(),
encoded: 0xf155,
quirks: InstructionTestQuirks {
chip8: LDIX(0x01),
schip: LDIX(0x01),
xochip: LDIX(0x01),
},
},
InstructionTest {
name: INST_LDRD.to_string(),
instruction: Chip8CpuInstructions::LDRD(0x01),
operands: "0x01".to_string(),
asm: "LDRD 0x01".to_string(),
encoded: 0xf107,
quirks: InstructionTestQuirks {
chip8: Chip8CpuInstructions::LDRD(0x01),
schip: Chip8CpuInstructions::LDRD(0x01),
xochip: Chip8CpuInstructions::LDRD(0x01),
},
},
InstructionTest {
name: INST_LDRI.to_string(),
instruction: Chip8CpuInstructions::LDRI(0x01),
operands: "0x01".to_string(),
asm: "LDRI 0x01".to_string(),
encoded: 0xf165,
quirks: InstructionTestQuirks {
chip8: Chip8CpuInstructions::LDRI(0x01),
schip: Chip8CpuInstructions::LDRI(0x01),
xochip: Chip8CpuInstructions::LDRI(0x01),
},
},
InstructionTest {
name: INST_SKP.to_string(),
instruction: SKP(0x01),
operands: "0x01".to_string(),
asm: "SKP 0x01".to_string(),
encoded: 0xe19e,
quirks: InstructionTestQuirks {
chip8: SKP(0x01),
schip: SKP(0x01),
xochip: SKP(0x01),
},
},
InstructionTest {
name: INST_SNEY.to_string(),
instruction: SNEY(0x01, 0x1),
operands: "0x1, 0x1".to_string(),
asm: "SNEY 0x1, 0x1".to_string(),
encoded: 0x9110,
quirks: InstructionTestQuirks {
chip8: SNEY(0x01, 0x1),
schip: SNEY(0x01, 0x1),
xochip: SNEY(0x01, 0x1),
},
},
InstructionTest {
name: INST_SKNP.to_string(),
instruction: SKNP(0x01),
operands: "0x01".to_string(),
asm: "SKNP 0x01".to_string(),
encoded: 0xe1a1,
quirks: InstructionTestQuirks {
chip8: SKNP(0x01),
schip: SKNP(0x01),
xochip: SKNP(0x01),
},
},
];
for current in it {
let instruction = current.clone().instruction;
let asm = Chip8CpuInstructions::from_str(&current.asm);
let as_chip8 = Chip8CpuInstructions::decode(current.encoded, &Chip8);
let quirks_chip8 = current.quirks.chip8;
let as_schip = Chip8CpuInstructions::decode(current.encoded, &SChipModern);
let quirks_schip = current.quirks.schip;
let as_xochip = Chip8CpuInstructions::decode(current.encoded, &XOChip);
let quirks_xochip = current.quirks.xochip;
// ** CONVERSION **
// -> Integer to Instruction
assert!(matches!(
Chip8CpuInstructions::decode(current.encoded, &Chip8),
i
));
// -> Instruction to Integer
println!(
"TESTING INSTRUCTION TO INTEGER FOR {:?} / {:04x} {:04x}",
current.instruction,
current.encoded,
instruction.encode()
);
assert_eq!(current.encoded, instruction.encode());
// -> Instruction to String
assert_eq!(instruction.to_string(), current.asm);
assert_eq!(instruction.operands(), current.operands);
assert_eq!(current.instruction.name(), current.name);
// -> String to Instruction
assert!(matches!(Chip8CpuInstructions::from_str(&current.name), asm));
// ** QUIRKS **
assert!(matches!(as_chip8, quirks_chip8));
assert!(matches!(as_schip, quirks_schip));
assert!(matches!(as_xochip, quirks_xochip));
}
}