Rizin
unix-like reverse engineering framework and cli tools
i4004dis.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2018 condret <condr3t@protonmail.com>
2 // SPDX-FileCopyrightText: 2014-2018 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_asm.h>
6 #include <rz_types.h>
7 #include <string.h>
8 #include <stdio.h>
9 
10 /* That 3 is a hack */
11 static const int i4004_ins_len[16] = {
12  1, 2, 3, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1
13 };
14 
15 static const char *i4004_e[16] = {
16  "wrm",
17  "wmp",
18  "wrr",
19  "wpm",
20  "wr0",
21  "wr1",
22  "wr2",
23  "wr3",
24  "sbm",
25  "rdm",
26  "rdr",
27  "adm",
28  "rd0",
29  "rd1",
30  "rd2",
31  "rd3"
32 };
33 
34 static const char *i4004_f[16] = {
35  "clb",
36  "clc",
37  "iac",
38  "cmc",
39  "cma",
40  "ral",
41  "rar",
42  "tcc",
43  "dac",
44  "tcs",
45  "stc",
46  "daa",
47  "kbp",
48  "dcl",
49  "invalid",
50  "invalid"
51 };
52 
53 static int i4004_get_ins_len(ut8 hex) {
54  ut8 high = (hex & 0xf0) >> 4;
55  int ret = i4004_ins_len[high];
56  if (ret == 3)
57  ret = (hex & 1) ? 1 : 2;
58  return ret;
59 }
60 
61 static int i4004dis(RzAsmOp *op, const ut8 *buf, int len) {
62  int rlen = i4004_get_ins_len(*buf);
63  ut8 high = (*buf & 0xf0) >> 4;
64  ut8 low = (*buf & 0xf);
65  const char *buf_asm = "invalid";
66  if (rlen > len) {
67  return op->size = 0;
68  }
69  switch (high) {
70  case 0: buf_asm = low ? "invalid" : "nop"; break;
71  case 1: buf_asm = sdb_fmt("jcn %d 0x%02x", low, buf[1]); break;
72  case 2:
73  if (rlen == 1) {
74  buf_asm = sdb_fmt("src r%d", (low & 0xe));
75  } else {
76  buf_asm = sdb_fmt("fim r%d, 0x%02x", (low & 0xe), buf[1]);
77  }
78  break;
79  case 3:
80  if ((low & 1) == 1) {
81  buf_asm = sdb_fmt("jin r%d", (low & 0xe));
82  } else {
83  buf_asm = sdb_fmt("fin r%d", (low & 0xe));
84  }
85  break;
86  case 4: buf_asm = sdb_fmt("jun 0x%03x", ((ut16)(low << 8) | buf[1])); break;
87  case 5: buf_asm = sdb_fmt("jms 0x%03x", ((ut16)(low << 8) | buf[1])); break;
88  case 6: buf_asm = sdb_fmt("inc r%d", low); break;
89  case 7: buf_asm = sdb_fmt("isz r%d, 0x%02x", low, buf[1]); break;
90  case 8: buf_asm = sdb_fmt("add r%d", low); break;
91  case 9: buf_asm = sdb_fmt("sub r%d", low); break;
92  case 10: buf_asm = sdb_fmt("ld r%d", low); break;
93  case 11: buf_asm = sdb_fmt("xch r%d", low); break;
94  case 12: buf_asm = sdb_fmt("bbl %d", low); break;
95  case 13: buf_asm = sdb_fmt("ldm %d", low); break;
96  case 14: buf_asm = i4004_e[low]; break;
97  case 15: buf_asm = i4004_f[low]; break;
98  }
99  rz_strbuf_set(&op->buf_asm, buf_asm);
100  return op->size = rlen;
101 }
size_t len
Definition: 6502dis.c:15
uint16_t ut16
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
static const char * i4004_f[16]
Definition: i4004dis.c:34
static int i4004_get_ins_len(ut8 hex)
Definition: i4004dis.c:53
static int i4004dis(RzAsmOp *op, const ut8 *buf, int len)
Definition: i4004dis.c:61
static const char * i4004_e[16]
Definition: i4004dis.c:15
static const int i4004_ins_len[16]
Definition: i4004dis.c:11
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
static const char hex[16]
Definition: print.c:21
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
Definition: dis.c:32