Mercurial > repos > blastem
comparison 68kinst.c @ 744:fc68992cf18d
Merge windows branch with latest changes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 28 May 2015 21:19:55 -0700 |
parents | f822d9216968 |
children | b1b5a7e7d955 |
comparison
equal
deleted
inserted
replaced
743:cf78cb045fa4 | 744:fc68992cf18d |
---|---|
17 return (val & 0x80) ? val | 0xFFFFFF00 : val; | 17 return (val & 0x80) ? val | 0xFFFFFF00 : val; |
18 } | 18 } |
19 | 19 |
20 uint16_t *m68k_decode_op_ex(uint16_t *cur, uint8_t mode, uint8_t reg, uint8_t size, m68k_op_info *dst) | 20 uint16_t *m68k_decode_op_ex(uint16_t *cur, uint8_t mode, uint8_t reg, uint8_t size, m68k_op_info *dst) |
21 { | 21 { |
22 uint16_t ext; | 22 uint16_t ext, tmp; |
23 dst->addr_mode = mode; | 23 dst->addr_mode = mode; |
24 switch(mode) | 24 switch(mode) |
25 { | 25 { |
26 case MODE_REG: | 26 case MODE_REG: |
27 case MODE_AREG: | 27 case MODE_AREG: |
34 ext = *(++cur); | 34 ext = *(++cur); |
35 dst->params.regs.pri = reg; | 35 dst->params.regs.pri = reg; |
36 dst->params.regs.displacement = sign_extend16(ext); | 36 dst->params.regs.displacement = sign_extend16(ext); |
37 break; | 37 break; |
38 case MODE_AREG_INDEX_MEM: | 38 case MODE_AREG_INDEX_MEM: |
39 #ifdef M68020 | 39 dst->params.regs.pri = reg; |
40 //TODO: implement me for M68020+ support | 40 ext = *(++cur); |
41 #else | 41 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit |
42 #ifdef M68020 | |
43 dst->params.regs.scale = ext >> 9 & 3; | |
44 if (ext & 0x100) | |
45 { | |
46 dst->params.regs.disp_sizes = ext >> 4 & 3; | |
47 switch (dst->params.regs.disp_sizes) | |
48 { | |
49 case 0: | |
50 //reserved | |
51 return NULL; | |
52 case 1: | |
53 dst->params.regs.displacement = 0; | |
54 break; | |
55 case 2: | |
56 dst->params.regs.displacement = sign_extend16(*(cur++)); | |
57 break; | |
58 case 3: | |
59 tmp = *(cur++); | |
60 dst->params.regs.displacement = tmp << 16 | *(cur++); | |
61 break; | |
62 } | |
63 if (ext & 0x3) | |
64 { | |
65 //memory indirect | |
66 switch (ext & 0xC4) | |
67 { | |
68 case 0x00: | |
69 dst->addr_mode = MODE_AREG_PREINDEX; | |
70 break; | |
71 case 0x04: | |
72 dst->addr_mode = MODE_AREG_POSTINDEX; | |
73 break; | |
74 case 0x40: | |
75 dst->addr_mode = MODE_AREG_MEM_INDIRECT; | |
76 break; | |
77 case 0x80: | |
78 dst->addr_mode = MODE_PREINDEX; | |
79 break; | |
80 case 0x84: | |
81 dst->addr_mode = MODE_POSTINDEX; | |
82 break; | |
83 case 0xC0: | |
84 dst->addr_mode = MODE_MEM_INDIRECT; | |
85 break; | |
86 } | |
87 dst->params.regs.disp_sizes |= ext << 4 & 0x30; | |
88 switch (ext & 0x3) | |
89 { | |
90 case 0: | |
91 //reserved | |
92 return NULL; | |
93 case 1: | |
94 dst->params.regs.outer_disp = 0; | |
95 break; | |
96 case 2: | |
97 dst->params.regs.outer_disp = sign_extend16(*(cur++)); | |
98 break; | |
99 case 3: | |
100 tmp = *(cur++); | |
101 dst->params.regs.outer_disp = tmp << 16 | *(cur++); | |
102 break; | |
103 } | |
104 } else { | |
105 switch (ext >> 6 & 3) | |
106 { | |
107 case 0: | |
108 dst->addr_mode = MODE_AREG_INDEX_BASE_DISP; | |
109 break; | |
110 case 1: | |
111 dst->addr_mode = MODE_AREG_BASE_DISP; | |
112 break; | |
113 case 2: | |
114 dst->addr_mode = MODE_INDEX_BASE_DISP; | |
115 break; | |
116 case 3: | |
117 dst->addr_mode = MODE_BASE_DISP; | |
118 break; | |
119 } | |
120 } | |
121 } else { | |
122 #endif | |
42 dst->addr_mode = MODE_AREG_INDEX_DISP8; | 123 dst->addr_mode = MODE_AREG_INDEX_DISP8; |
43 dst->params.regs.pri = reg; | |
44 ext = *(++cur); | |
45 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit | |
46 dst->params.regs.displacement = sign_extend8(ext&0xFF); | 124 dst->params.regs.displacement = sign_extend8(ext&0xFF); |
47 #endif | 125 #ifdef M68020 |
126 } | |
127 #endif | |
48 break; | 128 break; |
49 case MODE_PC_INDIRECT_ABS_IMMED: | 129 case MODE_PC_INDIRECT_ABS_IMMED: |
50 switch(reg) | 130 switch(reg) |
51 { | 131 { |
52 case 0: | 132 case 0: |
58 dst->addr_mode = MODE_ABSOLUTE; | 138 dst->addr_mode = MODE_ABSOLUTE; |
59 ext = *(++cur); | 139 ext = *(++cur); |
60 dst->params.immed = ext << 16 | *(++cur); | 140 dst->params.immed = ext << 16 | *(++cur); |
61 break; | 141 break; |
62 case 3: | 142 case 3: |
63 #ifdef M68020 | |
64 //TODO: Implement me for M68020+ support; | |
65 #else | |
66 dst->addr_mode = MODE_PC_INDEX_DISP8; | |
67 ext = *(++cur); | 143 ext = *(++cur); |
68 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit | 144 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit |
69 dst->params.regs.displacement = sign_extend8(ext&0xFF); | 145 #ifdef M68020 |
146 dst->params.regs.scale = ext >> 9 & 3; | |
147 if (ext & 0x100) | |
148 { | |
149 dst->params.regs.disp_sizes = ext >> 4 & 3; | |
150 switch (dst->params.regs.disp_sizes) | |
151 { | |
152 case 0: | |
153 //reserved | |
154 return NULL; | |
155 case 1: | |
156 dst->params.regs.displacement = 0; | |
157 break; | |
158 case 2: | |
159 dst->params.regs.displacement = sign_extend16(*(cur++)); | |
160 break; | |
161 case 3: | |
162 tmp = *(cur++); | |
163 dst->params.regs.displacement = tmp << 16 | *(cur++); | |
164 break; | |
165 } | |
166 if (ext & 0x3) | |
167 { | |
168 //memory indirect | |
169 switch (ext & 0xC4) | |
170 { | |
171 case 0x00: | |
172 dst->addr_mode = MODE_PC_PREINDEX; | |
173 break; | |
174 case 0x04: | |
175 dst->addr_mode = MODE_PC_POSTINDEX; | |
176 break; | |
177 case 0x40: | |
178 dst->addr_mode = MODE_PC_MEM_INDIRECT; | |
179 break; | |
180 case 0x80: | |
181 dst->addr_mode = MODE_ZPC_PREINDEX; | |
182 break; | |
183 case 0x84: | |
184 dst->addr_mode = MODE_ZPC_POSTINDEX; | |
185 break; | |
186 case 0xC0: | |
187 dst->addr_mode = MODE_ZPC_MEM_INDIRECT; | |
188 break; | |
189 } | |
190 dst->params.regs.disp_sizes |= ext << 4 & 0x30; | |
191 switch (ext & 0x3) | |
192 { | |
193 case 0: | |
194 //reserved | |
195 return NULL; | |
196 case 1: | |
197 dst->params.regs.outer_disp = 0; | |
198 break; | |
199 case 2: | |
200 dst->params.regs.outer_disp = sign_extend16(*(cur++)); | |
201 break; | |
202 case 3: | |
203 tmp = *(cur++); | |
204 dst->params.regs.outer_disp = tmp << 16 | *(cur++); | |
205 break; | |
206 } | |
207 } else { | |
208 switch (ext >> 6 & 3) | |
209 { | |
210 case 0: | |
211 dst->addr_mode = MODE_PC_INDEX_BASE_DISP; | |
212 break; | |
213 case 1: | |
214 dst->addr_mode = MODE_PC_BASE_DISP; | |
215 break; | |
216 case 2: | |
217 dst->addr_mode = MODE_ZPC_INDEX_BASE_DISP; | |
218 break; | |
219 case 3: | |
220 dst->addr_mode = MODE_ZPC_BASE_DISP; | |
221 break; | |
222 } | |
223 } | |
224 } else { | |
225 #endif | |
226 dst->addr_mode = MODE_PC_INDEX_DISP8; | |
227 dst->params.regs.displacement = sign_extend8(ext&0xFF); | |
228 #ifdef M68020 | |
229 } | |
70 #endif | 230 #endif |
71 break; | 231 break; |
72 case 2: | 232 case 2: |
73 dst->addr_mode = MODE_PC_DISPLACE; | 233 dst->addr_mode = MODE_PC_DISPLACE; |
74 ext = *(++cur); | 234 ext = *(++cur); |
170 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 330 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
171 decoded->extra.size = OPSIZE_BYTE; | 331 decoded->extra.size = OPSIZE_BYTE; |
172 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); | 332 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); |
173 if (!istream) { | 333 if (!istream) { |
174 decoded->op = M68K_INVALID; | 334 decoded->op = M68K_INVALID; |
175 return start+1; | 335 break; |
176 } | 336 } |
177 if (decoded->dst.addr_mode == MODE_REG) { | 337 if (decoded->dst.addr_mode == MODE_REG) { |
178 decoded->extra.size = OPSIZE_LONG; | 338 decoded->extra.size = OPSIZE_LONG; |
179 } | 339 } |
180 } else if ((*istream & 0xF00) == 0x800) { | 340 } else if ((*istream & 0xF00) == 0x800) { |
200 decoded->src.params.immed = *(++istream) & 0xFF; | 360 decoded->src.params.immed = *(++istream) & 0xFF; |
201 decoded->extra.size = OPSIZE_BYTE; | 361 decoded->extra.size = OPSIZE_BYTE; |
202 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 362 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
203 if (!istream) { | 363 if (!istream) { |
204 decoded->op = M68K_INVALID; | 364 decoded->op = M68K_INVALID; |
205 return start+1; | 365 break; |
206 } | 366 } |
207 if (decoded->dst.addr_mode == MODE_REG) { | 367 if (decoded->dst.addr_mode == MODE_REG) { |
208 decoded->extra.size = OPSIZE_LONG; | 368 decoded->extra.size = OPSIZE_LONG; |
209 } | 369 } |
210 } else if ((*istream & 0xC0) == 0xC0) { | 370 } else if ((*istream & 0xC0) == 0xC0) { |
246 break; | 406 break; |
247 } | 407 } |
248 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 408 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
249 if (!istream) { | 409 if (!istream) { |
250 decoded->op = M68K_INVALID; | 410 decoded->op = M68K_INVALID; |
251 return start+1; | 411 break; |
252 } | 412 } |
253 } | 413 } |
254 break; | 414 break; |
255 case 1: | 415 case 1: |
256 //ANDI, ANDI to CCR, ANDI to SR | 416 //ANDI, ANDI to CCR, ANDI to SR |
285 break; | 445 break; |
286 } | 446 } |
287 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 447 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
288 if (!istream) { | 448 if (!istream) { |
289 decoded->op = M68K_INVALID; | 449 decoded->op = M68K_INVALID; |
290 return start+1; | 450 break; |
291 } | 451 } |
292 } | 452 } |
293 break; | 453 break; |
294 case 2: | 454 case 2: |
295 decoded->op = M68K_SUB; | 455 decoded->op = M68K_SUB; |
312 break; | 472 break; |
313 } | 473 } |
314 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 474 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
315 if (!istream) { | 475 if (!istream) { |
316 decoded->op = M68K_INVALID; | 476 decoded->op = M68K_INVALID; |
317 return start+1; | 477 break; |
318 } | 478 } |
319 break; | 479 break; |
320 case 3: | 480 case 3: |
321 decoded->op = M68K_ADD; | 481 decoded->op = M68K_ADD; |
322 decoded->variant = VAR_IMMEDIATE; | 482 decoded->variant = VAR_IMMEDIATE; |
338 break; | 498 break; |
339 } | 499 } |
340 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 500 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
341 if (!istream) { | 501 if (!istream) { |
342 decoded->op = M68K_INVALID; | 502 decoded->op = M68K_INVALID; |
343 return start+1; | 503 break; |
344 } | 504 } |
345 break; | 505 break; |
346 case 4: | 506 case 4: |
347 //BTST, BCHG, BCLR, BSET | 507 //BTST, BCHG, BCLR, BSET |
348 switch ((*istream >> 6) & 0x3) | 508 switch ((*istream >> 6) & 0x3) |
363 decoded->src.addr_mode = MODE_IMMEDIATE; | 523 decoded->src.addr_mode = MODE_IMMEDIATE; |
364 decoded->src.params.immed = *(++istream) & 0xFF; | 524 decoded->src.params.immed = *(++istream) & 0xFF; |
365 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 525 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); |
366 if (!istream) { | 526 if (!istream) { |
367 decoded->op = M68K_INVALID; | 527 decoded->op = M68K_INVALID; |
368 return start+1; | 528 break; |
369 } | 529 } |
370 break; | 530 break; |
371 case 5: | 531 case 5: |
372 //EORI, EORI to CCR, EORI to SR | 532 //EORI, EORI to CCR, EORI to SR |
373 if ((*istream & 0xFF) == 0x3C) { | 533 if ((*istream & 0xFF) == 0x3C) { |
401 break; | 561 break; |
402 } | 562 } |
403 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 563 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
404 if (!istream) { | 564 if (!istream) { |
405 decoded->op = M68K_INVALID; | 565 decoded->op = M68K_INVALID; |
406 return start+1; | 566 break; |
407 } | 567 } |
408 } | 568 } |
409 break; | 569 break; |
410 case 6: | 570 case 6: |
411 decoded->op = M68K_CMP; | 571 decoded->op = M68K_CMP; |
425 case OPSIZE_LONG: | 585 case OPSIZE_LONG: |
426 immed = *(++istream); | 586 immed = *(++istream); |
427 decoded->src.params.immed = (immed << 16) | *(++istream); | 587 decoded->src.params.immed = (immed << 16) | *(++istream); |
428 break; | 588 break; |
429 } | 589 } |
430 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 590 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
431 if (!istream) { | 591 if (!istream) { |
432 decoded->op = M68K_INVALID; | 592 decoded->op = M68K_INVALID; |
433 return start+1; | 593 break; |
434 } | 594 } |
435 break; | 595 break; |
436 case 7: | 596 case 7: |
437 | 597 #ifdef M68010 |
438 | 598 decoded->op = M68K_MOVES; |
599 decoded->extra.size = *istream >> 6 & 0x3; | |
600 immed = *(++istream); | |
601 reg = immed >> 12 & 0x7; | |
602 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; | |
603 if (immed & 0x800) { | |
604 decoded->src.addr_mode = opmode; | |
605 decoded->src.params.regs.pri = reg; | |
606 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->dst)); | |
607 } else { | |
608 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->src)); | |
609 decoded->dst.addr_mode = opmode; | |
610 decoded->dst.params.regs.pri = reg; | |
611 } | |
612 #endif | |
439 break; | 613 break; |
440 } | 614 } |
441 } | 615 } |
442 break; | 616 break; |
443 case MOVE_BYTE: | 617 case MOVE_BYTE: |
448 opmode = (*istream >> 6) & 0x7; | 622 opmode = (*istream >> 6) & 0x7; |
449 reg = m68k_reg_quick_field(*istream); | 623 reg = m68k_reg_quick_field(*istream); |
450 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 624 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
451 if (!istream) { | 625 if (!istream) { |
452 decoded->op = M68K_INVALID; | 626 decoded->op = M68K_INVALID; |
453 return start+1; | 627 break; |
454 } | 628 } |
455 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 629 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
456 if (!istream || decoded->dst.addr_mode == MODE_IMMEDIATE) { | 630 if (!istream || decoded->dst.addr_mode == MODE_IMMEDIATE) { |
457 decoded->op = M68K_INVALID; | 631 decoded->op = M68K_INVALID; |
458 return start+1; | 632 break; |
459 } | 633 } |
460 break; | 634 break; |
461 case MISC: | 635 case MISC: |
462 | 636 |
463 if ((*istream & 0x1C0) == 0x1C0) { | 637 if ((*istream & 0x1C0) == 0x1C0) { |
466 decoded->dst.addr_mode = MODE_AREG; | 640 decoded->dst.addr_mode = MODE_AREG; |
467 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 641 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
468 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 642 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
469 if (!istream) { | 643 if (!istream) { |
470 decoded->op = M68K_INVALID; | 644 decoded->op = M68K_INVALID; |
471 return start+1; | 645 break; |
472 } | 646 } |
473 } else { | 647 } else { |
474 if (*istream & 0x100) { | 648 if (*istream & 0x100) { |
475 decoded->op = M68K_CHK; | 649 decoded->op = M68K_CHK; |
476 if ((*istream & 0x180) == 0x180) { | 650 if ((*istream & 0x180) == 0x180) { |
487 decoded->dst.addr_mode = MODE_REG; | 661 decoded->dst.addr_mode = MODE_REG; |
488 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 662 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
489 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 663 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
490 if (!istream) { | 664 if (!istream) { |
491 decoded->op = M68K_INVALID; | 665 decoded->op = M68K_INVALID; |
492 return start+1; | 666 break; |
493 } | 667 } |
494 } else { | 668 } else { |
495 opmode = (*istream >> 3) & 0x7; | 669 opmode = (*istream >> 3) & 0x7; |
496 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { | 670 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { |
497 //TODO: Check for invalid modes that are dependent on direction | 671 //TODO: Check for invalid modes that are dependent on direction |
502 decoded->dst.addr_mode = MODE_REG; | 676 decoded->dst.addr_mode = MODE_REG; |
503 decoded->dst.params.immed = *(++istream); | 677 decoded->dst.params.immed = *(++istream); |
504 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); | 678 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); |
505 if (!istream) { | 679 if (!istream) { |
506 decoded->op = M68K_INVALID; | 680 decoded->op = M68K_INVALID; |
507 return start+1; | 681 break; |
508 } | 682 } |
509 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) { | 683 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) { |
510 //adjust displacement to account for extra instruction word | 684 //adjust displacement to account for extra instruction word |
511 decoded->src.params.regs.displacement += 2; | 685 decoded->src.params.regs.displacement += 2; |
512 } | 686 } |
514 decoded->src.addr_mode = MODE_REG; | 688 decoded->src.addr_mode = MODE_REG; |
515 decoded->src.params.immed = *(++istream); | 689 decoded->src.params.immed = *(++istream); |
516 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 690 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
517 if (!istream) { | 691 if (!istream) { |
518 decoded->op = M68K_INVALID; | 692 decoded->op = M68K_INVALID; |
519 return start+1; | 693 break; |
520 } | 694 } |
521 } | 695 } |
522 } else { | 696 } else { |
523 optype = (*istream >> 9) & 0x7; | 697 optype = (*istream >> 9) & 0x7; |
524 size = (*istream >> 6) & 0x3; | 698 size = (*istream >> 6) & 0x3; |
534 } | 708 } |
535 decoded->extra.size = size; | 709 decoded->extra.size = size; |
536 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 710 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
537 if (!istream) { | 711 if (!istream) { |
538 decoded->op = M68K_INVALID; | 712 decoded->op = M68K_INVALID; |
539 return start+1; | 713 break; |
540 } | 714 } |
541 break; | 715 break; |
542 case 1: | 716 case 1: |
543 //MOVE from CCR or CLR | 717 //MOVE from CCR or CLR |
544 if (size == OPSIZE_INVALID) { | 718 if (size == OPSIZE_INVALID) { |
545 #ifdef M68010 | 719 #ifdef M68010 |
546 decoded->op = M68K_MOVE_FROM_CCR; | 720 decoded->op = M68K_MOVE_FROM_CCR; |
547 size = OPSIZE_WORD; | 721 size = OPSIZE_WORD; |
548 #else | 722 #else |
549 return istream+1; | 723 break; |
550 #endif | 724 #endif |
551 } else { | 725 } else { |
552 decoded->op = M68K_CLR; | 726 decoded->op = M68K_CLR; |
553 } | 727 } |
554 decoded->extra.size = size; | 728 decoded->extra.size = size; |
555 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 729 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
556 if (!istream) { | 730 if (!istream) { |
557 decoded->op = M68K_INVALID; | 731 decoded->op = M68K_INVALID; |
558 return start+1; | 732 break; |
559 } | 733 } |
560 break; | 734 break; |
561 case 2: | 735 case 2: |
562 //MOVE to CCR or NEG | 736 //MOVE to CCR or NEG |
563 if (size == OPSIZE_INVALID) { | 737 if (size == OPSIZE_INVALID) { |
564 decoded->op = M68K_MOVE_CCR; | 738 decoded->op = M68K_MOVE_CCR; |
565 size = OPSIZE_WORD; | 739 size = OPSIZE_WORD; |
566 istream= m68k_decode_op(istream, size, &(decoded->src)); | 740 istream= m68k_decode_op(istream, size, &(decoded->src)); |
567 if (!istream) { | 741 if (!istream) { |
568 decoded->op = M68K_INVALID; | 742 decoded->op = M68K_INVALID; |
569 return start+1; | 743 break; |
570 } | 744 } |
571 } else { | 745 } else { |
572 decoded->op = M68K_NEG; | 746 decoded->op = M68K_NEG; |
573 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 747 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
574 if (!istream) { | 748 if (!istream) { |
575 decoded->op = M68K_INVALID; | 749 decoded->op = M68K_INVALID; |
576 return start+1; | 750 break; |
577 } | 751 } |
578 } | 752 } |
579 decoded->extra.size = size; | 753 decoded->extra.size = size; |
580 break; | 754 break; |
581 case 3: | 755 case 3: |
584 decoded->op = M68K_MOVE_SR; | 758 decoded->op = M68K_MOVE_SR; |
585 size = OPSIZE_WORD; | 759 size = OPSIZE_WORD; |
586 istream= m68k_decode_op(istream, size, &(decoded->src)); | 760 istream= m68k_decode_op(istream, size, &(decoded->src)); |
587 if (!istream) { | 761 if (!istream) { |
588 decoded->op = M68K_INVALID; | 762 decoded->op = M68K_INVALID; |
589 return start+1; | 763 break; |
590 } | 764 } |
591 } else { | 765 } else { |
592 decoded->op = M68K_NOT; | 766 decoded->op = M68K_NOT; |
593 istream= m68k_decode_op(istream, size, &(decoded->dst)); | 767 istream= m68k_decode_op(istream, size, &(decoded->dst)); |
594 if (!istream) { | 768 if (!istream) { |
595 decoded->op = M68K_INVALID; | 769 decoded->op = M68K_INVALID; |
596 return start+1; | 770 break; |
597 } | 771 } |
598 } | 772 } |
599 decoded->extra.size = size; | 773 decoded->extra.size = size; |
600 break; | 774 break; |
601 case 4: | 775 case 4: |
646 decoded->op = M68K_NBCD; | 820 decoded->op = M68K_NBCD; |
647 decoded->extra.size = OPSIZE_BYTE; | 821 decoded->extra.size = OPSIZE_BYTE; |
648 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 822 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); |
649 if (!istream) { | 823 if (!istream) { |
650 decoded->op = M68K_INVALID; | 824 decoded->op = M68K_INVALID; |
651 return start+1; | 825 break; |
652 } | 826 } |
653 } else if((*istream & 0x1C0) == 0x40) { | 827 } else if((*istream & 0x1C0) == 0x40) { |
654 decoded->op = M68K_PEA; | 828 decoded->op = M68K_PEA; |
655 decoded->extra.size = OPSIZE_LONG; | 829 decoded->extra.size = OPSIZE_LONG; |
656 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 830 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); |
657 if (!istream) { | 831 if (!istream) { |
658 decoded->op = M68K_INVALID; | 832 decoded->op = M68K_INVALID; |
659 return start+1; | 833 break; |
660 } | 834 } |
661 } | 835 } |
662 } | 836 } |
663 break; | 837 break; |
664 case 5: | 838 case 5: |
676 decoded->op = M68K_TST; | 850 decoded->op = M68K_TST; |
677 decoded->extra.size = size; | 851 decoded->extra.size = size; |
678 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 852 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
679 if (!istream) { | 853 if (!istream) { |
680 decoded->op = M68K_INVALID; | 854 decoded->op = M68K_INVALID; |
681 return start+1; | 855 break; |
682 } | 856 } |
683 } | 857 } |
684 } | 858 } |
685 break; | 859 break; |
686 case 6: | 860 case 6: |
700 } | 874 } |
701 decoded->extra.size = OPSIZE_UNSIZED; | 875 decoded->extra.size = OPSIZE_UNSIZED; |
702 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src)); | 876 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src)); |
703 if (!istream) { | 877 if (!istream) { |
704 decoded->op = M68K_INVALID; | 878 decoded->op = M68K_INVALID; |
705 return start+1; | 879 break; |
706 } | 880 } |
707 } else { | 881 } else { |
708 //it would appear bit 6 needs to be set for it to be a valid instruction here | 882 //it would appear bit 6 needs to be set for it to be a valid instruction here |
709 switch((*istream >> 3) & 0x7) | 883 switch((*istream >> 3) & 0x7) |
710 { | 884 { |
781 } | 955 } |
782 break; | 956 break; |
783 case 7: | 957 case 7: |
784 //MOVEC | 958 //MOVEC |
785 #ifdef M68010 | 959 #ifdef M68010 |
960 decoded->op = M68K_MOVEC; | |
961 immed = *(++istream); | |
962 reg = immed >> 12 & 0x7; | |
963 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; | |
964 immed &= 0xFFF; | |
965 if (immed & 0x800) { | |
966 if (immed > MAX_HIGH_CR) { | |
967 decoded->op = M68K_INVALID; | |
968 break; | |
969 } else { | |
970 immed = immed - 0x800 + CR_USP; | |
971 } | |
972 } else { | |
973 if (immed > MAX_LOW_CR) { | |
974 decoded->op = M68K_INVALID; | |
975 break; | |
976 } | |
977 } | |
978 if (*start & 1) { | |
979 decoded->src.addr_mode = opmode; | |
980 decoded->src.params.regs.pri = reg; | |
981 decoded->dst.params.immed = immed; | |
982 } else { | |
983 decoded->dst.addr_mode = opmode; | |
984 decoded->dst.params.regs.pri = reg; | |
985 decoded->src.params.immed = immed; | |
986 } | |
786 #endif | 987 #endif |
787 break; | 988 break; |
788 } | 989 } |
789 } | 990 } |
790 break; | 991 break; |
814 decoded->op = M68K_SCC; | 1015 decoded->op = M68K_SCC; |
815 decoded->extra.cond = (*istream >> 8) & 0xF; | 1016 decoded->extra.cond = (*istream >> 8) & 0xF; |
816 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 1017 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); |
817 if (!istream) { | 1018 if (!istream) { |
818 decoded->op = M68K_INVALID; | 1019 decoded->op = M68K_INVALID; |
819 return start+1; | 1020 break; |
820 } | 1021 } |
821 } | 1022 } |
822 } else { | 1023 } else { |
823 //ADDQ, SUBQ | 1024 //ADDQ, SUBQ |
824 decoded->variant = VAR_QUICK; | 1025 decoded->variant = VAR_QUICK; |
835 decoded->op = M68K_ADD; | 1036 decoded->op = M68K_ADD; |
836 } | 1037 } |
837 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1038 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
838 if (!istream) { | 1039 if (!istream) { |
839 decoded->op = M68K_INVALID; | 1040 decoded->op = M68K_INVALID; |
840 return start+1; | 1041 break; |
841 } | 1042 } |
842 } | 1043 } |
843 break; | 1044 break; |
844 case BRANCH: | 1045 case BRANCH: |
845 m68k_decode_cond(*istream, decoded); | 1046 m68k_decode_cond(*istream, decoded); |
863 decoded->src.params.immed = immed; | 1064 decoded->src.params.immed = immed; |
864 break; | 1065 break; |
865 case MOVEQ: | 1066 case MOVEQ: |
866 if (*istream & 0x100) { | 1067 if (*istream & 0x100) { |
867 decoded->op = M68K_INVALID; | 1068 decoded->op = M68K_INVALID; |
868 return start+1; | 1069 break; |
869 } | 1070 } |
870 decoded->op = M68K_MOVE; | 1071 decoded->op = M68K_MOVE; |
871 decoded->variant = VAR_QUICK; | 1072 decoded->variant = VAR_QUICK; |
872 decoded->extra.size = OPSIZE_LONG; | 1073 decoded->extra.size = OPSIZE_LONG; |
873 decoded->src.addr_mode = MODE_IMMEDIATE; | 1074 decoded->src.addr_mode = MODE_IMMEDIATE; |
889 decoded->dst.addr_mode = MODE_REG; | 1090 decoded->dst.addr_mode = MODE_REG; |
890 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1091 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; |
891 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1092 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
892 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1093 if (!istream || decoded->src.addr_mode == MODE_AREG) { |
893 decoded->op = M68K_INVALID; | 1094 decoded->op = M68K_INVALID; |
894 return start+1; | 1095 break; |
895 } | 1096 } |
896 break; | 1097 break; |
897 case 4: | 1098 case 4: |
898 decoded->op = M68K_SBCD; | 1099 decoded->op = M68K_SBCD; |
1100 decoded->extra.size = OPSIZE_BYTE; | |
899 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG; | 1101 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG; |
900 decoded->src.params.regs.pri = *istream & 0x7; | 1102 decoded->src.params.regs.pri = *istream & 0x7; |
901 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1103 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; |
902 break; | 1104 break; |
903 case 5: | 1105 case 5: |
914 decoded->dst.addr_mode = MODE_REG; | 1116 decoded->dst.addr_mode = MODE_REG; |
915 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1117 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; |
916 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1118 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
917 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 1119 if (!istream || decoded->src.addr_mode == MODE_AREG) { |
918 decoded->op = M68K_INVALID; | 1120 decoded->op = M68K_INVALID; |
919 return start+1; | 1121 break; |
920 } | 1122 } |
921 break; | 1123 break; |
922 } | 1124 } |
923 } else { | 1125 } else { |
924 decoded->op = M68K_OR; | 1126 decoded->op = M68K_OR; |
927 decoded->src.addr_mode = MODE_REG; | 1129 decoded->src.addr_mode = MODE_REG; |
928 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; | 1130 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; |
929 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1131 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
930 if (!istream) { | 1132 if (!istream) { |
931 decoded->op = M68K_INVALID; | 1133 decoded->op = M68K_INVALID; |
932 return start+1; | 1134 break; |
933 } | 1135 } |
934 } else { | 1136 } else { |
935 decoded->dst.addr_mode = MODE_REG; | 1137 decoded->dst.addr_mode = MODE_REG; |
936 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; | 1138 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; |
937 istream = m68k_decode_op(istream, size, &(decoded->src)); | 1139 istream = m68k_decode_op(istream, size, &(decoded->src)); |
938 if (!istream) { | 1140 if (!istream) { |
939 decoded->op = M68K_INVALID; | 1141 decoded->op = M68K_INVALID; |
940 return start+1; | 1142 break; |
941 } | 1143 } |
942 } | 1144 } |
943 } | 1145 } |
944 break; | 1146 break; |
945 case SUB_SUBX: | 1147 case SUB_SUBX: |
954 decoded->dst.addr_mode = MODE_AREG; | 1156 decoded->dst.addr_mode = MODE_AREG; |
955 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1157 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
956 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 1158 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); |
957 if (!istream) { | 1159 if (!istream) { |
958 decoded->op = M68K_INVALID; | 1160 decoded->op = M68K_INVALID; |
959 return start+1; | 1161 break; |
960 } | 1162 } |
961 } else { | 1163 } else { |
962 decoded->extra.size = size; | 1164 decoded->extra.size = size; |
963 decoded->src.addr_mode = MODE_REG; | 1165 decoded->src.addr_mode = MODE_REG; |
964 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1166 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
965 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1167 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
966 if (!istream) { | 1168 if (!istream) { |
967 decoded->op = M68K_INVALID; | 1169 decoded->op = M68K_INVALID; |
968 return start+1; | 1170 break; |
969 } | 1171 } |
970 } | 1172 } |
971 } else { | 1173 } else { |
972 //SUBX | 1174 //SUBX |
973 decoded->op = M68K_SUBX; | 1175 decoded->op = M68K_SUBX; |
991 } | 1193 } |
992 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1194 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
993 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1195 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
994 if (!istream) { | 1196 if (!istream) { |
995 decoded->op = M68K_INVALID; | 1197 decoded->op = M68K_INVALID; |
996 return start+1; | 1198 break; |
997 } | 1199 } |
998 } | 1200 } |
999 break; | 1201 break; |
1000 case RESERVED: | 1202 case RESERVED: |
1001 break; | 1203 break; |
1009 decoded->dst.addr_mode = MODE_AREG; | 1211 decoded->dst.addr_mode = MODE_AREG; |
1010 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1212 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1011 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1213 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
1012 if (!istream) { | 1214 if (!istream) { |
1013 decoded->op = M68K_INVALID; | 1215 decoded->op = M68K_INVALID; |
1014 return start+1; | 1216 break; |
1015 } | 1217 } |
1016 } else { | 1218 } else { |
1017 reg = m68k_reg_quick_field(*istream); | 1219 reg = m68k_reg_quick_field(*istream); |
1018 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1220 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
1019 if (!istream) { | 1221 if (!istream) { |
1020 decoded->op = M68K_INVALID; | 1222 decoded->op = M68K_INVALID; |
1021 return start+1; | 1223 break; |
1022 } | 1224 } |
1023 decoded->extra.size = size; | 1225 decoded->extra.size = size; |
1024 if (decoded->dst.addr_mode == MODE_AREG) { | 1226 if (decoded->dst.addr_mode == MODE_AREG) { |
1025 //CMPM | 1227 //CMPM |
1026 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; | 1228 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; |
1044 } | 1246 } |
1045 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1247 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1046 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1248 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
1047 if (!istream) { | 1249 if (!istream) { |
1048 decoded->op = M68K_INVALID; | 1250 decoded->op = M68K_INVALID; |
1049 return start+1; | 1251 break; |
1050 } | 1252 } |
1051 } | 1253 } |
1052 break; | 1254 break; |
1053 case AND_MUL_ABCD_EXG: | 1255 case AND_MUL_ABCD_EXG: |
1054 //page 575 for summary | 1256 //page 575 for summary |
1067 decoded->dst.addr_mode = MODE_REG; | 1269 decoded->dst.addr_mode = MODE_REG; |
1068 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1270 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1069 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1271 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
1070 if (!istream) { | 1272 if (!istream) { |
1071 decoded->op = M68K_INVALID; | 1273 decoded->op = M68K_INVALID; |
1072 return start+1; | 1274 break; |
1073 } | 1275 } |
1074 } else if(!(*istream & 0xF0)) { | 1276 } else if(!(*istream & 0xF0)) { |
1075 decoded->op = M68K_ABCD; | 1277 decoded->op = M68K_ABCD; |
1076 decoded->extra.size = OPSIZE_BYTE; | 1278 decoded->extra.size = OPSIZE_BYTE; |
1077 decoded->src.params.regs.pri = *istream & 0x7; | 1279 decoded->src.params.regs.pri = *istream & 0x7; |
1098 decoded->src.addr_mode = MODE_REG; | 1300 decoded->src.addr_mode = MODE_REG; |
1099 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1301 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
1100 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); | 1302 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); |
1101 if (!istream) { | 1303 if (!istream) { |
1102 decoded->op = M68K_INVALID; | 1304 decoded->op = M68K_INVALID; |
1103 return start+1; | 1305 break; |
1104 } | 1306 } |
1105 } | 1307 } |
1106 } else { | 1308 } else { |
1107 if ((*istream & 0xC0) == 0xC0) { | 1309 if ((*istream & 0xC0) == 0xC0) { |
1108 decoded->op = M68K_MULU; | 1310 decoded->op = M68K_MULU; |
1110 decoded->dst.addr_mode = MODE_REG; | 1312 decoded->dst.addr_mode = MODE_REG; |
1111 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1313 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1112 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 1314 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
1113 if (!istream) { | 1315 if (!istream) { |
1114 decoded->op = M68K_INVALID; | 1316 decoded->op = M68K_INVALID; |
1115 return start+1; | 1317 break; |
1116 } | 1318 } |
1117 } else { | 1319 } else { |
1118 decoded->op = M68K_AND; | 1320 decoded->op = M68K_AND; |
1119 decoded->extra.size = (*istream >> 6) & 0x3; | 1321 decoded->extra.size = (*istream >> 6) & 0x3; |
1120 decoded->dst.addr_mode = MODE_REG; | 1322 decoded->dst.addr_mode = MODE_REG; |
1121 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1323 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1122 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1324 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
1123 if (!istream) { | 1325 if (!istream) { |
1124 decoded->op = M68K_INVALID; | 1326 decoded->op = M68K_INVALID; |
1125 return start+1; | 1327 break; |
1126 } | 1328 } |
1127 } | 1329 } |
1128 } | 1330 } |
1129 break; | 1331 break; |
1130 case ADD_ADDX: | 1332 case ADD_ADDX: |
1139 decoded->dst.addr_mode = MODE_AREG; | 1341 decoded->dst.addr_mode = MODE_AREG; |
1140 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1342 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1141 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); | 1343 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); |
1142 if (!istream) { | 1344 if (!istream) { |
1143 decoded->op = M68K_INVALID; | 1345 decoded->op = M68K_INVALID; |
1144 return start+1; | 1346 break; |
1145 } | 1347 } |
1146 } else { | 1348 } else { |
1147 decoded->extra.size = size; | 1349 decoded->extra.size = size; |
1148 decoded->src.addr_mode = MODE_REG; | 1350 decoded->src.addr_mode = MODE_REG; |
1149 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1351 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); |
1150 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1352 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
1151 if (!istream) { | 1353 if (!istream) { |
1152 decoded->op = M68K_INVALID; | 1354 decoded->op = M68K_INVALID; |
1153 return start+1; | 1355 break; |
1154 } | 1356 } |
1155 } | 1357 } |
1156 } else { | 1358 } else { |
1157 //ADDX | 1359 //ADDX |
1158 decoded->op = M68K_ADDX; | 1360 decoded->op = M68K_ADDX; |
1176 } | 1378 } |
1177 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1379 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1178 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 1380 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
1179 if (!istream) { | 1381 if (!istream) { |
1180 decoded->op = M68K_INVALID; | 1382 decoded->op = M68K_INVALID; |
1181 return start+1; | 1383 break; |
1182 } | 1384 } |
1183 } | 1385 } |
1184 break; | 1386 break; |
1185 case SHIFT_ROTATE: | 1387 case SHIFT_ROTATE: |
1186 if ((*istream & 0x8C0) == 0xC0) { | 1388 if ((*istream & 0x8C0) == 0xC0) { |
1213 } | 1415 } |
1214 decoded->extra.size = OPSIZE_WORD; | 1416 decoded->extra.size = OPSIZE_WORD; |
1215 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); | 1417 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); |
1216 if (!istream) { | 1418 if (!istream) { |
1217 decoded->op = M68K_INVALID; | 1419 decoded->op = M68K_INVALID; |
1218 return start+1; | 1420 break; |
1219 } | 1421 } |
1220 } else if((*istream & 0xC0) != 0xC0) { | 1422 } else if((*istream & 0xC0) != 0xC0) { |
1221 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) | 1423 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) |
1222 { | 1424 { |
1223 case 0: | 1425 case 0: |
1261 decoded->dst.params.regs.pri = *istream & 0x7; | 1463 decoded->dst.params.regs.pri = *istream & 0x7; |
1262 | 1464 |
1263 } else { | 1465 } else { |
1264 #ifdef M68020 | 1466 #ifdef M68020 |
1265 //TODO: Implement bitfield instructions for M68020+ support | 1467 //TODO: Implement bitfield instructions for M68020+ support |
1468 switch (*istream >> 8 & 7) | |
1469 { | |
1470 case 0: | |
1471 decoded->op = M68K_BFTST; //<ea> | |
1472 break; | |
1473 case 1: | |
1474 decoded->op = M68K_BFEXTU; //<ea>, Dn | |
1475 break; | |
1476 case 2: | |
1477 decoded->op = M68K_BFCHG; //<ea> | |
1478 break; | |
1479 case 3: | |
1480 decoded->op = M68K_BFEXTS; //<ea>, Dn | |
1481 break; | |
1482 case 4: | |
1483 decoded->op = M68K_BFCLR; //<ea> | |
1484 break; | |
1485 case 5: | |
1486 decoded->op = M68K_BFFFO; //<ea>, Dn | |
1487 break; | |
1488 case 6: | |
1489 decoded->op = M68K_BFSET; //<ea> | |
1490 break; | |
1491 case 7: | |
1492 decoded->op = M68K_BFINS; //Dn, <ea> | |
1493 break; | |
1494 } | |
1495 opmode = *istream >> 3 & 0x7; | |
1496 reg = *istream & 0x7; | |
1497 m68k_op_info *ea, *other; | |
1498 if (decoded->op == M68K_BFEXTU || decoded->op == M68K_BFEXTS || decoded->op == M68K_BFFFO) | |
1499 { | |
1500 ea = &(decoded->src); | |
1501 other = &(decoded->dst); | |
1502 } else { | |
1503 ea = &(decoded->dst); | |
1504 other = &(decoded->dst); | |
1505 } | |
1506 if (*istream & 0x100) | |
1507 { | |
1508 immed = *(istream++); | |
1509 other->addr_mode = MODE_REG; | |
1510 other->params.regs.pri = immed >> 12 & 0x7; | |
1511 } else { | |
1512 immed = *(istream++); | |
1513 } | |
1514 decoded->extra.size = OPSIZE_UNSIZED; | |
1515 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, ea); | |
1516 ea->addr_mode |= M68K_FLAG_BITFIELD; | |
1517 ea->bitfield = immed & 0xFFF; | |
1266 #endif | 1518 #endif |
1267 } | 1519 } |
1268 break; | 1520 break; |
1269 case COPROC: | 1521 case COPROC: |
1270 //TODO: Implement me | 1522 //TODO: Implement me |
1271 break; | 1523 break; |
1524 } | |
1525 if (decoded->op == M68K_INVALID) { | |
1526 decoded->src.params.immed = *start; | |
1527 return start + 1; | |
1272 } | 1528 } |
1273 return istream+1; | 1529 return istream+1; |
1274 } | 1530 } |
1275 | 1531 |
1276 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) | 1532 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) |
1414 "tas", | 1670 "tas", |
1415 "trap", | 1671 "trap", |
1416 "trapv", | 1672 "trapv", |
1417 "tst", | 1673 "tst", |
1418 "unlk", | 1674 "unlk", |
1419 "invalid" | 1675 "invalid", |
1676 #ifdef M68010 | |
1677 "bkpt", | |
1678 "move", //from ccr | |
1679 "movec", | |
1680 "moves", | |
1681 "rtd", | |
1682 #endif | |
1683 #ifdef M68020 | |
1684 "bfchg", | |
1685 "bfclr", | |
1686 "bfexts", | |
1687 "bfextu", | |
1688 "bfffo", | |
1689 "bfins", | |
1690 "bfset", | |
1691 "bftst", | |
1692 "callm", | |
1693 "cas", | |
1694 "cas2", | |
1695 "chk2", | |
1696 "cmp2", | |
1697 "cpbcc", | |
1698 "cpdbcc", | |
1699 "cpgen", | |
1700 "cprestore", | |
1701 "cpsave", | |
1702 "cpscc", | |
1703 "cptrapcc", | |
1704 "divsl", | |
1705 "divul", | |
1706 "extb", | |
1707 "pack", | |
1708 "rtm", | |
1709 "trapcc", | |
1710 "unpk" | |
1711 #endif | |
1420 }; | 1712 }; |
1421 | 1713 |
1422 char * cond_mnem[] = { | 1714 char * cond_mnem[] = { |
1423 "ra", | 1715 "ra", |
1424 "f", | 1716 "f", |
1435 "ge", | 1727 "ge", |
1436 "lt", | 1728 "lt", |
1437 "gt", | 1729 "gt", |
1438 "le" | 1730 "le" |
1439 }; | 1731 }; |
1732 #ifdef M68010 | |
1733 char * cr_mnem[] = { | |
1734 "SFC", | |
1735 "DFC", | |
1736 #ifdef M68020 | |
1737 "CACR", | |
1738 #endif | |
1739 "USP", | |
1740 "VBR", | |
1741 #ifdef M68020 | |
1742 "CAAR", | |
1743 "MSP", | |
1744 "ISP" | |
1745 #endif | |
1746 }; | |
1747 #endif | |
1440 | 1748 |
1441 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address) | 1749 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data) |
1442 { | 1750 { |
1443 char * c = need_comma ? "," : ""; | 1751 char * c = need_comma ? "," : ""; |
1444 switch(decoded->addr_mode) | 1752 int ret = 0; |
1753 #ifdef M68020 | |
1754 uint8_t addr_mode = decoded->addr_mode & (~M68K_FLAG_BITFIELD); | |
1755 #else | |
1756 uint8_t addr_mode = decoded->addr_mode; | |
1757 #endif | |
1758 switch(addr_mode) | |
1445 { | 1759 { |
1446 case MODE_REG: | 1760 case MODE_REG: |
1447 return sprintf(dst, "%s d%d", c, decoded->params.regs.pri); | 1761 ret = sprintf(dst, "%s d%d", c, decoded->params.regs.pri); |
1762 break; | |
1448 case MODE_AREG: | 1763 case MODE_AREG: |
1449 return sprintf(dst, "%s a%d", c, decoded->params.regs.pri); | 1764 ret = sprintf(dst, "%s a%d", c, decoded->params.regs.pri); |
1765 break; | |
1450 case MODE_AREG_INDIRECT: | 1766 case MODE_AREG_INDIRECT: |
1451 return sprintf(dst, "%s (a%d)", c, decoded->params.regs.pri); | 1767 ret = sprintf(dst, "%s (a%d)", c, decoded->params.regs.pri); |
1768 break; | |
1452 case MODE_AREG_POSTINC: | 1769 case MODE_AREG_POSTINC: |
1453 return sprintf(dst, "%s (a%d)+", c, decoded->params.regs.pri); | 1770 ret = sprintf(dst, "%s (a%d)+", c, decoded->params.regs.pri); |
1771 break; | |
1454 case MODE_AREG_PREDEC: | 1772 case MODE_AREG_PREDEC: |
1455 return sprintf(dst, "%s -(a%d)", c, decoded->params.regs.pri); | 1773 ret = sprintf(dst, "%s -(a%d)", c, decoded->params.regs.pri); |
1774 break; | |
1456 case MODE_AREG_DISPLACE: | 1775 case MODE_AREG_DISPLACE: |
1457 return sprintf(dst, "%s (%d, a%d)", c, decoded->params.regs.displacement, decoded->params.regs.pri); | 1776 ret = sprintf(dst, "%s (%d, a%d)", c, decoded->params.regs.displacement, decoded->params.regs.pri); |
1777 break; | |
1458 case MODE_AREG_INDEX_DISP8: | 1778 case MODE_AREG_INDEX_DISP8: |
1459 return sprintf(dst, "%s (%d, a%d, %c%d.%c)", c, decoded->params.regs.displacement, decoded->params.regs.pri, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); | 1779 #ifdef M68020 |
1780 if (decoded->params.regs.scale) | |
1781 { | |
1782 ret = sprintf(dst, "%s (%d, a%d, %c%d.%c*%d)", c, decoded->params.regs.displacement, decoded->params.regs.pri, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1783 } else { | |
1784 #endif | |
1785 ret = sprintf(dst, "%s (%d, a%d, %c%d.%c)", c, decoded->params.regs.displacement, decoded->params.regs.pri, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); | |
1786 #ifdef M68020 | |
1787 } | |
1788 #endif | |
1789 break; | |
1790 #ifdef M68020 | |
1791 case MODE_AREG_INDEX_BASE_DISP: | |
1792 if (decoded->params.regs.disp_sizes > 1) | |
1793 { | |
1794 ret = sprintf(dst, "%s (%d.%c, a%d, %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
1795 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l', decoded->params.regs.pri, | |
1796 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1797 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1798 } else { | |
1799 ret = sprintf(dst, "%s (a%d, %c%d.%c*%d)", c, decoded->params.regs.pri, | |
1800 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1801 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1802 } | |
1803 break; | |
1804 case MODE_AREG_PREINDEX: | |
1805 switch (decoded->params.regs.disp_sizes) | |
1806 { | |
1807 case 0x11: | |
1808 //no base displacement or outer displacement | |
1809 ret = sprintf(dst, "%s ([a%d, %c%d.%c*%d])", c, decoded->params.regs.pri, | |
1810 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1811 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1812 break; | |
1813 case 0x12: | |
1814 case 0x13: | |
1815 //base displacement only | |
1816 ret = sprintf(dst, "%s ([%d.%c, a%d, %c%d.%c*%d])", c, decoded->params.regs.displacement, | |
1817 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri, | |
1818 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1819 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1820 break; | |
1821 case 0x21: | |
1822 case 0x31: | |
1823 //outer displacement only | |
1824 ret = sprintf(dst, "%s ([a%d, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.pri, | |
1825 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1826 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
1827 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1828 break; | |
1829 case 0x22: | |
1830 case 0x23: | |
1831 case 0x32: | |
1832 case 0x33: | |
1833 //both outer and inner displacement | |
1834 ret = sprintf(dst, "%s ([%d.%c, a%d, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement, | |
1835 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri, | |
1836 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1837 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
1838 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1839 break; | |
1840 } | |
1841 break; | |
1842 case MODE_AREG_POSTINDEX: | |
1843 switch (decoded->params.regs.disp_sizes) | |
1844 { | |
1845 case 0x11: | |
1846 //no base displacement or outer displacement | |
1847 ret = sprintf(dst, "%s ([a%d], %c%d.%c*%d)", c, decoded->params.regs.pri, | |
1848 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1849 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1850 break; | |
1851 case 0x12: | |
1852 case 0x13: | |
1853 //base displacement only | |
1854 ret = sprintf(dst, "%s ([%d.%c, a%d], %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
1855 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri, | |
1856 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1857 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1858 break; | |
1859 case 0x21: | |
1860 case 0x31: | |
1861 //outer displacement only | |
1862 ret = sprintf(dst, "%s ([a%d], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.pri, | |
1863 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1864 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
1865 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1866 break; | |
1867 case 0x22: | |
1868 case 0x23: | |
1869 case 0x32: | |
1870 case 0x33: | |
1871 //both outer and inner displacement | |
1872 ret = sprintf(dst, "%s ([%d.%c, a%d], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement, | |
1873 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri, | |
1874 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1875 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
1876 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1877 break; | |
1878 } | |
1879 break; | |
1880 case MODE_AREG_MEM_INDIRECT: | |
1881 switch (decoded->params.regs.disp_sizes) | |
1882 { | |
1883 case 0x11: | |
1884 //no base displacement or outer displacement | |
1885 ret = sprintf(dst, "%s ([a%d])", c, decoded->params.regs.pri); | |
1886 break; | |
1887 case 0x12: | |
1888 case 0x13: | |
1889 //base displacement only | |
1890 ret = sprintf(dst, "%s ([%d.%c, a%d])", c, decoded->params.regs.displacement, | |
1891 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri); | |
1892 break; | |
1893 case 0x21: | |
1894 case 0x31: | |
1895 //outer displacement only | |
1896 ret = sprintf(dst, "%s ([a%d], %d.%c)", c, decoded->params.regs.pri, decoded->params.regs.outer_disp, | |
1897 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1898 break; | |
1899 case 0x22: | |
1900 case 0x23: | |
1901 case 0x32: | |
1902 case 0x33: | |
1903 //both outer and inner displacement | |
1904 ret = sprintf(dst, "%s ([%d.%c, a%d], %d.%c)", c, decoded->params.regs.displacement, | |
1905 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.pri, | |
1906 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1907 break; | |
1908 } | |
1909 break; | |
1910 case MODE_AREG_BASE_DISP: | |
1911 if (decoded->params.regs.disp_sizes > 1) | |
1912 { | |
1913 ret = sprintf(dst, "%s (%d.%c, a%d)", c, decoded->params.regs.displacement, | |
1914 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l', decoded->params.regs.pri); | |
1915 } else { | |
1916 //this is a lossy representation of the encoded instruction | |
1917 //not sure if there's a better way to print it though | |
1918 ret = sprintf(dst, "%s (a%d)", c, decoded->params.regs.pri); | |
1919 } | |
1920 break; | |
1921 case MODE_INDEX_BASE_DISP: | |
1922 if (decoded->params.regs.disp_sizes > 1) | |
1923 { | |
1924 ret = sprintf(dst, "%s (%d.%c, %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
1925 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l', | |
1926 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1927 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1928 } else { | |
1929 ret = sprintf(dst, "%s (%c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
1930 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
1931 1 << decoded->params.regs.scale); | |
1932 } | |
1933 break; | |
1934 case MODE_PREINDEX: | |
1935 switch (decoded->params.regs.disp_sizes) | |
1936 { | |
1937 case 0x11: | |
1938 //no base displacement or outer displacement | |
1939 ret = sprintf(dst, "%s ([%c%d.%c*%d])", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
1940 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
1941 1 << decoded->params.regs.scale); | |
1942 break; | |
1943 case 0x12: | |
1944 case 0x13: | |
1945 //base displacement only | |
1946 ret = sprintf(dst, "%s ([%d.%c, %c%d.%c*%d])", c, decoded->params.regs.displacement, | |
1947 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
1948 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1949 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1950 break; | |
1951 case 0x21: | |
1952 case 0x31: | |
1953 //outer displacement only | |
1954 ret = sprintf(dst, "%s ([%c%d.%c*%d], %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
1955 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
1956 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp, | |
1957 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1958 break; | |
1959 case 0x22: | |
1960 case 0x23: | |
1961 case 0x32: | |
1962 case 0x33: | |
1963 //both outer and inner displacement | |
1964 ret = sprintf(dst, "%s ([%d.%c, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement, | |
1965 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
1966 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1967 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
1968 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1969 break; | |
1970 } | |
1971 break; | |
1972 case MODE_POSTINDEX: | |
1973 switch (decoded->params.regs.disp_sizes) | |
1974 { | |
1975 case 0x11: | |
1976 //no base displacement or outer displacement | |
1977 ret = sprintf(dst, "%s ([], %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
1978 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
1979 1 << decoded->params.regs.scale); | |
1980 break; | |
1981 case 0x12: | |
1982 case 0x13: | |
1983 //base displacement only | |
1984 ret = sprintf(dst, "%s ([%d.%c], %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
1985 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
1986 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
1987 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
1988 break; | |
1989 case 0x21: | |
1990 case 0x31: | |
1991 //outer displacement only | |
1992 ret = sprintf(dst, "%s ([], %c%d.%c*%d, %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
1993 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
1994 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp, | |
1995 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
1996 break; | |
1997 case 0x22: | |
1998 case 0x23: | |
1999 case 0x32: | |
2000 case 0x33: | |
2001 //both outer and inner displacement | |
2002 ret = sprintf(dst, "%s ([%d.%c], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement, | |
2003 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2004 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2005 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
2006 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2007 break; | |
2008 } | |
2009 break; | |
2010 case MODE_MEM_INDIRECT: | |
2011 switch (decoded->params.regs.disp_sizes) | |
2012 { | |
2013 case 0x11: | |
2014 //no base displacement or outer displacement | |
2015 ret = sprintf(dst, "%s ([])", c); | |
2016 break; | |
2017 case 0x12: | |
2018 case 0x13: | |
2019 //base displacement only | |
2020 ret = sprintf(dst, "%s ([%d.%c])", c, decoded->params.regs.displacement, | |
2021 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l'); | |
2022 break; | |
2023 case 0x21: | |
2024 case 0x31: | |
2025 //outer displacement only | |
2026 ret = sprintf(dst, "%s ([], %d.%c)", c, decoded->params.regs.outer_disp, | |
2027 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2028 break; | |
2029 case 0x22: | |
2030 case 0x23: | |
2031 case 0x32: | |
2032 case 0x33: | |
2033 //both outer and inner displacement | |
2034 ret = sprintf(dst, "%s ([%d.%c], %d.%c)", c, decoded->params.regs.displacement, | |
2035 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.outer_disp, | |
2036 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2037 break; | |
2038 } | |
2039 break; | |
2040 case MODE_BASE_DISP: | |
2041 if (decoded->params.regs.disp_sizes > 1) | |
2042 { | |
2043 ret = sprintf(dst, "%s (%d.%c)", c, decoded->params.regs.displacement, | |
2044 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l'); | |
2045 } else { | |
2046 ret = sprintf(dst, "%s ()", c); | |
2047 } | |
2048 break; | |
2049 #endif | |
1460 case MODE_IMMEDIATE: | 2050 case MODE_IMMEDIATE: |
1461 case MODE_IMMEDIATE_WORD: | 2051 case MODE_IMMEDIATE_WORD: |
1462 return sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed); | 2052 ret = sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed); |
2053 break; | |
1463 case MODE_ABSOLUTE_SHORT: | 2054 case MODE_ABSOLUTE_SHORT: |
1464 if (labels) { | 2055 if (labels) { |
1465 return sprintf(dst, "%s ADR_%X.w", c, decoded->params.immed); | 2056 ret = sprintf(dst, "%s ", c); |
1466 } else { | 2057 ret += label_fun(dst+ret, decoded->params.immed, data); |
1467 return sprintf(dst, "%s $%X.w", c, decoded->params.immed); | 2058 strcat(dst+ret, ".w"); |
1468 } | 2059 ret = ret + 2; |
2060 } else { | |
2061 ret = sprintf(dst, "%s $%X.w", c, decoded->params.immed); | |
2062 } | |
2063 break; | |
1469 case MODE_ABSOLUTE: | 2064 case MODE_ABSOLUTE: |
1470 if (labels) { | 2065 if (labels) { |
1471 return sprintf(dst, "%s ADR_%X.l", c, decoded->params.immed); | 2066 ret = sprintf(dst, "%s ", c); |
1472 } else { | 2067 ret += label_fun(dst+ret, decoded->params.immed, data); |
1473 return sprintf(dst, "%s $%X", c, decoded->params.immed); | 2068 strcat(dst+ret, ".l"); |
1474 } | 2069 ret = ret + 2; |
2070 } else { | |
2071 ret = sprintf(dst, "%s $%X", c, decoded->params.immed); | |
2072 } | |
2073 break; | |
1475 case MODE_PC_DISPLACE: | 2074 case MODE_PC_DISPLACE: |
1476 if (labels) { | 2075 if (labels) { |
1477 return sprintf(dst, "%s ADR_%X(pc)", c, address + 2 + decoded->params.regs.displacement); | 2076 ret = sprintf(dst, "%s ", c); |
1478 } else { | 2077 ret += label_fun(dst+ret, address + 2 + decoded->params.regs.displacement, data); |
1479 return sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement); | 2078 strcat(dst+ret, "(pc)"); |
1480 } | 2079 ret = ret + 4; |
2080 } else { | |
2081 ret = sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement); | |
2082 } | |
2083 break; | |
1481 case MODE_PC_INDEX_DISP8: | 2084 case MODE_PC_INDEX_DISP8: |
1482 return sprintf(dst, "%s (%d, pc, %c%d.%c)", c, decoded->params.regs.displacement, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); | 2085 #ifdef M68020 |
2086 if (decoded->params.regs.scale) | |
2087 { | |
2088 ret = sprintf(dst, "%s (%d, pc, %c%d.%c*%d)", c, decoded->params.regs.displacement, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
2089 } else { | |
2090 #endif | |
2091 ret = sprintf(dst, "%s (%d, pc, %c%d.%c)", c, decoded->params.regs.displacement, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w'); | |
2092 #ifdef M68020 | |
2093 } | |
2094 #endif | |
2095 break; | |
2096 #ifdef M68020 | |
2097 case MODE_PC_INDEX_BASE_DISP: | |
2098 if (decoded->params.regs.disp_sizes > 1) | |
2099 { | |
2100 ret = sprintf(dst, "%s (%d.%c, pc, %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
2101 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l', | |
2102 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2103 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
2104 } else { | |
2105 ret = sprintf(dst, "%s (pc, %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2106 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2107 1 << decoded->params.regs.scale); | |
2108 } | |
2109 break; | |
2110 case MODE_PC_PREINDEX: | |
2111 switch (decoded->params.regs.disp_sizes) | |
2112 { | |
2113 case 0x11: | |
2114 //no base displacement or outer displacement | |
2115 ret = sprintf(dst, "%s ([pc, %c%d.%c*%d])", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2116 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2117 1 << decoded->params.regs.scale); | |
2118 break; | |
2119 case 0x12: | |
2120 case 0x13: | |
2121 //base displacement only | |
2122 ret = sprintf(dst, "%s ([%d.%c, pc, %c%d.%c*%d])", c, decoded->params.regs.displacement, | |
2123 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2124 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2125 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
2126 break; | |
2127 case 0x21: | |
2128 case 0x31: | |
2129 //outer displacement only | |
2130 ret = sprintf(dst, "%s ([pc, %c%d.%c*%d], %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2131 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2132 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp, | |
2133 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2134 break; | |
2135 case 0x22: | |
2136 case 0x23: | |
2137 case 0x32: | |
2138 case 0x33: | |
2139 //both outer and inner displacement | |
2140 ret = sprintf(dst, "%s ([%d.%c, pc, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement, | |
2141 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2142 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2143 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
2144 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2145 break; | |
2146 } | |
2147 break; | |
2148 case MODE_PC_POSTINDEX: | |
2149 switch (decoded->params.regs.disp_sizes) | |
2150 { | |
2151 case 0x11: | |
2152 //no base displacement or outer displacement | |
2153 ret = sprintf(dst, "%s ([pc], %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2154 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2155 1 << decoded->params.regs.scale); | |
2156 break; | |
2157 case 0x12: | |
2158 case 0x13: | |
2159 //base displacement only | |
2160 ret = sprintf(dst, "%s ([%d.%c, pc], %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
2161 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2162 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2163 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
2164 break; | |
2165 case 0x21: | |
2166 case 0x31: | |
2167 //outer displacement only | |
2168 ret = sprintf(dst, "%s ([pc], %c%d.%c*%d, %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2169 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2170 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp, | |
2171 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2172 break; | |
2173 case 0x22: | |
2174 case 0x23: | |
2175 case 0x32: | |
2176 case 0x33: | |
2177 //both outer and inner displacement | |
2178 ret = sprintf(dst, "%s ([%d.%c, pc], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement, | |
2179 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2180 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2181 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
2182 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2183 break; | |
2184 } | |
2185 break; | |
2186 case MODE_PC_MEM_INDIRECT: | |
2187 switch (decoded->params.regs.disp_sizes) | |
2188 { | |
2189 case 0x11: | |
2190 //no base displacement or outer displacement | |
2191 ret = sprintf(dst, "%s ([pc])", c); | |
2192 break; | |
2193 case 0x12: | |
2194 case 0x13: | |
2195 //base displacement only | |
2196 ret = sprintf(dst, "%s ([%d.%c, pc])", c, decoded->params.regs.displacement, | |
2197 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l'); | |
2198 break; | |
2199 case 0x21: | |
2200 case 0x31: | |
2201 //outer displacement only | |
2202 ret = sprintf(dst, "%s ([pc], %d.%c)", c, decoded->params.regs.outer_disp, | |
2203 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2204 break; | |
2205 case 0x22: | |
2206 case 0x23: | |
2207 case 0x32: | |
2208 case 0x33: | |
2209 //both outer and inner displacement | |
2210 ret = sprintf(dst, "%s ([%d.%c, pc], %d.%c)", c, decoded->params.regs.displacement, | |
2211 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.outer_disp, | |
2212 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2213 break; | |
2214 } | |
2215 break; | |
2216 case MODE_PC_BASE_DISP: | |
2217 if (decoded->params.regs.disp_sizes > 1) | |
2218 { | |
2219 ret = sprintf(dst, "%s (%d.%c, pc)", c, decoded->params.regs.displacement, | |
2220 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l'); | |
2221 } else { | |
2222 ret = sprintf(dst, "%s (pc)", c); | |
2223 } | |
2224 break; | |
2225 case MODE_ZPC_INDEX_BASE_DISP: | |
2226 if (decoded->params.regs.disp_sizes > 1) | |
2227 { | |
2228 ret = sprintf(dst, "%s (%d.%c, zpc, %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
2229 decoded->params.regs.disp_sizes == 2 ? 'w' : 'l', | |
2230 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2231 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
2232 } else { | |
2233 ret = sprintf(dst, "%s (zpc, %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2234 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2235 1 << decoded->params.regs.scale); | |
2236 } | |
2237 break; | |
2238 case MODE_ZPC_PREINDEX: | |
2239 switch (decoded->params.regs.disp_sizes) | |
2240 { | |
2241 case 0x11: | |
2242 //no base displacement or outer displacement | |
2243 ret = sprintf(dst, "%s ([zpc, %c%d.%c*%d])", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2244 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2245 1 << decoded->params.regs.scale); | |
2246 break; | |
2247 case 0x12: | |
2248 case 0x13: | |
2249 //base displacement only | |
2250 ret = sprintf(dst, "%s ([%d.%c, zpc, %c%d.%c*%d])", c, decoded->params.regs.displacement, | |
2251 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2252 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2253 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
2254 break; | |
2255 case 0x21: | |
2256 case 0x31: | |
2257 //outer displacement only | |
2258 ret = sprintf(dst, "%s ([zpc, %c%d.%c*%d], %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2259 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2260 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp, | |
2261 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2262 break; | |
2263 case 0x22: | |
2264 case 0x23: | |
2265 case 0x32: | |
2266 case 0x33: | |
2267 //both outer and inner displacement | |
2268 ret = sprintf(dst, "%s ([%d.%c, zpc, %c%d.%c*%d], %d.%c)", c, decoded->params.regs.displacement, | |
2269 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2270 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2271 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
2272 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2273 break; | |
2274 } | |
2275 break; | |
2276 case MODE_ZPC_POSTINDEX: | |
2277 switch (decoded->params.regs.disp_sizes) | |
2278 { | |
2279 case 0x11: | |
2280 //no base displacement or outer displacement | |
2281 ret = sprintf(dst, "%s ([zpc], %c%d.%c*%d)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2282 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2283 1 << decoded->params.regs.scale); | |
2284 break; | |
2285 case 0x12: | |
2286 case 0x13: | |
2287 //base displacement only | |
2288 ret = sprintf(dst, "%s ([%d.%c, zpc], %c%d.%c*%d)", c, decoded->params.regs.displacement, | |
2289 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2290 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2291 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale); | |
2292 break; | |
2293 case 0x21: | |
2294 case 0x31: | |
2295 //outer displacement only | |
2296 ret = sprintf(dst, "%s ([zpc], %c%d.%c*%d, %d.%c)", c, (decoded->params.regs.sec & 0x10) ? 'a': 'd', | |
2297 (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w', | |
2298 1 << decoded->params.regs.scale, decoded->params.regs.outer_disp, | |
2299 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2300 break; | |
2301 case 0x22: | |
2302 case 0x23: | |
2303 case 0x32: | |
2304 case 0x33: | |
2305 //both outer and inner displacement | |
2306 ret = sprintf(dst, "%s ([%d.%c, zpc], %c%d.%c*%d, %d.%c)", c, decoded->params.regs.displacement, | |
2307 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', | |
2308 (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, | |
2309 (decoded->params.regs.sec & 1) ? 'l': 'w', 1 << decoded->params.regs.scale, | |
2310 decoded->params.regs.outer_disp, decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2311 break; | |
2312 } | |
2313 break; | |
2314 case MODE_ZPC_MEM_INDIRECT: | |
2315 switch (decoded->params.regs.disp_sizes) | |
2316 { | |
2317 case 0x11: | |
2318 //no base displacement or outer displacement | |
2319 ret = sprintf(dst, "%s ([zpc])", c); | |
2320 break; | |
2321 case 0x12: | |
2322 case 0x13: | |
2323 //base displacement only | |
2324 ret = sprintf(dst, "%s ([%d.%c, zpc])", c, decoded->params.regs.displacement, | |
2325 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l'); | |
2326 break; | |
2327 case 0x21: | |
2328 case 0x31: | |
2329 //outer displacement only | |
2330 ret = sprintf(dst, "%s ([zpc], %d.%c)", c, decoded->params.regs.outer_disp, | |
2331 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2332 break; | |
2333 case 0x22: | |
2334 case 0x23: | |
2335 case 0x32: | |
2336 case 0x33: | |
2337 //both outer and inner displacement | |
2338 ret = sprintf(dst, "%s ([%d.%c, zpc], %d.%c)", c, decoded->params.regs.displacement, | |
2339 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l', decoded->params.regs.outer_disp, | |
2340 decoded->params.regs.disp_sizes & 0x30 == 0x20 ? 'w' : 'l'); | |
2341 break; | |
2342 } | |
2343 break; | |
2344 case MODE_ZPC_BASE_DISP: | |
2345 if (decoded->params.regs.disp_sizes > 1) | |
2346 { | |
2347 ret = sprintf(dst, "%s (%d.%c, zpc)", c, decoded->params.regs.displacement, | |
2348 decoded->params.regs.disp_sizes & 3 == 2 ? 'w' : 'l'); | |
2349 } else { | |
2350 ret = sprintf(dst, "%s (zpc)", c); | |
2351 } | |
2352 break; | |
2353 #endif | |
1483 default: | 2354 default: |
1484 return 0; | 2355 ret = 0; |
1485 } | 2356 } |
2357 #ifdef M68020 | |
2358 if (decoded->addr_mode & M68K_FLAG_BITFIELD) | |
2359 { | |
2360 switch (decoded->bitfield & 0x820) | |
2361 { | |
2362 case 0: | |
2363 return ret + sprintf(dst+ret, " {$%X:%d}", decoded->bitfield >> 6 & 0x1F, decoded->bitfield & 0x1F ? decoded->bitfield & 0x1F : 32); | |
2364 case 0x20: | |
2365 return ret + sprintf(dst+ret, " {$%X:d%d}", decoded->bitfield >> 6 & 0x1F, decoded->bitfield & 0x7); | |
2366 case 0x800: | |
2367 return ret + sprintf(dst+ret, " {d%d:%d}", decoded->bitfield >> 6 & 0x7, decoded->bitfield & 0x1F ? decoded->bitfield & 0x1F : 32); | |
2368 case 0x820: | |
2369 return ret + sprintf(dst+ret, " {d%d:d%d}", decoded->bitfield >> 6 & 0x7, decoded->bitfield & 0x7); | |
2370 } | |
2371 } | |
2372 #endif | |
2373 return ret; | |
1486 } | 2374 } |
1487 | 2375 |
1488 int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address) | 2376 int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data) |
1489 { | 2377 { |
1490 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; | 2378 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; |
1491 char *rtype, *last_rtype; | 2379 char *rtype, *last_rtype; |
1492 int oplen; | 2380 int oplen; |
1493 if (decoded->addr_mode == MODE_REG) { | 2381 if (decoded->addr_mode == MODE_REG) { |
1537 if (last >= 0 && last != first) { | 2425 if (last >= 0 && last != first) { |
1538 oplen += sprintf(dst + oplen, "-%s%d", last_rtype, last); | 2426 oplen += sprintf(dst + oplen, "-%s%d", last_rtype, last); |
1539 } | 2427 } |
1540 return oplen; | 2428 return oplen; |
1541 } else { | 2429 } else { |
1542 return m68k_disasm_op(decoded, dst, need_comma, labels, address); | 2430 return m68k_disasm_op(decoded, dst, need_comma, labels, address, label_fun, data); |
1543 } | 2431 } |
1544 } | 2432 } |
1545 | 2433 |
1546 int m68k_disasm_ex(m68kinst * decoded, char * dst, uint8_t labels) | 2434 int m68k_default_label_fun(char * dst, uint32_t address, void * data) |
2435 { | |
2436 return sprintf(dst, "ADR_%X", address); | |
2437 } | |
2438 | |
2439 int m68k_disasm_ex(m68kinst * decoded, char * dst, uint8_t labels, format_label_fun label_fun, void * data) | |
1547 { | 2440 { |
1548 int ret,op1len; | 2441 int ret,op1len; |
1549 uint8_t size; | 2442 uint8_t size; |
1550 char * special_op = "CCR"; | 2443 char * special_op = "CCR"; |
1551 switch (decoded->op) | 2444 switch (decoded->op) |
1559 strcpy(dst+ret, cond_mnem[decoded->extra.cond]); | 2452 strcpy(dst+ret, cond_mnem[decoded->extra.cond]); |
1560 ret = strlen(dst); | 2453 ret = strlen(dst); |
1561 if (decoded->op != M68K_SCC) { | 2454 if (decoded->op != M68K_SCC) { |
1562 if (labels) { | 2455 if (labels) { |
1563 if (decoded->op == M68K_DBCC) { | 2456 if (decoded->op == M68K_DBCC) { |
1564 ret += sprintf(dst+ret, " d%d, ADR_%X", decoded->dst.params.regs.pri, decoded->address + 2 + decoded->src.params.immed); | 2457 ret += sprintf(dst+ret, " d%d, ", decoded->dst.params.regs.pri); |
2458 ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data); | |
1565 } else { | 2459 } else { |
1566 ret += sprintf(dst+ret, " ADR_%X", decoded->address + 2 + decoded->src.params.immed); | 2460 dst[ret++] = ' '; |
2461 ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data); | |
1567 } | 2462 } |
1568 } else { | 2463 } else { |
1569 if (decoded->op == M68K_DBCC) { | 2464 if (decoded->op == M68K_DBCC) { |
1570 ret += sprintf(dst+ret, " d%d, #%d <%X>", decoded->dst.params.regs.pri, decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); | 2465 ret += sprintf(dst+ret, " d%d, #%d <%X>", decoded->dst.params.regs.pri, decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); |
1571 } else { | 2466 } else { |
1575 return ret; | 2470 return ret; |
1576 } | 2471 } |
1577 break; | 2472 break; |
1578 case M68K_BSR: | 2473 case M68K_BSR: |
1579 if (labels) { | 2474 if (labels) { |
1580 ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "", | 2475 ret = sprintf(dst, "bsr%s ", decoded->variant == VAR_BYTE ? ".s" : ""); |
1581 decoded->address + 2 + decoded->src.params.immed); | 2476 ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data); |
1582 } else { | 2477 } else { |
1583 ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); | 2478 ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); |
1584 } | 2479 } |
1585 return ret; | 2480 return ret; |
1586 case M68K_MOVE_FROM_SR: | 2481 case M68K_MOVE_FROM_SR: |
1587 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 2482 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1588 ret += sprintf(dst + ret, " SR"); | 2483 ret += sprintf(dst + ret, " SR"); |
1589 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1, labels, decoded->address); | 2484 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1, labels, decoded->address, label_fun, data); |
1590 return ret; | 2485 return ret; |
1591 case M68K_ANDI_SR: | 2486 case M68K_ANDI_SR: |
1592 case M68K_EORI_SR: | 2487 case M68K_EORI_SR: |
1593 case M68K_MOVE_SR: | 2488 case M68K_MOVE_SR: |
1594 case M68K_ORI_SR: | 2489 case M68K_ORI_SR: |
1596 case M68K_ANDI_CCR: | 2491 case M68K_ANDI_CCR: |
1597 case M68K_EORI_CCR: | 2492 case M68K_EORI_CCR: |
1598 case M68K_MOVE_CCR: | 2493 case M68K_MOVE_CCR: |
1599 case M68K_ORI_CCR: | 2494 case M68K_ORI_CCR: |
1600 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 2495 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1601 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address); | 2496 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); |
1602 ret += sprintf(dst + ret, ", %s", special_op); | 2497 ret += sprintf(dst + ret, ", %s", special_op); |
1603 return ret; | 2498 return ret; |
1604 case M68K_MOVE_USP: | 2499 case M68K_MOVE_USP: |
1605 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 2500 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1606 if (decoded->src.addr_mode != MODE_UNUSED) { | 2501 if (decoded->src.addr_mode != MODE_UNUSED) { |
1607 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address); | 2502 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); |
1608 ret += sprintf(dst + ret, ", USP"); | 2503 ret += sprintf(dst + ret, ", USP"); |
1609 } else { | 2504 } else { |
1610 ret += sprintf(dst + ret, "USP, "); | 2505 ret += sprintf(dst + ret, "USP, "); |
1611 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address); | 2506 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data); |
1612 } | 2507 } |
1613 return ret; | 2508 return ret; |
2509 case M68K_INVALID: | |
2510 ret = sprintf(dst, "dc.w $%X", decoded->src.params.immed); | |
2511 return ret; | |
2512 #ifdef M68010 | |
2513 case M68K_MOVEC: | |
2514 ret = sprintf(dst, "%s ", mnemonics[decoded->op]); | |
2515 if (decoded->src.addr_mode == MODE_UNUSED) { | |
2516 ret += sprintf(dst + ret, "%s, ", cr_mnem[decoded->src.params.immed]); | |
2517 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data); | |
2518 } else { | |
2519 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); | |
2520 ret += sprintf(dst + ret, ", %s", cr_mnem[decoded->dst.params.immed]); | |
2521 } | |
2522 return ret; | |
2523 #endif | |
1614 default: | 2524 default: |
1615 size = decoded->extra.size; | 2525 size = decoded->extra.size; |
1616 ret = sprintf(dst, "%s%s%s", | 2526 ret = sprintf(dst, "%s%s%s", |
1617 mnemonics[decoded->op], | 2527 mnemonics[decoded->op], |
1618 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), | 2528 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), |
1619 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); | 2529 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); |
1620 } | 2530 } |
1621 if (decoded->op == M68K_MOVEM) { | 2531 if (decoded->op == M68K_MOVEM) { |
1622 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address); | 2532 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data); |
1623 ret += op1len; | 2533 ret += op1len; |
1624 ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len, labels, decoded->address); | 2534 ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len, labels, decoded->address, label_fun, data); |
1625 } else { | 2535 } else { |
1626 op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address); | 2536 op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data); |
1627 ret += op1len; | 2537 ret += op1len; |
1628 ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len, labels, decoded->address); | 2538 ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len, labels, decoded->address, label_fun, data); |
1629 } | 2539 } |
1630 return ret; | 2540 return ret; |
1631 } | 2541 } |
1632 | 2542 |
1633 int m68k_disasm(m68kinst * decoded, char * dst) | 2543 int m68k_disasm(m68kinst * decoded, char * dst) |
1634 { | 2544 { |
1635 return m68k_disasm_ex(decoded, dst, 0); | 2545 return m68k_disasm_ex(decoded, dst, 0, NULL, NULL); |
1636 } | 2546 } |
1637 | 2547 |
1638 int m68k_disasm_labels(m68kinst * decoded, char * dst) | 2548 int m68k_disasm_labels(m68kinst * decoded, char * dst, format_label_fun label_fun, void * data) |
1639 { | 2549 { |
1640 return m68k_disasm_ex(decoded, dst, 1); | 2550 if (!label_fun) |
2551 { | |
2552 label_fun = m68k_default_label_fun; | |
2553 } | |
2554 return m68k_disasm_ex(decoded, dst, 1, label_fun, data); | |
1641 } | 2555 } |