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> |
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 |
< |
uae_u32 pc; |
76 |
> |
#endif |
77 |
|
}; |
78 |
|
|
79 |
< |
const int LOG_SIZE = 8192; |
79 |
> |
const int LOG_SIZE = 32768; |
80 |
|
static rec_step log[LOG_SIZE]; |
81 |
|
static int log_ptr = -1; // First time initialization |
82 |
|
|
88 |
|
|
89 |
|
void m68k_record_step(uaecptr pc) |
90 |
|
{ |
91 |
< |
for (int i = 0; i < 8; i++) { |
92 |
< |
log[log_ptr].d[i] = m68k_dreg(regs, i); |
93 |
< |
log[log_ptr].a[i] = m68k_areg(regs, i); |
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 |
|
} |
109 |
|
return; |
110 |
|
for (int i = 0; i < LOG_SIZE; i++) { |
111 |
|
int j = (i + log_ptr) % LOG_SIZE; |
112 |
< |
fprintf(f, "pc %08x\n", log[j].pc); |
113 |
< |
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]); |
114 |
< |
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]); |
115 |
< |
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]); |
116 |
< |
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]); |
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, log[j].pc); |
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 |
200 |
|
#endif |
201 |
|
} |
202 |
|
|
203 |
< |
cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
203 |
> |
void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; |
204 |
|
|
205 |
< |
cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode) |
205 |
> |
void REGPARAM2 op_illg_1 (uae_u32 opcode) |
206 |
|
{ |
207 |
< |
cpuop_return( op_illg (cft_map (opcode)) ); |
207 |
> |
op_illg (cft_map (opcode)); |
208 |
|
} |
209 |
|
|
210 |
|
static void build_cpufunctbl (void) |
825 |
|
|
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 |
|
int m68k_move2c (int regno, uae_u32 *regp) |
853 |
|
{ |
854 |
< |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
794 |
< |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
795 |
< |
|| (CPUType == 4 && regno == 0x802)) |
796 |
< |
{ |
854 |
> |
if (movec_illg (regno)) { |
855 |
|
op_illg (0x4E7B); |
856 |
|
return 0; |
857 |
|
} else { |
867 |
|
flush_icache(1); |
868 |
|
} |
869 |
|
else { |
870 |
< |
set_cache_state((cacr&0x8000) || 0); |
813 |
< |
// FIXME: The User Manual claims bit 3 of CACR is undefined |
814 |
< |
if (*regp & 0x08) |
815 |
< |
flush_icache(2); |
870 |
> |
set_cache_state(cacr&0x8000); |
871 |
|
} |
872 |
|
#endif |
873 |
|
break; |
894 |
|
|
895 |
|
int m68k_movec2 (int regno, uae_u32 *regp) |
896 |
|
{ |
897 |
< |
if ((CPUType == 1 && (regno & 0x7FF) > 1) |
843 |
< |
|| (CPUType < 4 && (regno & 0x7FF) > 2) |
844 |
< |
|| (CPUType == 4 && regno == 0x802)) |
897 |
> |
if (movec_illg (regno)) |
898 |
|
{ |
899 |
|
op_illg (0x4E7A); |
900 |
|
return 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 |
< |
if (log_ptr == -1) { |
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"); |
1159 |
– |
} |
1220 |
|
#endif |
1221 |
< |
log_ptr = 0; |
1162 |
< |
memset(log, 0, sizeof(log)); |
1221 |
> |
} |
1222 |
|
#endif |
1223 |
|
} |
1224 |
|
|
1248 |
|
MakeFromSR(); |
1249 |
|
} |
1250 |
|
|
1251 |
< |
cpuop_rettype REGPARAM2 op_illg (uae_u32 opcode) |
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 |
< |
cpuop_return(CFLOW_TRAP); |
1257 |
> |
return; |
1258 |
|
} |
1259 |
|
|
1260 |
|
if ((opcode & 0xF000) == 0xF000) { |
1261 |
|
Exception(0xB,0); |
1262 |
< |
cpuop_return(CFLOW_TRAP); |
1262 |
> |
return; |
1263 |
|
} |
1264 |
|
|
1265 |
|
write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); |
1268 |
|
#endif |
1269 |
|
|
1270 |
|
Exception (4,0); |
1271 |
< |
cpuop_return(CFLOW_TRAP); |
1271 |
> |
return; |
1272 |
|
} |
1273 |
|
|
1274 |
|
void mmu_op(uae_u32 opcode, uae_u16 extra) |
1366 |
|
} |
1367 |
|
if (SPCFLAGS_TEST( SPCFLAG_BRK )) { |
1368 |
|
SPCFLAGS_CLEAR( SPCFLAG_BRK ); |
1369 |
< |
return CFLOW_EXEC_RETURN; |
1369 |
> |
return 1; |
1370 |
|
} |
1371 |
|
return 0; |
1372 |
|
} |
1379 |
|
m68k_record_step(m68k_getpc()); |
1380 |
|
#endif |
1381 |
|
(*cpufunctbl[opcode])(opcode); |
1382 |
+ |
cpu_check_ticks(); |
1383 |
|
if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) { |
1384 |
|
if (m68k_do_specialties()) |
1385 |
|
return; |
1387 |
|
} |
1388 |
|
} |
1389 |
|
|
1330 |
– |
#if USE_JIT && !defined(X86_ASSEMBLY) |
1331 |
– |
void m68k_compile_execute (void) |
1332 |
– |
{ |
1333 |
– |
for (;;) { |
1334 |
– |
if (quit_program) |
1335 |
– |
break; |
1336 |
– |
m68k_do_compile_execute(); |
1337 |
– |
} |
1338 |
– |
} |
1339 |
– |
#endif |
1340 |
– |
|
1390 |
|
void m68k_execute (void) |
1391 |
|
{ |
1392 |
|
#if USE_JIT |