Annotation of previous/src/includes/m68000.h, revision 1.1.1.1

1.1       root        1: /*
                      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.
                      6: */
                      7: 
                      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: /* 2010/04/05  [NP]    Rework the pairing code to take BusCyclePenalty */
                     13: /*                     into account when using d8(an,ix).              */
                     14: /* 2010/05/07  [NP]    Add BusCyclePenalty to LastInstrCycles to detect*/
                     15: /*                     a possible pairing between add.l (a5,d1.w),d0   */
                     16: /*                     and move.b 7(a5,d1.w),d5.                       */
                     17: 
                     18: 
                     19: #ifndef HATARI_M68000_H
                     20: #define HATARI_M68000_H
                     21: 
                     22: #include "cycles.h"     /* for nCyclesMainCounter */
                     23: #include "sysdeps.h"
                     24: #include "memory.h"
                     25: #include "newcpu.h"     /* for regs */
                     26: #include "cycInt.h"
                     27: #include "log.h"
                     28: 
                     29: 
                     30: /* 68000 Register defines */
                     31: enum {
                     32:   REG_D0,    /* D0.. */
                     33:   REG_D1,
                     34:   REG_D2,
                     35:   REG_D3,
                     36:   REG_D4,
                     37:   REG_D5,
                     38:   REG_D6,
                     39:   REG_D7,    /* ..D7 */
                     40:   REG_A0,    /* A0.. */
                     41:   REG_A1,
                     42:   REG_A2,
                     43:   REG_A3,
                     44:   REG_A4,
                     45:   REG_A5,
                     46:   REG_A6,
                     47:   REG_A7,    /* ..A7 (also SP) */
                     48: };
                     49: 
                     50: /* 68000 Condition code's */
                     51: #define SR_AUX              0x0010
                     52: #define SR_NEG              0x0008
                     53: #define SR_ZERO             0x0004
                     54: #define SR_OVERFLOW         0x0002
                     55: #define SR_CARRY            0x0001
                     56: 
                     57: #define SR_CLEAR_AUX        0xffef
                     58: #define SR_CLEAR_NEG        0xfff7
                     59: #define SR_CLEAR_ZERO       0xfffb
                     60: #define SR_CLEAR_OVERFLOW   0xfffd
                     61: #define SR_CLEAR_CARRY      0xfffe
                     62: 
                     63: #define SR_CCODE_MASK       (SR_AUX|SR_NEG|SR_ZERO|SR_OVERFLOW|SR_CARRY)
                     64: #define SR_MASK             0xFFE0
                     65: 
                     66: #define SR_TRACEMODE        0x8000
                     67: #define SR_SUPERMODE        0x2000
                     68: #define SR_IPL              0x0700
                     69: 
                     70: #define SR_CLEAR_IPL        0xf8ff
                     71: #define SR_CLEAR_TRACEMODE  0x7fff
                     72: #define SR_CLEAR_SUPERMODE  0xdfff
                     73: 
                     74: /* Exception vectors */
                     75: #define  EXCEPTION_BUSERROR   0x00000008
                     76: #define  EXCEPTION_ADDRERROR  0x0000000c
                     77: #define  EXCEPTION_ILLEGALINS 0x00000010
                     78: #define  EXCEPTION_DIVZERO    0x00000014
                     79: #define  EXCEPTION_CHK        0x00000018
                     80: #define  EXCEPTION_TRAPV      0x0000001c
                     81: #define  EXCEPTION_TRACE      0x00000024
                     82: #define  EXCEPTION_LINE_A     0x00000028
                     83: #define  EXCEPTION_LINE_F     0x0000002c
                     84: #define  EXCEPTION_HBLANK     0x00000068
                     85: #define  EXCEPTION_VBLANK     0x00000070
                     86: #define  EXCEPTION_TRAP0      0x00000080
                     87: #define  EXCEPTION_TRAP1      0x00000084
                     88: #define  EXCEPTION_TRAP2      0x00000088
                     89: #define  EXCEPTION_TRAP13     0x000000B4
                     90: #define  EXCEPTION_TRAP14     0x000000B8
                     91: 
                     92: 
                     93: /* Size of 68000 instructions */
                     94: #define MAX_68000_INSTRUCTION_SIZE  10  /* Longest 68000 instruction is 10 bytes(6+4) */
                     95: #define MIN_68000_INSTRUCTION_SIZE  2   /* Smallest 68000 instruction is 2 bytes(ie NOP) */
                     96: 
                     97: /* Illegal Opcode used to help emulation. eg. free entries are 8 to 15 inc' */
                     98: #define  GEMDOS_OPCODE        8  /* Free op-code to intercept GemDOS trap */
                     99: #define  SYSINIT_OPCODE      10  /* Free op-code to initialize system (connected drives etc.) */
                    100: #define  VDI_OPCODE          12  /* Free op-code to call VDI handlers AFTER Trap#2 */
                    101: 
                    102: 
                    103: 
                    104: /* Ugly hacks to adapt the main code to the different CPU cores: */
                    105: 
                    106: #define Regs regs.regs
                    107: 
                    108: #if defined(UAE_NEWCPU_H)
                    109: 
                    110: # define M68000_GetPC()     m68k_getpc()
                    111: # define M68000_SetPC(val)  m68k_setpc(val)
                    112: 
                    113: static inline Uint16 M68000_GetSR(void)
                    114: {
                    115:        MakeSR();
                    116:        return regs.sr;
                    117: }
                    118: static inline void M68000_SetSR(Uint16 v)
                    119: {
                    120:        regs.sr = v;
                    121:        MakeFromSR();
                    122: }
                    123: 
                    124: # define M68000_SetSpecial(flags)   set_special(flags)
                    125: # define M68000_UnsetSpecial(flags) unset_special(flags)
                    126: 
                    127: #else  /* following code is for WinUAE CPU: */
                    128: 
                    129: # define M68000_GetPC()     m68k_getpc(&regs)
                    130: # define M68000_SetPC(val)  m68k_setpc(&regs,val)
                    131: 
                    132: static inline Uint16 M68000_GetSR(void)
                    133: {
                    134:        MakeSR(&regs);
                    135:        return regs.sr;
                    136: }
                    137: static inline void M68000_SetSR(Uint16 v)
                    138: {
                    139:        regs.sr = v;
                    140:        MakeFromSR(&regs);
                    141: }
                    142: 
                    143: # define M68000_SetSpecial(flags)   set_special(&regs,flags)
                    144: # define M68000_UnsetSpecial(flags) unset_special(&regs,flags)
                    145: 
                    146: #endif /* defined(UAE_NEWCPU_H) */
                    147: 
                    148: 
                    149: /* bus error mode */
                    150: #define BUS_ERROR_WRITE 0
                    151: #define BUS_ERROR_READ 1
                    152: 
                    153: 
                    154: /* bus acces mode */
                    155: #define        BUS_MODE_CPU            0                       /* bus is owned by the cpu */
                    156: #define        BUS_MODE_BLITTER        1                       /* bus is owned by the blitter */
                    157: 
                    158: 
                    159: extern Uint32 BusErrorAddress;
                    160: extern Uint32 BusErrorPC;
                    161: extern bool bBusErrorReadWrite;
                    162: extern int nCpuFreqShift;
                    163: extern int nWaitStateCycles;
                    164: extern int BusMode;
                    165: 
                    166: extern int     LastOpcodeFamily;
                    167: extern int     LastInstrCycles;
                    168: extern int     Pairing;
                    169: extern char    PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
                    170: extern const char *OpcodeName[];
                    171: 
                    172: 
                    173: /*-----------------------------------------------------------------------*/
                    174: /**
                    175:  * Add CPU cycles.
                    176:  * NOTE: All times are rounded up to nearest 4 cycles.
                    177:  */
                    178: static inline void M68000_AddCycles(int cycles)
                    179: {
                    180:        cycles = (cycles + 3) & ~3;
                    181:        cycles = cycles >> nCpuFreqShift;
                    182: 
                    183:        PendingInterruptCount -= INT_CONVERT_TO_INTERNAL(cycles, INT_CPU_CYCLE);
                    184:        nCyclesMainCounter += cycles;
                    185: }
                    186: 
                    187: 
                    188: /*-----------------------------------------------------------------------*/
                    189: /**
                    190:  * Add CPU cycles, take cycles pairing into account. Pairing will make
                    191:  * some specific instructions take 4 cycles less when run one after the other.
                    192:  * Pairing happens when the 2 instructions are "aligned" on different bus accesses.
                    193:  * Candidates are :
                    194:  *  - 2 instructions taking 4n+2 cycles
                    195:  *  - 1 instruction taking 4n+2 cycles, followed by 1 instruction using d8(an,ix)
                    196:  *
                    197:  * Not all the candidate instructions can pair, only the opcodes listed in PairingArray.
                    198:  * On ST, when using d8(an,ix), we get an extra 2 cycle penalty for misaligned bus access.
                    199:  * The only instruction that can generate BusCyclePenalty=4 is move d8(an,ix),d8(an,ix)
                    200:  * and although it takes 4n cycles (24 for .b/.w or 32 for .l) it can pair with
                    201:  * a previous 4n+2 instruction (but it will still have 1 misaligned bus access in the end).
                    202:  *
                    203:  * Verified pairing on an STF :
                    204:  *  - lsl.w #4,d1 + move.w 0(a4,d2.w),d1               motorola=14+14=28  stf=28
                    205:  *  - lsl.w #4,d1 + move.w 0(a4,d2.w),(a4)             motorola=14+18=32  stf=32
                    206:  *  - lsl.w #4,d1 + move.w 0(a4,d2.w),0(a4,d2.w)       motorola=14+24=38  stf=40
                    207:  *  - add.l (a5,d1.w),d0 + move.b 7(a5,d1.w),d5)       motorola=20+14=34  stf=36
                    208:  *
                    209:  * d8(an,ix) timings without pairing (2 cycles penalty) :
                    210:  *  - add.l   0(a4,d2.w),a1                            motorola=20  stf=24
                    211:  *  - move.w  0(a4,d2.w),d1                            motorola=14  stf=16
                    212:  *  - move.w  0(a4,d2.w),(a4)                          motorola=18  stf=20
                    213:  *  - move.w  0(a4,d2.w),0(a4,d2.w)                    motorola=24  stf=28
                    214:  *
                    215:  * NOTE: All times are rounded up to nearest 4 cycles.
                    216:  */
                    217: static inline void M68000_AddCyclesWithPairing(int cycles)
                    218: {
                    219:        Pairing = 0;
                    220:        /* Check if number of cycles for current instr and for */
                    221:        /* the previous one is of the form 4+2n */
                    222:        /* If so, a pairing could be possible depending on the opcode */
                    223:        /* A pairing is also possible if current instr is 4n but with BusCyclePenalty > 0 */
                    224:        if ( ( PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1 )
                    225:            && ( ( LastInstrCycles & 3 ) == 2 )
                    226:            && ( ( ( cycles & 3 ) == 2 ) || ( BusCyclePenalty > 0 ) ) )
                    227:        {
                    228:                Pairing = 1;
                    229:                LOG_TRACE(TRACE_CPU_PAIRING,
                    230:                          "cpu pairing detected pc=%x family %s/%s cycles %d/%d\n",
                    231:                          m68k_getpc(), OpcodeName[LastOpcodeFamily],
                    232:                          OpcodeName[OpcodeFamily], LastInstrCycles, cycles);
                    233:        }
                    234: 
                    235:        /* [NP] This part is only needed to track possible pairing instructions, */
                    236:        /* we can keep it disabled most of the time */
                    237: #if 0
                    238:        if ( (LastOpcodeFamily!=OpcodeFamily) && ( Pairing == 0 )
                    239:                && ( ( cycles & 3 ) == 2 ) && ( ( LastInstrCycles & 3 ) == 2 ) )
                    240:        {
                    241:                LOG_TRACE(TRACE_CPU_PAIRING,
                    242:                          "cpu could pair pc=%x family %s/%s cycles %d/%d\n",
                    243:                          m68k_getpc(), OpcodeName[LastOpcodeFamily],
                    244:                          OpcodeName[OpcodeFamily], LastInstrCycles, cycles);
                    245:        }
                    246: #endif
                    247: 
                    248:        /* Store current instr (not rounded) to check next time */
                    249:        LastInstrCycles = cycles + BusCyclePenalty;
                    250:        LastOpcodeFamily = OpcodeFamily;
                    251: 
                    252:        /* If pairing is true, we need to substract 2 cycles for the    */
                    253:        /* previous instr which was rounded to 4 cycles while it wasn't */
                    254:        /* needed (and we don't round the current one)                  */
                    255:        /* -> both instr will take 4 cycles less on the ST than if ran  */
                    256:        /* separately.                                                  */
                    257:        if (Pairing == 1)
                    258:        {
                    259:                if ( ( cycles & 3 ) == 2 )              /* pairing between 4n+2 and 4n+2 instructions */
                    260:                        cycles -= 2;                    /* if we have a pairing, we should not count the misaligned bus access */
                    261: 
                    262:                else                                    /* this is the case of move d8(an,ix),d8(an,ix) where BusCyclePenalty=4 */
                    263:                        /*do nothing */;                /* we gain 2 cycles for the pairing with 1st d8(an,ix) */
                    264:                                                        /* and we have 1 remaining misaligned access for the 2nd d8(an,ix). So in the end, we keep */
                    265:                                                        /* cycles unmodified as 4n cycles (eg lsl.w #4,d1 + move.w 0(a4,d2.w),0(a4,d2.w) takes 40 cycles) */
                    266:        }
                    267:        else
                    268:        {
                    269:                cycles += BusCyclePenalty;              /* >0 if d8(an,ix) was used */
                    270:                cycles = (cycles + 3) & ~3;             /* no pairing, round current instr to 4 cycles */
                    271:        }
                    272: 
                    273:        cycles = cycles >> nCpuFreqShift;
                    274: 
                    275:        PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
                    276: 
                    277:        nCyclesMainCounter += cycles;
                    278:        BusCyclePenalty = 0;
                    279: }
                    280: 
                    281: 
                    282: extern void M68000_Init(void);
                    283: extern void M68000_Reset(bool bCold);
                    284: extern void M68000_Start(void);
                    285: extern void M68000_CheckCpuLevel(void);
                    286: extern void M68000_MemorySnapShot_Capture(bool bSave);
                    287: extern void M68000_BusError(Uint32 addr, bool bReadWrite);
                    288: extern void M68000_Exception(Uint32 ExceptionVector , int ExceptionSource);
                    289: extern void M68000_WaitState(int nCycles);
                    290: 
                    291: #endif

unix.superglobalmegacorp.com

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