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(¤t.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(¤t.name), asm)); // ** QUIRKS ** assert!(matches!(as_chip8, quirks_chip8)); assert!(matches!(as_schip, quirks_schip)); assert!(matches!(as_xochip, quirks_xochip)); } }