1 /* radare - LGPL - Copyright 2012 - pancake<nopcode.org> */
2 
3 // This file is based on the Z80 analyser and modified for
4 // the Intel 8080 disassembler by Alexander Demin, 2012.
5 
6 #include <string.h>
7 #include <r_types.h>
8 #include <r_lib.h>
9 #include <r_asm.h>
10 #include <r_anal.h>
11 // hack
12 #include "../../asm/arch/i8080/i8080dis.c"
13 
i8080_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * data,int len,RAnalOpMask mask)14 static int i8080_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
15 	char out[32];
16 	int ilen = i8080_disasm (data, out, len);
17 	op->addr = addr;
18 	op->type = R_ANAL_OP_TYPE_UNK;
19 	switch (data[0]) {
20 	case 0x00:
21 		op->type = R_ANAL_OP_TYPE_NOP;
22 		break;
23 	case 0x03:
24 	case 0x04:
25 	case 0x0c:
26 	case 0x13:
27 	case 0x14:
28 	case 0x1c:
29 	case 0x23:
30 	case 0x24:
31 	case 0x2c:
32 	case 0x33:
33 	case 0x34:
34 	case 0x3c:
35 		op->type = R_ANAL_OP_TYPE_ADD; // INC
36 		break;
37 	case 0x09:
38 	case 0x19:
39 	case 0x29:
40 	case 0x39:
41 	case 0x80:
42 	case 0x81:
43 	case 0x82:
44 	case 0x83:
45 	case 0x84:
46 	case 0x85:
47 	case 0x86:
48 	case 0x87:
49 	case 0xc6:
50 		op->type = R_ANAL_OP_TYPE_ADD;
51 		break;
52 	case 0x90:
53 	case 0x91:
54 	case 0x92:
55 	case 0x93:
56 	case 0x94:
57 	case 0x95:
58 	case 0x96:
59 	case 0x97:
60 	case 0xd6:
61 		op->type = R_ANAL_OP_TYPE_SUB;
62 		break;
63 	case 0xc0:
64 	case 0xc8:
65 	case 0xd0:
66 	case 0xd8:
67 	case 0xe0:
68 	case 0xe8:
69 	case 0xf0:
70 	case 0xf8:
71 		op->type = R_ANAL_OP_TYPE_CRET;
72 		break;
73 	case 0xc9:
74 		op->type = R_ANAL_OP_TYPE_RET;
75 		break;
76 	case 0x05:
77 	case 0x0b:
78 	case 0x0d:
79 	case 0x15:
80 	case 0x1b:
81 	case 0x1d:
82 	case 0x25:
83 	case 0x2b:
84 	case 0x2d:
85 	case 0x35:
86 	case 0x3b:
87 	case 0x3d:
88 		// XXXX: DEC
89 		op->type = R_ANAL_OP_TYPE_SUB;
90 		break;
91 	case 0xc5:
92 	case 0xd5:
93 	case 0xe5:
94 	case 0xf5:
95 		op->type = R_ANAL_OP_TYPE_PUSH;
96 		break;
97 	case 0xc1:
98 	case 0xd1:
99 	case 0xe1:
100 	case 0xf1:
101 		op->type = R_ANAL_OP_TYPE_POP;
102 		break;
103 	case 0x40:
104 	case 0x49:
105 	case 0x52:
106 	case 0x5b:
107 	case 0x64:
108 	case 0x6d:
109 	case 0x76:
110 	case 0x7f:
111 		op->type = R_ANAL_OP_TYPE_TRAP; // HALT
112 		break;
113 	case 0x10:
114 	case 0x18:
115 	case 0x20:
116 	case 0x28:
117 	case 0x30:
118 	case 0x38:
119 	case 0xc2:
120 	case 0xc3:
121 	case 0xca:
122 	case 0xd2:
123 	case 0xda:
124 	case 0xe2:
125 	case 0xe9:
126 	case 0xea:
127 	case 0xf2:
128 	case 0xfa:
129 		op->type = R_ANAL_OP_TYPE_JMP; // jmpz
130 		break;
131 
132 	case 0xc4:
133 	case 0xcc:
134 	case 0xcd:
135 	case 0xd4:
136 	case 0xdc:
137 	case 0xdd:
138 	case 0xe4:
139 	case 0xec:
140 	case 0xed:
141 	case 0xf4:
142 	case 0xfc:
143 	case 0xfd:
144 		op->type = R_ANAL_OP_TYPE_CALL;
145 		break;
146 	case 0xc7:				//rst 0
147 		op->jump = 0x00;
148 		op->fail = addr + ilen;
149 		op->type = R_ANAL_OP_TYPE_JMP;
150 		break;
151 	case 0xcf:				//rst 8
152 		op->jump = 0x08;
153 		op->fail = addr + ilen;
154 		op->type = R_ANAL_OP_TYPE_JMP;
155 		break;
156 	case 0xd7:				//rst 16
157 		op->jump = 0x10;
158 		op->fail = addr + ilen;
159 		op->type = R_ANAL_OP_TYPE_JMP;
160 		break;
161 	case 0xdf:				 //rst 24
162 		op->jump = 0x18;
163 		op->fail = addr + ilen;
164 		op->type = R_ANAL_OP_TYPE_JMP;
165 		break;
166 	case 0xe7:				//rst 32
167 		op->jump = 0x20;
168 		op->fail = addr + ilen;
169 		op->type = R_ANAL_OP_TYPE_JMP;
170 		break;
171 	case 0xef:				//rst 40
172 		op->jump = 0x28;
173 		op->fail = addr + ilen;
174 		op->type = R_ANAL_OP_TYPE_JMP;
175 		break;
176 	case 0xf7:				//rst 48
177 		op->jump = 0x30;
178 		op->fail = addr + ilen;
179 		op->type = R_ANAL_OP_TYPE_JMP;
180 		break;
181 	case 0xff:				//rst 56
182 		op->jump = 0x38;
183 		op->fail = addr + ilen;
184 		op->type = R_ANAL_OP_TYPE_JMP;
185 	break;					// copypasta from gb and z80
186 	}
187 	return op->size = ilen;
188 }
189 
190 RAnalPlugin r_anal_plugin_i8080 = {
191 	.name = "i8080",
192 	.desc = "I8080 CPU code analysis plugin",
193 	.license = "LGPL3",
194 	.arch = "i8080",
195 	.bits = 16,
196 	.op = &i8080_op,
197 };
198 
199 #ifndef R2_PLUGIN_INCORE
200 R_API RLibStruct radare_plugin = {
201 	.type = R_LIB_TYPE_ANAL,
202 	.data = &r_anal_plugin_i8080,
203 	.version = R2_VERSION
204 };
205 #endif
206