ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/newcpu.cpp
(Generate patch)

Comparing BasiliskII/src/uae_cpu/newcpu.cpp (file contents):
Revision 1.1.1.1 by cebix, 1999-10-03T14:16:26Z vs.
Revision 1.24 by asvitkine, 2012-03-30T01:25:46Z

# Line 1 | Line 1
1 < /*
2 <  * UAE - The Un*x Amiga Emulator
3 <  *
4 <  * MC68000 emulation
5 <  *
6 <  * (c) 1995 Bernd Schmidt
7 <  */
1 > /*
2 > * UAE - The Un*x Amiga Emulator
3 > *
4 > * MC68000 emulation
5 > *
6 > * (c) 1995 Bernd Schmidt
7 > *
8 > * This program is free software; you can redistribute it and/or modify
9 > * it under the terms of the GNU General Public License as published by
10 > * the Free Software Foundation; either version 2 of the License, or
11 > * (at your option) any later version.
12 > *
13 > * This program is distributed in the hope that it will be useful,
14 > * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 > * GNU General Public License for more details.
17 > *
18 > * You should have received a copy of the GNU General Public License
19 > * along with this program; if not, write to the Free Software
20 > * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 > */
22  
23   #include <stdio.h>
24   #include <stdlib.h>
# Line 22 | Line 36 | extern int intlev(void);       // From baisili
36   #include "memory.h"
37   #include "readcpu.h"
38   #include "newcpu.h"
39 < #include "compiler.h"
39 > #include "compiler/compemu.h"
40 > #include "fpu/fpu.h"
41 >
42 > #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS)
43 > B2_mutex *spcflags_lock = NULL;
44 > #endif
45 >
46 > #if ENABLE_MON
47 > #include "mon.h"
48 > #include "mon_disass.h"
49 > #endif
50  
51 < int quit_program = 0;
28 < int debugging = 0;
51 > bool quit_program = false;
52   struct flag_struct regflags;
53  
54   /* Opcode of faulting instruction */
# Line 42 | Line 65 | int movem_index1[256];
65   int movem_index2[256];
66   int movem_next[256];
67  
45 int fpp_movem_index1[256];
46 int fpp_movem_index2[256];
47 int fpp_movem_next[256];
48
68   cpuop_func *cpufunctbl[65536];
69  
70 + #if FLIGHT_RECORDER
71 + struct rec_step {
72 +        uae_u32 pc;
73 + #if FLIGHT_RECORDER >= 2
74 +        uae_u32 d[8];
75 +        uae_u32 a[8];
76 + #endif
77 + };
78 +
79 + const int LOG_SIZE = 32768;
80 + static rec_step log[LOG_SIZE];
81 + static int log_ptr = -1; // First time initialization
82 +
83 + static const char *log_filename(void)
84 + {
85 +        const char *name = getenv("M68K_LOG_FILE");
86 +        return name ? name : "log.68k";
87 + }
88 +
89 + void m68k_record_step(uaecptr pc)
90 + {
91 + #if FLIGHT_RECORDER >= 2
92 +        /* XXX: if LSB is set, we are recording from generated code and we
93 +           don't support registers recording yet.  */
94 +        if ((pc & 1) == 0) {
95 +                for (int i = 0; i < 8; i++) {
96 +                        log[log_ptr].d[i] = m68k_dreg(regs, i);
97 +                        log[log_ptr].a[i] = m68k_areg(regs, i);
98 +                }
99 +        }
100 + #endif
101 +        log[log_ptr].pc = pc;
102 +        log_ptr = (log_ptr + 1) % LOG_SIZE;
103 + }
104 +
105 + static void dump_log(void)
106 + {
107 +        FILE *f = fopen(log_filename(), "w");
108 +        if (f == NULL)
109 +                return;
110 +        for (int i = 0; i < LOG_SIZE; i++) {
111 +                int j = (i + log_ptr) % LOG_SIZE;
112 +                uae_u32 pc = log[j].pc & ~1;
113 +                fprintf(f, "pc %08x", pc);
114 + #if FLIGHT_RECORDER >= 2
115 +                fprintf(f, "\n");
116 +                if ((log[j].pc & 1) == 0) {
117 +                        fprintf(f, "d0 %08x d1 %08x d2 %08x d3 %08x\n", log[j].d[0], log[j].d[1], log[j].d[2], log[j].d[3]);
118 +                        fprintf(f, "d4 %08x d5 %08x d6 %08x d7 %08x\n", log[j].d[4], log[j].d[5], log[j].d[6], log[j].d[7]);
119 +                        fprintf(f, "a0 %08x a1 %08x a2 %08x a3 %08x\n", log[j].a[0], log[j].a[1], log[j].a[2], log[j].a[3]);
120 +                        fprintf(f, "a4 %08x a5 %08x a6 %08x a7 %08x\n", log[j].a[4], log[j].a[5], log[j].a[6], log[j].a[7]);
121 +                }
122 + #else
123 +                fprintf(f, " | ");
124 + #endif
125 + #if ENABLE_MON
126 +                disass_68k(f, pc);
127 + #endif
128 +        }
129 +        fclose(f);
130 + }
131 + #endif
132 +
133 + #if ENABLE_MON
134 + static void dump_regs(void)
135 + {
136 +        m68k_dumpstate(NULL);
137 + }
138 + #endif
139 +
140   #define COUNT_INSTRS 0
141  
142   #if COUNT_INSTRS
# Line 111 | Line 200 | static __inline__ unsigned int cft_map (
200   #endif
201   }
202  
203 < static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM;
203 > void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM;
204  
205 < static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode)
205 > void REGPARAM2 op_illg_1 (uae_u32 opcode)
206   {
207      op_illg (cft_map (opcode));
119    return 4;
208   }
209  
210   static void build_cpufunctbl (void)
211   {
212      int i;
213      unsigned long opcode;
214 <        int cpu_level = (FPUType ? 3 : CPUType >= 2 ? 2 : CPUType == 1 ? 1 : 0);
215 <    struct cputbl *tbl = (cpu_level == 3 ? op_smalltbl_0
216 <                          : cpu_level == 2 ? op_smalltbl_1
217 <                          : cpu_level == 1 ? op_smalltbl_2
218 <                          : op_smalltbl_3);
214 >        int cpu_level = 0;              // 68000 (default)
215 >        if (CPUType == 4)
216 >                cpu_level = 4;          // 68040 with FPU
217 >        else {
218 >                if (FPUType)
219 >                        cpu_level = 3;  // 68020 with FPU
220 >                else if (CPUType >= 2)
221 >                        cpu_level = 2;  // 68020
222 >                else if (CPUType == 1)
223 >                        cpu_level = 1;
224 >        }
225 >    struct cputbl *tbl = (
226 >                  cpu_level == 4 ? op_smalltbl_0_ff
227 >                : cpu_level == 3 ? op_smalltbl_1_ff
228 >                : cpu_level == 2 ? op_smalltbl_2_ff
229 >                : cpu_level == 1 ? op_smalltbl_3_ff
230 >                : op_smalltbl_4_ff);
231  
232      for (opcode = 0; opcode < 65536; opcode++)
233          cpufunctbl[cft_map (opcode)] = op_illg_1;
# Line 167 | Line 267 | void init_m68k (void)
267          movem_index2[i] = 7-j;
268          movem_next[i] = i & (~(1 << j));
269      }
170    for (i = 0 ; i < 256 ; i++) {
171        int j;
172        for (j = 7 ; j >= 0 ; j--) {
173                if (i & (1 << j)) break;
174        }
175        fpp_movem_index1[i] = j;
176        fpp_movem_index2[i] = 7-j;
177        fpp_movem_next[i] = i & (~(1 << j));
178    }
270   #if COUNT_INSTRS
271      {
272          FILE *f = fopen (icountfilename (), "r");
# Line 196 | Line 287 | void init_m68k (void)
287      do_merges ();
288  
289      build_cpufunctbl ();
290 +        
291 + #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS)
292 +        spcflags_lock = B2_create_mutex();
293 + #endif
294 +    fpu_init(CPUType == 4);
295 + }
296 +
297 + void exit_m68k (void)
298 + {
299 +        fpu_exit ();
300 + #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS)
301 +        B2_delete_mutex(spcflags_lock);
302 + #endif
303   }
304  
305   struct regstruct regs, lastint_regs;
# Line 204 | Line 308 | static int backup_pointer = 0;
308   static long int m68kpc_offset;
309   int lastint_no;
310  
311 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
312 + #define get_ibyte_1(o) get_byte(get_virtual_address(regs.pc_p) + (o) + 1)
313 + #define get_iword_1(o) get_word(get_virtual_address(regs.pc_p) + (o))
314 + #define get_ilong_1(o) get_long(get_virtual_address(regs.pc_p) + (o))
315 + #else
316   #define get_ibyte_1(o) get_byte(regs.pc + (regs.pc_p - regs.pc_oldp) + (o) + 1)
317   #define get_iword_1(o) get_word(regs.pc + (regs.pc_p - regs.pc_oldp) + (o))
318   #define get_ilong_1(o) get_long(regs.pc + (regs.pc_p - regs.pc_oldp) + (o))
319 + #endif
320  
321   uae_s32 ShowEA (int reg, amodes mode, wordsizes size, char *buf)
322   {
# Line 239 | Line 349 | uae_s32 ShowEA (int reg, amodes mode, wo
349          disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2;
350          addr = m68k_areg(regs,reg) + (uae_s16)disp16;
351          sprintf (buffer,"(A%d,$%04x) == $%08lx", reg, disp16 & 0xffff,
352 <                                        (long unsigned int)addr);
352 >                                        (unsigned long)addr);
353          break;
354       case Ad8r:
355          dp = get_iword_1 (m68kpc_offset); m68kpc_offset += 2;
# Line 272 | Line 382 | uae_s32 ShowEA (int reg, amodes mode, wo
382                      dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
383                      1 << ((dp >> 9) & 3),
384                      disp,outer,
385 <                    (long unsigned int)addr);
385 >                    (unsigned long)addr);
386          } else {
387            addr = m68k_areg(regs,reg) + (uae_s32)((uae_s8)disp8) + dispreg;
388            sprintf (buffer,"(A%d, %c%d.%c*%d, $%02x) == $%08lx", reg,
389                 dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
390                 1 << ((dp >> 9) & 3), disp8,
391 <               (long unsigned int)addr);
391 >               (unsigned long)addr);
392          }
393          break;
394       case PC16:
395          addr = m68k_getpc () + m68kpc_offset;
396          disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2;
397          addr += (uae_s16)disp16;
398 <        sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(long unsigned int)addr);
398 >        sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(unsigned long)addr);
399          break;
400       case PC8r:
401          addr = m68k_getpc () + m68kpc_offset;
# Line 319 | Line 429 | uae_s32 ShowEA (int reg, amodes mode, wo
429                      dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
430                      1 << ((dp >> 9) & 3),
431                      disp,outer,
432 <                    (long unsigned int)addr);
432 >                    (unsigned long)addr);
433          } else {
434            addr += (uae_s32)((uae_s8)disp8) + dispreg;
435            sprintf (buffer,"(PC, %c%d.%c*%d, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D',
436                  (int)r, dp & 0x800 ? 'L' : 'W',  1 << ((dp >> 9) & 3),
437 <                disp8, (long unsigned int)addr);
437 >                disp8, (unsigned long)addr);
438          }
439          break;
440       case absw:
441 <        sprintf (buffer,"$%08lx", (long unsigned int)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset));
441 >        sprintf (buffer,"$%08lx", (unsigned long)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset));
442          m68kpc_offset += 2;
443          break;
444       case absl:
445 <        sprintf (buffer,"$%08lx", (long unsigned int)get_ilong_1 (m68kpc_offset));
445 >        sprintf (buffer,"$%08lx", (unsigned long)get_ilong_1 (m68kpc_offset));
446          m68kpc_offset += 4;
447          break;
448       case imm:
# Line 346 | Line 456 | uae_s32 ShowEA (int reg, amodes mode, wo
456              m68kpc_offset += 2;
457              break;
458           case sz_long:
459 <            sprintf (buffer,"#$%08lx", (long unsigned int)(get_ilong_1 (m68kpc_offset)));
459 >            sprintf (buffer,"#$%08lx", (unsigned long)(get_ilong_1 (m68kpc_offset)));
460              m68kpc_offset += 4;
461              break;
462           default:
# Line 366 | Line 476 | uae_s32 ShowEA (int reg, amodes mode, wo
476       case imm2:
477          offset = (uae_s32)get_ilong_1 (m68kpc_offset);
478          m68kpc_offset += 4;
479 <        sprintf (buffer,"#$%08lx", (long unsigned int)offset);
479 >        sprintf (buffer,"#$%08lx", (unsigned long)offset);
480          break;
481       case immi:
482          offset = (uae_s32)(uae_s8)(reg & 0xff);
483 <        sprintf (buffer,"#$%08lx", (long unsigned int)offset);
483 >        sprintf (buffer,"#$%08lx", (unsigned long)offset);
484          break;
485       default:
486          break;
# Line 625 | Line 735 | void MakeFromSR (void)
735          }
736      }
737  
738 <    regs.spcflags |= SPCFLAG_INT;
738 >    SPCFLAGS_SET( SPCFLAG_INT );
739      if (regs.t1 || regs.t0)
740 <        regs.spcflags |= SPCFLAG_TRACE;
740 >                SPCFLAGS_SET( SPCFLAG_TRACE );
741      else
742 <        regs.spcflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
742 >        /* Keep SPCFLAG_DOTRACE, we still want a trace exception for
743 >           SR-modifying instructions (including STOP).  */
744 >                SPCFLAGS_CLEAR( SPCFLAG_TRACE );
745   }
746  
747   void Exception(int nr, uaecptr oldpc)
748   {
749 <    compiler_flush_jsr_stack();
749 >    uae_u32 currpc = m68k_getpc ();
750      MakeSR();
751      if (!regs.s) {
752          regs.usp = m68k_areg(regs, 7);
# Line 663 | Line 775 | void Exception(int nr, uaecptr oldpc)
775              m68k_areg(regs, 7) -= 2;
776              put_word (m68k_areg(regs, 7), nr * 4);
777              m68k_areg(regs, 7) -= 4;
778 <            put_long (m68k_areg(regs, 7), m68k_getpc ());
778 >            put_long (m68k_areg(regs, 7), currpc);
779              m68k_areg(regs, 7) -= 2;
780              put_word (m68k_areg(regs, 7), regs.sr);
781              regs.sr |= (1 << 13);
# Line 689 | Line 801 | void Exception(int nr, uaecptr oldpc)
801          }
802      }
803      m68k_areg(regs, 7) -= 4;
804 <    put_long (m68k_areg(regs, 7), m68k_getpc ());
804 >    put_long (m68k_areg(regs, 7), currpc);
805   kludge_me_do:
806      m68k_areg(regs, 7) -= 2;
807      put_word (m68k_areg(regs, 7), regs.sr);
808      m68k_setpc (get_long (regs.vbr + 4*nr));
809 +        SPCFLAGS_SET( SPCFLAG_JIT_END_COMPILE );
810      fill_prefetch_0 ();
811      regs.t1 = regs.t0 = regs.m = 0;
812 <    regs.spcflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
812 >        SPCFLAGS_CLEAR( SPCFLAG_TRACE | SPCFLAG_DOTRACE );
813   }
814  
815   static void Interrupt(int nr)
# Line 707 | Line 820 | static void Interrupt(int nr)
820      Exception(nr+24, 0);
821  
822      regs.intmask = nr;
823 <    regs.spcflags |= SPCFLAG_INT;
823 >        SPCFLAGS_SET( SPCFLAG_INT );
824   }
825  
826 < static int caar, cacr;
826 > static int caar, cacr, tc, itt0, itt1, dtt0, dtt1, mmusr, urp, srp;
827 >
828 > static int movec_illg (int regno)
829 > {
830 >        switch (CPUType) {
831 >        case 1:
832 >                if ((regno & 0x7ff) <= 1)
833 >                        return 0;
834 >                break;
835 >        case 2:
836 >        case 3:
837 >                if ((regno & 0x7ff) <= 2)
838 >                        return 0;
839 >                if (regno == 3 || regno == 4)
840 >                        return 0;
841 >                break;
842 >        case 4:
843 >                if ((regno & 0x7ff) <= 7) {
844 >                        if (regno != 0x802)
845 >                                return 0;
846 >                }
847 >                break;
848 >        }
849 >        return 1;
850 > }
851  
852 < void m68k_move2c (int regno, uae_u32 *regp)
852 > int m68k_move2c (int regno, uae_u32 *regp)
853   {
854 <    if (CPUType == 1 && (regno & 0x7FF) > 1)
854 >  if (movec_illg (regno)) {
855          op_illg (0x4E7B);
856 <    else
856 >        return 0;
857 >  } else {
858          switch (regno) {
859           case 0: regs.sfc = *regp & 7; break;
860           case 1: regs.dfc = *regp & 7; break;
861 <         case 2: cacr = *regp & 0x3; break;     /* ignore C and CE */
861 >         case 2:
862 >                cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000);
863 > #if USE_JIT
864 >                if (CPUType < 4) {
865 >                        set_cache_state(cacr&1);
866 >                        if (*regp & 0x08)
867 >                                flush_icache(1);
868 >                }
869 >                else {
870 >                        set_cache_state(cacr&0x8000);
871 >                }
872 > #endif
873 >         break;
874 >         case 3: tc = *regp & 0xc000; break;
875 >         case 4: itt0 = *regp & 0xffffe364; break;
876 >         case 5: itt1 = *regp & 0xffffe364; break;
877 >         case 6: dtt0 = *regp & 0xffffe364; break;
878 >         case 7: dtt1 = *regp & 0xffffe364; break;
879           case 0x800: regs.usp = *regp; break;
880           case 0x801: regs.vbr = *regp; break;
881           case 0x802: caar = *regp &0xfc; break;
882           case 0x803: regs.msp = *regp; if (regs.m == 1) m68k_areg(regs, 7) = regs.msp; break;
883           case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break;
884 +        case 0x805: mmusr = *regp; break;
885 +        case 0x806: urp = *regp; break;
886 +        case 0x807: srp = *regp; break;
887           default:
888              op_illg (0x4E7B);
889 <            break;
889 >            return 0;
890          }
891 +  }
892 +  return 1;
893   }
894  
895 < void m68k_movec2 (int regno, uae_u32 *regp)
895 > int m68k_movec2 (int regno, uae_u32 *regp)
896   {
897 <    if (CPUType == 1 && (regno & 0x7FF) > 1)
897 >    if (movec_illg (regno))
898 >    {
899          op_illg (0x4E7A);
900 <    else
900 >        return 0;
901 >    } else {
902          switch (regno) {
903           case 0: *regp = regs.sfc; break;
904           case 1: *regp = regs.dfc; break;
905           case 2: *regp = cacr; break;
906 +         case 3: *regp = tc; break;
907 +         case 4: *regp = itt0; break;
908 +         case 5: *regp = itt1; break;
909 +         case 6: *regp = dtt0; break;
910 +         case 7: *regp = dtt1; break;
911           case 0x800: *regp = regs.usp; break;
912           case 0x801: *regp = regs.vbr; break;
913           case 0x802: *regp = caar; break;
914           case 0x803: *regp = regs.m == 1 ? m68k_areg(regs, 7) : regs.msp; break;
915           case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break;
916 +        case 0x805: *regp = mmusr; break;
917 +        case 0x806: *regp = urp; break;
918 +        case 0x807: *regp = srp; break;
919           default:
920              op_illg (0x4E7A);
921 <            break;
921 >            return 0;
922          }
923 +        }
924 +        return 1;
925   }
926  
927   static __inline__ int
# Line 1007 | Line 1179 | static char* ccnames[] =
1179   { "T ","F ","HI","LS","CC","CS","NE","EQ",
1180    "VC","VS","PL","MI","GE","LT","GT","LE" };
1181  
1182 + // If value is greater than zero, this means we are still processing an EmulOp
1183 + // because the counter is incremented only in m68k_execute(), i.e. interpretive
1184 + // execution only
1185 + static int m68k_execute_depth = 0;
1186 +
1187   void m68k_reset (void)
1188   {
1189      m68k_areg (regs, 7) = 0x2000;
1190      m68k_setpc (ROMBaseMac + 0x2a);
1191      fill_prefetch_0 ();
1015    regs.kick_mask = 0xF80000;
1192      regs.s = 1;
1193      regs.m = 0;
1194      regs.stopped = 0;
# Line 1023 | Line 1199 | void m68k_reset (void)
1199      SET_CFLG (0);
1200      SET_VFLG (0);
1201      SET_NFLG (0);
1202 <    regs.spcflags = 0;
1202 >        SPCFLAGS_INIT( 0 );
1203      regs.intmask = 7;
1204      regs.vbr = regs.sfc = regs.dfc = 0;
1205 <    regs.fpcr = regs.fpsr = regs.fpiar = 0;
1205 >    fpu_reset();
1206 >        
1207 > #if FLIGHT_RECORDER
1208 >        log_ptr = 0;
1209 >        memset(log, 0, sizeof(log));
1210 > #endif
1211 >
1212 > #if ENABLE_MON
1213 >        static bool first_time = true;
1214 >        if (first_time) {
1215 >                first_time = false;
1216 >                mon_add_command("regs", dump_regs, "regs                    Dump m68k emulator registers\n");
1217 > #if FLIGHT_RECORDER
1218 >                // Install "log" command in mon
1219 >                mon_add_command("log", dump_log, "log                      Dump m68k emulation log\n");
1220 > #endif
1221 >        }
1222 > #endif
1223   }
1224  
1225 < unsigned long REGPARAM2 op_illg (uae_u32 opcode)
1225 > void m68k_emulop_return(void)
1226   {
1227 <    uaecptr pc = m68k_getpc ();
1228 <
1229 <    compiler_flush_jsr_stack ();
1227 >        SPCFLAGS_SET( SPCFLAG_BRK );
1228 >        quit_program = true;
1229 > }
1230  
1231 <        if ((opcode & 0xFF00) == 0x7100) {
1231 > void m68k_emulop(uae_u32 opcode)
1232 > {
1233                  struct M68kRegisters r;
1234                  int i;
1235  
1042                // Return from Execute68k()?
1043                if (opcode == M68K_EXEC_RETURN) {
1044                        regs.spcflags |= SPCFLAG_BRK;
1045                        quit_program = 1;
1046                        return 4;
1047                }
1048
1049                // Call EMUL_OP opcode
1236                  for (i=0; i<8; i++) {
1237                          r.d[i] = m68k_dreg(regs, i);
1238                          r.a[i] = m68k_areg(regs, i);
# Line 1060 | Line 1246 | unsigned long REGPARAM2 op_illg (uae_u32
1246                  }
1247                  regs.sr = r.sr;
1248                  MakeFromSR();
1249 <                m68k_incpc(2);
1250 <                fill_prefetch_0 ();
1251 <                return 4;
1252 <        }
1249 > }
1250 >
1251 > void REGPARAM2 op_illg (uae_u32 opcode)
1252 > {
1253 >        uaecptr pc = m68k_getpc ();
1254  
1255      if ((opcode & 0xF000) == 0xA000) {
1256          Exception(0xA,0);
1257 <        return 4;
1257 >        return;
1258      }
1259  
1260      if ((opcode & 0xF000) == 0xF000) {
1261          Exception(0xB,0);
1262 <        return 4;
1262 >        return;
1263      }
1264  
1265      write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc);
1266 + #if USE_JIT && JIT_DEBUG
1267 +    compiler_dumpstate();
1268 + #endif
1269 +
1270      Exception (4,0);
1271 <    return 4;
1271 >        return;
1272   }
1273  
1274   void mmu_op(uae_u32 opcode, uae_u16 extra)
1275   {
1276 <    if ((extra & 0xB000) == 0) { /* PMOVE instruction */
1277 <
1278 <    } else if ((extra & 0xF000) == 0x2000) { /* PLOAD instruction */
1279 <    } else if ((extra & 0xF000) == 0x8000) { /* PTEST instruction */
1276 >    if ((opcode & 0xFE0) == 0x0500) {
1277 >                /* PFLUSH */
1278 >                mmusr = 0;
1279 >        } else if ((opcode & 0x0FD8) == 0x548) {
1280 >                /* PTEST */
1281      } else
1282 <        op_illg (opcode);
1282 >                op_illg (opcode);
1283   }
1284  
1285   static int n_insns = 0, n_spcinsns = 0;
# Line 1096 | Line 1288 | static uaecptr last_trace_ad = 0;
1288  
1289   static void do_trace (void)
1290   {
1291 <    if (regs.t0) {
1291 >    if (regs.t0 && CPUType >= 2) {
1292         uae_u16 opcode;
1293         /* should also include TRAP, CHK, SR modification FPcc */
1294         /* probably never used so why bother */
1295         /* We can afford this to be inefficient... */
1296         m68k_setpc (m68k_getpc ());
1297         fill_prefetch_0 ();
1298 <       opcode = get_word (regs.pc);
1298 >       opcode = get_word(m68k_getpc());
1299         if (opcode == 0x4e72            /* RTE */
1300             || opcode == 0x4e74                 /* RTD */
1301             || opcode == 0x4e75                 /* RTS */
# Line 1119 | Line 1311 | static void do_trace (void)
1311                 && (uae_s16)m68k_dreg(regs, opcode & 7) != 0))
1312        {
1313              last_trace_ad = m68k_getpc ();
1314 <            regs.spcflags &= ~SPCFLAG_TRACE;
1315 <            regs.spcflags |= SPCFLAG_DOTRACE;
1314 >                SPCFLAGS_CLEAR( SPCFLAG_TRACE );
1315 >                SPCFLAGS_SET( SPCFLAG_DOTRACE );
1316          }
1317      } else if (regs.t1) {
1318         last_trace_ad = m68k_getpc ();
1319 <       regs.spcflags &= ~SPCFLAG_TRACE;
1320 <       regs.spcflags |= SPCFLAG_DOTRACE;
1319 >       SPCFLAGS_CLEAR( SPCFLAG_TRACE );
1320 >       SPCFLAGS_SET( SPCFLAG_DOTRACE );
1321      }
1322   }
1323  
1324 <
1133 < static int do_specialties (void)
1324 > int m68k_do_specialties (void)
1325   {
1326 <    /*n_spcinsns++;*/
1327 <    run_compiled_code();
1328 <    if (regs.spcflags & SPCFLAG_DOTRACE) {
1326 > #if USE_JIT
1327 >    // Block was compiled
1328 >    SPCFLAGS_CLEAR( SPCFLAG_JIT_END_COMPILE );
1329 >
1330 >    // Retain the request to get out of compiled code until
1331 >    // we reached the toplevel execution, i.e. the one that
1332 >    // can compile then run compiled code. This also means
1333 >    // we processed all (nested) EmulOps
1334 >    if ((m68k_execute_depth == 0) && SPCFLAGS_TEST( SPCFLAG_JIT_EXEC_RETURN ))
1335 >        SPCFLAGS_CLEAR( SPCFLAG_JIT_EXEC_RETURN );
1336 > #endif
1337 >        
1338 >    if (SPCFLAGS_TEST( SPCFLAG_DOTRACE )) {
1339          Exception (9,last_trace_ad);
1340      }
1341 <    while (regs.spcflags & SPCFLAG_STOP) {
1342 <        if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)){
1341 >    while (SPCFLAGS_TEST( SPCFLAG_STOP )) {
1342 >        if (SPCFLAGS_TEST( SPCFLAG_INT | SPCFLAG_DOINT )){
1343 >                SPCFLAGS_CLEAR( SPCFLAG_INT | SPCFLAG_DOINT );
1344              int intr = intlev ();
1143            regs.spcflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
1345              if (intr != -1 && intr > regs.intmask) {
1346                  Interrupt (intr);
1347                  regs.stopped = 0;
1348 <                regs.spcflags &= ~SPCFLAG_STOP;
1348 >                SPCFLAGS_CLEAR( SPCFLAG_STOP );
1349              }
1350          }
1351      }
1352 <    if (regs.spcflags & SPCFLAG_TRACE)
1352 >    if (SPCFLAGS_TEST( SPCFLAG_TRACE ))
1353         do_trace ();
1354  
1355 <    if (regs.spcflags & SPCFLAG_DOINT) {
1355 >    if (SPCFLAGS_TEST( SPCFLAG_DOINT )) {
1356 >        SPCFLAGS_CLEAR( SPCFLAG_DOINT );
1357          int intr = intlev ();
1156        regs.spcflags &= ~SPCFLAG_DOINT;
1358          if (intr != -1 && intr > regs.intmask) {
1359              Interrupt (intr);
1360              regs.stopped = 0;
1361          }
1362      }
1363 <    if (regs.spcflags & SPCFLAG_INT) {
1364 <        regs.spcflags &= ~SPCFLAG_INT;
1365 <        regs.spcflags |= SPCFLAG_DOINT;
1363 >    if (SPCFLAGS_TEST( SPCFLAG_INT )) {
1364 >        SPCFLAGS_CLEAR( SPCFLAG_INT );
1365 >        SPCFLAGS_SET( SPCFLAG_DOINT );
1366      }
1367 <    if (regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)) {
1368 <        regs.spcflags &= ~(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
1367 >    if (SPCFLAGS_TEST( SPCFLAG_BRK )) {
1368 >        SPCFLAGS_CLEAR( SPCFLAG_BRK );
1369          return 1;
1370      }
1371      return 0;
1372   }
1373  
1374 < static void m68k_run_1 (void)
1374 > void m68k_do_execute (void)
1375   {
1376 <    for (;;) {
1377 <        int cycles;
1378 <        uae_u32 opcode = GET_OPCODE;
1379 < #if 0
1179 <        if (get_ilong (0) != do_get_mem_long (&regs.prefetch)) {
1180 <            debugging = 1;
1181 <            return;
1182 <        }
1183 < #endif
1184 <        /* assert (!regs.stopped && !(regs.spcflags & SPCFLAG_STOP)); */
1185 < /*      regs_backup[backup_pointer = (backup_pointer + 1) % 16] = regs;*/
1186 < #if COUNT_INSTRS == 2
1187 <        if (table68k[cft_map (opcode)].handler != -1)
1188 <            instrcount[table68k[cft_map (opcode)].handler]++;
1189 < #elif COUNT_INSTRS == 1
1190 <        instrcount[opcode]++;
1191 < #endif
1192 < #if defined(X86_ASSEMBLYxxx)
1193 <        __asm__ __volatile__("\tcall *%%ebx"
1194 <                             : "=&a" (cycles) : "b" (cpufunctbl[opcode]), "0" (opcode)
1195 <                             : "%edx", "%ecx",
1196 <                             "%esi", "%edi", "%ebp", "memory", "cc");
1197 < #else
1198 <        cycles = (*cpufunctbl[opcode])(opcode);
1376 >        for (;;) {
1377 >                uae_u32 opcode = GET_OPCODE;
1378 > #if FLIGHT_RECORDER
1379 >                m68k_record_step(m68k_getpc());
1380   #endif
1381 <        /*n_insns++;*/
1382 <        if (regs.spcflags) {
1383 <            if (do_specialties ())
1384 <                return;
1381 >                (*cpufunctbl[opcode])(opcode);
1382 >                cpu_check_ticks();
1383 >                if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) {
1384 >                        if (m68k_do_specialties())
1385 >                                return;
1386 >                }
1387          }
1205    }
1388   }
1389  
1390 < #ifdef X86_ASSEMBLYxxx
1209 < static __inline__ void m68k_run1 (void)
1390 > void m68k_execute (void)
1391   {
1392 <    /* Work around compiler bug: GCC doesn't push %ebp in m68k_run_1. */
1393 <    __asm__ __volatile__ ("pushl %%ebp\n\tcall *%0\n\tpopl %%ebp" : : "r" (m68k_run_1) : "%eax", "%edx", "%ecx", "memory", "cc");
1213 < }
1214 < #else
1215 < #define m68k_run1 m68k_run_1
1392 > #if USE_JIT
1393 >    ++m68k_execute_depth;
1394   #endif
1217
1218 int in_m68k_go = 0;
1219
1220 void m68k_go (int may_quit)
1221 {
1222 // m68k_go() must be reentrant for Execute68k() and Execute68kTrap() to work
1223 /*
1224    if (in_m68k_go || !may_quit) {
1225        write_log("Bug! m68k_go is not reentrant.\n");
1226        abort();
1227    }
1228 */
1229    in_m68k_go++;
1395      for (;;) {
1396 <        if (quit_program > 0) {
1232 <            if (quit_program == 1)
1396 >          if (quit_program)
1397                  break;
1398 <            quit_program = 0;
1235 <            m68k_reset ();
1236 <        }
1237 <        m68k_run1();
1398 >          m68k_do_execute();
1399      }
1400 <        if (debugging) {
1401 <                uaecptr nextpc;
1402 <                m68k_dumpstate(&nextpc);
1242 <                exit(1);
1243 <        }
1244 <    in_m68k_go--;
1400 > #if USE_JIT
1401 >    --m68k_execute_depth;
1402 > #endif
1403   }
1404  
1405   static void m68k_verify (uaecptr addr, uaecptr *nextpc)
# Line 1350 | Line 1508 | void m68k_dumpstate (uaecptr *nextpc)
1508      printf ("T=%d%d S=%d M=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n",
1509              regs.t1, regs.t0, regs.s, regs.m,
1510              GET_XFLG, GET_NFLG, GET_ZFLG, GET_VFLG, GET_CFLG, regs.intmask);
1511 <    for (i = 0; i < 8; i++){
1512 <        printf ("FP%d: %g ", i, regs.fp[i]);
1513 <        if ((i & 3) == 3) printf ("\n");
1514 <    }
1357 <    printf ("N=%d Z=%d I=%d NAN=%d\n",
1358 <                (regs.fpsr & 0x8000000) != 0,
1359 <                (regs.fpsr & 0x4000000) != 0,
1360 <                (regs.fpsr & 0x2000000) != 0,
1361 <                (regs.fpsr & 0x1000000) != 0);
1362 <
1511 >        
1512 >        fpu_dump_registers();
1513 >        fpu_dump_flags();
1514 >        
1515      m68k_disasm(m68k_getpc (), nextpc, 1);
1516      if (nextpc)
1517          printf ("next PC: %08lx\n", *nextpc);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines