22 |
|
#include "memory.h" |
23 |
|
#include "readcpu.h" |
24 |
|
#include "newcpu.h" |
25 |
< |
#include "compiler.h" |
25 |
> |
#include "fpu/fpu.h" |
26 |
> |
|
27 |
> |
#if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) |
28 |
> |
B2_mutex *spcflags_lock = NULL; |
29 |
> |
#endif |
30 |
> |
|
31 |
> |
#if ENABLE_MON |
32 |
> |
#include "mon.h" |
33 |
> |
#include "mon_disass.h" |
34 |
> |
#endif |
35 |
|
|
36 |
|
int quit_program = 0; |
37 |
< |
int debugging = 0; |
37 |
> |
const int debugging = 0; |
38 |
|
struct flag_struct regflags; |
39 |
|
|
40 |
|
/* Opcode of faulting instruction */ |
51 |
|
int movem_index2[256]; |
52 |
|
int movem_next[256]; |
53 |
|
|
45 |
– |
int fpp_movem_index1[256]; |
46 |
– |
int fpp_movem_index2[256]; |
47 |
– |
int fpp_movem_next[256]; |
48 |
– |
|
54 |
|
cpuop_func *cpufunctbl[65536]; |
55 |
|
|
56 |
+ |
#define FLIGHT_RECORDER 0 |
57 |
+ |
|
58 |
+ |
#if FLIGHT_RECORDER |
59 |
+ |
struct rec_step { |
60 |
+ |
uae_u32 d[8]; |
61 |
+ |
uae_u32 a[8]; |
62 |
+ |
uae_u32 pc; |
63 |
+ |
}; |
64 |
+ |
|
65 |
+ |
const int LOG_SIZE = 8192; |
66 |
+ |
static rec_step log[LOG_SIZE]; |
67 |
+ |
static int log_ptr = -1; // First time initialization |
68 |
+ |
|
69 |
+ |
static const char *log_filename(void) |
70 |
+ |
{ |
71 |
+ |
const char *name = getenv("M68K_LOG_FILE"); |
72 |
+ |
return name ? name : "log.68k"; |
73 |
+ |
} |
74 |
+ |
|
75 |
+ |
static void record_step(uaecptr pc) |
76 |
+ |
{ |
77 |
+ |
for (int i = 0; i < 8; i++) { |
78 |
+ |
log[log_ptr].d[i] = m68k_dreg(regs, i); |
79 |
+ |
log[log_ptr].a[i] = m68k_areg(regs, i); |
80 |
+ |
} |
81 |
+ |
log[log_ptr].pc = pc; |
82 |
+ |
log_ptr = (log_ptr + 1) % LOG_SIZE; |
83 |
+ |
} |
84 |
+ |
|
85 |
+ |
static void dump_log(void) |
86 |
+ |
{ |
87 |
+ |
FILE *f = fopen(log_filename(), "w"); |
88 |
+ |
if (f == NULL) |
89 |
+ |
return; |
90 |
+ |
for (int i = 0; i < LOG_SIZE; i++) { |
91 |
+ |
int j = (i + log_ptr) % LOG_SIZE; |
92 |
+ |
fprintf(f, "pc %08x\n", log[j].pc); |
93 |
+ |
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]); |
94 |
+ |
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]); |
95 |
+ |
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]); |
96 |
+ |
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]); |
97 |
+ |
#if ENABLE_MON |
98 |
+ |
disass_68k(f, log[j].pc); |
99 |
+ |
#endif |
100 |
+ |
} |
101 |
+ |
fclose(f); |
102 |
+ |
} |
103 |
+ |
#endif |
104 |
+ |
|
105 |
|
#define COUNT_INSTRS 0 |
106 |
|
|
107 |
|
#if COUNT_INSTRS |
165 |
|
#endif |
166 |
|
} |
167 |
|
|
168 |
< |
static void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
168 |
> |
cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
169 |
|
|
170 |
< |
static void REGPARAM2 op_illg_1 (uae_u32 opcode) |
170 |
> |
cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode) |
171 |
|
{ |
172 |
< |
op_illg (cft_map (opcode)); |
172 |
> |
cpuop_return( op_illg (cft_map (opcode)) ); |
173 |
|
} |
174 |
|
|
175 |
|
static void build_cpufunctbl (void) |
188 |
|
cpu_level = 1; |
189 |
|
} |
190 |
|
struct cputbl *tbl = ( |
191 |
< |
cpu_level == 4 ? op_smalltbl_0 |
192 |
< |
: cpu_level == 3 ? op_smalltbl_1 |
193 |
< |
: cpu_level == 2 ? op_smalltbl_2 |
194 |
< |
: cpu_level == 1 ? op_smalltbl_3 |
195 |
< |
: op_smalltbl_4); |
191 |
> |
cpu_level == 4 ? op_smalltbl_0_ff |
192 |
> |
: cpu_level == 3 ? op_smalltbl_1_ff |
193 |
> |
: cpu_level == 2 ? op_smalltbl_2_ff |
194 |
> |
: cpu_level == 1 ? op_smalltbl_3_ff |
195 |
> |
: op_smalltbl_4_ff); |
196 |
|
|
197 |
|
for (opcode = 0; opcode < 65536; opcode++) |
198 |
|
cpufunctbl[cft_map (opcode)] = op_illg_1; |
232 |
|
movem_index2[i] = 7-j; |
233 |
|
movem_next[i] = i & (~(1 << j)); |
234 |
|
} |
181 |
– |
for (i = 0 ; i < 256 ; i++) { |
182 |
– |
int j; |
183 |
– |
for (j = 7 ; j >= 0 ; j--) { |
184 |
– |
if (i & (1 << j)) break; |
185 |
– |
} |
186 |
– |
fpp_movem_index1[i] = 7-j; |
187 |
– |
fpp_movem_index2[i] = j; |
188 |
– |
fpp_movem_next[i] = i & (~(1 << j)); |
189 |
– |
} |
235 |
|
#if COUNT_INSTRS |
236 |
|
{ |
237 |
|
FILE *f = fopen (icountfilename (), "r"); |
252 |
|
do_merges (); |
253 |
|
|
254 |
|
build_cpufunctbl (); |
255 |
< |
|
256 |
< |
fpu_init (); |
257 |
< |
fpu_set_integral_fpu (CPUType == 4); |
255 |
> |
|
256 |
> |
#if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) |
257 |
> |
spcflags_lock = B2_create_mutex(); |
258 |
> |
#endif |
259 |
> |
fpu_init(CPUType == 4); |
260 |
|
} |
261 |
|
|
262 |
|
void exit_m68k (void) |
263 |
|
{ |
264 |
|
fpu_exit (); |
265 |
+ |
#if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) |
266 |
+ |
B2_delete_mutex(spcflags_lock); |
267 |
+ |
#endif |
268 |
|
} |
269 |
|
|
270 |
|
struct regstruct regs, lastint_regs; |
700 |
|
} |
701 |
|
} |
702 |
|
|
703 |
< |
regs.spcflags |= SPCFLAG_INT; |
703 |
> |
SPCFLAGS_SET( SPCFLAG_INT ); |
704 |
|
if (regs.t1 || regs.t0) |
705 |
< |
regs.spcflags |= SPCFLAG_TRACE; |
705 |
> |
SPCFLAGS_SET( SPCFLAG_TRACE ); |
706 |
|
else |
707 |
< |
regs.spcflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE); |
707 |
> |
/* Keep SPCFLAG_DOTRACE, we still want a trace exception for |
708 |
> |
SR-modifying instructions (including STOP). */ |
709 |
> |
SPCFLAGS_CLEAR( SPCFLAG_TRACE ); |
710 |
|
} |
711 |
|
|
712 |
|
void Exception(int nr, uaecptr oldpc) |
713 |
|
{ |
714 |
< |
compiler_flush_jsr_stack(); |
714 |
> |
uae_u32 currpc = m68k_getpc (); |
715 |
|
MakeSR(); |
716 |
|
if (!regs.s) { |
717 |
|
regs.usp = m68k_areg(regs, 7); |
740 |
|
m68k_areg(regs, 7) -= 2; |
741 |
|
put_word (m68k_areg(regs, 7), nr * 4); |
742 |
|
m68k_areg(regs, 7) -= 4; |
743 |
< |
put_long (m68k_areg(regs, 7), m68k_getpc ()); |
743 |
> |
put_long (m68k_areg(regs, 7), currpc); |
744 |
|
m68k_areg(regs, 7) -= 2; |
745 |
|
put_word (m68k_areg(regs, 7), regs.sr); |
746 |
|
regs.sr |= (1 << 13); |
766 |
|
} |
767 |
|
} |
768 |
|
m68k_areg(regs, 7) -= 4; |
769 |
< |
put_long (m68k_areg(regs, 7), m68k_getpc ()); |
769 |
> |
put_long (m68k_areg(regs, 7), currpc); |
770 |
|
kludge_me_do: |
771 |
|
m68k_areg(regs, 7) -= 2; |
772 |
|
put_word (m68k_areg(regs, 7), regs.sr); |
773 |
|
m68k_setpc (get_long (regs.vbr + 4*nr)); |
774 |
+ |
SPCFLAGS_SET( SPCFLAG_JIT_END_COMPILE ); |
775 |
|
fill_prefetch_0 (); |
776 |
|
regs.t1 = regs.t0 = regs.m = 0; |
777 |
< |
regs.spcflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE); |
777 |
> |
SPCFLAGS_CLEAR( SPCFLAG_TRACE | SPCFLAG_DOTRACE ); |
778 |
|
} |
779 |
|
|
780 |
|
static void Interrupt(int nr) |
785 |
|
Exception(nr+24, 0); |
786 |
|
|
787 |
|
regs.intmask = nr; |
788 |
< |
regs.spcflags |= SPCFLAG_INT; |
788 |
> |
SPCFLAGS_SET( SPCFLAG_INT ); |
789 |
|
} |
790 |
|
|
791 |
< |
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1; |
791 |
> |
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1, mmusr, urp, srp; |
792 |
|
|
793 |
< |
void m68k_move2c (int regno, uae_u32 *regp) |
793 |
> |
int m68k_move2c (int regno, uae_u32 *regp) |
794 |
|
{ |
795 |
< |
if (CPUType == 1 && (regno & 0x7FF) > 1) |
795 |
> |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
796 |
> |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
797 |
> |
|| (CPUType == 4 && regno == 0x802)) |
798 |
> |
{ |
799 |
|
op_illg (0x4E7B); |
800 |
< |
else |
800 |
> |
return 0; |
801 |
> |
} else { |
802 |
|
switch (regno) { |
803 |
|
case 0: regs.sfc = *regp & 7; break; |
804 |
|
case 1: regs.dfc = *regp & 7; break; |
805 |
< |
case 2: cacr = *regp & 0x3; break; /* ignore C and CE */ |
805 |
> |
case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); break; |
806 |
|
case 3: tc = *regp & 0xc000; break; |
807 |
|
case 4: itt0 = *regp & 0xffffe364; break; |
808 |
|
case 5: itt1 = *regp & 0xffffe364; break; |
813 |
|
case 0x802: caar = *regp &0xfc; break; |
814 |
|
case 0x803: regs.msp = *regp; if (regs.m == 1) m68k_areg(regs, 7) = regs.msp; break; |
815 |
|
case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break; |
816 |
+ |
case 0x805: mmusr = *regp; break; |
817 |
+ |
case 0x806: urp = *regp; break; |
818 |
+ |
case 0x807: srp = *regp; break; |
819 |
|
default: |
820 |
|
op_illg (0x4E7B); |
821 |
< |
break; |
821 |
> |
return 0; |
822 |
|
} |
823 |
+ |
} |
824 |
+ |
return 1; |
825 |
|
} |
826 |
|
|
827 |
< |
void m68k_movec2 (int regno, uae_u32 *regp) |
827 |
> |
int m68k_movec2 (int regno, uae_u32 *regp) |
828 |
|
{ |
829 |
< |
if (CPUType == 1 && (regno & 0x7FF) > 1) |
829 |
> |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
830 |
> |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
831 |
> |
|| (CPUType == 4 && regno == 0x802)) |
832 |
> |
{ |
833 |
|
op_illg (0x4E7A); |
834 |
< |
else |
834 |
> |
return 0; |
835 |
> |
} else { |
836 |
|
switch (regno) { |
837 |
|
case 0: *regp = regs.sfc; break; |
838 |
|
case 1: *regp = regs.dfc; break; |
847 |
|
case 0x802: *regp = caar; break; |
848 |
|
case 0x803: *regp = regs.m == 1 ? m68k_areg(regs, 7) : regs.msp; break; |
849 |
|
case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break; |
850 |
+ |
case 0x805: *regp = mmusr; break; |
851 |
+ |
case 0x806: *regp = urp; break; |
852 |
+ |
case 0x807: *regp = srp; break; |
853 |
|
default: |
854 |
|
op_illg (0x4E7A); |
855 |
< |
break; |
855 |
> |
return 0; |
856 |
> |
} |
857 |
|
} |
858 |
+ |
return 1; |
859 |
|
} |
860 |
|
|
861 |
|
static __inline__ int |
1113 |
|
{ "T ","F ","HI","LS","CC","CS","NE","EQ", |
1114 |
|
"VC","VS","PL","MI","GE","LT","GT","LE" }; |
1115 |
|
|
1116 |
+ |
// If value is greater than zero, this means we are still processing an EmulOp |
1117 |
+ |
// because the counter is incremented only in m68k_execute(), i.e. interpretive |
1118 |
+ |
// execution only |
1119 |
+ |
static int m68k_execute_depth = 0; |
1120 |
+ |
|
1121 |
|
void m68k_reset (void) |
1122 |
|
{ |
1123 |
|
m68k_areg (regs, 7) = 0x2000; |
1124 |
|
m68k_setpc (ROMBaseMac + 0x2a); |
1125 |
|
fill_prefetch_0 (); |
1050 |
– |
regs.kick_mask = 0xF80000; |
1126 |
|
regs.s = 1; |
1127 |
|
regs.m = 0; |
1128 |
|
regs.stopped = 0; |
1133 |
|
SET_CFLG (0); |
1134 |
|
SET_VFLG (0); |
1135 |
|
SET_NFLG (0); |
1136 |
< |
regs.spcflags = 0; |
1136 |
> |
SPCFLAGS_INIT( 0 ); |
1137 |
|
regs.intmask = 7; |
1138 |
|
regs.vbr = regs.sfc = regs.dfc = 0; |
1064 |
– |
/* gb-- moved into {fpp,fpu_x86}.cpp::fpu_init() |
1065 |
– |
regs.fpcr = regs.fpsr = regs.fpiar = 0; */ |
1139 |
|
fpu_reset(); |
1140 |
+ |
|
1141 |
+ |
#if FLIGHT_RECORDER |
1142 |
+ |
#if ENABLE_MON |
1143 |
+ |
if (log_ptr == -1) { |
1144 |
+ |
// Install "log" command in mon |
1145 |
+ |
mon_add_command("log", dump_log, "log Dump m68k emulation log\n"); |
1146 |
+ |
} |
1147 |
+ |
#endif |
1148 |
+ |
log_ptr = 0; |
1149 |
+ |
memset(log, 0, sizeof(log)); |
1150 |
+ |
#endif |
1151 |
|
} |
1152 |
|
|
1153 |
< |
void REGPARAM2 op_illg (uae_u32 opcode) |
1153 |
> |
void m68k_emulop_return(void) |
1154 |
|
{ |
1155 |
< |
uaecptr pc = m68k_getpc (); |
1156 |
< |
|
1157 |
< |
compiler_flush_jsr_stack (); |
1155 |
> |
SPCFLAGS_SET( SPCFLAG_BRK ); |
1156 |
> |
quit_program = 1; |
1157 |
> |
} |
1158 |
|
|
1159 |
< |
if ((opcode & 0xFF00) == 0x7100) { |
1159 |
> |
void m68k_emulop(uae_u32 opcode) |
1160 |
> |
{ |
1161 |
|
struct M68kRegisters r; |
1162 |
|
int i; |
1163 |
|
|
1079 |
– |
// Return from Execute68k()? |
1080 |
– |
if (opcode == M68K_EXEC_RETURN) { |
1081 |
– |
regs.spcflags |= SPCFLAG_BRK; |
1082 |
– |
quit_program = 1; |
1083 |
– |
return; |
1084 |
– |
} |
1085 |
– |
|
1086 |
– |
// Call EMUL_OP opcode |
1164 |
|
for (i=0; i<8; i++) { |
1165 |
|
r.d[i] = m68k_dreg(regs, i); |
1166 |
|
r.a[i] = m68k_areg(regs, i); |
1174 |
|
} |
1175 |
|
regs.sr = r.sr; |
1176 |
|
MakeFromSR(); |
1177 |
< |
m68k_incpc(2); |
1178 |
< |
fill_prefetch_0 (); |
1179 |
< |
return; |
1180 |
< |
} |
1177 |
> |
} |
1178 |
> |
|
1179 |
> |
cpuop_rettype REGPARAM2 op_illg (uae_u32 opcode) |
1180 |
> |
{ |
1181 |
> |
uaecptr pc = m68k_getpc (); |
1182 |
|
|
1183 |
|
if ((opcode & 0xF000) == 0xA000) { |
1184 |
|
Exception(0xA,0); |
1185 |
< |
return; |
1185 |
> |
cpuop_return(CFLOW_TRAP); |
1186 |
|
} |
1187 |
|
|
1110 |
– |
// write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); |
1111 |
– |
|
1188 |
|
if ((opcode & 0xF000) == 0xF000) { |
1189 |
|
Exception(0xB,0); |
1190 |
< |
return; |
1190 |
> |
cpuop_return(CFLOW_TRAP); |
1191 |
|
} |
1192 |
|
|
1193 |
|
write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); |
1194 |
|
|
1195 |
|
Exception (4,0); |
1196 |
+ |
cpuop_return(CFLOW_TRAP); |
1197 |
|
} |
1198 |
|
|
1199 |
|
void mmu_op(uae_u32 opcode, uae_u16 extra) |
1200 |
|
{ |
1201 |
< |
if ((extra & 0xB000) == 0) { /* PMOVE instruction */ |
1202 |
< |
|
1203 |
< |
} else if ((extra & 0xF000) == 0x2000) { /* PLOAD instruction */ |
1204 |
< |
} else if ((extra & 0xF000) == 0x8000) { /* PTEST instruction */ |
1201 |
> |
if ((opcode & 0xFE0) == 0x0500) { |
1202 |
> |
/* PFLUSH */ |
1203 |
> |
mmusr = 0; |
1204 |
> |
} else if ((opcode & 0x0FD8) == 0x548) { |
1205 |
> |
/* PTEST */ |
1206 |
|
} else |
1207 |
< |
op_illg (opcode); |
1207 |
> |
op_illg (opcode); |
1208 |
|
} |
1209 |
|
|
1210 |
|
static int n_insns = 0, n_spcinsns = 0; |
1213 |
|
|
1214 |
|
static void do_trace (void) |
1215 |
|
{ |
1216 |
< |
if (regs.t0) { |
1216 |
> |
if (regs.t0 && CPUType >= 2) { |
1217 |
|
uae_u16 opcode; |
1218 |
|
/* should also include TRAP, CHK, SR modification FPcc */ |
1219 |
|
/* probably never used so why bother */ |
1220 |
|
/* We can afford this to be inefficient... */ |
1221 |
|
m68k_setpc (m68k_getpc ()); |
1222 |
|
fill_prefetch_0 (); |
1223 |
< |
opcode = get_word (regs.pc); |
1223 |
> |
opcode = get_word(m68k_getpc()); |
1224 |
|
if (opcode == 0x4e72 /* RTE */ |
1225 |
|
|| opcode == 0x4e74 /* RTD */ |
1226 |
|
|| opcode == 0x4e75 /* RTS */ |
1236 |
|
&& (uae_s16)m68k_dreg(regs, opcode & 7) != 0)) |
1237 |
|
{ |
1238 |
|
last_trace_ad = m68k_getpc (); |
1239 |
< |
regs.spcflags &= ~SPCFLAG_TRACE; |
1240 |
< |
regs.spcflags |= SPCFLAG_DOTRACE; |
1239 |
> |
SPCFLAGS_CLEAR( SPCFLAG_TRACE ); |
1240 |
> |
SPCFLAGS_SET( SPCFLAG_DOTRACE ); |
1241 |
|
} |
1242 |
|
} else if (regs.t1) { |
1243 |
|
last_trace_ad = m68k_getpc (); |
1244 |
< |
regs.spcflags &= ~SPCFLAG_TRACE; |
1245 |
< |
regs.spcflags |= SPCFLAG_DOTRACE; |
1244 |
> |
SPCFLAGS_CLEAR( SPCFLAG_TRACE ); |
1245 |
> |
SPCFLAGS_SET( SPCFLAG_DOTRACE ); |
1246 |
|
} |
1247 |
|
} |
1248 |
|
|
1249 |
< |
|
1172 |
< |
static int do_specialties (void) |
1249 |
> |
int m68k_do_specialties (void) |
1250 |
|
{ |
1251 |
< |
/*n_spcinsns++;*/ |
1175 |
< |
run_compiled_code(); |
1176 |
< |
if (regs.spcflags & SPCFLAG_DOTRACE) { |
1251 |
> |
if (SPCFLAGS_TEST( SPCFLAG_DOTRACE )) { |
1252 |
|
Exception (9,last_trace_ad); |
1253 |
|
} |
1254 |
< |
while (regs.spcflags & SPCFLAG_STOP) { |
1255 |
< |
if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)){ |
1254 |
> |
while (SPCFLAGS_TEST( SPCFLAG_STOP )) { |
1255 |
> |
if (SPCFLAGS_TEST( SPCFLAG_INT | SPCFLAG_DOINT )){ |
1256 |
> |
SPCFLAGS_CLEAR( SPCFLAG_INT | SPCFLAG_DOINT ); |
1257 |
|
int intr = intlev (); |
1182 |
– |
regs.spcflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT); |
1258 |
|
if (intr != -1 && intr > regs.intmask) { |
1259 |
|
Interrupt (intr); |
1260 |
|
regs.stopped = 0; |
1261 |
< |
regs.spcflags &= ~SPCFLAG_STOP; |
1261 |
> |
SPCFLAGS_CLEAR( SPCFLAG_STOP ); |
1262 |
|
} |
1263 |
|
} |
1264 |
|
} |
1265 |
< |
if (regs.spcflags & SPCFLAG_TRACE) |
1265 |
> |
if (SPCFLAGS_TEST( SPCFLAG_TRACE )) |
1266 |
|
do_trace (); |
1267 |
|
|
1268 |
< |
if (regs.spcflags & SPCFLAG_DOINT) { |
1268 |
> |
if (SPCFLAGS_TEST( SPCFLAG_DOINT )) { |
1269 |
> |
SPCFLAGS_CLEAR( SPCFLAG_DOINT ); |
1270 |
|
int intr = intlev (); |
1195 |
– |
regs.spcflags &= ~SPCFLAG_DOINT; |
1271 |
|
if (intr != -1 && intr > regs.intmask) { |
1272 |
|
Interrupt (intr); |
1273 |
|
regs.stopped = 0; |
1274 |
|
} |
1275 |
|
} |
1276 |
< |
if (regs.spcflags & SPCFLAG_INT) { |
1277 |
< |
regs.spcflags &= ~SPCFLAG_INT; |
1278 |
< |
regs.spcflags |= SPCFLAG_DOINT; |
1279 |
< |
} |
1280 |
< |
if (regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)) { |
1281 |
< |
regs.spcflags &= ~(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE); |
1282 |
< |
return 1; |
1276 |
> |
if (SPCFLAGS_TEST( SPCFLAG_INT )) { |
1277 |
> |
SPCFLAGS_CLEAR( SPCFLAG_INT ); |
1278 |
> |
SPCFLAGS_SET( SPCFLAG_DOINT ); |
1279 |
> |
} |
1280 |
> |
if (SPCFLAGS_TEST( SPCFLAG_BRK )) { |
1281 |
> |
SPCFLAGS_CLEAR( SPCFLAG_BRK ); |
1282 |
> |
return CFLOW_EXEC_RETURN; |
1283 |
|
} |
1284 |
|
return 0; |
1285 |
|
} |
1286 |
|
|
1287 |
< |
static void m68k_run_1 (void) |
1287 |
> |
void m68k_do_execute (void) |
1288 |
|
{ |
1289 |
|
for (;;) { |
1290 |
|
uae_u32 opcode = GET_OPCODE; |
1291 |
+ |
#if FLIGHT_RECORDER |
1292 |
+ |
record_step(m68k_getpc()); |
1293 |
+ |
#endif |
1294 |
+ |
#ifdef X86_ASSEMBLY |
1295 |
+ |
__asm__ __volatile__("\tpushl %%ebp\n\tcall *%%ebx\n\tpopl %%ebp" /* FIXME */ |
1296 |
+ |
: : "b" (cpufunctbl[opcode]), "a" (opcode) |
1297 |
+ |
: "%edx", "%ecx", "%esi", "%edi", "%ebp", "memory", "cc"); |
1298 |
+ |
#else |
1299 |
|
(*cpufunctbl[opcode])(opcode); |
1300 |
< |
if (regs.spcflags) { |
1301 |
< |
if (do_specialties()) |
1300 |
> |
#endif |
1301 |
> |
if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) { |
1302 |
> |
if (m68k_do_specialties()) |
1303 |
|
return; |
1304 |
|
} |
1305 |
|
} |
1306 |
|
} |
1307 |
|
|
1308 |
< |
#define m68k_run1 m68k_run_1 |
1225 |
< |
|
1226 |
< |
int in_m68k_go = 0; |
1227 |
< |
|
1228 |
< |
void m68k_go (int may_quit) |
1308 |
> |
void m68k_execute (void) |
1309 |
|
{ |
1230 |
– |
// m68k_go() must be reentrant for Execute68k() and Execute68kTrap() to work |
1231 |
– |
/* |
1232 |
– |
if (in_m68k_go || !may_quit) { |
1233 |
– |
write_log("Bug! m68k_go is not reentrant.\n"); |
1234 |
– |
abort(); |
1235 |
– |
} |
1236 |
– |
*/ |
1237 |
– |
in_m68k_go++; |
1310 |
|
for (;;) { |
1311 |
|
if (quit_program > 0) { |
1312 |
|
if (quit_program == 1) |
1314 |
|
quit_program = 0; |
1315 |
|
m68k_reset (); |
1316 |
|
} |
1317 |
< |
m68k_run1(); |
1317 |
> |
m68k_do_execute(); |
1318 |
|
} |
1319 |
|
if (debugging) { |
1320 |
|
uaecptr nextpc; |
1321 |
|
m68k_dumpstate(&nextpc); |
1322 |
|
exit(1); |
1323 |
|
} |
1252 |
– |
in_m68k_go--; |
1324 |
|
} |
1325 |
|
|
1326 |
|
static void m68k_verify (uaecptr addr, uaecptr *nextpc) |
1429 |
|
printf ("T=%d%d S=%d M=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n", |
1430 |
|
regs.t1, regs.t0, regs.s, regs.m, |
1431 |
|
GET_XFLG, GET_NFLG, GET_ZFLG, GET_VFLG, GET_CFLG, regs.intmask); |
1432 |
< |
for (i = 0; i < 8; i++){ |
1433 |
< |
printf ("FP%d: %g ", i, regs.fp[i]); |
1434 |
< |
if ((i & 3) == 3) printf ("\n"); |
1435 |
< |
} |
1365 |
< |
printf ("N=%d Z=%d I=%d NAN=%d\n", |
1366 |
< |
(regs.fpsr & 0x8000000) != 0, |
1367 |
< |
(regs.fpsr & 0x4000000) != 0, |
1368 |
< |
(regs.fpsr & 0x2000000) != 0, |
1369 |
< |
(regs.fpsr & 0x1000000) != 0); |
1370 |
< |
|
1432 |
> |
|
1433 |
> |
fpu_dump_registers(); |
1434 |
> |
fpu_dump_flags(); |
1435 |
> |
|
1436 |
|
m68k_disasm(m68k_getpc (), nextpc, 1); |
1437 |
|
if (nextpc) |
1438 |
|
printf ("next PC: %08lx\n", *nextpc); |