|
|
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(®s)
124: # define M68000_SetPC(val) m68k_setpc(®s,val)
1.1.1.6 root 125:
1.1.1.10 root 126: static inline Uint16 M68000_GetSR(void)
127: {
128: MakeSR(®s);
129: return regs.sr;
130: }
131: static inline void M68000_SetSR(Uint16 v)
132: {
133: regs.sr = v;
134: MakeFromSR(®s);
135: }
136:
137: # define M68000_SetSpecial(flags) set_special(®s,flags)
138: # define M68000_UnsetSpecial(flags) unset_special(®s,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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.