23 |
|
#include "readcpu.h" |
24 |
|
#include "newcpu.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; |
33 |
|
struct flag_struct regflags; |
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 |
+ |
fclose(f); |
101 |
+ |
} |
102 |
+ |
#endif |
103 |
+ |
|
104 |
|
#define COUNT_INSTRS 0 |
105 |
|
|
106 |
|
#if COUNT_INSTRS |
707 |
|
if (regs.t1 || regs.t0) |
708 |
|
regs.spcflags |= SPCFLAG_TRACE; |
709 |
|
else |
710 |
< |
regs.spcflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE); |
710 |
> |
/* Keep SPCFLAG_DOTRACE, we still want a trace exception for |
711 |
> |
SR-modifying instructions (including STOP). */ |
712 |
> |
regs.spcflags &= ~SPCFLAG_TRACE; |
713 |
|
} |
714 |
|
|
715 |
|
void Exception(int nr, uaecptr oldpc) |
716 |
|
{ |
717 |
+ |
uae_u32 currpc = m68k_getpc (); |
718 |
|
MakeSR(); |
719 |
|
if (!regs.s) { |
720 |
|
regs.usp = m68k_areg(regs, 7); |
743 |
|
m68k_areg(regs, 7) -= 2; |
744 |
|
put_word (m68k_areg(regs, 7), nr * 4); |
745 |
|
m68k_areg(regs, 7) -= 4; |
746 |
< |
put_long (m68k_areg(regs, 7), m68k_getpc ()); |
746 |
> |
put_long (m68k_areg(regs, 7), currpc); |
747 |
|
m68k_areg(regs, 7) -= 2; |
748 |
|
put_word (m68k_areg(regs, 7), regs.sr); |
749 |
|
regs.sr |= (1 << 13); |
769 |
|
} |
770 |
|
} |
771 |
|
m68k_areg(regs, 7) -= 4; |
772 |
< |
put_long (m68k_areg(regs, 7), m68k_getpc ()); |
772 |
> |
put_long (m68k_areg(regs, 7), currpc); |
773 |
|
kludge_me_do: |
774 |
|
m68k_areg(regs, 7) -= 2; |
775 |
|
put_word (m68k_areg(regs, 7), regs.sr); |
790 |
|
regs.spcflags |= SPCFLAG_INT; |
791 |
|
} |
792 |
|
|
793 |
< |
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1; |
793 |
> |
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1, mmusr, urp, srp; |
794 |
|
|
795 |
< |
void m68k_move2c (int regno, uae_u32 *regp) |
795 |
> |
int m68k_move2c (int regno, uae_u32 *regp) |
796 |
|
{ |
797 |
< |
if (CPUType == 1 && (regno & 0x7FF) > 1) |
797 |
> |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
798 |
> |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
799 |
> |
|| (CPUType == 4 && regno == 0x802)) |
800 |
> |
{ |
801 |
|
op_illg (0x4E7B); |
802 |
< |
else |
802 |
> |
return 0; |
803 |
> |
} else { |
804 |
|
switch (regno) { |
805 |
|
case 0: regs.sfc = *regp & 7; break; |
806 |
|
case 1: regs.dfc = *regp & 7; break; |
807 |
< |
case 2: cacr = *regp & 0x3; break; /* ignore C and CE */ |
807 |
> |
case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); break; |
808 |
|
case 3: tc = *regp & 0xc000; break; |
809 |
|
case 4: itt0 = *regp & 0xffffe364; break; |
810 |
|
case 5: itt1 = *regp & 0xffffe364; break; |
815 |
|
case 0x802: caar = *regp &0xfc; break; |
816 |
|
case 0x803: regs.msp = *regp; if (regs.m == 1) m68k_areg(regs, 7) = regs.msp; break; |
817 |
|
case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break; |
818 |
+ |
case 0x805: mmusr = *regp; break; |
819 |
+ |
case 0x806: urp = *regp; break; |
820 |
+ |
case 0x807: srp = *regp; break; |
821 |
|
default: |
822 |
|
op_illg (0x4E7B); |
823 |
< |
break; |
823 |
> |
return 0; |
824 |
|
} |
825 |
+ |
} |
826 |
+ |
return 1; |
827 |
|
} |
828 |
|
|
829 |
< |
void m68k_movec2 (int regno, uae_u32 *regp) |
829 |
> |
int m68k_movec2 (int regno, uae_u32 *regp) |
830 |
|
{ |
831 |
< |
if (CPUType == 1 && (regno & 0x7FF) > 1) |
831 |
> |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
832 |
> |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
833 |
> |
|| (CPUType == 4 && regno == 0x802)) |
834 |
> |
{ |
835 |
|
op_illg (0x4E7A); |
836 |
< |
else |
836 |
> |
return 0; |
837 |
> |
} else { |
838 |
|
switch (regno) { |
839 |
|
case 0: *regp = regs.sfc; break; |
840 |
|
case 1: *regp = regs.dfc; break; |
849 |
|
case 0x802: *regp = caar; break; |
850 |
|
case 0x803: *regp = regs.m == 1 ? m68k_areg(regs, 7) : regs.msp; break; |
851 |
|
case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break; |
852 |
+ |
case 0x805: *regp = mmusr; break; |
853 |
+ |
case 0x806: *regp = urp; break; |
854 |
+ |
case 0x807: *regp = srp; break; |
855 |
|
default: |
856 |
|
op_illg (0x4E7A); |
857 |
< |
break; |
857 |
> |
return 0; |
858 |
|
} |
859 |
+ |
} |
860 |
+ |
return 1; |
861 |
|
} |
862 |
|
|
863 |
|
static __inline__ int |
1137 |
|
/* gb-- moved into {fpp,fpu_x86}.cpp::fpu_init() |
1138 |
|
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) |
1158 |
|
struct M68kRegisters r; |
1159 |
|
int i; |
1160 |
|
|
1161 |
< |
// Return from Execute68k()? |
1161 |
> |
// Return from Exectue68k()? |
1162 |
|
if (opcode == M68K_EXEC_RETURN) { |
1163 |
|
regs.spcflags |= SPCFLAG_BRK; |
1164 |
|
quit_program = 1; |
1203 |
|
|
1204 |
|
void mmu_op(uae_u32 opcode, uae_u16 extra) |
1205 |
|
{ |
1206 |
< |
if ((extra & 0xB000) == 0) { /* PMOVE instruction */ |
1207 |
< |
|
1208 |
< |
} else if ((extra & 0xF000) == 0x2000) { /* PLOAD instruction */ |
1209 |
< |
} else if ((extra & 0xF000) == 0x8000) { /* PTEST instruction */ |
1206 |
> |
if ((opcode & 0xFE0) == 0x0500) { |
1207 |
> |
/* PFLUSH */ |
1208 |
> |
mmusr = 0; |
1209 |
> |
} else if ((opcode & 0x0FD8) == 0x548) { |
1210 |
> |
/* PTEST */ |
1211 |
|
} else |
1212 |
< |
op_illg (opcode); |
1212 |
> |
op_illg (opcode); |
1213 |
|
} |
1214 |
|
|
1215 |
|
static int n_insns = 0, n_spcinsns = 0; |
1218 |
|
|
1219 |
|
static void do_trace (void) |
1220 |
|
{ |
1221 |
< |
if (regs.t0) { |
1221 |
> |
if (regs.t0 && CPUType >= 2) { |
1222 |
|
uae_u16 opcode; |
1223 |
|
/* should also include TRAP, CHK, SR modification FPcc */ |
1224 |
|
/* probably never used so why bother */ |
1295 |
|
{ |
1296 |
|
for (;;) { |
1297 |
|
uae_u32 opcode = GET_OPCODE; |
1298 |
+ |
#if FLIGHT_RECORDER |
1299 |
+ |
record_step(m68k_getpc()); |
1300 |
+ |
#endif |
1301 |
+ |
#ifdef X86_ASSEMBLY |
1302 |
+ |
__asm__ __volatile__("\tpushl %%ebp\n\tcall *%%ebx\n\tpopl %%ebp" /* FIXME */ |
1303 |
+ |
: : "b" (cpufunctbl[opcode]), "a" (opcode) |
1304 |
+ |
: "%edx", "%ecx", "%esi", "%edi", "%ebp", "memory", "cc"); |
1305 |
+ |
#else |
1306 |
|
(*cpufunctbl[opcode])(opcode); |
1307 |
+ |
#endif |
1308 |
|
if (regs.spcflags) { |
1309 |
|
if (do_specialties()) |
1310 |
|
return; |