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

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.12  root      151: /* bus acces mode */
                    152: #define        BUS_MODE_CPU            0                       /* bus is owned by the cpu */
                    153: #define        BUS_MODE_BLITTER        1                       /* bus is owned by the blitter */
                    154: 
                    155: 
1.1.1.7   root      156: extern Uint32 BusErrorAddress;
1.1.1.5   root      157: extern Uint32 BusErrorPC;
1.1.1.11  root      158: extern bool bBusErrorReadWrite;
1.1.1.7   root      159: extern int nCpuFreqShift;
1.1.1.9   root      160: extern int nWaitStateCycles;
1.1.1.12  root      161: extern int BusMode;
1.1.1.6   root      162: 
1.1.1.10  root      163: extern int     LastOpcodeFamily;
                    164: extern int     LastInstrCycles;
                    165: extern int     Pairing;
                    166: extern char    PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
                    167: extern const char *OpcodeName[];
                    168: 
1.1.1.6   root      169: 
                    170: /*-----------------------------------------------------------------------*/
1.1.1.10  root      171: /**
                    172:  * Add CPU cycles.
                    173:  * NOTE: All times are rounded up to nearest 4 cycles.
                    174:  */
1.1.1.6   root      175: static inline void M68000_AddCycles(int cycles)
                    176: {
1.1.1.10  root      177:        cycles = (cycles + 3) & ~3;
                    178:        cycles = cycles >> nCpuFreqShift;
                    179: 
                    180:        PendingInterruptCount -= INT_CONVERT_TO_INTERNAL(cycles, INT_CPU_CYCLE);
1.1.1.9   root      181:        nCyclesMainCounter += cycles;
1.1.1.6   root      182: }
1.1.1.5   root      183: 
1.1.1.10  root      184: 
                    185: /*-----------------------------------------------------------------------*/
                    186: /**
                    187:  * Add CPU cycles, take cycles pairing into account.
                    188:  * NOTE: All times are rounded up to nearest 4 cycles.
                    189:  */
                    190: static inline void M68000_AddCyclesWithPairing(int cycles)
                    191: {
                    192:        Pairing = 0;
                    193:        /* Check if number of cycles for current instr and for */
                    194:        /* the previous one is of the form 4+2n */
                    195:        /* If so, a pairing could be possible depending on the opcode */
                    196:        if ( ( PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1 )
                    197:            && ( ( cycles & 3 ) == 2 ) && ( ( LastInstrCycles & 3 ) == 2 ) )
                    198:        {
                    199:                Pairing = 1;
1.1.1.13! root      200:                LOG_TRACE(TRACE_CPU_PAIRING,
        !           201:                          "cpu pairing detected pc=%x family %s/%s cycles %d/%d\n",
        !           202:                          m68k_getpc(), OpcodeName[LastOpcodeFamily],
        !           203:                          OpcodeName[OpcodeFamily], LastInstrCycles, cycles);
1.1.1.10  root      204:        }
                    205: 
1.1.1.11  root      206:        /* [NP] This part is only needed to track possible pairing instructions, */
                    207:        /* we can keep it disabled most of the time */
                    208: #if 0
                    209:        if ( (LastOpcodeFamily!=OpcodeFamily) && ( Pairing == 0 )
                    210:                && ( ( cycles & 3 ) == 2 ) && ( ( LastInstrCycles & 3 ) == 2 ) )
                    211:        {
1.1.1.13! root      212:                LOG_TRACE(TRACE_CPU_PAIRING,
        !           213:                          "cpu could pair pc=%x family %s/%s cycles %d/%d\n",
        !           214:                          m68k_getpc(), OpcodeName[LastOpcodeFamily],
        !           215:                          OpcodeName[OpcodeFamily], LastInstrCycles, cycles);
1.1.1.11  root      216:        }
                    217: #endif
                    218: 
1.1.1.10  root      219:        /* Store current instr (not rounded) to check next time */
                    220:        LastInstrCycles = cycles;
                    221:        LastOpcodeFamily = OpcodeFamily;
                    222: 
                    223:        /* If pairing is true, we need to substract 2 cycles for the    */
                    224:        /* previous instr which was rounded to 4 cycles while it wasn't */
                    225:        /* needed (and we don't round the current one)                  */
                    226:        /* -> both instr will take 4 cycles less on the ST than if ran  */
                    227:        /* separately.                                                  */
                    228:        if (Pairing == 1)
                    229:                cycles -= 2;
                    230:        else
                    231:                cycles = (cycles + 3) & ~3;      /* no pairing, round current instr to 4 cycles */
                    232: 
                    233:        cycles = cycles >> nCpuFreqShift;
                    234: 
                    235:        PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
                    236: 
                    237:        nCyclesMainCounter += cycles;
                    238: }
                    239: 
                    240: 
                    241: extern void M68000_InitPairing(void);
1.1.1.11  root      242: extern void M68000_Reset(bool bCold);
1.1.1.10  root      243: extern void M68000_Start(void);
                    244: extern void M68000_CheckCpuLevel(void);
1.1.1.11  root      245: extern void M68000_MemorySnapShot_Capture(bool bSave);
                    246: extern void M68000_BusError(Uint32 addr, bool bReadWrite);
                    247: extern void M68000_Exception(Uint32 ExceptionVector , int ExceptionSource);
1.1.1.9   root      248: extern void M68000_WaitState(int nCycles);
1.1.1.5   root      249: 
                    250: #endif

unix.superglobalmegacorp.com

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