22 |
|
#include "memory.h" |
23 |
|
#include "readcpu.h" |
24 |
|
#include "newcpu.h" |
25 |
< |
#include "compiler.h" |
25 |
> |
|
26 |
> |
#if ENABLE_MON |
27 |
> |
#include "mon.h" |
28 |
> |
#include "mon_disass.h" |
29 |
> |
#endif |
30 |
|
|
31 |
|
int quit_program = 0; |
32 |
|
int debugging = 0; |
52 |
|
|
53 |
|
cpuop_func *cpufunctbl[65536]; |
54 |
|
|
55 |
+ |
#define FLIGHT_RECORDER 0 |
56 |
+ |
|
57 |
+ |
#if FLIGHT_RECORDER |
58 |
+ |
struct rec_step { |
59 |
+ |
uae_u32 d[8]; |
60 |
+ |
uae_u32 a[8]; |
61 |
+ |
uae_u32 pc; |
62 |
+ |
}; |
63 |
+ |
|
64 |
+ |
const int LOG_SIZE = 8192; |
65 |
+ |
static rec_step log[LOG_SIZE]; |
66 |
+ |
static int log_ptr = -1; // First time initialization |
67 |
+ |
|
68 |
+ |
static const char *log_filename(void) |
69 |
+ |
{ |
70 |
+ |
const char *name = getenv("M68K_LOG_FILE"); |
71 |
+ |
return name ? name : "log.68k"; |
72 |
+ |
} |
73 |
+ |
|
74 |
+ |
static void record_step(uaecptr pc) |
75 |
+ |
{ |
76 |
+ |
for (int i = 0; i < 8; i++) { |
77 |
+ |
log[log_ptr].d[i] = m68k_dreg(regs, i); |
78 |
+ |
log[log_ptr].a[i] = m68k_areg(regs, i); |
79 |
+ |
} |
80 |
+ |
log[log_ptr].pc = pc; |
81 |
+ |
log_ptr = (log_ptr + 1) % LOG_SIZE; |
82 |
+ |
} |
83 |
+ |
|
84 |
+ |
static void dump_log(void) |
85 |
+ |
{ |
86 |
+ |
FILE *f = fopen(log_filename(), "w"); |
87 |
+ |
if (f == NULL) |
88 |
+ |
return; |
89 |
+ |
for (int i = 0; i < LOG_SIZE; i++) { |
90 |
+ |
int j = (i + log_ptr) % LOG_SIZE; |
91 |
+ |
fprintf(f, "pc %08x\n", log[j].pc); |
92 |
+ |
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]); |
93 |
+ |
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]); |
94 |
+ |
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]); |
95 |
+ |
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]); |
96 |
+ |
#if ENABLE_MON |
97 |
+ |
disass_68k(f, log[j].pc); |
98 |
+ |
#endif |
99 |
+ |
} |
100 |
+ |
} |
101 |
+ |
#endif |
102 |
+ |
|
103 |
|
#define COUNT_INSTRS 0 |
104 |
|
|
105 |
|
#if COUNT_INSTRS |
163 |
|
#endif |
164 |
|
} |
165 |
|
|
166 |
< |
static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
166 |
> |
static void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
167 |
|
|
168 |
< |
static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) |
168 |
> |
static void REGPARAM2 op_illg_1 (uae_u32 opcode) |
169 |
|
{ |
170 |
|
op_illg (cft_map (opcode)); |
119 |
– |
return 4; |
171 |
|
} |
172 |
|
|
173 |
|
static void build_cpufunctbl (void) |
235 |
|
for (j = 7 ; j >= 0 ; j--) { |
236 |
|
if (i & (1 << j)) break; |
237 |
|
} |
238 |
< |
fpp_movem_index1[i] = j; |
239 |
< |
fpp_movem_index2[i] = 7-j; |
238 |
> |
fpp_movem_index1[i] = 7-j; |
239 |
> |
fpp_movem_index2[i] = j; |
240 |
|
fpp_movem_next[i] = i & (~(1 << j)); |
241 |
|
} |
242 |
|
#if COUNT_INSTRS |
259 |
|
do_merges (); |
260 |
|
|
261 |
|
build_cpufunctbl (); |
262 |
+ |
|
263 |
+ |
fpu_init (); |
264 |
+ |
fpu_set_integral_fpu (CPUType == 4); |
265 |
+ |
} |
266 |
+ |
|
267 |
+ |
void exit_m68k (void) |
268 |
+ |
{ |
269 |
+ |
fpu_exit (); |
270 |
|
} |
271 |
|
|
272 |
|
struct regstruct regs, lastint_regs; |
275 |
|
static long int m68kpc_offset; |
276 |
|
int lastint_no; |
277 |
|
|
278 |
+ |
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
279 |
+ |
#define get_ibyte_1(o) get_byte(get_virtual_address(regs.pc_p) + (o) + 1) |
280 |
+ |
#define get_iword_1(o) get_word(get_virtual_address(regs.pc_p) + (o)) |
281 |
+ |
#define get_ilong_1(o) get_long(get_virtual_address(regs.pc_p) + (o)) |
282 |
+ |
#else |
283 |
|
#define get_ibyte_1(o) get_byte(regs.pc + (regs.pc_p - regs.pc_oldp) + (o) + 1) |
284 |
|
#define get_iword_1(o) get_word(regs.pc + (regs.pc_p - regs.pc_oldp) + (o)) |
285 |
|
#define get_ilong_1(o) get_long(regs.pc + (regs.pc_p - regs.pc_oldp) + (o)) |
286 |
+ |
#endif |
287 |
|
|
288 |
|
uae_s32 ShowEA (int reg, amodes mode, wordsizes size, char *buf) |
289 |
|
{ |
316 |
|
disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; |
317 |
|
addr = m68k_areg(regs,reg) + (uae_s16)disp16; |
318 |
|
sprintf (buffer,"(A%d,$%04x) == $%08lx", reg, disp16 & 0xffff, |
319 |
< |
(long unsigned int)addr); |
319 |
> |
(unsigned long)addr); |
320 |
|
break; |
321 |
|
case Ad8r: |
322 |
|
dp = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; |
349 |
|
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', |
350 |
|
1 << ((dp >> 9) & 3), |
351 |
|
disp,outer, |
352 |
< |
(long unsigned int)addr); |
352 |
> |
(unsigned long)addr); |
353 |
|
} else { |
354 |
|
addr = m68k_areg(regs,reg) + (uae_s32)((uae_s8)disp8) + dispreg; |
355 |
|
sprintf (buffer,"(A%d, %c%d.%c*%d, $%02x) == $%08lx", reg, |
356 |
|
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', |
357 |
|
1 << ((dp >> 9) & 3), disp8, |
358 |
< |
(long unsigned int)addr); |
358 |
> |
(unsigned long)addr); |
359 |
|
} |
360 |
|
break; |
361 |
|
case PC16: |
362 |
|
addr = m68k_getpc () + m68kpc_offset; |
363 |
|
disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; |
364 |
|
addr += (uae_s16)disp16; |
365 |
< |
sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(long unsigned int)addr); |
365 |
> |
sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(unsigned long)addr); |
366 |
|
break; |
367 |
|
case PC8r: |
368 |
|
addr = m68k_getpc () + m68kpc_offset; |
396 |
|
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', |
397 |
|
1 << ((dp >> 9) & 3), |
398 |
|
disp,outer, |
399 |
< |
(long unsigned int)addr); |
399 |
> |
(unsigned long)addr); |
400 |
|
} else { |
401 |
|
addr += (uae_s32)((uae_s8)disp8) + dispreg; |
402 |
|
sprintf (buffer,"(PC, %c%d.%c*%d, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D', |
403 |
|
(int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), |
404 |
< |
disp8, (long unsigned int)addr); |
404 |
> |
disp8, (unsigned long)addr); |
405 |
|
} |
406 |
|
break; |
407 |
|
case absw: |
408 |
< |
sprintf (buffer,"$%08lx", (long unsigned int)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); |
408 |
> |
sprintf (buffer,"$%08lx", (unsigned long)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); |
409 |
|
m68kpc_offset += 2; |
410 |
|
break; |
411 |
|
case absl: |
412 |
< |
sprintf (buffer,"$%08lx", (long unsigned int)get_ilong_1 (m68kpc_offset)); |
412 |
> |
sprintf (buffer,"$%08lx", (unsigned long)get_ilong_1 (m68kpc_offset)); |
413 |
|
m68kpc_offset += 4; |
414 |
|
break; |
415 |
|
case imm: |
423 |
|
m68kpc_offset += 2; |
424 |
|
break; |
425 |
|
case sz_long: |
426 |
< |
sprintf (buffer,"#$%08lx", (long unsigned int)(get_ilong_1 (m68kpc_offset))); |
426 |
> |
sprintf (buffer,"#$%08lx", (unsigned long)(get_ilong_1 (m68kpc_offset))); |
427 |
|
m68kpc_offset += 4; |
428 |
|
break; |
429 |
|
default: |
443 |
|
case imm2: |
444 |
|
offset = (uae_s32)get_ilong_1 (m68kpc_offset); |
445 |
|
m68kpc_offset += 4; |
446 |
< |
sprintf (buffer,"#$%08lx", (long unsigned int)offset); |
446 |
> |
sprintf (buffer,"#$%08lx", (unsigned long)offset); |
447 |
|
break; |
448 |
|
case immi: |
449 |
|
offset = (uae_s32)(uae_s8)(reg & 0xff); |
450 |
< |
sprintf (buffer,"#$%08lx", (long unsigned int)offset); |
450 |
> |
sprintf (buffer,"#$%08lx", (unsigned long)offset); |
451 |
|
break; |
452 |
|
default: |
453 |
|
break; |
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); |
789 |
|
|
790 |
|
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1; |
791 |
|
|
792 |
< |
void m68k_move2c (int regno, uae_u32 *regp) |
792 |
> |
int m68k_move2c (int regno, uae_u32 *regp) |
793 |
|
{ |
794 |
< |
if (CPUType == 1 && (regno & 0x7FF) > 1) |
794 |
> |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
795 |
> |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
796 |
> |
|| (CPUType == 4 && regno == 0x802)) |
797 |
> |
{ |
798 |
|
op_illg (0x4E7B); |
799 |
< |
else |
799 |
> |
return 0; |
800 |
> |
} else { |
801 |
|
switch (regno) { |
802 |
|
case 0: regs.sfc = *regp & 7; break; |
803 |
|
case 1: regs.dfc = *regp & 7; break; |
804 |
< |
case 2: cacr = *regp & 0x3; break; /* ignore C and CE */ |
804 |
> |
case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); break; |
805 |
|
case 3: tc = *regp & 0xc000; break; |
806 |
|
case 4: itt0 = *regp & 0xffffe364; break; |
807 |
|
case 5: itt1 = *regp & 0xffffe364; break; |
814 |
|
case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break; |
815 |
|
default: |
816 |
|
op_illg (0x4E7B); |
817 |
< |
break; |
817 |
> |
return 0; |
818 |
|
} |
819 |
+ |
} |
820 |
+ |
return 1; |
821 |
|
} |
822 |
|
|
823 |
< |
void m68k_movec2 (int regno, uae_u32 *regp) |
823 |
> |
int m68k_movec2 (int regno, uae_u32 *regp) |
824 |
|
{ |
825 |
< |
if (CPUType == 1 && (regno & 0x7FF) > 1) |
825 |
> |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
826 |
> |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
827 |
> |
|| (CPUType == 4 && regno == 0x802)) |
828 |
> |
{ |
829 |
|
op_illg (0x4E7A); |
830 |
< |
else |
830 |
> |
return 0; |
831 |
> |
} else { |
832 |
|
switch (regno) { |
833 |
|
case 0: *regp = regs.sfc; break; |
834 |
|
case 1: *regp = regs.dfc; break; |
845 |
|
case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break; |
846 |
|
default: |
847 |
|
op_illg (0x4E7A); |
848 |
< |
break; |
848 |
> |
return 0; |
849 |
|
} |
850 |
+ |
} |
851 |
+ |
return 1; |
852 |
|
} |
853 |
|
|
854 |
|
static __inline__ int |
1125 |
|
regs.spcflags = 0; |
1126 |
|
regs.intmask = 7; |
1127 |
|
regs.vbr = regs.sfc = regs.dfc = 0; |
1128 |
< |
regs.fpcr = regs.fpsr = regs.fpiar = 0; |
1128 |
> |
/* gb-- moved into {fpp,fpu_x86}.cpp::fpu_init() |
1129 |
> |
regs.fpcr = regs.fpsr = regs.fpiar = 0; */ |
1130 |
> |
fpu_reset(); |
1131 |
> |
|
1132 |
> |
#if FLIGHT_RECORDER |
1133 |
> |
#if ENABLE_MON |
1134 |
> |
if (log_ptr == -1) { |
1135 |
> |
// Install "log" command in mon |
1136 |
> |
mon_add_command("log", dump_log, "log Dump m68k emulation log\n"); |
1137 |
> |
} |
1138 |
> |
#endif |
1139 |
> |
log_ptr = 0; |
1140 |
> |
memset(log, 0, sizeof(log)); |
1141 |
> |
#endif |
1142 |
|
} |
1143 |
|
|
1144 |
< |
unsigned long REGPARAM2 op_illg (uae_u32 opcode) |
1144 |
> |
void REGPARAM2 op_illg (uae_u32 opcode) |
1145 |
|
{ |
1146 |
|
uaecptr pc = m68k_getpc (); |
1147 |
|
|
1058 |
– |
compiler_flush_jsr_stack (); |
1059 |
– |
|
1148 |
|
if ((opcode & 0xFF00) == 0x7100) { |
1149 |
|
struct M68kRegisters r; |
1150 |
|
int i; |
1151 |
|
|
1152 |
< |
// Return from Execute68k()? |
1152 |
> |
// Return from Exectue68k()? |
1153 |
|
if (opcode == M68K_EXEC_RETURN) { |
1154 |
|
regs.spcflags |= SPCFLAG_BRK; |
1155 |
|
quit_program = 1; |
1156 |
< |
return 4; |
1156 |
> |
return; |
1157 |
|
} |
1158 |
|
|
1159 |
|
// Call EMUL_OP opcode |
1172 |
|
MakeFromSR(); |
1173 |
|
m68k_incpc(2); |
1174 |
|
fill_prefetch_0 (); |
1175 |
< |
return 4; |
1175 |
> |
return; |
1176 |
|
} |
1177 |
|
|
1178 |
|
if ((opcode & 0xF000) == 0xA000) { |
1179 |
|
Exception(0xA,0); |
1180 |
< |
return 4; |
1180 |
> |
return; |
1181 |
|
} |
1182 |
|
|
1183 |
< |
printf("Illegal instruction %04x at %08lx\n", opcode, pc); //!! |
1183 |
> |
// write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); |
1184 |
> |
|
1185 |
|
if ((opcode & 0xF000) == 0xF000) { |
1186 |
|
Exception(0xB,0); |
1187 |
< |
return 4; |
1187 |
> |
return; |
1188 |
|
} |
1189 |
|
|
1190 |
|
write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); |
1191 |
+ |
|
1192 |
|
Exception (4,0); |
1103 |
– |
return 4; |
1193 |
|
} |
1194 |
|
|
1195 |
|
void mmu_op(uae_u32 opcode, uae_u16 extra) |
1208 |
|
|
1209 |
|
static void do_trace (void) |
1210 |
|
{ |
1211 |
< |
if (regs.t0) { |
1211 |
> |
if (regs.t0 && CPUType >= 2) { |
1212 |
|
uae_u16 opcode; |
1213 |
|
/* should also include TRAP, CHK, SR modification FPcc */ |
1214 |
|
/* probably never used so why bother */ |
1245 |
|
static int do_specialties (void) |
1246 |
|
{ |
1247 |
|
/*n_spcinsns++;*/ |
1159 |
– |
run_compiled_code(); |
1248 |
|
if (regs.spcflags & SPCFLAG_DOTRACE) { |
1249 |
|
Exception (9,last_trace_ad); |
1250 |
|
} |
1283 |
|
|
1284 |
|
static void m68k_run_1 (void) |
1285 |
|
{ |
1286 |
< |
for (;;) { |
1287 |
< |
int cycles; |
1288 |
< |
uae_u32 opcode = GET_OPCODE; |
1289 |
< |
#if 0 |
1202 |
< |
if (get_ilong (0) != do_get_mem_long (®s.prefetch)) { |
1203 |
< |
debugging = 1; |
1204 |
< |
return; |
1205 |
< |
} |
1206 |
< |
#endif |
1207 |
< |
/* assert (!regs.stopped && !(regs.spcflags & SPCFLAG_STOP)); */ |
1208 |
< |
/* regs_backup[backup_pointer = (backup_pointer + 1) % 16] = regs;*/ |
1209 |
< |
#if COUNT_INSTRS == 2 |
1210 |
< |
if (table68k[cft_map (opcode)].handler != -1) |
1211 |
< |
instrcount[table68k[cft_map (opcode)].handler]++; |
1212 |
< |
#elif COUNT_INSTRS == 1 |
1213 |
< |
instrcount[opcode]++; |
1286 |
> |
for (;;) { |
1287 |
> |
uae_u32 opcode = GET_OPCODE; |
1288 |
> |
#if FLIGHT_RECORDER |
1289 |
> |
record_step(m68k_getpc()); |
1290 |
|
#endif |
1291 |
< |
#if defined(X86_ASSEMBLYxxx) |
1292 |
< |
__asm__ __volatile__("\tcall *%%ebx" |
1293 |
< |
: "=&a" (cycles) : "b" (cpufunctbl[opcode]), "0" (opcode) |
1294 |
< |
: "%edx", "%ecx", |
1295 |
< |
"%esi", "%edi", "%ebp", "memory", "cc"); |
1220 |
< |
#else |
1221 |
< |
cycles = (*cpufunctbl[opcode])(opcode); |
1222 |
< |
#endif |
1223 |
< |
/*n_insns++;*/ |
1224 |
< |
if (regs.spcflags) { |
1225 |
< |
if (do_specialties ()) |
1226 |
< |
return; |
1291 |
> |
(*cpufunctbl[opcode])(opcode); |
1292 |
> |
if (regs.spcflags) { |
1293 |
> |
if (do_specialties()) |
1294 |
> |
return; |
1295 |
> |
} |
1296 |
|
} |
1228 |
– |
} |
1297 |
|
} |
1298 |
|
|
1231 |
– |
#ifdef X86_ASSEMBLYxxx |
1232 |
– |
static __inline__ void m68k_run1 (void) |
1233 |
– |
{ |
1234 |
– |
/* Work around compiler bug: GCC doesn't push %ebp in m68k_run_1. */ |
1235 |
– |
__asm__ __volatile__ ("pushl %%ebp\n\tcall *%0\n\tpopl %%ebp" : : "r" (m68k_run_1) : "%eax", "%edx", "%ecx", "memory", "cc"); |
1236 |
– |
} |
1237 |
– |
#else |
1299 |
|
#define m68k_run1 m68k_run_1 |
1239 |
– |
#endif |
1300 |
|
|
1301 |
|
int in_m68k_go = 0; |
1302 |
|
|