--- previous/src/m68000.c 2018/04/24 19:25:10 1.1 +++ previous/src/m68000.c 2018/04/24 19:28:49 1.1.1.3 @@ -19,6 +19,9 @@ const char M68000_fileid[] = "Hatari m68 #include "savestate.h" #include "nextMemory.h" +#if ENABLE_WINUAE_CPU +#include "mmu_common.h" +#endif Uint32 BusErrorAddress; /* Stores the offending address for bus-/address errors */ Uint32 BusErrorPC; /* Value of the PC when bus error occurs */ @@ -100,6 +103,7 @@ static void M68000_InitPairing(void) M68000_InitPairing_BitShift ( i_MOVE ); M68000_InitPairing_BitShift ( i_MOVEA ); M68000_InitPairing_BitShift ( i_LEA ); + M68000_InitPairing_BitShift ( i_JMP ); PairingArray[ i_MULU ][ i_MOVEA] = 1; PairingArray[ i_MULS ][ i_MOVEA] = 1; @@ -150,16 +154,26 @@ void M68000_Init(void) */ void M68000_Reset(bool bCold) { - /* Clear registers */ - if (bCold) - { - memset(®s, 0, sizeof(regs)); - } - - /* Now directly reset the UAE CPU core: */ - m68k_reset(); - - BusMode = BUS_MODE_CPU; +#if ENABLE_WINUAE_CPU + if (bCold) + { + /* Clear registers, but we need to keep SPCFLAG_MODE_CHANGE and SPCFLAG_BRK unchanged */ + int spcFlags = regs.spcflags & (SPCFLAG_MODE_CHANGE | SPCFLAG_BRK); + memset(®s, 0, sizeof(regs)); + regs.spcflags = spcFlags; + } + /* Now reset the WINUAE CPU core */ + m68k_reset(bCold); +#else /* UAE CPU core */ + if (bCold) + { + /* Clear registers */ + memset(®s, 0, sizeof(regs)); + } + /* Now reset the UAE CPU core */ + m68k_reset(); +#endif + BusMode = BUS_MODE_CPU; } @@ -185,14 +199,44 @@ void M68000_Start(void) /*-----------------------------------------------------------------------*/ /** - * Check wether the CPU mode has been changed. + * Check whether CPU settings have been changed. */ -void M68000_CheckCpuLevel(void) +void M68000_CheckCpuSettings(void) { + if (ConfigureParams.System.nCpuFreq < 12) + { + ConfigureParams.System.nCpuFreq = 8; + nCpuFreqShift = 0; + } + else if (ConfigureParams.System.nCpuFreq > 26) + { + ConfigureParams.System.nCpuFreq = 32; + nCpuFreqShift = 2; + } + else + { + ConfigureParams.System.nCpuFreq = 16; + nCpuFreqShift = 1; + } changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel; changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu; -#ifndef UAE_NEWCPU_H - changed_prefs.cpu_cycle_exact = 0; // TODO + +#if ENABLE_WINUAE_CPU + switch (changed_prefs.cpu_level) { + case 0 : changed_prefs.cpu_model = 68000; break; + case 1 : changed_prefs.cpu_model = 68010; break; + case 2 : changed_prefs.cpu_model = 68020; break; + case 3 : changed_prefs.cpu_model = 68030; break; + case 4 : changed_prefs.cpu_model = 68040; break; + case 5 : changed_prefs.cpu_model = 68060; break; + default: fprintf (stderr, "Init680x0() : Error, cpu_level unknown\n"); + } + + changed_prefs.address_space_24 = ConfigureParams.System.bAddressSpace24; + changed_prefs.cpu_cycle_exact = ConfigureParams.System.bCycleExactCpu; + changed_prefs.fpu_model = ConfigureParams.System.n_FPUType; + changed_prefs.fpu_strict = ConfigureParams.System.bCompatibleFPU; + changed_prefs.mmu_model = ConfigureParams.System.bMMU; #endif if (table68k) check_prefs_changed_cpu(); @@ -206,6 +250,10 @@ void M68000_CheckCpuLevel(void) void M68000_MemorySnapShot_Capture(bool bSave) { Uint32 savepc; +#if ENABLE_WINUAE_CPU + int len; + uae_u8 *chunk = 0; +#endif /* For the UAE CPU core: */ MemorySnapShot_Store(&currprefs.address_space_24, @@ -235,11 +283,7 @@ void M68000_MemorySnapShot_Capture(bool if (bSave) { -#ifdef UAE_NEWCPU_H MakeSR(); -#else - MakeSR(®s); -#endif if (regs.s) { MemorySnapShot_Store(®s.usp, sizeof(regs.usp)); /* USP */ @@ -262,8 +306,13 @@ void M68000_MemorySnapShot_Capture(bool MemorySnapShot_Store(®s.dfc, sizeof(regs.dfc)); /* DFC */ MemorySnapShot_Store(®s.sfc, sizeof(regs.sfc)); /* SFC */ MemorySnapShot_Store(®s.vbr, sizeof(regs.vbr)); /* VBR */ +#if ENABLE_WINUAE_CPU + MemorySnapShot_Store(®s.caar, sizeof(regs.caar)); /* CAAR */ + MemorySnapShot_Store(®s.cacr, sizeof(regs.cacr)); /* CACR */ +#else MemorySnapShot_Store(&caar, sizeof(caar)); /* CAAR */ MemorySnapShot_Store(&cacr, sizeof(cacr)); /* CACR */ +#endif MemorySnapShot_Store(®s.msp, sizeof(regs.msp)); /* MSP */ if (!bSave) @@ -271,46 +320,50 @@ void M68000_MemorySnapShot_Capture(bool M68000_SetPC(regs.pc); /* MakeFromSR() must not swap stack pointer */ regs.s = (regs.sr >> 13) & 1; -#ifdef UAE_NEWCPU_H MakeFromSR(); /* set stack pointer */ if (regs.s) m68k_areg(regs, 7) = regs.isp; else m68k_areg(regs, 7) = regs.usp; -#else - MakeFromSR(®s); - /* set stack pointer */ - if (regs.s) - m68k_areg(®s, 7) = regs.isp; - else - m68k_areg(®s, 7) = regs.usp; -#endif } +#if ENABLE_WINUAE_CPU + if (bSave) + save_fpu(&len,0); + else + restore_fpu(chunk); +#else if (bSave) save_fpu(); else restore_fpu(); +#endif } /*-----------------------------------------------------------------------*/ /** * BUSERROR - Access outside valid memory range. - * Use bReadWrite = 0 for write errors and bReadWrite = 1 for read errors! + * Use bRead = 0 for write errors and bRead = 1 for read errors! */ -void M68000_BusError(Uint32 addr, bool bReadWrite) +void M68000_BusError(Uint32 addr, bool bRead) { /* FIXME: In prefetch mode, m68k_getpc() seems already to point to the next instruction */ // BusErrorPC = M68000_GetPC(); /* [NP] We set BusErrorPC in m68k_run_1 */ - fprintf(stderr, "M68000 Bus Error at address $%x.\n", addr); - + if ((regs.spcflags & SPCFLAG_BUSERROR) == 0) /* [NP] Check that the opcode has not already generated a read bus error */ { + regs.mmu_fault_addr = addr; BusErrorAddress = addr; /* Store for exception frame */ - bBusErrorReadWrite = bReadWrite; + bBusErrorReadWrite = bRead; +#if ENABLE_WINUAE_CPU + if (currprefs.mmu_model) { + THROW(2); + return; + } +#endif M68000_SetSpecial(SPCFLAG_BUSERROR); /* The exception will be done in newcpu.c */ } } @@ -347,19 +400,23 @@ void M68000_Exception(Uint32 ExceptionVe } /* 68k exceptions are handled by Exception() of the UAE CPU core */ +#if ENABLE_WINUAE_CPU + Exception(exceptionNr, m68k_getpc(), ExceptionSource); +#else #ifdef UAE_NEWCPU_H Exception(exceptionNr, m68k_getpc(), ExceptionSource); #else Exception(exceptionNr, ®s, m68k_getpc(®s)); #endif - +#endif SR = M68000_GetSR(); /* Set Status Register so interrupt can ONLY be stopped by another interrupt * of higher priority! */ + SR = (SR&SR_CLEAR_IPL)|0x0600; /* DSP, level 6 */ - - M68000_SetSR(SR); + + M68000_SetSR(SR); } }