Rizin
unix-like reverse engineering framework and cli tools
z80.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2015 condret
2 // SPDX-FileCopyrightText: 2016 unlogic
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_asm.h>
6 #include <rz_types.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include "z80_tab.h"
10 
12  if (hex < 0x40) {
13  return hex;
14  }
15  switch (hex) {
16  case 0x46: return 0x40;
17  case 0x4e: return 0x41;
18  case 0x56: return 0x42;
19  case 0x5e: return 0x43;
20  case 0x66: return 0x44;
21  case 0x6e: return 0x45;
22  case 0x76: return 0x46;
23  case 0x7e: return 0x47;
24  }
25  return (hex > 0x7f)? hex - 0x38: 0xc8;
26 }
27 
28 static int z80OpLength (const ut8 *buf, int len) {
29  const z80_opcode *op;
30  int type = 0, ret = 0;
31  if (len < 1) {
32  return 0;
33  }
34  op = z80_op;
35  if (op[buf[0]].type & Z80_OP_UNK) {
36  if (len < 2) {
37  return 0;
38  }
39  if (op[buf[0]].type & Z80_ENC0) {
40  op = (const z80_opcode *)op[buf[0]].op_moar;
42  } else if (op[buf[0]].type & Z80_ENC1) {
43  op = (const z80_opcode *)op[buf[0]].op_moar;
44  type = op[z80_ed_branch_index_res(buf[1])].type;
45  }
46  } else {
47  type = op[buf[0]].type;
48  }
49  if (type & Z80_OP8) {
50  ret++;
51  }
52  if ((type & Z80_ARG8) && !(type & Z80_ARG16)) { //XXX
53  ret++;
54  }
55  if (type & Z80_OP16) {
56  ret += 2;
57  }
58  if (type & Z80_ARG16) {
59  ret += 2;
60  }
61  if (type & Z80_OP24) {
62  ret += 3;
63  }
64  if (ret > len) {
65  return 0;
66  }
67  return ret;
68 }
69 
70 // #include'd in asm/p/asm_z80.c
71 FUNC_ATTR_USED static int z80Disass (RzAsmOp *op, const ut8 *buf, int len) {
72  int ret = z80OpLength (buf, len);
73  const z80_opcode *z_op;
74  const char **cb_tab;
75  ut8 res;
76  if (!ret) {
77  return ret;
78  }
79  z_op = z80_op;
80  const char *buf_asm = "invalid";
81  switch (z_op[buf[0]].type) {
82  case Z80_OP8:
83  buf_asm = sdb_fmt ("%s", z_op[buf[0]].name);
84  break;
85  case Z80_OP8^Z80_ARG8:
86  buf_asm = sdb_fmt (z_op[buf[0]].name, buf[1]);
87  break;
88  case Z80_OP8^Z80_ARG16:
89  buf_asm = sdb_fmt (z_op[buf[0]].name, buf[1]+(buf[2]<<8));
90  break;
91  case Z80_OP16:
92  cb_tab = (const char **) z_op[buf[0]].op_moar;
93  buf_asm = sdb_fmt ("%s", cb_tab[buf[1]]);
94  break;
95  case Z80_OP_UNK ^ Z80_ENC1:
96  z_op = (const z80_opcode *)z_op[buf[0]].op_moar;
97  res = z80_ed_branch_index_res (buf[1]);
98  if (z_op[res].type == Z80_OP16) {
99  buf_asm = sdb_fmt ("%s", z_op[res].name);
100  }
101  if (z_op[res].type == (Z80_OP16^Z80_ARG16)) {
102  buf_asm = sdb_fmt (z_op[res].name, buf[2]+(buf[3]<<8));
103  }
104  break;
105  case Z80_OP_UNK ^ Z80_ENC0:
106  z_op = (const z80_opcode *)z_op[buf[0]].op_moar;
107  res = z80_fddd_branch_index_res (buf[1]);
108  if (z_op[res].type == Z80_OP16) {
109  buf_asm = sdb_fmt ("%s", z_op[res].name);
110  }
111  if (z_op[res].type == (Z80_OP16^Z80_ARG16)) {
112  buf_asm = sdb_fmt (z_op[res].name, buf[2]+(buf[3]<<8));
113  }
114  if (z_op[res].type == (Z80_OP16^Z80_ARG8)) {
115  buf_asm = sdb_fmt (z_op[res].name, buf[2]);
116  }
117  if (z_op[res].type == (Z80_OP24 ^ Z80_ARG8)) {
118  cb_tab = (const char **) z_op[res].op_moar;
119  buf_asm = sdb_fmt (cb_tab[z80_op_24_branch_index_res (buf[3])], buf[2]);
120  }
121  if (z_op[res].type == (Z80_OP16 ^ Z80_ARG8 ^ Z80_ARG16)) {
122  buf_asm = sdb_fmt (z_op[res].name, buf[2], buf[3]);
123  }
124  break;
125  }
126  if (!strcmp (buf_asm, "invalid")) {
127  ret = 0;
128  }
129  rz_asm_op_set_asm (op, buf_asm);
130  return ret;
131 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
RZ_API void rz_asm_op_set_asm(RzAsmOp *op, const char *str)
Definition: aop.c:53
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
int type
Definition: mipsasm.c:17
static const char hex[16]
Definition: print.c:21
#define FUNC_ATTR_USED
Definition: rz_types.h:183
Definition: z80asm.h:102
Definition: dis.c:32
static int z80OpLength(const ut8 *buf, int len)
Definition: z80.c:28
static FUNC_ATTR_USED int z80Disass(RzAsmOp *op, const ut8 *buf, int len)
Definition: z80.c:71
static ut8 z80_op_24_branch_index_res(ut8 hex)
Definition: z80.c:11
@ Z80_OP24
Definition: z80_tab.h:16
@ Z80_ARG8
Definition: z80_tab.h:17
@ Z80_OP_UNK
Definition: z80_tab.h:13
@ Z80_ENC0
Definition: z80_tab.h:19
@ Z80_ARG16
Definition: z80_tab.h:18
@ Z80_ENC1
Definition: z80_tab.h:20
@ Z80_OP8
Definition: z80_tab.h:14
@ Z80_OP16
Definition: z80_tab.h:15
static const z80_opcode z80_op[]
Definition: z80_tab.h:1087
static ut8 z80_ed_branch_index_res(ut8 hex)
Definition: z80_tab.h:148
static ut8 z80_fddd_branch_index_res(ut8 hex)
Definition: z80_tab.h:29