--- previous/src/m68000.c 2018/04/24 19:25:10 1.1.1.1 +++ previous/src/m68000.c 2018/04/24 19:30:01 1.1.1.4 @@ -19,11 +19,13 @@ const char M68000_fileid[] = "Hatari m68 #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 nCpuFreqDivider; /* Used to emulate higher CPU frequencies: 1=8MHz, 2=16MHz, 4=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, ...) */ @@ -100,6 +102,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 +153,26 @@ void M68000_Init(void) */ void M68000_Reset(bool bCold) { - /* Clear registers */ - if (bCold) - { - memset(®s, 0, sizeof(regs)); - } + 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; +} - /* Now directly reset the UAE CPU core: */ - m68k_reset(); - BusMode = BUS_MODE_CPU; +/*-----------------------------------------------------------------------*/ +/** + * Stop 680x0 emulation + */ +void M68000_Stop(void) +{ + M68000_SetSpecial(SPCFLAG_BRK); } @@ -185,15 +198,87 @@ 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 USE_FREQ_DIVIDER + if (ConfigureParams.System.nCpuFreq < 20) + { + ConfigureParams.System.nCpuFreq = 16; + nCpuFreqDivider = 2; + } + else if (ConfigureParams.System.nCpuFreq < 24) + { + ConfigureParams.System.nCpuFreq = 20; + nCpuFreqDivider = 3; + } + else if (ConfigureParams.System.nCpuFreq < 32) + { + ConfigureParams.System.nCpuFreq = 25; + nCpuFreqDivider = 3; + } + else if (ConfigureParams.System.nCpuFreq < 40) + { + ConfigureParams.System.nCpuFreq = 33; + nCpuFreqDivider = 4; + } else { + if (ConfigureParams.System.bTurbo) { + ConfigureParams.System.nCpuFreq = 40; + nCpuFreqDivider = 5; + } else { + ConfigureParams.System.nCpuFreq = 33; + nCpuFreqDivider = 4; + } + } +#else + 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; + } +#endif 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 + + 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"); + } + + changed_prefs.address_space_24 = ConfigureParams.System.bAddressSpace24; + changed_prefs.cpu_cycle_exact = ConfigureParams.System.bCycleExactCpu; + changed_prefs.fpu_strict = ConfigureParams.System.bCompatibleFPU; + changed_prefs.mmu_model = ConfigureParams.System.bMMU?changed_prefs.cpu_model:0; + if (table68k) check_prefs_changed_cpu(); } @@ -206,6 +291,8 @@ void M68000_CheckCpuLevel(void) void M68000_MemorySnapShot_Capture(bool bSave) { Uint32 savepc; + int len; + uae_u8 *chunk = 0; /* For the UAE CPU core: */ MemorySnapShot_Store(&currprefs.address_space_24, @@ -235,11 +322,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 +345,8 @@ 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 */ - MemorySnapShot_Store(&caar, sizeof(caar)); /* CAAR */ - MemorySnapShot_Store(&cacr, sizeof(cacr)); /* CACR */ + MemorySnapShot_Store(®s.caar, sizeof(regs.caar)); /* CAAR */ + MemorySnapShot_Store(®s.cacr, sizeof(regs.cacr)); /* CACR */ MemorySnapShot_Store(®s.msp, sizeof(regs.msp)); /* MSP */ if (!bSave) @@ -271,50 +354,67 @@ 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 (bSave) - save_fpu(); + save_fpu(&len,0); else - restore_fpu(); + restore_fpu(chunk); } /*-----------------------------------------------------------------------*/ /** * 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 /*-----------------------------------------------------------------------*/ /** @@ -347,19 +447,16 @@ 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); } }