--- previous/src/m68000.c 2018/04/24 19:25:10 1.1.1.1 +++ previous/src/m68000.c 2018/04/24 19:31:27 1.1.1.5 @@ -14,17 +14,14 @@ const char M68000_fileid[] = "Hatari m68 #include "hatari-glue.h" #include "cycInt.h" #include "m68000.h" -#include "memorySnapShot.h" #include "options.h" -#include "savestate.h" #include "nextMemory.h" +#include "mmu_common.h" Uint32 BusErrorAddress; /* Stores the offending address for bus-/address errors */ Uint32 BusErrorPC; /* Value of the PC when bus error occurs */ bool bBusErrorReadWrite; /* 0 for write error, 1 for read error */ -int nCpuFreqShift; /* Used to emulate higher CPU frequencies: 0=8MHz, 1=16MHz, 2=32Mhz */ -int nWaitStateCycles; /* Used to emulate the wait state cycles of certain IO registers */ int BusMode = BUS_MODE_CPU; /* Used to tell which part is owning the bus (cpu, blitter, ...) */ int LastOpcodeFamily = i_NOP; /* see the enum in readcpu.h i_XXX */ @@ -100,6 +97,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; @@ -143,178 +141,153 @@ void M68000_Init(void) M68000_InitPairing(); } +static int pendingInterrupts = 0; /*-----------------------------------------------------------------------*/ /** * Reset CPU 68000 variables */ -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; +void M68000_Reset(bool bCold) { + pendingInterrupts = 0; + 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); + BusMode = BUS_MODE_CPU; } /*-----------------------------------------------------------------------*/ /** - * Start 680x0 emulation + * Stop 680x0 emulation */ -void M68000_Start(void) +void M68000_Stop(void) { - /* Load initial memory snapshot */ - if (bLoadMemorySave) - { - MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName, false); - } - else if (bLoadAutoSave) - { - MemorySnapShot_Restore(ConfigureParams.Memory.szAutoSaveFileName, false); - } - - m68k_go(true); + M68000_SetSpecial(SPCFLAG_BRK); } /*-----------------------------------------------------------------------*/ /** - * Check wether the CPU mode has been changed. + * Start 680x0 emulation */ -void M68000_CheckCpuLevel(void) +void M68000_Start(void) { - 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 -#endif - if (table68k) - check_prefs_changed_cpu(); + m68k_go(true); } /*-----------------------------------------------------------------------*/ /** - * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type) + * Check whether CPU settings have been changed. */ -void M68000_MemorySnapShot_Capture(bool bSave) +void M68000_CheckCpuSettings(void) { - Uint32 savepc; - - /* For the UAE CPU core: */ - MemorySnapShot_Store(&currprefs.address_space_24, - sizeof(currprefs.address_space_24)); - MemorySnapShot_Store(®s.regs[0], sizeof(regs.regs)); /* D0-D7 A0-A6 */ + if (ConfigureParams.System.nCpuFreq < 20) + { + ConfigureParams.System.nCpuFreq = 16; + } + else if (ConfigureParams.System.nCpuFreq < 24) + { + ConfigureParams.System.nCpuFreq = 20; + } + else if (ConfigureParams.System.nCpuFreq < 32) + { + ConfigureParams.System.nCpuFreq = 25; + } + else if (ConfigureParams.System.nCpuFreq < 40) + { + ConfigureParams.System.nCpuFreq = 33; + } else { + if (ConfigureParams.System.bTurbo) { + ConfigureParams.System.nCpuFreq = 40; + } else { + ConfigureParams.System.nCpuFreq = 33; + } + } + changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel; + changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu; - if (bSave) - { - savepc = M68000_GetPC(); - MemorySnapShot_Store(&savepc, sizeof(savepc)); /* PC */ - } - else - { - MemorySnapShot_Store(&savepc, sizeof(savepc)); /* PC */ - regs.pc = savepc; -#ifdef UAE_NEWCPU_H - regs.prefetch_pc = regs.pc + 128; -#endif - } + 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.fpu_model = ConfigureParams.System.n_FPUType; + switch (changed_prefs.fpu_model) { + case 68881: changed_prefs.fpu_revision = 0x1f; break; + case 68882: changed_prefs.fpu_revision = 0x20; break; + case 68040: + if (ConfigureParams.System.bTurbo) + changed_prefs.fpu_revision = 0x41; + else + changed_prefs.fpu_revision = 0x40; + break; + default: fprintf (stderr, "Init680x0() : Error, fpu_model unknown\n"); + } -#ifdef UAE_NEWCPU_H - MemorySnapShot_Store(®s.prefetch, sizeof(regs.prefetch)); /* prefetch */ -#else - uae_u32 prefetch_dummy; - MemorySnapShot_Store(&prefetch_dummy, sizeof(prefetch_dummy)); -#endif + changed_prefs.fpu_strict = ConfigureParams.System.bCompatibleFPU; + changed_prefs.mmu_model = ConfigureParams.System.bMMU?changed_prefs.cpu_model:0; - if (bSave) - { -#ifdef UAE_NEWCPU_H - MakeSR(); -#else - MakeSR(®s); -#endif - if (regs.s) - { - MemorySnapShot_Store(®s.usp, sizeof(regs.usp)); /* USP */ - MemorySnapShot_Store(®s.regs[15], sizeof(regs.regs[15])); /* ISP */ - } - else - { - MemorySnapShot_Store(®s.regs[15], sizeof(regs.regs[15])); /* USP */ - MemorySnapShot_Store(®s.isp, sizeof(regs.isp)); /* ISP */ - } - MemorySnapShot_Store(®s.sr, sizeof(regs.sr)); /* SR/CCR */ - } - else - { - MemorySnapShot_Store(®s.usp, sizeof(regs.usp)); - MemorySnapShot_Store(®s.isp, sizeof(regs.isp)); - MemorySnapShot_Store(®s.sr, sizeof(regs.sr)); - } - MemorySnapShot_Store(®s.stopped, sizeof(regs.stopped)); - MemorySnapShot_Store(®s.dfc, sizeof(regs.dfc)); /* DFC */ - MemorySnapShot_Store(®s.sfc, sizeof(regs.sfc)); /* SFC */ - MemorySnapShot_Store(®s.vbr, sizeof(regs.vbr)); /* VBR */ - MemorySnapShot_Store(&caar, sizeof(caar)); /* CAAR */ - MemorySnapShot_Store(&cacr, sizeof(cacr)); /* CACR */ - MemorySnapShot_Store(®s.msp, sizeof(regs.msp)); /* MSP */ - - if (!bSave) - { - 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 (bSave) - save_fpu(); - else - restore_fpu(); + if (table68k) + check_prefs_changed_cpu(); } - /*-----------------------------------------------------------------------*/ /** * 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) +{ + exception2 (addr, bRead, 0, regs.s ? 5 : 1); /* assumes data access, + size not set */ +} +#if 0 +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 (currprefs.mmu_model) { + /* This is a hack for the special status word, this needs to be corrected later */ + if (ConfigureParams.System.nCpuLevel==3) { /* CPU 68030 */ + int fc = 5; /* hack */ + regs.mmu_ssw = (fc&1) ? MMU030_SSW_DF : (MMU030_SSW_FB|MMU030_SSW_RB); + regs.mmu_ssw |= bRead ? MMU030_SSW_RW : 0; + regs.mmu_ssw |= fc&MMU030_SSW_FC_MASK; + /*switch (size) { + case 4: regs.mmu_ssw |= MMU030_SSW_SIZE_L; break; + case 2: regs.mmu_ssw |= MMU030_SSW_SIZE_W; break; + case 1: regs.mmu_ssw |= MMU030_SSW_SIZE_B; break; + default: break; + }*/ + printf("Bus Error: Warning! Using hacked SSW (%04X)!\n", regs.mmu_ssw); + } + THROW(2); + return; + } + M68000_SetSpecial(SPCFLAG_BUSERROR); /* The exception will be done in newcpu.c */ } } - +#endif /*-----------------------------------------------------------------------*/ /** @@ -329,13 +302,12 @@ void M68000_Exception(Uint32 ExceptionVe { /* Handle autovector interrupts the UAE's way * (see intlev() and do_specialties() in UAE CPU core) */ - /* In our case, this part is only called for HBL and VBL interrupts */ int intnr = exceptionNr - 24; pendingInterrupts |= (1 << intnr); M68000_SetSpecial(SPCFLAG_INT); } - else /* MFP or direct CPU exceptions */ + else /* direct CPU exceptions */ { Uint16 SR; @@ -347,34 +319,15 @@ void M68000_Exception(Uint32 ExceptionVe } /* 68k exceptions are handled by Exception() of the UAE CPU core */ -#ifdef UAE_NEWCPU_H - Exception(exceptionNr, m68k_getpc(), ExceptionSource); -#else - Exception(exceptionNr, ®s, m68k_getpc(®s)); -#endif + Exception(exceptionNr/*, m68k_getpc(), ExceptionSource*/); 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); } -} - - -/*-----------------------------------------------------------------------*/ -/** - * There seem to be wait states when a program accesses certain hardware - * registers on the ST. Use this function to simulate these wait states. - * [NP] with some instructions like CLR, we have a read then a write at the - * same location, so we may have 2 wait states (read and write) to add - * (nWaitStateCycles should be reset to 0 after the cycles were added). - */ -void M68000_WaitState(int nCycles) -{ - M68000_SetSpecial(SPCFLAG_EXTRA_CYCLES); - - nWaitStateCycles += nCycles; /* add all the wait states for this instruction */ -} +} \ No newline at end of file