Annotation of hatari/src/includes/m68000.h, revision 1.1.1.11

1.1       root        1: /*
1.1.1.5   root        2:   Hatari - m68000.h
                      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.
1.1       root        6: */
                      7: 
1.1.1.10  root        8: /* 2007/11/10  [NP]    Add pairing for lsr / dbcc (and all variants    */
                      9: /*                     working on register, not on memory).            */
                     10: /* 2008/01/07  [NP]    Use PairingArray to store all valid pairing     */
                     11: /*                     combinations (in m68000.c)                      */
                     12: 
1.1.1.5   root       13: #ifndef HATARI_M68000_H
                     14: #define HATARI_M68000_H
                     15: 
1.1.1.9   root       16: #include "cycles.h"     /* for nCyclesMainCounter */
1.1.1.6   root       17: #include "sysdeps.h"
                     18: #include "memory.h"
1.1.1.9   root       19: #include "newcpu.h"     /* for regs */
1.1.1.10  root       20: #include "int.h"
1.1.1.11! root       21: #include "log.h"
        !            22: 
        !            23: 
        !            24: /* 68000 Register defines */
        !            25: enum {
        !            26:   REG_D0,    /* D0.. */
        !            27:   REG_D1,
        !            28:   REG_D2,
        !            29:   REG_D3,
        !            30:   REG_D4,
        !            31:   REG_D5,
        !            32:   REG_D6,
        !            33:   REG_D7,    /* ..D7 */
        !            34:   REG_A0,    /* A0.. */
        !            35:   REG_A1,
        !            36:   REG_A2,
        !            37:   REG_A3,
        !            38:   REG_A4,
        !            39:   REG_A5,
        !            40:   REG_A6,
        !            41:   REG_A7,    /* ..A7 (also SP) */
        !            42: };
        !            43: 
        !            44: /* 68000 Condition code's */
        !            45: #define SR_AUX              0x0010
        !            46: #define SR_NEG              0x0008
        !            47: #define SR_ZERO             0x0004
        !            48: #define SR_OVERFLOW         0x0002
        !            49: #define SR_CARRY            0x0001
        !            50: 
        !            51: #define SR_CLEAR_AUX        0xffef
        !            52: #define SR_CLEAR_NEG        0xfff7
        !            53: #define SR_CLEAR_ZERO       0xfffb
        !            54: #define SR_CLEAR_OVERFLOW   0xfffd
        !            55: #define SR_CLEAR_CARRY      0xfffe
        !            56: 
        !            57: #define SR_CCODE_MASK       (SR_AUX|SR_NEG|SR_ZERO|SR_OVERFLOW|SR_CARRY)
        !            58: #define SR_MASK             0xFFE0
        !            59: 
        !            60: #define SR_TRACEMODE        0x8000
        !            61: #define SR_SUPERMODE        0x2000
        !            62: #define SR_IPL              0x0700
        !            63: 
        !            64: #define SR_CLEAR_IPL        0xf8ff
        !            65: #define SR_CLEAR_TRACEMODE  0x7fff
        !            66: #define SR_CLEAR_SUPERMODE  0xdfff
        !            67: 
        !            68: /* Exception vectors */
        !            69: #define  EXCEPTION_BUSERROR   0x00000008
        !            70: #define  EXCEPTION_ADDRERROR  0x0000000c
        !            71: #define  EXCEPTION_ILLEGALINS 0x00000010
        !            72: #define  EXCEPTION_DIVZERO    0x00000014
        !            73: #define  EXCEPTION_CHK        0x00000018
        !            74: #define  EXCEPTION_TRAPV      0x0000001c
        !            75: #define  EXCEPTION_TRACE      0x00000024
        !            76: #define  EXCEPTION_LINE_A     0x00000028
        !            77: #define  EXCEPTION_LINE_F     0x0000002c
        !            78: #define  EXCEPTION_HBLANK     0x00000068
        !            79: #define  EXCEPTION_VBLANK     0x00000070
        !            80: #define  EXCEPTION_TRAP0      0x00000080
        !            81: #define  EXCEPTION_TRAP1      0x00000084
        !            82: #define  EXCEPTION_TRAP2      0x00000088
        !            83: #define  EXCEPTION_TRAP13     0x000000B4
        !            84: #define  EXCEPTION_TRAP14     0x000000B8
        !            85: 
        !            86: 
        !            87: /* Size of 68000 instructions */
        !            88: #define MAX_68000_INSTRUCTION_SIZE  10  /* Longest 68000 instruction is 10 bytes(6+4) */
        !            89: #define MIN_68000_INSTRUCTION_SIZE  2   /* Smallest 68000 instruction is 2 bytes(ie NOP) */
        !            90: 
        !            91: /* Illegal Opcode used to help emulation. eg. free entries are 8 to 15 inc' */
        !            92: #define  GEMDOS_OPCODE        8  /* Free op-code to intercept GemDOS trap */
        !            93: #define  SYSINIT_OPCODE      10  /* Free op-code to initialize system (connected drives etc.) */
        !            94: #define  VDI_OPCODE          12  /* Free op-code to call VDI handlers AFTER Trap#2 */
        !            95: 
1.1.1.10  root       96: 
                     97: 
                     98: /* Ugly hacks to adapt the main code to the different CPU cores: */
                     99: 
                    100: #define Regs regs.regs
                    101: 
                    102: #if defined(UAE_NEWCPU_H)
                    103: 
                    104: # define M68000_GetPC()     m68k_getpc()
                    105: # define M68000_SetPC(val)  m68k_setpc(val)
                    106: 
                    107: static inline Uint16 M68000_GetSR(void)
                    108: {
                    109:        MakeSR();
                    110:        return regs.sr;
                    111: }
                    112: static inline void M68000_SetSR(Uint16 v)
                    113: {
                    114:        regs.sr = v;
                    115:        MakeFromSR();
                    116: }
                    117: 
                    118: # define M68000_SetSpecial(flags)   set_special(flags)
                    119: # define M68000_UnsetSpecial(flags) unset_special(flags)
                    120: 
                    121: #else  /* following code is for WinUAE CPU: */
                    122: 
                    123: # define M68000_GetPC()     m68k_getpc(&regs)
                    124: # define M68000_SetPC(val)  m68k_setpc(&regs,val)
1.1.1.6   root      125: 
1.1.1.10  root      126: static inline Uint16 M68000_GetSR(void)
                    127: {
                    128:        MakeSR(&regs);
                    129:        return regs.sr;
                    130: }
                    131: static inline void M68000_SetSR(Uint16 v)
                    132: {
                    133:        regs.sr = v;
                    134:        MakeFromSR(&regs);
                    135: }
                    136: 
                    137: # define M68000_SetSpecial(flags)   set_special(&regs,flags)
                    138: # define M68000_UnsetSpecial(flags) unset_special(&regs,flags)
                    139: 
                    140: #endif /* defined(UAE_NEWCPU_H) */
                    141: 
                    142: 
                    143: #define FIND_IPL    ((regs.intmask)&0x7)
1.1.1.6   root      144: 
                    145: 
1.1.1.9   root      146: /* bus error mode */
                    147: #define BUS_ERROR_WRITE 0
                    148: #define BUS_ERROR_READ 1
                    149: 
1.1.1.10  root      150: 
1.1.1.7   root      151: extern Uint32 BusErrorAddress;
1.1.1.5   root      152: extern Uint32 BusErrorPC;
1.1.1.11! root      153: extern bool bBusErrorReadWrite;
1.1.1.7   root      154: extern int nCpuFreqShift;
1.1.1.9   root      155: extern int nWaitStateCycles;
1.1.1.6   root      156: 
1.1.1.10  root      157: extern int     LastOpcodeFamily;
                    158: extern int     LastInstrCycles;
                    159: extern int     Pairing;
                    160: extern char    PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
                    161: extern const char *OpcodeName[];
                    162: 
1.1.1.6   root      163: 
                    164: /*-----------------------------------------------------------------------*/
1.1.1.10  root      165: /**
                    166:  * Add CPU cycles.
                    167:  * NOTE: All times are rounded up to nearest 4 cycles.
                    168:  */
1.1.1.6   root      169: static inline void M68000_AddCycles(int cycles)
                    170: {
1.1.1.10  root      171:        cycles = (cycles + 3) & ~3;
                    172:        cycles = cycles >> nCpuFreqShift;
                    173: 
                    174:        PendingInterruptCount -= INT_CONVERT_TO_INTERNAL(cycles, INT_CPU_CYCLE);
1.1.1.9   root      175:        nCyclesMainCounter += cycles;
1.1.1.6   root      176: }
1.1.1.5   root      177: 
1.1.1.10  root      178: 
                    179: /*-----------------------------------------------------------------------*/
                    180: /**
                    181:  * Add CPU cycles, take cycles pairing into account.
                    182:  * NOTE: All times are rounded up to nearest 4 cycles.
                    183:  */
                    184: static inline void M68000_AddCyclesWithPairing(int cycles)
                    185: {
                    186:        Pairing = 0;
                    187:        /* Check if number of cycles for current instr and for */
                    188:        /* the previous one is of the form 4+2n */
                    189:        /* If so, a pairing could be possible depending on the opcode */
                    190:        if ( ( PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1 )
                    191:            && ( ( cycles & 3 ) == 2 ) && ( ( LastInstrCycles & 3 ) == 2 ) )
                    192:        {
                    193:                Pairing = 1;
                    194:                HATARI_TRACE( HATARI_TRACE_CPU_PAIRING ,
                    195:                              "pairing detected pc=%x family %s/%s cycles %d/%d\n" ,
                    196:                              m68k_getpc(), OpcodeName[LastOpcodeFamily] ,
                    197:                              OpcodeName[OpcodeFamily], LastInstrCycles, cycles );
                    198:        }
                    199: 
1.1.1.11! root      200:        /* [NP] This part is only needed to track possible pairing instructions, */
        !           201:        /* we can keep it disabled most of the time */
        !           202: #if 0
        !           203:        if ( (LastOpcodeFamily!=OpcodeFamily) && ( Pairing == 0 )
        !           204:                && ( ( cycles & 3 ) == 2 ) && ( ( LastInstrCycles & 3 ) == 2 ) )
        !           205:        {
        !           206:                HATARI_TRACE( HATARI_TRACE_CPU_PAIRING ,
        !           207:                              "could pair pc=%x family %s/%s cycles %d/%d\n" ,
        !           208:                              m68k_getpc(), OpcodeName[LastOpcodeFamily] ,
        !           209:                              OpcodeName[OpcodeFamily], LastInstrCycles, cycles );
        !           210:        }
        !           211: #endif
        !           212: 
1.1.1.10  root      213:        /* Store current instr (not rounded) to check next time */
                    214:        LastInstrCycles = cycles;
                    215:        LastOpcodeFamily = OpcodeFamily;
                    216: 
                    217:        /* If pairing is true, we need to substract 2 cycles for the    */
                    218:        /* previous instr which was rounded to 4 cycles while it wasn't */
                    219:        /* needed (and we don't round the current one)                  */
                    220:        /* -> both instr will take 4 cycles less on the ST than if ran  */
                    221:        /* separately.                                                  */
                    222:        if (Pairing == 1)
                    223:                cycles -= 2;
                    224:        else
                    225:                cycles = (cycles + 3) & ~3;      /* no pairing, round current instr to 4 cycles */
                    226: 
                    227:        cycles = cycles >> nCpuFreqShift;
                    228: 
                    229:        PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
                    230: 
                    231:        nCyclesMainCounter += cycles;
                    232: }
                    233: 
                    234: 
                    235: extern void M68000_InitPairing(void);
1.1.1.11! root      236: extern void M68000_Reset(bool bCold);
1.1.1.10  root      237: extern void M68000_Start(void);
                    238: extern void M68000_CheckCpuLevel(void);
1.1.1.11! root      239: extern void M68000_MemorySnapShot_Capture(bool bSave);
        !           240: extern void M68000_BusError(Uint32 addr, bool bReadWrite);
        !           241: extern void M68000_Exception(Uint32 ExceptionVector , int ExceptionSource);
1.1.1.9   root      242: extern void M68000_WaitState(int nCycles);
1.1.1.5   root      243: 
                    244: #endif

unix.superglobalmegacorp.com

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