1 #ifndef M68KCPU__HEADER
2 #define M68KCPU__HEADER
8 /* ======================================================================== */
9 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
10 /* ======================================================================== */
12 /* Check if we have certain storage sizes */
15 #define M68K_HAS_8_BIT_SIZE 1
17 #define M68K_HAS_8_BIT_SIZE 0
18 #endif /* UCHAR_MAX == 0xff */
20 #if USHRT_MAX == 0xffff
21 #define M68K_HAS_16_BIT_SIZE 1
23 #define M68K_HAS_16_BIT_SIZE 0
24 #endif /* USHRT_MAX == 0xffff */
26 #if ULONG_MAX == 0xffffffff
27 #define M68K_HAS_32_BIT_SIZE 1
29 #define M68K_HAS_32_BIT_SIZE 0
30 #endif /* ULONG_MAX == 0xffffffff */
32 #if UINT_MAX > 0xffffffff
33 #define M68K_OVER_32_BIT 1
35 #define M68K_OVER_32_BIT 0
36 #endif /* UINT_MAX > 0xffffffff */
38 /* Data types used in this emulation core */
47 #define int8 signed char /* ASG: changed from char to signed char */
48 #define uint8 unsigned char
50 #define uint16 unsigned short
53 /* int and unsigned int must be at least 32 bits wide */
54 #define uint unsigned int
57 /* Allow for architectures that don't have 8-bit sizes */
58 #if M68K_HAS_8_BIT_SIZE
59 #define MAKE_INT_8(A) (int8)((A)&0xff)
64 #define uint8 unsigned int
65 INLINE
int MAKE_INT_8(int value
)
67 /* Will this work for 1's complement machines? */
68 return (value
& 0x80) ? value
| ~0xff : value
& 0xff;
70 #endif /* M68K_HAS_8_BIT_SIZE */
73 /* Allow for architectures that don't have 16-bit sizes */
74 #if M68K_HAS_16_BIT_SIZE
75 #define MAKE_INT_16(A) (int16)((A)&0xffff)
80 #define uint16 unsigned int
81 INLINE
int MAKE_INT_16(int value
)
83 /* Will this work for 1's complement machines? */
84 return (value
& 0x8000) ? value
| ~0xffff : value
& 0xffff;
86 #endif /* M68K_HAS_16_BIT_SIZE */
89 /* Allow for architectures that don't have 32-bit sizes */
90 #if M68K_HAS_32_BIT_SIZE
92 #define MAKE_INT_32(A) (int32)((A)&0xffffffff)
94 #define MAKE_INT_32(A) (int32)(A)
95 #endif /* M68K_OVER_32_BIT */
99 INLINE
int MAKE_INT_32(int value
)
101 /* Will this work for 1's complement machines? */
102 return (value
& 0x80000000) ? value
| ~0xffffffff : value
& 0xffffffff;
104 #endif /* M68K_HAS_32_BIT_SIZE */
108 /* ======================================================================== */
109 /* ============================ GENERAL DEFINES =========================== */
110 /* ======================================================================== */
112 /* Exception Vectors handled by emulation */
113 #define EXCEPTION_ILLEGAL_INSTRUCTION 4
114 #define EXCEPTION_ZERO_DIVIDE 5
115 #define EXCEPTION_CHK 6
116 #define EXCEPTION_TRAPV 7
117 #define EXCEPTION_PRIVILEGE_VIOLATION 8
118 #define EXCEPTION_TRACE 9
119 #define EXCEPTION_1010 10
120 #define EXCEPTION_1111 11
121 #define EXCEPTION_FORMAT_ERROR 14
122 #define EXCEPTION_UNINITIALIZED_INTERRUPT 15
123 #define EXCEPTION_SPURIOUS_INTERRUPT 24
124 #define EXCEPTION_INTERRUPT_AUTOVECTOR 24
125 #define EXCEPTION_TRAP_BASE 32
127 /* Function codes set by CPU during data/address bus activity */
128 #define FUNCTION_CODE_USER_DATA 1
129 #define FUNCTION_CODE_USER_PROGRAM 2
130 #define FUNCTION_CODE_SUPERVISOR_DATA 5
131 #define FUNCTION_CODE_SUPERVISOR_PROGRAM 6
132 #define FUNCTION_CODE_CPU_SPACE 7
134 /* CPU modes for deciding what to emulate */
135 #define CPU_MODE_000 M68K_CPU_MODE_68000
136 #define CPU_MODE_010 M68K_CPU_MODE_68010
137 #define CPU_MODE_020 M68K_CPU_MODE_68020
139 #define CPU_MODE_ALL (CPU_MODE_000 | CPU_MODE_010 | CPU_MODE_020)
140 #define CPU_MODE_010_PLUS (CPU_MODE_010 | CPU_MODE_020)
141 #define CPU_MODE_010_LESS (CPU_MODE_000 | CPU_MODE_010)
142 #define CPU_MODE_020_PLUS CPU_MODE_020
143 #define CPU_MODE_020_LESS (CPU_MODE_000 | CPU_MODE_010 | CPU_MODE_020)
146 /* ======================================================================== */
147 /* ================================ MACROS ================================ */
148 /* ======================================================================== */
150 /* Bit Isolation Macros */
151 #define BIT_0(A) ((A) & 0x00000001)
152 #define BIT_1(A) ((A) & 0x00000002)
153 #define BIT_2(A) ((A) & 0x00000004)
154 #define BIT_3(A) ((A) & 0x00000008)
155 #define BIT_4(A) ((A) & 0x00000010)
156 #define BIT_5(A) ((A) & 0x00000020)
157 #define BIT_6(A) ((A) & 0x00000040)
158 #define BIT_7(A) ((A) & 0x00000080)
159 #define BIT_8(A) ((A) & 0x00000100)
160 #define BIT_9(A) ((A) & 0x00000200)
161 #define BIT_A(A) ((A) & 0x00000400)
162 #define BIT_B(A) ((A) & 0x00000800)
163 #define BIT_C(A) ((A) & 0x00001000)
164 #define BIT_D(A) ((A) & 0x00002000)
165 #define BIT_E(A) ((A) & 0x00004000)
166 #define BIT_F(A) ((A) & 0x00008000)
167 #define BIT_10(A) ((A) & 0x00010000)
168 #define BIT_11(A) ((A) & 0x00020000)
169 #define BIT_12(A) ((A) & 0x00040000)
170 #define BIT_13(A) ((A) & 0x00080000)
171 #define BIT_14(A) ((A) & 0x00100000)
172 #define BIT_15(A) ((A) & 0x00200000)
173 #define BIT_16(A) ((A) & 0x00400000)
174 #define BIT_17(A) ((A) & 0x00800000)
175 #define BIT_18(A) ((A) & 0x01000000)
176 #define BIT_19(A) ((A) & 0x02000000)
177 #define BIT_1A(A) ((A) & 0x04000000)
178 #define BIT_1B(A) ((A) & 0x08000000)
179 #define BIT_1C(A) ((A) & 0x10000000)
180 #define BIT_1D(A) ((A) & 0x20000000)
181 #define BIT_1E(A) ((A) & 0x40000000)
182 #define BIT_1F(A) ((A) & 0x80000000)
184 /* Get the most significant bit for specific sizes */
185 #define GET_MSB_8(A) ((A) & 0x80)
186 #define GET_MSB_9(A) ((A) & 0x100)
187 #define GET_MSB_16(A) ((A) & 0x8000)
188 #define GET_MSB_17(A) ((A) & 0x10000)
189 #define GET_MSB_32(A) ((A) & 0x80000000)
191 /* Isolate nibbles */
192 #define LOW_NIBBLE(A) ((A) & 0x0f)
193 #define HIGH_NIBBLE(A) ((A) & 0xf0)
195 /* These are used to isolate 8, 16, and 32 bit sizes */
196 #define MASK_OUT_ABOVE_8(A) ((A) & 0xff)
197 #define MASK_OUT_ABOVE_16(A) ((A) & 0xffff)
198 #define MASK_OUT_BELOW_8(A) ((A) & ~0xff)
199 #define MASK_OUT_BELOW_16(A) ((A) & ~0xffff)
201 /* No need for useless masking if we're 32-bit */
203 #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff)
204 #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff)
206 #define MASK_OUT_ABOVE_32(A) (A)
207 #define MASK_OUT_BELOW_32(A) 0
208 #endif /* M68K_OVER_32_BIT */
211 /* Simulate address lines of 68k family */
212 #define ADDRESS_68K(A) (CPU_MODE & CPU_MODE_020_PLUS ? A : (A)&0xffffff)
215 /* Instruction extension word information for indexed addressing modes */
216 #define EXT_INDEX_LONG(A) BIT_B(A)
217 #define EXT_INDEX_AR(A) BIT_F(A)
218 #define EXT_INDEX_REGISTER(A) (((A)>>12)&7)
219 #define EXT_INDEX_SCALE(A) (((A)>>9)&3)
220 #define EXT_BRIEF_FORMAT(A) !BIT_8(A)
221 #define EXT_IX_SUPPRESSED(A) BIT_6(A)
222 #define EXT_BR_SUPPRESSED(A) BIT_7(A)
223 #define EXT_BD_PRESENT(A) BIT_5(A)
224 #define EXT_BD_LONG(A) BIT_4(A)
225 #define EXT_NO_MEMORY_INDIRECT(A) !((A)&7)
226 #define EXT_OD_PRESENT(A) BIT_1(A)
227 #define EXT_OD_LONG(A) BIT_0(A)
228 #define EXT_POSTINDEX(A) BIT_2(A)
231 /* Shift & Rotate Macros.
232 * 32-bit shifts defined in architecture-dependant section.
235 #define LSL(A, C) ((A) << (C))
236 #define LSR(A, C) ((A) >> (C))
238 /* Some > 32-bit optimizations */
240 /* Shift left and right */
241 #define LSR_32(A, C) ((A) >> (C))
242 #define LSL_32(A, C) ((A) << (C))
244 /* We have to do this because the morons at ANSI decided that shifts
245 * by >= data size are undefined.
247 #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
248 #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
249 #endif /* M68K_OVER_32_BIT */
251 #define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C)))
252 #define ROL_9(A, C) LSL(A, C) | LSR(A, 9-(C))
253 #define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C)))
254 #define ROL_17(A, C) LSL(A, C) | LSR(A, 17-(C))
255 #define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C)))
256 #define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C)))
258 #define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C)))
259 #define ROR_9(A, C) LSR(A, C) | LSL(A, 9-(C))
260 #define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C)))
261 #define ROR_17(A, C) LSR(A, C) | LSL(A, 17-(C))
262 #define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C)))
263 #define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C)))
266 /* Access the CPU registers */
267 #define CPU_MODE m68k_cpu.mode
268 #define CPU_D m68k_cpu.dr
269 #define CPU_A m68k_cpu.ar
270 #define CPU_PPC m68k_cpu.ppc
271 #define CPU_PC m68k_cpu.pc
272 #define CPU_SP m68k_cpu.sp
273 #define CPU_USP m68k_cpu.sp[0]
274 #define CPU_ISP m68k_cpu.sp[1]
275 #define CPU_MSP m68k_cpu.sp[3]
276 #define CPU_VBR m68k_cpu.vbr
277 #define CPU_SFC m68k_cpu.sfc
278 #define CPU_DFC m68k_cpu.dfc
279 #define CPU_IR m68k_cpu.ir
280 #define CPU_T1 m68k_cpu.t1_flag
281 #define CPU_T0 m68k_cpu.t0_flag
282 #define CPU_S m68k_cpu.s_flag
283 #define CPU_M m68k_cpu.m_flag
284 #define CPU_X m68k_cpu.x_flag
285 #define CPU_N m68k_cpu.n_flag
286 #define CPU_NOT_Z m68k_cpu.not_z_flag
287 #define CPU_V m68k_cpu.v_flag
288 #define CPU_C m68k_cpu.c_flag
289 #define CPU_INT_MASK m68k_cpu.int_mask
290 #define CPU_INT_STATE m68k_cpu.int_state /* ASG: changed from CPU_INTS_PENDING */
291 #define CPU_STOPPED m68k_cpu.stopped
292 #define CPU_HALTED m68k_cpu.halted
293 #define CPU_INT_CYCLES m68k_cpu.int_cycles /* ASG */
295 #define CPU_INT_ACK_CALLBACK m68k_cpu.int_ack_callback
296 #define CPU_BKPT_ACK_CALLBACK m68k_cpu.bkpt_ack_callback
297 #define CPU_RESET_INSTR_CALLBACK m68k_cpu.reset_instr_callback
298 #define CPU_PC_CHANGED_CALLBACK m68k_cpu.pc_changed_callback
299 #define CPU_SET_FC_CALLBACK m68k_cpu.set_fc_callback
300 #define CPU_INSTR_HOOK_CALLBACK m68k_cpu.instr_hook_callback
304 * The general instruction format follows this pattern:
305 * .... XXX. .... .YYY
306 * where XXX is register X and YYY is register Y
308 /* Data Register Isolation */
309 #define DX (CPU_D[(CPU_IR >> 9) & 7])
310 #define DY (CPU_D[CPU_IR & 7])
311 /* Address Register Isolation */
312 #define AX (CPU_A[(CPU_IR >> 9) & 7])
313 #define AY (CPU_A[CPU_IR & 7])
316 /* Effective Address Calculations */
317 #define EA_AI AY /* address register indirect */
318 #define EA_PI_8 (AY++) /* postincrement (size = byte) */
319 #define EA_PI7_8 ((CPU_A[7]+=2)-2) /* postincrement (size = byte & AR = 7) */
320 #define EA_PI_16 ((AY+=2)-2) /* postincrement (size = word) */
321 #define EA_PI_32 ((AY+=4)-4) /* postincrement (size = long) */
322 #define EA_PD_8 (--AY) /* predecrement (size = byte) */
323 #define EA_PD7_8 (CPU_A[7]-=2) /* predecrement (size = byte & AR = 7) */
324 #define EA_PD_16 (AY-=2) /* predecrement (size = word) */
325 #define EA_PD_32 (AY-=4) /* predecrement (size = long) */
326 #define EA_DI (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */
327 #define EA_IX m68ki_get_ea_ix() /* indirect + index */
328 #define EA_AW MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */
329 #define EA_AL m68ki_read_imm_32() /* absolute long */
330 #define EA_PCIX m68ki_get_ea_pcix() /* pc indirect + index */
333 /* Add and Subtract Flag Calculation Macros */
334 #define VFLAG_ADD_8(S, D, R) GET_MSB_8((S & D & ~R) | (~S & ~D & R))
335 #define VFLAG_ADD_16(S, D, R) GET_MSB_16((S & D & ~R) | (~S & ~D & R))
336 #define VFLAG_ADD_32(S, D, R) GET_MSB_32((S & D & ~R) | (~S & ~D & R))
338 #define CFLAG_ADD_8(S, D, R) GET_MSB_8((S & D) | (~R & D) | (S & ~R))
339 #define CFLAG_ADD_16(S, D, R) GET_MSB_16((S & D) | (~R & D) | (S & ~R))
340 #define CFLAG_ADD_32(S, D, R) GET_MSB_32((S & D) | (~R & D) | (S & ~R))
343 #define VFLAG_SUB_8(S, D, R) GET_MSB_8((~S & D & ~R) | (S & ~D & R))
344 #define VFLAG_SUB_16(S, D, R) GET_MSB_16((~S & D & ~R) | (S & ~D & R))
345 #define VFLAG_SUB_32(S, D, R) GET_MSB_32((~S & D & ~R) | (S & ~D & R))
347 #define CFLAG_SUB_8(S, D, R) GET_MSB_8((S & ~D) | (R & ~D) | (S & R))
348 #define CFLAG_SUB_16(S, D, R) GET_MSB_16((S & ~D) | (R & ~D) | (S & R))
349 #define CFLAG_SUB_32(S, D, R) GET_MSB_32((S & ~D) | (R & ~D) | (S & R))
353 #define CONDITION_HI (CPU_C == 0 && CPU_NOT_Z != 0)
354 #define CONDITION_NOT_HI (CPU_C != 0 || CPU_NOT_Z == 0)
355 #define CONDITION_LS (CPU_C != 0 || CPU_NOT_Z == 0)
356 #define CONDITION_NOT_LS (CPU_C == 0 && CPU_NOT_Z != 0)
357 #define CONDITION_CC (CPU_C == 0)
358 #define CONDITION_NOT_CC (CPU_C != 0)
359 #define CONDITION_CS (CPU_C != 0)
360 #define CONDITION_NOT_CS (CPU_C == 0)
361 #define CONDITION_NE (CPU_NOT_Z != 0)
362 #define CONDITION_NOT_NE (CPU_NOT_Z == 0)
363 #define CONDITION_EQ (CPU_NOT_Z == 0)
364 #define CONDITION_NOT_EQ (CPU_NOT_Z != 0)
365 #define CONDITION_VC (CPU_V == 0)
366 #define CONDITION_NOT_VC (CPU_V != 0)
367 #define CONDITION_VS (CPU_V != 0)
368 #define CONDITION_NOT_VS (CPU_V == 0)
369 #define CONDITION_PL (CPU_N == 0)
370 #define CONDITION_NOT_PL (CPU_N != 0)
371 #define CONDITION_MI (CPU_N != 0)
372 #define CONDITION_NOT_MI (CPU_N == 0)
373 #define CONDITION_GE ((CPU_N == 0) == (CPU_V == 0))
374 #define CONDITION_NOT_GE ((CPU_N == 0) != (CPU_V == 0))
375 #define CONDITION_LT ((CPU_N == 0) != (CPU_V == 0))
376 #define CONDITION_NOT_LT ((CPU_N == 0) == (CPU_V == 0))
377 #define CONDITION_GT (CPU_NOT_Z != 0 && (CPU_N == 0) == (CPU_V == 0))
378 #define CONDITION_NOT_GT (CPU_NOT_Z == 0 || (CPU_N == 0) != (CPU_V == 0))
379 #define CONDITION_LE (CPU_NOT_Z == 0 || (CPU_N == 0) != (CPU_V == 0))
380 #define CONDITION_NOT_LE (CPU_NOT_Z != 0 && (CPU_N == 0) == (CPU_V == 0))
383 /* Use up clock cycles.
384 * NOTE: clock cycles used in here are 99.9% correct for a 68000, not for the
387 #define USE_CLKS(A) m68k_clks_left -= (A)
390 /* Push/pull data to/from the stack */
391 #define m68ki_push_16(A) m68ki_write_16(CPU_A[7]-=2, A)
392 #define m68ki_push_32(A) m68ki_write_32(CPU_A[7]-=4, A)
393 #define m68ki_pull_16() m68ki_read_16((CPU_A[7]+=2) - 2)
394 #define m68ki_pull_32() m68ki_read_32((CPU_A[7]+=4) - 4)
397 /* branch byte and word are for branches, while long is for jumps.
398 * So far it's been safe to not call set_pc() for branch word.
400 #define m68ki_branch_byte(A) CPU_PC += MAKE_INT_8(A)
401 #define m68ki_branch_word(A) CPU_PC += MAKE_INT_16(A)
402 #define m68ki_branch_long(A) m68ki_set_pc(A)
405 /* Get the condition code register */
406 #define m68ki_get_ccr() (((CPU_X != 0) << 4) | \
407 ((CPU_N != 0) << 3) | \
408 ((CPU_NOT_Z == 0) << 2) | \
409 ((CPU_V != 0) << 1) | \
412 /* Get the status register */
413 #define m68ki_get_sr() (((CPU_T1 != 0) << 15) | \
414 ((CPU_T0 != 0) << 14) | \
415 ((CPU_S != 0) << 13) | \
416 ((CPU_M != 0) << 12) | \
417 (CPU_INT_MASK << 8) | \
418 ((CPU_X != 0) << 4) | \
419 ((CPU_N != 0) << 3) | \
420 ((CPU_NOT_Z == 0) << 2) | \
421 ((CPU_V != 0) << 1) | \
426 /* ======================================================================== */
427 /* ========================= CONFIGURATION DEFINES ======================== */
428 /* ======================================================================== */
430 /* Act on values in m68kconf.h */
432 #define m68ki_int_ack(A) CPU_INT_ACK_CALLBACK(A)
434 /* Default action is to used autovector mode, which is most common */
435 #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR
436 #endif /* M68K_INT_ACK */
439 #define m68ki_bkpt_ack(A) CPU_BKPT_ACK_CALLBACK(A)
441 #define m68ki_bkpt_ack(A)
442 #endif /* M68K_BKPT_ACK */
444 #if M68K_OUTPUT_RESET
445 #define m68ki_output_reset() CPU_RESET_INSTR_CALLBACK()
447 #define m68ki_output_reset()
448 #endif /* M68K_OUTPUT_RESET */
451 #define m68ki_pc_changed(A) CPU_PC_CHANGED_CALLBACK(A)
453 #define m68ki_pc_changed(A)
454 #endif /* M68K_PC_CHANGED */
457 #define m68ki_set_fc(A) CPU_SET_FC_CALLBACK(A)
459 #define m68ki_set_fc(A)
460 #endif /* M68K_SET_FC */
463 #define m68ki_instr_hook() CPU_INSTR_HOOK_CALLBACK()
465 #define m68ki_instr_hook()
466 #endif /* M68K_INSTR_HOOK */
469 /* Initiates trace checking before each instruction (t1) */
470 #define m68ki_set_trace() m68k_tracing = CPU_T1
471 /* adds t0 to trace checking if we encounter change of flow */
472 #define m68ki_add_trace() m68k_tracing |= CPU_T0
473 /* Clear all tracing */
474 #define m68ki_clear_trace() m68k_tracing = 0
475 /* Cause a trace exception if we are tracing */
476 #define m68ki_exception_if_trace() if(m68k_tracing) m68ki_exception(EXCEPTION_TRACE)
478 #define m68ki_set_trace()
479 #define m68ki_add_trace()
480 #define m68ki_clear_trace()
481 #define m68ki_exception_if_trace()
482 #endif /* M68K_TRACE */
487 extern char* m68k_disassemble_quick(uint pc
);
488 extern uint m68k_pc_offset
;
489 extern char* m68k_cpu_names
[];
491 #define M68K_DO_LOG(A) if(M68K_LOG) fprintf A
492 #if M68K_LOG_EMULATED_INSTRUCTIONS
493 #define M68K_DO_LOG_EMU(A) if(M68K_LOG) fprintf A
495 #define M68K_DO_LOG_EMU(A)
499 #define M68K_DO_LOG(A)
500 #define M68K_DO_LOG_EMU(A)
505 /* ======================================================================== */
506 /* =============================== PROTOTYPES ============================= */
507 /* ======================================================================== */
511 uint mode
; /* CPU Operation Mode: 68000, 68010, or 68020 */
512 uint dr
[8]; /* Data Registers */
513 uint ar
[8]; /* Address Registers */
514 uint ppc
; /* Previous program counter */
515 uint pc
; /* Program Counter */
516 uint sp
[4]; /* User, Interrupt, and Master Stack Pointers */
517 uint vbr
; /* Vector Base Register (68010+) */
518 uint sfc
; /* Source Function Code Register (m68010+) */
519 uint dfc
; /* Destination Function Code Register (m68010+) */
520 uint ir
; /* Instruction Register */
521 uint t1_flag
; /* Trace 1 */
522 uint t0_flag
; /* Trace 0 */
523 uint s_flag
; /* Supervisor */
524 uint m_flag
; /* Master/Interrupt state */
525 uint x_flag
; /* Extend */
526 uint n_flag
; /* Negative */
527 uint not_z_flag
; /* Zero, inverted for speedups */
528 uint v_flag
; /* Overflow */
529 uint c_flag
; /* Carry */
530 uint int_mask
; /* I0-I2 */
531 uint int_state
; /* Current interrupt state -- ASG: changed from ints_pending */
532 uint stopped
; /* Stopped state */
533 uint halted
; /* Halted state */
534 uint int_cycles
; /* ASG: extra cycles from generated interrupts */
536 /* Callbacks to host */
537 int (*int_ack_callback
)(int int_line
); /* Interrupt Acknowledge */
538 void (*bkpt_ack_callback
)(int data
); /* Breakpoint Acknowledge */
539 void (*reset_instr_callback
)(void); /* Called when a RESET instruction is encountered */
540 void (*pc_changed_callback
)(int new_pc
); /* Called when the PC changes by a large amount */
541 void (*set_fc_callback
)(int new_fc
); /* Called when the CPU function code changes */
542 void (*instr_hook_callback
)(void); /* Called every instruction cycle prior to execution */
548 extern int m68k_clks_left
;
549 extern uint m68k_tracing
;
550 extern uint m68k_sr_implemented_bits
[];
551 extern m68k_cpu_core m68k_cpu
;
552 extern uint
* m68k_cpu_dar
[];
553 extern uint
* m68k_movem_pi_table
[];
554 extern uint
* m68k_movem_pd_table
[];
555 extern uint8 m68k_int_masks
[];
556 extern uint8 m68k_shift_8_table
[];
557 extern uint16 m68k_shift_16_table
[];
558 extern uint m68k_shift_32_table
[];
559 extern uint8 m68k_exception_cycle_table
[];
562 /* Read data from anywhere */
563 INLINE uint
m68ki_read_8 (uint address
);
564 INLINE uint
m68ki_read_16 (uint address
);
565 INLINE uint
m68ki_read_32 (uint address
);
567 /* Write to memory */
568 INLINE
void m68ki_write_8 (uint address
, uint value
);
569 INLINE
void m68ki_write_16(uint address
, uint value
);
570 INLINE
void m68ki_write_32(uint address
, uint value
);
572 /* Read data immediately after the program counter */
573 INLINE uint
m68ki_read_imm_8(void);
574 INLINE uint
m68ki_read_imm_16(void);
575 INLINE uint
m68ki_read_imm_32(void);
577 /* Reads the next word after the program counter */
578 INLINE uint
m68ki_read_instruction(void);
580 /* Read data with specific function code */
581 INLINE uint
m68ki_read_8_fc (uint address
, uint fc
);
582 INLINE uint
m68ki_read_16_fc (uint address
, uint fc
);
583 INLINE uint
m68ki_read_32_fc (uint address
, uint fc
);
585 /* Write data with specific function code */
586 INLINE
void m68ki_write_8_fc (uint address
, uint fc
, uint value
);
587 INLINE
void m68ki_write_16_fc(uint address
, uint fc
, uint value
);
588 INLINE
void m68ki_write_32_fc(uint address
, uint fc
, uint value
);
590 INLINE uint
m68ki_get_ea_ix(void); /* Get ea for address register indirect + index */
591 INLINE uint
m68ki_get_ea_pcix(void); /* Get ea for program counter indirect + index */
592 INLINE uint
m68ki_get_ea_ix_dst(void); /* Get ea ix for destination of move instruction */
594 INLINE
void m68ki_set_s_flag(int value
); /* Set the S flag */
595 INLINE
void m68ki_set_m_flag(int value
); /* Set the M flag */
596 INLINE
void m68ki_set_sm_flag(int s_value
, int m_value
); /* Set the S and M flags */
597 INLINE
void m68ki_set_ccr(uint value
); /* set the condition code register */
598 INLINE
void m68ki_set_sr(uint value
); /* set the status register */
599 INLINE
void m68ki_set_sr_no_int(uint value
); /* ASG: set the status register, but don't check interrupts */
600 INLINE
void m68ki_set_pc(uint address
); /* set the program counter */
601 INLINE
void m68ki_service_interrupt(uint pending_mask
); /* service a pending interrupt -- ASG: added parameter */
602 INLINE
void m68ki_exception(uint vector
); /* process an exception */
603 INLINE
void m68ki_interrupt(uint vector
); /* process an interrupt */
604 INLINE
void m68ki_check_interrupts(void); /* ASG: check for interrupts */
606 /* ======================================================================== */
607 /* =========================== UTILITY FUNCTIONS ========================== */
608 /* ======================================================================== */
610 /* Set the function code and read memory from anywhere. */
611 INLINE uint
m68ki_read_8(uint address
)
613 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
614 return m68k_read_memory_8(ADDRESS_68K(address
));
616 INLINE uint
m68ki_read_16(uint address
)
618 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
619 return m68k_read_memory_16(ADDRESS_68K(address
));
621 INLINE uint
m68ki_read_32(uint address
)
623 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
624 return m68k_read_memory_32(ADDRESS_68K(address
));
628 /* Set the function code and write memory to anywhere. */
629 INLINE
void m68ki_write_8(uint address
, uint value
)
631 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
632 m68k_write_memory_8(ADDRESS_68K(address
), value
);
634 INLINE
void m68ki_write_16(uint address
, uint value
)
636 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
637 m68k_write_memory_16(ADDRESS_68K(address
), value
);
639 INLINE
void m68ki_write_32(uint address
, uint value
)
641 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
642 m68k_write_memory_32(ADDRESS_68K(address
), value
);
646 /* Set the function code and read memory immediately following the PC. */
647 INLINE uint
m68ki_read_imm_8(void)
649 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
651 return m68k_read_immediate_8(ADDRESS_68K(CPU_PC
-1));
653 INLINE uint
m68ki_read_imm_16(void)
655 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
657 return m68k_read_immediate_16(ADDRESS_68K(CPU_PC
-2));
659 INLINE uint
m68ki_read_imm_32(void)
661 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_DATA
: FUNCTION_CODE_USER_DATA
);
663 return m68k_read_immediate_32(ADDRESS_68K(CPU_PC
-4));
667 /* Set the function code and read an instruction immediately following the PC. */
668 INLINE uint
m68ki_read_instruction(void)
670 m68ki_set_fc(CPU_S
? FUNCTION_CODE_SUPERVISOR_PROGRAM
: FUNCTION_CODE_USER_PROGRAM
);
672 return m68k_read_instruction(ADDRESS_68K(CPU_PC
-2));
676 /* Read/Write data with a specific function code (used by MOVES) */
677 INLINE uint
m68ki_read_8_fc(uint address
, uint fc
)
680 return m68k_read_memory_8(ADDRESS_68K(address
));
682 INLINE uint
m68ki_read_16_fc(uint address
, uint fc
)
685 return m68k_read_memory_16(ADDRESS_68K(address
));
687 INLINE uint
m68ki_read_32_fc(uint address
, uint fc
)
690 return m68k_read_memory_32(ADDRESS_68K(address
));
693 INLINE
void m68ki_write_8_fc(uint address
, uint fc
, uint value
)
696 m68k_write_memory_8(ADDRESS_68K(address
), value
);
698 INLINE
void m68ki_write_16_fc(uint address
, uint fc
, uint value
)
701 m68k_write_memory_16(ADDRESS_68K(address
), value
);
703 INLINE
void m68ki_write_32_fc(uint address
, uint fc
, uint value
)
706 m68k_write_memory_32(ADDRESS_68K(address
), value
);
710 /* Decode address register indirect with index */
711 INLINE uint
m68ki_get_ea_ix(void)
713 uint extension
= m68ki_read_imm_16();
714 uint ea_index
= m68k_cpu_dar
[EXT_INDEX_AR(extension
)!=0][EXT_INDEX_REGISTER(extension
)];
718 /* Sign-extend the index value if needed */
719 if(!EXT_INDEX_LONG(extension
))
720 ea_index
= MAKE_INT_16(ea_index
);
722 /* If we're running 010 or less, there's no scale or full extension word mode */
723 if(CPU_MODE
& CPU_MODE_010_LESS
)
724 return base
+ ea_index
+ MAKE_INT_8(extension
);
726 /* Scale the index value */
727 ea_index
<<= EXT_INDEX_SCALE(extension
);
729 /* If we're using brief extension mode, we are done */
730 if(EXT_BRIEF_FORMAT(extension
))
731 return base
+ ea_index
+ MAKE_INT_8(extension
);
733 /* Decode the long extension format */
734 if(EXT_IX_SUPPRESSED(extension
))
736 if(EXT_BR_SUPPRESSED(extension
))
738 if(EXT_BD_PRESENT(extension
))
739 base
+= EXT_BD_LONG(extension
) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
740 if(EXT_NO_MEMORY_INDIRECT(extension
))
741 return base
+ ea_index
;
743 if(EXT_OD_PRESENT(extension
))
744 outer
= EXT_OD_LONG(extension
) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
745 if(EXT_POSTINDEX(extension
))
746 return m68ki_read_32(base
) + ea_index
+ outer
;
747 return m68ki_read_32(base
+ ea_index
) + outer
;
750 /* Decode address register indirect with index for MOVE destination */
751 INLINE uint
m68ki_get_ea_ix_dst(void)
753 uint extension
= m68ki_read_imm_16();
754 uint ea_index
= m68k_cpu_dar
[EXT_INDEX_AR(extension
)!=0][EXT_INDEX_REGISTER(extension
)];
755 uint base
= AX
; /* This is the only thing different from m68ki_get_ea_ix() */
758 /* Sign-extend the index value if needed */
759 if(!EXT_INDEX_LONG(extension
))
760 ea_index
= MAKE_INT_16(ea_index
);
762 /* If we're running 010 or less, there's no scale or full extension word mode */
763 if(CPU_MODE
& CPU_MODE_010_LESS
)
764 return base
+ ea_index
+ MAKE_INT_8(extension
);
766 /* Scale the index value */
767 ea_index
<<= EXT_INDEX_SCALE(extension
);
769 /* If we're using brief extension mode, we are done */
770 if(EXT_BRIEF_FORMAT(extension
))
771 return base
+ ea_index
+ MAKE_INT_8(extension
);
773 /* Decode the long extension format */
774 if(EXT_IX_SUPPRESSED(extension
))
776 if(EXT_BR_SUPPRESSED(extension
))
778 if(EXT_BD_PRESENT(extension
))
779 base
+= EXT_BD_LONG(extension
) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
780 if(EXT_NO_MEMORY_INDIRECT(extension
))
781 return base
+ ea_index
;
783 if(EXT_OD_PRESENT(extension
))
784 outer
= EXT_OD_LONG(extension
) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
785 if(EXT_POSTINDEX(extension
))
786 return m68ki_read_32(base
) + ea_index
+ outer
;
787 return m68ki_read_32(base
+ ea_index
) + outer
;
790 /* Decode program counter indirect with index */
791 INLINE uint
m68ki_get_ea_pcix(void)
793 uint base
= (CPU_PC
+=2) - 2;
794 uint extension
= m68ki_read_16(base
);
795 uint ea_index
= m68k_cpu_dar
[EXT_INDEX_AR(extension
)!=0][EXT_INDEX_REGISTER(extension
)];
798 /* Sign-extend the index value if needed */
799 if(!EXT_INDEX_LONG(extension
))
800 ea_index
= MAKE_INT_16(ea_index
);
802 /* If we're running 010 or less, there's no scale or full extension word mode */
803 if(CPU_MODE
& CPU_MODE_010_LESS
)
804 return base
+ ea_index
+ MAKE_INT_8(extension
);
806 /* Scale the index value */
807 ea_index
<<= EXT_INDEX_SCALE(extension
);
809 /* If we're using brief extension mode, we are done */
810 if(EXT_BRIEF_FORMAT(extension
))
811 return base
+ ea_index
+ MAKE_INT_8(extension
);
813 /* Decode the long extension format */
814 if(EXT_IX_SUPPRESSED(extension
))
816 if(EXT_BR_SUPPRESSED(extension
))
818 if(EXT_BD_PRESENT(extension
))
819 base
+= EXT_BD_LONG(extension
) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
820 if(EXT_NO_MEMORY_INDIRECT(extension
))
821 return base
+ ea_index
;
823 if(EXT_OD_PRESENT(extension
))
824 outer
= EXT_OD_LONG(extension
) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
825 if(EXT_POSTINDEX(extension
))
826 return m68ki_read_32(base
) + ea_index
+ outer
;
827 return m68ki_read_32(base
+ ea_index
) + outer
;
831 /* Set the S flag and change the active stack pointer. */
832 INLINE
void m68ki_set_s_flag(int value
)
834 /* ASG: Only do the rest if we're changing */
835 value
= (value
!= 0);
838 /* Backup the old stack pointer */
839 CPU_SP
[CPU_S
| (CPU_M
& (CPU_S
<<1))] = CPU_A
[7];
842 /* Set the new stack pointer */
843 CPU_A
[7] = CPU_SP
[CPU_S
| (CPU_M
& (CPU_S
<<1))];
847 /* Set the M flag and change the active stack pointer. */
848 INLINE
void m68ki_set_m_flag(int value
)
850 /* ASG: Only do the rest if we're changing */
851 value
= (value
!= 0 && CPU_MODE
& CPU_MODE_020_PLUS
)<<1;
854 /* Backup the old stack pointer */
855 CPU_SP
[CPU_S
| (CPU_M
& (CPU_S
<<1))] = CPU_A
[7];
858 /* Set the new stack pointer */
859 CPU_A
[7] = CPU_SP
[CPU_S
| (CPU_M
& (CPU_S
<<1))];
863 /* Set the S and M flags and change the active stack pointer. */
864 INLINE
void m68ki_set_sm_flag(int s_value
, int m_value
)
866 /* ASG: Only do the rest if we're changing */
867 s_value
= (s_value
!= 0);
868 m_value
= (m_value
!= 0 && CPU_MODE
& CPU_MODE_020_PLUS
)<<1;
869 if (CPU_S
!= s_value
|| CPU_M
!= m_value
)
871 /* Backup the old stack pointer */
872 CPU_SP
[CPU_S
| (CPU_M
& (CPU_S
<<1))] = CPU_A
[7];
873 /* Set the S and M flags */
874 CPU_S
= s_value
!= 0;
875 CPU_M
= (m_value
!= 0 && CPU_MODE
& CPU_MODE_020_PLUS
)<<1;
876 /* Set the new stack pointer */
877 CPU_A
[7] = CPU_SP
[CPU_S
| (CPU_M
& (CPU_S
<<1))];
882 /* Set the condition code register */
883 INLINE
void m68ki_set_ccr(uint value
)
885 CPU_X
= BIT_4(value
);
886 CPU_N
= BIT_3(value
);
887 CPU_NOT_Z
= !BIT_2(value
);
888 CPU_V
= BIT_1(value
);
889 CPU_C
= BIT_0(value
);
892 /* Set the status register */
893 INLINE
void m68ki_set_sr(uint value
)
895 /* ASG: detect changes to the INT_MASK */
896 int old_mask
= CPU_INT_MASK
;
898 /* Mask out the "unimplemented" bits */
899 value
&= m68k_sr_implemented_bits
[CPU_MODE
];
901 /* Now set the status register */
902 CPU_T1
= BIT_F(value
);
903 CPU_T0
= BIT_E(value
);
904 CPU_INT_MASK
= (value
>> 8) & 7;
905 CPU_X
= BIT_4(value
);
906 CPU_N
= BIT_3(value
);
907 CPU_NOT_Z
= !BIT_2(value
);
908 CPU_V
= BIT_1(value
);
909 CPU_C
= BIT_0(value
);
910 m68ki_set_sm_flag(BIT_D(value
), BIT_C(value
));
912 /* ASG: detect changes to the INT_MASK */
913 if (CPU_INT_MASK
!= old_mask
)
914 m68ki_check_interrupts();
918 /* Set the status register */
919 INLINE
void m68ki_set_sr_no_int(uint value
)
921 /* Mask out the "unimplemented" bits */
922 value
&= m68k_sr_implemented_bits
[CPU_MODE
];
924 /* Now set the status register */
925 CPU_T1
= BIT_F(value
);
926 CPU_T0
= BIT_E(value
);
927 CPU_INT_MASK
= (value
>> 8) & 7;
928 CPU_X
= BIT_4(value
);
929 CPU_N
= BIT_3(value
);
930 CPU_NOT_Z
= !BIT_2(value
);
931 CPU_V
= BIT_1(value
);
932 CPU_C
= BIT_0(value
);
933 m68ki_set_sm_flag(BIT_D(value
), BIT_C(value
));
937 /* I set the PC this way to let host programs be nicer.
938 * This is mainly for programs running from separate ram banks.
939 * If the host program knows where the PC is, it can offer faster
940 * ram access times for data to be retrieved immediately following
943 INLINE
void m68ki_set_pc(uint address
)
945 /* Set the program counter */
947 /* Inform the host program */
949 // change_pc24(ADDRESS_68K(address));
951 m68ki_pc_changed(ADDRESS_68K(address));
956 /* Process an exception */
957 INLINE
void m68ki_exception(uint vector
)
959 /* Save the old status register */
960 uint old_sr
= m68ki_get_sr();
962 /* Use up some clock cycles */
963 USE_CLKS(m68k_exception_cycle_table
[vector
]);
965 /* Turn off stopped state and trace flag, clear pending traces */
969 /* Enter supervisor mode */
971 /* Push a stack frame */
972 if(CPU_MODE
& CPU_MODE_010_PLUS
)
973 m68ki_push_16(vector
<<2); /* This is format 0 */
974 m68ki_push_32(CPU_PPC
); /* save previous PC, ie. PC that contains an offending instruction */
975 m68ki_push_16(old_sr
);
976 /* Generate a new program counter from the vector */
977 m68ki_set_pc(m68ki_read_32((vector
<<2)+CPU_VBR
));
981 /* Process an interrupt (or trap) */
982 INLINE
void m68ki_interrupt(uint vector
)
984 /* Save the old status register */
985 uint old_sr
= m68ki_get_sr();
987 /* Use up some clock cycles */
988 /* ASG: just keep them pending */
989 /* USE_CLKS(m68k_exception_cycle_table[vector]);*/
990 CPU_INT_CYCLES
+= m68k_exception_cycle_table
[vector
];
992 /* Turn off stopped state and trace flag, clear pending traces */
996 /* Enter supervisor mode */
998 /* Push a stack frame */
999 if(CPU_MODE
& CPU_MODE_010_PLUS
)
1000 m68ki_push_16(vector
<<2); /* This is format 0 */
1001 m68ki_push_32(CPU_PC
);
1002 m68ki_push_16(old_sr
);
1003 /* Generate a new program counter from the vector */
1004 m68ki_set_pc(m68ki_read_32((vector
<<2)+CPU_VBR
));
1008 /* Service an interrupt request */
1009 INLINE
void m68ki_service_interrupt(uint pending_mask
) /* ASG: added parameter here */
1014 /* Start at level 7 and then go down */
1015 for(;!(pending_mask
& (1<<int_level
));int_level
--) /* ASG: changed to use parameter instead of CPU_INTS_PENDING */
1018 /* Get the exception vector */
1019 switch(vector
= m68ki_int_ack(int_level
))
1021 case 0x00: case 0x01:
1022 /* vectors 0 and 1 are ignored since they are for reset only */
1024 case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
1025 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
1026 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
1027 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
1028 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
1029 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
1030 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
1031 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
1032 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
1033 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
1034 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
1035 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
1036 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
1037 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
1038 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
1039 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
1040 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
1041 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
1042 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
1043 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
1044 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
1045 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
1046 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
1047 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
1048 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1049 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
1050 case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
1051 case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
1052 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
1053 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
1054 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
1055 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
1056 /* The external peripheral has provided the interrupt vector to take */
1058 case M68K_INT_ACK_AUTOVECTOR
:
1059 /* Use the autovectors. This is the most commonly used implementation */
1060 vector
= EXCEPTION_INTERRUPT_AUTOVECTOR
+int_level
;
1062 case M68K_INT_ACK_SPURIOUS
:
1063 /* Called if no devices respond to the interrupt acknowledge */
1064 vector
= EXCEPTION_SPURIOUS_INTERRUPT
;
1067 /* Everything else is ignored */
1071 /* If vector is uninitialized, call the uninitialized interrupt vector */
1072 if(m68ki_read_32(vector
<<2) == 0)
1073 vector
= EXCEPTION_UNINITIALIZED_INTERRUPT
;
1075 /* Generate an interupt */
1076 m68ki_interrupt(vector
);
1078 /* Set the interrupt mask to the level of the one being serviced */
1079 CPU_INT_MASK
= int_level
;
1083 /* ASG: Check for interrupts */
1084 INLINE
void m68ki_check_interrupts(void)
1086 uint pending_mask
= 1 << CPU_INT_STATE
;
1087 if (pending_mask
& m68k_int_masks
[CPU_INT_MASK
])
1088 m68ki_service_interrupt(pending_mask
);
1092 #endif /* M68KCPU__HEADER */