comparison 68kinst.c @ 9:0a0cd3705c19

Implement (possibly broken) decoding of all M68000 instructions not in the OR_DIV_SBCD group
author Mike Pavone <pavone@retrodev.com>
date Tue, 13 Nov 2012 18:26:43 -0800
parents 23b83d94c633
children 4553fc97b15e
comparison
equal deleted inserted replaced
8:23b83d94c633 9:0a0cd3705c19
323 } 323 }
324 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 324 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
325 break; 325 break;
326 case 7: 326 case 7:
327 //MOVEP 327 //MOVEP
328 deocded->op = M68K_MOVEP; 328 decoded->op = M68K_MOVEP;
329 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; 329 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD;
330 if (*istream & 0x80) { 330 if (*istream & 0x80) {
331 //memory dest 331 //memory dest
332 decoded->src.addr_mode = MODE_REG; 332 decoded->src.addr_mode = MODE_REG;
333 decoded->src.params.regs.pri = m68K_reg_quick_field(*istream); 333 decoded->src.params.regs.pri = m68K_reg_quick_field(*istream);
335 decoded->dst.params.regs.pri = *istream & 0x7; 335 decoded->dst.params.regs.pri = *istream & 0x7;
336 } else { 336 } else {
337 //memory source 337 //memory source
338 decoded->dst.addr_mode = MODE_REG; 338 decoded->dst.addr_mode = MODE_REG;
339 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); 339 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream);
340 decoded->sr.addr_mode = MODE_AREG_DISPLACE; 340 decoded->src.addr_mode = MODE_AREG_DISPLACE;
341 decoded->sr.params.regs.pri = *istream & 0x7; 341 decoded->src.params.regs.pri = *istream & 0x7;
342 } 342 }
343 immed = *(++istream); 343 immed = *(++istream);
344 344
345 break; 345 break;
346 } 346 }
367 decoded->op = M68K_CHK; 367 decoded->op = M68K_CHK;
368 if ((*istream & 0x180) == 0x180) { 368 if ((*istream & 0x180) == 0x180) {
369 decoded->extra.size = OPSIZE_WORD; 369 decoded->extra.size = OPSIZE_WORD;
370 } else { 370 } else {
371 //only on M68020+ 371 //only on M68020+
372 #ifdef M68020
372 decoded->extra.size = OPSIZE_LONG; 373 decoded->extra.size = OPSIZE_LONG;
374 #else
375 decoded->op = M68K_INVALID;
376 break;
377 #endif
373 } 378 }
374 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 379 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
375 decoded->dst.addr_mode = MODE_REG; 380 decoded->dst.addr_mode = MODE_REG;
376 decoded->dst.addr_mode = m68K_reg_quick_field(*istream); 381 decoded->dst.addr_mode = m68K_reg_quick_field(*istream);
377 } else { 382 } else {
378 optype = (*istream >> 9) & 0x7; 383 if ((*istream & 0xB80) == 0x880) {
379 switch(optype) 384 decoded->op = M68K_MOVEM;
380 { 385 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD;
381 case 0: 386 immed = *(++istream);
382 //Move from SR or NEGX 387 opmode = (*istream >> 3) & 0x7;
383 break; 388 reg = *istream & 0x7;
384 case 1: 389 if(*istream & 0x400) {
385 //MOVE from CCR or CLR 390 decoded->dst.addr_mode = MODE_REG;
386 break; 391 decoded->dst.params.u16 = immed;
387 case 2: 392 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src));
388 //MOVE to CCR or NEG
389 break;
390 case 3:
391 //MOVE to SR or NOT
392 break;
393 case 4:
394 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA, MOVEM
395 break;
396 case 5:
397 //BGND, ILLEGAL, TAS, TST
398 optype = *istream & 0xFF;
399 if (optype == 0xFA) {
400 //BGND - CPU32 only
401 } else if (optype == 0xFC) {
402 decoded->op = M68K_ILLEGAL;
403 } else { 393 } else {
404 size = (*istream & 0xC0) >> 6; 394 decoded->src.addr_mode = MODE_REG;
395 decoded->src.params.u16 = immed;
396 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
397 }
398 } else {
399 optype = (*istream >> 9) & 0x7;
400 size = (*istream >> 6) & 0x3;
401 switch(optype)
402 {
403 case 0:
404 //Move from SR or NEGX
405 if (size == OPSIZE_INVALID) { 405 if (size == OPSIZE_INVALID) {
406 decoded->op = M68K_TAS; 406 decoded->op = M68K_MOVE_FROM_SR;
407 size = OPSIZE_WORD;
407 } else { 408 } else {
408 decoded->op = M68K_TST; 409 decoded->op = M68K_NEGX;
409 decoded->extra.size = size;
410 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
411 } 410 }
412 } 411 decoded->extra.size = size;
413 break; 412 istream= m68k_decode_op(istream, size, &(decoded->dst));
414 case 6: 413 break;
415 //MULU, MULS, DIVU, DIVUL, DIVS, DIVSL, MOVEM 414 case 1:
416 break; 415 //MOVE from CCR or CLR
417 case 7: 416 if (size == OPSIZE_INVALID) {
418 //TRAP, LINK.w, UNLNK, MOVE USP, RESET, NOP, STOP, RTE, RTD, RTS, TRAPV, RTR, MOVEC, JSR, JMP 417 #ifdef M68010
419 if (*istream & 0x80) { 418 decoded->op = M68K_MOVE_FROM_CCR;
420 //JSR, JMP 419 size = OPSIZE_WORD;
421 } else { 420 #else
422 //it would appear bit 6 needs to be set for it to be a valid instruction here 421 return istream+1;
423 switch((*istream >> 3) & 0x7) 422 #endif
423 } else {
424 decoded->op = M68K_CLR;
425 }
426 decoded->extra.size = size;
427 istream= m68k_decode_op(istream, size, &(decoded->dst));
428 break;
429 case 2:
430 //MOVE to CCR or NEG
431 if (size == OPSIZE_INVALID) {
432 decoded->op = M68K_MOVE_CCR;
433 size = OPSIZE_WORD;
434 istream= m68k_decode_op(istream, size, &(decoded->src));
435 } else {
436 decoded->op = M68K_NEG;
437 istream= m68k_decode_op(istream, size, &(decoded->dst));
438 }
439 decoded->extra.size = size;
440 break;
441 case 3:
442 //MOVE to SR or NOT
443 if (size == OPSIZE_INVALID) {
444 decoded->op = M68K_MOVE_SR;
445 size = OPSIZE_WORD;
446 istream= m68k_decode_op(istream, size, &(decoded->src));
447 } else {
448 decoded->op = M68K_NOT;
449 istream= m68k_decode_op(istream, size, &(decoded->dst));
450 }
451 decoded->extra.size = size;
452 break;
453 case 4:
454 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA
455 switch((*istream >> 3) & 0x3F)
424 { 456 {
425 case 0:
426 case 1: 457 case 1:
427 //TRAP 458 #ifdef M68020
459 decoded->op = M68K_LINK;
460 decoded->extra.size = OPSIZE_LONG;
461 reg = *istream & 0x7;
462 immed = *(++istream) << 16;
463 immed |= *(++istream);
464 #endif
428 break; 465 break;
429 case 2: 466 case 8:
430 //LINK.w 467 decoded->op = M68K_SWAP;
468 decoded->src.addr_mode = MODE_REG;
469 decoded->src.params.regs.pri = *istream & 0x7;
470 decoded->extra.size = OPSIZE_WORD;
431 break; 471 break;
432 case 3: 472 case 9:
433 //UNLNK 473 #ifdef M68010
474 decoded->op = M68K_BKPT;
475 decoded->src.addr_mode = MODE_IMMEDIATE;
476 decoded->extra.size = OPSIZE_BYTE;
477 decoded->src.params.u8 = *istream & 0x7;
478 #endif
434 break; 479 break;
435 case 4: 480 case 0x10:
436 case 5: 481 decoded->op = M68K_EXT;
437 //MOVE USP 482 decoded->src.addr_mode = MODE_REG;
483 decoded->src.params.regs.pri = *istream & 0x7;
484 decoded->extra.size = OPSIZE_WORD;
438 break; 485 break;
439 case 6: 486 case 0x18:
440 switch(*istream & 0x7) 487 decoded->op = M68K_EXT;
488 decoded->src.addr_mode = MODE_REG;
489 decoded->src.params.regs.pri = *istream & 0x7;
490 decoded->extra.size = OPSIZE_LONG;
491 break;
492 case 0x38:
493 #ifdef M68020
494 #endif
495 break;
496 default:
497 if (!(*istream & 0x1C0)) {
498 decoded->op = M68K_NBCD;
499 decoded->extra.size = OPSIZE_BYTE;
500 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst));
501 } else if(*istream & 0x1C0 == 0x40) {
502 decoded->op = M68K_PEA;
503 decoded->extra.size = OPSIZE_LONG;
504 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->dst));
505 }
506 }
507 break;
508 case 5:
509 //BGND, ILLEGAL, TAS, TST
510 optype = *istream & 0xFF;
511 if (optype == 0xFA) {
512 //BGND - CPU32 only
513 } else if (optype == 0xFC) {
514 decoded->op = M68K_ILLEGAL;
515 } else {
516 if (size == OPSIZE_INVALID) {
517 decoded->op = M68K_TAS;
518 } else {
519 decoded->op = M68K_TST;
520 decoded->extra.size = size;
521 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
522 }
523 }
524 break;
525 case 6:
526 //MULU, MULS, DIVU, DIVUL, DIVS, DIVSL
527 #ifdef M68020
528 //TODO: Implement these for 68020+ support
529 #endif
530 break;
531 case 7:
532 //TRAP, LINK.w, UNLNK, MOVE USP, RESET, NOP, STOP, RTE, RTD, RTS, TRAPV, RTR, MOVEC, JSR, JMP
533 if (*istream & 0x80) {
534 //JSR, JMP
535 if (*istream & 0x40) {
536 decoded->op = M68K_JMP;
537 } else {
538 decoded->op = M68K_JSR;
539 }
540 istream = m68k_decode_op(istream, OPSIZE_INVALID, &(decoded->src));
541 } else {
542 //it would appear bit 6 needs to be set for it to be a valid instruction here
543 switch((*istream >> 3) & 0x7)
441 { 544 {
442 case 0: 545 case 0:
443 decoded->op = M68K_RESET;
444 break;
445 case 1: 546 case 1:
446 decoded->op = M68K_NOP; 547 //TRAP
548 decoded->op = M68K_TRAP;
549 decoded->extra.size = OPSIZE_BYTE;
550 decoded->src.addr_mode = MODE_IMMEDIATE;
551 decoded->src.params.u8 = *istream & 0xF;
447 break; 552 break;
448 case 2: 553 case 2:
449 decoded->op = M68K_STOP; 554 //LINK.w
555 decoded->op = M68K_LINK;
450 decoded->extra.size = OPSIZE_WORD; 556 decoded->extra.size = OPSIZE_WORD;
451 decoded->src.addr_mode = MODE_IMMEDIATE; 557 decoded->src.addr_mode = MODE_AREG;
452 decoded->src.params.u16 =*(++istream); 558 decoded->src.params.regs.pri = *istream & 0x7;
559 decoded->dst.addr_mode = MODE_IMMEDIATE;
560 decoded->dst.params.u16 = immed;
453 break; 561 break;
454 case 3: 562 case 3:
455 decoded->op = M68K_RTE; 563 //UNLK
564 decoded->op = M68K_UNLK;
565 decoded->dst.addr_mode = MODE_AREG;
566 decoded->dst.params.regs.pri = *istream & 0x7;
456 break; 567 break;
457 case 4: 568 case 4:
569 case 5:
570 //MOVE USP
571 decoded->op = M68K_MOVE_USP;
572 if (*istream & 0x8) {
573 decoded->dst.addr_mode = MODE_AREG;
574 decoded->dst.params.regs.pri = *istream & 0x7;
575 } else {
576 decoded->src.addr_mode = MODE_AREG;
577 decoded->src.params.regs.pri = *istream & 0x7;
578 }
579 break;
580 case 6:
581 switch(*istream & 0x7)
582 {
583 case 0:
584 decoded->op = M68K_RESET;
585 break;
586 case 1:
587 decoded->op = M68K_NOP;
588 break;
589 case 2:
590 decoded->op = M68K_STOP;
591 decoded->extra.size = OPSIZE_WORD;
592 decoded->src.addr_mode = MODE_IMMEDIATE;
593 decoded->src.params.u16 =*(++istream);
594 break;
595 case 3:
596 decoded->op = M68K_RTE;
597 break;
598 case 4:
458 #ifdef M68010 599 #ifdef M68010
459 decoded->op = M68K_RTD; 600 decoded->op = M68K_RTD;
460 decoded->extra.size = OPSIZE_WORD; 601 decoded->extra.size = OPSIZE_WORD;
461 decoded->src.addr_mode = MODE_IMMEDIATE; 602 decoded->src.addr_mode = MODE_IMMEDIATE;
462 decoded->src.params.u16 =*(++istream); 603 decoded->src.params.u16 =*(++istream);
604 #endif
605 break;
606 case 5:
607 decoded->op = M68K_RTS;
608 break;
609 case 6:
610 decoded->op = M68K_TRAPV;
611 break;
612 case 7:
613 decoded->op = M68K_RTR;
614 break;
615 }
616 break;
617 case 7:
618 //MOVEC
619 #ifdef M68010
463 #endif 620 #endif
464 break; 621 break;
465 case 5:
466 decoded->op = M68K_RTS;
467 break;
468 case 6:
469 decoded->op = M68K_TRAPV;
470 break;
471 case 7:
472 decoded->op = M68K_RTR;
473 break;
474 } 622 }
475 break;
476 case 7:
477 //MOVEC
478 break;
479 } 623 }
624 break;
480 } 625 }
481 break;
482 } 626 }
483 } 627 }
484 } 628 }
485 break; 629 break;
486 case QUICK_ARITH_LOOP: 630 case QUICK_ARITH_LOOP:
605 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); 749 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream);
606 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 750 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
607 } 751 }
608 break; 752 break;
609 case RESERVED: 753 case RESERVED:
610 //TODO: implement me
611 break; 754 break;
612 case CMP_XOR: 755 case CMP_XOR:
613 size = *istream >> 6 & 0x3; 756 size = *istream >> 6 & 0x3;
614 decoded->op = M68K_CMP; 757 decoded->op = M68K_CMP;
615 if (*istream & 0x100) { 758 if (*istream & 0x100) {
733 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); 876 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream);
734 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 877 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
735 } 878 }
736 break; 879 break;
737 case SHIFT_ROTATE: 880 case SHIFT_ROTATE:
738 //TODO: Implement me 881 if ((*istream & 0x8C0) == 0xC0) {
882 switch((*istream >> 8) & 0x7)
883 {
884 case 0:
885 decoded->op = M68K_ASR;
886 break;
887 case 1:
888 decoded->op = M68K_ASL;
889 break;
890 case 2:
891 decoded->op = M68K_LSR;
892 break;
893 case 3:
894 decoded->op = M68K_LSL;
895 break;
896 case 4:
897 decoded->op = M68K_ROXR;
898 break;
899 case 5:
900 decoded->op = M68K_ROXL;
901 break;
902 case 6:
903 decoded->op = M68K_ROR;
904 break;
905 case 7:
906 decoded->op = M68K_ROL;
907 break;
908 }
909 decoded->extra.size = OPSIZE_WORD;
910 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst));
911 } else if((*istream & 0xC0) != 0xC0) {
912 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1))
913 {
914 case 0:
915 decoded->op = M68K_ASR;
916 break;
917 case 1:
918 decoded->op = M68K_ASL;
919 break;
920 case 2:
921 decoded->op = M68K_LSR;
922 break;
923 case 3:
924 decoded->op = M68K_LSL;
925 break;
926 case 4:
927 decoded->op = M68K_ROXR;
928 break;
929 case 5:
930 decoded->op = M68K_ROXL;
931 break;
932 case 6:
933 decoded->op = M68K_ROR;
934 break;
935 case 7:
936 decoded->op = M68K_ROL;
937 break;
938 }
939 decoded->extra.size = (*istream >> 6) & 0x3;
940 immed = (*istream >> 9) & 0x7;
941 if (*istream & 0x100) {
942 decoded->src.addr_mode = MODE_IMMEDIATE;
943 switch(decoded->extra.size)
944 {
945 case OPSIZE_BYTE:
946 decoded->src.params.u8 = immed;
947 break;
948 case OPSIZE_WORD:
949 decoded->src.params.u16 = immed;
950 break;
951 case OPSIZE_LONG:
952 decoded->src.params.u32 = immed;
953 break;
954 }
955 } else {
956 decoded->src.addr_mode = MODE_REG;
957 decoded->src.params.regs.pri = immed;
958 }
959 decoded->dst.addr_mode = MODE_REG;
960 decoded->dst.params.regs.pri = *istream & 0x7;
961
962 } else {
963 #ifdef M68020
964 //TODO: Implement bitfield instructions for M68020+ support
965 #endif
966 }
739 break; 967 break;
740 case COPROC: 968 case COPROC:
741 //TODO: Implement me 969 //TODO: Implement me
742 break; 970 break;
743 } 971 }