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 }