|
|
1.1 root 1: /*
1.1.1.5 root 2: Hatari - m68000.h
3:
1.1.1.16 root 4: This file is distributed under the GNU General Public License, version 2
5: or at 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) */
1.1.1.14 root 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:
1.1.1.10 root 18:
1.1.1.5 root 19: #ifndef HATARI_M68000_H
20: #define HATARI_M68000_H
21:
1.1.1.9 root 22: #include "cycles.h" /* for nCyclesMainCounter */
1.1.1.6 root 23: #include "sysdeps.h"
24: #include "memory.h"
1.1.1.9 root 25: #include "newcpu.h" /* for regs */
1.1.1.14 root 26: #include "cycInt.h"
1.1.1.11 root 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,
1.1.1.16 root 47: REG_A7 /* ..A7 (also SP) */
1.1.1.11 root 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:
1.1.1.17 root 74: /* Exception numbers most commonly used in ST */
75: #define EXCEPTION_NR_BUSERROR 2
76: #define EXCEPTION_NR_ADDRERROR 3
77: #define EXCEPTION_NR_ILLEGALINS 4
78: #define EXCEPTION_NR_DIVZERO 5
79: #define EXCEPTION_NR_CHK 6
80: #define EXCEPTION_NR_TRAPV 7
81: #define EXCEPTION_NR_TRACE 9
82: #define EXCEPTION_NR_LINE_A 10
83: #define EXCEPTION_NR_LINE_F 11
84: #define EXCEPTION_NR_HBLANK 26 /* Level 2 interrupt */
85: #define EXCEPTION_NR_VBLANK 28 /* Level 4 interrupt */
86: #define EXCEPTION_NR_MFP_DSP 30 /* Level 6 interrupt */
87: #define EXCEPTION_NR_TRAP0 32
88: #define EXCEPTION_NR_TRAP1 33
89: #define EXCEPTION_NR_TRAP2 34
90: #define EXCEPTION_NR_TRAP13 45
91: #define EXCEPTION_NR_TRAP14 46
1.1.1.11 root 92:
93:
94: /* Size of 68000 instructions */
95: #define MAX_68000_INSTRUCTION_SIZE 10 /* Longest 68000 instruction is 10 bytes(6+4) */
96: #define MIN_68000_INSTRUCTION_SIZE 2 /* Smallest 68000 instruction is 2 bytes(ie NOP) */
97:
98: /* Illegal Opcode used to help emulation. eg. free entries are 8 to 15 inc' */
99: #define GEMDOS_OPCODE 8 /* Free op-code to intercept GemDOS trap */
100: #define SYSINIT_OPCODE 10 /* Free op-code to initialize system (connected drives etc.) */
101: #define VDI_OPCODE 12 /* Free op-code to call VDI handlers AFTER Trap#2 */
102:
1.1.1.16 root 103: /* Illegal opcodes used for Native Features emulation:
104: * http://wiki.aranym.org/natfeats/proposal#special_opcodes
105: */
106: #define NATFEAT_ID_OPCODE 0x7300
107: #define NATFEAT_CALL_OPCODE 0x7301
1.1.1.10 root 108:
109:
110: /* Ugly hacks to adapt the main code to the different CPU cores: */
111:
112: #define Regs regs.regs
113:
114:
115: # define M68000_GetPC() m68k_getpc()
116: # define M68000_SetPC(val) m68k_setpc(val)
117:
1.1.1.17 root 118: # define M68000_InstrPC regs.instruction_pc
119: # define M68000_CurrentOpcode regs.opcode
120:
121:
1.1.1.10 root 122: static inline Uint16 M68000_GetSR(void)
123: {
124: MakeSR();
125: return regs.sr;
126: }
127: static inline void M68000_SetSR(Uint16 v)
128: {
129: regs.sr = v;
130: MakeFromSR();
131: }
132:
133: # define M68000_SetSpecial(flags) set_special(flags)
134: # define M68000_UnsetSpecial(flags) unset_special(flags)
135:
136:
1.1.1.17 root 137: /* Some define's for bus error (see newcpu.c) */
138: /* Bus error read/write mode */
139: #define BUS_ERROR_WRITE 0
140: #define BUS_ERROR_READ 1
141: /* Bus error access size */
142: #define BUS_ERROR_SIZE_BYTE 1
143: #define BUS_ERROR_SIZE_WORD 2
144: #define BUS_ERROR_SIZE_LONG 4
145: /* Bus error access type */
146: #define BUS_ERROR_ACCESS_INSTR 0
147: #define BUS_ERROR_ACCESS_DATA 1
1.1.1.9 root 148:
1.1.1.10 root 149:
1.1.1.17 root 150: /* Bus access mode */
1.1.1.12 root 151: #define BUS_MODE_CPU 0 /* bus is owned by the cpu */
152: #define BUS_MODE_BLITTER 1 /* bus is owned by the blitter */
153:
154:
1.1.1.17 root 155: /* [NP] Notes on IACK :
1.1.1.16 root 156: * When an interrupt happens, it's possible a similar interrupt happens again
157: * between the start of the exception and the IACK sequence. In that case, we
158: * might have to set pending bit twice and change the interrupt vector.
1.1.1.17 root 159: *
1.1.1.18! root 160: * From the 68000's doc, IACK starts after 10 cycles (12 cycles on STF due to 2 cycle
! 161: * bus penalty) and is supposed to take 4 cycles if the interrupt takes a total of 44 cycles.
1.1.1.17 root 162: *
163: * On Atari STF, interrupts take 56 cycles instead of 44, which means it takes
164: * 12 extra cycles to fetch the vector number and to handle non-aligned memory accesses.
165: * From WinUAE's CE mode, we have 2 non-aligned memory accesses to wait for (ie 2+2 cycles),
166: * which leaves a total of 12 cycles to fetch the vector.
1.1.1.18! root 167: *
! 168: * As seen wth a custom program on STF that measures HBL's jitter, we get the same results with Hatari
! 169: * in CE mode if we use 10 cycles to fetch the vector (step 3), which will also add 2 cycle penalty (step 4b)
! 170: * This means we have at max 12+10=22 cycles after the start of the exception where some
1.1.1.17 root 171: * changes can happen (maybe it's a little less, depending on when the interrupt
172: * vector is written on the bus).
173: *
1.1.1.18! root 174: * Additionally, auto vectored interrupts (HBL and VBL) require to be in sync with E-clock,
! 175: * which can add 0 to 8 cycles (step 3a). In that case we have between 22+0 and 22+8 cycles
! 176: * to get another interrupt before vector is written on the bus.
! 177: *
! 178: * The values we use were not entirely measured on real ST hardware, they were guessed/adjusted
! 179: * to get the correct behaviour in some games/demos relying on this.
! 180: * These values are when running in CE mode (2 cycle precision) ; when CPU runs in prefetch
! 181: * mode, values need to be rounded to 4).
! 182: *
! 183: * Interrupt steps + WinUAE cycles (measured on real A500 HW) + ST specific values :
! 184: *
! 185: * 1 6 idle cycles
! 186: * 1b 2(*) ST bus access penalty (if necessary)
! 187: * 2 4 write PC low word
! 188: * 3a 0-8(*) wait for E-clock for auto vectored interrupt
! 189: * 3 10(*) read exception number
! 190: * 4 4 idle cycles
! 191: * 4b 2(*) ST bus access penalty
! 192: * 5 4 write SR
! 193: * 6 4 write PC high word
! 194: * 7 4 read exception address high word
! 195: * 8 4 read exception address low word
! 196: * 9 4 prefetch
! 197: * 10 2 idle cycles
! 198: * 10b 2(*) ST bus access penalty
! 199: * 11 4 prefetch
! 200: * TOTAL = 56
1.1.1.17 root 201: *
202: * (*) ST specific timings
1.1.1.16 root 203: */
204:
1.1.1.18! root 205: /* Values for IACK sequence when running in cycle exact mode */
! 206: #define CPU_IACK_CYCLES_MFP_CE 12 /* vector sent by the MFP (TODO value not measured on real STF) */
! 207: #define CPU_IACK_CYCLES_VIDEO_CE 10 /* auto vectored for HBL/VBL (value measured on real STF) */
! 208:
! 209: /* Values for IACK sequence when running in normal/prefetch mode or when using old UAE CPU */
! 210: #define CPU_IACK_CYCLES_START 12 /* number of cycles before starting the IACK when not using CE mode */
! 211: /* (this should be a multiple of 4, else it will be rounded by M68000_AddCycles) */
! 212: #define CPU_IACK_CYCLES_MFP 12 /* vector sent by the MFP */
! 213: #define CPU_IACK_CYCLES_VIDEO 12 /* auto vectored for HBL/VBL */
1.1.1.16 root 214:
1.1.1.17 root 215: /* Informations about current CPU instruction */
1.1.1.16 root 216: typedef struct {
1.1.1.17 root 217: /* These are provided only by WinUAE CPU core */
218: int I_Cache_miss; /* Instruction cache for 68020/30/40/60 */
219: int I_Cache_hit;
220: int D_Cache_miss; /* Data cache for 68030/40/60 */
221: int D_Cache_hit;
1.1.1.16 root 222:
223: /* TODO: move other instruction specific Hatari variables here */
224: } cpu_instruction_t;
225:
226: extern cpu_instruction_t CpuInstruction;
227:
1.1.1.7 root 228: extern Uint32 BusErrorAddress;
1.1.1.11 root 229: extern bool bBusErrorReadWrite;
1.1.1.7 root 230: extern int nCpuFreqShift;
1.1.1.18! root 231: extern int WaitStateCycles;
1.1.1.12 root 232: extern int BusMode;
1.1.1.16 root 233: extern bool CPU_IACK;
1.1.1.6 root 234:
1.1.1.10 root 235: extern int LastOpcodeFamily;
236: extern int LastInstrCycles;
237: extern int Pairing;
238: extern char PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
239: extern const char *OpcodeName[];
240:
1.1.1.6 root 241:
242: /*-----------------------------------------------------------------------*/
1.1.1.10 root 243: /**
244: * Add CPU cycles.
245: * NOTE: All times are rounded up to nearest 4 cycles.
246: */
1.1.1.6 root 247: static inline void M68000_AddCycles(int cycles)
248: {
1.1.1.10 root 249: cycles = (cycles + 3) & ~3;
1.1.1.18! root 250: #ifdef OLD_CPU_SHIFT
1.1.1.10 root 251: cycles = cycles >> nCpuFreqShift;
252:
1.1.1.18! root 253: PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
! 254: #else
! 255: // PendingInterruptCount -= INT_CONVERT_TO_INTERNAL_NO_FREQSHIFT ( cycles , INT_CPU_CYCLE );
! 256: PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
! 257: #endif
1.1.1.9 root 258: nCyclesMainCounter += cycles;
1.1.1.16 root 259: CyclesGlobalClockCounter += cycles;
1.1.1.6 root 260: }
1.1.1.5 root 261:
1.1.1.10 root 262:
263: /*-----------------------------------------------------------------------*/
264: /**
1.1.1.14 root 265: * Add CPU cycles, take cycles pairing into account. Pairing will make
266: * some specific instructions take 4 cycles less when run one after the other.
267: * Pairing happens when the 2 instructions are "aligned" on different bus accesses.
268: * Candidates are :
269: * - 2 instructions taking 4n+2 cycles
270: * - 1 instruction taking 4n+2 cycles, followed by 1 instruction using d8(an,ix)
271: *
272: * Not all the candidate instructions can pair, only the opcodes listed in PairingArray.
273: * On ST, when using d8(an,ix), we get an extra 2 cycle penalty for misaligned bus access.
274: * The only instruction that can generate BusCyclePenalty=4 is move d8(an,ix),d8(an,ix)
275: * and although it takes 4n cycles (24 for .b/.w or 32 for .l) it can pair with
276: * a previous 4n+2 instruction (but it will still have 1 misaligned bus access in the end).
277: *
278: * Verified pairing on an STF :
279: * - lsl.w #4,d1 + move.w 0(a4,d2.w),d1 motorola=14+14=28 stf=28
280: * - lsl.w #4,d1 + move.w 0(a4,d2.w),(a4) motorola=14+18=32 stf=32
281: * - lsl.w #4,d1 + move.w 0(a4,d2.w),0(a4,d2.w) motorola=14+24=38 stf=40
282: * - add.l (a5,d1.w),d0 + move.b 7(a5,d1.w),d5) motorola=20+14=34 stf=36
283: *
284: * d8(an,ix) timings without pairing (2 cycles penalty) :
285: * - add.l 0(a4,d2.w),a1 motorola=20 stf=24
286: * - move.w 0(a4,d2.w),d1 motorola=14 stf=16
287: * - move.w 0(a4,d2.w),(a4) motorola=18 stf=20
288: * - move.w 0(a4,d2.w),0(a4,d2.w) motorola=24 stf=28
289: *
1.1.1.10 root 290: * NOTE: All times are rounded up to nearest 4 cycles.
291: */
292: static inline void M68000_AddCyclesWithPairing(int cycles)
293: {
294: Pairing = 0;
295: /* Check if number of cycles for current instr and for */
296: /* the previous one is of the form 4+2n */
297: /* If so, a pairing could be possible depending on the opcode */
1.1.1.14 root 298: /* A pairing is also possible if current instr is 4n but with BusCyclePenalty > 0 */
1.1.1.10 root 299: if ( ( PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1 )
1.1.1.14 root 300: && ( ( LastInstrCycles & 3 ) == 2 )
301: && ( ( ( cycles & 3 ) == 2 ) || ( BusCyclePenalty > 0 ) ) )
1.1.1.10 root 302: {
303: Pairing = 1;
1.1.1.13 root 304: LOG_TRACE(TRACE_CPU_PAIRING,
305: "cpu pairing detected pc=%x family %s/%s cycles %d/%d\n",
306: m68k_getpc(), OpcodeName[LastOpcodeFamily],
307: OpcodeName[OpcodeFamily], LastInstrCycles, cycles);
1.1.1.10 root 308: }
309:
1.1.1.11 root 310: /* [NP] This part is only needed to track possible pairing instructions, */
311: /* we can keep it disabled most of the time */
312: #if 0
313: if ( (LastOpcodeFamily!=OpcodeFamily) && ( Pairing == 0 )
314: && ( ( cycles & 3 ) == 2 ) && ( ( LastInstrCycles & 3 ) == 2 ) )
315: {
1.1.1.13 root 316: LOG_TRACE(TRACE_CPU_PAIRING,
317: "cpu could pair pc=%x family %s/%s cycles %d/%d\n",
318: m68k_getpc(), OpcodeName[LastOpcodeFamily],
319: OpcodeName[OpcodeFamily], LastInstrCycles, cycles);
1.1.1.11 root 320: }
321: #endif
322:
1.1.1.10 root 323: /* Store current instr (not rounded) to check next time */
1.1.1.14 root 324: LastInstrCycles = cycles + BusCyclePenalty;
1.1.1.10 root 325: LastOpcodeFamily = OpcodeFamily;
326:
1.1.1.16 root 327: /* If pairing is true, we need to subtract 2 cycles for the */
1.1.1.10 root 328: /* previous instr which was rounded to 4 cycles while it wasn't */
329: /* needed (and we don't round the current one) */
330: /* -> both instr will take 4 cycles less on the ST than if ran */
331: /* separately. */
332: if (Pairing == 1)
1.1.1.14 root 333: {
334: if ( ( cycles & 3 ) == 2 ) /* pairing between 4n+2 and 4n+2 instructions */
335: cycles -= 2; /* if we have a pairing, we should not count the misaligned bus access */
336:
337: else /* this is the case of move d8(an,ix),d8(an,ix) where BusCyclePenalty=4 */
338: /*do nothing */; /* we gain 2 cycles for the pairing with 1st d8(an,ix) */
339: /* and we have 1 remaining misaligned access for the 2nd d8(an,ix). So in the end, we keep */
340: /* cycles unmodified as 4n cycles (eg lsl.w #4,d1 + move.w 0(a4,d2.w),0(a4,d2.w) takes 40 cycles) */
341: }
1.1.1.10 root 342: else
1.1.1.14 root 343: {
344: cycles += BusCyclePenalty; /* >0 if d8(an,ix) was used */
345: cycles = (cycles + 3) & ~3; /* no pairing, round current instr to 4 cycles */
346: }
1.1.1.10 root 347:
1.1.1.18! root 348: #ifdef OLD_CPU_SHIFT
1.1.1.10 root 349: cycles = cycles >> nCpuFreqShift;
350:
351: PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
1.1.1.18! root 352: #else
! 353: // PendingInterruptCount -= INT_CONVERT_TO_INTERNAL_NO_FREQSHIFT ( cycles , INT_CPU_CYCLE );
! 354: PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
! 355: #endif
1.1.1.10 root 356:
357: nCyclesMainCounter += cycles;
1.1.1.16 root 358: CyclesGlobalClockCounter += cycles;
1.1.1.14 root 359: BusCyclePenalty = 0;
1.1.1.10 root 360: }
361:
362:
1.1.1.18! root 363: /*-----------------------------------------------------------------------*/
! 364: /**
! 365: * Add CPU cycles when using WinUAE CPU 'cycle exact' mode.
! 366: * In this mode, we should not round cycles to the next nearest 4 cycles
! 367: * because all memory accesses will already be aligned to 4 cycles when
! 368: * using CE mode.
! 369: * The CE mode will also give the correct 'instruction pairing' for all
! 370: * opcodes/addressing mode, without requiring tables/heuristics (in the
! 371: * same way that it's done in real hardware)
! 372: */
! 373: static inline void M68000_AddCycles_CE(int cycles)
! 374: {
! 375: #ifdef OLD_CPU_SHIFT
! 376: cycles = cycles >> nCpuFreqShift;
! 377:
! 378: PendingInterruptCount -= INT_CONVERT_TO_INTERNAL(cycles, INT_CPU_CYCLE);
! 379: #else
! 380: // PendingInterruptCount -= INT_CONVERT_TO_INTERNAL_NO_FREQSHIFT ( cycles , INT_CPU_CYCLE );
! 381: PendingInterruptCount -= INT_CONVERT_TO_INTERNAL ( cycles , INT_CPU_CYCLE );
! 382: #endif
! 383:
! 384: nCyclesMainCounter += cycles;
! 385: CyclesGlobalClockCounter += cycles;
! 386: }
! 387:
! 388:
! 389:
1.1.1.14 root 390: extern void M68000_Init(void);
1.1.1.11 root 391: extern void M68000_Reset(bool bCold);
1.1.1.10 root 392: extern void M68000_Start(void);
1.1.1.15 root 393: extern void M68000_CheckCpuSettings(void);
1.1.1.11 root 394: extern void M68000_MemorySnapShot_Capture(bool bSave);
1.1.1.17 root 395: extern void M68000_BusError ( Uint32 addr , int ReadWrite , int Size , int AccessType );
396: extern void M68000_Exception(Uint32 ExceptionNr , int ExceptionSource);
397: extern void M68000_Update_intlev ( void );
1.1.1.18! root 398: extern void M68000_WaitState(int WaitCycles);
1.1.1.16 root 399: extern int M68000_WaitEClock ( void );
1.1.1.18! root 400: extern void M68000_SyncCpuBus_OnReadAccess ( void );
! 401: extern void M68000_SyncCpuBus_OnWriteAccess ( void );
1.1.1.17 root 402: extern void M68000_Flush_Instr_Cache ( uaecptr addr , int size );
403: extern void M68000_Flush_Data_Cache ( uaecptr addr , int size );
404: extern void M68000_Flush_All_Caches ( uaecptr addr , int size );
1.1.1.18! root 405: extern int DMA_MaskAddressHigh ( void );
! 406: extern void M68000_ChangeCpuFreq ( void );
1.1.1.5 root 407:
408: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.