--- BasiliskII/src/uae_cpu/newcpu.cpp 1999/10/28 15:33:23 1.2 +++ BasiliskII/src/uae_cpu/newcpu.cpp 2002/03/16 16:31:54 1.10 @@ -22,7 +22,11 @@ extern int intlev(void); // From baisili #include "memory.h" #include "readcpu.h" #include "newcpu.h" -#include "compiler.h" + +#if ENABLE_MON +#include "mon.h" +#include "mon_disass.h" +#endif int quit_program = 0; int debugging = 0; @@ -48,6 +52,54 @@ int fpp_movem_next[256]; cpuop_func *cpufunctbl[65536]; +#define FLIGHT_RECORDER 0 + +#if FLIGHT_RECORDER +struct rec_step { + uae_u32 d[8]; + uae_u32 a[8]; + uae_u32 pc; +}; + +const int LOG_SIZE = 8192; +static rec_step log[LOG_SIZE]; +static int log_ptr = -1; // First time initialization + +static const char *log_filename(void) +{ + const char *name = getenv("M68K_LOG_FILE"); + return name ? name : "log.68k"; +} + +static void record_step(uaecptr pc) +{ + for (int i = 0; i < 8; i++) { + log[log_ptr].d[i] = m68k_dreg(regs, i); + log[log_ptr].a[i] = m68k_areg(regs, i); + } + log[log_ptr].pc = pc; + log_ptr = (log_ptr + 1) % LOG_SIZE; +} + +static void dump_log(void) +{ + FILE *f = fopen(log_filename(), "w"); + if (f == NULL) + return; + for (int i = 0; i < LOG_SIZE; i++) { + int j = (i + log_ptr) % LOG_SIZE; + fprintf(f, "pc %08x\n", log[j].pc); + 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]); + 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]); + 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]); + 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]); +#if ENABLE_MON + disass_68k(f, log[j].pc); +#endif + } +} +#endif + #define COUNT_INSTRS 0 #if COUNT_INSTRS @@ -111,12 +163,11 @@ static __inline__ unsigned int cft_map ( #endif } -static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; +static void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; -static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) +static void REGPARAM2 op_illg_1 (uae_u32 opcode) { op_illg (cft_map (opcode)); - return 4; } static void build_cpufunctbl (void) @@ -184,8 +235,8 @@ void init_m68k (void) for (j = 7 ; j >= 0 ; j--) { if (i & (1 << j)) break; } - fpp_movem_index1[i] = j; - fpp_movem_index2[i] = 7-j; + fpp_movem_index1[i] = 7-j; + fpp_movem_index2[i] = j; fpp_movem_next[i] = i & (~(1 << j)); } #if COUNT_INSTRS @@ -208,6 +259,14 @@ void init_m68k (void) do_merges (); build_cpufunctbl (); + + fpu_init (); + fpu_set_integral_fpu (CPUType == 4); +} + +void exit_m68k (void) +{ + fpu_exit (); } struct regstruct regs, lastint_regs; @@ -216,9 +275,15 @@ static int backup_pointer = 0; static long int m68kpc_offset; int lastint_no; +#if REAL_ADDRESSING || DIRECT_ADDRESSING +#define get_ibyte_1(o) get_byte(get_virtual_address(regs.pc_p) + (o) + 1) +#define get_iword_1(o) get_word(get_virtual_address(regs.pc_p) + (o)) +#define get_ilong_1(o) get_long(get_virtual_address(regs.pc_p) + (o)) +#else #define get_ibyte_1(o) get_byte(regs.pc + (regs.pc_p - regs.pc_oldp) + (o) + 1) #define get_iword_1(o) get_word(regs.pc + (regs.pc_p - regs.pc_oldp) + (o)) #define get_ilong_1(o) get_long(regs.pc + (regs.pc_p - regs.pc_oldp) + (o)) +#endif uae_s32 ShowEA (int reg, amodes mode, wordsizes size, char *buf) { @@ -251,7 +316,7 @@ uae_s32 ShowEA (int reg, amodes mode, wo disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; addr = m68k_areg(regs,reg) + (uae_s16)disp16; sprintf (buffer,"(A%d,$%04x) == $%08lx", reg, disp16 & 0xffff, - (long unsigned int)addr); + (unsigned long)addr); break; case Ad8r: dp = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; @@ -284,20 +349,20 @@ uae_s32 ShowEA (int reg, amodes mode, wo dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp,outer, - (long unsigned int)addr); + (unsigned long)addr); } else { addr = m68k_areg(regs,reg) + (uae_s32)((uae_s8)disp8) + dispreg; sprintf (buffer,"(A%d, %c%d.%c*%d, $%02x) == $%08lx", reg, dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp8, - (long unsigned int)addr); + (unsigned long)addr); } break; case PC16: addr = m68k_getpc () + m68kpc_offset; disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; addr += (uae_s16)disp16; - sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(long unsigned int)addr); + sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(unsigned long)addr); break; case PC8r: addr = m68k_getpc () + m68kpc_offset; @@ -331,20 +396,20 @@ uae_s32 ShowEA (int reg, amodes mode, wo dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp,outer, - (long unsigned int)addr); + (unsigned long)addr); } else { addr += (uae_s32)((uae_s8)disp8) + dispreg; sprintf (buffer,"(PC, %c%d.%c*%d, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), - disp8, (long unsigned int)addr); + disp8, (unsigned long)addr); } break; case absw: - sprintf (buffer,"$%08lx", (long unsigned int)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); + sprintf (buffer,"$%08lx", (unsigned long)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); m68kpc_offset += 2; break; case absl: - sprintf (buffer,"$%08lx", (long unsigned int)get_ilong_1 (m68kpc_offset)); + sprintf (buffer,"$%08lx", (unsigned long)get_ilong_1 (m68kpc_offset)); m68kpc_offset += 4; break; case imm: @@ -358,7 +423,7 @@ uae_s32 ShowEA (int reg, amodes mode, wo m68kpc_offset += 2; break; case sz_long: - sprintf (buffer,"#$%08lx", (long unsigned int)(get_ilong_1 (m68kpc_offset))); + sprintf (buffer,"#$%08lx", (unsigned long)(get_ilong_1 (m68kpc_offset))); m68kpc_offset += 4; break; default: @@ -378,11 +443,11 @@ uae_s32 ShowEA (int reg, amodes mode, wo case imm2: offset = (uae_s32)get_ilong_1 (m68kpc_offset); m68kpc_offset += 4; - sprintf (buffer,"#$%08lx", (long unsigned int)offset); + sprintf (buffer,"#$%08lx", (unsigned long)offset); break; case immi: offset = (uae_s32)(uae_s8)(reg & 0xff); - sprintf (buffer,"#$%08lx", (long unsigned int)offset); + sprintf (buffer,"#$%08lx", (unsigned long)offset); break; default: break; @@ -646,7 +711,7 @@ void MakeFromSR (void) void Exception(int nr, uaecptr oldpc) { - compiler_flush_jsr_stack(); + uae_u32 currpc = m68k_getpc (); MakeSR(); if (!regs.s) { regs.usp = m68k_areg(regs, 7); @@ -675,7 +740,7 @@ void Exception(int nr, uaecptr oldpc) m68k_areg(regs, 7) -= 2; put_word (m68k_areg(regs, 7), nr * 4); m68k_areg(regs, 7) -= 4; - put_long (m68k_areg(regs, 7), m68k_getpc ()); + put_long (m68k_areg(regs, 7), currpc); m68k_areg(regs, 7) -= 2; put_word (m68k_areg(regs, 7), regs.sr); regs.sr |= (1 << 13); @@ -701,7 +766,7 @@ void Exception(int nr, uaecptr oldpc) } } m68k_areg(regs, 7) -= 4; - put_long (m68k_areg(regs, 7), m68k_getpc ()); + put_long (m68k_areg(regs, 7), currpc); kludge_me_do: m68k_areg(regs, 7) -= 2; put_word (m68k_areg(regs, 7), regs.sr); @@ -724,15 +789,19 @@ static void Interrupt(int nr) static int caar, cacr, tc, itt0, itt1, dtt0, dtt1; -void m68k_move2c (int regno, uae_u32 *regp) +int m68k_move2c (int regno, uae_u32 *regp) { - if (CPUType == 1 && (regno & 0x7FF) > 1) + if ((CPUType == 1 && (regno & 0x7FF) > 1) + || (CPUType < 4 && (regno & 0x7FF) > 2) + || (CPUType == 4 && regno == 0x802)) + { op_illg (0x4E7B); - else + return 0; + } else { switch (regno) { case 0: regs.sfc = *regp & 7; break; case 1: regs.dfc = *regp & 7; break; - case 2: cacr = *regp & 0x3; break; /* ignore C and CE */ + case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); break; case 3: tc = *regp & 0xc000; break; case 4: itt0 = *regp & 0xffffe364; break; case 5: itt1 = *regp & 0xffffe364; break; @@ -745,15 +814,21 @@ void m68k_move2c (int regno, uae_u32 *re case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break; default: op_illg (0x4E7B); - break; + return 0; } + } + return 1; } -void m68k_movec2 (int regno, uae_u32 *regp) +int m68k_movec2 (int regno, uae_u32 *regp) { - if (CPUType == 1 && (regno & 0x7FF) > 1) + if ((CPUType == 1 && (regno & 0x7FF) > 1) + || (CPUType < 4 && (regno & 0x7FF) > 2) + || (CPUType == 4 && regno == 0x802)) + { op_illg (0x4E7A); - else + return 0; + } else { switch (regno) { case 0: *regp = regs.sfc; break; case 1: *regp = regs.dfc; break; @@ -770,8 +845,10 @@ void m68k_movec2 (int regno, uae_u32 *re case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break; default: op_illg (0x4E7A); - break; + return 0; } + } + return 1; } static __inline__ int @@ -1048,24 +1125,35 @@ void m68k_reset (void) regs.spcflags = 0; regs.intmask = 7; regs.vbr = regs.sfc = regs.dfc = 0; - regs.fpcr = regs.fpsr = regs.fpiar = 0; + /* gb-- moved into {fpp,fpu_x86}.cpp::fpu_init() + regs.fpcr = regs.fpsr = regs.fpiar = 0; */ + fpu_reset(); + +#if FLIGHT_RECORDER +#if ENABLE_MON + if (log_ptr == -1) { + // Install "log" command in mon + mon_add_command("log", dump_log, "log Dump m68k emulation log\n"); + } +#endif + log_ptr = 0; + memset(log, 0, sizeof(log)); +#endif } -unsigned long REGPARAM2 op_illg (uae_u32 opcode) +void REGPARAM2 op_illg (uae_u32 opcode) { uaecptr pc = m68k_getpc (); - compiler_flush_jsr_stack (); - if ((opcode & 0xFF00) == 0x7100) { struct M68kRegisters r; int i; - // Return from Execute68k()? + // Return from Exectue68k()? if (opcode == M68K_EXEC_RETURN) { regs.spcflags |= SPCFLAG_BRK; quit_program = 1; - return 4; + return; } // Call EMUL_OP opcode @@ -1084,23 +1172,24 @@ unsigned long REGPARAM2 op_illg (uae_u32 MakeFromSR(); m68k_incpc(2); fill_prefetch_0 (); - return 4; + return; } if ((opcode & 0xF000) == 0xA000) { Exception(0xA,0); - return 4; + return; } -printf("Illegal instruction %04x at %08lx\n", opcode, pc); //!! +// write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); + if ((opcode & 0xF000) == 0xF000) { Exception(0xB,0); - return 4; + return; } write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); + Exception (4,0); - return 4; } void mmu_op(uae_u32 opcode, uae_u16 extra) @@ -1119,7 +1208,7 @@ static uaecptr last_trace_ad = 0; static void do_trace (void) { - if (regs.t0) { + if (regs.t0 && CPUType >= 2) { uae_u16 opcode; /* should also include TRAP, CHK, SR modification FPcc */ /* probably never used so why bother */ @@ -1156,7 +1245,6 @@ static void do_trace (void) static int do_specialties (void) { /*n_spcinsns++;*/ - run_compiled_code(); if (regs.spcflags & SPCFLAG_DOTRACE) { Exception (9,last_trace_ad); } @@ -1195,48 +1283,20 @@ static int do_specialties (void) static void m68k_run_1 (void) { - for (;;) { - int cycles; - uae_u32 opcode = GET_OPCODE; -#if 0 - if (get_ilong (0) != do_get_mem_long (®s.prefetch)) { - debugging = 1; - return; - } -#endif - /* assert (!regs.stopped && !(regs.spcflags & SPCFLAG_STOP)); */ -/* regs_backup[backup_pointer = (backup_pointer + 1) % 16] = regs;*/ -#if COUNT_INSTRS == 2 - if (table68k[cft_map (opcode)].handler != -1) - instrcount[table68k[cft_map (opcode)].handler]++; -#elif COUNT_INSTRS == 1 - instrcount[opcode]++; + for (;;) { + uae_u32 opcode = GET_OPCODE; +#if FLIGHT_RECORDER + record_step(m68k_getpc()); #endif -#if defined(X86_ASSEMBLYxxx) - __asm__ __volatile__("\tcall *%%ebx" - : "=&a" (cycles) : "b" (cpufunctbl[opcode]), "0" (opcode) - : "%edx", "%ecx", - "%esi", "%edi", "%ebp", "memory", "cc"); -#else - cycles = (*cpufunctbl[opcode])(opcode); -#endif - /*n_insns++;*/ - if (regs.spcflags) { - if (do_specialties ()) - return; + (*cpufunctbl[opcode])(opcode); + if (regs.spcflags) { + if (do_specialties()) + return; + } } - } } -#ifdef X86_ASSEMBLYxxx -static __inline__ void m68k_run1 (void) -{ - /* Work around compiler bug: GCC doesn't push %ebp in m68k_run_1. */ - __asm__ __volatile__ ("pushl %%ebp\n\tcall *%0\n\tpopl %%ebp" : : "r" (m68k_run_1) : "%eax", "%edx", "%ecx", "memory", "cc"); -} -#else #define m68k_run1 m68k_run_1 -#endif int in_m68k_go = 0;