this repo has no description
1/*
2 DISAM68K.c
3
4 Copyright (C) 2010 Paul C. Pratt
5
6 You can redistribute this file and/or modify it under the terms
7 of version 2 of the GNU General Public License as published by
8 the Free Software Foundation. You should have received a copy
9 of the license along with this file; see the file COPYING.
10
11 This file is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 license for more details.
15*/
16
17/*
18 DISAssemble Motorola 68K instructions.
19*/
20
21#include "PICOMMON.h"
22
23#if WantDisasm
24
25#include "M68KITAB.h"
26
27#include "DISAM68K.h"
28
29LOCALVAR ui5r Disasm_pc;
30
31/*
32 don't use get_vm_byte/get_vm_word/get_vm_long
33 so as to be sure of no side effects
34 (if pc points to memory mapped device)
35*/
36
37LOCALVAR ui3p Disasm_pcp;
38LOCALVAR ui5r Disasm_pc_blockmask;
39LOCALVAR ui3b Disasm_pcp_dummy[2] = {
40 0, 0
41};
42
43IMPORTFUNC ATTep FindATTel(CPTR addr);
44
45LOCALPROC Disasm_Find_pcp(void)
46{
47 ATTep p;
48
49 p = FindATTel(Disasm_pc);
50 if (0 == (p->Access & kATTA_readreadymask)) {
51 Disasm_pcp = Disasm_pcp_dummy;
52 Disasm_pc_blockmask = 0;
53 } else {
54 Disasm_pc_blockmask = p->usemask & ~ p->cmpmask;
55 Disasm_pc_blockmask = Disasm_pc_blockmask
56 & ~ (Disasm_pc_blockmask + 1);
57 Disasm_pcp = p->usebase + (Disasm_pc & p->usemask);
58 }
59}
60
61LOCALFUNC ui4r Disasm_nextiword(void)
62/* NOT sign extended */
63{
64 ui4r r = do_get_mem_word(Disasm_pcp);
65 Disasm_pcp += 2;
66 Disasm_pc += 2;
67 if (0 == (Disasm_pc_blockmask & Disasm_pc)) {
68 Disasm_Find_pcp();
69 }
70 return r;
71}
72
73LOCALINLINEFUNC ui3r Disasm_nextibyte(void)
74{
75 return (ui3b) Disasm_nextiword();
76}
77
78LOCALFUNC ui5r Disasm_nextilong(void)
79{
80 ui5r hi = Disasm_nextiword();
81 ui5r lo = Disasm_nextiword();
82 ui5r r = ((hi << 16) & 0xFFFF0000)
83 | (lo & 0x0000FFFF);
84
85 return r;
86}
87
88LOCALPROC Disasm_setpc(CPTR newpc)
89{
90 if (newpc != Disasm_pc) {
91 Disasm_pc = newpc;
92
93 Disasm_Find_pcp();
94 }
95}
96
97LOCALVAR ui5b Disasm_opcode;
98
99LOCALVAR ui5b Disasm_opsize;
100
101#define Disasm_b76 ((Disasm_opcode >> 6) & 3)
102#define Disasm_b8 ((Disasm_opcode >> 8) & 1)
103#define Disasm_mode ((Disasm_opcode >> 3) & 7)
104#define Disasm_reg (Disasm_opcode & 7)
105#define Disasm_md6 ((Disasm_opcode >> 6) & 7)
106#define Disasm_rg9 ((Disasm_opcode >> 9) & 7)
107
108LOCALPROC DisasmOpSizeFromb76(void)
109{
110 Disasm_opsize = 1 << Disasm_b76;
111 switch (Disasm_opsize) {
112 case 1 :
113 dbglog_writeCStr(".B");
114 break;
115 case 2 :
116 dbglog_writeCStr(".W");
117 break;
118 case 4 :
119 dbglog_writeCStr(".L");
120 break;
121 }
122}
123
124LOCALPROC DisasmModeRegister(ui5b themode, ui5b thereg)
125{
126 switch (themode) {
127 case 0 :
128 dbglog_writeCStr("D");
129 dbglog_writeHex(thereg);
130 break;
131 case 1 :
132 dbglog_writeCStr("A");
133 dbglog_writeHex(thereg);
134 break;
135 case 2 :
136 dbglog_writeCStr("(A");
137 dbglog_writeHex(thereg);
138 dbglog_writeCStr(")");
139 break;
140 case 3 :
141 dbglog_writeCStr("(A");
142 dbglog_writeHex(thereg);
143 dbglog_writeCStr(")+");
144 break;
145 case 4 :
146 dbglog_writeCStr("-(A");
147 dbglog_writeHex(thereg);
148 dbglog_writeCStr(")");
149 break;
150 case 5 :
151 dbglog_writeHex(Disasm_nextiword());
152 dbglog_writeCStr("(A");
153 dbglog_writeHex(thereg);
154 dbglog_writeCStr(")");
155 break;
156 case 6 :
157 dbglog_writeCStr("???");
158#if 0
159 ArgKind = AKMemory;
160 ArgAddr.mem = get_disp_ea(m68k_areg(thereg));
161#endif
162 break;
163 case 7 :
164 switch (thereg) {
165 case 0 :
166 dbglog_writeCStr("(");
167 dbglog_writeHex(Disasm_nextiword());
168 dbglog_writeCStr(")");
169 break;
170 case 1 :
171 dbglog_writeCStr("(");
172 dbglog_writeHex(Disasm_nextilong());
173 dbglog_writeCStr(")");
174 break;
175 case 2 :
176 {
177 ui5r s = Disasm_pc;
178 s += ui5r_FromSWord(Disasm_nextiword());
179 dbglog_writeCStr("(");
180 dbglog_writeHex(s);
181 dbglog_writeCStr(")");
182 }
183 break;
184 case 3 :
185 dbglog_writeCStr("???");
186#if 0
187 ArgKind = AKMemory;
188 s = get_disp_ea(Disasm_pc);
189#endif
190 break;
191 case 4 :
192 dbglog_writeCStr("#");
193 if (Disasm_opsize == 2) {
194 dbglog_writeHex(Disasm_nextiword());
195 } else if (Disasm_opsize < 2) {
196 dbglog_writeHex(Disasm_nextibyte());
197 } else {
198 dbglog_writeHex(Disasm_nextilong());
199 }
200 break;
201 }
202 break;
203 case 8 :
204 dbglog_writeCStr("#");
205 dbglog_writeHex(thereg);
206 break;
207 }
208}
209
210LOCALPROC DisasmStartOne(char *s)
211{
212 dbglog_writeCStr(s);
213}
214
215LOCALPROC Disasm_xxxxxxxxssmmmrrr(char *s)
216{
217 DisasmStartOne(s);
218 DisasmOpSizeFromb76();
219 dbglog_writeCStr(" ");
220 DisasmModeRegister(Disasm_mode, Disasm_reg);
221 dbglog_writeReturn();
222}
223
224LOCALPROC DisasmEaD_xxxxdddxssmmmrrr(char *s)
225{
226 DisasmStartOne(s);
227 DisasmOpSizeFromb76();
228 dbglog_writeCStr(" ");
229 DisasmModeRegister(Disasm_mode, Disasm_reg);
230 dbglog_writeCStr(", ");
231 dbglog_writeCStr("D");
232 dbglog_writeHex(Disasm_rg9);
233 dbglog_writeReturn();
234}
235
236LOCALPROC DisasmI_xxxxxxxxssmmmrrr(char *s)
237{
238 DisasmStartOne(s);
239 DisasmOpSizeFromb76();
240 dbglog_writeCStr(" #");
241 if (Disasm_opsize == 2) {
242 dbglog_writeHex(ui5r_FromSWord(Disasm_nextiword()));
243 } else if (Disasm_opsize < 2) {
244 dbglog_writeHex(ui5r_FromSByte(Disasm_nextibyte()));
245 } else {
246 dbglog_writeHex(ui5r_FromSLong(Disasm_nextilong()));
247 }
248 dbglog_writeCStr(", ");
249 DisasmModeRegister(Disasm_mode, Disasm_reg);
250 dbglog_writeReturn();
251}
252
253LOCALPROC DisasmsAA_xxxxdddxssxxxrrr(char *s)
254{
255 DisasmStartOne(s);
256 DisasmOpSizeFromb76();
257 DisasmModeRegister(3, Disasm_reg);
258 dbglog_writeCStr(", ");
259 DisasmModeRegister(3, Disasm_rg9);
260 dbglog_writeReturn();
261}
262
263LOCALFUNC ui5r Disasm_octdat(ui5r x)
264{
265 if (x == 0) {
266 return 8;
267 } else {
268 return x;
269 }
270}
271
272LOCALPROC Disasm_xxxxnnnxssmmmrrr(char *s)
273{
274 DisasmStartOne(s);
275 DisasmOpSizeFromb76();
276 dbglog_writeCStr(" #");
277
278 dbglog_writeHex(Disasm_octdat(Disasm_rg9));
279 dbglog_writeCStr(", ");
280 DisasmModeRegister(Disasm_mode, Disasm_reg);
281 dbglog_writeReturn();
282}
283
284LOCALPROC DisasmDEa_xxxxdddxssmmmrrr(char *s)
285{
286 DisasmStartOne(s);
287 DisasmOpSizeFromb76();
288 dbglog_writeCStr(" D");
289 dbglog_writeHex(Disasm_rg9);
290 dbglog_writeCStr(", ");
291 DisasmModeRegister(Disasm_mode, Disasm_reg);
292 dbglog_writeReturn();
293}
294
295LOCALPROC DisasmEaA_xxxxdddsxxmmmrrr(char *s)
296{
297 DisasmStartOne(s);
298
299 Disasm_opsize = Disasm_b8 * 2 + 2;
300 if (Disasm_opsize == 2) {
301 dbglog_writeCStr(".W");
302 } else {
303 dbglog_writeCStr(".L");
304 }
305 dbglog_writeCStr(" ");
306 DisasmModeRegister(Disasm_mode, Disasm_reg);
307 dbglog_writeCStr(", A");
308 dbglog_writeHex(Disasm_rg9);
309 dbglog_writeReturn();
310}
311
312LOCALPROC DisasmDD_xxxxdddxssxxxrrr(char *s)
313{
314 DisasmStartOne(s);
315 DisasmOpSizeFromb76();
316 dbglog_writeCStr(" ");
317 DisasmModeRegister(0, Disasm_reg);
318 dbglog_writeCStr(", ");
319 DisasmModeRegister(0, Disasm_rg9);
320 dbglog_writeReturn();
321}
322
323LOCALPROC DisasmAAs_xxxxdddxssxxxrrr(char *s)
324{
325 DisasmStartOne(s);
326 DisasmOpSizeFromb76();
327 dbglog_writeCStr(" ");
328 DisasmModeRegister(4, Disasm_reg);
329 dbglog_writeCStr(", ");
330 DisasmModeRegister(4, Disasm_rg9);
331 dbglog_writeReturn();
332}
333
334LOCALPROCUSEDONCE DisasmTst(void)
335{
336 /* Tst 01001010ssmmmrrr */
337 Disasm_xxxxxxxxssmmmrrr("TST");
338}
339
340LOCALPROCUSEDONCE DisasmCompare(void)
341{
342 /* Cmp 1011ddd0ssmmmrrr */
343 DisasmEaD_xxxxdddxssmmmrrr("CMP");
344}
345
346LOCALPROCUSEDONCE DisasmCmpI(void)
347{
348 /* CMPI 00001100ssmmmrrr */
349 DisasmI_xxxxxxxxssmmmrrr("CMP");
350}
351
352LOCALPROCUSEDONCE DisasmCmpM(void)
353{
354 /* CmpM 1011ddd1ss001rrr */
355 DisasmsAA_xxxxdddxssxxxrrr("CMP");
356}
357
358LOCALPROC DisasmCC(void)
359{
360 switch ((Disasm_opcode >> 8) & 15) {
361 case 0: dbglog_writeCStr("T"); break;
362 case 1: dbglog_writeCStr("F"); break;
363 case 2: dbglog_writeCStr("HI"); break;
364 case 3: dbglog_writeCStr("LS"); break;
365 case 4: dbglog_writeCStr("CC"); break;
366 case 5: dbglog_writeCStr("CS"); break;
367 case 6: dbglog_writeCStr("NE"); break;
368 case 7: dbglog_writeCStr("EQ"); break;
369 case 8: dbglog_writeCStr("VC"); break;
370 case 9: dbglog_writeCStr("VS"); break;
371 case 10: dbglog_writeCStr("P"); break;
372 case 11: dbglog_writeCStr("MI"); break;
373 case 12: dbglog_writeCStr("GE"); break;
374 case 13: dbglog_writeCStr("LT"); break;
375 case 14: dbglog_writeCStr("GT"); break;
376 case 15: dbglog_writeCStr("LE"); break;
377 default: break; /* shouldn't get here */
378 }
379}
380
381LOCALPROCUSEDONCE DisasmBcc(void)
382{
383 /* Bcc 0110ccccnnnnnnnn */
384 ui5b src = ((ui5b)Disasm_opcode) & 255;
385 ui5r s = Disasm_pc;
386
387 if (0 == ((Disasm_opcode >> 8) & 15)) {
388 DisasmStartOne("BRA");
389 } else {
390 DisasmStartOne("B");
391 DisasmCC();
392 }
393 dbglog_writeCStr(" ");
394
395 if (src == 0) {
396 s += ui5r_FromSWord(Disasm_nextiword());
397 } else
398#if Use68020
399 if (src == 255) {
400 s += ui5r_FromSLong(Disasm_nextilong());
401 /* ReportAbnormal("long branch in DoCode6"); */
402 /* Used by various Apps */
403 } else
404#endif
405 {
406 s += ui5r_FromSByte(src);
407 }
408 dbglog_writeHex(s);
409 dbglog_writeReturn();
410}
411
412LOCALPROCUSEDONCE DisasmDBcc(void)
413{
414 /* DBcc 0101cccc11001ddd */
415
416 ui5r s = Disasm_pc;
417
418 DisasmStartOne("DB");
419 DisasmCC();
420
421 dbglog_writeCStr(" D");
422 dbglog_writeHex(Disasm_reg);
423 dbglog_writeCStr(", ");
424
425 s += (si5b)(si4b)Disasm_nextiword();
426 dbglog_writeHex(s);
427 dbglog_writeReturn();
428}
429
430LOCALPROCUSEDONCE DisasmSwap(void)
431{
432 /* Swap 0100100001000rrr */
433
434 DisasmStartOne("SWAP D");
435 dbglog_writeHex(Disasm_reg);
436 dbglog_writeReturn();
437}
438
439LOCALPROC DisasmMove(void) /* MOVE */
440{
441 DisasmModeRegister(Disasm_mode, Disasm_reg);
442 dbglog_writeCStr(", ");
443 DisasmModeRegister(Disasm_md6, Disasm_rg9);
444 dbglog_writeReturn();
445}
446
447LOCALPROCUSEDONCE DisasmMoveL(void)
448{
449 DisasmStartOne("MOVE.L ");
450 Disasm_opsize = 4;
451 DisasmMove();
452}
453
454LOCALPROCUSEDONCE DisasmMoveW(void)
455{
456 DisasmStartOne("MOVE.W ");
457 Disasm_opsize = 2;
458 DisasmMove();
459}
460
461LOCALPROCUSEDONCE DisasmMoveB(void)
462{
463 DisasmStartOne("MOVE.B ");
464 Disasm_opsize = 1;
465 DisasmMove();
466}
467
468LOCALPROCUSEDONCE DisasmMoveAL(void)
469{
470 DisasmStartOne("MOVEA.L ");
471 Disasm_opsize = 4;
472 DisasmMove();
473}
474
475LOCALPROCUSEDONCE DisasmMoveAW(void)
476{
477 DisasmStartOne("MOVEA.W ");
478 Disasm_opsize = 2;
479 DisasmMove();
480}
481
482LOCALPROCUSEDONCE DisasmMoveQ(void)
483{
484 /* MoveQ 0111ddd0nnnnnnnn */
485 DisasmStartOne("MOVEQ #");
486 dbglog_writeHex(ui5r_FromSByte(Disasm_opcode));
487 dbglog_writeCStr(", D");
488 dbglog_writeHex(Disasm_rg9);
489 dbglog_writeReturn();
490}
491
492LOCALPROCUSEDONCE DisasmAddEaR(void)
493{
494 DisasmEaD_xxxxdddxssmmmrrr("ADD");
495}
496
497LOCALPROCUSEDONCE DisasmAddQ(void)
498{
499 /* AddQ 0101nnn0ssmmmrrr */
500 Disasm_xxxxnnnxssmmmrrr("ADDQ");
501}
502
503LOCALPROCUSEDONCE DisasmAddI(void)
504{
505 DisasmI_xxxxxxxxssmmmrrr("ADDI");
506}
507
508LOCALPROCUSEDONCE DisasmAddREa(void)
509{
510 DisasmDEa_xxxxdddxssmmmrrr("ADD");
511}
512
513LOCALPROCUSEDONCE DisasmSubEaR(void)
514{
515 DisasmEaD_xxxxdddxssmmmrrr("SUB");
516}
517
518LOCALPROCUSEDONCE DisasmSubQ(void)
519{
520 /* SubQ 0101nnn1ssmmmrrr */
521 Disasm_xxxxnnnxssmmmrrr("SUBQ");
522}
523
524LOCALPROCUSEDONCE DisasmSubI(void)
525{
526 DisasmI_xxxxxxxxssmmmrrr("SUBI");
527}
528
529LOCALPROCUSEDONCE DisasmSubREa(void)
530{
531 DisasmDEa_xxxxdddxssmmmrrr("SUB");
532}
533
534LOCALPROCUSEDONCE DisasmLea(void)
535{
536 /* Lea 0100aaa111mmmrrr */
537 DisasmStartOne("LEA ");
538 DisasmModeRegister(Disasm_mode, Disasm_reg);
539 dbglog_writeCStr(", A");
540 dbglog_writeHex(Disasm_rg9);
541 dbglog_writeReturn();
542}
543
544LOCALPROCUSEDONCE DisasmPEA(void)
545{
546 /* PEA 0100100001mmmrrr */
547 DisasmStartOne("PEA ");
548 DisasmModeRegister(Disasm_mode, Disasm_reg);
549 dbglog_writeReturn();
550}
551
552LOCALPROCUSEDONCE DisasmALine(void)
553{
554 DisasmStartOne("$");
555 dbglog_writeHex(Disasm_opcode);
556 dbglog_writeReturn();
557}
558
559LOCALPROCUSEDONCE DisasmBsr(void)
560{
561 ui5b src = ((ui5b)Disasm_opcode) & 255;
562 ui5r s = Disasm_pc;
563
564 DisasmStartOne("BSR ");
565 if (src == 0) {
566 s += (si5b)(si4b)Disasm_nextiword();
567 } else
568#if Use68020
569 if (src == 255) {
570 s += (si5b)Disasm_nextilong();
571 /* ReportAbnormal("long branch in DoCode6"); */
572 /* Used by various Apps */
573 } else
574#endif
575 {
576 s += (si5b)(si3b)src;
577 }
578 dbglog_writeHex(s);
579 dbglog_writeReturn();
580}
581
582LOCALPROCUSEDONCE DisasmJsr(void)
583{
584 /* Jsr 0100111010mmmrrr */
585 DisasmStartOne("JSR ");
586 DisasmModeRegister(Disasm_mode, Disasm_reg);
587 dbglog_writeReturn();
588}
589
590LOCALPROCUSEDONCE DisasmLinkA6(void)
591{
592 DisasmStartOne("LINK A6, ");
593 dbglog_writeHex(Disasm_nextiword());
594 dbglog_writeReturn();
595}
596
597LOCALPROCUSEDONCE DisasmMOVEMRmM(void)
598{
599 /* MOVEM reg to mem 0100100011s100rrr */
600 si4b z;
601 ui5r regmask;
602
603 DisasmStartOne("MOVEM");
604 if (Disasm_b76 == 2) {
605 dbglog_writeCStr(".W");
606 } else {
607 dbglog_writeCStr(".L");
608 }
609 dbglog_writeCStr(" ");
610 regmask = Disasm_nextiword();
611
612 for (z = 16; --z >= 0; ) {
613 if ((regmask & (1 << (15 - z))) != 0) {
614 if (z >= 8) {
615 dbglog_writeCStr("A");
616 dbglog_writeHex(z - 8);
617 } else {
618 dbglog_writeCStr("D");
619 dbglog_writeHex(z);
620 }
621 }
622 }
623 dbglog_writeCStr(", -(A");
624 dbglog_writeHex(Disasm_reg);
625 dbglog_writeCStr(")");
626 dbglog_writeReturn();
627}
628
629LOCALPROCUSEDONCE DisasmMOVEMApR(void)
630{
631 /* MOVEM mem to reg 0100110011s011rrr */
632 si4b z;
633 ui5r regmask;
634
635 regmask = Disasm_nextiword();
636
637 DisasmStartOne("MOVEM");
638 if (Disasm_b76 == 2) {
639 dbglog_writeCStr(".W");
640 } else {
641 dbglog_writeCStr(".L");
642 }
643 dbglog_writeCStr(" (A");
644 dbglog_writeHex(Disasm_reg);
645 dbglog_writeCStr(")+, ");
646
647 for (z = 0; z < 16; ++z) {
648 if ((regmask & (1 << z)) != 0) {
649 if (z >= 8) {
650 dbglog_writeCStr("A");
651 dbglog_writeHex(z - 8);
652 } else {
653 dbglog_writeCStr("D");
654 dbglog_writeHex(z);
655 }
656 }
657 }
658 dbglog_writeReturn();
659}
660
661LOCALPROCUSEDONCE DisasmUnlkA6(void)
662{
663 DisasmStartOne("UNLINK A6");
664 dbglog_writeReturn();
665}
666
667LOCALPROCUSEDONCE DisasmRts(void)
668{
669 /* Rts 0100111001110101 */
670 DisasmStartOne("RTS");
671 dbglog_writeReturn();
672}
673
674LOCALPROCUSEDONCE DisasmJmp(void)
675{
676 /* JMP 0100111011mmmrrr */
677 DisasmStartOne("JMP ");
678 DisasmModeRegister(Disasm_mode, Disasm_reg);
679 dbglog_writeReturn();
680}
681
682LOCALPROCUSEDONCE DisasmClr(void)
683{
684 /* Clr 01000010ssmmmrrr */
685 Disasm_xxxxxxxxssmmmrrr("CLR");
686}
687
688LOCALPROCUSEDONCE DisasmAddA(void)
689{
690 /* ADDA 1101dddm11mmmrrr */
691 DisasmEaA_xxxxdddsxxmmmrrr("ADDA");
692}
693
694LOCALPROCUSEDONCE DisasmAddQA(void)
695{
696 /* 0101nnn0ss001rrr */
697 DisasmStartOne("ADDQA #");
698 dbglog_writeHex(Disasm_octdat(Disasm_rg9));
699 dbglog_writeCStr(", A");
700 dbglog_writeHex(Disasm_reg);
701 dbglog_writeReturn();
702}
703
704LOCALPROCUSEDONCE DisasmSubQA(void)
705{
706 /* 0101nnn1ss001rrr */
707 DisasmStartOne("SUBQA #");
708 dbglog_writeHex(Disasm_octdat(Disasm_rg9));
709 dbglog_writeCStr(", A");
710 dbglog_writeHex(Disasm_reg);
711 dbglog_writeReturn();
712}
713
714LOCALPROCUSEDONCE DisasmSubA(void)
715{
716 /* SUBA 1001dddm11mmmrrr */
717 DisasmEaA_xxxxdddsxxmmmrrr("SUBA");
718}
719
720LOCALPROCUSEDONCE DisasmCmpA(void)
721{
722 DisasmStartOne("CMPA ");
723 Disasm_opsize = Disasm_b8 * 2 + 2;
724 DisasmModeRegister(Disasm_mode, Disasm_reg);
725 dbglog_writeCStr(", A");
726 dbglog_writeHex(Disasm_rg9);
727 dbglog_writeReturn();
728}
729
730LOCALPROCUSEDONCE DisasmAddXd(void)
731{
732 DisasmDD_xxxxdddxssxxxrrr("ADDX");
733}
734
735LOCALPROCUSEDONCE DisasmAddXm(void)
736{
737 DisasmAAs_xxxxdddxssxxxrrr("ADDX");
738}
739
740LOCALPROCUSEDONCE DisasmSubXd(void)
741{
742 DisasmDD_xxxxdddxssxxxrrr("SUBX");
743}
744
745LOCALPROCUSEDONCE DisasmSubXm(void)
746{
747 DisasmAAs_xxxxdddxssxxxrrr("SUBX");
748}
749
750LOCALPROC DisasmBinOp1(ui5r x)
751{
752 if (! Disasm_b8) {
753 switch (x) {
754 case 0:
755 DisasmStartOne("ASR");
756 break;
757 case 1:
758 DisasmStartOne("LSR");
759 break;
760 case 2:
761 DisasmStartOne("RXR");
762 break;
763 case 3:
764 DisasmStartOne("ROR");
765 break;
766 default:
767 /* should not get here */
768 break;
769 }
770 } else {
771 switch (x) {
772 case 0:
773 DisasmStartOne("ASL");
774 break;
775 case 1:
776 DisasmStartOne("LSL");
777 break;
778 case 2:
779 DisasmStartOne("RXL");
780 break;
781 case 3:
782 DisasmStartOne("ROL");
783 break;
784 default:
785 /* should not get here */
786 break;
787 }
788 }
789}
790
791LOCALPROCUSEDONCE DisasmRolopNM(void)
792{
793 DisasmBinOp1(Disasm_rg9);
794 dbglog_writeCStr(" ");
795 Disasm_opsize = 2;
796 DisasmModeRegister(Disasm_mode, Disasm_reg);
797 dbglog_writeReturn();
798}
799
800LOCALPROCUSEDONCE DisasmRolopND(void)
801{
802 /* 1110cccdss0ttddd */
803 DisasmBinOp1(Disasm_mode & 3);
804 DisasmOpSizeFromb76();
805 dbglog_writeCStr(" #");
806 dbglog_writeHex(Disasm_octdat(Disasm_rg9));
807 dbglog_writeCStr(", ");
808 DisasmModeRegister(0, Disasm_reg);
809 dbglog_writeReturn();
810}
811
812LOCALPROCUSEDONCE DisasmRolopDD(void)
813{
814 /* 1110rrrdss1ttddd */
815 DisasmBinOp1(Disasm_mode & 3);
816 DisasmOpSizeFromb76();
817 dbglog_writeCStr(" ");
818 DisasmModeRegister(0, Disasm_rg9);
819 dbglog_writeCStr(", ");
820 DisasmModeRegister(0, Disasm_reg);
821 dbglog_writeReturn();
822}
823
824LOCALPROC DisasmBinBitOp1(void)
825{
826 switch (Disasm_b76) {
827 case 0:
828 DisasmStartOne("BTST");
829 break;
830 case 1:
831 DisasmStartOne("BCHG");
832 break;
833 case 2:
834 DisasmStartOne("BCLR");
835 break;
836 case 3:
837 DisasmStartOne("BSET");
838 break;
839 default:
840 /* should not get here */
841 break;
842 }
843}
844
845LOCALPROCUSEDONCE DisasmBitOpDD(void)
846{
847 /* dynamic bit, Opcode = 0000ddd1tt000rrr */
848 DisasmBinBitOp1();
849 Disasm_opsize = 4;
850 dbglog_writeCStr(" ");
851 DisasmModeRegister(0, Disasm_rg9);
852 dbglog_writeCStr(", ");
853 DisasmModeRegister(0, Disasm_reg);
854 dbglog_writeReturn();
855}
856
857LOCALPROCUSEDONCE DisasmBitOpDM(void)
858{
859 /* dynamic bit, Opcode = 0000ddd1ttmmmrrr */
860 DisasmBinBitOp1();
861 Disasm_opsize = 1;
862 dbglog_writeCStr(" ");
863 DisasmModeRegister(0, Disasm_rg9);
864 dbglog_writeCStr(", ");
865 DisasmModeRegister(Disasm_mode, Disasm_reg);
866 dbglog_writeReturn();
867}
868
869LOCALPROCUSEDONCE DisasmBitOpND(void)
870{
871 /* static bit 00001010tt000rrr */
872 DisasmBinBitOp1();
873 Disasm_opsize = 4;
874 dbglog_writeCStr(" #");
875 dbglog_writeHex(ui5r_FromSByte(Disasm_nextibyte()));
876 dbglog_writeCStr(", ");
877 DisasmModeRegister(0, Disasm_reg);
878 dbglog_writeReturn();
879}
880
881LOCALPROCUSEDONCE DisasmBitOpNM(void)
882{
883 /* static bit 00001010ttmmmrrr */
884 DisasmBinBitOp1();
885 Disasm_opsize = 1;
886 dbglog_writeCStr(" #");
887 dbglog_writeHex(ui5r_FromSByte(Disasm_nextibyte()));
888 dbglog_writeCStr(", ");
889 DisasmModeRegister(Disasm_mode, Disasm_reg);
890 dbglog_writeReturn();
891}
892
893LOCALPROCUSEDONCE DisasmAndI(void)
894{
895 DisasmI_xxxxxxxxssmmmrrr("ANDI");
896}
897
898LOCALPROCUSEDONCE DisasmAndDEa(void)
899{
900 /* And 1100ddd1ssmmmrrr */
901 DisasmDEa_xxxxdddxssmmmrrr("AND");
902}
903
904LOCALPROCUSEDONCE DisasmAndEaD(void)
905{
906 /* And 1100ddd0ssmmmrrr */
907 DisasmEaD_xxxxdddxssmmmrrr("AND");
908}
909
910LOCALPROCUSEDONCE DisasmOrI(void)
911{
912 DisasmI_xxxxxxxxssmmmrrr("ORI");
913}
914
915LOCALPROCUSEDONCE DisasmOrDEa(void)
916{
917 /* OR 1000ddd1ssmmmrrr */
918 DisasmDEa_xxxxdddxssmmmrrr("OR");
919}
920
921LOCALPROCUSEDONCE DisasmOrEaD(void)
922{
923 /* OR 1000ddd0ssmmmrrr */
924 DisasmEaD_xxxxdddxssmmmrrr("OR");
925}
926
927LOCALPROCUSEDONCE DisasmEorI(void)
928{
929 DisasmI_xxxxxxxxssmmmrrr("EORI");
930}
931
932LOCALPROCUSEDONCE DisasmEor(void)
933{
934 /* Eor 1011ddd1ssmmmrrr */
935 DisasmDEa_xxxxdddxssmmmrrr("EOR");
936}
937
938LOCALPROCUSEDONCE DisasmNot(void)
939{
940 /* Not 01000110ssmmmrrr */
941 Disasm_xxxxxxxxssmmmrrr("NOT");
942}
943
944LOCALPROCUSEDONCE DisasmScc(void)
945{
946 /* Scc 0101cccc11mmmrrr */
947 Disasm_opsize = 1;
948 DisasmStartOne("S");
949 DisasmCC();
950 dbglog_writeCStr(" ");
951 DisasmModeRegister(Disasm_mode, Disasm_reg);
952 dbglog_writeReturn();
953}
954
955LOCALPROCUSEDONCE DisasmEXTL(void)
956{
957 DisasmStartOne("EXT.L D");
958 dbglog_writeHex(Disasm_reg);
959 dbglog_writeReturn();
960}
961
962LOCALPROCUSEDONCE DisasmEXTW(void)
963{
964 DisasmStartOne("EXT.W D");
965 dbglog_writeHex(Disasm_reg);
966 dbglog_writeReturn();
967}
968
969LOCALPROCUSEDONCE DisasmNeg(void)
970{
971 /* Neg 01000100ssmmmrrr */
972 Disasm_xxxxxxxxssmmmrrr("NEG");
973}
974
975LOCALPROCUSEDONCE DisasmNegX(void)
976{
977 /* NegX 01000000ssmmmrrr */
978 Disasm_xxxxxxxxssmmmrrr("NEGX");
979}
980
981LOCALPROCUSEDONCE DisasmMulU(void)
982{
983 /* MulU 1100ddd011mmmrrr */
984 Disasm_opsize = 2;
985 DisasmStartOne("MULU ");
986
987 DisasmModeRegister(Disasm_mode, Disasm_reg);
988 dbglog_writeCStr(", ");
989 DisasmModeRegister(0, Disasm_rg9);
990 dbglog_writeReturn();
991}
992
993LOCALPROCUSEDONCE DisasmMulS(void)
994{
995 /* MulS 1100ddd111mmmrrr */
996 Disasm_opsize = 2;
997 DisasmStartOne("MULS ");
998
999 DisasmModeRegister(Disasm_mode, Disasm_reg);
1000 dbglog_writeCStr(", ");
1001 DisasmModeRegister(0, Disasm_rg9);
1002 dbglog_writeReturn();
1003}
1004
1005LOCALPROCUSEDONCE DisasmDivU(void)
1006{
1007 /* DivU 1000ddd011mmmrrr */
1008
1009 Disasm_opsize = 2;
1010 DisasmStartOne("DIVU ");
1011
1012 DisasmModeRegister(Disasm_mode, Disasm_reg);
1013 dbglog_writeCStr(", ");
1014 DisasmModeRegister(0, Disasm_rg9);
1015 dbglog_writeReturn();
1016}
1017
1018LOCALPROCUSEDONCE DisasmDivS(void)
1019{
1020 /* DivS 1000ddd111mmmrrr */
1021
1022 Disasm_opsize = 2;
1023 DisasmStartOne("DIVS ");
1024
1025 DisasmModeRegister(Disasm_mode, Disasm_reg);
1026 dbglog_writeCStr(", ");
1027 DisasmModeRegister(0, Disasm_rg9);
1028 dbglog_writeReturn();
1029}
1030
1031LOCALPROCUSEDONCE DisasmExgdd(void)
1032{
1033 /* Exg 1100ddd101000rrr */
1034
1035 Disasm_opsize = 4;
1036 DisasmStartOne("EXG ");
1037 DisasmModeRegister(0, Disasm_rg9);
1038 dbglog_writeCStr(", ");
1039 DisasmModeRegister(0, Disasm_reg);
1040 dbglog_writeReturn();
1041}
1042
1043LOCALPROCUSEDONCE DisasmExgaa(void)
1044{
1045 /* Exg 1100ddd101001rrr */
1046
1047 Disasm_opsize = 4;
1048 DisasmStartOne("EXG ");
1049 DisasmModeRegister(1, Disasm_rg9);
1050 dbglog_writeCStr(", ");
1051 DisasmModeRegister(1, Disasm_reg);
1052 dbglog_writeReturn();
1053}
1054
1055LOCALPROCUSEDONCE DisasmExgda(void)
1056{
1057 /* Exg 1100ddd110001rrr */
1058
1059 Disasm_opsize = 4;
1060 DisasmStartOne("EXG ");
1061 DisasmModeRegister(0, Disasm_rg9);
1062 dbglog_writeCStr(", ");
1063 DisasmModeRegister(1, Disasm_reg);
1064 dbglog_writeReturn();
1065}
1066
1067LOCALPROCUSEDONCE DisasmMoveCCREa(void)
1068{
1069 /* Move from CCR 0100001011mmmrrr */
1070 Disasm_opsize = 2;
1071 DisasmStartOne("MOVE CCR, ");
1072 DisasmModeRegister(Disasm_mode, Disasm_reg);
1073 dbglog_writeReturn();
1074}
1075
1076LOCALPROCUSEDONCE DisasmMoveEaCR(void)
1077{
1078 /* 0100010011mmmrrr */
1079 Disasm_opsize = 2;
1080 DisasmStartOne("MOVE ");
1081 DisasmModeRegister(Disasm_mode, Disasm_reg);
1082 dbglog_writeCStr(", CCR");
1083 dbglog_writeReturn();
1084}
1085
1086LOCALPROCUSEDONCE DisasmMoveSREa(void)
1087{
1088 /* Move from SR 0100000011mmmrrr */
1089 Disasm_opsize = 2;
1090 DisasmStartOne("MOVE SR, ");
1091 DisasmModeRegister(Disasm_mode, Disasm_reg);
1092 dbglog_writeReturn();
1093}
1094
1095LOCALPROCUSEDONCE DisasmMoveEaSR(void)
1096{
1097 /* 0100011011mmmrrr */
1098 Disasm_opsize = 2;
1099 DisasmStartOne("MOVE ");
1100 DisasmModeRegister(Disasm_mode, Disasm_reg);
1101 dbglog_writeCStr(", SR");
1102 dbglog_writeReturn();
1103}
1104
1105LOCALPROC DisasmBinOpStatusCCR(void)
1106{
1107 switch (Disasm_rg9) {
1108 case 0 :
1109 DisasmStartOne("OR");
1110 break;
1111 case 1 :
1112 DisasmStartOne("AND");
1113 break;
1114 case 5 :
1115 DisasmStartOne("EOR");
1116 break;
1117 default: /* should not happen */
1118 break;
1119 }
1120 DisasmOpSizeFromb76();
1121 dbglog_writeCStr(" #");
1122 dbglog_writeHex(ui5r_FromSWord(Disasm_nextiword()));
1123 if (Disasm_b76 != 0) {
1124 dbglog_writeCStr(", SR");
1125 } else {
1126 dbglog_writeCStr(", CCR");
1127 }
1128 dbglog_writeReturn();
1129}
1130
1131LOCALPROC disasmreglist(si4b direction, ui5b m1, ui5b r1)
1132{
1133 si4b z;
1134 ui5r regmask;
1135
1136 DisasmStartOne("MOVEM");
1137
1138 regmask = Disasm_nextiword();
1139 Disasm_opsize = 2 * Disasm_b76 - 2;
1140
1141 if (Disasm_opsize == 2) {
1142 dbglog_writeCStr(".W");
1143 } else {
1144 dbglog_writeCStr(".L");
1145 }
1146
1147 dbglog_writeCStr(" ");
1148
1149 if (direction != 0) {
1150 DisasmModeRegister(m1, r1);
1151 dbglog_writeCStr(", ");
1152 }
1153
1154 for (z = 0; z < 16; ++z) {
1155 if ((regmask & (1 << z)) != 0) {
1156 if (z >= 8) {
1157 dbglog_writeCStr("A");
1158 dbglog_writeHex(z - 8);
1159 } else {
1160 dbglog_writeCStr("D");
1161 dbglog_writeHex(z);
1162 }
1163 }
1164 }
1165
1166 if (direction == 0) {
1167 dbglog_writeCStr(", ");
1168 DisasmModeRegister(m1, r1);
1169 }
1170
1171 dbglog_writeReturn();
1172}
1173
1174LOCALPROCUSEDONCE DisasmMOVEMrm(void)
1175{
1176 /* MOVEM reg to mem 010010001ssmmmrrr */
1177 disasmreglist(0, Disasm_mode, Disasm_reg);
1178}
1179
1180LOCALPROCUSEDONCE DisasmMOVEMmr(void)
1181{
1182 /* MOVEM mem to reg 0100110011smmmrrr */
1183 disasmreglist(1, Disasm_mode, Disasm_reg);
1184}
1185
1186LOCALPROC DisasmByteBinOp(char *s, ui5b m1, ui5b r1, ui5b m2, ui5b r2)
1187{
1188 DisasmStartOne(s);
1189 dbglog_writeCStr(" ");
1190 DisasmOpSizeFromb76();
1191 DisasmModeRegister(m1, r1);
1192 dbglog_writeCStr(", ");
1193 DisasmModeRegister(m2, r2);
1194 dbglog_writeReturn();
1195}
1196
1197LOCALPROCUSEDONCE DisasmAbcdr(void)
1198{
1199 /* ABCD 1100ddd100000rrr */
1200 DisasmByteBinOp("ABCD", 0, Disasm_reg, 0, Disasm_rg9);
1201}
1202
1203LOCALPROCUSEDONCE DisasmAbcdm(void)
1204{
1205 /* ABCD 1100ddd100001rrr */
1206 DisasmByteBinOp("ABCD", 4, Disasm_reg, 4, Disasm_rg9);
1207}
1208
1209LOCALPROCUSEDONCE DisasmSbcdr(void)
1210{
1211 /* SBCD 1000xxx100000xxx */
1212 DisasmByteBinOp("ABCD", 0, Disasm_reg, 0, Disasm_rg9);
1213}
1214
1215LOCALPROCUSEDONCE DisasmSbcdm(void)
1216{
1217 /* SBCD 1000xxx100001xxx */
1218 DisasmByteBinOp("ABCD", 4, Disasm_reg, 4, Disasm_rg9);
1219}
1220
1221LOCALPROCUSEDONCE DisasmNbcd(void)
1222{
1223 /* Nbcd 0100100000mmmrrr */
1224 Disasm_xxxxxxxxssmmmrrr("NBCD");
1225}
1226
1227LOCALPROCUSEDONCE DisasmRte(void)
1228{
1229 /* Rte 0100111001110011 */
1230 DisasmStartOne("RTE");
1231 dbglog_writeReturn();
1232}
1233
1234LOCALPROCUSEDONCE DisasmNop(void)
1235{
1236 /* Nop 0100111001110001 */
1237 DisasmStartOne("NOP");
1238 dbglog_writeReturn();
1239}
1240
1241LOCALPROCUSEDONCE DisasmMoveP(void)
1242{
1243 /* MoveP 0000ddd1mm001aaa */
1244
1245 DisasmStartOne("MOVEP");
1246 if (0 == (Disasm_b76 & 1)) {
1247 Disasm_opsize = 2;
1248 dbglog_writeCStr(".W");
1249 } else {
1250 Disasm_opsize = 4;
1251 dbglog_writeCStr(".L");
1252 }
1253 dbglog_writeCStr(" ");
1254 if (Disasm_b76 < 2) {
1255 DisasmModeRegister(5, Disasm_reg);
1256 dbglog_writeCStr(", ");
1257 DisasmModeRegister(0, Disasm_rg9);
1258 } else {
1259 DisasmModeRegister(0, Disasm_rg9);
1260 dbglog_writeCStr(", ");
1261 DisasmModeRegister(5, Disasm_reg);
1262 }
1263 dbglog_writeReturn();
1264}
1265
1266LOCALPROCUSEDONCE DisasmIllegal(void)
1267{
1268 DisasmStartOne("ILLEGAL");
1269 dbglog_writeReturn();
1270}
1271
1272LOCALPROC DisasmCheck(void)
1273{
1274 DisasmStartOne("CHK");
1275 if (2 == Disasm_opsize) {
1276 dbglog_writeCStr(".W");
1277 } else {
1278 dbglog_writeCStr(".L");
1279 }
1280 dbglog_writeCStr(" ");
1281
1282 DisasmModeRegister(Disasm_mode, Disasm_reg);
1283 dbglog_writeCStr(", ");
1284 DisasmModeRegister(0, Disasm_rg9);
1285 dbglog_writeReturn();
1286}
1287
1288LOCALPROCUSEDONCE DisasmChkW(void)
1289{
1290 /* Chk.W 0100ddd110mmmrrr */
1291 Disasm_opsize = 2;
1292 DisasmCheck();
1293}
1294
1295LOCALPROCUSEDONCE DisasmTrap(void)
1296{
1297 /* Trap 010011100100vvvv */
1298 DisasmStartOne("TRAP ");
1299 dbglog_writeHex(Disasm_opcode & 15);
1300 dbglog_writeReturn();
1301}
1302
1303LOCALPROCUSEDONCE DisasmTrapV(void)
1304{
1305 /* TrapV 0100111001110110 */
1306 DisasmStartOne("TRAPV");
1307 dbglog_writeReturn();
1308}
1309
1310LOCALPROCUSEDONCE DisasmRtr(void)
1311{
1312 /* Rtr 0100111001110111 */
1313 DisasmStartOne("RTR");
1314 dbglog_writeReturn();
1315}
1316
1317LOCALPROCUSEDONCE DisasmLink(void)
1318{
1319 DisasmStartOne("LINK A");
1320 dbglog_writeHex(Disasm_reg);
1321 dbglog_writeCStr(", ");
1322 dbglog_writeHex(Disasm_nextiword());
1323 dbglog_writeReturn();
1324}
1325
1326LOCALPROCUSEDONCE DisasmUnlk(void)
1327{
1328 DisasmStartOne("UNLINK A");
1329 dbglog_writeHex(Disasm_reg);
1330 dbglog_writeReturn();
1331}
1332
1333LOCALPROCUSEDONCE DisasmMoveRUSP(void)
1334{
1335 /* MOVE USP 0100111001100aaa */
1336 DisasmStartOne("MOVE A");
1337 dbglog_writeHex(Disasm_reg);
1338 dbglog_writeCStr(", USP");
1339 dbglog_writeReturn();
1340}
1341
1342LOCALPROCUSEDONCE DisasmMoveUSPR(void)
1343{
1344 /* MOVE USP 0100111001101aaa */
1345 DisasmStartOne("MOVE USP, A");
1346 dbglog_writeHex(Disasm_reg);
1347 dbglog_writeReturn();
1348}
1349
1350LOCALPROCUSEDONCE DisasmTas(void)
1351{
1352 /* Tas 0100101011mmmrrr */
1353 Disasm_opsize = 1;
1354 DisasmStartOne("TAS");
1355 dbglog_writeCStr(" ");
1356 DisasmModeRegister(Disasm_mode, Disasm_reg);
1357 dbglog_writeReturn();
1358}
1359
1360LOCALPROCUSEDONCE DisasmFLine(void)
1361{
1362 DisasmStartOne("$");
1363 dbglog_writeHex(Disasm_opcode);
1364 dbglog_writeReturn();
1365}
1366
1367LOCALPROCUSEDONCE DisasmCallMorRtm(void)
1368{
1369 DisasmStartOne("CALLM #");
1370 dbglog_writeHex(Disasm_nextibyte());
1371 dbglog_writeCStr(", ");
1372 DisasmModeRegister(Disasm_mode, Disasm_reg);
1373 dbglog_writeReturn();
1374}
1375
1376LOCALPROCUSEDONCE DisasmStop(void)
1377{
1378 /* Stop 0100111001110010 */
1379 DisasmStartOne("STOP #");
1380 dbglog_writeHex(Disasm_nextiword());
1381 dbglog_writeReturn();
1382}
1383
1384LOCALPROCUSEDONCE DisasmReset(void)
1385{
1386 /* Reset 0100111001100000 */
1387 DisasmStartOne("RESET");
1388 dbglog_writeReturn();
1389}
1390
1391#if Use68020
1392LOCALPROCUSEDONCE DisasmEXTBL(void)
1393{
1394 /* EXTB.L */
1395 DisasmStartOne("EXTB.L D");
1396 dbglog_writeHex(Disasm_reg);
1397 dbglog_writeReturn();
1398}
1399#endif
1400
1401#if Use68020
1402LOCALPROCUSEDONCE DisasmTRAPcc(void)
1403{
1404 /* TRAPcc 0101cccc11111sss */
1405
1406 DisasmStartOne("TRAP");
1407 DisasmCC();
1408
1409 switch (Disasm_reg) {
1410 case 2:
1411 dbglog_writeCStr(" ");
1412 dbglog_writeHex(Disasm_nextiword());
1413 break;
1414 case 3:
1415 dbglog_writeCStr(" ");
1416 dbglog_writeHex(Disasm_nextilong());
1417 break;
1418 case 4:
1419 /* no optional data */
1420 break;
1421 default:
1422 /* illegal format */
1423 break;
1424 }
1425
1426 dbglog_writeReturn();
1427}
1428#endif
1429
1430#if Use68020
1431LOCALPROCUSEDONCE DisasmChkL(void)
1432{
1433 /* Chk.L 0100ddd100mmmrrr */
1434 Disasm_opsize = 4;
1435 DisasmCheck();
1436}
1437#endif
1438
1439#if Use68020
1440LOCALPROCUSEDONCE DisasmBkpt(void)
1441{
1442 /* BKPT 0100100001001rrr */
1443 DisasmStartOne("BKPT #");
1444 dbglog_writeHex(Disasm_reg);
1445 dbglog_writeReturn();
1446}
1447#endif
1448
1449#if Use68020
1450LOCALPROCUSEDONCE DisasmDivL(void)
1451{
1452 /* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
1453 /* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
1454 Disasm_opsize = 4;
1455 DisasmStartOne("DIV");
1456
1457 {
1458 ui4b extra = Disasm_nextiword();
1459 ui5b rDr = extra & 7;
1460 ui5b rDq = (extra >> 12) & 7;
1461
1462 if (extra & 0x0800) {
1463 dbglog_writeCStr("S");
1464 } else {
1465 dbglog_writeCStr("U");
1466 }
1467 if (extra & 0x0400) {
1468 dbglog_writeCStr("L");
1469 }
1470 dbglog_writeCStr(".L ");
1471
1472 DisasmModeRegister(Disasm_mode, Disasm_reg);
1473
1474 dbglog_writeCStr(", ");
1475
1476 if (rDr != rDq) {
1477 dbglog_writeCStr("D");
1478 dbglog_writeHex(rDr);
1479 dbglog_writeCStr(":");
1480 }
1481 dbglog_writeCStr("D");
1482 dbglog_writeHex(rDq);
1483 }
1484
1485 dbglog_writeReturn();
1486}
1487#endif
1488
1489#if Use68020
1490LOCALPROCUSEDONCE DisasmMulL(void)
1491{
1492 /* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
1493 /* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
1494
1495 Disasm_opsize = 4;
1496 DisasmStartOne("MUL");
1497
1498 {
1499 ui4b extra = Disasm_nextiword();
1500 ui5b rhi = extra & 7;
1501 ui5b rlo = (extra >> 12) & 7;
1502
1503 if (extra & 0x0800) {
1504 dbglog_writeCStr("S");
1505 } else {
1506 dbglog_writeCStr("U");
1507 }
1508
1509 dbglog_writeCStr(".L ");
1510
1511 DisasmModeRegister(Disasm_mode, Disasm_reg);
1512
1513 dbglog_writeCStr(", ");
1514
1515 if (extra & 0x400) {
1516 dbglog_writeCStr("D");
1517 dbglog_writeHex(rhi);
1518 dbglog_writeCStr(":");
1519 }
1520 dbglog_writeCStr("D");
1521 dbglog_writeHex(rlo);
1522 }
1523
1524 dbglog_writeReturn();
1525}
1526#endif
1527
1528#if Use68020
1529LOCALPROCUSEDONCE DisasmRtd(void)
1530{
1531 /* Rtd 0100111001110100 */
1532 DisasmStartOne("RTD #");
1533 dbglog_writeHex((si5b)(si4b)Disasm_nextiword());
1534 dbglog_writeReturn();
1535}
1536#endif
1537
1538#if Use68020
1539LOCALPROC DisasmControlReg(ui4r i)
1540{
1541 switch (i) {
1542 case 0x0000:
1543 dbglog_writeCStr("SFC");
1544 break;
1545 case 0x0001:
1546 dbglog_writeCStr("DFC");
1547 break;
1548 case 0x0002:
1549 dbglog_writeCStr("CACR");
1550 break;
1551 case 0x0800:
1552 dbglog_writeCStr("USP");
1553 break;
1554 case 0x0801:
1555 dbglog_writeCStr("VBR");
1556 break;
1557 case 0x0802:
1558 dbglog_writeCStr("CAAR");
1559 break;
1560 case 0x0803:
1561 dbglog_writeCStr("MSP");
1562 break;
1563 case 0x0804:
1564 dbglog_writeCStr("ISP");
1565 break;
1566 default:
1567 dbglog_writeCStr("???");
1568 break;
1569 }
1570}
1571#endif
1572
1573#if Use68020
1574LOCALPROCUSEDONCE DisasmMoveC(void)
1575{
1576 /* MOVEC 010011100111101m */
1577 DisasmStartOne("MOVEC ");
1578
1579 {
1580 ui4b src = Disasm_nextiword();
1581 int regno = (src >> 12) & 0x0F;
1582 switch (Disasm_reg) {
1583 case 2:
1584 DisasmControlReg(src & 0x0FFF);
1585 dbglog_writeCStr(", ");
1586 if (regno < 8) {
1587 dbglog_writeCStr("D");
1588 } else {
1589 dbglog_writeCStr("A");
1590 }
1591 dbglog_writeHex(regno & 7);
1592 break;
1593 case 3:
1594 if (regno < 8) {
1595 dbglog_writeCStr("D");
1596 } else {
1597 dbglog_writeCStr("A");
1598 }
1599 dbglog_writeHex(regno & 7);
1600
1601 dbglog_writeCStr(", ");
1602
1603 DisasmControlReg(src & 0x0FFF);
1604 break;
1605 default:
1606 /* illegal */
1607 break;
1608 }
1609 }
1610
1611 dbglog_writeReturn();
1612}
1613#endif
1614
1615#if Use68020
1616LOCALPROCUSEDONCE DisasmLinkL(void)
1617{
1618 /* Link.L 0100100000001rrr */
1619 DisasmStartOne("LINK.L A");
1620 dbglog_writeHex(Disasm_reg);
1621 dbglog_writeCStr(", ");
1622 dbglog_writeHex(Disasm_nextilong());
1623 dbglog_writeReturn();
1624}
1625#endif
1626
1627#if Use68020
1628LOCALPROCUSEDONCE DisasmPack(void)
1629{
1630 DisasmStartOne("PACK ???");
1631 dbglog_writeReturn();
1632 /* DoCodePack */
1633}
1634#endif
1635
1636#if Use68020
1637LOCALPROCUSEDONCE DisasmUnpk(void)
1638{
1639 DisasmStartOne("UNPK ???");
1640 dbglog_writeReturn();
1641 /* DoCodeUnpk */
1642}
1643#endif
1644
1645#if Use68020
1646LOCALPROCUSEDONCE DisasmCHK2orCMP2(void)
1647{
1648 DisasmStartOne("CHK2/CMP2 ???");
1649 dbglog_writeReturn();
1650 /* DoCHK2orCMP2 */
1651}
1652#endif
1653
1654#if Use68020
1655LOCALPROCUSEDONCE DisasmCAS2(void)
1656{
1657 DisasmStartOne("CAS2 ???");
1658 dbglog_writeReturn();
1659 /* DoCAS2 */
1660}
1661#endif
1662
1663#if Use68020
1664LOCALPROCUSEDONCE DisasmCAS(void)
1665{
1666 DisasmStartOne("CAS ???");
1667 dbglog_writeReturn();
1668 /* DoDoCAS */
1669}
1670#endif
1671
1672#if Use68020
1673LOCALPROCUSEDONCE DisasmMOVES(void)
1674{
1675 DisasmStartOne("MOVES ???");
1676 dbglog_writeReturn();
1677 /* DoMOVES */
1678}
1679#endif
1680
1681#if Use68020
1682LOCALPROCUSEDONCE DisasmBitField(void)
1683{
1684 DisasmStartOne("BitField ???");
1685 dbglog_writeReturn();
1686 /* DoBitField */
1687}
1688#endif
1689
1690LOCALFUNC blnr IsValidAddrMode(void)
1691{
1692 return (Disasm_mode != 7) || (Disasm_reg < 5);
1693}
1694
1695LOCALFUNC blnr IsValidDstAddrMode(void)
1696{
1697 return (Disasm_md6 != 7) || (Disasm_rg9 < 2);
1698}
1699
1700LOCALFUNC blnr IsValidDataAltAddrMode(void)
1701{
1702 blnr IsOk;
1703
1704 switch (Disasm_mode) {
1705 case 1:
1706 default: /* keep compiler happy */
1707 IsOk = falseblnr;
1708 break;
1709 case 0:
1710 case 2:
1711 case 3:
1712 case 4:
1713 case 5:
1714 case 6:
1715 IsOk = trueblnr;
1716 break;
1717 case 7:
1718 IsOk = Disasm_reg < 2;
1719 break;
1720 }
1721
1722 return IsOk;
1723}
1724
1725LOCALFUNC blnr IsValidDataAddrMode(void)
1726{
1727 blnr IsOk;
1728
1729 switch (Disasm_mode) {
1730 case 1:
1731 default: /* keep compiler happy */
1732 IsOk = falseblnr;
1733 break;
1734 case 0:
1735 case 2:
1736 case 3:
1737 case 4:
1738 case 5:
1739 case 6:
1740 IsOk = trueblnr;
1741 break;
1742 case 7:
1743 IsOk = Disasm_reg < 5;
1744 break;
1745 }
1746
1747 return IsOk;
1748}
1749
1750LOCALFUNC blnr IsValidControlAddrMode(void)
1751{
1752 blnr IsOk;
1753
1754 switch (Disasm_mode) {
1755 case 0:
1756 case 1:
1757 case 3:
1758 case 4:
1759 default: /* keep compiler happy */
1760 IsOk = falseblnr;
1761 break;
1762 case 2:
1763 case 5:
1764 case 6:
1765 IsOk = trueblnr;
1766 break;
1767 case 7:
1768 IsOk = Disasm_reg < 4;
1769 break;
1770 }
1771
1772 return IsOk;
1773}
1774
1775LOCALFUNC blnr IsValidControlAltAddrMode(void)
1776{
1777 blnr IsOk;
1778
1779 switch (Disasm_mode) {
1780 case 0:
1781 case 1:
1782 case 3:
1783 case 4:
1784 default: /* keep compiler happy */
1785 IsOk = falseblnr;
1786 break;
1787 case 2:
1788 case 5:
1789 case 6:
1790 IsOk = trueblnr;
1791 break;
1792 case 7:
1793 IsOk = Disasm_reg < 2;
1794 break;
1795 }
1796
1797 return IsOk;
1798}
1799
1800LOCALFUNC blnr IsValidAltMemAddrMode(void)
1801{
1802 blnr IsOk;
1803
1804 switch (Disasm_mode) {
1805 case 0:
1806 case 1:
1807 default: /* keep compiler happy */
1808 IsOk = falseblnr;
1809 break;
1810 case 2:
1811 case 3:
1812 case 4:
1813 case 5:
1814 case 6:
1815 IsOk = trueblnr;
1816 break;
1817 case 7:
1818 IsOk = Disasm_reg < 2;
1819 break;
1820 }
1821
1822 return IsOk;
1823}
1824
1825LOCALPROCUSEDONCE DisasmCode0(void)
1826{
1827 if (Disasm_b8 == 1) {
1828 if (Disasm_mode == 1) {
1829 /* MoveP 0000ddd1mm001aaa */
1830 DisasmMoveP();
1831 } else {
1832 /* dynamic bit, Opcode = 0000ddd1ttmmmrrr */
1833 if (Disasm_mode == 0) {
1834 DisasmBitOpDD();
1835 } else {
1836 if (Disasm_b76 == 0) {
1837 if (IsValidDataAddrMode()) {
1838 DisasmBitOpDM();
1839 } else {
1840 DisasmIllegal();
1841 }
1842 } else {
1843 if (IsValidDataAltAddrMode()) {
1844 DisasmBitOpDM();
1845 } else {
1846 DisasmIllegal();
1847 }
1848 }
1849 }
1850 }
1851 } else {
1852 if (Disasm_rg9 == 4) {
1853 /* static bit 00001010ssmmmrrr */
1854 if (Disasm_mode == 0) {
1855 DisasmBitOpND();
1856 } else {
1857 if (Disasm_b76 == 0) {
1858 if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
1859 DisasmIllegal();
1860 } else {
1861 if (IsValidDataAddrMode()) {
1862 DisasmBitOpNM();
1863 } else {
1864 DisasmIllegal();
1865 }
1866 }
1867 } else {
1868 if (IsValidDataAltAddrMode()) {
1869 DisasmBitOpNM();
1870 } else {
1871 DisasmIllegal();
1872 }
1873 }
1874 }
1875 } else
1876 if (Disasm_b76 == 3) {
1877#if Use68020
1878 if (Disasm_rg9 < 3) {
1879 /* CHK2 or CMP2 00000ss011mmmrrr */
1880 if (IsValidControlAddrMode()) {
1881 DisasmCHK2orCMP2();
1882 } else {
1883 DisasmIllegal();
1884 }
1885 } else
1886 if (Disasm_rg9 >= 5) {
1887 if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
1888 /* CAS2 00001ss011111100 */
1889 DisasmCAS2();
1890 } else {
1891 /* CAS 00001ss011mmmrrr */
1892 DisasmCAS2();
1893 }
1894 } else
1895 if (Disasm_rg9 == 3) {
1896 /* CALLM or RTM 0000011011mmmrrr */
1897 DisasmCallMorRtm();
1898 } else
1899#endif
1900 {
1901 DisasmIllegal();
1902 }
1903 } else
1904 if (Disasm_rg9 == 6) {
1905 /* CMPI 00001100ssmmmrrr */
1906 if (IsValidDataAltAddrMode()) {
1907 DisasmCmpI();
1908 } else {
1909 DisasmIllegal();
1910 }
1911 } else if (Disasm_rg9 == 7) {
1912#if Use68020
1913 /* MoveS 00001110ssmmmrrr */
1914 if (IsValidAltMemAddrMode()) {
1915 DisasmMoveSREa();
1916 } else {
1917 DisasmIllegal();
1918 }
1919#else
1920 DisasmIllegal();
1921#endif
1922 } else {
1923 if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
1924 switch (Disasm_rg9) {
1925 case 0:
1926 case 1:
1927 case 5:
1928 DisasmBinOpStatusCCR();
1929 break;
1930 default:
1931 DisasmIllegal();
1932 break;
1933 }
1934 } else {
1935 if (! IsValidDataAltAddrMode()) {
1936 DisasmIllegal();
1937 } else {
1938 switch (Disasm_rg9) {
1939 case 0:
1940 DisasmOrI();
1941 break;
1942 case 1:
1943 DisasmAndI();
1944 break;
1945 case 2:
1946 DisasmSubI();
1947 break;
1948 case 3:
1949 DisasmAddI();
1950 break;
1951 case 5:
1952 DisasmEorI();
1953 break;
1954 default:
1955 /*
1956 for compiler.
1957 should be 0, 1, 2, 3, or 5
1958 */
1959 DisasmIllegal();
1960 break;
1961 }
1962 }
1963 }
1964 }
1965 }
1966}
1967
1968LOCALPROCUSEDONCE DisasmCode1(void)
1969{
1970 if ((Disasm_mode == 1) || ! IsValidAddrMode()) {
1971 DisasmIllegal();
1972 } else if (Disasm_md6 == 1) { /* MOVEA */
1973 DisasmIllegal();
1974 } else if (! IsValidDstAddrMode()) {
1975 DisasmIllegal();
1976 } else {
1977 DisasmMoveB();
1978 }
1979}
1980
1981LOCALPROCUSEDONCE DisasmCode2(void)
1982{
1983 if (Disasm_md6 == 1) { /* MOVEA */
1984 if (IsValidAddrMode()) {
1985 DisasmMoveAL();
1986 } else {
1987 DisasmIllegal();
1988 }
1989 } else if (! IsValidAddrMode()) {
1990 DisasmIllegal();
1991 } else if (! IsValidDstAddrMode()) {
1992 DisasmIllegal();
1993 } else {
1994 DisasmMoveL();
1995 }
1996}
1997
1998LOCALPROCUSEDONCE DisasmCode3(void)
1999{
2000 if (Disasm_md6 == 1) { /* MOVEA */
2001 if (IsValidAddrMode()) {
2002 DisasmMoveAW();
2003 } else {
2004 DisasmIllegal();
2005 }
2006 } else if (! IsValidAddrMode()) {
2007 DisasmIllegal();
2008 } else if (! IsValidDstAddrMode()) {
2009 DisasmIllegal();
2010 } else {
2011 DisasmMoveW();
2012 }
2013}
2014
2015LOCALPROCUSEDONCE DisasmCode4(void)
2016{
2017 if (Disasm_b8 != 0) {
2018 switch (Disasm_b76) {
2019 case 0:
2020#if Use68020
2021 /* Chk.L 0100ddd100mmmrrr */
2022 if (IsValidDataAddrMode()) {
2023 DisasmChkL();
2024 } else {
2025 DisasmIllegal();
2026 }
2027#else
2028 DisasmIllegal();
2029#endif
2030 break;
2031 case 1:
2032 DisasmIllegal();
2033 break;
2034 case 2:
2035 /* Chk.W 0100ddd110mmmrrr */
2036 if (IsValidDataAddrMode()) {
2037 DisasmChkW();
2038 } else {
2039 DisasmIllegal();
2040 }
2041 break;
2042 case 3:
2043 default: /* keep compiler happy */
2044#if Use68020
2045 if ((0 == Disasm_mode) && (4 == Disasm_rg9)) {
2046 DisasmEXTBL();
2047 } else
2048#endif
2049 {
2050 /* Lea 0100aaa111mmmrrr */
2051 if (IsValidControlAddrMode()) {
2052 DisasmLea();
2053 } else {
2054 DisasmIllegal();
2055 }
2056 }
2057 break;
2058 }
2059 } else {
2060 switch (Disasm_rg9) {
2061 case 0:
2062 if (Disasm_b76 != 3) {
2063 /* NegX 01000000ssmmmrrr */
2064 if (IsValidDataAltAddrMode()) {
2065 DisasmNegX();
2066 } else {
2067 DisasmIllegal();
2068 }
2069 } else {
2070#if Use68020
2071/* reference seems incorrect to say not for 68000 */
2072#endif
2073 /* Move from SR 0100000011mmmrrr */
2074 if (IsValidDataAltAddrMode()) {
2075 DisasmMoveSREa();
2076 } else {
2077 DisasmIllegal();
2078 }
2079 }
2080 break;
2081 case 1:
2082 if (Disasm_b76 != 3) {
2083 /* Clr 01000010ssmmmrrr */
2084 if (IsValidDataAltAddrMode()) {
2085 DisasmClr();
2086 } else {
2087 DisasmIllegal();
2088 }
2089 } else {
2090#if Use68020
2091 /* Move from CCR 0100001011mmmrrr */
2092 if (IsValidDataAltAddrMode()) {
2093 DisasmMoveCCREa();
2094 } else {
2095 DisasmIllegal();
2096 }
2097#else
2098 DisasmIllegal();
2099#endif
2100 }
2101 break;
2102 case 2:
2103 if (Disasm_b76 != 3) {
2104 /* Neg 01000100ssmmmrrr */
2105 if (IsValidDataAltAddrMode()) {
2106 DisasmNeg();
2107 } else {
2108 DisasmIllegal();
2109 }
2110 } else {
2111 /* Move to CCR 0100010011mmmrrr */
2112 if (IsValidDataAddrMode()) {
2113 DisasmMoveEaCR();
2114 } else {
2115 DisasmIllegal();
2116 }
2117 }
2118 break;
2119 case 3:
2120 if (Disasm_b76 != 3) {
2121 /* Not 01000110ssmmmrrr */
2122 if (IsValidDataAltAddrMode()) {
2123 DisasmNot();
2124 } else {
2125 DisasmIllegal();
2126 }
2127 } else {
2128 /* Move from SR 0100011011mmmrrr */
2129 if (IsValidDataAddrMode()) {
2130 DisasmMoveEaSR();
2131 } else {
2132 DisasmIllegal();
2133 }
2134 }
2135 break;
2136 case 4:
2137 switch (Disasm_b76) {
2138 case 0:
2139#if Use68020
2140 if (Disasm_mode == 1) {
2141 /* Link.L 0100100000001rrr */
2142 DisasmLinkL();
2143 } else
2144#endif
2145 {
2146 /* Nbcd 0100100000mmmrrr */
2147 if (IsValidDataAltAddrMode()) {
2148 DisasmNbcd();
2149 } else {
2150 DisasmIllegal();
2151 }
2152 }
2153 break;
2154 case 1:
2155 if (Disasm_mode == 0) {
2156 /* Swap 0100100001000rrr */
2157 DisasmSwap();
2158 } else
2159#if Use68020
2160 if (Disasm_mode == 1) {
2161 DisasmBkpt();
2162 } else
2163#endif
2164 {
2165 /* PEA 0100100001mmmrrr */
2166 if (IsValidControlAddrMode()) {
2167 DisasmPEA();
2168 } else {
2169 DisasmIllegal();
2170 }
2171 }
2172 break;
2173 case 2:
2174 if (Disasm_mode == 0) {
2175 /* EXT.W */
2176 DisasmEXTW();
2177 } else {
2178 /*
2179 MOVEM Disasm_reg
2180 to mem 01001d001ssmmmrrr
2181 */
2182 if (Disasm_mode == 4) {
2183 DisasmMOVEMRmM();
2184 } else {
2185 if (IsValidControlAltAddrMode()) {
2186 DisasmMOVEMrm();
2187 } else {
2188 DisasmIllegal();
2189 }
2190 }
2191 }
2192 break;
2193 case 3:
2194 default: /* keep compiler happy */
2195 if (Disasm_mode == 0) {
2196 /* EXT.L */
2197 DisasmEXTL();
2198 } else {
2199 /*
2200 MOVEM Disasm_reg
2201 to mem 01001d001ssmmmrrr
2202 */
2203 if (Disasm_mode == 4) {
2204 DisasmMOVEMRmM();
2205 } else {
2206 if (IsValidControlAltAddrMode()) {
2207 DisasmMOVEMrm();
2208 } else {
2209 DisasmIllegal();
2210 }
2211 }
2212 }
2213 break;
2214 }
2215 break;
2216 case 5:
2217 if (Disasm_b76 == 3) {
2218 if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
2219 /* the ILLEGAL instruction */
2220 DisasmIllegal();
2221 } else {
2222 /* Tas 0100101011mmmrrr */
2223 if (IsValidDataAltAddrMode()) {
2224 DisasmTas();
2225 } else {
2226 DisasmIllegal();
2227 }
2228 }
2229 } else {
2230 /* Tst 01001010ssmmmrrr */
2231 if (Disasm_b76 == 0) {
2232 if (IsValidDataAltAddrMode()) {
2233 DisasmTst();
2234 } else {
2235 DisasmIllegal();
2236 }
2237 } else {
2238 if (IsValidAddrMode()) {
2239 DisasmTst();
2240 } else {
2241 DisasmIllegal();
2242 }
2243 }
2244 }
2245 break;
2246 case 6:
2247 if (((Disasm_opcode >> 7) & 1) == 1) {
2248 /* MOVEM mem to Disasm_reg 0100110011smmmrrr */
2249 if (Disasm_mode == 3) {
2250 DisasmMOVEMApR();
2251 } else {
2252 if (IsValidControlAddrMode()) {
2253 DisasmMOVEMmr();
2254 } else {
2255 DisasmIllegal();
2256 }
2257 }
2258 } else {
2259#if Use68020
2260 if (((Disasm_opcode >> 6) & 1) == 1) {
2261 /* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
2262 /* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
2263 DisasmDivL();
2264 } else {
2265 /* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
2266 /* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
2267 DisasmMulL();
2268 }
2269#else
2270 DisasmIllegal();
2271#endif
2272 }
2273 break;
2274 case 7:
2275 default: /* keep compiler happy */
2276 switch (Disasm_b76) {
2277 case 0:
2278 DisasmIllegal();
2279 break;
2280 case 1:
2281 switch (Disasm_mode) {
2282 case 0:
2283 case 1:
2284 /* Trap 010011100100vvvv */
2285 DisasmTrap();
2286 break;
2287 case 2:
2288 /* Link */
2289 if (Disasm_reg == 6) {
2290 DisasmLinkA6();
2291 } else {
2292 DisasmLink();
2293 }
2294 break;
2295 case 3:
2296 /* Unlk */
2297 if (Disasm_reg == 6) {
2298 DisasmUnlkA6();
2299 } else {
2300 DisasmUnlk();
2301 }
2302 break;
2303 case 4:
2304 /* MOVE USP 0100111001100aaa */
2305 DisasmMoveRUSP();
2306 break;
2307 case 5:
2308 /* MOVE USP 0100111001101aaa */
2309 DisasmMoveUSPR();
2310 break;
2311 case 6:
2312 switch (Disasm_reg) {
2313 case 0:
2314 /* Reset 0100111001100000 */
2315 DisasmReset();
2316 break;
2317 case 1:
2318 /*
2319 Nop Opcode
2320 = 0100111001110001
2321 */
2322 DisasmNop();
2323 break;
2324 case 2:
2325 /* Stop 0100111001110010 */
2326 DisasmStop();
2327 break;
2328 case 3:
2329 /* Rte 0100111001110011 */
2330 DisasmRte();
2331 break;
2332 case 4:
2333 /* Rtd 0100111001110100 */
2334#if Use68020
2335 DisasmRtd();
2336#else
2337 DisasmIllegal();
2338#endif
2339 break;
2340 case 5:
2341 /* Rts 0100111001110101 */
2342 DisasmRts();
2343 break;
2344 case 6:
2345 /* TrapV 0100111001110110 */
2346 DisasmTrapV();
2347 break;
2348 case 7:
2349 default: /* keep compiler happy */
2350 /* Rtr 0100111001110111 */
2351 DisasmRtr();
2352 break;
2353 }
2354 break;
2355 case 7:
2356 default: /* keep compiler happy */
2357#if Use68020
2358 /* MOVEC 010011100111101m */
2359 DisasmMoveC();
2360#else
2361 DisasmIllegal();
2362#endif
2363 break;
2364 }
2365 break;
2366 case 2:
2367 /* Jsr 0100111010mmmrrr */
2368 if (IsValidControlAddrMode()) {
2369 DisasmJsr();
2370 } else {
2371 DisasmIllegal();
2372 }
2373 break;
2374 case 3:
2375 default: /* keep compiler happy */
2376 /* JMP 0100111011mmmrrr */
2377 if (IsValidControlAddrMode()) {
2378 DisasmJmp();
2379 } else {
2380 DisasmIllegal();
2381 }
2382 break;
2383 }
2384 break;
2385 }
2386 }
2387}
2388
2389LOCALPROCUSEDONCE DisasmCode5(void)
2390{
2391 if (Disasm_b76 == 3) {
2392 if (Disasm_mode == 1) {
2393 /* DBcc 0101cccc11001ddd */
2394 DisasmDBcc();
2395 } else {
2396#if Use68020
2397 if ((Disasm_mode == 7) && (Disasm_reg >= 2)) {
2398 /* TRAPcc 0101cccc11111sss */
2399 DisasmTRAPcc();
2400 } else
2401#endif
2402 {
2403 /* Scc 0101cccc11mmmrrr */
2404 if (IsValidDataAltAddrMode()) {
2405 DisasmScc();
2406 } else {
2407 DisasmIllegal();
2408 }
2409 }
2410 }
2411 } else {
2412 if (Disasm_mode == 1) {
2413 if (Disasm_b8 == 0) {
2414 DisasmAddQA(); /* AddQA 0101nnn0ss001rrr */
2415 } else {
2416 DisasmSubQA(); /* SubQA 0101nnn1ss001rrr */
2417 }
2418 } else {
2419 if (Disasm_b8 == 0) {
2420 /* AddQ 0101nnn0ssmmmrrr */
2421 if (IsValidDataAltAddrMode()) {
2422 DisasmAddQ();
2423 } else {
2424 DisasmIllegal();
2425 }
2426 } else {
2427 /* SubQ 0101nnn1ssmmmrrr */
2428 if (IsValidDataAltAddrMode()) {
2429 DisasmSubQ();
2430 } else {
2431 DisasmIllegal();
2432 }
2433 }
2434 }
2435 }
2436}
2437
2438LOCALPROCUSEDONCE DisasmCode6(void)
2439{
2440 ui5b cond = (Disasm_opcode >> 8) & 15;
2441
2442 if (cond == 1) {
2443 /* Bsr 01100001nnnnnnnn */
2444 DisasmBsr();
2445 } else if (cond == 0) {
2446 /* Bra 01100000nnnnnnnn */
2447 DisasmBcc();
2448 } else {
2449 /* Bcc 0110ccccnnnnnnnn */
2450 DisasmBcc();
2451 }
2452}
2453
2454LOCALPROCUSEDONCE DisasmCode7(void)
2455{
2456 if (Disasm_b8 == 0) {
2457 DisasmMoveQ();
2458 } else {
2459 DisasmIllegal();
2460 }
2461}
2462
2463LOCALPROCUSEDONCE DisasmCode8(void)
2464{
2465 if (Disasm_b76 == 3) {
2466 if (Disasm_b8 == 0) {
2467 /* DivU 1000ddd011mmmrrr */
2468 if (IsValidDataAddrMode()) {
2469 DisasmDivU();
2470 } else {
2471 DisasmIllegal();
2472 }
2473 } else {
2474 /* DivS 1000ddd111mmmrrr */
2475 if (IsValidDataAddrMode()) {
2476 DisasmDivS();
2477 } else {
2478 DisasmIllegal();
2479 }
2480 }
2481 } else {
2482 if (Disasm_b8 == 0) {
2483 /* OR 1000ddd0ssmmmrrr */
2484 if (IsValidDataAddrMode()) {
2485 DisasmOrEaD();
2486 } else {
2487 DisasmIllegal();
2488 }
2489 } else {
2490 if (Disasm_mode < 2) {
2491 switch (Disasm_b76) {
2492 case 0:
2493 /* SBCD 1000xxx10000mxxx */
2494 if (Disasm_mode == 0) {
2495 DisasmSbcdr();
2496 } else {
2497 DisasmSbcdm();
2498 }
2499 break;
2500#if Use68020
2501 case 1:
2502 /* PACK 1000rrr10100mrrr */
2503 DisasmPack();
2504 break;
2505 case 2:
2506 /* UNPK 1000rrr11000mrrr */
2507 DisasmUnpk();
2508 break;
2509#endif
2510 default:
2511 DisasmIllegal();
2512 break;
2513 }
2514 } else {
2515 /* OR 1000ddd1ssmmmrrr */
2516 if (IsValidDataAltAddrMode()) {
2517 DisasmOrDEa();
2518 } else {
2519 DisasmIllegal();
2520 }
2521 }
2522 }
2523 }
2524}
2525
2526LOCALPROCUSEDONCE DisasmCode9(void)
2527{
2528 if (Disasm_b76 == 3) {
2529 /* SUBA 1001dddm11mmmrrr */
2530 if (IsValidAddrMode()) {
2531 DisasmSubA();
2532 } else {
2533 DisasmIllegal();
2534 }
2535 } else {
2536 if (Disasm_b8 == 0) {
2537 /* SUB 1001ddd0ssmmmrrr */
2538 if (IsValidAddrMode()) {
2539 DisasmSubEaR();
2540 } else {
2541 DisasmIllegal();
2542 }
2543 } else {
2544 if (Disasm_mode == 0) {
2545 /* SUBX 1001ddd1ss000rrr */
2546 DisasmSubXd();
2547 } else if (Disasm_mode == 1) {
2548 /* SUBX 1001ddd1ss001rrr */
2549 DisasmSubXm();
2550 } else {
2551 /* SUB 1001ddd1ssmmmrrr */
2552 if (IsValidAltMemAddrMode()) {
2553 DisasmSubREa();
2554 } else {
2555 DisasmIllegal();
2556 }
2557 }
2558 }
2559 }
2560}
2561
2562LOCALPROCUSEDONCE DisasmCodeA(void)
2563{
2564 DisasmALine();
2565}
2566
2567LOCALPROCUSEDONCE DisasmCodeB(void)
2568{
2569 if (Disasm_b76 == 3) {
2570 /* CMPA 1011ddds11mmmrrr */
2571 if (IsValidAddrMode()) {
2572 DisasmCmpA();
2573 } else {
2574 DisasmIllegal();
2575 }
2576 } else if (Disasm_b8 == 1) {
2577 if (Disasm_mode == 1) {
2578 /* CmpM 1011ddd1ss001rrr */
2579 DisasmCmpM();
2580 } else {
2581 /* Eor 1011ddd1ssmmmrrr */
2582 if (IsValidDataAltAddrMode()) {
2583 DisasmEor();
2584 } else {
2585 DisasmIllegal();
2586 }
2587 }
2588 } else {
2589 /* Cmp 1011ddd0ssmmmrrr */
2590 if (IsValidAddrMode()) {
2591 DisasmCompare();
2592 } else {
2593 DisasmIllegal();
2594 }
2595 }
2596}
2597
2598LOCALPROCUSEDONCE DisasmCodeC(void)
2599{
2600 if (Disasm_b76 == 3) {
2601 if (Disasm_b8 == 0) {
2602 /* MulU 1100ddd011mmmrrr */
2603 if (IsValidDataAddrMode()) {
2604 DisasmMulU();
2605 } else {
2606 DisasmIllegal();
2607 }
2608 } else {
2609 /* MulS 1100ddd111mmmrrr */
2610 if (IsValidDataAddrMode()) {
2611 DisasmMulS();
2612 } else {
2613 DisasmIllegal();
2614 }
2615 }
2616 } else {
2617 if (Disasm_b8 == 0) {
2618 /* And 1100ddd0ssmmmrrr */
2619 if (IsValidDataAddrMode()) {
2620 DisasmAndEaD();
2621 } else {
2622 DisasmIllegal();
2623 }
2624 } else {
2625 if (Disasm_mode < 2) {
2626 switch (Disasm_b76) {
2627 case 0:
2628 /* ABCD 1100ddd10000mrrr */
2629 if (Disasm_mode == 0) {
2630 DisasmAbcdr();
2631 } else {
2632 DisasmAbcdm();
2633 }
2634 break;
2635 case 1:
2636 /* Exg 1100ddd10100trrr */
2637 if (Disasm_mode == 0) {
2638 DisasmExgdd();
2639 } else {
2640 DisasmExgaa();
2641 }
2642 break;
2643 case 2:
2644 default: /* keep compiler happy */
2645 if (Disasm_mode == 0) {
2646 DisasmIllegal();
2647 } else {
2648 /* Exg 1100ddd110001rrr */
2649 DisasmExgda();
2650 }
2651 break;
2652 }
2653 } else {
2654 /* And 1100ddd1ssmmmrrr */
2655 if (IsValidAltMemAddrMode()) {
2656 DisasmAndDEa();
2657 } else {
2658 DisasmIllegal();
2659 }
2660 }
2661 }
2662 }
2663}
2664
2665LOCALPROCUSEDONCE DisasmCodeD(void)
2666{
2667 if (Disasm_b76 == 3) {
2668 /* ADDA 1101dddm11mmmrrr */
2669 if (IsValidAddrMode()) {
2670 DisasmAddA();
2671 } else {
2672 DisasmIllegal();
2673 }
2674 } else {
2675 if (Disasm_b8 == 0) {
2676 /* ADD 1101ddd0ssmmmrrr */
2677 if (IsValidAddrMode()) {
2678 DisasmAddEaR();
2679 } else {
2680 DisasmIllegal();
2681 }
2682 } else {
2683 if (Disasm_mode == 0) {
2684 DisasmAddXd();
2685 } else if (Disasm_mode == 1) {
2686 DisasmAddXm();
2687 } else {
2688 /* ADD 1101ddd1ssmmmrrr */
2689 if (IsValidAltMemAddrMode()) {
2690 DisasmAddREa();
2691 } else {
2692 DisasmIllegal();
2693 }
2694 }
2695 }
2696 }
2697}
2698
2699LOCALPROCUSEDONCE DisasmCodeE(void)
2700{
2701 if (Disasm_b76 == 3) {
2702 if ((Disasm_opcode & 0x0800) != 0) {
2703#if Use68020
2704 /* 11101???11mmmrrr */
2705 switch (Disasm_mode) {
2706 case 1:
2707 case 3:
2708 case 4:
2709 default: /* keep compiler happy */
2710 DisasmIllegal();
2711 break;
2712 case 0:
2713 case 2:
2714 case 5:
2715 case 6:
2716 DisasmBitField();
2717 break;
2718 case 7:
2719 switch (Disasm_reg) {
2720 case 0:
2721 case 1:
2722 DisasmBitField();
2723 break;
2724 case 2:
2725 case 3:
2726 switch ((Disasm_opcode >> 8) & 7) {
2727 case 0: /* BFTST */
2728 case 1: /* BFEXTU */
2729 case 3: /* BFEXTS */
2730 case 5: /* BFFFO */
2731 DisasmBitField();
2732 break;
2733 default:
2734 DisasmIllegal();
2735 break;
2736 }
2737 break;
2738 default:
2739 DisasmIllegal();
2740 break;
2741 }
2742 break;
2743 }
2744#else
2745 DisasmIllegal();
2746#endif
2747 } else {
2748 /* 11100ttd11mmmddd */
2749 if (IsValidAltMemAddrMode()) {
2750 DisasmRolopNM();
2751 } else {
2752 DisasmIllegal();
2753 }
2754 }
2755 } else {
2756 if (Disasm_mode < 4) {
2757 /* 1110cccdss0ttddd */
2758 DisasmRolopND();
2759 } else {
2760 /* 1110rrrdss1ttddd */
2761 DisasmRolopDD();
2762 }
2763 }
2764}
2765
2766LOCALPROCUSEDONCE DisasmCodeF(void)
2767{
2768 DisasmFLine();
2769}
2770
2771LOCALPROC m68k_Disasm_one(void)
2772{
2773 Disasm_opcode = Disasm_nextiword();
2774
2775 switch (Disasm_opcode >> 12) {
2776 case 0x0:
2777 DisasmCode0();
2778 break;
2779 case 0x1:
2780 DisasmCode1();
2781 break;
2782 case 0x2:
2783 DisasmCode2();
2784 break;
2785 case 0x3:
2786 DisasmCode3();
2787 break;
2788 case 0x4:
2789 DisasmCode4();
2790 break;
2791 case 0x5:
2792 DisasmCode5();
2793 break;
2794 case 0x6:
2795 DisasmCode6();
2796 break;
2797 case 0x7:
2798 DisasmCode7();
2799 break;
2800 case 0x8:
2801 DisasmCode8();
2802 break;
2803 case 0x9:
2804 DisasmCode9();
2805 break;
2806 case 0xA:
2807 DisasmCodeA();
2808 break;
2809 case 0xB:
2810 DisasmCodeB();
2811 break;
2812 case 0xC:
2813 DisasmCodeC();
2814 break;
2815 case 0xD:
2816 DisasmCodeD();
2817 break;
2818 case 0xE:
2819 DisasmCodeE();
2820 break;
2821 case 0xF:
2822 default: /* keep compiler happy */
2823 DisasmCodeF();
2824 break;
2825 }
2826}
2827
2828#define Ln2SavedPCs 4
2829#define NumSavedPCs (1 << Ln2SavedPCs)
2830#define SavedPCsMask (NumSavedPCs - 1)
2831LOCALVAR ui5r SavedPCs[NumSavedPCs];
2832LOCALVAR ui5r SavedPCsIn = 0;
2833LOCALVAR ui5r SavedPCsOut = 0;
2834
2835#define DisasmIncludeCycles 0
2836
2837LOCALPROCUSEDONCE DisasmOneAndBack(ui5r pc)
2838{
2839#if DisasmIncludeCycles
2840 dbglog_writeHex(GetCuriCount());
2841 dbglog_writeCStr(" ");
2842#endif
2843 dbglog_writeHex(pc);
2844 dbglog_writeCStr(" ");
2845 Disasm_setpc(pc);
2846 m68k_Disasm_one();
2847}
2848
2849LOCALPROCUSEDONCE DisasmSavedPCs(void)
2850{
2851 ui5r n = SavedPCsIn - SavedPCsOut;
2852
2853 if (n != 0) {
2854 ui5r pc;
2855#if DisasmIncludeCycles
2856 ui5r i;
2857#endif
2858#if 0
2859 blnr Skipped = falseblnr;
2860#endif
2861 ui5r j = SavedPCsOut;
2862
2863 SavedPCsOut = SavedPCsIn;
2864 /*
2865 do first, prevent recursion
2866 in case of error while disassembling.
2867 (i.e. failure to read emulated memory.)
2868 */
2869
2870#if DisasmIncludeCycles
2871 i = GetCuriCount();
2872#endif
2873
2874 if (n > NumSavedPCs) {
2875 n = NumSavedPCs;
2876 j = SavedPCsIn - NumSavedPCs;
2877 dbglog_writeReturn();
2878#if 0
2879 Skipped = trueblnr;
2880#endif
2881 }
2882
2883 do {
2884 --n;
2885 pc = SavedPCs[j & SavedPCsMask];
2886#if DisasmIncludeCycles
2887 dbglog_writeHex(i /* - n */);
2888 dbglog_writeCStr("-? ");
2889#endif
2890 dbglog_writeHex(pc);
2891 dbglog_writeCStr(" ");
2892 Disasm_setpc(pc);
2893 m68k_Disasm_one();
2894 ++j;
2895 } while (n != 0);
2896
2897#if 0
2898 if (Skipped) {
2899 si4b z;
2900
2901 for (z = 0; z < 16; ++z) {
2902 if (z >= 8) {
2903 dbglog_writeCStr(" A");
2904 dbglog_writeHex(z - 8);
2905 } else {
2906 dbglog_writeCStr(" D");
2907 dbglog_writeHex(z);
2908 }
2909 dbglog_writeCStr(" = ");
2910 dbglog_writeHex(regs.regs[z]);
2911 dbglog_writeReturn();
2912 }
2913 }
2914#endif
2915 }
2916}
2917
2918LOCALVAR ui5r DisasmCounter = 0;
2919
2920GLOBALPROC DisasmOneOrSave(ui5r pc)
2921{
2922 if (0 != DisasmCounter) {
2923 DisasmOneAndBack(pc);
2924 --DisasmCounter;
2925 } else {
2926 SavedPCs[SavedPCsIn & SavedPCsMask] = pc;
2927 ++SavedPCsIn;
2928 }
2929}
2930
2931GLOBALPROC m68k_WantDisasmContext(void)
2932{
2933 DisasmSavedPCs();
2934 DisasmCounter = /* 256 */ 128;
2935}
2936
2937#endif /* WantDisasm */