1 #include <r_types.h>
2 #include <r_util.h>
3 #include "h8300_disas.h"
4 
5 static const char *commands_4bit[] = {
6 	[H8300_MOV_4BIT_2] = "mov.b",
7 	[H8300_MOV_4BIT_3] = "mov.b",
8 	[H8300_ADD_4BIT] = "add.b",
9 	[H8300_ADDX_4BIT] = "addx",
10 	[H8300_CMP_4BIT] = "cmp.b",
11 	[H8300_SUBX_4BIT] = "subx",
12 	[H8300_OR_4BIT] = "or",
13 	[H8300_XOR_4BIT] = "xor",
14 	[H8300_AND_4BIT] = "and",
15 	[H8300_MOV_4BIT] = "mov.b"
16 };
17 
18 static const char *commands[] = {
19 	[H8300_ANDC] = "andc",
20 	[H8300_ADDB_DIRECT] = "add.b",
21 	[H8300_ADDW_DIRECT] = "add.w",
22 	[H8300_ADDS] = "adds",
23 	[H8300_AND] = "and",
24 	[H8300_ADDX] = "addx",
25 	[H8300_SUBW] = "sub.w",
26 	[H8300_BILD_IMM2R8] = "bld",
27 	[H8300_BNOT_1] = "bnot",
28 	[H8300_BNOT_2] = "bnot",
29 	[H8300_BSET_1] = "bset",
30 	[H8300_BSET_2] = "bset",
31 	[H8300_BCLR_R2R8] = "bclr",
32 	[H8300_BCLR_IMM2R8] = "bclr",
33 	[H8300_BCLR_R2IND16] = "bclr",
34 	[H8300_BCLR_R2ABS8] = "bclr",
35 	[H8300_BOR_BIOR] = "bior",
36 
37 	[H8300_BAND_BIAND] = "biand",
38 	[H8300_BIAND_IMM2IND16] = "biand",
39 	[H8300_BIAND_IMM2ABS8] = "biand",
40 	[H8300_BST_BIST] = "bist",
41 	[H8300_BTST] = "btst",
42 	[H8300_BTST_R2R8] = "btst",
43 	[H8300_BXOR] = "bixor",
44 
45 	[H8300_BSR] = "bsr",
46 	[H8300_NOP] = "nop",
47 	[H8300_DAA] = "daa",
48 	[H8300_DAS] = "das",
49 	[H8300_DEC] = "dec",
50 	[H8300_INC] = "inc",
51 	[H8300_NOT_NEG] = "neg",
52 	[H8300_OR] = "or",
53 	[H8300_DIVXU] = "divxu",
54 	[H8300_MULXU] = "mulxu",
55 	[H8300_EEPMOV] = "eepmov",
56 	[H8300_JMP_1] = "jmp",
57 	[H8300_JMP_2] = "jmp",
58 	[H8300_JMP_3] = "jmp",
59 	[H8300_JSR_1] = "jsr",
60 	[H8300_JSR_2] = "jsr",
61 	[H8300_JSR_3] = "jsr",
62 	[H8300_ORC] = "orc",
63 	[H8300_ROTL] = "rotl",
64 	[H8300_ROTR] = "rotr",
65 	[H8300_RTE] = "rte",
66 	[H8300_RTS] = "rts",
67 	[H8300_SHL] = "shal",
68 	[H8300_SHR] = "shar",
69 	[H8300_SLEEP] = "sleep",
70 	[H8300_STC] = "stc",
71 	[H8300_SUB_1] = "sub.b",
72 	[H8300_SUBS] = "subs",
73 	[H8300_SUBX] = "subx",
74 	[H8300_XOR] = "xor",
75 	[H8300_XORC] = "xorc",
76 
77 	[H8300_LDC] = "ldc",
78 	[H8300_LDC_2] = "ldc",
79 
80 	[H8300_MOV_1] = "mov.b",
81 	[H8300_MOV_2] = "mov.w",
82 	[H8300_MOV_IMM162R16] = "mov.w",
83 	[H8300_MOV_DISP162R16] = "mov.w",
84 	[H8300_MOV_INDINC162R16] = "mov.w",
85 	[H8300_MOV_ABS162R16] = "mov.w",
86 	[H8300_MOV_IND162R16] = "mov.w",
87 
88 	[H8300_MOV_R82IND16] = "mov.b",
89 	[H8300_MOV_R82DISPR16] = "mov.b",
90 	[H8300_MOV_R82RDEC16] = "mov.b",
91 	[H8300_MOV_R82ABS16] = "mov.b",
92 
93 	[H8300_BRA] = "bra",
94 	[H8300_BRN] = "brn",
95 	[H8300_BHI] = "bhi",
96 	[H8300_BLS] = "bls",
97 	[H8300_BCC] = "bcc",
98 	[H8300_BCS] = "bcs",
99 	[H8300_BNE] = "bne",
100 	[H8300_BEQ] = "beq",
101 	[H8300_BVC] = "bvc",
102 	[H8300_BVS] = "bvs",
103 	[H8300_BPL] = "bpl",
104 	[H8300_BMI] = "bmi",
105 	[H8300_BGE] = "bge",
106 	[H8300_BLT] = "blt",
107 	[H8300_BGT] = "bgt",
108 	[H8300_BLE] = "ble",
109 
110 	[H8300_CMP_1] = "cmp.b",
111 	[H8300_CMP_2] = "cmp.w",
112 };
113 
114 static const char *commands_9bit[] = {
115 	[H8300_BST] = "bst",
116 	[H8300_BIST] = "bist",
117 	[H8300_BOR] = "bor",
118 	[H8300_BIOR] = "bior",
119 	[H8300_BXOR] = "bxor",
120 	[H8300_BIXOR] = "bixor",
121 	[H8300_BAND] = "band",
122 	[H8300_BIAND] = "biand",
123 	[H8300_BLD] = "bld",
124 	[H8300_BILD] = "bild",
125 };
126 
decode_opcode_4bit(const ut8 * bytes,struct h8300_cmd * cmd)127 static int decode_opcode_4bit(const ut8 *bytes, struct h8300_cmd *cmd)
128 {
129 	ut8 opcode = bytes[0] >> 4;
130 
131 	if (opcode >= sizeof(commands_4bit)/sizeof(void*)
132 			|| !commands_4bit[opcode]) {
133 		return -1;
134 	}
135 
136 	strncpy(cmd->instr, commands_4bit[opcode], H8300_INSTR_MAXLEN - 1);
137 	cmd->instr[H8300_INSTR_MAXLEN - 1] = '\0';
138 
139 	return 0;
140 }
141 
decode_opcode(const ut8 * bytes,struct h8300_cmd * cmd)142 static int decode_opcode(const ut8 *bytes, struct h8300_cmd *cmd)
143 {
144 	ut16 ext_opcode;
145 
146 	ext_opcode = (r_read_be16 (bytes)) >> 7;
147 
148 	switch (ext_opcode) {
149 	case H8300_BOR:
150 	case H8300_BIOR:
151 	case H8300_BXOR:
152 	case H8300_BIXOR:
153 	case H8300_BAND:
154 	case H8300_BIAND:
155 	case H8300_BLD:
156 	case H8300_BILD:
157 	case H8300_BST:
158 	case H8300_BIST:
159 		if (ext_opcode >= sizeof(commands_9bit)/sizeof(void*) ||
160 				!commands_9bit[ext_opcode]) {
161 			break;
162 		}
163 		strncpy(cmd->instr, commands_9bit[ext_opcode], H8300_INSTR_MAXLEN - 1);
164 		cmd->instr[H8300_INSTR_MAXLEN - 1] = '\0';
165 		return 0;
166 	}
167 
168 	switch (bytes[0]) {
169 	case H8300_BIAND_IMM2IND16:
170 	case H8300_BIAND_IMM2ABS8:
171 	case H8300_BCLR_R2IND16:
172 	case H8300_BCLR_R2ABS8:
173 		switch (bytes[2]) {
174 		case 0x74:
175 			strncpy(cmd->instr, bytes[3] & 0x80 ? "bior" : "bor",
176 					H8300_INSTR_MAXLEN - 1);
177 			return 0;
178 		case 0x76:
179 			strncpy(cmd->instr, bytes[3] & 0x80 ? "biand" : "band",
180 					H8300_INSTR_MAXLEN - 1);
181 			return 0;
182 		case 0x77:
183 			strncpy(cmd->instr, bytes[3] & 0x80 ? "bild" : "bld",
184 					H8300_INSTR_MAXLEN - 1);
185 			return 0;
186 		case 0x67:
187 			strncpy(cmd->instr, bytes[3] & 0x80 ? "bist" : "bst",
188 					H8300_INSTR_MAXLEN - 1);
189 			return 0;
190 		case 0x75:
191 			strncpy(cmd->instr, bytes[3] & 0x80 ? "bixor" : "bxor",
192 					H8300_INSTR_MAXLEN - 1);
193 			return 0;
194 		case 0x60:
195 		case 0x70:
196 			strncpy(cmd->instr, "bset", H8300_INSTR_MAXLEN - 1);
197 			return 0;
198 		case 0x61:
199 		case 0x71:
200 			strncpy(cmd->instr, "bnot", H8300_INSTR_MAXLEN - 1);
201 			return 0;
202 		}
203 		break;
204 	}
205 
206 	if (bytes[0] >= sizeof(commands)/sizeof(void*) || !commands[bytes[0]]) {
207 		return -1;
208 	}
209 
210 	strncpy(cmd->instr, commands[bytes[0]], H8300_INSTR_MAXLEN - 1);
211 	cmd->instr[H8300_INSTR_MAXLEN - 1] = '\0';
212 
213 	return 0;
214 }
215 
decode_eepmov(const ut8 * bytes,struct h8300_cmd * cmd)216 static int decode_eepmov(const ut8 *bytes, struct h8300_cmd *cmd)
217 {
218 	int ret = 4;
219 
220 	if (decode_opcode(bytes, cmd)) {
221 		return -1;
222 	}
223 	cmd->operands[0] = '\0';
224 
225 	switch (bytes[0]) {
226 	case H8300_RTS:
227 	case H8300_RTE:
228 		ret = 2;
229 		break;
230 	}
231 
232 	return ret;
233 }
234 
decode_ldc(const ut8 * bytes,struct h8300_cmd * cmd)235 static int decode_ldc(const ut8 *bytes, struct h8300_cmd *cmd)
236 {
237 	int ret = 2;
238 
239 	if (decode_opcode(bytes, cmd)) {
240 		return -1;
241 	}
242 
243 	if (bytes[0] == H8300_LDC_2 || bytes[0] == H8300_XORC ||
244 			bytes[0] == H8300_ORC) {
245 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
246 				"#0x%x:8,ccr", bytes[1]);
247 	} else if (bytes[0] == H8300_LDC) {
248 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
249 				"r%u%c,ccr", bytes[1] & 0x7,
250 				bytes[1] & 0x8 ? 'l' : 'h');
251 	} else if (bytes[0] == H8300_STC) {
252 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
253 				"ccr,r%u%c", bytes[1] & 0x7,
254 				bytes[1] & 0x8 ? 'l' : 'h');
255 	}
256 
257 	return ret;
258 }
259 
decode_r162r16(const ut8 * bytes,struct h8300_cmd * cmd)260 static int decode_r162r16(const ut8 *bytes, struct h8300_cmd *cmd)
261 {
262 	int ret = 2;
263 
264 	if (decode_opcode(bytes, cmd)) {
265 		return -1;
266 	}
267 
268 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u,r%u",
269 			bytes[1] >> 4,
270 			bytes[1] & 0x7);
271 
272 	return ret;
273 }
274 
decode_andc(const ut8 * bytes,struct h8300_cmd * cmd)275 static int decode_andc(const ut8 *bytes, struct h8300_cmd *cmd)
276 {
277 	int ret = 2;
278 
279 	if (decode_opcode(bytes, cmd)) {
280 		return -1;
281 	}
282 
283 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#0x%x:8,ccr", bytes[1]);
284 
285 	return ret;
286 }
287 
decode_adds(const ut8 * bytes,struct h8300_cmd * cmd)288 static int decode_adds(const ut8 *bytes, struct h8300_cmd *cmd)
289 {
290 	int ret = 2;
291 	unsigned reg, val;
292 
293 	if (decode_opcode(bytes, cmd)) {
294 		return -1;
295 	}
296 
297 	reg = bytes[1] & 0x7;
298 
299 	if (bytes[1] & 0x80) {
300 		val = 2;
301 	} else {
302 		val = 1;
303 	}
304 
305 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#%u,r%u", val, reg);
306 
307 	return ret;
308 }
309 
decode_bsr(const ut8 * bytes,struct h8300_cmd * cmd)310 static int decode_bsr(const ut8 *bytes, struct h8300_cmd *cmd)
311 {
312 	int ret = 2;
313 
314 	if (decode_opcode(bytes, cmd)) {
315 		return -1;
316 	}
317 
318 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, ".%d",
319 			(st8)bytes[1]);
320 
321 	return ret;
322 }
323 
324 /* [opcode ] [ 0000 | 0 rd] [      imm    ] */
decode_imm162r16(const ut8 * bytes,struct h8300_cmd * cmd)325 static int decode_imm162r16(const ut8 *bytes, struct h8300_cmd *cmd)
326 {
327 	int ret = 4;
328 	ut16 imm;
329 
330 	if (decode_opcode(bytes, cmd)) {
331 		return -1;
332 	}
333 
334 	imm = r_read_at_be16 (bytes, 2);
335 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#0x%x:16,r%u",
336 			imm, bytes[1] & 0x7);
337 
338 	return ret;
339 }
340 
341 /* [ opcode ] [ 0 rs | 0 rd ] [         disp    ] */
decode_disp162r16(const ut8 * bytes,struct h8300_cmd * cmd)342 static int decode_disp162r16(const ut8 *bytes, struct h8300_cmd *cmd)
343 {
344 	int ret = 4;
345 	ut16 disp;
346 
347 	if (decode_opcode(bytes, cmd)) {
348 		return -1;
349 	}
350 
351 	disp = r_read_at_be16 (bytes, 2);
352 
353 	if (bytes[1] & 0x80) {
354 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
355 			"r%u,@(0x%x:16,r%u)",
356 			bytes[1] & 0x7, disp,
357 			(bytes[1] >> 4) & 0x7);
358 	} else {
359 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
360 			"@(0x%x:16,r%u),r%u", disp,
361 			(bytes[1] >> 4) & 0x7, bytes[1] & 0x7);
362 	}
363 
364 	return ret;
365 }
366 
decode_pop(const ut8 * bytes,struct h8300_cmd * cmd)367 static int decode_pop(const ut8 *bytes, struct h8300_cmd *cmd)
368 {
369 	int ret = 2;
370 	ut8 tmp = bytes[1] >> 4;
371 
372 	strncpy(cmd->instr, tmp == 0x7 ? "pop" : "push",
373 			H8300_INSTR_MAXLEN - 1);
374 	cmd->instr[H8300_INSTR_MAXLEN - 1] = '\0';
375 
376 
377 	snprintf(cmd->operands, H8300_INSTR_MAXLEN,
378 			"r%u", bytes[1] & 0x7);
379 
380 	return ret;
381 }
382 
383 /* [ opcode ] [ 0 r2 | 0 rd ] @rs+,@rd */
decode_indinc162r16(const ut8 * bytes,struct h8300_cmd * cmd)384 static int decode_indinc162r16(const ut8 *bytes, struct h8300_cmd *cmd)
385 {
386 	int ret = 2;
387 	ut8 tmp = bytes[1] >> 4;
388 
389 	if (bytes[0] == 0x6D && (tmp == 7 || tmp == 0xF)) {
390 		return decode_pop(bytes, cmd);
391 	}
392 
393 	if (decode_opcode(bytes, cmd)) {
394 		return -1;
395 	}
396 
397 	if (bytes[1] & 0x80) {
398 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u,@-r%u",
399 			bytes[1] & 0x7, (bytes[1] >> 4) & 0x7);
400 	} else {
401 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "@r%u+,r%u",
402 			(bytes[1] >> 4) & 0x7, bytes[1] & 0x7);
403 	}
404 
405 	return ret;
406 }
407 
408 /* [ opcode ] [ 0 rs | 0 rd ] */
decode_ind162r16(const ut8 * bytes,struct h8300_cmd * cmd)409 static int decode_ind162r16(const ut8 *bytes, struct h8300_cmd *cmd)
410 {
411 	int ret = 2;
412 
413 	if (decode_opcode(bytes, cmd)) {
414 		return -1;
415 	}
416 
417 	if (bytes[1] & 0x80) {
418 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u,@r%u",
419 			bytes[1] & 0x7,
420 			(bytes[1] >> 4) & 0x7);
421 	} else {
422 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "@r%u,r%u",
423 			(bytes[1] >> 4) & 0x7,
424 			bytes[1] & 0x7);
425 	}
426 
427 	return ret;
428 }
429 
430 /* [ opcode ] [0 | IMM | rd ] */
decode_imm2r8(const ut8 * bytes,struct h8300_cmd * cmd)431 static int decode_imm2r8(const ut8 *bytes, struct h8300_cmd *cmd)
432 {
433 	int ret = 2;
434 
435 	if (decode_opcode(bytes, cmd)) {
436 		return -1;
437 	}
438 
439 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#0x%x:3,r%u%c",
440 			(bytes[1] >> 4) & 0x7, bytes[1] & 0x7,
441 			bytes[1] & 0x8 ? 'l' : 'h');
442 
443 	return ret;
444 }
445 
446 /* [opcode] [0 | rd | 0000] [opcode] [0|IMM|0000] */
decode_imm2ind16(const ut8 * bytes,struct h8300_cmd * cmd)447 static int decode_imm2ind16(const ut8 *bytes, struct h8300_cmd *cmd)
448 {
449 	int ret = 4;
450 
451 	if (decode_opcode(bytes, cmd)) {
452 		return -1;
453 	}
454 
455 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#0x%x:3,@r%u",
456 			(bytes[3] >> 4) & 0x7, bytes[1] >> 4);
457 
458 	return ret;
459 }
460 
461 /* [opcode] [   abs   ] [opcode] [0|IMM | 0000] */
decode_imm2abs8(const ut8 * bytes,struct h8300_cmd * cmd)462 static int decode_imm2abs8(const ut8 *bytes, struct h8300_cmd *cmd)
463 {
464 	int ret = 4;
465 
466 	if (decode_opcode(bytes, cmd)) {
467 		return -1;
468 	}
469 
470 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#0x%x:3,@0x%x:8",
471 			(bytes[3] >> 4) & 0x7, bytes[1]);
472 
473 	return ret;
474 
475 }
476 
477 /* [opcode] [ rn  |  rd ] */
decode_r2r8(const ut8 * bytes,struct h8300_cmd * cmd)478 static int decode_r2r8(const ut8 *bytes, struct h8300_cmd *cmd)
479 {
480 	int ret = 2;
481 
482 	if (decode_opcode(bytes, cmd)) {
483 		return -1;
484 	}
485 
486 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u%c,r%u%c",
487 			(bytes[1] >> 4) & 0x7,
488 			bytes[1] & 0x80 ? 'l' : 'h',
489 			bytes[1] & 0x7, bytes[1] & 0x8  ? 'l' : 'h');
490 
491 	return ret;
492 }
493 
494 /* [opcode] [0| rd | 0000] [opcode] [ rn | 0 ] */
decode_r2ind16(const ut8 * bytes,struct h8300_cmd * cmd)495 static int decode_r2ind16(const ut8 *bytes, struct h8300_cmd *cmd)
496 {
497 	int ret = 4;
498 
499 	if (decode_opcode(bytes, cmd)) {
500 		return -1;
501 	}
502 
503 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u%c,@r%u",
504 			(bytes[3] >> 4) & 0x7,
505 			bytes[3] & 0x80 ? 'l' : 'h',
506 			bytes[1] >> 4);
507 
508 	return ret;
509 }
510 
511 /* [opcode] [ abs ] [opcode] [ rn | 0000 ] */
decode_r2abs8(const ut8 * bytes,struct h8300_cmd * cmd)512 static int decode_r2abs8(const ut8 *bytes, struct h8300_cmd *cmd)
513 {
514 	int ret = 4;
515 
516 	if (decode_opcode(bytes, cmd)) {
517 		return -1;
518 	}
519 
520 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u%c,@0x%x:8",
521 			(bytes[3] >> 4) & 0x7,
522 			bytes[3] & 0x80 ? 'l' : 'h',
523 			bytes[1]);
524 
525 	return ret;
526 }
527 
decode_subs(const ut8 * bytes,struct h8300_cmd * cmd)528 static int decode_subs(const ut8 *bytes, struct h8300_cmd *cmd)
529 {
530 	int ret = 2;
531 
532 	if (decode_opcode(bytes, cmd)) {
533 		return -1;
534 	}
535 
536 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#%u,r%u",
537 			bytes[1] & 0x80 ? 2 : 1, bytes[1] & 0x7);
538 
539 	return ret;
540 }
541 
542 /* [ opcode ] [ 0000 |  rd ] */
decode_daa(const ut8 * bytes,struct h8300_cmd * cmd)543 static int decode_daa(const ut8 *bytes, struct h8300_cmd *cmd)
544 {
545 	int ret = 2;
546 
547 	if (bytes[0] == 0x17 && bytes[1] >> 4 == 0) {
548 		strncpy(cmd->instr, "not", H8300_INSTR_MAXLEN - 1);
549 		cmd->instr[H8300_INSTR_MAXLEN - 1] = '\0';
550 	} else if (bytes[0] == 0x12 && bytes[1] >> 4 == 0) {
551 		strncpy(cmd->instr, "rotxl", H8300_INSTR_MAXLEN - 1);
552 		cmd->instr[H8300_INSTR_MAXLEN - 1] = '\0';
553 	} else if (bytes[0] == 0x13 && bytes[1] >> 4 == 0) {
554 		strncpy(cmd->instr, "rotxr", H8300_INSTR_MAXLEN - 1);
555 		cmd->instr[H8300_INSTR_MAXLEN - 1] = '\0';
556 	} else if (bytes[0] == 0x10 && bytes[1] >> 4 == 0) {
557 		strncpy(cmd->instr, "shll", H8300_INSTR_MAXLEN - 1);
558 	} else if (bytes[0] == 0x11 && bytes[1] >> 4 == 0) {
559 		strncpy(cmd->instr, "shlr", H8300_INSTR_MAXLEN - 1);
560 	} else if (decode_opcode(bytes, cmd)) {
561 		return -1;
562 	}
563 
564 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u%c",
565 			(bytes[1]) & 0x7,
566 			bytes[1] & 0x8 ? 'l' : 'h');
567 
568 	return ret;
569 }
570 
571 /* [ opcode ] [ rs | 0 rd] */
decode_r82r16(const ut8 * bytes,struct h8300_cmd * cmd)572 static int decode_r82r16(const ut8 *bytes, struct h8300_cmd *cmd)
573 {
574 	int ret = 2;
575 
576 	if (decode_opcode(bytes, cmd)) {
577 		return -1;
578 	}
579 
580 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u%c,r%u",
581 			(bytes[1] >> 4) & 0x7,
582 			bytes[1] & 0x80 ? 'l' : 'h',
583 			bytes[1] & 0x7);
584 
585 	return ret;
586 }
587 
588 /* [opcode] [0000 0000] [       abs    ] */
decode_jmp_abs16(const ut8 * bytes,struct h8300_cmd * cmd)589 int decode_jmp_abs16(const ut8 *bytes, struct h8300_cmd *cmd)
590 {
591 	int ret = 4;
592 	ut16 abs;
593 
594 	if (decode_opcode(bytes, cmd)) {
595 		return -1;
596 	}
597 
598 	abs = r_read_at_be16 (bytes, 2);
599 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "@0x%x:16", abs);
600 
601 	return ret;
602 }
603 
604 /* [opcode] [  abs    ] */
decode_jmp_abs8(const ut8 * bytes,struct h8300_cmd * cmd)605 int decode_jmp_abs8(const ut8 *bytes, struct h8300_cmd *cmd)
606 {
607 	int ret = 2;
608 
609 	if (decode_opcode(bytes, cmd)) {
610 		return -1;
611 	}
612 
613 	snprintf(cmd->operands, H8300_INSTR_MAXLEN,
614 			"@@0x%x:8", bytes[1]);
615 
616 	return ret;
617 }
618 
619 /* [opcode] [0 rn 0000] */
decode_jmp_ind(const ut8 * bytes,struct h8300_cmd * cmd)620 static int decode_jmp_ind(const ut8 *bytes, struct h8300_cmd *cmd)
621 {
622 	int ret = 2;
623 
624 	if (decode_opcode(bytes, cmd)) {
625 		return -1;
626 	}
627 
628 	snprintf(cmd->operands, H8300_INSTR_MAXLEN,
629 			"@r%u", (bytes[1] >> 4) & 0x7);
630 
631 	return ret;
632 }
633 
634 /* [ opcode ] [ 0000 | 0 rd ] [     abs    ] */
decode_abs162r16(const ut8 * bytes,struct h8300_cmd * cmd)635 static int decode_abs162r16(const ut8 *bytes, struct h8300_cmd *cmd)
636 {
637 	int ret = 4;
638 	ut16 abs;
639 
640 	if (decode_opcode(bytes, cmd)) {
641 		return -1;
642 	}
643 
644 	abs = r_read_at_be16 (bytes, 2);
645 	if (bytes[1] & 0x80) {
646 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
647 				"r%u,@0x%x:16", bytes[1] & 0x7, abs);
648 	} else {
649 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "@0x%x:16,r%u",
650 			abs, bytes[1] & 0x7);
651 	}
652 
653 	return ret;
654 }
655 
656 /* [ opcode ] [ 1 rd | rs ] */
decode_r82ind16(const ut8 * bytes,struct h8300_cmd * cmd)657 static int decode_r82ind16(const ut8 *bytes, struct h8300_cmd *cmd)
658 {
659 	int ret = 2;
660 
661 	if (decode_opcode(bytes, cmd)) {
662 		return -1;
663 	}
664 
665 	if (bytes[1] & 0x80) {
666 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u%c,@r%u",
667 			bytes[1] & 0x7, bytes[1] & 0x8 ? 'l' : 'h',
668 			(bytes[1] >> 4) & 0x7);
669 	} else {
670 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "@r%u,r%u%c",
671 			(bytes[1] >> 4) & 0x7,
672 			bytes[1] & 0x7, bytes[1] & 0x8 ? 'l' : 'h');
673 	}
674 
675 	return ret;
676 }
677 
678 /* [ opcode ] [ 1 rd |  rs ] [       disp     ] */
decode_r82dispr16(const ut8 * bytes,struct h8300_cmd * cmd)679 static int decode_r82dispr16(const ut8 *bytes, struct h8300_cmd *cmd)
680 {
681 	int ret = 4;
682 	ut16 disp;
683 
684 	if (decode_opcode(bytes, cmd)) {
685 		return -1;
686 	}
687 
688 	disp = r_read_at_be16 (bytes, 2);
689 	if (bytes[1] & 0x80) {
690 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
691 			"r%u%c,@(0x%x:16,r%u)",
692 			bytes[1] & 0x7, bytes[1] & 0x8 ? 'l' : 'h',
693 			disp, (bytes[1] >> 4) & 0x7);
694 	} else {
695 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
696 			"@(0x%x:16,r%u),r%u%c",
697 			disp, (bytes[1] >> 4) & 0x7,
698 			bytes[1] & 0x7, bytes[1] & 0x8 ? 'l' : 'h');
699 	}
700 	return ret;
701 }
702 
703 /* [ opcode ] [1 rd rs ] */
decode_r82rdec16(const ut8 * bytes,struct h8300_cmd * cmd)704 static int decode_r82rdec16(const ut8 *bytes, struct h8300_cmd *cmd)
705 {
706 	int ret = 2;
707 
708 	if (decode_opcode(bytes, cmd)) {
709 		return -1;
710 	}
711 
712 	if (bytes[1] & 0x80) {
713 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
714 			"r%u%c,@-r%u",
715 			bytes[1] & 0x7, bytes[1] & 0x8 ? 'l' : 'h',
716 			(bytes[1] >> 4) & 0x7);
717 	} else {
718 		snprintf(cmd->operands, H8300_INSTR_MAXLEN,
719 			"@r%u+,r%u%c",
720 			(bytes[1] >> 4) & 0x7,
721 			bytes[1] & 0x7, bytes[1] & 0x8 ? 'l' : 'h');
722 	}
723 
724 	return ret;
725 }
726 
727 /* [opcode ] [ 8 | rs ] [    abs    ] */
decode_r82abs16(const ut8 * bytes,struct h8300_cmd * cmd)728 static int decode_r82abs16(const ut8 *bytes, struct h8300_cmd *cmd)
729 {
730 	int ret = 4;
731 	ut16 abs;
732 
733 	if (bytes[0] == 0x6A && bytes[1] >> 4 == 4) {
734 		strncpy(cmd->instr, "movfpe", H8300_INSTR_MAXLEN);
735 	} else if (bytes[0] == 0x6A && bytes[1] >> 4 == 0xC) {
736 		strncpy(cmd->instr, "movtpe", H8300_INSTR_MAXLEN);
737 	} else if (decode_opcode(bytes, cmd)) {
738 		return -1;
739 	}
740 
741 	abs = r_read_at_be16 (bytes, 2);
742 
743 	if (bytes[1] & 0x80) {
744 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "r%u%c,@0x%x:16",
745 			bytes[1] & 0x7, bytes[1] & 0x8 ? 'l' : 'h', abs);
746 	} else {
747 		snprintf(cmd->operands, H8300_INSTR_MAXLEN, "@0x%x:16,r%u%c",
748 			abs, bytes[1] & 0x7,
749 			bytes[1] & 0x8 ? 'l' : 'h');
750 	}
751 
752 	return ret;
753 }
754 
decode_nop(const ut8 * bytes,struct h8300_cmd * cmd)755 static int decode_nop(const ut8 *bytes, struct h8300_cmd *cmd)
756 {
757 	int ret = 2;
758 
759 	if (decode_opcode(bytes, cmd)) {
760 		return -1;
761 	}
762 
763 	cmd->operands[0] = '\0';
764 
765 	return ret;
766 }
767 
decode_abs2r_short(const ut8 * bytes,struct h8300_cmd * cmd)768 static int decode_abs2r_short(const ut8 *bytes, struct h8300_cmd *cmd)
769 {
770 	int ret = 2;
771 
772 	if (decode_opcode_4bit(bytes, cmd)) {
773 		return -1;
774 	}
775 
776 	snprintf(cmd->operands, H8300_INSTR_MAXLEN,
777 			"@0x%x:8,r%u%c",
778 				bytes[1], bytes[0] & 0x7,
779 				bytes[0] & 0x8 ? 'l' : 'h');
780 
781 	return ret;
782 }
783 
decode_r2imm_short(const ut8 * bytes,struct h8300_cmd * cmd)784 static int decode_r2imm_short(const ut8 *bytes, struct h8300_cmd *cmd)
785 {
786 	int ret = 2;
787 
788 	if (decode_opcode_4bit(bytes, cmd)) {
789 		return -1;
790 	}
791 
792 	snprintf(cmd->operands, H8300_INSTR_MAXLEN,
793 				"r%u%c,@0x%x:8",
794 				bytes[0] & 0x7, bytes[0] & 0x8 ? 'l' : 'h',
795 				bytes[1]);
796 	return ret;
797 }
798 
decode_imm2r_short(const ut8 * bytes,struct h8300_cmd * cmd)799 static int decode_imm2r_short(const ut8 *bytes, struct h8300_cmd *cmd)
800 {
801 	int ret = 2;
802 
803 	if (decode_opcode_4bit(bytes, cmd)) {
804 		return -1;
805 	}
806 
807 	snprintf(cmd->operands, H8300_INSTR_MAXLEN, "#0x%x:8,r%u%c",
808 			bytes[1], bytes[0] & 0x7, bytes[0] & 0x8 ? 'l' : 'h');
809 
810 	return ret;
811 }
812 
h8300_decode_command(const ut8 * instr,struct h8300_cmd * cmd)813 int h8300_decode_command(const ut8 *instr, struct h8300_cmd *cmd)
814 {
815 	int ret = 0;
816 
817 	switch (instr[0] >> 4) {
818 	case H8300_MOV_4BIT_3:
819 		ret = decode_r2imm_short(instr, cmd);
820 		break;
821 	case H8300_MOV_4BIT_2:
822 		ret = decode_abs2r_short(instr, cmd);
823 		break;
824 	case H8300_AND_4BIT:
825 	case H8300_ADDX_4BIT:
826 	case H8300_ADD_4BIT:
827 	case H8300_CMP_4BIT:
828 	case H8300_MOV_4BIT:
829 	case H8300_OR_4BIT:
830 	case H8300_SUBX_4BIT:
831 	case H8300_XOR_4BIT:
832 		ret = decode_imm2r_short(instr, cmd);
833 		break;
834 	}
835 
836 	if (ret) {
837 		{
838 			return ret;
839 		}
840 	}
841 
842 	switch (instr[0]) {
843 	case H8300_ANDC:
844 		ret = decode_andc(instr, cmd);
845 		break;
846 	case H8300_SUBS:
847 		ret = decode_subs(instr, cmd);
848 		break;
849 	case H8300_ADDW_DIRECT:
850 	case H8300_CMP_2:
851 		ret = decode_r162r16(instr, cmd);
852 		break;
853 	case H8300_ADDS:
854 		ret = decode_adds(instr, cmd);
855 		break;
856 	case H8300_BAND_BIAND:
857 	case H8300_BCLR_IMM2R8:
858 	case H8300_BST_BIST:
859 	case H8300_BTST:
860 	case H8300_BILD_IMM2R8:
861 	case H8300_BOR_BIOR:
862 	case H8300_BXOR_BIXOR:
863 	case H8300_BNOT_2:
864 	case H8300_BSET_2:
865 		ret = decode_imm2r8(instr, cmd);
866 		break;
867 	case H8300_AND:
868 	case H8300_ADDB_DIRECT:
869 	case H8300_BCLR_R2R8:
870 	case H8300_SUB_1:
871 	case H8300_SUBX:
872 	case H8300_ADDX:
873 	case H8300_XOR:
874 	case H8300_BNOT_1:
875 	case H8300_BSET_1:
876 	case H8300_CMP_1:
877 	case H8300_MOV_1:
878 	case H8300_BTST_R2R8:
879 		ret = decode_r2r8(instr, cmd);
880 		break;
881 	case H8300_BCLR_R2IND16:
882 		switch(instr[2]) {
883 		case 0x60:
884 		case 0x61:
885 		case 0x62:
886 			ret = decode_r2ind16(instr, cmd);
887 			break;
888 		case 0x70:
889 		case 0x71:
890 		case 0x72:
891 		case 0x67:
892 		case 0x75:
893 			ret = decode_imm2ind16(instr, cmd);
894 			break;
895 		default:
896 			ret = -1;
897 		}
898 		break;
899 	case H8300_BCLR_R2ABS8:
900 		switch (instr[2]) {
901 		case 0x60:
902 		case 0x61:
903 		case 0x62:
904 			ret = decode_r2abs8(instr, cmd);
905 			break;
906 		case 0x67:
907 		case 0x70:
908 		case 0x71:
909 		case 0x72:
910 			ret = decode_imm2abs8(instr, cmd);
911 			break;
912 		default:
913 			ret = -1;
914 		}
915 		break;
916 	case H8300_BIAND_IMM2IND16:
917 		ret = decode_imm2ind16(instr, cmd);
918 		break;
919 	case H8300_BIAND_IMM2ABS8:
920 		ret = decode_imm2abs8(instr, cmd);
921 		break;
922 	case H8300_BSR:
923 		ret = decode_bsr(instr, cmd);
924 		break;
925 	case H8300_NOP:
926 		ret = decode_nop(instr, cmd);
927 		break;
928 	case H8300_DAA:
929 	case H8300_DAS:
930 	case H8300_DEC:
931 	case H8300_INC:
932 	case H8300_NOT_NEG:
933 	case H8300_ROTL:
934 	case H8300_ROTR:
935 	case H8300_SHL:
936 	case H8300_SHR:
937 		ret = decode_daa(instr, cmd);
938 		break;
939 	case H8300_DIVXU:
940 	case H8300_MULXU:
941 		ret = decode_r82r16(instr, cmd);
942 		break;
943 	case H8300_EEPMOV:
944 	case H8300_RTS:
945 	case H8300_RTE:
946 	case H8300_SLEEP:
947 		ret = decode_eepmov(instr, cmd);
948 		break;
949 	case H8300_JMP_1:
950 	case H8300_JSR_1:
951 		ret = decode_jmp_ind(instr, cmd);
952 		break;
953 	case H8300_JMP_2:
954 	case H8300_JSR_2:
955 		ret = decode_jmp_abs16(instr, cmd);
956 		break;
957 	case H8300_JMP_3:
958 	case H8300_JSR_3:
959 	case H8300_BRA:
960 	case H8300_BRN:
961 	case H8300_BHI:
962 	case H8300_BLS:
963 	case H8300_BCC:
964 	case H8300_BCS:
965 	case H8300_BNE:
966 	case H8300_BEQ:
967 	case H8300_BVC:
968 	case H8300_BVS:
969 	case H8300_BPL:
970 	case H8300_BMI:
971 	case H8300_BGE:
972 	case H8300_BLT:
973 	case H8300_BGT:
974 	case H8300_BLE:
975 		ret = decode_jmp_abs8(instr, cmd);
976 		break;
977 	case H8300_ORC:
978 	case H8300_LDC:
979 	case H8300_LDC_2:
980 	case H8300_STC:
981 	case H8300_XORC:
982 		ret = decode_ldc(instr, cmd);
983 		break;
984 	case H8300_OR:
985 		ret = decode_r2r8(instr, cmd);
986 		break;
987 	case H8300_MOV_2:
988 	case H8300_SUBW:
989 		ret = decode_r162r16(instr, cmd);
990 		break;
991 	case H8300_MOV_IMM162R16:
992 		ret = decode_imm162r16(instr, cmd);
993 		break;
994 	case H8300_MOV_IND162R16:
995 		ret = decode_ind162r16(instr, cmd);
996 		break;
997 	case H8300_MOV_DISP162R16:
998 		ret = decode_disp162r16(instr, cmd);
999 		break;
1000 	case H8300_MOV_INDINC162R16:
1001 		ret = decode_indinc162r16(instr, cmd);
1002 		break;
1003 	case H8300_MOV_ABS162R16:
1004 		ret = decode_abs162r16(instr, cmd);
1005 		break;
1006 	case H8300_MOV_R82IND16:
1007 		ret = decode_r82ind16(instr, cmd);
1008 		break;
1009 	case H8300_MOV_R82DISPR16:
1010 		ret = decode_r82dispr16(instr, cmd);
1011 		break;
1012 	case H8300_MOV_R82RDEC16:
1013 		ret = decode_r82rdec16(instr, cmd);
1014 		break;
1015 	case H8300_MOV_R82ABS16:
1016 		ret = decode_r82abs16(instr, cmd);
1017 		break;
1018 	default:
1019 		return -1;
1020 	}
1021 
1022 	return ret;
1023 }
1024