home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Emulatoren / UAE061.LZH / uae-0.6.1 / newcpu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  14.5 KB  |  666 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * MC68000 emulation
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "events.h"
  15. #include "gui.h"
  16. #include "memory.h"
  17. #include "custom.h"
  18. #include "newcpu.h"
  19. #include "ersatz.h"
  20. #include "readcpu.h"
  21. #include "blitter.h"
  22.  
  23. int areg_byteinc[] = { 1,1,1,1,1,1,1,2 };
  24. int imm8_table[] = { 8,1,2,3,4,5,6,7 };
  25.  
  26. cpuop_func *cpufunctbl[65536];
  27.  
  28. #ifdef COUNT_INSTRS
  29. static unsigned long int instrcount[65536];
  30. static UWORD opcodenums[65536];
  31.  
  32. int compfn(const void *el1, const void *el2)
  33. {
  34.     return instrcount[*(const UWORD *)el1] < instrcount[*(const UWORD *)el2];
  35. }
  36.  
  37. void dump_counts(void)
  38. {
  39.     FILE *f = fopen("insncount", "w");
  40.     unsigned long int total = 0;
  41.     int i;
  42.     
  43.     for(i=0; i < 65536; i++) {
  44.     opcodenums[i] = i;
  45.         total += instrcount[i];
  46.     }
  47.     qsort(opcodenums, 65536, sizeof(UWORD), compfn);
  48.     
  49.     fprintf(f, "Total: %ld\n", total);
  50.     for(i=0; i < 65536; i++) {
  51.     unsigned long int cnt = instrcount[opcodenums[i]];
  52.     if (!cnt)
  53.         break;
  54.     fprintf(f, "%04x: %ld\n", opcodenums[i], cnt);
  55.     }
  56.     fclose(f);
  57. }
  58. #endif
  59.  
  60. int broken_in;
  61.  
  62. #ifdef INTEL_FLAG_OPT
  63. union flagu intel_flag_lookup[256];
  64. #elif defined(M68K_FLAG_OPT)
  65. union flagu m68k_flag_lookup[16];
  66. #endif
  67.  
  68. void init_m68k (void)
  69. {
  70.     long int opcode;
  71.     int i;
  72.     
  73. #ifdef COUNT_INSTRS
  74.     memset(instrcount, 0, sizeof instrcount);
  75. #endif
  76. #ifdef INTEL_FLAG_OPT
  77.     for (i = 0; i < 256; i++) {
  78.     intel_flag_lookup[i].flags.c = !!(i & 1);
  79.     intel_flag_lookup[i].flags.z = !!(i & 64);
  80.     intel_flag_lookup[i].flags.n = !!(i & 128);
  81.     intel_flag_lookup[i].flags.v = 0;
  82.     }
  83. #elif defined(M68K_FLAG_OPT)
  84.     for (i = 0; i < 16; i++) {
  85.     m68k_flag_lookup[i].flags.c = !!(i & 1);
  86.     m68k_flag_lookup[i].flags.z = !!(i & 4);
  87.     m68k_flag_lookup[i].flags.n = !!(i & 8);
  88.     m68k_flag_lookup[i].flags.v = !!(i & 2);
  89.     }
  90. #endif
  91.     printf("Building CPU table...\n");
  92.     read_table68k ();
  93.     do_merges ();
  94.     for (opcode = 0; opcode < 65536; opcode++)
  95.     cpufunctbl[opcode] = op_illg;
  96.     for (i = 0; smallcputbl[i].handler != NULL; i++) {
  97.     if (!smallcputbl[i].specific)
  98.         cpufunctbl[smallcputbl[i].opcode] = smallcputbl[i].handler;
  99.     }
  100.     for (opcode = 0; opcode < 65536; opcode++) {
  101.     cpuop_func *f;
  102.     
  103.     if (table68k[opcode].mnemo == i_ILLG)
  104.         continue;
  105.     
  106.     if (table68k[opcode].handler != -1) {
  107.         f = cpufunctbl[table68k[opcode].handler];
  108.         if (f == op_illg)
  109.         abort();
  110.         cpufunctbl[opcode] = f;
  111.     }
  112.     }    
  113.     for (i = 0; smallcputbl[i].handler != NULL; i++) {
  114.     if (smallcputbl[i].specific)
  115.         cpufunctbl[smallcputbl[i].opcode] = smallcputbl[i].handler;
  116.     }
  117. }
  118.  
  119. struct regstruct regs;
  120. union flagu regflags;
  121. static void ShowEA(int reg, amodes mode, wordsizes size)
  122. {
  123.     UWORD dp;
  124.     BYTE disp8;
  125.     WORD disp16;
  126.     int r;
  127.     ULONG dispreg;
  128.     CPTR addr;
  129.     
  130.     switch(mode){
  131.      case Dreg:
  132.     printf("D%d", reg);
  133.     break;
  134.      case Areg:
  135.     printf("A%d", reg);
  136.     break;
  137.      case Aind:
  138.     printf("(A%d)", reg);
  139.     break;
  140.      case Aipi:
  141.     printf("(A%d)+", reg);
  142.     break;
  143.      case Apdi:
  144.     printf("-(A%d)", reg);
  145.     break;
  146.      case Ad16:
  147.     disp16 = nextiword();
  148.     addr = regs.a[reg] + (WORD)disp16;
  149.     printf("(A%d,$%04lx) == $%08lx", reg, disp16, (long unsigned int)addr);
  150.     break;
  151.      case Ad8r:
  152.     dp = nextiword();
  153.     disp8 = dp & 0xFF;
  154.     r = (dp & 0x7000) >> 12;
  155.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];    
  156.     if (!(dp & 0x800)) dispreg = (LONG)(WORD)(dispreg);
  157.     
  158.     addr = regs.a[reg] + disp8 + dispreg;
  159.     printf("(A%d, %c%d.%c, $%02x) == $%08lx", reg, 
  160.            dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', disp8,
  161.            (long unsigned int)addr);
  162.     break;
  163.      case PC16:
  164.     addr = m68k_getpc();
  165.     disp16 = nextiword();
  166.     addr += (WORD)disp16;
  167.     printf("(PC,$%08lx) == $%08lx", disp16, (long unsigned int)addr);
  168.     break;
  169.      case PC8r:
  170.     addr = m68k_getpc();
  171.     dp = nextiword();
  172.     disp8 = dp & 0xFF;
  173.     r = (dp & 0x7000) >> 12;
  174.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  175.     
  176.     if (!(dp & 0x800)) dispreg = (LONG)(WORD)(dispreg);
  177.     addr += disp8 + dispreg;
  178.     printf("(PC, %c%d.%c, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D', 
  179.            (int)r, dp & 0x800 ? 'L' : 'W', disp8, (long unsigned int)addr);
  180.     break;
  181.      case absw:
  182.     printf("$%08lx", (LONG)(WORD)nextiword());
  183.     break;
  184.      case absl:
  185.     printf("$%08lx", nextilong());
  186.     break;
  187.      case imm:
  188.     switch(size){
  189.      case sz_byte:
  190.         printf("#$%02x", nextiword() & 0xff); break;
  191.      case sz_word:
  192.         printf("#$%04x", nextiword()); break;
  193.      case sz_long:
  194.         printf("#$%08lx", nextilong()); break;
  195.      default:
  196.         abort();
  197.     }
  198.     break;
  199.      case imm0:
  200.     printf("#$%02lx", nextiword() & 0xff);
  201.     break;
  202.      case imm1:
  203.     printf("#$%04lx", nextiword());
  204.     break;
  205.      case imm2:
  206.     printf("#$%08lx", nextilong());
  207.     break;
  208.      case immi:
  209.     printf("#$%04lx", reg);
  210.     break;
  211.      default:
  212.     abort();
  213.     }
  214. }
  215.  
  216. #if CPU_LEVEL > 1
  217. ULONG get_disp_ea (ULONG base, UWORD dp)
  218. {
  219.     int reg = (dp >> 12) & 7;
  220.     LONG regd;
  221.     if (dp & 0x8000)
  222.     regd = regs.a[reg];
  223.     else
  224.     regd = regs.d[reg];
  225.     if (!(dp & 0x800))
  226.     regd = (LONG)(WORD)regd;
  227.     if (dp & 0x100) {
  228.     LONG extraind = 0;
  229.     printf("020\n");
  230.     regd <<= (dp >> 9) & 3;
  231.     if (dp & 0x80)
  232.         base = 0;
  233.     if (dp & 0x40)
  234.         regd = 0;
  235.     if ((dp & 0x30) == 0x20)
  236.         base += (LONG)(WORD)nextiword();
  237.     if ((dp & 0x30) == 0x30)
  238.         base += nextilong();
  239.     
  240.     if ((dp & 0x3) == 0x2)
  241.         extraind = (LONG)(WORD)nextiword();
  242.     if ((dp & 0x3) == 0x3)
  243.         extraind = nextilong();
  244.     
  245.     if (!(dp & 4))
  246.         base += regd;
  247.     if (dp & 3)
  248.         base = get_long (base);
  249.     if (dp & 4)
  250.         base += regd;
  251.     
  252.     return base + extraind;
  253.     /* Yikes, that's complicated */
  254.     } else {
  255.     return base + (BYTE)(dp) + regd;
  256.     }
  257. }
  258. #endif
  259.  
  260. void MakeSR(void)
  261. {
  262. #if 0
  263.     assert((NFLG & 1) == NFLG);
  264.     assert((regs.s & 1) == regs.s);
  265.     assert((regs.x & 1) == regs.x);
  266.     assert((CFLG & 1) == CFLG);
  267.     assert((VFLG & 1) == VFLG);
  268.     assert((ZFLG & 1) == ZFLG);
  269. #endif
  270.     regs.sr = ((regs.t << 15) | (regs.s << 13) | (regs.intmask << 8)
  271.            | (regs.x << 4) | (NFLG << 3) | (ZFLG << 2) | (VFLG << 1) 
  272.            |  CFLG);
  273. }
  274.  
  275. void MakeFromSR(void)
  276. {
  277.     int olds = regs.s;
  278.  
  279.     regs.t = (regs.sr >> 15) & 1;
  280.     regs.s = (regs.sr >> 13) & 1;
  281.     regs.intmask = (regs.sr >> 8) & 7;
  282.     regs.x = (regs.sr >> 4) & 1;
  283.     NFLG = (regs.sr >> 3) & 1;
  284.     ZFLG = (regs.sr >> 2) & 1;
  285.     VFLG = (regs.sr >> 1) & 1;
  286.     CFLG = regs.sr & 1;
  287.     if (olds != regs.s) {
  288.     CPTR temp = regs.usp;
  289.     regs.usp = regs.a[7];
  290.     regs.a[7] = temp;
  291.     }
  292.     specialflags |= SPCFLAG_INT;
  293.     if (regs.t)
  294.         specialflags |= SPCFLAG_TRACE;
  295.     else
  296.         specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
  297. }
  298.  
  299. void Exception(int nr)
  300. {
  301.     MakeSR();
  302.     if (!regs.s) {
  303.     CPTR temp = regs.usp;
  304.     regs.usp = regs.a[7];
  305.     regs.a[7] = temp;
  306.     regs.s = 1;
  307.     }
  308.     if (CPU_LEVEL > 0) {
  309.     regs.a[7] -= 2;
  310.     put_word (regs.a[7], nr * 4);
  311.     }
  312.     regs.a[7] -= 4;
  313.     put_long (regs.a[7], m68k_getpc ());
  314.     regs.a[7] -= 2;
  315.     put_word (regs.a[7], regs.sr);
  316.     m68k_setpc(get_long(regs.vbr + 4*nr));
  317.     regs.t = 0;
  318.     specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
  319. }
  320.  
  321. static void Interrupt(int nr)
  322. {
  323.     assert(nr < 8 && nr >= 0);
  324.     Exception(nr+24);
  325.     
  326.     regs.intmask = nr;
  327.     specialflags |= SPCFLAG_INT;
  328. }
  329.  
  330. static int caar, cacr;
  331.  
  332. void m68k_move2c (int regno, ULONG *regp)
  333. {
  334.     if (CPU_LEVEL == 1 && (regno & 0x7FF) > 1)
  335.     op_illg (0x4E7B);
  336.     else
  337.     switch (regno) {
  338.      case 0: regs.sfc = *regp; break;
  339.      case 1: regs.dfc = *regp; break;
  340.      case 2: cacr = *regp & 0xFF; break;
  341.      case 0x800: regs.usp = *regp; break;
  342.      case 0x801: regs.vbr = *regp; break;
  343.      case 0x802: caar = *regp & 0xFF; break;
  344.      default:
  345.         op_illg (0x4E7B);
  346.         break;
  347.     }
  348. }
  349.  
  350. void m68k_movec2 (int regno, ULONG *regp)
  351. {
  352.     if (CPU_LEVEL == 1 && (regno & 0x7FF) > 1)
  353.     op_illg (0x4E7A);
  354.     else
  355.     switch (regno) {
  356.      case 0: *regp = regs.sfc; break;
  357.      case 1: *regp = regs.dfc; break;
  358.      case 2: *regp = cacr; break;
  359.      case 0x800: *regp = regs.usp; break;
  360.      case 0x801: *regp = regs.vbr; break;
  361.      case 0x802: *regp = caar; break;
  362.      default:
  363.         op_illg (0x4E7A);
  364.         break;
  365.     }
  366. }
  367.  
  368. extern void m68k_divl (UWORD opcode, ULONG src, UWORD extra)
  369. {
  370.     if (src == 0)
  371.     return;
  372. #ifdef INT_64BIT
  373.     if (extra & 0x800) {
  374.     /* signed variant */
  375.     INT_64BIT a = regs.d[(extra >> 12) & 7];
  376.     INT_64BIT quot, rem;
  377.     
  378.     if (extra & 0x400)
  379.         a |= (INT_64BIT)regs.d[extra & 7] << 32;
  380.     rem = a % src;
  381.     quot = a / src;
  382.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  383.         regs.d[extra & 7] = rem;
  384.     regs.d[(extra >> 12) & 7] = quot;
  385.     } else {
  386.     /* unsigned */
  387.     unsigned INT_64BIT a = regs.d[(extra >> 12) & 7];
  388.     unsigned INT_64BIT quot, rem;
  389.     
  390.     if (extra & 0x400)
  391.         a |= (INT_64BIT)regs.d[extra & 7] << 32;
  392.     rem = a % src;
  393.     quot = a / src;
  394.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  395.         regs.d[extra & 7] = rem;
  396.     regs.d[(extra >> 12) & 7] = quot;
  397.     }
  398. #endif
  399. }
  400.  
  401. extern void m68k_mull (UWORD opcode, ULONG src, UWORD extra)
  402. {
  403. #ifdef INT_64BIT
  404.     if (extra & 0x800) {
  405.     /* signed variant */
  406.     INT_64BIT a = (LONG)regs.d[(extra >> 12) & 7];
  407.  
  408.     a *= (LONG)src;
  409.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  410.         regs.d[extra & 7] = a >> 32;
  411.     regs.d[(extra >> 12) & 7] = (ULONG)a;
  412.     } else {
  413.     /* unsigned */
  414.     unsigned INT_64BIT a = (ULONG)regs.d[(extra >> 12) & 7];
  415.     unsigned INT_64BIT quot, rem;
  416.     
  417.     a *= src;
  418.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  419.         regs.d[extra & 7] = a >> 32;
  420.     regs.d[(extra >> 12) & 7] = (ULONG)a;
  421.     }
  422. #endif
  423. }
  424.  
  425. static char* ccnames[] =
  426. { "T ","F ","HI","LS","CC","CS","NE","EQ",
  427.   "VC","VS","PL","MI","GE","LT","GT","LE" };
  428.  
  429. void MC68000_reset(void)
  430. {
  431.     regs.a[7] = get_long(0x00f80000);
  432.     m68k_setpc(get_long(0x00f80004));
  433.     regs.s = 1;
  434.     regs.stopped = 0;
  435.     regs.t = 0;
  436.     specialflags = 0;
  437.     regs.intmask = 7;
  438.     regs.vbr = regs.sfc = regs.dfc = 0;
  439.     customreset();
  440. }
  441.  
  442. void op_illg(ULONG opcode)
  443. {
  444.     if (opcode == 0x4E7B && get_long(0x10) == 0 
  445.     && (m68k_getpc() & 0xF80000) == 0xF80000) 
  446.     {
  447.     fprintf(stderr, "Your Kickstart requires a 68020 CPU. Giving up.\n");
  448.     broken_in = 1; 
  449.     specialflags |= SPCFLAG_BRK;
  450.     quit_program = 1;
  451.     }
  452.     if (opcode == 0xF00D && ((m68k_getpc() & 0xF80000) == 0xF80000)) {
  453.     /* This is from the dummy Kickstart replacement */
  454.     ersatz_perform (nextiword ());
  455.     return;
  456.     }
  457.     regs.pc_p--;
  458.     if ((opcode & 0xF000) == 0xF000) {
  459.     if ((opcode & 0xE00) == 0x200)
  460.         Exception(0xB);
  461.     else 
  462.         switch (opcode & 0x1FF) {
  463.          case 0x17:
  464.         regs.pc_p+=2;
  465.         break;
  466.          default:
  467.         regs.pc_p++;
  468.         }
  469.     return;
  470.     }
  471.     if ((opcode & 0xF000) == 0xA000) {
  472.         Exception(0xA);
  473.     return;
  474.     }
  475.     fprintf(stderr, "Illegal instruction: %04x\n", opcode);
  476.     Exception(4);
  477. }
  478.  
  479. static int n_insns=0, n_spcinsns=0;
  480.  
  481. static __inline__ void do_hardware(void)
  482. {
  483.     if (specialflags & SPCFLAG_BLIT) {
  484.     do_blitter();
  485. #ifdef NO_FAST_BLITTER
  486.     do_blitter();
  487.     do_blitter();
  488.     do_blitter();
  489. #endif
  490.     }
  491.     if (specialflags & SPCFLAG_DISK) {
  492.     do_disk(); /* This is not critical. Four calls make disk */
  493.     do_disk(); /* loading quite fast. */
  494.     do_disk();
  495.     do_disk();
  496.     }
  497. }
  498.  
  499. void MC68000_run(void)
  500. {
  501.     for(;;) {
  502.     UWORD opcode;
  503.     /* assert (!regs.stopped && !(specialflags & SPCFLAG_STOP)); */
  504.     opcode = nextiword();
  505. #ifdef COUNT_INSTRS
  506.     instrcount[opcode]++;
  507. #endif
  508.     (*cpufunctbl[opcode])(opcode);
  509. #ifndef NO_EXCEPTION_3
  510.     if (buserr) {
  511.         Exception(3);
  512.         buserr = 0;
  513.     }
  514. #endif
  515.     /*n_insns++;*/
  516.     do_cycles();    
  517.     if (specialflags) {
  518.         /*n_spcinsns++;*/
  519.         while (specialflags & SPCFLAG_BLTNASTY) {
  520.         do_cycles();
  521.         do_hardware();
  522.         }
  523.         if (specialflags & SPCFLAG_DOTRACE) {
  524.         Exception(9);
  525.         }
  526.         while (specialflags & SPCFLAG_STOP) {
  527.         do_cycles();
  528.         do_hardware();
  529.         if (specialflags & (SPCFLAG_INT | SPCFLAG_DOINT)){
  530.             int intr = intlev();
  531.             specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  532.             specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  533.             if (intr != -1 && intr > regs.intmask) {
  534.             Interrupt(intr);
  535.             regs.stopped = 0;
  536.             specialflags &= ~SPCFLAG_STOP;
  537.             }        
  538.         }        
  539.         }
  540.         if (specialflags & SPCFLAG_TRACE) {
  541.         specialflags &= ~SPCFLAG_TRACE;
  542.         specialflags |= SPCFLAG_DOTRACE;
  543.         }
  544. #ifdef WANT_SLOW_MULTIPLY
  545.         /* Kludge for Hardwired demo. The guys who wrote it should be
  546.          * mutilated. */
  547.         if (specialflags & SPCFLAG_EXTRA_CYCLES) {
  548.         do_cycles ();
  549.         do_cycles ();
  550.         do_cycles ();
  551.         do_cycles ();
  552.         specialflags &= ~SPCFLAG_EXTRA_CYCLES;
  553.         }
  554. #endif
  555.         do_hardware();
  556.         
  557.         if (specialflags & SPCFLAG_DOINT) {
  558.         int intr = intlev();
  559.         specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  560.         if (intr != -1 && intr > regs.intmask) {
  561.             Interrupt(intr);
  562.             regs.stopped = 0;
  563.         }        
  564.         }
  565.         if (specialflags & SPCFLAG_INT) {
  566.         specialflags &= ~SPCFLAG_INT;
  567.         specialflags |= SPCFLAG_DOINT;
  568.         }
  569.         if (specialflags & SPCFLAG_BRK) {        
  570.         specialflags &= ~SPCFLAG_BRK;
  571.         return;        
  572.         }
  573.     }
  574.     }
  575. }
  576.  
  577. void MC68000_step(void)
  578. {
  579.     specialflags |= SPCFLAG_BRK;
  580.     MC68000_run();
  581. }
  582.  
  583. void MC68000_skip(CPTR nextpc)
  584. {
  585.     broken_in = 0;
  586.     specialflags |= SPCFLAG_BRK;
  587.     do {
  588.     MC68000_step();
  589.     } while (nextpc != m68k_getpc() && !broken_in);
  590. }
  591.  
  592. void MC68000_disasm(CPTR addr, CPTR *nextpc, int cnt)
  593. {
  594.     CPTR pc = m68k_getpc();
  595.     m68k_setpc(addr);
  596.     for (;cnt--;){
  597.     char instrname[20],*ccpt;
  598.     int opwords;
  599.     UWORD opcode;
  600.     UWORD special = 0;
  601.     struct mnemolookup *lookup;
  602.     struct instr *dp;
  603.     printf("%08lx: ", m68k_getpc());
  604.     for(opwords = 0; opwords < 5; opwords++){
  605.         printf("%04x ", get_word(m68k_getpc() + opwords*2));
  606.     }
  607.     
  608.     opcode = nextiword();
  609.     if (cpufunctbl[opcode] == op_illg) {
  610.         opcode = 0x4AFC;
  611.     }
  612.     dp = table68k + opcode;
  613.     for (lookup = lookuptab;lookup->mnemo != dp->mnemo; lookup++)
  614.         ;
  615.     
  616.     strcpy(instrname,lookup->name);
  617.     ccpt = strstr(instrname,"cc");
  618.     if (ccpt != 0) {
  619.         strncpy(ccpt,ccnames[dp->cc],2);
  620.     }
  621.     printf("%s", instrname);
  622.     switch(dp->size){
  623.      case sz_byte: printf(".B "); break;
  624.      case sz_word: printf(".W "); break;
  625.      case sz_long: printf(".L "); break;
  626.      default: break;
  627.     }
  628.  
  629.     if (dp->suse) {
  630.         ShowEA(dp->sreg, dp->smode, dp->size);
  631.     }
  632.     if (dp->suse && dp->duse)
  633.         printf(",");
  634.     if (dp->duse) {
  635.         ShowEA(dp->dreg, dp->dmode, dp->size);
  636.     }
  637.     if (ccpt != 0) {
  638.         if (cctrue(dp->cc))
  639.         printf(" (TRUE)");
  640.         else 
  641.         printf(" (FALSE)");
  642.     }
  643.     printf("\n");
  644.     }
  645.     *nextpc = m68k_getpc();
  646.     m68k_setpc(pc);
  647. }
  648.  
  649. void MC68000_dumpstate(CPTR *nextpc)
  650. {
  651.     int i;
  652.     for(i = 0; i < 8; i++){
  653.     printf("D%d: %08lx ", i, regs.d[i]);
  654.     if ((i & 3) == 3) printf("\n");
  655.     }
  656.     for(i=0;i<8;i++){
  657.     printf("A%d: %08lx ", i, regs.a[i]);
  658.     if ((i & 3) == 3) printf("\n");
  659.     }
  660.     printf ("T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n", regs.t, regs.s, 
  661.         regs.x, NFLG, ZFLG, VFLG, CFLG, regs.intmask);
  662.     MC68000_disasm(m68k_getpc(), nextpc, 1);
  663.     printf("next PC: %08lx\n", *nextpc);
  664. }
  665.  
  666.