--- hatari/src/uae-cpu/newcpu.c 2019/04/01 07:09:16 1.1 +++ hatari/src/uae-cpu/newcpu.c 2019/04/01 07:09:48 1.1.1.3 @@ -1,9 +1,12 @@ /* - * UAE - The Un*x Amiga Emulator + * UAE - The Un*x Amiga Emulator - CPU core * * MC68000 emulation * * (c) 1995 Bernd Schmidt + * + * Adaptation to Hatari by Thomas Huth + * */ #include "sysdeps.h" @@ -14,21 +17,14 @@ #include "compiler.h" #include "events.h" #include "../includes/tos.h" -/* -#include "sysconfig.h" -#include "config.h" -#include "options.h" -#include "uae.h" -#include "autoconf.h" -#include "debug.h" -*/ -/*int crashtrace=0;*/ int quit_program = 0; int debugging = 0; struct flag_struct regflags; +int lastInstructionCycles; /* how many cycles last instruction took to execute */ + /* Opcode of faulting instruction */ uae_u16 last_op_for_exception_3; /* PC at fault time */ @@ -159,21 +155,13 @@ static void build_cpufunctbl (void) } /* Hataris illegal opcodes: */ + cpufunctbl[cft_map(GEMDOS_OPCODE)] = OpCode_GemDos; + cpufunctbl[cft_map(RUNOLDGEMDOS_OPCODE)] = OpCode_OldGemDos; cpufunctbl[cft_map(CONDRV_OPCODE)] = OpCode_ConnectedDrive; cpufunctbl[cft_map(TIMERD_OPCODE)] = OpCode_TimerD; } -unsigned long cycles_mask, cycles_val; -static void update_68k_cycles (void) -{ - cycles_mask = 0; - cycles_val = m68k_speed; - if (m68k_speed < 1) { - cycles_mask = 0xFFFFFFFF; - cycles_val = 0; - } -} /* void check_prefs_changed_cpu (void) @@ -196,8 +184,6 @@ void init_m68k (void) { int i; - update_68k_cycles (); - for (i = 0 ; i < 256 ; i++) { int j; for (j = 0 ; j < 8 ; j++) { @@ -703,8 +689,7 @@ void Exception(int nr, uaecptr oldpc) { uae_u32 currpc = m68k_getpc (); - if( nr>=2 && nr<10 ) - fprintf(stderr,"Exception (-> %i bombs)!\n",nr); + /*if( nr>=2 && nr<10 ) fprintf(stderr,"Exception (-> %i bombs)!\n",nr);*/ compiler_flush_jsr_stack(); MakeSR(); @@ -748,26 +733,39 @@ void Exception(int nr, uaecptr oldpc) m68k_areg(regs, 7) -= 2; put_word (m68k_areg(regs, 7), nr * 4); } - } else { - if (nr == 2 || nr == 3) { - /*crashtrace=4;*/ - /*sleep(1);*/ - m68k_areg(regs, 7) -= 12; - /* ??????? */ - if (nr == 3) { - put_long (m68k_areg(regs, 7), last_fault_for_exception_3); - put_word (m68k_areg(regs, 7)+4, last_op_for_exception_3); - put_long (m68k_areg(regs, 7)+8, last_addr_for_exception_3); - } - /*write_log ("UAE CPU Exception.\n");*/ - goto kludge_me_do; - } } + + /* Push PC on stack: */ m68k_areg(regs, 7) -= 4; put_long (m68k_areg(regs, 7), currpc); -kludge_me_do: + /* Push SR on stack: */ m68k_areg(regs, 7) -= 2; put_word (m68k_areg(regs, 7), regs.sr); + + /* 68000 bus/address errors: */ + if (cpu_level==0 && (nr==2 || nr==3)) { + m68k_areg(regs, 7) -= 8; + if (nr == 3) { /* Address error */ + put_word (m68k_areg(regs, 7), regs.sr); /*?*/ + put_long (m68k_areg(regs, 7)+2, last_fault_for_exception_3); + put_word (m68k_areg(regs, 7)+6, last_op_for_exception_3); + put_long (m68k_areg(regs, 7)+10, last_addr_for_exception_3); + if( bEnableDebug ) { + fprintf(stderr,"Address Error at address $%x, PC=$%x\n",last_fault_for_exception_3,currpc); + DebugUI(); + } + } + else { /* Bus error */ + put_word (m68k_areg(regs, 7), regs.sr); /*?*/ + put_long (m68k_areg(regs, 7)+2, BusAddressLocation); + put_word (m68k_areg(regs, 7)+6, get_word(currpc)); + if( bEnableDebug && BusAddressLocation!=0xff8a00) { + fprintf(stderr,"Bus Error at address $%x, PC=$%x\n",BusAddressLocation,currpc); + DebugUI(); + } + } + } + m68k_setpc (get_long (regs.vbr + 4*nr)); fill_prefetch_0 (); regs.t1 = regs.t0 = regs.m = 0; @@ -1112,7 +1110,6 @@ void m68k_reset (void) m68k_areg (regs, 7) = get_long (ROMmem_start); m68k_setpc (get_long (ROMmem_start+4)); fill_prefetch_0 (); - regs.kick_mask = 0xF80000; regs.s = 1; regs.m = 0; regs.stopped = 0; @@ -1190,7 +1187,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 return 4; } -#if 1 +#if 0 write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); #endif Exception (4,0); @@ -1210,7 +1207,6 @@ void mmu_op(uae_u32 opcode, uae_u16 extr op_illg (opcode); } -static int n_insns = 0, n_spcinsns = 0; static uaecptr last_trace_ad = 0; @@ -1252,45 +1248,32 @@ static void do_trace (void) static int do_specialties (void) { -/* - if (regs.spcflags & SPCFLAG_COPPER) - do_copper (); - - //n_spcinsns++; - while (regs.spcflags & SPCFLAG_BLTNASTY) { - do_cycles (4); - if (regs.spcflags & SPCFLAG_COPPER) - do_copper (); - } -*/ run_compiled_code(); if (regs.spcflags & SPCFLAG_DOTRACE) { Exception (9,last_trace_ad); } while (regs.spcflags & SPCFLAG_STOP) { do_cycles (4); - /*if (regs.spcflags & SPCFLAG_COPPER) - do_copper ();*/ if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)){ - int intr = intlev (); + /*int intr = intlev ();*/ unset_special (SPCFLAG_INT | SPCFLAG_DOINT); - if (intr != -1 && intr > regs.intmask) { + /*if (intr != -1 && intr > regs.intmask) { Interrupt (intr); regs.stopped = 0; unset_special (SPCFLAG_STOP); - } + }*/ } } if (regs.spcflags & SPCFLAG_TRACE) do_trace (); if (regs.spcflags & SPCFLAG_DOINT) { - int intr = intlev (); + /*int intr = intlev ();*/ unset_special (SPCFLAG_DOINT); - if (intr != -1 && intr > regs.intmask) { + /*if (intr != -1 && intr > regs.intmask) { Interrupt (intr); regs.stopped = 0; - } + }*/ } if (regs.spcflags & SPCFLAG_INT) { unset_special (SPCFLAG_INT); @@ -1303,6 +1286,7 @@ static int do_specialties (void) return 0; } + /* It's really sad to have two almost identical functions for this, but we do it all for performance... :( */ static void m68k_run_1 (void) @@ -1325,8 +1309,7 @@ static void m68k_run_1 (void) #endif /*m68k_dumpstate(stderr, NULL);*/ - m68k_disasm(stderr, m68k_getpc (), NULL, 1); - /*if( opcode == 0 ) sleep(1);*/ + /*m68k_disasm(stderr, m68k_getpc (), NULL, 1);*/ /* assert (!regs.stopped && !(regs.spcflags & SPCFLAG_STOP)); */ /* regs_backup[backup_pointer = (backup_pointer + 1) % 16] = regs;*/ @@ -1336,14 +1319,9 @@ static void m68k_run_1 (void) #elif COUNT_INSTRS == 1 instrcount[opcode]++; #endif -#if defined X86_ASSEMBLY - __asm__ __volatile__("\tcall *%%ebx" - : "=&a" (cycles) : "b" (cpufunctbl[cft_map(opcode)]), "0" (opcode) - : "%edx", "%ecx", - "%esi", "%edi", "%ebp", "memory", "cc"); -#else + cycles = (*cpufunctbl[cft_map(opcode)])(opcode); -#endif + #ifdef DEBUG_PREFETCH if (memcmp (saved_bytes, oldpcp, 20) != 0) { fprintf (stderr, "Self-modifying code detected.\n"); @@ -1351,9 +1329,7 @@ static void m68k_run_1 (void) debugging = 1; } #endif - /*n_insns++;*/ - /*cycles &= cycles_mask; - cycles |= cycles_val;*/ + do_cycles (cycles); if (regs.spcflags) { if (do_specialties ()) @@ -1376,9 +1352,7 @@ static void m68k_run_2 (void) #endif /*m68k_dumpstate(stderr, NULL);*/ - /*if(crashtrace) - { --crashtrace ; m68k_disasm(stderr, m68k_getpc (), NULL, 1); }*/ - /*if( opcode == 0 ) sleep(1); */ + /*m68k_disasm(stderr, m68k_getpc (), NULL, 1);*/ /* assert (!regs.stopped && !(regs.spcflags & SPCFLAG_STOP)); */ /* regs_backup[backup_pointer = (backup_pointer + 1) % 16] = regs;*/ @@ -1388,18 +1362,9 @@ static void m68k_run_2 (void) #elif COUNT_INSTRS == 1 instrcount[opcode]++; #endif -#if defined X86_ASSEMBLY - __asm__ __volatile__("\tcall *%%ebx" - : "=&a" (cycles) : "b" (cpufunctbl[cft_map(opcode)]), "0" (opcode) - : "%edx", "%ecx", - "%esi", "%edi", "%ebp", "memory", "cc"); -#else + cycles = (*cpufunctbl[cft_map(opcode)])(opcode); -#endif - /*n_insns++;*/ - /*cycles &= cycles_mask; - cycles |= cycles_val;*/ do_cycles (cycles); if (regs.spcflags) { if (do_specialties ()) @@ -1408,16 +1373,6 @@ static void m68k_run_2 (void) } } -#ifdef X86_ASSEMBLY -STATIC_INLINE void m68k_run1 (void (*func)(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" (func) : "%eax", "%edx", "%ecx", "memory", "cc"); -} -#else -#define m68k_run1(F) F() -#endif int in_m68k_go = 0; @@ -1428,26 +1383,16 @@ void m68k_go (int may_quit) abort (); } - /*reset_frame_rate_hack ();*/ - update_68k_cycles (); - in_m68k_go++; while(!quit_program) { /* - if (quit_program > 0) { - if (quit_program == 1) - break; - quit_program = 0; - m68k_reset (); - //reset_all_systems (); - customreset (); - } -*/ -/* if (debugging) debug (); */ - m68k_run1 (cpu_compatible ? m68k_run_1 : m68k_run_2); + if(cpu_compatible) + m68k_run_1(); + else + m68k_run_2(); } in_m68k_go--; }