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

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 "memorySnapShot.h"
                     18: #include "options.h"
                     19: #include "savestate.h"
                     20: #include "nextMemory.h"
                     21: 
1.1.1.3   root       22: #include "mmu_common.h"
1.1       root       23: 
                     24: Uint32 BusErrorAddress;         /* Stores the offending address for bus-/address errors */
                     25: Uint32 BusErrorPC;              /* Value of the PC when bus error occurs */
                     26: bool bBusErrorReadWrite;        /* 0 for write error, 1 for read error */
                     27: int nCpuFreqShift;              /* Used to emulate higher CPU frequencies: 0=8MHz, 1=16MHz, 2=32Mhz */
1.1.1.4 ! root       28: int nCpuFreqDivider;            /* Used to emulate higher CPU frequencies: 1=8MHz, 2=16MHz, 4=32Mhz */
1.1       root       29: int nWaitStateCycles;           /* Used to emulate the wait state cycles of certain IO registers */
                     30: int BusMode = BUS_MODE_CPU;    /* Used to tell which part is owning the bus (cpu, blitter, ...) */
                     31: 
                     32: int LastOpcodeFamily = i_NOP;  /* see the enum in readcpu.h i_XXX */
                     33: int LastInstrCycles = 0;       /* number of cycles for previous instr. (not rounded to 4) */
                     34: int Pairing = 0;               /* set to 1 if the latest 2 intr paired */
                     35: char PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
                     36: 
                     37: 
                     38: /* to convert the enum from OpcodeFamily to a readable value for pairing's debug */
                     39: const char *OpcodeName[] = { "ILLG",
                     40:        "OR","AND","EOR","ORSR","ANDSR","EORSR",
                     41:        "SUB","SUBA","SUBX","SBCD",
                     42:        "ADD","ADDA","ADDX","ABCD",
                     43:        "NEG","NEGX","NBCD","CLR","NOT","TST",
                     44:        "BTST","BCHG","BCLR","BSET",
                     45:        "CMP","CMPM","CMPA",
                     46:        "MVPRM","MVPMR","MOVE","MOVEA","MVSR2","MV2SR",
                     47:        "SWAP","EXG","EXT","MVMEL","MVMLE",
                     48:        "TRAP","MVR2USP","MVUSP2R","RESET","NOP","STOP","RTE","RTD",
                     49:        "LINK","UNLK",
                     50:        "RTS","TRAPV","RTR",
                     51:        "JSR","JMP","BSR","Bcc",
                     52:        "LEA","PEA","DBcc","Scc",
                     53:        "DIVU","DIVS","MULU","MULS",
                     54:        "ASR","ASL","LSR","LSL","ROL","ROR","ROXL","ROXR",
                     55:        "ASRW","ASLW","LSRW","LSLW","ROLW","RORW","ROXLW","ROXRW",
                     56:        "CHK","CHK2",
                     57:        "MOVEC2","MOVE2C","CAS","CAS2","DIVL","MULL",
                     58:        "BFTST","BFEXTU","BFCHG","BFEXTS","BFCLR","BFFFO","BFSET","BFINS",
                     59:        "PACK","UNPK","TAS","BKPT","CALLM","RTM","TRAPcc","MOVES",
                     60:        "FPP","FDBcc","FScc","FTRAPcc","FBcc","FSAVE","FRESTORE",
                     61:        "CINVL","CINVP","CINVA","CPUSHL","CPUSHP","CPUSHA","MOVE16",
                     62:        "MMUOP"
                     63: };
                     64: 
                     65: 
                     66: /*-----------------------------------------------------------------------*/
                     67: /**
                     68:  * Add pairing between all the bit shifting instructions and a given Opcode
                     69:  */
                     70: 
                     71: static void M68000_InitPairing_BitShift ( int OpCode )
                     72: {
                     73:        PairingArray[  i_ASR ][ OpCode ] = 1; 
                     74:        PairingArray[  i_ASL ][ OpCode ] = 1; 
                     75:        PairingArray[  i_LSR ][ OpCode ] = 1; 
                     76:        PairingArray[  i_LSL ][ OpCode ] = 1; 
                     77:        PairingArray[  i_ROL ][ OpCode ] = 1; 
                     78:        PairingArray[  i_ROR ][ OpCode ] = 1; 
                     79:        PairingArray[ i_ROXR ][ OpCode ] = 1; 
                     80:        PairingArray[ i_ROXL ][ OpCode ] = 1; 
                     81: }
                     82: 
                     83: 
                     84: /**
                     85:  * Init the pairing matrix
                     86:  * Two instructions can pair if PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1
                     87:  */
                     88: static void M68000_InitPairing(void)
                     89: {
                     90:        /* First, clear the matrix (pairing is false) */
                     91:        memset(PairingArray , 0 , MAX_OPCODE_FAMILY * MAX_OPCODE_FAMILY);
                     92: 
                     93:        /* Set all valid pairing combinations to 1 */
                     94:        PairingArray[  i_EXG ][ i_DBcc ] = 1;
                     95:        PairingArray[  i_EXG ][ i_MOVE ] = 1;
                     96:        PairingArray[  i_EXG ][ i_MOVEA] = 1;
                     97: 
                     98:        PairingArray[ i_CMPA ][  i_Bcc ] = 1;
                     99:        PairingArray[  i_CMP ][  i_Bcc ] = 1;
                    100: 
                    101:        M68000_InitPairing_BitShift ( i_DBcc );
                    102:        M68000_InitPairing_BitShift ( i_MOVE );
                    103:        M68000_InitPairing_BitShift ( i_MOVEA );
                    104:        M68000_InitPairing_BitShift ( i_LEA );
1.1.1.2   root      105:        M68000_InitPairing_BitShift ( i_JMP );
1.1       root      106: 
                    107:        PairingArray[ i_MULU ][ i_MOVEA] = 1; 
                    108:        PairingArray[ i_MULS ][ i_MOVEA] = 1; 
                    109:        PairingArray[ i_MULU ][ i_MOVE ] = 1; 
                    110:        PairingArray[ i_MULS ][ i_MOVE ] = 1; 
                    111: 
                    112:        PairingArray[ i_MULU ][ i_DIVU ] = 1;
                    113:        PairingArray[ i_MULU ][ i_DIVS ] = 1;
                    114:        PairingArray[ i_MULS ][ i_DIVU ] = 1;
                    115:        PairingArray[ i_MULS ][ i_DIVS ] = 1;
                    116: 
                    117:        PairingArray[ i_BTST ][  i_Bcc ] = 1;
                    118: 
                    119:        M68000_InitPairing_BitShift ( i_ADD );
                    120:        M68000_InitPairing_BitShift ( i_SUB );
                    121:        M68000_InitPairing_BitShift ( i_OR );
                    122:        M68000_InitPairing_BitShift ( i_AND );
                    123:        M68000_InitPairing_BitShift ( i_EOR );
                    124:        M68000_InitPairing_BitShift ( i_NOT );
                    125:        M68000_InitPairing_BitShift ( i_CLR );
                    126:        M68000_InitPairing_BitShift ( i_NEG );
                    127:        M68000_InitPairing_BitShift ( i_ADDX );
                    128:        M68000_InitPairing_BitShift ( i_SUBX );
                    129:        M68000_InitPairing_BitShift ( i_ABCD );
                    130:        M68000_InitPairing_BitShift ( i_SBCD );
                    131: 
                    132:        PairingArray[ i_ADD ][ i_MOVE ] = 1;            /* when using xx(an,dn) addr mode */
                    133:        PairingArray[ i_SUB ][ i_MOVE ] = 1;
                    134: }
                    135: 
                    136: 
                    137: /**
                    138:  * One-time CPU initialization.
                    139:  */
                    140: void M68000_Init(void)
                    141: {
                    142:        /* Init UAE CPU core */
                    143:        Init680x0();
                    144: 
                    145:        /* Init the pairing matrix */
                    146:        M68000_InitPairing();
                    147: }
                    148: 
                    149: 
                    150: /*-----------------------------------------------------------------------*/
                    151: /**
                    152:  * Reset CPU 68000 variables
                    153:  */
                    154: void M68000_Reset(bool bCold)
                    155: {
1.1.1.3   root      156:     if (bCold)
                    157:     {
                    158:         /* Clear registers, but we need to keep SPCFLAG_MODE_CHANGE and SPCFLAG_BRK unchanged */
                    159:         int spcFlags = regs.spcflags & (SPCFLAG_MODE_CHANGE | SPCFLAG_BRK);
                    160:         memset(&regs, 0, sizeof(regs));
                    161:         regs.spcflags = spcFlags;
                    162:     }
                    163:     /* Now reset the WINUAE CPU core */
                    164:     m68k_reset(bCold);
                    165:     BusMode = BUS_MODE_CPU;
1.1       root      166: }
                    167: 
                    168: 
                    169: /*-----------------------------------------------------------------------*/
                    170: /**
1.1.1.4 ! root      171:  * Stop 680x0 emulation
        !           172:  */
        !           173: void M68000_Stop(void)
        !           174: {
        !           175:     M68000_SetSpecial(SPCFLAG_BRK);
        !           176: }
        !           177: 
        !           178: 
        !           179: /*-----------------------------------------------------------------------*/
        !           180: /**
1.1       root      181:  * Start 680x0 emulation
                    182:  */
                    183: void M68000_Start(void)
                    184: {
                    185:        /* Load initial memory snapshot */
                    186:        if (bLoadMemorySave)
                    187:        {
                    188:                MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName, false);
                    189:        }
                    190:        else if (bLoadAutoSave)
                    191:        {
                    192:                MemorySnapShot_Restore(ConfigureParams.Memory.szAutoSaveFileName, false);
                    193:        }
                    194: 
                    195:        m68k_go(true);
                    196: }
                    197: 
                    198: 
                    199: /*-----------------------------------------------------------------------*/
                    200: /**
1.1.1.2   root      201:  * Check whether CPU settings have been changed.
1.1       root      202:  */
1.1.1.2   root      203: void M68000_CheckCpuSettings(void)
1.1       root      204: {
1.1.1.4 ! root      205: #if USE_FREQ_DIVIDER
        !           206:     if (ConfigureParams.System.nCpuFreq < 20)
        !           207:     {
        !           208:         ConfigureParams.System.nCpuFreq = 16;
        !           209:         nCpuFreqDivider = 2;
        !           210:     }
        !           211:     else if (ConfigureParams.System.nCpuFreq < 24)
        !           212:     {
        !           213:         ConfigureParams.System.nCpuFreq = 20;
        !           214:         nCpuFreqDivider = 3;
        !           215:     }
        !           216:     else if (ConfigureParams.System.nCpuFreq < 32)
        !           217:     {
        !           218:         ConfigureParams.System.nCpuFreq = 25;
        !           219:         nCpuFreqDivider = 3;
        !           220:     }
        !           221:     else if (ConfigureParams.System.nCpuFreq < 40)
        !           222:     {
        !           223:         ConfigureParams.System.nCpuFreq = 33;
        !           224:         nCpuFreqDivider = 4;
        !           225:     } else {
        !           226:         if (ConfigureParams.System.bTurbo) {
        !           227:             ConfigureParams.System.nCpuFreq = 40;
        !           228:             nCpuFreqDivider = 5;
        !           229:         } else {
        !           230:             ConfigureParams.System.nCpuFreq = 33;
        !           231:             nCpuFreqDivider = 4;
        !           232:         }
        !           233:     }
        !           234: #else
1.1.1.2   root      235:        if (ConfigureParams.System.nCpuFreq < 12)
                    236:        {
                    237:                ConfigureParams.System.nCpuFreq = 8;
                    238:                nCpuFreqShift = 0;
                    239:        }
                    240:        else if (ConfigureParams.System.nCpuFreq > 26)
                    241:        {
                    242:                ConfigureParams.System.nCpuFreq = 32;
                    243:                nCpuFreqShift = 2;
                    244:        }
                    245:        else
                    246:        {
                    247:                ConfigureParams.System.nCpuFreq = 16;
                    248:                nCpuFreqShift = 1;
                    249:        }
1.1.1.4 ! root      250: #endif
1.1       root      251:        changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel;
                    252:        changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu;
1.1.1.2   root      253: 
                    254:        switch (changed_prefs.cpu_level) {
                    255:                case 0 : changed_prefs.cpu_model = 68000; break;
                    256:                case 1 : changed_prefs.cpu_model = 68010; break;
                    257:                case 2 : changed_prefs.cpu_model = 68020; break;
                    258:                case 3 : changed_prefs.cpu_model = 68030; break;
                    259:                case 4 : changed_prefs.cpu_model = 68040; break;
                    260:                case 5 : changed_prefs.cpu_model = 68060; break;
                    261:                default: fprintf (stderr, "Init680x0() : Error, cpu_level unknown\n");
                    262:        }
                    263: 
1.1.1.4 ! root      264:     changed_prefs.fpu_model = ConfigureParams.System.n_FPUType;
        !           265:     switch (changed_prefs.fpu_model) {
        !           266:         case 68881: changed_prefs.fpu_revision = 0x1f; break;
        !           267:         case 68882: changed_prefs.fpu_revision = 0x20; break;
        !           268:         case 68040:
        !           269:             if (ConfigureParams.System.bTurbo)
        !           270:                 changed_prefs.fpu_revision = 0x41;
        !           271:             else
        !           272:                 changed_prefs.fpu_revision = 0x40;
        !           273:             break;
        !           274:                default: fprintf (stderr, "Init680x0() : Error, fpu_model unknown\n");
        !           275:     }
        !           276: 
1.1.1.2   root      277:        changed_prefs.address_space_24 = ConfigureParams.System.bAddressSpace24;
                    278:        changed_prefs.cpu_cycle_exact = ConfigureParams.System.bCycleExactCpu;
                    279:        changed_prefs.fpu_strict = ConfigureParams.System.bCompatibleFPU;
1.1.1.4 ! root      280:        changed_prefs.mmu_model = ConfigureParams.System.bMMU?changed_prefs.cpu_model:0;
        !           281: 
1.1       root      282:        if (table68k)
                    283:                check_prefs_changed_cpu();
                    284: }
                    285: 
                    286: 
                    287: /*-----------------------------------------------------------------------*/
                    288: /**
                    289:  * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type)
                    290:  */
                    291: void M68000_MemorySnapShot_Capture(bool bSave)
                    292: {
                    293:        Uint32 savepc;
1.1.1.2   root      294:        int len;
                    295:        uae_u8 *chunk = 0;
1.1       root      296: 
                    297:        /* For the UAE CPU core: */
                    298:        MemorySnapShot_Store(&currprefs.address_space_24,
                    299:                             sizeof(currprefs.address_space_24));
                    300:        MemorySnapShot_Store(&regs.regs[0], sizeof(regs.regs));       /* D0-D7 A0-A6 */
                    301: 
                    302:        if (bSave)
                    303:        {
                    304:                savepc = M68000_GetPC();
                    305:                MemorySnapShot_Store(&savepc, sizeof(savepc));            /* PC */
                    306:        }
                    307:        else
                    308:        {
                    309:                MemorySnapShot_Store(&savepc, sizeof(savepc));            /* PC */
                    310:                regs.pc = savepc;
                    311: #ifdef UAE_NEWCPU_H
                    312:                regs.prefetch_pc = regs.pc + 128;
                    313: #endif
                    314:        }
                    315: 
                    316: #ifdef UAE_NEWCPU_H
                    317:        MemorySnapShot_Store(&regs.prefetch, sizeof(regs.prefetch));  /* prefetch */
                    318: #else
                    319:        uae_u32 prefetch_dummy;
                    320:        MemorySnapShot_Store(&prefetch_dummy, sizeof(prefetch_dummy));
                    321: #endif
                    322: 
                    323:        if (bSave)
                    324:        {
                    325:                MakeSR();
                    326:                if (regs.s)
                    327:                {
                    328:                        MemorySnapShot_Store(&regs.usp, sizeof(regs.usp));    /* USP */
                    329:                        MemorySnapShot_Store(&regs.regs[15], sizeof(regs.regs[15]));  /* ISP */
                    330:                }
                    331:                else
                    332:                {
                    333:                        MemorySnapShot_Store(&regs.regs[15], sizeof(regs.regs[15]));  /* USP */
                    334:                        MemorySnapShot_Store(&regs.isp, sizeof(regs.isp));    /* ISP */
                    335:                }
                    336:                MemorySnapShot_Store(&regs.sr, sizeof(regs.sr));          /* SR/CCR */
                    337:        }
                    338:        else
                    339:        {
                    340:                MemorySnapShot_Store(&regs.usp, sizeof(regs.usp));
                    341:                MemorySnapShot_Store(&regs.isp, sizeof(regs.isp));
                    342:                MemorySnapShot_Store(&regs.sr, sizeof(regs.sr));
                    343:        }
                    344:        MemorySnapShot_Store(&regs.stopped, sizeof(regs.stopped));
                    345:        MemorySnapShot_Store(&regs.dfc, sizeof(regs.dfc));            /* DFC */
                    346:        MemorySnapShot_Store(&regs.sfc, sizeof(regs.sfc));            /* SFC */
                    347:        MemorySnapShot_Store(&regs.vbr, sizeof(regs.vbr));            /* VBR */
1.1.1.2   root      348:        MemorySnapShot_Store(&regs.caar, sizeof(regs.caar));          /* CAAR */
                    349:        MemorySnapShot_Store(&regs.cacr, sizeof(regs.cacr));          /* CACR */
1.1       root      350:        MemorySnapShot_Store(&regs.msp, sizeof(regs.msp));            /* MSP */
                    351: 
                    352:        if (!bSave)
                    353:        {
                    354:                M68000_SetPC(regs.pc);
                    355:                /* MakeFromSR() must not swap stack pointer */
                    356:                regs.s = (regs.sr >> 13) & 1;
                    357:                MakeFromSR();
                    358:                /* set stack pointer */
                    359:                if (regs.s)
                    360:                        m68k_areg(regs, 7) = regs.isp;
                    361:                else
                    362:                        m68k_areg(regs, 7) = regs.usp;
                    363:        }
                    364: 
1.1.1.2   root      365:        if (bSave)
                    366:                save_fpu(&len,0);
                    367:        else
                    368:                restore_fpu(chunk);
1.1       root      369: }
                    370: 
                    371: 
                    372: /*-----------------------------------------------------------------------*/
                    373: /**
                    374:  * BUSERROR - Access outside valid memory range.
1.1.1.2   root      375:  * Use bRead = 0 for write errors and bRead = 1 for read errors!
1.1       root      376:  */
1.1.1.2   root      377: void M68000_BusError(Uint32 addr, bool bRead)
1.1       root      378: {
1.1.1.4 ! root      379:        exception2 (addr, bRead, 0, regs.s ? 5 : 1); /* assumes data access,
        !           380:                                                   size not set */
        !           381: }
        !           382: #if 0
        !           383: void M68000_BusError(Uint32 addr, bool bRead)
        !           384: {
1.1       root      385:        /* FIXME: In prefetch mode, m68k_getpc() seems already to point to the next instruction */
                    386:        // BusErrorPC = M68000_GetPC();         /* [NP] We set BusErrorPC in m68k_run_1 */
                    387: 
1.1.1.2   root      388:        
1.1       root      389:        if ((regs.spcflags & SPCFLAG_BUSERROR) == 0)    /* [NP] Check that the opcode has not already generated a read bus error */
                    390:        {
1.1.1.3   root      391:         regs.mmu_fault_addr = addr;
1.1       root      392:                BusErrorAddress = addr;                         /* Store for exception frame */
1.1.1.2   root      393:                bBusErrorReadWrite = bRead;
1.1.1.4 ! root      394: 
1.1.1.3   root      395:         if (currprefs.mmu_model) {
1.1.1.4 ! root      396:             /* This is a hack for the special status word, this needs to be corrected later */
        !           397:             if (ConfigureParams.System.nCpuLevel==3) { /* CPU 68030 */
        !           398:                 int fc = 5; /* hack */
        !           399:                 regs.mmu_ssw = (fc&1) ? MMU030_SSW_DF : (MMU030_SSW_FB|MMU030_SSW_RB);
        !           400:                 regs.mmu_ssw |= bRead ? MMU030_SSW_RW : 0;
        !           401:                 regs.mmu_ssw |= fc&MMU030_SSW_FC_MASK;
        !           402:                 /*switch (size) {
        !           403:                  case 4: regs.mmu_ssw |= MMU030_SSW_SIZE_L; break;
        !           404:                  case 2: regs.mmu_ssw |= MMU030_SSW_SIZE_W; break;
        !           405:                  case 1: regs.mmu_ssw |= MMU030_SSW_SIZE_B; break;
        !           406:                  default: break;
        !           407:                  }*/
        !           408:                 printf("Bus Error: Warning! Using hacked SSW (%04X)!\n", regs.mmu_ssw);
        !           409:             }
1.1.1.3   root      410:             THROW(2);
                    411:             return;
                    412:         }
1.1.1.4 ! root      413: 
1.1       root      414:                M68000_SetSpecial(SPCFLAG_BUSERROR);            /* The exception will be done in newcpu.c */
                    415:        }
                    416: }
1.1.1.4 ! root      417: #endif
1.1       root      418: 
                    419: /*-----------------------------------------------------------------------*/
                    420: /**
                    421:  * Exception handler
                    422:  */
                    423: void M68000_Exception(Uint32 ExceptionVector , int ExceptionSource)
                    424: {
                    425:        int exceptionNr = ExceptionVector/4;
                    426: 
                    427:        if ((ExceptionSource == M68000_EXC_SRC_AUTOVEC)
                    428:                && (exceptionNr>24 && exceptionNr<32))  /* 68k autovector interrupt? */
                    429:        {
                    430:                /* Handle autovector interrupts the UAE's way
                    431:                 * (see intlev() and do_specialties() in UAE CPU core) */
                    432:                /* In our case, this part is only called for HBL and VBL interrupts */
                    433:                int intnr = exceptionNr - 24;
                    434:                pendingInterrupts |= (1 << intnr);
                    435:                M68000_SetSpecial(SPCFLAG_INT);
                    436:        }
                    437: 
                    438:        else                                                    /* MFP or direct CPU exceptions */
                    439:        {
                    440:                Uint16 SR;
                    441: 
                    442:                /* Was the CPU stopped, i.e. by a STOP instruction? */
                    443:                if (regs.spcflags & SPCFLAG_STOP)
                    444:                {
                    445:                        regs.stopped = 0;
                    446:                        M68000_UnsetSpecial(SPCFLAG_STOP);    /* All is go,go,go! */
                    447:                }
                    448: 
                    449:                /* 68k exceptions are handled by Exception() of the UAE CPU core */
1.1.1.4 ! root      450:                Exception(exceptionNr/*, m68k_getpc(), ExceptionSource*/);
        !           451: 
1.1       root      452:                SR = M68000_GetSR();
                    453: 
                    454:                /* Set Status Register so interrupt can ONLY be stopped by another interrupt
                    455:                 * of higher priority! */
1.1.1.2   root      456:                
1.1       root      457:                SR = (SR&SR_CLEAR_IPL)|0x0600;     /* DSP, level 6 */
1.1.1.2   root      458:         
                    459:         M68000_SetSR(SR);
1.1       root      460:        }
                    461: }
                    462: 
                    463: 
                    464: /*-----------------------------------------------------------------------*/
                    465: /**
                    466:  * There seem to be wait states when a program accesses certain hardware
                    467:  * registers on the ST. Use this function to simulate these wait states.
                    468:  * [NP] with some instructions like CLR, we have a read then a write at the
                    469:  * same location, so we may have 2 wait states (read and write) to add
                    470:  * (nWaitStateCycles should be reset to 0 after the cycles were added).
                    471:  */
                    472: void M68000_WaitState(int nCycles)
                    473: {
                    474:        M68000_SetSpecial(SPCFLAG_EXTRA_CYCLES);
                    475: 
                    476:        nWaitStateCycles += nCycles;    /* add all the wait states for this instruction */
                    477: }

unix.superglobalmegacorp.com

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