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