Rizin
unix-like reverse engineering framework and cli tools
asm_chip8.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017-2018 maijin <maijin21@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_asm.h>
5 #include <rz_lib.h>
6 
7 static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l) {
8  ut16 opcode = rz_read_be16(b);
9  uint8_t x = (opcode >> 8) & 0x0F;
10  uint8_t y = (opcode >> 4) & 0x0F;
11  uint8_t nibble = opcode & 0x0F;
12  uint16_t nnn = opcode & 0x0FFF;
13  uint8_t kk = opcode & 0xFF;
14  const char *buf_asm = "invalid";
15  switch (opcode & 0xF000) {
16  case 0x0000:
17  if (opcode == 0x00E0) {
18  buf_asm = "cls";
19  } else if (opcode == 0x00EE) {
20  buf_asm = "ret";
21  } else if ((opcode & 0xFFF0) == 0x00C0) {
22  buf_asm = sdb_fmt("scd 0x%01x", nibble);
23  } else if (opcode == 0x00FB) {
24  buf_asm = "scr";
25  } else if (opcode == 0x00FC) {
26  buf_asm = "scl";
27  } else if (opcode == 0x00FD) {
28  buf_asm = "exit";
29  } else if (opcode == 0x00FE) {
30  buf_asm = "low";
31  } else if (opcode == 0x00FF) {
32  buf_asm = "high";
33  }
34  break;
35  case 0x1000: buf_asm = sdb_fmt("jp 0x%03x", nnn); break;
36  case 0x2000: buf_asm = sdb_fmt("call 0x%03x", nnn); break;
37  case 0x3000: buf_asm = sdb_fmt("se v%1x, 0x%02x", x, kk); break;
38  case 0x4000: buf_asm = sdb_fmt("sne v%1x, 0x%02x", x, kk); break;
39  case 0x5000: buf_asm = sdb_fmt("se v%1x, v%1x", x, y); break;
40  case 0x6000: buf_asm = sdb_fmt("ld v%1x, 0x%02x", x, kk); break;
41  case 0x7000: buf_asm = sdb_fmt("add v%1x, 0x%02x", x, kk); break;
42  case 0x8000: {
43  switch (nibble) {
44  case 0x0: buf_asm = sdb_fmt("ld v%1x, v%1x", x, y); break;
45  case 0x1: buf_asm = sdb_fmt("or v%1x, v%1x", x, y); break;
46  case 0x2: buf_asm = sdb_fmt("and v%1x, v%1x", x, y); break;
47  case 0x3: buf_asm = sdb_fmt("xor v%1x, v%1x", x, y); break;
48  case 0x4: buf_asm = sdb_fmt("add v%1x, v%1x", x, y); break;
49  case 0x5: buf_asm = sdb_fmt("sub v%1x, v%1x", x, y); break;
50  case 0x6: buf_asm = sdb_fmt("shr v%1x, v%1x", x, y); break;
51  case 0x7: buf_asm = sdb_fmt("subn v%1x, v%1x", x, y); break;
52  case 0xE: buf_asm = sdb_fmt("shl v%1x, v%1x", x, y); break;
53  }
54  } break;
55  case 0x9000: buf_asm = sdb_fmt("sne v%1x, v%1x", x, y); break;
56  case 0xA000: buf_asm = sdb_fmt("ld i, 0x%03x", nnn); break;
57  case 0xB000: buf_asm = sdb_fmt("jp v0, 0x%03x", nnn); break;
58  case 0xC000: buf_asm = sdb_fmt("rnd v%1x, 0x%02x", x, kk); break;
59  case 0xD000: buf_asm = sdb_fmt("drw v%1x, v%1x, 0x%01x", x, y, nibble); break;
60  case 0xE000: {
61  if (kk == 0x9E) {
62  buf_asm = sdb_fmt("skp v%1x", x);
63  } else if (kk == 0xA1) {
64  buf_asm = sdb_fmt("sknp v%1x", x);
65  }
66  } break;
67  case 0xF000: {
68  switch (kk) {
69  case 0x07: buf_asm = sdb_fmt("ld v%1x, dt", x); break;
70  case 0x0A: buf_asm = sdb_fmt("ld v%1x, k", x); break;
71  case 0x15: buf_asm = sdb_fmt("ld dt, v%1x", x); break;
72  case 0x18: buf_asm = sdb_fmt("ld st, v%1x", x); break;
73  case 0x1E: buf_asm = sdb_fmt("add i, v%1x", x); break;
74  case 0x29: buf_asm = sdb_fmt("ld f, v%1x", x); break;
75  case 0x33: buf_asm = sdb_fmt("ld b, v%1x", x); break;
76  case 0x55: buf_asm = sdb_fmt("ld [i], v%1x", x); break;
77  case 0x65: buf_asm = sdb_fmt("ld v%1x, [i]", x); break;
78  case 0x30: buf_asm = sdb_fmt("ld hf, v%1x", x); break;
79  case 0x75: buf_asm = sdb_fmt("ld r, v%1x", x); break;
80  case 0x85: buf_asm = sdb_fmt("ld v%1x, r", x); break;
81  }
82  } break;
83  }
84  rz_strbuf_set(&op->buf_asm, buf_asm);
85  op->size = 2;
86  return op->size;
87 }
88 
90  .name = "chip8",
91  .arch = "chip8",
92  .license = "LGPL3",
93  .bits = 32,
94  .desc = "Chip8 disassembler",
95  .disassemble = &disassemble,
96 };
97 
98 #ifndef RZ_PLUGIN_INCORE
101  .data = &rz_asm_plugin_chip8,
103 };
104 #endif
RzAsmPlugin rz_asm_plugin_chip8
Definition: asm_chip8.c:89
RZ_API RzLibStruct rizin_plugin
Definition: asm_chip8.c:99
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l)
Definition: asm_chip8.c:7
#define RZ_API
uint16_t ut16
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
uint8_t ut8
Definition: lh5801.h:11
int x
Definition: mipsasm.c:20
static ut16 rz_read_be16(const void *src)
Definition: rz_endian.h:50
@ RZ_LIB_TYPE_ASM
Definition: rz_lib.h:72
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
#define RZ_VERSION
Definition: rz_version.h:8
unsigned short uint16_t
Definition: sftypes.h:30
unsigned char uint8_t
Definition: sftypes.h:31
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
const char * name
Definition: rz_asm.h:130
const char * version
Definition: rz_asm.h:133
Definition: dis.c:32