this repo has no description
at main 2937 lines 54 kB view raw
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 */