Import Upstream version 1.23
[debian-dgen.git] / musa / m68kcpu.h
blob47eed811ba9e0f5ae3093ac21cd8537585f48759
1 #ifndef M68KCPU__HEADER
2 #define M68KCPU__HEADER
5 #include "m68k.h"
6 #include <limits.h>
8 /* ======================================================================== */
9 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
10 /* ======================================================================== */
12 /* Check if we have certain storage sizes */
14 #if UCHAR_MAX == 0xff
15 #define M68K_HAS_8_BIT_SIZE 1
16 #else
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
22 #else
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
28 #else
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
34 #else
35 #define M68K_OVER_32_BIT 0
36 #endif /* UINT_MAX > 0xffffffff */
38 /* Data types used in this emulation core */
39 #undef int8
40 #undef int16
41 #undef int32
42 #undef uint
43 #undef uint8
44 #undef uint16
45 #undef uint
47 #define int8 signed char /* ASG: changed from char to signed char */
48 #define uint8 unsigned char
49 #define int16 short
50 #define uint16 unsigned short
51 #define int32 long
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)
60 #else
61 #undef int8
62 #define int8 int
63 #undef uint8
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)
76 #else
77 #undef int16
78 #define int16 int
79 #undef uint16
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
91 #if M68K_OVER_32_BIT
92 #define MAKE_INT_32(A) (int32)((A)&0xffffffff)
93 #else
94 #define MAKE_INT_32(A) (int32)(A)
95 #endif /* M68K_OVER_32_BIT */
96 #else
97 #undef int32
98 #define int32 int
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 */
202 #if M68K_OVER_32_BIT
203 #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff)
204 #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff)
205 #else
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 */
239 #if M68K_OVER_32_BIT
240 /* Shift left and right */
241 #define LSR_32(A, C) ((A) >> (C))
242 #define LSL_32(A, C) ((A) << (C))
243 #else
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))
352 /* Conditions */
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
385 * higher processors.
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) | \
410 (CPU_C != 0))
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) | \
422 (CPU_C != 0))
426 /* ======================================================================== */
427 /* ========================= CONFIGURATION DEFINES ======================== */
428 /* ======================================================================== */
430 /* Act on values in m68kconf.h */
431 #if M68K_INT_ACK
432 #define m68ki_int_ack(A) CPU_INT_ACK_CALLBACK(A)
433 #else
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 */
438 #if M68K_BKPT_ACK
439 #define m68ki_bkpt_ack(A) CPU_BKPT_ACK_CALLBACK(A)
440 #else
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()
446 #else
447 #define m68ki_output_reset()
448 #endif /* M68K_OUTPUT_RESET */
450 #if M68K_PC_CHANGED
451 #define m68ki_pc_changed(A) CPU_PC_CHANGED_CALLBACK(A)
452 #else
453 #define m68ki_pc_changed(A)
454 #endif /* M68K_PC_CHANGED */
456 #if M68K_SET_FC
457 #define m68ki_set_fc(A) CPU_SET_FC_CALLBACK(A)
458 #else
459 #define m68ki_set_fc(A)
460 #endif /* M68K_SET_FC */
462 #if M68K_INSTR_HOOK
463 #define m68ki_instr_hook() CPU_INSTR_HOOK_CALLBACK()
464 #else
465 #define m68ki_instr_hook()
466 #endif /* M68K_INSTR_HOOK */
468 #if M68K_TRACE
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)
477 #else
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 */
485 #ifdef M68K_LOG
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
494 #else
495 #define M68K_DO_LOG_EMU(A)
496 #endif
498 #else
499 #define M68K_DO_LOG(A)
500 #define M68K_DO_LOG_EMU(A)
502 #endif
505 /* ======================================================================== */
506 /* =============================== PROTOTYPES ============================= */
507 /* ======================================================================== */
509 typedef struct
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 */
544 } m68k_cpu_core;
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);
650 CPU_PC += 2;
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);
656 CPU_PC += 2;
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);
662 CPU_PC += 4;
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);
671 CPU_PC += 2;
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)
679 m68ki_set_fc(fc&7);
680 return m68k_read_memory_8(ADDRESS_68K(address));
682 INLINE uint m68ki_read_16_fc(uint address, uint fc)
684 m68ki_set_fc(fc&7);
685 return m68k_read_memory_16(ADDRESS_68K(address));
687 INLINE uint m68ki_read_32_fc(uint address, uint fc)
689 m68ki_set_fc(fc&7);
690 return m68k_read_memory_32(ADDRESS_68K(address));
693 INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
695 m68ki_set_fc(fc&7);
696 m68k_write_memory_8(ADDRESS_68K(address), value);
698 INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
700 m68ki_set_fc(fc&7);
701 m68k_write_memory_16(ADDRESS_68K(address), value);
703 INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
705 m68ki_set_fc(fc&7);
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)];
715 uint base = AY;
716 uint outer = 0;
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))
735 ea_index = 0;
736 if(EXT_BR_SUPPRESSED(extension))
737 base = 0;
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() */
756 uint outer = 0;
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))
775 ea_index = 0;
776 if(EXT_BR_SUPPRESSED(extension))
777 base = 0;
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)];
796 uint outer = 0;
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))
815 ea_index = 0;
816 if(EXT_BR_SUPPRESSED(extension))
817 base = 0;
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);
836 if (CPU_S != value)
838 /* Backup the old stack pointer */
839 CPU_SP[CPU_S | (CPU_M & (CPU_S<<1))] = CPU_A[7];
840 /* Set the S flag */
841 CPU_S = value;
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;
852 if (CPU_M != value)
854 /* Backup the old stack pointer */
855 CPU_SP[CPU_S | (CPU_M & (CPU_S<<1))] = CPU_A[7];
856 /* Set the M flag */
857 CPU_M = value;
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
941 * the PC.
943 INLINE void m68ki_set_pc(uint address)
945 /* Set the program counter */
946 CPU_PC = address;
947 /* Inform the host program */
948 /* MAME */
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 */
966 CPU_STOPPED = 0;
967 CPU_T1 = CPU_T0 = 0;
968 m68ki_clear_trace();
969 /* Enter supervisor mode */
970 m68ki_set_s_flag(1);
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 */
993 CPU_STOPPED = 0;
994 CPU_T1 = CPU_T0 = 0;
995 m68ki_clear_trace();
996 /* Enter supervisor mode */
997 m68ki_set_s_flag(1);
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 */
1011 uint int_level = 7;
1012 uint vector;
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 */
1023 return;
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 */
1057 break;
1058 case M68K_INT_ACK_AUTOVECTOR:
1059 /* Use the autovectors. This is the most commonly used implementation */
1060 vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
1061 break;
1062 case M68K_INT_ACK_SPURIOUS:
1063 /* Called if no devices respond to the interrupt acknowledge */
1064 vector = EXCEPTION_SPURIOUS_INTERRUPT;
1065 break;
1066 default:
1067 /* Everything else is ignored */
1068 return;
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 */