Annotation of previous/src/m68000.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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