typedef enum { C8_ILL, /* Onnn = 0,1,2,A,B */ /* 00E0 - CLS */ C8_CLS, /* 00EE - RET */ C8_RET, /* 0nnn - SYS addr */ C8_SYS, /* 1nnn - JP addr */ C8_JP, /* 2nnn - CALL addr */ C8_CALL, /* Annn - LD I, addr */ C8_LDI, /* Bnnn - JP V0, addr */ C8_JPV, /* Oxkk = 3,4,6,7,C,E,F */ /* 3xkk - SE Vx, byte */ C8_SEB, /* 4xkk - SNE Vx, byte */ C8_SNEB, /* 6xkk - LD Vx, byte */ C8_LD, /* 7xkk - ADD Vx, byte */ C8_ADDB, /* Cxkk - RND Vx, byte */ C8_RND, /* Ex9E - SKP Vx */ C8_SKP, /* ExA1 - SKNP Vx */ C8_SKNP, /* Fx07 - LD Vx, DT */ C8_MVDT, /* Fx0A - LD Vx, K */ C8_LDK, /* Fx15 - LD DT, Vx */ C8_LDDT, /* Fx18 - LD ST, Vx */ C8_LDST, /* Fx1E - ADD I, Vx */ C8_ADDI, /* Fx29 - LD F, Vx */ C8_HEX, /* Fx33 - LD B, Vx */ C8_BCD, /* Fx55 - LD [I], Vx */ C8_SAVE, /* Fx65 - LD Vx, [I] */ C8_RESTORE, /* Oxyn = 5,8,9,D */ /* 5xy0 - SE Vx, Vy */ C8_SE, /* 8xy0 - LD Vx, Vy */ C8_MOVE, /* 8xy1 - OR Vx, Vy */ C8_OR, /* 8xy2 - AND Vx, Vy */ C8_AND, /* 8xy3 - XOR Vx, Vy */ C8_XOR, /* 8xy4 - ADD Vx, Vy */ C8_ADD, /* 8xy5 - SUB Vx, Vy */ C8_SUB, /* 8xy6 - SHR Vx {, Vy} */ C8_SHR, /* 8xy7 - SUBN Vx, Vy */ C8_SUBN, /* 8xyE - SHL Vx {, Vy} */ C8_SHL, /* 9xy0 - SNE Vx, Vy */ C8_SNE, /* Dxyn - DRW Vx, Vy, nibble */ C8_DRW, C8_OP_CNT } chip8_op; typedef void (*instr_func)(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 n, u8 kk); const char* chip8_disasm_fmts[C8_OP_CNT] = { "ILL unknown", "CLS", "RET", "SYS %03X", "JP %03X", "CALL %03X", "LD I, %03X", "JP V0, %03X", "SE V%-2x, %-2d", "SNE V%-2x, %-2d", "LD V%-2x, %-2d", "ADD V%-2x, %-2d", "RND V%-2x, %-2d", "SKP V%-2x", "SKNP V%-2x", "LD V%-2x, DT", "LD V%-2x, K", "LD DT, V%-2x", "LD ST, V%-2x", "ADD I, V%-2x", "LD F, V%-2x", "LD B, V%-2x", "LD [I], V%-2x", "LD V%-2x, [I]", "SE V%-2x, V%-2x", "LD V%-2x, V%-2x", "OR V%-2x, V%-2x", "AND V%-2x, V%-2x", "XOR V%-2x, V%-2x", "ADD V%-2x, V%-2x", "SUB V%-2x, V%-2x", "SHR V%-2x, V%-2x", "SUBN V%-2x, V%-2x", "SHL V%-2x, V%-2x", "SNE V%-2x, V%-2x", "DRW V%-2x, V%-2x, %-1d" }; void c8_decode(u8* code, u16 offset, instr_func func, chip8* c8); void c8_disasm(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 n, u8 kk); void c8_do(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 n, u8 kk); void c8_decode(u8* code, u16 offset, instr_func func, chip8* c8) { chip8_op op = C8_ILL; u16 word, instr, nnn; u8 o, x, y, n, kk; word = *(u16*)(code + offset); instr = be16toh(word); o = (instr & 0xF000) >> 12; nnn = (instr & 0x0FFF); x = (instr & 0x0F00) >> 8; y = (instr & 0x00F0) >> 4; n = (instr & 0x000F); kk = (instr & 0x00FF); if(o == 0 && nnn == 0x0E0) op = C8_CLS; else if(o == 0 && nnn == 0x0EE) op = C8_RET; else if(o == 0) op = C8_SYS; else if(o == 1) op = C8_JP; else if(o == 2) op = C8_CALL; else if(o == 0xA) op = C8_LDI; else if(o == 0xB) op = C8_JPV; else if(o == 3) op = C8_SEB; else if(o == 4) op = C8_SNEB; else if(o == 6) op = C8_LD; else if(o == 7) op = C8_ADDB; else if(o == 0xC) op = C8_RND; else if(o == 0xE && kk == 0x9E) op = C8_SKP; else if(o == 0xE && kk == 0xA1) op = C8_SKNP; else if(o == 0xF && kk == 0x07) op = C8_MVDT; else if(o == 0xF && kk == 0x0A) op = C8_LDK; else if(o == 0xF && kk == 0x15) op = C8_LDDT; else if(o == 0xF && kk == 0x18) op = C8_LDST; else if(o == 0xF && kk == 0x1E) op = C8_ADDI; else if(o == 0xF && kk == 0x29) op = C8_HEX; else if(o == 0xF && kk == 0x33) op = C8_BCD; else if(o == 0xF && kk == 0x55) op = C8_SAVE; else if(o == 0xF && kk == 0x65) op = C8_RESTORE; else if(o == 5 && n == 0) op = C8_SE; else if(o == 8 && n == 0) op = C8_MOVE; else if(o == 8 && n == 1) op = C8_OR; else if(o == 8 && n == 2) op = C8_AND; else if(o == 8 && n == 3) op = C8_XOR; else if(o == 8 && n == 4) op = C8_ADD; else if(o == 8 && n == 5) op = C8_SUB; else if(o == 8 && n == 6) op = C8_SHR; else if(o == 8 && n == 7) op = C8_SUBN; else if(o == 8 && n == 0xE) op = C8_SHL; else if(o == 9 && n == 0) op = C8_SNE; else if(o == 0xD) op = C8_DRW; func(c8, op, nnn, x, y, n, kk); } void c8_disasm(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 kk, u8 n); void c8_do(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 kk, u8 n);