Annotation of hatari/src/m68000.c, revision 1.1.1.13

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - m68000.c
1.1       root        3: 
1.1.1.6   root        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:   These routines originally (in WinSTon) handled exceptions as well as some
1.1.1.5   root        8:   few OpCode's such as Line-F and Line-A. In Hatari it has mainly become a
                      9:   wrapper between the WinSTon sources and the UAE CPU code.
1.1       root       10: */
1.1.1.12  root       11: 
                     12: /* 2007/03/xx  [NP]    Possibility to add several wait states for the same instruction in              */
                     13: /*                     M68000_WaitState (e.g. clr.b $fa1b.w in Decade Demo Menu).                      */
                     14: /* 2007/04/14  [NP]    Add support for instruction pairing in M68000_AddCycles, using OpcodeFamily and */
                     15: /*                     LastOpcodeFamily (No Cooper Loader, Oh Crickey ... Hidden Screen).              */
                     16: /* 2007/04/24  [NP]    Add pairing for BCLR/Bcc.                                                       */
                     17: /* 2007/09/29  [NP]    Use the new int.c and INT_CONVERT_TO_INTERNAL.                                  */
                     18: /* 2007/11/26  [NP]    We set BusErrorPC in m68k_run_1 instead of M68000_BusError, else the BusErrorPC */
                     19: /*                     will not point to the opcode that generated the bus error.                      */
                     20: /*                     In M68000_BusError, if we have 'move.l $0,$24', we need to generate a bus error */
                     21: /*                     for the read, not for the write that should occur after (TransBeauce 2 Demo).   */
                     22: /* 2008/01/07  [NP]    Function 'M68000_InitPairing' and 'PairingArray' as a lookup table for fast     */
                     23: /*                     determination of valid pairing combinations (replace lots of 'if' tests in      */
                     24: /*                     m68000.h).                                                                      */
                     25: /* 2008/01/25  [NP]    Add pairing for LSR/MOVE (and all other bit shifting instr) (Anomaly Demo Intro)*/
                     26: /* 2008/02/02  [NP]    Add pairing for CMP/Bcc (Level 16 Fullscreen (1988)).                           */
                     27: /* 2008/02/08  [NP]    Add pairing for LSL/LEA (and all other bit shifting instr) (TVI 2 - The Year    */
                     28: /*                     After Demo).                                                                    */
                     29: /* 2008/02/11  [NP]    Add pairing for MULS/MOVEA (Delirious Demo IV Loader).                          */
                     30: /* 2008/01/25  [NP]    Add pairing for LSR/MOVEA (and all other bit shifting instr) (Decade Demo Reset)*/
1.1.1.13! root       31: /* 2008/02/16  [NP]    Add pairing for MULS/DIVS (fixes e605 demo part 3).                             */
1.1.1.12  root       32: /* 2008/03/08  [NP]    In M68000_Exception, we need to know if the exception was triggered by an MFP   */
                     33: /*                     interrupt or by a video interrupt. In the case MFP vector base was changed in   */
                     34: /*                     fffa17 to an other value than the default $40, testing exceptionNr is not enough*/
                     35: /*                     to correctly process the exception. For example, if vector base is set to $10   */
                     36: /*                     then MFP Timer A will call vector stored at address $74, which would be wrongly */
                     37: /*                     interpreted as a level 5 int (which doesn't exist on Atari and will cause an    */
1.1.1.13! root       38: /*                     assert to fail in intlevel()). We use InterruptSource to correctly recognize the*/
1.1.1.12  root       39: /*                     MFP interrupts (fix 'Toki' end part fullscreen which sets vector base to $10).  */
1.1.1.13! root       40: /* 2008/04/14  [NP]    Add pairing for BTST/Bcc (eg btst #7,d0 + bne.s label  (with branch taken)).    */
        !            41: /* 2008/04/15  [NP]    As tested on a real STF :                                                       */
        !            42: /*                             - MUL/DIV can pair (but DIV/MUL can't)                                  */
        !            43: /*                                     (eg mulu d0,d0 + divs d1,d1 with d0=0 and d1=1)                 */
        !            44: /*                             - MUL/MOVE can pair, but not DIV/MOVE                                   */
        !            45: /*                             - EXG/MOVE can pair (eg exg d3,d4 + move.l 0(a3,d1.w),a4)               */
        !            46: /*                             - MOVE/DBcc can't pair                                                  */
        !            47: /* 2008/04/16  [NP]    Functions 'M68000_InitPairing_BitShift' to ease code maintenance.               */
        !            48: /*                     Tested on STF : add pairing between bit shift instr and ADD/SUB/OR/AND/EOR/NOT  */
        !            49: /*                     CLR/NEG (certainly some more possible, haven't tested everything)               */
        !            50: /*                     (fixes lsr.w #4,d4 + add.b $f0(a4,d4),d7 used in Zoolook part of ULM New Year). */
        !            51: /* 2008/07/08  [NP]    Add pairing between bit shift instr and ADDX/SUBX/ABCD/SBCD (fixes lsl.l #1,d0  */
        !            52: /*                     + abcd d1,d1 used in Dragonnels - Rainbow Wall).                                */
        !            53: /* 2008/10/05  [NP]    Pass the 'ExceptionSource' parameter to Exception() in uae-cpu/newcpu.c         */
1.1.1.12  root       54: 
                     55: 
                     56: 
1.1.1.13! root       57: const char M68000_rcsid[] = "Hatari $Id: m68000.c,v 1.61 2008/10/05 17:55:31 npomarede Exp $";
1.1       root       58: 
                     59: #include "main.h"
1.1.1.12  root       60: #include "configuration.h"
1.1       root       61: #include "gemdos.h"
1.1.1.6   root       62: #include "hatari-glue.h"
1.1       root       63: #include "int.h"
                     64: #include "m68000.h"
                     65: #include "memorySnapShot.h"
                     66: #include "mfp.h"
1.1.1.12  root       67: #include "options.h"
                     68: #include "savestate.h"
1.1       root       69: #include "stMemory.h"
                     70: #include "tos.h"
                     71: 
                     72: 
1.1.1.12  root       73: Uint32 BusErrorAddress;         /* Stores the offending address for bus-/address errors */
                     74: Uint32 BusErrorPC;              /* Value of the PC when bus error occurs */
1.1.1.13! root       75: bool bBusErrorReadWrite;        /* 0 for write error, 1 for read error */
1.1.1.12  root       76: int nCpuFreqShift;              /* Used to emulate higher CPU frequencies: 0=8MHz, 1=16MHz, 2=32Mhz */
                     77: int nWaitStateCycles;           /* Used to emulate the wait state cycles of certain IO registers */
                     78: 
                     79: int LastOpcodeFamily = -1;      /* see the enum in readcpu.h i_XXX */
                     80: int LastInstrCycles = -1;       /* number of cycles for previous instr. (not rounded to 4) */
                     81: int Pairing = 0;                /* set to 1 if the latest 2 intr paired */
                     82: char PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
                     83: 
                     84: 
                     85: /* to convert the enum from OpcodeFamily to a readable value for pairing's debug */
                     86: const char *OpcodeName[] = { "ILLG",
                     87:        "OR","AND","EOR","ORSR","ANDSR","EORSR",
                     88:        "SUB","SUBA","SUBX","SBCD",
                     89:        "ADD","ADDA","ADDX","ABCD",
                     90:        "NEG","NEGX","NBCD","CLR","NOT","TST",
                     91:        "BTST","BCHG","BCLR","BSET",
                     92:        "CMP","CMPM","CMPA",
                     93:        "MVPRM","MVPMR","MOVE","MOVEA","MVSR2","MV2SR",
                     94:        "SWAP","EXG","EXT","MVMEL","MVMLE",
                     95:        "TRAP","MVR2USP","MVUSP2R","RESET","NOP","STOP","RTE","RTD",
                     96:        "LINK","UNLK",
                     97:        "RTS","TRAPV","RTR",
                     98:        "JSR","JMP","BSR","Bcc",
                     99:        "LEA","PEA","DBcc","Scc",
                    100:        "DIVU","DIVS","MULU","MULS",
                    101:        "ASR","ASL","LSR","LSL","ROL","ROR","ROXL","ROXR",
                    102:        "ASRW","ASLW","LSRW","LSLW","ROLW","RORW","ROXLW","ROXRW",
                    103:        "CHK","CHK2",
                    104:        "MOVEC2","MOVE2C","CAS","CAS2","DIVL","MULL",
                    105:        "BFTST","BFEXTU","BFCHG","BFEXTS","BFCLR","BFFFO","BFSET","BFINS",
                    106:        "PACK","UNPK","TAS","BKPT","CALLM","RTM","TRAPcc","MOVES",
                    107:        "FPP","FDBcc","FScc","FTRAPcc","FBcc","FSAVE","FRESTORE",
                    108:        "CINVL","CINVP","CINVA","CPUSHL","CPUSHP","CPUSHA","MOVE16",
                    109:        "MMUOP"
                    110: };
1.1.1.8   root      111: 
1.1.1.12  root      112: 
                    113: /*-----------------------------------------------------------------------*/
                    114: /**
1.1.1.13! root      115:  * Add pairing between all the bit shifting instructions and a given Opcode
        !           116:  */
        !           117: 
        !           118: static void M68000_InitPairing_BitShift ( int OpCode )
        !           119: {
        !           120:        PairingArray[  i_ASR ][ OpCode ] = 1; 
        !           121:        PairingArray[  i_ASL ][ OpCode ] = 1; 
        !           122:        PairingArray[  i_LSR ][ OpCode ] = 1; 
        !           123:        PairingArray[  i_LSL ][ OpCode ] = 1; 
        !           124:        PairingArray[  i_ROL ][ OpCode ] = 1; 
        !           125:        PairingArray[  i_ROR ][ OpCode ] = 1; 
        !           126:        PairingArray[ i_ROXR ][ OpCode ] = 1; 
        !           127:        PairingArray[ i_ROXL ][ OpCode ] = 1; 
        !           128: }
        !           129: 
        !           130: 
        !           131: /*-----------------------------------------------------------------------*/
        !           132: /**
1.1.1.12  root      133:  * Init the pairing matrix
                    134:  * Two instructions can pair if PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1
                    135:  */
                    136: void M68000_InitPairing(void)
                    137: {
                    138:        /* First, clear the matrix (pairing is false) */
                    139:        memset(PairingArray , 0 , MAX_OPCODE_FAMILY * MAX_OPCODE_FAMILY);
                    140: 
                    141:        /* Set all valid pairing combinations to 1 */
                    142:        PairingArray[  i_EXG ][ i_DBcc ] = 1;
1.1.1.13! root      143:        PairingArray[  i_EXG ][ i_MOVE ] = 1;
        !           144:        PairingArray[  i_EXG ][ i_MOVEA] = 1;
        !           145: 
1.1.1.12  root      146:        PairingArray[ i_CMPA ][  i_Bcc ] = 1;
                    147:        PairingArray[  i_CMP ][  i_Bcc ] = 1;
1.1.1.13! root      148: 
        !           149:        M68000_InitPairing_BitShift ( i_DBcc );
        !           150:        M68000_InitPairing_BitShift ( i_MOVE );
        !           151:        M68000_InitPairing_BitShift ( i_MOVEA );
        !           152:        M68000_InitPairing_BitShift ( i_LEA );
        !           153: 
1.1.1.12  root      154:        PairingArray[ i_MULU ][ i_MOVEA] = 1; 
                    155:        PairingArray[ i_MULS ][ i_MOVEA] = 1; 
                    156:        PairingArray[ i_MULU ][ i_MOVE ] = 1; 
                    157:        PairingArray[ i_MULS ][ i_MOVE ] = 1; 
1.1.1.13! root      158: 
        !           159:        PairingArray[ i_MULU ][ i_DIVU ] = 1;
        !           160:        PairingArray[ i_MULU ][ i_DIVS ] = 1;
        !           161:        PairingArray[ i_MULS ][ i_DIVU ] = 1;
        !           162:        PairingArray[ i_MULS ][ i_DIVS ] = 1;
        !           163: 
        !           164:        PairingArray[ i_BTST ][  i_Bcc ] = 1;
        !           165: 
        !           166:        M68000_InitPairing_BitShift ( i_ADD );
        !           167:        M68000_InitPairing_BitShift ( i_SUB );
        !           168:        M68000_InitPairing_BitShift ( i_OR );
        !           169:        M68000_InitPairing_BitShift ( i_AND );
        !           170:        M68000_InitPairing_BitShift ( i_EOR );
        !           171:        M68000_InitPairing_BitShift ( i_NOT );
        !           172:        M68000_InitPairing_BitShift ( i_CLR );
        !           173:        M68000_InitPairing_BitShift ( i_NEG );
        !           174:        M68000_InitPairing_BitShift ( i_ADDX );
        !           175:        M68000_InitPairing_BitShift ( i_SUBX );
        !           176:        M68000_InitPairing_BitShift ( i_ABCD );
        !           177:        M68000_InitPairing_BitShift ( i_SBCD );
1.1.1.12  root      178: }
1.1       root      179: 
                    180: 
1.1.1.3   root      181: /*-----------------------------------------------------------------------*/
1.1.1.12  root      182: /**
                    183:  * Reset CPU 68000 variables
                    184:  */
1.1.1.13! root      185: void M68000_Reset(bool bCold)
1.1       root      186: {
1.1.1.12  root      187:        int i;
                    188: 
                    189:        /* Clear registers */
                    190:        if (bCold)
                    191:        {
                    192:                for (i=0; i<(16+1); i++)
                    193:                        Regs[i] = 0;
                    194:        }
                    195: 
                    196:        /* Now directly reset the UAE CPU core: */
                    197:        m68k_reset();
                    198: 
                    199:        /* Init the pairing matrix */
                    200:        M68000_InitPairing();
                    201: }
                    202: 
                    203: 
                    204: /*-----------------------------------------------------------------------*/
                    205: /**
                    206:  * Reset and start 680x0 emulation
                    207:  */
                    208: void M68000_Start(void)
                    209: {
                    210:        m68k_reset();
1.1       root      211: 
1.1.1.12  root      212:        /* Load initial memory snapshot */
                    213:        if (bLoadMemorySave)
                    214:        {
                    215:                MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName, FALSE);
                    216:        }
                    217:        else if (bLoadAutoSave)
                    218:        {
                    219:                MemorySnapShot_Restore(ConfigureParams.Memory.szAutoSaveFileName, FALSE);
                    220:        }
1.1.1.7   root      221: 
1.1.1.12  root      222:        m68k_go(TRUE);
1.1       root      223: }
                    224: 
1.1.1.3   root      225: 
                    226: /*-----------------------------------------------------------------------*/
1.1.1.12  root      227: /**
                    228:  * Check wether the CPU mode has been changed.
                    229:  */
                    230: void M68000_CheckCpuLevel(void)
                    231: {
                    232:        changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel;
                    233:        changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu;
                    234: #ifndef UAE_NEWCPU_H
                    235:        changed_prefs.cpu_cycle_exact = 0;  // TODO
                    236: #endif
                    237:        if (table68k)
                    238:                check_prefs_changed_cpu();
                    239: }
                    240: 
                    241: 
                    242: /*-----------------------------------------------------------------------*/
                    243: /**
                    244:  * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type)
                    245:  */
1.1.1.13! root      246: void M68000_MemorySnapShot_Capture(bool bSave)
1.1       root      247: {
1.1.1.12  root      248:        Uint32 savepc;
1.1       root      249: 
1.1.1.12  root      250:        /* Save/Restore details */
                    251:        MemorySnapShot_Store(Regs,sizeof(Regs));
                    252:        MemorySnapShot_Store(&STRamEnd,sizeof(STRamEnd));
                    253: 
                    254:        /* For the UAE CPU core: */
                    255:        MemorySnapShot_Store(&currprefs.address_space_24,
                    256:                             sizeof(currprefs.address_space_24));
                    257:        MemorySnapShot_Store(&regs.regs[0], sizeof(regs.regs));       /* D0-D7 A0-A6 */
                    258: 
                    259:        if (bSave)
                    260:        {
                    261:                savepc = M68000_GetPC();
                    262:                MemorySnapShot_Store(&savepc, sizeof(savepc));            /* PC */
                    263:        }
                    264:        else
                    265:        {
                    266:                MemorySnapShot_Store(&savepc, sizeof(savepc));            /* PC */
                    267:                regs.pc = savepc;
                    268: #ifdef UAE_NEWCPU_H
                    269:                regs.prefetch_pc = regs.pc + 128;
                    270: #endif
                    271:        }
1.1.1.8   root      272: 
1.1.1.12  root      273: #ifdef UAE_NEWCPU_H
                    274:        MemorySnapShot_Store(&regs.prefetch, sizeof(regs.prefetch));  /* prefetch */
                    275: #else
                    276:        uae_u32 prefetch_dummy;
                    277:        MemorySnapShot_Store(&prefetch_dummy, sizeof(prefetch_dummy));
                    278: #endif
                    279: 
                    280:        if (bSave)
                    281:        {
                    282: #ifdef UAE_NEWCPU_H
                    283:                MakeSR();
                    284: #else
                    285:                MakeSR(&regs);
                    286: #endif
                    287:                if (regs.s)
                    288:                {
                    289:                        MemorySnapShot_Store(&regs.usp, sizeof(regs.usp));    /* USP */
                    290:                        MemorySnapShot_Store(&regs.regs[15], sizeof(regs.regs[15]));  /* ISP */
                    291:                }
                    292:                else
                    293:                {
                    294:                        MemorySnapShot_Store(&regs.regs[15], sizeof(regs.regs[15]));  /* USP */
                    295:                        MemorySnapShot_Store(&regs.isp, sizeof(regs.isp));    /* ISP */
                    296:                }
                    297:                MemorySnapShot_Store(&regs.sr, sizeof(regs.sr));          /* SR/CCR */
                    298:        }
                    299:        else
                    300:        {
                    301:                MemorySnapShot_Store(&regs.usp, sizeof(regs.usp));
                    302:                MemorySnapShot_Store(&regs.isp, sizeof(regs.isp));
                    303:                MemorySnapShot_Store(&regs.sr, sizeof(regs.sr));
                    304:        }
                    305:        MemorySnapShot_Store(&regs.stopped, sizeof(regs.stopped));
                    306:        MemorySnapShot_Store(&regs.dfc, sizeof(regs.dfc));            /* DFC */
                    307:        MemorySnapShot_Store(&regs.sfc, sizeof(regs.sfc));            /* SFC */
                    308:        MemorySnapShot_Store(&regs.vbr, sizeof(regs.vbr));            /* VBR */
                    309:        MemorySnapShot_Store(&caar, sizeof(caar));                    /* CAAR */
                    310:        MemorySnapShot_Store(&cacr, sizeof(cacr));                    /* CACR */
                    311:        MemorySnapShot_Store(&regs.msp, sizeof(regs.msp));            /* MSP */
                    312: 
                    313:        if (!bSave)
                    314:        {
                    315:                M68000_SetPC(regs.pc);
                    316:                /* MakeFromSR() must not swap stack pointer */
                    317:                regs.s = (regs.sr >> 13) & 1;
                    318: #ifdef UAE_NEWCPU_H
                    319:                MakeFromSR();
                    320:                /* set stack pointer */
                    321:                if (regs.s)
                    322:                        m68k_areg(regs, 7) = regs.isp;
                    323:                else
                    324:                        m68k_areg(regs, 7) = regs.usp;
                    325: #else
                    326:                MakeFromSR(&regs);
                    327:                /* set stack pointer */
                    328:                if (regs.s)
                    329:                        m68k_areg(&regs, 7) = regs.isp;
                    330:                else
                    331:                        m68k_areg(&regs, 7) = regs.usp;
                    332: #endif
                    333:        }
                    334: 
                    335:        if (bSave)
                    336:                save_fpu();
                    337:        else
                    338:                restore_fpu();
1.1       root      339: }
                    340: 
                    341: 
1.1.1.3   root      342: /*-----------------------------------------------------------------------*/
1.1.1.12  root      343: /**
                    344:  * BUSERROR - Access outside valid memory range.
                    345:  * Use bReadWrite = 0 for write errors and bReadWrite = 1 for read errors!
                    346:  */
1.1.1.13! root      347: void M68000_BusError(Uint32 addr, bool bReadWrite)
1.1       root      348: {
1.1.1.12  root      349:        /* FIXME: In prefetch mode, m68k_getpc() seems already to point to the next instruction */
                    350:        // BusErrorPC = M68000_GetPC();         /* [NP] We set BusErrorPC in m68k_run_1 */
1.1.1.7   root      351: 
1.1.1.12  root      352:        if (BusErrorPC < TosAddress || BusErrorPC > TosAddress + TosSize)
                    353:        {
                    354:                /* Print bus errors (except for TOS' hardware tests) */
                    355:                fprintf(stderr, "M68000_BusError at address $%lx\n", (long)addr);
                    356:        }
                    357: 
                    358:        if ((regs.spcflags & SPCFLAG_BUSERROR) == 0)    /* [NP] Check that the opcode has not already generated a read bus error */
                    359:        {
                    360:                BusErrorAddress = addr;                         /* Store for exception frame */
                    361:                bBusErrorReadWrite = bReadWrite;
                    362:                M68000_SetSpecial(SPCFLAG_BUSERROR);            /* The exception will be done in newcpu.c */
                    363:        }
1.1       root      364: }
                    365: 
1.1.1.3   root      366: 
                    367: /*-----------------------------------------------------------------------*/
1.1.1.12  root      368: /**
                    369:  * Exception handler
                    370:  */
1.1.1.13! root      371: void M68000_Exception(Uint32 ExceptionVector , int ExceptionSource)
1.1.1.12  root      372: {
                    373:        int exceptionNr = ExceptionVector/4;
                    374: 
1.1.1.13! root      375:        if ( ( ExceptionSource == M68000_EXCEPTION_SRC_INT_VIDEO )
1.1.1.12  root      376:                && (exceptionNr>24 && exceptionNr<32) ) /* 68k autovector interrupt? */
                    377:        {
                    378:                /* Handle autovector interrupts the UAE's way
                    379:                 * (see intlev() and do_specialties() in UAE CPU core) */
                    380:                /* In our case, this part is only called for HBL and VBL interrupts */
                    381:                int intnr = exceptionNr - 24;
                    382:                pendingInterrupts |= (1 << intnr);
                    383:                M68000_SetSpecial(SPCFLAG_INT);
                    384:        }
1.1.1.13! root      385: 
        !           386:        else                                                    /* MFP or direct CPU exceptions */
1.1.1.12  root      387:        {
                    388:                Uint16 SR;
                    389: 
                    390:                /* Was the CPU stopped, i.e. by a STOP instruction? */
                    391:                if (regs.spcflags & SPCFLAG_STOP)
                    392:                {
                    393:                        regs.stopped = 0;
                    394:                        M68000_UnsetSpecial(SPCFLAG_STOP);    /* All is go,go,go! */
                    395:                }
                    396: 
                    397:                /* 68k exceptions are handled by Exception() of the UAE CPU core */
                    398: #ifdef UAE_NEWCPU_H
1.1.1.13! root      399:                Exception(exceptionNr, m68k_getpc(), ExceptionSource);
1.1.1.12  root      400: #else
                    401:                Exception(exceptionNr, &regs, m68k_getpc(&regs));
                    402: #endif
                    403: 
                    404:                SR = M68000_GetSR();
                    405: 
                    406:                /* Set Status Register so interrupt can ONLY be stopped by another interrupt
                    407:                 * of higher priority! */
1.1.1.6   root      408: #if 0  /* VBL and HBL are handled in the UAE CPU core (see above). */
1.1.1.12  root      409:                if (ExceptionVector == EXCEPTION_VBLANK)
                    410:                        SR = (SR&SR_CLEAR_IPL)|0x0400;  /* VBL, level 4 */
                    411:                else if (ExceptionVector == EXCEPTION_HBLANK)
                    412:                        SR = (SR&SR_CLEAR_IPL)|0x0200;  /* HBL, level 2 */
                    413:                else
                    414: #endif
                    415:                {
                    416:                        Uint32 MFPBaseVector = (unsigned int)(MFP_VR&0xf0)<<2;
                    417:                        if ( (ExceptionVector>=MFPBaseVector) && (ExceptionVector<=(MFPBaseVector+0x3c)) )
                    418:                                SR = (SR&SR_CLEAR_IPL)|0x0600; /* MFP, level 6 */
                    419:                }
                    420: 
                    421:                M68000_SetSR(SR);
                    422:        }
1.1       root      423: }
                    424: 
1.1.1.8   root      425: 
                    426: /*-----------------------------------------------------------------------*/
1.1.1.12  root      427: /**
                    428:  * There seem to be wait states when a program accesses certain hardware
                    429:  * registers on the ST. Use this function to simulate these wait states.
                    430:  * [NP] with some instructions like CLR, we have a read then a write at the
                    431:  * same location, so we may have 2 wait states (read and write) to add
                    432:  * (nWaitStateCycles should be reset to 0 after the cycles were added).
                    433:  */
1.1.1.11  root      434: void M68000_WaitState(int nCycles)
1.1.1.8   root      435: {
1.1.1.12  root      436:        M68000_SetSpecial(SPCFLAG_EXTRA_CYCLES);
1.1.1.11  root      437: 
1.1.1.12  root      438:        nWaitStateCycles += nCycles;    /* add all the wait states for this instruction */
1.1.1.8   root      439: }

unix.superglobalmegacorp.com

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