Annotation of previous_trunk/src/m68000.c, revision 1.1

1.1     ! root        1: /*
        !             2:   Hatari - m68000.c
        !             3: 
        !             4:   This file is distributed under the GNU Public License, version 2 or at
        !             5:   your option any later version. Read the file gpl.txt for details.
        !             6: 
        !             7: */
        !             8: 
        !             9: 
        !            10: const char M68000_fileid[] = "Hatari m68000.c : " __DATE__ " " __TIME__;
        !            11: 
        !            12: #include "main.h"
        !            13: #include "configuration.h"
        !            14: #include "hatari-glue.h"
        !            15: #include "cycInt.h"
        !            16: #include "m68000.h"
        !            17: #include "nextMemory.h"
        !            18: 
        !            19: #include "mmu_common.h"
        !            20: 
        !            21: Uint32 BusErrorAddress;         /* Stores the offending address for bus-/address errors */
        !            22: Uint32 BusErrorPC;              /* Value of the PC when bus error occurs */
        !            23: bool bBusErrorReadWrite;        /* 0 for write error, 1 for read error */
        !            24: int BusMode = BUS_MODE_CPU;    /* Used to tell which part is owning the bus (cpu, blitter, ...) */
        !            25: 
        !            26: int LastOpcodeFamily = i_NOP;  /* see the enum in readcpu.h i_XXX */
        !            27: int LastInstrCycles = 0;       /* number of cycles for previous instr. (not rounded to 4) */
        !            28: int Pairing = 0;               /* set to 1 if the latest 2 intr paired */
        !            29: char PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
        !            30: 
        !            31: 
        !            32: /* to convert the enum from OpcodeFamily to a readable value for pairing's debug */
        !            33: const char *OpcodeName[] = { "ILLG",
        !            34:        "OR","AND","EOR","ORSR","ANDSR","EORSR",
        !            35:        "SUB","SUBA","SUBX","SBCD",
        !            36:        "ADD","ADDA","ADDX","ABCD",
        !            37:        "NEG","NEGX","NBCD","CLR","NOT","TST",
        !            38:        "BTST","BCHG","BCLR","BSET",
        !            39:        "CMP","CMPM","CMPA",
        !            40:        "MVPRM","MVPMR","MOVE","MOVEA","MVSR2","MV2SR",
        !            41:        "SWAP","EXG","EXT","MVMEL","MVMLE",
        !            42:        "TRAP","MVR2USP","MVUSP2R","RESET","NOP","STOP","RTE","RTD",
        !            43:        "LINK","UNLK",
        !            44:        "RTS","TRAPV","RTR",
        !            45:        "JSR","JMP","BSR","Bcc",
        !            46:        "LEA","PEA","DBcc","Scc",
        !            47:        "DIVU","DIVS","MULU","MULS",
        !            48:        "ASR","ASL","LSR","LSL","ROL","ROR","ROXL","ROXR",
        !            49:        "ASRW","ASLW","LSRW","LSLW","ROLW","RORW","ROXLW","ROXRW",
        !            50:        "CHK","CHK2",
        !            51:        "MOVEC2","MOVE2C","CAS","CAS2","DIVL","MULL",
        !            52:        "BFTST","BFEXTU","BFCHG","BFEXTS","BFCLR","BFFFO","BFSET","BFINS",
        !            53:        "PACK","UNPK","TAS","BKPT","CALLM","RTM","TRAPcc","MOVES",
        !            54:        "FPP","FDBcc","FScc","FTRAPcc","FBcc","FSAVE","FRESTORE",
        !            55:        "CINVL","CINVP","CINVA","CPUSHL","CPUSHP","CPUSHA","MOVE16",
        !            56:        "MMUOP"
        !            57: };
        !            58: 
        !            59: 
        !            60: /*-----------------------------------------------------------------------*/
        !            61: /**
        !            62:  * Add pairing between all the bit shifting instructions and a given Opcode
        !            63:  */
        !            64: 
        !            65: static void M68000_InitPairing_BitShift ( int OpCode )
        !            66: {
        !            67:        PairingArray[  i_ASR ][ OpCode ] = 1; 
        !            68:        PairingArray[  i_ASL ][ OpCode ] = 1; 
        !            69:        PairingArray[  i_LSR ][ OpCode ] = 1; 
        !            70:        PairingArray[  i_LSL ][ OpCode ] = 1; 
        !            71:        PairingArray[  i_ROL ][ OpCode ] = 1; 
        !            72:        PairingArray[  i_ROR ][ OpCode ] = 1; 
        !            73:        PairingArray[ i_ROXR ][ OpCode ] = 1; 
        !            74:        PairingArray[ i_ROXL ][ OpCode ] = 1; 
        !            75: }
        !            76: 
        !            77: 
        !            78: /**
        !            79:  * Init the pairing matrix
        !            80:  * Two instructions can pair if PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1
        !            81:  */
        !            82: static void M68000_InitPairing(void)
        !            83: {
        !            84:        /* First, clear the matrix (pairing is false) */
        !            85:        memset(PairingArray , 0 , MAX_OPCODE_FAMILY * MAX_OPCODE_FAMILY);
        !            86: 
        !            87:        /* Set all valid pairing combinations to 1 */
        !            88:        PairingArray[  i_EXG ][ i_DBcc ] = 1;
        !            89:        PairingArray[  i_EXG ][ i_MOVE ] = 1;
        !            90:        PairingArray[  i_EXG ][ i_MOVEA] = 1;
        !            91: 
        !            92:        PairingArray[ i_CMPA ][  i_Bcc ] = 1;
        !            93:        PairingArray[  i_CMP ][  i_Bcc ] = 1;
        !            94: 
        !            95:        M68000_InitPairing_BitShift ( i_DBcc );
        !            96:        M68000_InitPairing_BitShift ( i_MOVE );
        !            97:        M68000_InitPairing_BitShift ( i_MOVEA );
        !            98:        M68000_InitPairing_BitShift ( i_LEA );
        !            99:        M68000_InitPairing_BitShift ( i_JMP );
        !           100: 
        !           101:        PairingArray[ i_MULU ][ i_MOVEA] = 1; 
        !           102:        PairingArray[ i_MULS ][ i_MOVEA] = 1; 
        !           103:        PairingArray[ i_MULU ][ i_MOVE ] = 1; 
        !           104:        PairingArray[ i_MULS ][ i_MOVE ] = 1; 
        !           105: 
        !           106:        PairingArray[ i_MULU ][ i_DIVU ] = 1;
        !           107:        PairingArray[ i_MULU ][ i_DIVS ] = 1;
        !           108:        PairingArray[ i_MULS ][ i_DIVU ] = 1;
        !           109:        PairingArray[ i_MULS ][ i_DIVS ] = 1;
        !           110: 
        !           111:        PairingArray[ i_BTST ][  i_Bcc ] = 1;
        !           112: 
        !           113:        M68000_InitPairing_BitShift ( i_ADD );
        !           114:        M68000_InitPairing_BitShift ( i_SUB );
        !           115:        M68000_InitPairing_BitShift ( i_OR );
        !           116:        M68000_InitPairing_BitShift ( i_AND );
        !           117:        M68000_InitPairing_BitShift ( i_EOR );
        !           118:        M68000_InitPairing_BitShift ( i_NOT );
        !           119:        M68000_InitPairing_BitShift ( i_CLR );
        !           120:        M68000_InitPairing_BitShift ( i_NEG );
        !           121:        M68000_InitPairing_BitShift ( i_ADDX );
        !           122:        M68000_InitPairing_BitShift ( i_SUBX );
        !           123:        M68000_InitPairing_BitShift ( i_ABCD );
        !           124:        M68000_InitPairing_BitShift ( i_SBCD );
        !           125: 
        !           126:        PairingArray[ i_ADD ][ i_MOVE ] = 1;            /* when using xx(an,dn) addr mode */
        !           127:        PairingArray[ i_SUB ][ i_MOVE ] = 1;
        !           128: }
        !           129: 
        !           130: 
        !           131: /**
        !           132:  * One-time CPU initialization.
        !           133:  */
        !           134: void M68000_Init(void)
        !           135: {
        !           136:        /* Init UAE CPU core */
        !           137:        Init680x0();
        !           138: 
        !           139:        /* Init the pairing matrix */
        !           140:        M68000_InitPairing();
        !           141: }
        !           142: 
        !           143: static int pendingInterrupts = 0;
        !           144: 
        !           145: /*-----------------------------------------------------------------------*/
        !           146: /**
        !           147:  * Reset CPU 68000 variables
        !           148:  */
        !           149: void M68000_Reset(bool bCold) {
        !           150:     pendingInterrupts = 0;
        !           151:     if (bCold) {
        !           152:         /* Clear registers, but we need to keep SPCFLAG_MODE_CHANGE and SPCFLAG_BRK unchanged */
        !           153:         int spcFlags = regs.spcflags & (SPCFLAG_MODE_CHANGE | SPCFLAG_BRK);
        !           154:         memset(&regs, 0, sizeof(regs));
        !           155:         regs.spcflags = spcFlags;
        !           156:     }
        !           157:     /* Now reset the WINUAE CPU core */
        !           158:     m68k_reset(bCold);
        !           159:     BusMode = BUS_MODE_CPU;
        !           160: }
        !           161: 
        !           162: 
        !           163: /*-----------------------------------------------------------------------*/
        !           164: /**
        !           165:  * Stop 680x0 emulation
        !           166:  */
        !           167: void M68000_Stop(void)
        !           168: {
        !           169:     M68000_SetSpecial(SPCFLAG_BRK);
        !           170: }
        !           171: 
        !           172: 
        !           173: /*-----------------------------------------------------------------------*/
        !           174: /**
        !           175:  * Start 680x0 emulation
        !           176:  */
        !           177: void M68000_Start(void)
        !           178: {
        !           179:        m68k_go(true);
        !           180: }
        !           181: 
        !           182: 
        !           183: /*-----------------------------------------------------------------------*/
        !           184: /**
        !           185:  * Check whether CPU settings have been changed.
        !           186:  */
        !           187: void M68000_CheckCpuSettings(void)
        !           188: {
        !           189:     if (ConfigureParams.System.nCpuFreq < 20)
        !           190:     {
        !           191:         ConfigureParams.System.nCpuFreq = 16;
        !           192:     }
        !           193:     else if (ConfigureParams.System.nCpuFreq < 24)
        !           194:     {
        !           195:         ConfigureParams.System.nCpuFreq = 20;
        !           196:     }
        !           197:     else if (ConfigureParams.System.nCpuFreq < 32)
        !           198:     {
        !           199:         ConfigureParams.System.nCpuFreq = 25;
        !           200:     }
        !           201:     else if (ConfigureParams.System.nCpuFreq < 40)
        !           202:     {
        !           203:         ConfigureParams.System.nCpuFreq = 33;
        !           204:     } else {
        !           205:         if (ConfigureParams.System.bTurbo) {
        !           206:             ConfigureParams.System.nCpuFreq = 40;
        !           207:         } else {
        !           208:             ConfigureParams.System.nCpuFreq = 33;
        !           209:         }
        !           210:     }
        !           211:        changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel;
        !           212:        changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu;
        !           213: 
        !           214:        switch (changed_prefs.cpu_level) {
        !           215:                case 0 : changed_prefs.cpu_model = 68000; break;
        !           216:                case 1 : changed_prefs.cpu_model = 68010; break;
        !           217:                case 2 : changed_prefs.cpu_model = 68020; break;
        !           218:                case 3 : changed_prefs.cpu_model = 68030; break;
        !           219:                case 4 : changed_prefs.cpu_model = 68040; break;
        !           220:                case 5 : changed_prefs.cpu_model = 68060; break;
        !           221:                default: fprintf (stderr, "Init680x0() : Error, cpu_level unknown\n");
        !           222:        }
        !           223: 
        !           224:     changed_prefs.fpu_model = ConfigureParams.System.n_FPUType;
        !           225:     switch (changed_prefs.fpu_model) {
        !           226:         case 68881: changed_prefs.fpu_revision = 0x1f; break;
        !           227:         case 68882: changed_prefs.fpu_revision = 0x20; break;
        !           228:         case 68040:
        !           229:             if (ConfigureParams.System.bTurbo)
        !           230:                 changed_prefs.fpu_revision = 0x41;
        !           231:             else
        !           232:                 changed_prefs.fpu_revision = 0x40;
        !           233:             break;
        !           234:                default: fprintf (stderr, "Init680x0() : Error, fpu_model unknown\n");
        !           235:     }
        !           236: 
        !           237:        changed_prefs.fpu_strict = ConfigureParams.System.bCompatibleFPU;
        !           238:        changed_prefs.mmu_model = ConfigureParams.System.bMMU?changed_prefs.cpu_model:0;
        !           239: 
        !           240:        if (table68k)
        !           241:                check_prefs_changed_cpu();
        !           242: }
        !           243: 
        !           244: /*-----------------------------------------------------------------------*/
        !           245: /**
        !           246:  * BUSERROR - Access outside valid memory range.
        !           247:  * Use bRead = 0 for write errors and bRead = 1 for read errors!
        !           248:  */
        !           249: void M68000_BusError(Uint32 addr, bool bRead)
        !           250: {
        !           251:        exception2 (addr, bRead, 0, regs.s ? 5 : 1); /* assumes data access,
        !           252:                                                   size not set */
        !           253: }
        !           254: #if 0
        !           255: void M68000_BusError(Uint32 addr, bool bRead)
        !           256: {
        !           257:        /* FIXME: In prefetch mode, m68k_getpc() seems already to point to the next instruction */
        !           258:        // BusErrorPC = M68000_GetPC();         /* [NP] We set BusErrorPC in m68k_run_1 */
        !           259: 
        !           260:        
        !           261:        if ((regs.spcflags & SPCFLAG_BUSERROR) == 0)    /* [NP] Check that the opcode has not already generated a read bus error */
        !           262:        {
        !           263:         regs.mmu_fault_addr = addr;
        !           264:                BusErrorAddress = addr;                         /* Store for exception frame */
        !           265:                bBusErrorReadWrite = bRead;
        !           266: 
        !           267:         if (currprefs.mmu_model) {
        !           268:             /* This is a hack for the special status word, this needs to be corrected later */
        !           269:             if (ConfigureParams.System.nCpuLevel==3) { /* CPU 68030 */
        !           270:                 int fc = 5; /* hack */
        !           271:                 regs.mmu_ssw = (fc&1) ? MMU030_SSW_DF : (MMU030_SSW_FB|MMU030_SSW_RB);
        !           272:                 regs.mmu_ssw |= bRead ? MMU030_SSW_RW : 0;
        !           273:                 regs.mmu_ssw |= fc&MMU030_SSW_FC_MASK;
        !           274:                 /*switch (size) {
        !           275:                  case 4: regs.mmu_ssw |= MMU030_SSW_SIZE_L; break;
        !           276:                  case 2: regs.mmu_ssw |= MMU030_SSW_SIZE_W; break;
        !           277:                  case 1: regs.mmu_ssw |= MMU030_SSW_SIZE_B; break;
        !           278:                  default: break;
        !           279:                  }*/
        !           280:                 printf("Bus Error: Warning! Using hacked SSW (%04X)!\n", regs.mmu_ssw);
        !           281:             }
        !           282:             THROW(2);
        !           283:             return;
        !           284:         }
        !           285: 
        !           286:                M68000_SetSpecial(SPCFLAG_BUSERROR);            /* The exception will be done in newcpu.c */
        !           287:        }
        !           288: }
        !           289: #endif
        !           290: 
        !           291: /*-----------------------------------------------------------------------*/
        !           292: /**
        !           293:  * Exception handler
        !           294:  */
        !           295: void M68000_Exception(Uint32 ExceptionVector , int ExceptionSource)
        !           296: {
        !           297:        int exceptionNr = ExceptionVector/4;
        !           298: 
        !           299:        if ((ExceptionSource == M68000_EXC_SRC_AUTOVEC)
        !           300:                && (exceptionNr>24 && exceptionNr<32))  /* 68k autovector interrupt? */
        !           301:        {
        !           302:                /* Handle autovector interrupts the UAE's way
        !           303:                 * (see intlev() and do_specialties() in UAE CPU core) */
        !           304:                int intnr = exceptionNr - 24;
        !           305:                pendingInterrupts |= (1 << intnr);
        !           306:                M68000_SetSpecial(SPCFLAG_INT);
        !           307:        }
        !           308: 
        !           309:        else                                                    /* direct CPU exceptions */
        !           310:        {
        !           311:                Uint16 SR;
        !           312: 
        !           313:                /* Was the CPU stopped, i.e. by a STOP instruction? */
        !           314:                if (regs.spcflags & SPCFLAG_STOP)
        !           315:                {
        !           316:                        regs.stopped = 0;
        !           317:                        M68000_UnsetSpecial(SPCFLAG_STOP);    /* All is go,go,go! */
        !           318:                }
        !           319: 
        !           320:                /* 68k exceptions are handled by Exception() of the UAE CPU core */
        !           321:                Exception(exceptionNr/*, m68k_getpc(), ExceptionSource*/);
        !           322: 
        !           323:                SR = M68000_GetSR();
        !           324: 
        !           325:                /* Set Status Register so interrupt can ONLY be stopped by another interrupt
        !           326:                 * of higher priority! */
        !           327:                
        !           328:                SR = (SR&SR_CLEAR_IPL)|0x0600;     /* DSP, level 6 */
        !           329:         
        !           330:         M68000_SetSR(SR);
        !           331:        }
        !           332: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.