111 |
|
#endif |
112 |
|
} |
113 |
|
|
114 |
< |
static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
114 |
> |
static void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
115 |
|
|
116 |
< |
static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) |
116 |
> |
static void REGPARAM2 op_illg_1 (uae_u32 opcode) |
117 |
|
{ |
118 |
|
op_illg (cft_map (opcode)); |
119 |
– |
return 4; |
119 |
|
} |
120 |
|
|
121 |
|
static void build_cpufunctbl (void) |
122 |
|
{ |
123 |
|
int i; |
124 |
|
unsigned long opcode; |
125 |
< |
int cpu_level = (FPUType ? 3 : CPUType >= 2 ? 2 : CPUType == 1 ? 1 : 0); |
126 |
< |
struct cputbl *tbl = (cpu_level == 3 ? op_smalltbl_0 |
127 |
< |
: cpu_level == 2 ? op_smalltbl_1 |
128 |
< |
: cpu_level == 1 ? op_smalltbl_2 |
129 |
< |
: op_smalltbl_3); |
125 |
> |
int cpu_level = 0; // 68000 (default) |
126 |
> |
if (CPUType == 4) |
127 |
> |
cpu_level = 4; // 68040 with FPU |
128 |
> |
else { |
129 |
> |
if (FPUType) |
130 |
> |
cpu_level = 3; // 68020 with FPU |
131 |
> |
else if (CPUType >= 2) |
132 |
> |
cpu_level = 2; // 68020 |
133 |
> |
else if (CPUType == 1) |
134 |
> |
cpu_level = 1; |
135 |
> |
} |
136 |
> |
struct cputbl *tbl = ( |
137 |
> |
cpu_level == 4 ? op_smalltbl_0 |
138 |
> |
: cpu_level == 3 ? op_smalltbl_1 |
139 |
> |
: cpu_level == 2 ? op_smalltbl_2 |
140 |
> |
: cpu_level == 1 ? op_smalltbl_3 |
141 |
> |
: op_smalltbl_4); |
142 |
|
|
143 |
|
for (opcode = 0; opcode < 65536; opcode++) |
144 |
|
cpufunctbl[cft_map (opcode)] = op_illg_1; |
183 |
|
for (j = 7 ; j >= 0 ; j--) { |
184 |
|
if (i & (1 << j)) break; |
185 |
|
} |
186 |
< |
fpp_movem_index1[i] = j; |
187 |
< |
fpp_movem_index2[i] = 7-j; |
186 |
> |
fpp_movem_index1[i] = 7-j; |
187 |
> |
fpp_movem_index2[i] = j; |
188 |
|
fpp_movem_next[i] = i & (~(1 << j)); |
189 |
|
} |
190 |
|
#if COUNT_INSTRS |
250 |
|
disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; |
251 |
|
addr = m68k_areg(regs,reg) + (uae_s16)disp16; |
252 |
|
sprintf (buffer,"(A%d,$%04x) == $%08lx", reg, disp16 & 0xffff, |
253 |
< |
(long unsigned int)addr); |
253 |
> |
(unsigned long)addr); |
254 |
|
break; |
255 |
|
case Ad8r: |
256 |
|
dp = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; |
283 |
|
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', |
284 |
|
1 << ((dp >> 9) & 3), |
285 |
|
disp,outer, |
286 |
< |
(long unsigned int)addr); |
286 |
> |
(unsigned long)addr); |
287 |
|
} else { |
288 |
|
addr = m68k_areg(regs,reg) + (uae_s32)((uae_s8)disp8) + dispreg; |
289 |
|
sprintf (buffer,"(A%d, %c%d.%c*%d, $%02x) == $%08lx", reg, |
290 |
|
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', |
291 |
|
1 << ((dp >> 9) & 3), disp8, |
292 |
< |
(long unsigned int)addr); |
292 |
> |
(unsigned long)addr); |
293 |
|
} |
294 |
|
break; |
295 |
|
case PC16: |
296 |
|
addr = m68k_getpc () + m68kpc_offset; |
297 |
|
disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; |
298 |
|
addr += (uae_s16)disp16; |
299 |
< |
sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(long unsigned int)addr); |
299 |
> |
sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(unsigned long)addr); |
300 |
|
break; |
301 |
|
case PC8r: |
302 |
|
addr = m68k_getpc () + m68kpc_offset; |
330 |
|
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', |
331 |
|
1 << ((dp >> 9) & 3), |
332 |
|
disp,outer, |
333 |
< |
(long unsigned int)addr); |
333 |
> |
(unsigned long)addr); |
334 |
|
} else { |
335 |
|
addr += (uae_s32)((uae_s8)disp8) + dispreg; |
336 |
|
sprintf (buffer,"(PC, %c%d.%c*%d, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D', |
337 |
|
(int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), |
338 |
< |
disp8, (long unsigned int)addr); |
338 |
> |
disp8, (unsigned long)addr); |
339 |
|
} |
340 |
|
break; |
341 |
|
case absw: |
342 |
< |
sprintf (buffer,"$%08lx", (long unsigned int)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); |
342 |
> |
sprintf (buffer,"$%08lx", (unsigned long)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); |
343 |
|
m68kpc_offset += 2; |
344 |
|
break; |
345 |
|
case absl: |
346 |
< |
sprintf (buffer,"$%08lx", (long unsigned int)get_ilong_1 (m68kpc_offset)); |
346 |
> |
sprintf (buffer,"$%08lx", (unsigned long)get_ilong_1 (m68kpc_offset)); |
347 |
|
m68kpc_offset += 4; |
348 |
|
break; |
349 |
|
case imm: |
357 |
|
m68kpc_offset += 2; |
358 |
|
break; |
359 |
|
case sz_long: |
360 |
< |
sprintf (buffer,"#$%08lx", (long unsigned int)(get_ilong_1 (m68kpc_offset))); |
360 |
> |
sprintf (buffer,"#$%08lx", (unsigned long)(get_ilong_1 (m68kpc_offset))); |
361 |
|
m68kpc_offset += 4; |
362 |
|
break; |
363 |
|
default: |
377 |
|
case imm2: |
378 |
|
offset = (uae_s32)get_ilong_1 (m68kpc_offset); |
379 |
|
m68kpc_offset += 4; |
380 |
< |
sprintf (buffer,"#$%08lx", (long unsigned int)offset); |
380 |
> |
sprintf (buffer,"#$%08lx", (unsigned long)offset); |
381 |
|
break; |
382 |
|
case immi: |
383 |
|
offset = (uae_s32)(uae_s8)(reg & 0xff); |
384 |
< |
sprintf (buffer,"#$%08lx", (long unsigned int)offset); |
384 |
> |
sprintf (buffer,"#$%08lx", (unsigned long)offset); |
385 |
|
break; |
386 |
|
default: |
387 |
|
break; |
721 |
|
regs.spcflags |= SPCFLAG_INT; |
722 |
|
} |
723 |
|
|
724 |
< |
static int caar, cacr; |
724 |
> |
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1; |
725 |
|
|
726 |
|
void m68k_move2c (int regno, uae_u32 *regp) |
727 |
|
{ |
732 |
|
case 0: regs.sfc = *regp & 7; break; |
733 |
|
case 1: regs.dfc = *regp & 7; break; |
734 |
|
case 2: cacr = *regp & 0x3; break; /* ignore C and CE */ |
735 |
+ |
case 3: tc = *regp & 0xc000; break; |
736 |
+ |
case 4: itt0 = *regp & 0xffffe364; break; |
737 |
+ |
case 5: itt1 = *regp & 0xffffe364; break; |
738 |
+ |
case 6: dtt0 = *regp & 0xffffe364; break; |
739 |
+ |
case 7: dtt1 = *regp & 0xffffe364; break; |
740 |
|
case 0x800: regs.usp = *regp; break; |
741 |
|
case 0x801: regs.vbr = *regp; break; |
742 |
|
case 0x802: caar = *regp &0xfc; break; |
757 |
|
case 0: *regp = regs.sfc; break; |
758 |
|
case 1: *regp = regs.dfc; break; |
759 |
|
case 2: *regp = cacr; break; |
760 |
+ |
case 3: *regp = tc; break; |
761 |
+ |
case 4: *regp = itt0; break; |
762 |
+ |
case 5: *regp = itt1; break; |
763 |
+ |
case 6: *regp = dtt0; break; |
764 |
+ |
case 7: *regp = dtt1; break; |
765 |
|
case 0x800: *regp = regs.usp; break; |
766 |
|
case 0x801: *regp = regs.vbr; break; |
767 |
|
case 0x802: *regp = caar; break; |
1050 |
|
regs.fpcr = regs.fpsr = regs.fpiar = 0; |
1051 |
|
} |
1052 |
|
|
1053 |
< |
unsigned long REGPARAM2 op_illg (uae_u32 opcode) |
1053 |
> |
void REGPARAM2 op_illg (uae_u32 opcode) |
1054 |
|
{ |
1055 |
|
uaecptr pc = m68k_getpc (); |
1056 |
|
|
1064 |
|
if (opcode == M68K_EXEC_RETURN) { |
1065 |
|
regs.spcflags |= SPCFLAG_BRK; |
1066 |
|
quit_program = 1; |
1067 |
< |
return 4; |
1067 |
> |
return; |
1068 |
|
} |
1069 |
|
|
1070 |
|
// Call EMUL_OP opcode |
1083 |
|
MakeFromSR(); |
1084 |
|
m68k_incpc(2); |
1085 |
|
fill_prefetch_0 (); |
1086 |
< |
return 4; |
1086 |
> |
return; |
1087 |
|
} |
1088 |
|
|
1089 |
|
if ((opcode & 0xF000) == 0xA000) { |
1090 |
|
Exception(0xA,0); |
1091 |
< |
return 4; |
1091 |
> |
return; |
1092 |
|
} |
1093 |
|
|
1094 |
+ |
// write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); |
1095 |
+ |
|
1096 |
|
if ((opcode & 0xF000) == 0xF000) { |
1097 |
|
Exception(0xB,0); |
1098 |
< |
return 4; |
1098 |
> |
return; |
1099 |
|
} |
1100 |
|
|
1101 |
|
write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); |
1102 |
+ |
|
1103 |
|
Exception (4,0); |
1080 |
– |
return 4; |
1104 |
|
} |
1105 |
|
|
1106 |
|
void mmu_op(uae_u32 opcode, uae_u16 extra) |
1195 |
|
|
1196 |
|
static void m68k_run_1 (void) |
1197 |
|
{ |
1198 |
< |
for (;;) { |
1199 |
< |
int cycles; |
1200 |
< |
uae_u32 opcode = GET_OPCODE; |
1201 |
< |
#if 0 |
1202 |
< |
if (get_ilong (0) != do_get_mem_long (®s.prefetch)) { |
1203 |
< |
debugging = 1; |
1204 |
< |
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); |
1199 |
< |
#endif |
1200 |
< |
/*n_insns++;*/ |
1201 |
< |
if (regs.spcflags) { |
1202 |
< |
if (do_specialties ()) |
1203 |
< |
return; |
1198 |
> |
for (;;) { |
1199 |
> |
uae_u32 opcode = GET_OPCODE; |
1200 |
> |
(*cpufunctbl[opcode])(opcode); |
1201 |
> |
if (regs.spcflags) { |
1202 |
> |
if (do_specialties()) |
1203 |
> |
return; |
1204 |
> |
} |
1205 |
|
} |
1205 |
– |
} |
1206 |
|
} |
1207 |
|
|
1208 |
– |
#ifdef X86_ASSEMBLYxxx |
1209 |
– |
static __inline__ void m68k_run1 (void) |
1210 |
– |
{ |
1211 |
– |
/* Work around compiler bug: GCC doesn't push %ebp in m68k_run_1. */ |
1212 |
– |
__asm__ __volatile__ ("pushl %%ebp\n\tcall *%0\n\tpopl %%ebp" : : "r" (m68k_run_1) : "%eax", "%edx", "%ecx", "memory", "cc"); |
1213 |
– |
} |
1214 |
– |
#else |
1208 |
|
#define m68k_run1 m68k_run_1 |
1216 |
– |
#endif |
1209 |
|
|
1210 |
|
int in_m68k_go = 0; |
1211 |
|
|