]> git.sesse.net Git - pistorm/blob - m68kcpu.h
MMU and InstructionCache update (MAME's latest code)
[pistorm] / m68kcpu.h
1 /* ======================================================================== */
2 /* ========================= LICENSING & COPYRIGHT ======================== */
3 /* ======================================================================== */
4 /*
5  *                                  MUSASHI
6  *                                Version 4.5
7  *
8  * A portable Motorola M680x0 processor emulation engine.
9  * Copyright Karl Stenerud.  All rights reserved.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27  * THE SOFTWARE.
28  */
29
30
31
32
33 #ifndef M68KCPU__HEADER
34 #define M68KCPU__HEADER
35
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 #include "m68k.h"
41
42 #include <limits.h>
43 #include <endian.h>
44
45 #include <setjmp.h>
46
47 /* ======================================================================== */
48 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
49 /* ======================================================================== */
50
51 /* Check for > 32bit sizes */
52 #if UINT_MAX > 0xffffffff
53         #define M68K_INT_GT_32_BIT  1
54 #else
55         #define M68K_INT_GT_32_BIT  0
56 #endif
57
58 /* Data types used in this emulation core */
59 #undef sint8
60 #undef sint16
61 #undef sint32
62 #undef sint64
63 #undef uint8
64 #undef uint16
65 #undef uint32
66 #undef uint64
67 #undef sint
68 #undef uint
69
70 typedef signed   char  sint8;           /* ASG: changed from char to signed char */
71 typedef signed   short sint16;
72 typedef signed   int   sint32;          /* AWJ: changed from long to int */
73 typedef unsigned char  uint8;
74 typedef unsigned short uint16;
75 typedef unsigned int   uint32;                  /* AWJ: changed from long to int */
76
77 /* signed and unsigned int must be at least 32 bits wide */
78 typedef signed   int sint;
79 typedef unsigned int uint;
80
81
82 #if M68K_USE_64_BIT
83 typedef signed   long long sint64;
84 typedef unsigned long long uint64;
85 #else
86 typedef sint32 sint64;
87 typedef uint32 uint64;
88 #endif /* M68K_USE_64_BIT */
89
90 /* U64 and S64 are used to wrap long integer constants. */
91 #ifdef __GNUC__
92 #define U64(val) val##ULL
93 #define S64(val) val##LL
94 #else
95 #define U64(val) val
96 #define S64(val) val
97 #endif
98
99 #include "softfloat/milieu.h"
100 #include "softfloat/softfloat.h"
101
102
103 /* Allow for architectures that don't have 8-bit sizes */
104 #if UCHAR_MAX == 0xff
105         #define MAKE_INT_8(A) (sint8)(A)
106 #else
107         #undef  sint8
108         #define sint8  signed   int
109         #undef  uint8
110         #define uint8  unsigned int
111         static inline sint MAKE_INT_8(uint value)
112         {
113                 return (value & 0x80) ? value | ~0xff : value & 0xff;
114         }
115 #endif /* UCHAR_MAX == 0xff */
116
117
118 /* Allow for architectures that don't have 16-bit sizes */
119 #if USHRT_MAX == 0xffff
120         #define MAKE_INT_16(A) (sint16)(A)
121 #else
122         #undef  sint16
123         #define sint16 signed   int
124         #undef  uint16
125         #define uint16 unsigned int
126         static inline sint MAKE_INT_16(uint value)
127         {
128                 return (value & 0x8000) ? value | ~0xffff : value & 0xffff;
129         }
130 #endif /* USHRT_MAX == 0xffff */
131
132
133 /* Allow for architectures that don't have 32-bit sizes */
134 #if UINT_MAX == 0xffffffff
135         #define MAKE_INT_32(A) (sint32)(A)
136 #else
137         #undef  sint32
138         #define sint32  signed   int
139         #undef  uint32
140         #define uint32  unsigned int
141         static inline sint MAKE_INT_32(uint value)
142         {
143                 return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff;
144         }
145 #endif /* UINT_MAX == 0xffffffff */
146
147 /* ======================================================================== */
148 /* ============================ GENERAL DEFINES =========================== */
149 /* ======================================================================== */
150
151 /* MMU constants */
152 #define MMU_ATC_ENTRIES 22    // 68851 has 64, 030 has 22
153
154 /* instruction cache constants */
155 #define M68K_IC_SIZE 128
156
157 /* Exception Vectors handled by emulation */
158 #define EXCEPTION_RESET                    0
159 #define EXCEPTION_BUS_ERROR                2 /* This one is not emulated! */
160 #define EXCEPTION_ADDRESS_ERROR            3 /* This one is partially emulated (doesn't stack a proper frame yet) */
161 #define EXCEPTION_ILLEGAL_INSTRUCTION      4
162 #define EXCEPTION_ZERO_DIVIDE              5
163 #define EXCEPTION_CHK                      6
164 #define EXCEPTION_TRAPV                    7
165 #define EXCEPTION_PRIVILEGE_VIOLATION      8
166 #define EXCEPTION_TRACE                    9
167 #define EXCEPTION_1010                    10
168 #define EXCEPTION_1111                    11
169 #define EXCEPTION_FORMAT_ERROR            14
170 #define EXCEPTION_UNINITIALIZED_INTERRUPT 15
171 #define EXCEPTION_SPURIOUS_INTERRUPT      24
172 #define EXCEPTION_INTERRUPT_AUTOVECTOR    24
173 #define EXCEPTION_TRAP_BASE               32
174 #define EXCEPTION_MMU_CONFIGURATION       56 // only on 020/030
175
176 /* Function codes set by CPU during data/address bus activity */
177 #define FUNCTION_CODE_USER_DATA          1
178 #define FUNCTION_CODE_USER_PROGRAM       2
179 #define FUNCTION_CODE_SUPERVISOR_DATA    5
180 #define FUNCTION_CODE_SUPERVISOR_PROGRAM 6
181 #define FUNCTION_CODE_CPU_SPACE          7
182
183 /* CPU types for deciding what to emulate */
184 #define CPU_TYPE_000    (0x00000001)
185 #define CPU_TYPE_008    (0x00000002)
186 #define CPU_TYPE_010    (0x00000004)
187 #define CPU_TYPE_EC020  (0x00000008)
188 #define CPU_TYPE_020    (0x00000010)
189 #define CPU_TYPE_EC030  (0x00000020)
190 #define CPU_TYPE_030    (0x00000040)
191 #define CPU_TYPE_EC040  (0x00000080)
192 #define CPU_TYPE_LC040  (0x00000100)
193 #define CPU_TYPE_040    (0x00000200)
194 #define CPU_TYPE_SCC070 (0x00000400)
195
196 /* Different ways to stop the CPU */
197 #define STOP_LEVEL_STOP 1
198 #define STOP_LEVEL_HALT 2
199
200 /* Used for 68000 address error processing */
201 #define INSTRUCTION_YES 0
202 #define INSTRUCTION_NO  0x08
203 #define MODE_READ       0x10
204 #define MODE_WRITE      0
205
206 #define RUN_MODE_NORMAL              0
207 #define RUN_MODE_BERR_AERR_RESET_WSF 1 // writing the stack frame
208 #define RUN_MODE_BERR_AERR_RESET     2 // stack frame done
209
210 #define M68K_CACR_IBE  0x10 // Instruction Burst Enable
211 #define M68K_CACR_CI   0x08 // Clear Instruction Cache
212 #define M68K_CACR_CEI  0x04 // Clear Entry in Instruction Cache
213 #define M68K_CACR_FI   0x02 // Freeze Instruction Cache
214 #define M68K_CACR_EI   0x01 // Enable Instruction Cache
215
216 #ifndef NULL
217 #define NULL ((void*)0)
218 #endif
219
220 /* ======================================================================== */
221 /* ================================ MACROS ================================ */
222 /* ======================================================================== */
223
224
225 /* ---------------------------- General Macros ---------------------------- */
226
227 /* Bit Isolation Macros */
228 #define BIT_0(A)  ((A) & 0x00000001)
229 #define BIT_1(A)  ((A) & 0x00000002)
230 #define BIT_2(A)  ((A) & 0x00000004)
231 #define BIT_3(A)  ((A) & 0x00000008)
232 #define BIT_4(A)  ((A) & 0x00000010)
233 #define BIT_5(A)  ((A) & 0x00000020)
234 #define BIT_6(A)  ((A) & 0x00000040)
235 #define BIT_7(A)  ((A) & 0x00000080)
236 #define BIT_8(A)  ((A) & 0x00000100)
237 #define BIT_9(A)  ((A) & 0x00000200)
238 #define BIT_A(A)  ((A) & 0x00000400)
239 #define BIT_B(A)  ((A) & 0x00000800)
240 #define BIT_C(A)  ((A) & 0x00001000)
241 #define BIT_D(A)  ((A) & 0x00002000)
242 #define BIT_E(A)  ((A) & 0x00004000)
243 #define BIT_F(A)  ((A) & 0x00008000)
244 #define BIT_10(A) ((A) & 0x00010000)
245 #define BIT_11(A) ((A) & 0x00020000)
246 #define BIT_12(A) ((A) & 0x00040000)
247 #define BIT_13(A) ((A) & 0x00080000)
248 #define BIT_14(A) ((A) & 0x00100000)
249 #define BIT_15(A) ((A) & 0x00200000)
250 #define BIT_16(A) ((A) & 0x00400000)
251 #define BIT_17(A) ((A) & 0x00800000)
252 #define BIT_18(A) ((A) & 0x01000000)
253 #define BIT_19(A) ((A) & 0x02000000)
254 #define BIT_1A(A) ((A) & 0x04000000)
255 #define BIT_1B(A) ((A) & 0x08000000)
256 #define BIT_1C(A) ((A) & 0x10000000)
257 #define BIT_1D(A) ((A) & 0x20000000)
258 #define BIT_1E(A) ((A) & 0x40000000)
259 #define BIT_1F(A) ((A) & 0x80000000)
260
261 /* Get the most significant bit for specific sizes */
262 #define GET_MSB_8(A)  ((A) & 0x80)
263 #define GET_MSB_9(A)  ((A) & 0x100)
264 #define GET_MSB_16(A) ((A) & 0x8000)
265 #define GET_MSB_17(A) ((A) & 0x10000)
266 #define GET_MSB_32(A) ((A) & 0x80000000)
267 #if M68K_USE_64_BIT
268 #define GET_MSB_33(A) ((A) & 0x100000000)
269 #endif /* M68K_USE_64_BIT */
270
271 /* Isolate nibbles */
272 #define LOW_NIBBLE(A)  ((A) & 0x0f)
273 #define HIGH_NIBBLE(A) ((A) & 0xf0)
274
275 /* These are used to isolate 8, 16, and 32 bit sizes */
276 #define MASK_OUT_ABOVE_2(A)  ((A) & 3)
277 #define MASK_OUT_ABOVE_8(A)  ((A) & 0xff)
278 #define MASK_OUT_ABOVE_16(A) ((A) & 0xffff)
279 #define MASK_OUT_BELOW_2(A)  ((A) & ~3)
280 #define MASK_OUT_BELOW_8(A)  ((A) & ~0xff)
281 #define MASK_OUT_BELOW_16(A) ((A) & ~0xffff)
282
283 /* No need to mask if we are 32 bit */
284 #if M68K_INT_GT_32_BIT || M68K_USE_64_BIT
285         #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff)
286         #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff)
287 #else
288         #define MASK_OUT_ABOVE_32(A) (A)
289         #define MASK_OUT_BELOW_32(A) 0
290 #endif /* M68K_INT_GT_32_BIT || M68K_USE_64_BIT */
291
292 /* Simulate address lines of 68k family */
293 #define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK)
294
295
296 /* Shift & Rotate Macros. */
297 #define LSL(A, C) ((A) << (C))
298 #define LSR(A, C) ((A) >> (C))
299
300 /* Some > 32-bit optimizations */
301 #if M68K_INT_GT_32_BIT
302         /* Shift left and right */
303         #define LSR_32(A, C) ((A) >> (C))
304         #define LSL_32(A, C) ((A) << (C))
305 #else
306         /* We have to do this because the morons at ANSI decided that shifts
307          * by >= data size are undefined.
308          */
309         #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
310         #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
311 #endif /* M68K_INT_GT_32_BIT */
312
313 #if M68K_USE_64_BIT
314         #define LSL_32_64(A, C) ((A) << (C))
315         #define LSR_32_64(A, C) ((A) >> (C))
316         #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C)))
317         #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C)))
318 #endif /* M68K_USE_64_BIT */
319
320 #define ROL_8(A, C)      MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C)))
321 #define ROL_9(A, C)                      (LSL(A, C) | LSR(A, 9-(C)))
322 #define ROL_16(A, C)    MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C)))
323 #define ROL_17(A, C)                     (LSL(A, C) | LSR(A, 17-(C)))
324 #define ROL_32(A, C)    MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C)))
325 #define ROL_33(A, C)                     (LSL_32(A, C) | LSR_32(A, 33-(C)))
326
327 #define ROR_8(A, C)      MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C)))
328 #define ROR_9(A, C)                      (LSR(A, C) | LSL(A, 9-(C)))
329 #define ROR_16(A, C)    MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C)))
330 #define ROR_17(A, C)                     (LSR(A, C) | LSL(A, 17-(C)))
331 #define ROR_32(A, C)    MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C)))
332 #define ROR_33(A, C)                     (LSR_32(A, C) | LSL_32(A, 33-(C)))
333
334
335
336 /* ------------------------------ CPU Access ------------------------------ */
337
338 /* Access the CPU registers */
339 #define CPU_TYPE         m68ki_cpu.cpu_type
340
341 #define REG_DA           m68ki_cpu.dar /* easy access to data and address regs */
342 #define REG_DA_SAVE      m68ki_cpu.dar_save
343 #define REG_D            m68ki_cpu.dar
344 #define REG_A            (m68ki_cpu.dar+8)
345 #define REG_PPC          m68ki_cpu.ppc
346 #define REG_PC           m68ki_cpu.pc
347 #define REG_SP_BASE      m68ki_cpu.sp
348 #define REG_USP          m68ki_cpu.sp[0]
349 #define REG_ISP          m68ki_cpu.sp[4]
350 #define REG_MSP          m68ki_cpu.sp[6]
351 #define REG_SP           m68ki_cpu.dar[15]
352 #define REG_VBR          m68ki_cpu.vbr
353 #define REG_SFC          m68ki_cpu.sfc
354 #define REG_DFC          m68ki_cpu.dfc
355 #define REG_CACR         m68ki_cpu.cacr
356 #define REG_CAAR         m68ki_cpu.caar
357 #define REG_IR           m68ki_cpu.ir
358
359 #define REG_FP           m68ki_cpu.fpr
360 #define REG_FPCR         m68ki_cpu.fpcr
361 #define REG_FPSR         m68ki_cpu.fpsr
362 #define REG_FPIAR        m68ki_cpu.fpiar
363
364 #define FLAG_T1          m68ki_cpu.t1_flag
365 #define FLAG_T0          m68ki_cpu.t0_flag
366 #define FLAG_S           m68ki_cpu.s_flag
367 #define FLAG_M           m68ki_cpu.m_flag
368 #define FLAG_X           m68ki_cpu.x_flag
369 #define FLAG_N           m68ki_cpu.n_flag
370 #define FLAG_Z           m68ki_cpu.not_z_flag
371 #define FLAG_V           m68ki_cpu.v_flag
372 #define FLAG_C           m68ki_cpu.c_flag
373 #define FLAG_INT_MASK    m68ki_cpu.int_mask
374
375 #define CPU_INT_LEVEL    m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */
376 #define CPU_STOPPED      m68ki_cpu.stopped
377 #define CPU_PREF_ADDR    m68ki_cpu.pref_addr
378 #define CPU_PREF_DATA    m68ki_cpu.pref_data
379 #define CPU_ADDRESS_MASK m68ki_cpu.address_mask
380 #define CPU_SR_MASK      m68ki_cpu.sr_mask
381 #define CPU_INSTR_MODE   m68ki_cpu.instr_mode
382 #define CPU_RUN_MODE     m68ki_cpu.run_mode
383
384 #define CYC_INSTRUCTION  m68ki_cpu.cyc_instruction
385 #define CYC_EXCEPTION    m68ki_cpu.cyc_exception
386 #define CYC_BCC_NOTAKE_B m68ki_cpu.cyc_bcc_notake_b
387 #define CYC_BCC_NOTAKE_W m68ki_cpu.cyc_bcc_notake_w
388 #define CYC_DBCC_F_NOEXP m68ki_cpu.cyc_dbcc_f_noexp
389 #define CYC_DBCC_F_EXP   m68ki_cpu.cyc_dbcc_f_exp
390 #define CYC_SCC_R_TRUE   m68ki_cpu.cyc_scc_r_true
391 #define CYC_MOVEM_W      m68ki_cpu.cyc_movem_w
392 #define CYC_MOVEM_L      m68ki_cpu.cyc_movem_l
393 #define CYC_SHIFT        m68ki_cpu.cyc_shift
394 #define CYC_RESET        m68ki_cpu.cyc_reset
395 #define HAS_PMMU         m68ki_cpu.has_pmmu
396 #define HAS_FPU          m68ki_cpu.has_fpu
397 #define PMMU_ENABLED     m68ki_cpu.pmmu_enabled
398 #define RESET_CYCLES     m68ki_cpu.reset_cycles
399
400
401 #define CALLBACK_INT_ACK      m68ki_cpu.int_ack_callback
402 #define CALLBACK_BKPT_ACK     m68ki_cpu.bkpt_ack_callback
403 #define CALLBACK_RESET_INSTR  m68ki_cpu.reset_instr_callback
404 #define CALLBACK_CMPILD_INSTR m68ki_cpu.cmpild_instr_callback
405 #define CALLBACK_RTE_INSTR    m68ki_cpu.rte_instr_callback
406 #define CALLBACK_TAS_INSTR    m68ki_cpu.tas_instr_callback
407 #define CALLBACK_ILLG_INSTR   m68ki_cpu.illg_instr_callback
408 #define CALLBACK_PC_CHANGED   m68ki_cpu.pc_changed_callback
409 #define CALLBACK_SET_FC       m68ki_cpu.set_fc_callback
410 #define CALLBACK_INSTR_HOOK   m68ki_cpu.instr_hook_callback
411
412
413
414 /* ----------------------------- Configuration ---------------------------- */
415
416 /* These defines are dependant on the configuration defines in m68kconf.h */
417
418 /* Disable certain comparisons if we're not using all CPU types */
419 #if M68K_EMULATE_040
420 #define CPU_TYPE_IS_040_PLUS(A)    ((A) & (CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_LC040))
421         #define CPU_TYPE_IS_040_LESS(A)    1
422 #else
423         #define CPU_TYPE_IS_040_PLUS(A)    0
424         #define CPU_TYPE_IS_040_LESS(A)    1
425 #endif
426
427 #if M68K_EMULATE_030
428 #define CPU_TYPE_IS_030_PLUS(A)    ((A) & (CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_LC040))
429 #define CPU_TYPE_IS_030_LESS(A)    1
430 #else
431 #define CPU_TYPE_IS_030_PLUS(A) 0
432 #define CPU_TYPE_IS_030_LESS(A)    1
433 #endif
434
435 #if M68K_EMULATE_020
436 #define CPU_TYPE_IS_020_PLUS(A)    ((A) & (CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_LC040))
437         #define CPU_TYPE_IS_020_LESS(A)    1
438 #else
439         #define CPU_TYPE_IS_020_PLUS(A)    0
440         #define CPU_TYPE_IS_020_LESS(A)    1
441 #endif
442
443 #if M68K_EMULATE_EC020
444 #define CPU_TYPE_IS_EC020_PLUS(A)  ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_LC040))
445         #define CPU_TYPE_IS_EC020_LESS(A)  ((A) & (CPU_TYPE_000 | CPU_TYPE_010 | CPU_TYPE_EC020))
446 #else
447         #define CPU_TYPE_IS_EC020_PLUS(A)  CPU_TYPE_IS_020_PLUS(A)
448         #define CPU_TYPE_IS_EC020_LESS(A)  CPU_TYPE_IS_020_LESS(A)
449 #endif
450
451 #if M68K_EMULATE_010
452         #define CPU_TYPE_IS_010(A)         ((A) == CPU_TYPE_010)
453 #define CPU_TYPE_IS_010_PLUS(A)    ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_LC040))
454 #define CPU_TYPE_IS_010_LESS(A)    ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010))
455 #else
456         #define CPU_TYPE_IS_010(A)         0
457         #define CPU_TYPE_IS_010_PLUS(A)    CPU_TYPE_IS_EC020_PLUS(A)
458         #define CPU_TYPE_IS_010_LESS(A)    CPU_TYPE_IS_EC020_LESS(A)
459 #endif
460
461 #if M68K_EMULATE_020 || M68K_EMULATE_EC020
462         #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
463 #else
464         #define CPU_TYPE_IS_020_VARIANT(A) 0
465 #endif
466
467 #if M68K_EMULATE_040 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010
468         #define CPU_TYPE_IS_000(A)         ((A) == CPU_TYPE_000)
469 #else
470         #define CPU_TYPE_IS_000(A)         1
471 #endif
472
473
474 #if !M68K_SEPARATE_READS
475 #define m68k_read_immediate_16(A) m68ki_read_program_16(A)
476 #define m68k_read_immediate_32(A) m68ki_read_program_32(A)
477
478 #define m68k_read_pcrelative_8(A) m68ki_read_program_8(A)
479 #define m68k_read_pcrelative_16(A) m68ki_read_program_16(A)
480 #define m68k_read_pcrelative_32(A) m68ki_read_program_32(A)
481 #endif /* M68K_SEPARATE_READS */
482
483
484 /* Enable or disable callback functions */
485 #if M68K_EMULATE_INT_ACK
486         #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER
487                 #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A)
488         #else
489                 #define m68ki_int_ack(A) CALLBACK_INT_ACK(A)
490         #endif
491 #else
492         /* Default action is to used autovector mode, which is most common */
493         #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR
494 #endif /* M68K_EMULATE_INT_ACK */
495
496 #if M68K_EMULATE_BKPT_ACK
497         #if M68K_EMULATE_BKPT_ACK == OPT_SPECIFY_HANDLER
498                 #define m68ki_bkpt_ack(A) M68K_BKPT_ACK_CALLBACK(A)
499         #else
500                 #define m68ki_bkpt_ack(A) CALLBACK_BKPT_ACK(A)
501         #endif
502 #else
503         #define m68ki_bkpt_ack(A)
504 #endif /* M68K_EMULATE_BKPT_ACK */
505
506 #if M68K_EMULATE_RESET
507         #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER
508                 #define m68ki_output_reset() M68K_RESET_CALLBACK()
509         #else
510                 #define m68ki_output_reset() CALLBACK_RESET_INSTR()
511         #endif
512 #else
513         #define m68ki_output_reset()
514 #endif /* M68K_EMULATE_RESET */
515
516 #if M68K_CMPILD_HAS_CALLBACK
517         #if M68K_CMPILD_HAS_CALLBACK == OPT_SPECIFY_HANDLER
518                 #define m68ki_cmpild_callback(v,r) M68K_CMPILD_CALLBACK(v,r)
519         #else
520                 #define m68ki_cmpild_callback(v,r) CALLBACK_CMPILD_INSTR(v,r)
521         #endif
522 #else
523         #define m68ki_cmpild_callback(v,r)
524 #endif /* M68K_CMPILD_HAS_CALLBACK */
525
526 #if M68K_RTE_HAS_CALLBACK
527         #if M68K_RTE_HAS_CALLBACK == OPT_SPECIFY_HANDLER
528                 #define m68ki_rte_callback() M68K_RTE_CALLBACK()
529         #else
530                 #define m68ki_rte_callback() CALLBACK_RTE_INSTR()
531         #endif
532 #else
533         #define m68ki_rte_callback()
534 #endif /* M68K_RTE_HAS_CALLBACK */
535
536 #if M68K_TAS_HAS_CALLBACK
537         #if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER
538                 #define m68ki_tas_callback() M68K_TAS_CALLBACK()
539         #else
540                 #define m68ki_tas_callback() CALLBACK_TAS_INSTR()
541         #endif
542 #else
543         #define m68ki_tas_callback() 1
544 #endif /* M68K_TAS_HAS_CALLBACK */
545
546 #if M68K_ILLG_HAS_CALLBACK
547         #if M68K_ILLG_HAS_CALLBACK == OPT_SPECIFY_HANDLER
548                 #define m68ki_illg_callback(opcode) M68K_ILLG_CALLBACK(opcode)
549         #else
550                 #define m68ki_illg_callback(opcode) CALLBACK_ILLG_INSTR(opcode)
551         #endif
552 #else
553         #define m68ki_illg_callback(opcode) 0 // Default is 0 = not handled, exception will occur
554 #endif /* M68K_ILLG_HAS_CALLBACK */
555
556 #if M68K_INSTRUCTION_HOOK
557         #if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
558                 #define m68ki_instr_hook(pc) M68K_INSTRUCTION_CALLBACK(pc)
559         #else
560                 #define m68ki_instr_hook(pc) CALLBACK_INSTR_HOOK(pc)
561         #endif
562 #else
563         #define m68ki_instr_hook(pc)
564 #endif /* M68K_INSTRUCTION_HOOK */
565
566 #if M68K_MONITOR_PC
567         #if M68K_MONITOR_PC == OPT_SPECIFY_HANDLER
568                 #define m68ki_pc_changed(A) M68K_SET_PC_CALLBACK(ADDRESS_68K(A))
569         #else
570                 #define m68ki_pc_changed(A) CALLBACK_PC_CHANGED(ADDRESS_68K(A))
571         #endif
572 #else
573         #define m68ki_pc_changed(A)
574 #endif /* M68K_MONITOR_PC */
575
576
577 /* Enable or disable function code emulation */
578 #if M68K_EMULATE_FC
579         #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER
580                 #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A)
581         #else
582                 #define m68ki_set_fc(A) CALLBACK_SET_FC(A)
583         #endif
584         #define m68ki_use_data_space() m68ki_address_space = FUNCTION_CODE_USER_DATA
585         #define m68ki_use_program_space() m68ki_address_space = FUNCTION_CODE_USER_PROGRAM
586         #define m68ki_get_address_space() m68ki_address_space
587 #else
588         #define m68ki_set_fc(A)
589         #define m68ki_use_data_space()
590         #define m68ki_use_program_space()
591         #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA
592 #endif /* M68K_EMULATE_FC */
593
594
595 /* Enable or disable trace emulation */
596 #if M68K_EMULATE_TRACE
597         /* Initiates trace checking before each instruction (t1) */
598         #define m68ki_trace_t1() m68ki_tracing = FLAG_T1
599         /* adds t0 to trace checking if we encounter change of flow */
600         #define m68ki_trace_t0() m68ki_tracing |= FLAG_T0
601         /* Clear all tracing */
602         #define m68ki_clear_trace() m68ki_tracing = 0
603         /* Cause a trace exception if we are tracing */
604         #define m68ki_exception_if_trace() if(m68ki_tracing) m68ki_exception_trace()
605 #else
606         #define m68ki_trace_t1()
607         #define m68ki_trace_t0()
608         #define m68ki_clear_trace()
609         #define m68ki_exception_if_trace()
610 #endif /* M68K_EMULATE_TRACE */
611
612
613
614 /* Address error */
615 #if M68K_EMULATE_ADDRESS_ERROR
616         #include <setjmp.h>
617
618 /* sigjmp() on Mac OS X and *BSD in general saves signal contexts and is super-slow, use sigsetjmp() to tell it not to */
619 #ifdef _BSD_SETJMP_H
620 extern sigjmp_buf m68ki_aerr_trap;
621 #define m68ki_set_address_error_trap(m68k) \
622         if(sigsetjmp(m68ki_aerr_trap, 0) != 0) \
623         { \
624                 m68ki_exception_address_error(m68k); \
625                 if(CPU_STOPPED) \
626                 { \
627                         if (m68ki_remaining_cycles > 0) \
628                                 m68ki_remaining_cycles = 0; \
629                         return m68ki_initial_cycles; \
630                 } \
631         }
632
633 #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \
634         if((ADDR)&1) \
635         { \
636                 m68ki_aerr_address = ADDR; \
637                 m68ki_aerr_write_mode = WRITE_MODE; \
638                 m68ki_aerr_fc = FC; \
639                 siglongjmp(m68ki_aerr_trap, 1); \
640         }
641 #else
642 extern jmp_buf m68ki_aerr_trap;
643         #define m68ki_set_address_error_trap() \
644                 if(setjmp(m68ki_aerr_trap) != 0) \
645                 { \
646                         m68ki_exception_address_error(); \
647                         if(CPU_STOPPED) \
648                         { \
649                                 SET_CYCLES(0); \
650                                 return m68ki_initial_cycles; \
651                         } \
652                         /* ensure we don't re-enter execution loop after an
653                            address error if there's no more cycles remaining */ \
654                         if(GET_CYCLES() <= 0) \
655                         { \
656                                 /* return how many clocks we used */ \
657                                 return m68ki_initial_cycles - GET_CYCLES(); \
658                         } \
659                 }
660
661         #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \
662                 if((ADDR)&1) \
663                 { \
664                         m68ki_aerr_address = ADDR; \
665                         m68ki_aerr_write_mode = WRITE_MODE; \
666                         m68ki_aerr_fc = FC; \
667                         longjmp(m68ki_aerr_trap, 1); \
668                 }
669 #endif
670
671         #define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC) \
672                 if (CPU_TYPE_IS_010_LESS(CPU_TYPE)) \
673                 { \
674                         m68ki_check_address_error(ADDR, WRITE_MODE, FC) \
675                 }
676 #else
677         #define m68ki_set_address_error_trap()
678         #define m68ki_check_address_error(ADDR, WRITE_MODE, FC)
679         #define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC)
680 #endif /* M68K_ADDRESS_ERROR */
681
682 /* Logging */
683 #if M68K_LOG_ENABLE
684         #include <stdio.h>
685         extern FILE* M68K_LOG_FILEHANDLE
686         extern const char *const m68ki_cpu_names[];
687
688         #define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A
689         #if M68K_LOG_1010_1111
690                 #define M68K_DO_LOG_EMU(A) if(M68K_LOG_FILEHANDLE) fprintf A
691         #else
692                 #define M68K_DO_LOG_EMU(A)
693         #endif
694 #else
695         #define M68K_DO_LOG(A)
696         #define M68K_DO_LOG_EMU(A)
697 #endif
698
699
700
701 /* -------------------------- EA / Operand Access ------------------------- */
702
703 /*
704  * The general instruction format follows this pattern:
705  * .... XXX. .... .YYY
706  * where XXX is register X and YYY is register Y
707  */
708 /* Data Register Isolation */
709 #define DX (REG_D[(REG_IR >> 9) & 7])
710 #define DY (REG_D[REG_IR & 7])
711 /* Address Register Isolation */
712 #define AX (REG_A[(REG_IR >> 9) & 7])
713 #define AY (REG_A[REG_IR & 7])
714
715
716 /* Effective Address Calculations */
717 #define EA_AY_AI_8()   AY                                    /* address register indirect */
718 #define EA_AY_AI_16()  EA_AY_AI_8()
719 #define EA_AY_AI_32()  EA_AY_AI_8()
720 #define EA_AY_PI_8()   (AY++)                                /* postincrement (size = byte) */
721 #define EA_AY_PI_16()  ((AY+=2)-2)                           /* postincrement (size = word) */
722 #define EA_AY_PI_32()  ((AY+=4)-4)                           /* postincrement (size = long) */
723 #define EA_AY_PD_8()   (--AY)                                /* predecrement (size = byte) */
724 #define EA_AY_PD_16()  (AY-=2)                               /* predecrement (size = word) */
725 #define EA_AY_PD_32()  (AY-=4)                               /* predecrement (size = long) */
726 #define EA_AY_DI_8()   (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */
727 #define EA_AY_DI_16()  EA_AY_DI_8()
728 #define EA_AY_DI_32()  EA_AY_DI_8()
729 #define EA_AY_IX_8()   m68ki_get_ea_ix(AY)                   /* indirect + index */
730 #define EA_AY_IX_16()  EA_AY_IX_8()
731 #define EA_AY_IX_32()  EA_AY_IX_8()
732
733 #define EA_AX_AI_8()   AX
734 #define EA_AX_AI_16()  EA_AX_AI_8()
735 #define EA_AX_AI_32()  EA_AX_AI_8()
736 #define EA_AX_PI_8()   (AX++)
737 #define EA_AX_PI_16()  ((AX+=2)-2)
738 #define EA_AX_PI_32()  ((AX+=4)-4)
739 #define EA_AX_PD_8()   (--AX)
740 #define EA_AX_PD_16()  (AX-=2)
741 #define EA_AX_PD_32()  (AX-=4)
742 #define EA_AX_DI_8()   (AX+MAKE_INT_16(m68ki_read_imm_16()))
743 #define EA_AX_DI_16()  EA_AX_DI_8()
744 #define EA_AX_DI_32()  EA_AX_DI_8()
745 #define EA_AX_IX_8()   m68ki_get_ea_ix(AX)
746 #define EA_AX_IX_16()  EA_AX_IX_8()
747 #define EA_AX_IX_32()  EA_AX_IX_8()
748
749 #define EA_A7_PI_8()   ((REG_A[7]+=2)-2)
750 #define EA_A7_PD_8()   (REG_A[7]-=2)
751
752 #define EA_AW_8()      MAKE_INT_16(m68ki_read_imm_16())      /* absolute word */
753 #define EA_AW_16()     EA_AW_8()
754 #define EA_AW_32()     EA_AW_8()
755 #define EA_AL_8()      m68ki_read_imm_32()                   /* absolute long */
756 #define EA_AL_16()     EA_AL_8()
757 #define EA_AL_32()     EA_AL_8()
758 #define EA_PCDI_8()    m68ki_get_ea_pcdi()                   /* pc indirect + displacement */
759 #define EA_PCDI_16()   EA_PCDI_8()
760 #define EA_PCDI_32()   EA_PCDI_8()
761 #define EA_PCIX_8()    m68ki_get_ea_pcix()                   /* pc indirect + index */
762 #define EA_PCIX_16()   EA_PCIX_8()
763 #define EA_PCIX_32()   EA_PCIX_8()
764
765
766 #define OPER_I_8()     m68ki_read_imm_8()
767 #define OPER_I_16()    m68ki_read_imm_16()
768 #define OPER_I_32()    m68ki_read_imm_32()
769
770
771
772 /* --------------------------- Status Register ---------------------------- */
773
774 /* Flag Calculation Macros */
775 #define CFLAG_8(A) (A)
776 #define CFLAG_16(A) ((A)>>8)
777
778 #if M68K_INT_GT_32_BIT
779         #define CFLAG_ADD_32(S, D, R) ((R)>>24)
780         #define CFLAG_SUB_32(S, D, R) ((R)>>24)
781 #else
782         #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23)
783         #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23)
784 #endif /* M68K_INT_GT_32_BIT */
785
786 #define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R))
787 #define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
788 #define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24)
789
790 #define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D))
791 #define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
792 #define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24)
793
794 #define NFLAG_8(A) (A)
795 #define NFLAG_16(A) ((A)>>8)
796 #define NFLAG_32(A) ((A)>>24)
797 #define NFLAG_64(A) ((A)>>56)
798
799 #define ZFLAG_8(A) MASK_OUT_ABOVE_8(A)
800 #define ZFLAG_16(A) MASK_OUT_ABOVE_16(A)
801 #define ZFLAG_32(A) MASK_OUT_ABOVE_32(A)
802
803
804 /* Flag values */
805 #define NFLAG_SET   0x80
806 #define NFLAG_CLEAR 0
807 #define CFLAG_SET   0x100
808 #define CFLAG_CLEAR 0
809 #define XFLAG_SET   0x100
810 #define XFLAG_CLEAR 0
811 #define VFLAG_SET   0x80
812 #define VFLAG_CLEAR 0
813 #define ZFLAG_SET   0
814 #define ZFLAG_CLEAR 0xffffffff
815
816 #define SFLAG_SET   4
817 #define SFLAG_CLEAR 0
818 #define MFLAG_SET   2
819 #define MFLAG_CLEAR 0
820
821 /* Turn flag values into 1 or 0 */
822 #define XFLAG_AS_1() ((FLAG_X>>8)&1)
823 #define NFLAG_AS_1() ((FLAG_N>>7)&1)
824 #define VFLAG_AS_1() ((FLAG_V>>7)&1)
825 #define ZFLAG_AS_1() (!FLAG_Z)
826 #define CFLAG_AS_1() ((FLAG_C>>8)&1)
827
828
829 /* Conditions */
830 #define COND_CS() (FLAG_C&0x100)
831 #define COND_CC() (!COND_CS())
832 #define COND_VS() (FLAG_V&0x80)
833 #define COND_VC() (!COND_VS())
834 #define COND_NE() FLAG_Z
835 #define COND_EQ() (!COND_NE())
836 #define COND_MI() (FLAG_N&0x80)
837 #define COND_PL() (!COND_MI())
838 #define COND_LT() ((FLAG_N^FLAG_V)&0x80)
839 #define COND_GE() (!COND_LT())
840 #define COND_HI() (COND_CC() && COND_NE())
841 #define COND_LS() (COND_CS() || COND_EQ())
842 #define COND_GT() (COND_GE() && COND_NE())
843 #define COND_LE() (COND_LT() || COND_EQ())
844
845 /* Reversed conditions */
846 #define COND_NOT_CS() COND_CC()
847 #define COND_NOT_CC() COND_CS()
848 #define COND_NOT_VS() COND_VC()
849 #define COND_NOT_VC() COND_VS()
850 #define COND_NOT_NE() COND_EQ()
851 #define COND_NOT_EQ() COND_NE()
852 #define COND_NOT_MI() COND_PL()
853 #define COND_NOT_PL() COND_MI()
854 #define COND_NOT_LT() COND_GE()
855 #define COND_NOT_GE() COND_LT()
856 #define COND_NOT_HI() COND_LS()
857 #define COND_NOT_LS() COND_HI()
858 #define COND_NOT_GT() COND_LE()
859 #define COND_NOT_LE() COND_GT()
860
861 /* Not real conditions, but here for convenience */
862 #define COND_XS() (FLAG_X&0x100)
863 #define COND_XC() (!COND_XS)
864
865
866 /* Get the condition code register */
867 #define m68ki_get_ccr() ((COND_XS() >> 4) | \
868                                                  (COND_MI() >> 4) | \
869                                                  (COND_EQ() << 2) | \
870                                                  (COND_VS() >> 6) | \
871                                                  (COND_CS() >> 8))
872
873 /* Get the status register */
874 #define m68ki_get_sr() ( FLAG_T1              | \
875                                                  FLAG_T0              | \
876                                                 (FLAG_S        << 11) | \
877                                                 (FLAG_M        << 11) | \
878                                                  FLAG_INT_MASK        | \
879                                                  m68ki_get_ccr())
880
881
882
883 /* ---------------------------- Cycle Counting ---------------------------- */
884
885 #define ADD_CYCLES(A)    m68ki_remaining_cycles += (A)
886 #define USE_CYCLES(A)    m68ki_remaining_cycles -= (A)
887 #define SET_CYCLES(A)    m68ki_remaining_cycles = A
888 #define GET_CYCLES()     m68ki_remaining_cycles
889 #define USE_ALL_CYCLES() m68ki_remaining_cycles %= CYC_INSTRUCTION[REG_IR]
890
891
892
893 /* ----------------------------- Read / Write ----------------------------- */
894
895 /* Read from the current address space */
896 #define m68ki_read_8(A)  m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space())
897 #define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space())
898 #define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space())
899
900 /* Write to the current data space */
901 #define m68ki_write_8(A, V)  m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
902 #define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
903 #define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
904
905 #if M68K_SIMULATE_PD_WRITES
906 #define m68ki_write_32_pd(A, V) m68ki_write_32_pd_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
907 #else
908 #define m68ki_write_32_pd(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
909 #endif
910
911 /* Map PC-relative reads */
912 #define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A)
913 #define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A)
914 #define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A)
915
916 /* Read from the program space */
917 #define m68ki_read_program_8(A)         m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
918 #define m68ki_read_program_16(A)        m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
919 #define m68ki_read_program_32(A)        m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
920
921 /* Read from the data space */
922 #define m68ki_read_data_8(A)    m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
923 #define m68ki_read_data_16(A)   m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
924 #define m68ki_read_data_32(A)   m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
925
926
927
928 /* ======================================================================== */
929 /* =============================== PROTOTYPES ============================= */
930 /* ======================================================================== */
931
932 typedef union
933 {
934         uint64 i;
935         double f;
936 } fp_reg;
937
938 typedef struct
939 {
940         uint cpu_type;     /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */
941         uint dar[16];      /* Data and Address Registers */
942         uint dar_save[16];  /* Saved Data and Address Registers (pushed onto the
943                                                    stack when a bus error occurs)*/
944         uint ppc;                  /* Previous program counter */
945         uint pc;           /* Program Counter */
946         uint sp[7];        /* User, Interrupt, and Master Stack Pointers */
947         uint vbr;          /* Vector Base Register (m68010+) */
948         uint sfc;          /* Source Function Code Register (m68010+) */
949         uint dfc;          /* Destination Function Code Register (m68010+) */
950         uint cacr;         /* Cache Control Register (m68020, unemulated) */
951         uint caar;         /* Cache Address Register (m68020, unemulated) */
952         uint ir;           /* Instruction Register */
953         floatx80 fpr[8];     /* FPU Data Register (m68030/040) */
954         uint fpiar;        /* FPU Instruction Address Register (m68040) */
955         uint fpsr;         /* FPU Status Register (m68040) */
956         uint fpcr;         /* FPU Control Register (m68040) */
957         uint t1_flag;      /* Trace 1 */
958         uint t0_flag;      /* Trace 0 */
959         uint s_flag;       /* Supervisor */
960         uint m_flag;       /* Master/Interrupt state */
961         uint x_flag;       /* Extend */
962         uint n_flag;       /* Negative */
963         uint not_z_flag;   /* Zero, inverted for speedups */
964         uint v_flag;       /* Overflow */
965         uint c_flag;       /* Carry */
966         uint int_mask;     /* I0-I2 */
967         uint int_level;    /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */
968         uint stopped;      /* Stopped state */
969         uint pref_addr;    /* Last prefetch address */
970         uint pref_data;    /* Data in the prefetch queue */
971         uint address_mask; /* Available address pins */
972         uint sr_mask;      /* Implemented status register bits */
973         uint instr_mode;   /* Stores whether we are in instruction mode or group 0/1 exception mode */
974         uint run_mode;     /* Stores whether we are processing a reset, bus error, address error, or something else */
975         int    has_pmmu;   /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */
976         int    has_fpu;    /* Indicates if a FPU available */
977         int    pmmu_enabled; /* Indicates if the PMMU is enabled */
978         int    fpu_just_reset; /* Indicates the FPU was just reset */
979         uint reset_cycles;
980
981         /* Clocks required for instructions / exceptions */
982         uint cyc_bcc_notake_b;
983         uint cyc_bcc_notake_w;
984         uint cyc_dbcc_f_noexp;
985         uint cyc_dbcc_f_exp;
986         uint cyc_scc_r_true;
987         uint cyc_movem_w;
988         uint cyc_movem_l;
989         uint cyc_shift;
990         uint cyc_reset;
991
992         /* Virtual IRQ lines state */
993         uint virq_state;
994         uint nmi_pending;
995
996         /* PMMU registers */
997         uint mmu_crp_aptr, mmu_crp_limit;
998         uint mmu_srp_aptr, mmu_srp_limit;
999         uint mmu_tc;
1000         uint16 mmu_sr;
1001
1002         uint mmu_urp_aptr;    /* 040 only */
1003         uint mmu_sr_040;
1004         uint mmu_atc_tag[MMU_ATC_ENTRIES], mmu_atc_data[MMU_ATC_ENTRIES];
1005         uint mmu_atc_rr;
1006         uint mmu_tt0, mmu_tt1;
1007         uint mmu_itt0, mmu_itt1, mmu_dtt0, mmu_dtt1;
1008         uint mmu_acr0, mmu_acr1, mmu_acr2, mmu_acr3;
1009         uint mmu_last_page_entry, mmu_last_page_entry_addr;
1010
1011         uint16 mmu_tmp_sr;      /* temporary hack: status code for ptest and to handle write protection */
1012         uint16 mmu_tmp_fc;      /* temporary hack: function code for the mmu (moves) */
1013         uint16 mmu_tmp_rw;      /* temporary hack: read/write (1/0) for the mmu */
1014         uint8 mmu_tmp_sz;       /* temporary hack: size for mmu */
1015
1016         uint mmu_tmp_buserror_address;   /* temporary hack: (first) bus error address */
1017         uint16 mmu_tmp_buserror_occurred;  /* temporary hack: flag that bus error has occurred from mmu */
1018         uint16 mmu_tmp_buserror_fc;   /* temporary hack: (first) bus error fc */
1019         uint16 mmu_tmp_buserror_rw;   /* temporary hack: (first) bus error rw */
1020         uint16 mmu_tmp_buserror_sz;   /* temporary hack: (first) bus error size` */
1021
1022         uint8 mmu_tablewalk;             /* set when MMU walks page tables */
1023         uint mmu_last_logical_addr;
1024         uint ic_address[M68K_IC_SIZE];   /* instruction cache address data */
1025         uint ic_data[M68K_IC_SIZE];      /* instruction cache content data */
1026         uint8 ic_valid[M68K_IC_SIZE];     /* instruction cache valid flags */
1027
1028         const uint8* cyc_instruction;
1029         const uint8* cyc_exception;
1030
1031         /* Callbacks to host */
1032         int  (*int_ack_callback)(int int_line);           /* Interrupt Acknowledge */
1033         void (*bkpt_ack_callback)(unsigned int data);     /* Breakpoint Acknowledge */
1034         void (*reset_instr_callback)(void);               /* Called when a RESET instruction is encountered */
1035         void (*cmpild_instr_callback)(unsigned int, int); /* Called when a CMPI.L #v, Dn instruction is encountered */
1036         void (*rte_instr_callback)(void);                 /* Called when a RTE instruction is encountered */
1037         int  (*tas_instr_callback)(void);                 /* Called when a TAS instruction is encountered, allows / disallows writeback */
1038         int  (*illg_instr_callback)(int);                 /* Called when an illegal instruction is encountered, allows handling */
1039         void (*pc_changed_callback)(unsigned int new_pc); /* Called when the PC changes by a large amount */
1040         void (*set_fc_callback)(unsigned int new_fc);     /* Called when the CPU function code changes */
1041         void (*instr_hook_callback)(unsigned int pc);     /* Called every instruction cycle prior to execution */
1042
1043 } m68ki_cpu_core;
1044
1045
1046 extern m68ki_cpu_core m68ki_cpu;
1047 extern sint           m68ki_remaining_cycles;
1048 extern uint           m68ki_tracing;
1049 extern const uint8    m68ki_shift_8_table[];
1050 extern const uint16   m68ki_shift_16_table[];
1051 extern const uint     m68ki_shift_32_table[];
1052 extern const uint8    m68ki_exception_cycle_table[][256];
1053 extern uint           m68ki_address_space;
1054 extern const uint8    m68ki_ea_idx_cycle_table[];
1055
1056 extern uint           m68ki_aerr_address;
1057 extern uint           m68ki_aerr_write_mode;
1058 extern uint           m68ki_aerr_fc;
1059
1060 /* Forward declarations to keep some of the macros happy */
1061 static inline uint m68ki_read_16_fc (uint address, uint fc);
1062 static inline uint m68ki_read_32_fc (uint address, uint fc);
1063 static inline uint m68ki_get_ea_ix(uint An);
1064 static inline void m68ki_check_interrupts(void);            /* ASG: check for interrupts */
1065
1066 /* quick disassembly (used for logging) */
1067 char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type);
1068
1069
1070 /* ======================================================================== */
1071 /* =========================== UTILITY FUNCTIONS ========================== */
1072 /* ======================================================================== */
1073
1074
1075 /* ---------------------------- Read Immediate ---------------------------- */
1076
1077 extern unsigned char read_ranges;
1078 extern unsigned int read_addr[8];
1079 extern unsigned int read_upper[8];
1080 extern unsigned char *read_data[8];
1081 extern unsigned char write_ranges;
1082 extern unsigned int write_addr[8];
1083 extern unsigned int write_upper[8];
1084 extern unsigned char *write_data[8];
1085
1086 // clear the instruction cache
1087 inline void m68ki_ic_clear()
1088 {
1089         int i;
1090         for (i=0; i< M68K_IC_SIZE; i++) {
1091                 m68ki_cpu.ic_address[i] = ~0;
1092         }
1093 }
1094
1095 extern uint32 pmmu_translate_addr(uint32 addr_in, const uint16 rw);
1096
1097 // read immediate word using the instruction cache
1098
1099 static inline uint32 m68ki_ic_readimm16(uint32 address)
1100 {
1101         if (m68ki_cpu.cacr & M68K_CACR_EI)
1102         {
1103                 // 68020 series I-cache (MC68020 User's Manual, Section 4 - On-Chip Cache Memory)
1104                 if (CPU_TYPE & (CPU_TYPE_EC020 | CPU_TYPE_020))
1105                 {
1106                         uint32 tag = (address >> 8) | (m68ki_cpu.s_flag ? 0x1000000 : 0);
1107                         int idx = (address >> 2) & 0x3f;    // 1-of-64 select
1108
1109                         // do a cache fill if the line is invalid or the tags don't match
1110                         if ((!m68ki_cpu.ic_valid[idx]) || (m68ki_cpu.ic_address[idx] != tag))
1111                         {
1112                                 // if the cache is frozen, don't update it
1113                                 if (m68ki_cpu.cacr & M68K_CACR_FI)
1114                                 {
1115                                         return m68k_read_immediate_16(address);
1116                                 }
1117
1118                                 uint32 data = m68ki_read_32(address & ~3);
1119
1120                                 //printf("m68k: doing cache fill at %08x (tag %08x idx %d)\n", address, tag, idx);
1121
1122                                 // if no buserror occurred, validate the tag
1123                                 if (!m68ki_cpu.mmu_tmp_buserror_occurred)
1124                                 {
1125                                         m68ki_cpu.ic_address[idx] = tag;
1126                                         m68ki_cpu.ic_data[idx] = data;
1127                                         m68ki_cpu.ic_valid[idx] = 1;
1128                                 }
1129                                 else
1130                                 {
1131                                         return m68k_read_immediate_16(address);
1132                                 }
1133                         }
1134
1135                         // at this point, the cache is guaranteed to be valid, either as
1136                         // a hit or because we just filled it.
1137                         if (address & 2)
1138                         {
1139                                 return m68ki_cpu.ic_data[idx] & 0xffff;
1140                         }
1141                         else
1142                         {
1143                                 return m68ki_cpu.ic_data[idx] >> 16;
1144                         }
1145                 }
1146         }
1147         return m68k_read_immediate_16(address);
1148 }
1149
1150 /* Handles all immediate reads, does address error check, function code setting,
1151  * and prefetching if they are enabled in m68kconf.h
1152  */
1153 static inline uint m68ki_read_imm_16(void)
1154 {
1155         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1156         m68ki_cpu.mmu_tmp_fc = FLAG_S | FUNCTION_CODE_USER_PROGRAM;
1157         m68ki_cpu.mmu_tmp_rw = 1;
1158         m68ki_cpu.mmu_tmp_sz = M68K_SZ_WORD;
1159         m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1160
1161 #if M68K_EMULATE_PREFETCH
1162 {
1163         uint result;
1164         if(REG_PC != CPU_PREF_ADDR)
1165         {
1166                 CPU_PREF_DATA = m68ki_ic_readimm16(REG_PC);
1167                 CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
1168         }
1169         result = MASK_OUT_ABOVE_16(CPU_PREF_DATA);
1170         REG_PC += 2;
1171         if (!m68ki_cpu.mmu_tmp_buserror_occurred) {
1172                 // prefetch only if no bus error occurred in opcode fetch
1173                 CPU_PREF_DATA = m68ki_ic_readimm16(REG_PC);
1174                 CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
1175                 // ignore bus error on prefetch
1176                 m68ki_cpu.mmu_tmp_buserror_occurred = 0;
1177         }
1178         return result;
1179 }
1180 #else
1181
1182         uint32_t address = ADDRESS_68K(REG_PC);
1183         REG_PC += 2;
1184
1185         for (int i = 0; i < read_ranges; i++) {
1186                 if(address >= read_addr[i] && address < read_upper[i]) {
1187                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1188                 }
1189         }
1190
1191         return m68k_read_immediate_16(address);
1192 #endif /* M68K_EMULATE_PREFETCH */
1193 }
1194
1195 static inline uint m68ki_read_imm_8(void)
1196 {
1197         /* map read immediate 8 to read immediate 16 */
1198         return MASK_OUT_ABOVE_8(m68ki_read_imm_16());
1199 }
1200
1201 static inline uint m68ki_read_imm_32(void)
1202 {
1203 #if M68K_SEPARATE_READS
1204 #if M68K_EMULATE_PMMU
1205 //      if (PMMU_ENABLED)
1206 //          address = pmmu_translate_addr(address,1);
1207 #endif
1208 #endif
1209
1210 #if M68K_EMULATE_PREFETCH
1211         uint temp_val;
1212
1213         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1214         m68ki_cpu.mmu_tmp_fc = FLAG_S | FUNCTION_CODE_USER_PROGRAM;
1215         m68ki_cpu.mmu_tmp_rw = 1;
1216         m68ki_cpu.mmu_tmp_sz = M68K_SZ_LONG;
1217         m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1218
1219         if(REG_PC != CPU_PREF_ADDR)
1220         {
1221                 CPU_PREF_ADDR = REG_PC;
1222                 CPU_PREF_DATA = m68ki_ic_readimm16(ADDRESS_68K(CPU_PREF_ADDR));
1223         }
1224         temp_val = MASK_OUT_ABOVE_16(CPU_PREF_DATA);
1225         REG_PC += 2;
1226         CPU_PREF_ADDR = REG_PC;
1227         CPU_PREF_DATA = m68ki_ic_readimm16(ADDRESS_68K(CPU_PREF_ADDR));
1228
1229         temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(CPU_PREF_DATA));
1230         REG_PC += 2;
1231         CPU_PREF_DATA = m68ki_ic_readimm16(REG_PC);
1232         CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
1233
1234         return temp_val;
1235 #else
1236         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1237         m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1238         uint32_t address = ADDRESS_68K(REG_PC);
1239         REG_PC += 4;
1240         for (int i = 0; i < read_ranges; i++) {
1241                 if(address >= read_addr[i] && address < read_upper[i]) {
1242                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1243                 }
1244         }
1245
1246         return m68k_read_immediate_32(address);
1247 #endif /* M68K_EMULATE_PREFETCH */
1248 }
1249
1250 /* ------------------------- Top level read/write ------------------------- */
1251
1252 /* Handles all memory accesses (except for immediate reads if they are
1253  * configured to use separate functions in m68kconf.h).
1254  * All memory accesses must go through these top level functions.
1255  * These functions will also check for address error and set the function
1256  * code if they are enabled in m68kconf.h.
1257  */
1258
1259 static inline uint m68ki_read_8_fc(uint address, uint fc)
1260 {
1261         (void)fc;
1262         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1263         m68ki_cpu.mmu_tmp_fc = fc;
1264         m68ki_cpu.mmu_tmp_rw = 1;
1265         m68ki_cpu.mmu_tmp_sz = M68K_SZ_BYTE;
1266
1267 #if M68K_EMULATE_PMMU
1268         if (PMMU_ENABLED)
1269             address = pmmu_translate_addr(address,1);
1270 #endif
1271
1272         for (int i = 0; i < read_ranges; i++) {
1273                 if(address >= read_addr[i] && address < read_upper[i]) {
1274                         return read_data[i][address - read_addr[i]];
1275                 }
1276         }
1277
1278         return m68k_read_memory_8(ADDRESS_68K(address));
1279 }
1280 static inline uint m68ki_read_16_fc(uint address, uint fc)
1281 {
1282         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1283         m68ki_cpu.mmu_tmp_fc = fc;
1284         m68ki_cpu.mmu_tmp_rw = 1;
1285         m68ki_cpu.mmu_tmp_sz = M68K_SZ_WORD;
1286         m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
1287
1288 #if M68K_EMULATE_PMMU
1289         if (PMMU_ENABLED)
1290             address = pmmu_translate_addr(address,1);
1291 #endif
1292
1293         for (int i = 0; i < read_ranges; i++) {
1294                 if(address >= read_addr[i] && address < read_upper[i]) {
1295                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1296                 }
1297         }
1298
1299         return m68k_read_memory_16(ADDRESS_68K(address));
1300 }
1301 static inline uint m68ki_read_32_fc(uint address, uint fc)
1302 {
1303         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1304         m68ki_cpu.mmu_tmp_fc = fc;
1305         m68ki_cpu.mmu_tmp_rw = 1;
1306         m68ki_cpu.mmu_tmp_sz = M68K_SZ_LONG;
1307         m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
1308
1309 #if M68K_EMULATE_PMMU
1310         if (PMMU_ENABLED)
1311             address = pmmu_translate_addr(address,1);
1312 #endif
1313
1314         for (int i = 0; i < read_ranges; i++) {
1315                 if(address >= read_addr[i] && address < read_upper[i]) {
1316                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1317                 }
1318         }
1319
1320         return m68k_read_memory_32(ADDRESS_68K(address));
1321 }
1322
1323 static inline void m68ki_write_8_fc(uint address, uint fc, uint value)
1324 {
1325         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1326         m68ki_cpu.mmu_tmp_fc = fc;
1327         m68ki_cpu.mmu_tmp_rw = 0;
1328         m68ki_cpu.mmu_tmp_sz = M68K_SZ_BYTE;
1329
1330 #if M68K_EMULATE_PMMU
1331         if (PMMU_ENABLED)
1332             address = pmmu_translate_addr(address,0);
1333 #endif
1334
1335         for (int i = 0; i < write_ranges; i++) {
1336                 if(address >= write_addr[i] && address < write_upper[i]) {
1337                         write_data[i][address - write_addr[i]] = (unsigned char)value;
1338                         return;
1339                 }
1340         }
1341
1342         m68k_write_memory_8(ADDRESS_68K(address), value);
1343 }
1344 static inline void m68ki_write_16_fc(uint address, uint fc, uint value)
1345 {
1346         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1347         m68ki_cpu.mmu_tmp_fc = fc;
1348         m68ki_cpu.mmu_tmp_rw = 0;
1349         m68ki_cpu.mmu_tmp_sz = M68K_SZ_WORD;
1350         m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
1351
1352 #if M68K_EMULATE_PMMU
1353         if (PMMU_ENABLED)
1354             address = pmmu_translate_addr(address,0);
1355 #endif
1356
1357         for (int i = 0; i < write_ranges; i++) {
1358                 if(address >= write_addr[i] && address < write_upper[i]) {
1359                         ((short *)(write_data[i] + (address - write_addr[i])))[0] = htobe16(value);
1360                         return;
1361                 }
1362         }
1363
1364         m68k_write_memory_16(ADDRESS_68K(address), value);
1365 }
1366 static inline void m68ki_write_32_fc(uint address, uint fc, uint value)
1367 {
1368         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1369         m68ki_cpu.mmu_tmp_fc = fc;
1370         m68ki_cpu.mmu_tmp_rw = 0;
1371         m68ki_cpu.mmu_tmp_sz = M68K_SZ_LONG;
1372         m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
1373
1374 #if M68K_EMULATE_PMMU
1375         if (PMMU_ENABLED)
1376             address = pmmu_translate_addr(address,0);
1377 #endif
1378
1379         for (int i = 0; i < write_ranges; i++) {
1380                 if(address >= write_addr[i] && address < write_upper[i]) {
1381                         ((int *)(write_data[i] + (address - write_addr[i])))[0] = htobe32(value);
1382                         return;
1383                 }
1384         }
1385
1386         m68k_write_memory_32(ADDRESS_68K(address), value);
1387 }
1388
1389 #if M68K_SIMULATE_PD_WRITES
1390 /* Special call to simulate undocumented 68k behavior when move.l with a
1391  * predecrement destination mode is executed.
1392  * A real 68k first writes the high word to [address+2], and then writes the
1393  * low word to [address].
1394  */
1395 static inline void m68ki_write_32_pd_fc(uint address, uint fc, uint value)
1396 {
1397         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1398         m68ki_cpu.mmu_tmp_fc = fc;
1399         m68ki_cpu.mmu_tmp_rw = 0;
1400         m68ki_cpu.mmu_tmp_sz = M68K_SZ_LONG;
1401         m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
1402
1403 #if M68K_EMULATE_PMMU
1404         if (PMMU_ENABLED)
1405             address = pmmu_translate_addr(address,0);
1406 #endif
1407
1408         m68k_write_memory_32_pd(ADDRESS_68K(address), value);
1409 }
1410 #endif
1411
1412 /* --------------------- Effective Address Calculation -------------------- */
1413
1414 /* The program counter relative addressing modes cause operands to be
1415  * retrieved from program space, not data space.
1416  */
1417 static inline uint m68ki_get_ea_pcdi(void)
1418 {
1419         uint old_pc = REG_PC;
1420         m68ki_use_program_space(); /* auto-disable */
1421         return old_pc + MAKE_INT_16(m68ki_read_imm_16());
1422 }
1423
1424
1425 static inline uint m68ki_get_ea_pcix(void)
1426 {
1427         m68ki_use_program_space(); /* auto-disable */
1428         return m68ki_get_ea_ix(REG_PC);
1429 }
1430
1431 /* Indexed addressing modes are encoded as follows:
1432  *
1433  * Base instruction format:
1434  * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0
1435  * x x x x x x x x x x | 1 1 0 | BASE REGISTER      (An)
1436  *
1437  * Base instruction format for destination EA in move instructions:
1438  * F E D C | B A 9    | 8 7 6 | 5 4 3 2 1 0
1439  * x x x x | BASE REG | 1 1 0 | X X X X X X       (An)
1440  *
1441  * Brief extension format:
1442  *  F  |  E D C   |  B  |  A 9  | 8 | 7 6 5 4 3 2 1 0
1443  * D/A | REGISTER | W/L | SCALE | 0 |  DISPLACEMENT
1444  *
1445  * Full extension format:
1446  *  F     E D C      B     A 9    8   7    6    5 4       3   2 1 0
1447  * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS
1448  * BASE DISPLACEMENT (0, 16, 32 bit)                (bd)
1449  * OUTER DISPLACEMENT (0, 16, 32 bit)               (od)
1450  *
1451  * D/A:     0 = Dn, 1 = An                          (Xn)
1452  * W/L:     0 = W (sign extend), 1 = L              (.SIZE)
1453  * SCALE:   00=1, 01=2, 10=4, 11=8                  (*SCALE)
1454  * BS:      0=add base reg, 1=suppress base reg     (An suppressed)
1455  * IS:      0=add index, 1=suppress index           (Xn suppressed)
1456  * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long  (size of bd)
1457  *
1458  * IS I/IS Operation
1459  * 0  000  No Memory Indirect
1460  * 0  001  indir prex with null outer
1461  * 0  010  indir prex with word outer
1462  * 0  011  indir prex with long outer
1463  * 0  100  reserved
1464  * 0  101  indir postx with null outer
1465  * 0  110  indir postx with word outer
1466  * 0  111  indir postx with long outer
1467  * 1  000  no memory indirect
1468  * 1  001  mem indir with null outer
1469  * 1  010  mem indir with word outer
1470  * 1  011  mem indir with long outer
1471  * 1  100-111  reserved
1472  */
1473 static inline uint m68ki_get_ea_ix(uint An)
1474 {
1475         /* An = base register */
1476         uint extension = m68ki_read_imm_16();
1477         uint Xn = 0;                        /* Index register */
1478         uint bd = 0;                        /* Base Displacement */
1479         uint od = 0;                        /* Outer Displacement */
1480
1481         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
1482         {
1483                 /* Calculate index */
1484                 Xn = REG_DA[extension>>12];     /* Xn */
1485                 if(!BIT_B(extension))           /* W/L */
1486                         Xn = MAKE_INT_16(Xn);
1487
1488                 /* Add base register and displacement and return */
1489                 return An + Xn + MAKE_INT_8(extension);
1490         }
1491
1492         /* Brief extension format */
1493         if(!BIT_8(extension))
1494         {
1495                 /* Calculate index */
1496                 Xn = REG_DA[extension>>12];     /* Xn */
1497                 if(!BIT_B(extension))           /* W/L */
1498                         Xn = MAKE_INT_16(Xn);
1499                 /* Add scale if proper CPU type */
1500                 if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
1501                         Xn <<= (extension>>9) & 3;  /* SCALE */
1502
1503                 /* Add base register and displacement and return */
1504                 return An + Xn + MAKE_INT_8(extension);
1505         }
1506
1507         /* Full extension format */
1508
1509         USE_CYCLES(m68ki_ea_idx_cycle_table[extension&0x3f]);
1510
1511         /* Check if base register is present */
1512         if(BIT_7(extension))                /* BS */
1513                 An = 0;                         /* An */
1514
1515         /* Check if index is present */
1516         if(!BIT_6(extension))               /* IS */
1517         {
1518                 Xn = REG_DA[extension>>12];     /* Xn */
1519                 if(!BIT_B(extension))           /* W/L */
1520                         Xn = MAKE_INT_16(Xn);
1521                 Xn <<= (extension>>9) & 3;      /* SCALE */
1522         }
1523
1524         /* Check if base displacement is present */
1525         if(BIT_5(extension))                /* BD SIZE */
1526                 bd = BIT_4(extension) ? m68ki_read_imm_32() : (uint32)MAKE_INT_16(m68ki_read_imm_16());
1527
1528         /* If no indirect action, we are done */
1529         if(!(extension&7))                  /* No Memory Indirect */
1530                 return An + bd + Xn;
1531
1532         /* Check if outer displacement is present */
1533         if(BIT_1(extension))                /* I/IS:  od */
1534                 od = BIT_0(extension) ? m68ki_read_imm_32() : (uint32)MAKE_INT_16(m68ki_read_imm_16());
1535
1536         /* Postindex */
1537         if(BIT_2(extension))                /* I/IS:  0 = preindex, 1 = postindex */
1538                 return m68ki_read_32(An + bd) + Xn + od;
1539
1540         /* Preindex */
1541         return m68ki_read_32(An + bd + Xn) + od;
1542 }
1543
1544
1545 /* Fetch operands */
1546 static inline uint OPER_AY_AI_8(void)  {uint ea = EA_AY_AI_8();  return m68ki_read_8(ea); }
1547 static inline uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);}
1548 static inline uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);}
1549 static inline uint OPER_AY_PI_8(void)  {uint ea = EA_AY_PI_8();  return m68ki_read_8(ea); }
1550 static inline uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);}
1551 static inline uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);}
1552 static inline uint OPER_AY_PD_8(void)  {uint ea = EA_AY_PD_8();  return m68ki_read_8(ea); }
1553 static inline uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);}
1554 static inline uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);}
1555 static inline uint OPER_AY_DI_8(void)  {uint ea = EA_AY_DI_8();  return m68ki_read_8(ea); }
1556 static inline uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);}
1557 static inline uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);}
1558 static inline uint OPER_AY_IX_8(void)  {uint ea = EA_AY_IX_8();  return m68ki_read_8(ea); }
1559 static inline uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);}
1560 static inline uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);}
1561
1562 static inline uint OPER_AX_AI_8(void)  {uint ea = EA_AX_AI_8();  return m68ki_read_8(ea); }
1563 static inline uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);}
1564 static inline uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);}
1565 static inline uint OPER_AX_PI_8(void)  {uint ea = EA_AX_PI_8();  return m68ki_read_8(ea); }
1566 static inline uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);}
1567 static inline uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);}
1568 static inline uint OPER_AX_PD_8(void)  {uint ea = EA_AX_PD_8();  return m68ki_read_8(ea); }
1569 static inline uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);}
1570 static inline uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);}
1571 static inline uint OPER_AX_DI_8(void)  {uint ea = EA_AX_DI_8();  return m68ki_read_8(ea); }
1572 static inline uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);}
1573 static inline uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);}
1574 static inline uint OPER_AX_IX_8(void)  {uint ea = EA_AX_IX_8();  return m68ki_read_8(ea); }
1575 static inline uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);}
1576 static inline uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);}
1577
1578 static inline uint OPER_A7_PI_8(void)  {uint ea = EA_A7_PI_8();  return m68ki_read_8(ea); }
1579 static inline uint OPER_A7_PD_8(void)  {uint ea = EA_A7_PD_8();  return m68ki_read_8(ea); }
1580
1581 static inline uint OPER_AW_8(void)     {uint ea = EA_AW_8();     return m68ki_read_8(ea); }
1582 static inline uint OPER_AW_16(void)    {uint ea = EA_AW_16();    return m68ki_read_16(ea);}
1583 static inline uint OPER_AW_32(void)    {uint ea = EA_AW_32();    return m68ki_read_32(ea);}
1584 static inline uint OPER_AL_8(void)     {uint ea = EA_AL_8();     return m68ki_read_8(ea); }
1585 static inline uint OPER_AL_16(void)    {uint ea = EA_AL_16();    return m68ki_read_16(ea);}
1586 static inline uint OPER_AL_32(void)    {uint ea = EA_AL_32();    return m68ki_read_32(ea);}
1587 static inline uint OPER_PCDI_8(void)   {uint ea = EA_PCDI_8();   return m68ki_read_pcrel_8(ea); }
1588 static inline uint OPER_PCDI_16(void)  {uint ea = EA_PCDI_16();  return m68ki_read_pcrel_16(ea);}
1589 static inline uint OPER_PCDI_32(void)  {uint ea = EA_PCDI_32();  return m68ki_read_pcrel_32(ea);}
1590 static inline uint OPER_PCIX_8(void)   {uint ea = EA_PCIX_8();   return m68ki_read_pcrel_8(ea); }
1591 static inline uint OPER_PCIX_16(void)  {uint ea = EA_PCIX_16();  return m68ki_read_pcrel_16(ea);}
1592 static inline uint OPER_PCIX_32(void)  {uint ea = EA_PCIX_32();  return m68ki_read_pcrel_32(ea);}
1593
1594
1595
1596 /* ---------------------------- Stack Functions --------------------------- */
1597
1598 /* Push/pull data from the stack */
1599 static inline void m68ki_push_16(uint value)
1600 {
1601         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1602         m68ki_write_16(REG_SP, value);
1603 }
1604
1605 static inline void m68ki_push_32(uint value)
1606 {
1607         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1608         m68ki_write_32(REG_SP, value);
1609 }
1610
1611 static inline uint m68ki_pull_16(void)
1612 {
1613         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1614         return m68ki_read_16(REG_SP-2);
1615 }
1616
1617 static inline uint m68ki_pull_32(void)
1618 {
1619         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1620         return m68ki_read_32(REG_SP-4);
1621 }
1622
1623
1624 /* Increment/decrement the stack as if doing a push/pull but
1625  * don't do any memory access.
1626  */
1627 static inline void m68ki_fake_push_16(void)
1628 {
1629         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1630 }
1631
1632 static inline void m68ki_fake_push_32(void)
1633 {
1634         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1635 }
1636
1637 static inline void m68ki_fake_pull_16(void)
1638 {
1639         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1640 }
1641
1642 static inline void m68ki_fake_pull_32(void)
1643 {
1644         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1645 }
1646
1647
1648 /* ----------------------------- Program Flow ----------------------------- */
1649
1650 /* Jump to a new program location or vector.
1651  * These functions will also call the pc_changed callback if it was enabled
1652  * in m68kconf.h.
1653  */
1654 static inline void m68ki_jump(uint new_pc)
1655 {
1656         REG_PC = new_pc;
1657         m68ki_pc_changed(REG_PC);
1658 }
1659
1660 static inline void m68ki_jump_vector(uint vector)
1661 {
1662         REG_PC = (vector<<2) + REG_VBR;
1663         REG_PC = m68ki_read_data_32(REG_PC);
1664         m68ki_pc_changed(REG_PC);
1665 }
1666
1667
1668 /* Branch to a new memory location.
1669  * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h.
1670  * So far I've found no problems with not calling pc_changed for 8 or 16
1671  * bit branches.
1672  */
1673 static inline void m68ki_branch_8(uint offset)
1674 {
1675         REG_PC += MAKE_INT_8(offset);
1676 }
1677
1678 static inline void m68ki_branch_16(uint offset)
1679 {
1680         REG_PC += MAKE_INT_16(offset);
1681 }
1682
1683 static inline void m68ki_branch_32(uint offset)
1684 {
1685         REG_PC += offset;
1686         m68ki_pc_changed(REG_PC);
1687 }
1688
1689 /* ---------------------------- Status Register --------------------------- */
1690
1691 /* Set the S flag and change the active stack pointer.
1692  * Note that value MUST be 4 or 0.
1693  */
1694 static inline void m68ki_set_s_flag(uint value)
1695 {
1696         /* Backup the old stack pointer */
1697         REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
1698         /* Set the S flag */
1699         FLAG_S = value;
1700         /* Set the new stack pointer */
1701         REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];
1702 }
1703
1704 /* Set the S and M flags and change the active stack pointer.
1705  * Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M).
1706  */
1707 static inline void m68ki_set_sm_flag(uint value)
1708 {
1709         /* Backup the old stack pointer */
1710         REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
1711         /* Set the S and M flags */
1712         FLAG_S = value & SFLAG_SET;
1713         FLAG_M = value & MFLAG_SET;
1714         /* Set the new stack pointer */
1715         REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];
1716 }
1717
1718 /* Set the S and M flags.  Don't touch the stack pointer. */
1719 static inline void m68ki_set_sm_flag_nosp(uint value)
1720 {
1721         /* Set the S and M flags */
1722         FLAG_S = value & SFLAG_SET;
1723         FLAG_M = value & MFLAG_SET;
1724 }
1725
1726
1727 /* Set the condition code register */
1728 static inline void m68ki_set_ccr(uint value)
1729 {
1730         FLAG_X = BIT_4(value)  << 4;
1731         FLAG_N = BIT_3(value)  << 4;
1732         FLAG_Z = !BIT_2(value);
1733         FLAG_V = BIT_1(value)  << 6;
1734         FLAG_C = BIT_0(value)  << 8;
1735 }
1736
1737 /* Set the status register but don't check for interrupts */
1738 static inline void m68ki_set_sr_noint(uint value)
1739 {
1740         /* Mask out the "unimplemented" bits */
1741         value &= CPU_SR_MASK;
1742
1743         /* Now set the status register */
1744         FLAG_T1 = BIT_F(value);
1745         FLAG_T0 = BIT_E(value);
1746         FLAG_INT_MASK = value & 0x0700;
1747         m68ki_set_ccr(value);
1748         m68ki_set_sm_flag((value >> 11) & 6);
1749 }
1750
1751 /* Set the status register but don't check for interrupts nor
1752  * change the stack pointer
1753  */
1754 static inline void m68ki_set_sr_noint_nosp(uint value)
1755 {
1756         /* Mask out the "unimplemented" bits */
1757         value &= CPU_SR_MASK;
1758
1759         /* Now set the status register */
1760         FLAG_T1 = BIT_F(value);
1761         FLAG_T0 = BIT_E(value);
1762         FLAG_INT_MASK = value & 0x0700;
1763         m68ki_set_ccr(value);
1764         m68ki_set_sm_flag_nosp((value >> 11) & 6);
1765 }
1766
1767 /* Set the status register and check for interrupts */
1768 static inline void m68ki_set_sr(uint value)
1769 {
1770         m68ki_set_sr_noint(value);
1771         m68ki_check_interrupts();
1772 }
1773
1774
1775 /* ------------------------- Exception Processing ------------------------- */
1776
1777 /* Initiate exception processing */
1778 static inline uint m68ki_init_exception(void)
1779 {
1780         /* Save the old status register */
1781         uint sr = m68ki_get_sr();
1782
1783         /* Turn off trace flag, clear pending traces */
1784         FLAG_T1 = FLAG_T0 = 0;
1785         m68ki_clear_trace();
1786         /* Enter supervisor mode */
1787         m68ki_set_s_flag(SFLAG_SET);
1788
1789         return sr;
1790 }
1791
1792 /* 3 word stack frame (68000 only) */
1793 static inline void m68ki_stack_frame_3word(uint pc, uint sr)
1794 {
1795         m68ki_push_32(pc);
1796         m68ki_push_16(sr);
1797 }
1798
1799 /* Format 0 stack frame.
1800  * This is the standard stack frame for 68010+.
1801  */
1802 static inline void m68ki_stack_frame_0000(uint pc, uint sr, uint vector)
1803 {
1804         /* Stack a 3-word frame if we are 68000 */
1805         if(CPU_TYPE == CPU_TYPE_000)
1806         {
1807                 m68ki_stack_frame_3word(pc, sr);
1808                 return;
1809         }
1810         m68ki_push_16(vector<<2);
1811         m68ki_push_32(pc);
1812         m68ki_push_16(sr);
1813 }
1814
1815 /* Format 1 stack frame (68020).
1816  * For 68020, this is the 4 word throwaway frame.
1817  */
1818 static inline void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)
1819 {
1820         m68ki_push_16(0x1000 | (vector<<2));
1821         m68ki_push_32(pc);
1822         m68ki_push_16(sr);
1823 }
1824
1825 /* Format 2 stack frame.
1826  * This is used only by 68020 for trap exceptions.
1827  */
1828 static inline void m68ki_stack_frame_0010(uint sr, uint vector)
1829 {
1830         m68ki_push_32(REG_PPC);
1831         m68ki_push_16(0x2000 | (vector<<2));
1832         m68ki_push_32(REG_PC);
1833         m68ki_push_16(sr);
1834 }
1835
1836
1837 /* Bus error stack frame (68000 only).
1838  */
1839 static inline void m68ki_stack_frame_buserr(uint sr)
1840 {
1841         m68ki_push_32(REG_PC);
1842         m68ki_push_16(sr);
1843         m68ki_push_16(REG_IR);
1844         m68ki_push_32(m68ki_aerr_address);      /* access address */
1845         /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC
1846          * R/W  0 = write, 1 = read
1847          * I/N  0 = instruction, 1 = not
1848          * FC   3-bit function code
1849          */
1850         m68ki_push_16(m68ki_aerr_write_mode | CPU_INSTR_MODE | m68ki_aerr_fc);
1851 }
1852
1853 /* Format 8 stack frame (68010).
1854  * 68010 only.  This is the 29 word bus/address error frame.
1855  */
1856 static inline void m68ki_stack_frame_1000(uint pc, uint sr, uint vector)
1857 {
1858         /* VERSION
1859          * NUMBER
1860          * INTERNAL INFORMATION, 16 WORDS
1861          */
1862         m68ki_fake_push_32();
1863         m68ki_fake_push_32();
1864         m68ki_fake_push_32();
1865         m68ki_fake_push_32();
1866         m68ki_fake_push_32();
1867         m68ki_fake_push_32();
1868         m68ki_fake_push_32();
1869         m68ki_fake_push_32();
1870
1871         /* INSTRUCTION INPUT BUFFER */
1872         m68ki_push_16(0);
1873
1874         /* UNUSED, RESERVED (not written) */
1875         m68ki_fake_push_16();
1876
1877         /* DATA INPUT BUFFER */
1878         m68ki_push_16(0);
1879
1880         /* UNUSED, RESERVED (not written) */
1881         m68ki_fake_push_16();
1882
1883         /* DATA OUTPUT BUFFER */
1884         m68ki_push_16(0);
1885
1886         /* UNUSED, RESERVED (not written) */
1887         m68ki_fake_push_16();
1888
1889         /* FAULT ADDRESS */
1890         m68ki_push_32(0);
1891
1892         /* SPECIAL STATUS WORD */
1893         m68ki_push_16(0);
1894
1895         /* 1000, VECTOR OFFSET */
1896         m68ki_push_16(0x8000 | (vector<<2));
1897
1898         /* PROGRAM COUNTER */
1899         m68ki_push_32(pc);
1900
1901         /* STATUS REGISTER */
1902         m68ki_push_16(sr);
1903 }
1904
1905 /* Format A stack frame (short bus fault).
1906  * This is used only by 68020 for bus fault and address error
1907  * if the error happens at an instruction boundary.
1908  * PC stacked is address of next instruction.
1909  */
1910 static inline void m68ki_stack_frame_1010(uint sr, uint vector, uint pc, uint fault_address)
1911 {
1912         int orig_rw = m68ki_cpu.mmu_tmp_buserror_rw;    // this gets splatted by the following pushes, so save it now
1913         int orig_fc = m68ki_cpu.mmu_tmp_buserror_fc;
1914         int orig_sz = m68ki_cpu.mmu_tmp_buserror_sz;
1915
1916         /* INTERNAL REGISTER */
1917         m68ki_push_16(0);
1918
1919         /* INTERNAL REGISTER */
1920         m68ki_push_16(0);
1921
1922         /* DATA OUTPUT BUFFER (2 words) */
1923         m68ki_push_32(0);
1924
1925         /* INTERNAL REGISTER */
1926         m68ki_push_16(0);
1927
1928         /* INTERNAL REGISTER */
1929         m68ki_push_16(0);
1930
1931         /* DATA CYCLE FAULT ADDRESS (2 words) */
1932         m68ki_push_32(fault_address);
1933
1934         /* INSTRUCTION PIPE STAGE B */
1935         m68ki_push_16(0);
1936
1937         /* INSTRUCTION PIPE STAGE C */
1938         m68ki_push_16(0);
1939
1940         /* SPECIAL STATUS REGISTER */
1941         // set bit for: Rerun Faulted bus Cycle, or run pending prefetch
1942         // set FC
1943         m68ki_push_16(0x0100 | orig_fc | orig_rw<<6 | orig_sz<<4);
1944
1945         /* INTERNAL REGISTER */
1946         m68ki_push_16(0);
1947
1948         /* 1010, VECTOR OFFSET */
1949         m68ki_push_16(0xa000 | (vector<<2));
1950
1951         /* PROGRAM COUNTER */
1952         m68ki_push_32(pc);
1953
1954         /* STATUS REGISTER */
1955         m68ki_push_16(sr);
1956 }
1957
1958 /* Format B stack frame (long bus fault).
1959  * This is used only by 68020 for bus fault and address error
1960  * if the error happens during instruction execution.
1961  * PC stacked is address of instruction in progress.
1962  */
1963 static inline void m68ki_stack_frame_1011(uint sr, uint vector, uint pc, uint fault_address)
1964 {
1965         int orig_rw = m68ki_cpu.mmu_tmp_buserror_rw;    // this gets splatted by the following pushes, so save it now
1966         int orig_fc = m68ki_cpu.mmu_tmp_buserror_fc;
1967         int orig_sz = m68ki_cpu.mmu_tmp_buserror_sz;
1968         /* INTERNAL REGISTERS (18 words) */
1969         m68ki_push_32(0);
1970         m68ki_push_32(0);
1971         m68ki_push_32(0);
1972         m68ki_push_32(0);
1973         m68ki_push_32(0);
1974         m68ki_push_32(0);
1975         m68ki_push_32(0);
1976         m68ki_push_32(0);
1977         m68ki_push_32(0);
1978
1979         /* VERSION# (4 bits), INTERNAL INFORMATION */
1980         m68ki_push_16(0);
1981
1982         /* INTERNAL REGISTERS (3 words) */
1983         m68ki_push_32(0);
1984         m68ki_push_16(0);
1985
1986         /* DATA INTPUT BUFFER (2 words) */
1987         m68ki_push_32(0);
1988
1989         /* INTERNAL REGISTERS (2 words) */
1990         m68ki_push_32(0);
1991
1992         /* STAGE B ADDRESS (2 words) */
1993         m68ki_push_32(0);
1994
1995         /* INTERNAL REGISTER (4 words) */
1996         m68ki_push_32(0);
1997         m68ki_push_32(0);
1998
1999         /* DATA OUTPUT BUFFER (2 words) */
2000         m68ki_push_32(0);
2001
2002         /* INTERNAL REGISTER */
2003         m68ki_push_16(0);
2004
2005         /* INTERNAL REGISTER */
2006         m68ki_push_16(0);
2007
2008         /* DATA CYCLE FAULT ADDRESS (2 words) */
2009         m68ki_push_32(fault_address);
2010
2011         /* INSTRUCTION PIPE STAGE B */
2012         m68ki_push_16(0);
2013
2014         /* INSTRUCTION PIPE STAGE C */
2015         m68ki_push_16(0);
2016
2017         /* SPECIAL STATUS REGISTER */
2018         m68ki_push_16(0x0100 | orig_fc | (orig_rw<<6) | (orig_sz<<4));
2019
2020         /* INTERNAL REGISTER */
2021         m68ki_push_16(0);
2022
2023         /* 1011, VECTOR OFFSET */
2024         m68ki_push_16(0xb000 | (vector<<2));
2025
2026         /* PROGRAM COUNTER */
2027         m68ki_push_32(pc);
2028
2029         /* STATUS REGISTER */
2030         m68ki_push_16(sr);
2031 }
2032
2033 /* Type 7 stack frame (access fault).
2034  * This is used by the 68040 for bus fault and mmu trap
2035  * 30 words
2036  */
2037 static inline void m68ki_stack_frame_0111(uint sr, uint vector, uint pc, uint fault_address, uint8 in_mmu)
2038 {
2039         int orig_rw = m68ki_cpu.mmu_tmp_buserror_rw;    // this gets splatted by the following pushes, so save it now
2040         int orig_fc = m68ki_cpu.mmu_tmp_buserror_fc;
2041
2042         /* INTERNAL REGISTERS (18 words) */
2043         m68ki_push_32(0);
2044         m68ki_push_32(0);
2045         m68ki_push_32(0);
2046         m68ki_push_32(0);
2047         m68ki_push_32(0);
2048         m68ki_push_32(0);
2049         m68ki_push_32(0);
2050         m68ki_push_32(0);
2051         m68ki_push_32(0);
2052
2053         /* FAULT ADDRESS (2 words) */
2054         m68ki_push_32(fault_address);
2055
2056         /* INTERNAL REGISTERS (3 words) */
2057         m68ki_push_32(0);
2058         m68ki_push_16(0);
2059
2060         /* SPECIAL STATUS REGISTER (1 word) */
2061         m68ki_push_16((in_mmu ? 0x400 : 0) | orig_fc | (orig_rw<<8));
2062
2063         /* EFFECTIVE ADDRESS (2 words) */
2064         m68ki_push_32(fault_address);
2065
2066         /* 0111, VECTOR OFFSET (1 word) */
2067         m68ki_push_16(0x7000 | (vector<<2));
2068
2069         /* PROGRAM COUNTER (2 words) */
2070         m68ki_push_32(pc);
2071
2072         /* STATUS REGISTER (1 word) */
2073         m68ki_push_16(sr);
2074 }
2075
2076 /* Used for Group 2 exceptions.
2077  * These stack a type 2 frame on the 020.
2078  */
2079 static inline void m68ki_exception_trap(uint vector)
2080 {
2081         uint sr = m68ki_init_exception();
2082
2083         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
2084                 m68ki_stack_frame_0000(REG_PC, sr, vector);
2085         else
2086                 m68ki_stack_frame_0010(sr, vector);
2087
2088         m68ki_jump_vector(vector);
2089
2090         /* Use up some clock cycles and undo the instruction's cycles */
2091         USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]);
2092 }
2093
2094 /* Trap#n stacks a 0 frame but behaves like group2 otherwise */
2095 static inline void m68ki_exception_trapN(uint vector)
2096 {
2097         uint sr = m68ki_init_exception();
2098         m68ki_stack_frame_0000(REG_PC, sr, vector);
2099         m68ki_jump_vector(vector);
2100
2101         /* Use up some clock cycles and undo the instruction's cycles */
2102         USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]);
2103 }
2104
2105 /* Exception for trace mode */
2106 static inline void m68ki_exception_trace(void)
2107 {
2108         uint sr = m68ki_init_exception();
2109
2110         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
2111         {
2112                 #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
2113                 if(CPU_TYPE_IS_000(CPU_TYPE))
2114                 {
2115                         CPU_INSTR_MODE = INSTRUCTION_NO;
2116                 }
2117                 #endif /* M68K_EMULATE_ADDRESS_ERROR */
2118                 m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE);
2119         }
2120         else
2121                 m68ki_stack_frame_0010(sr, EXCEPTION_TRACE);
2122
2123         m68ki_jump_vector(EXCEPTION_TRACE);
2124
2125         /* Trace nullifies a STOP instruction */
2126         CPU_STOPPED &= ~STOP_LEVEL_STOP;
2127
2128         /* Use up some clock cycles */
2129         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]);
2130 }
2131
2132 /* Exception for privilege violation */
2133 static inline void m68ki_exception_privilege_violation(void)
2134 {
2135         uint sr = m68ki_init_exception();
2136
2137         #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
2138         if(CPU_TYPE_IS_000(CPU_TYPE))
2139         {
2140                 CPU_INSTR_MODE = INSTRUCTION_NO;
2141         }
2142         #endif /* M68K_EMULATE_ADDRESS_ERROR */
2143
2144         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_PRIVILEGE_VIOLATION);
2145         m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION);
2146
2147         /* Use up some clock cycles and undo the instruction's cycles */
2148         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]);
2149 }
2150
2151 extern jmp_buf m68ki_bus_error_jmp_buf;
2152
2153 #define m68ki_check_bus_error_trap() setjmp(m68ki_bus_error_jmp_buf)
2154
2155 /* Exception for bus error */
2156 static inline void m68ki_exception_bus_error(void)
2157 {
2158         int i;
2159
2160         /* If we were processing a bus error, address error, or reset,
2161          * this is a catastrophic failure.
2162          * Halt the CPU
2163          */
2164         if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET)
2165         {
2166                 m68k_read_memory_8(0x00ffff01);
2167                 CPU_STOPPED = STOP_LEVEL_HALT;
2168                 return;
2169         }
2170         CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
2171
2172         /* Use up some clock cycles and undo the instruction's cycles */
2173         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_BUS_ERROR] - CYC_INSTRUCTION[REG_IR]);
2174
2175         for (i = 15; i >= 0; i--){
2176                 REG_DA[i] = REG_DA_SAVE[i];
2177         }
2178
2179         uint sr = m68ki_init_exception();
2180         m68ki_stack_frame_1000(REG_PPC, sr, EXCEPTION_BUS_ERROR);
2181
2182         m68ki_jump_vector(EXCEPTION_BUS_ERROR);
2183         longjmp(m68ki_bus_error_jmp_buf, 1);
2184 }
2185
2186 extern int cpu_log_enabled;
2187
2188 /* Exception for A-Line instructions */
2189 static inline void m68ki_exception_1010(void)
2190 {
2191         uint sr;
2192 #if M68K_LOG_1010_1111 == OPT_ON
2193         M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n",
2194                                          m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
2195                                          m68ki_disassemble_quick(ADDRESS_68K(REG_PPC),CPU_TYPE)));
2196 #endif
2197
2198         sr = m68ki_init_exception();
2199         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1010);
2200         m68ki_jump_vector(EXCEPTION_1010);
2201
2202         /* Use up some clock cycles and undo the instruction's cycles */
2203         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]);
2204 }
2205
2206 /* Exception for F-Line instructions */
2207 static inline void m68ki_exception_1111(void)
2208 {
2209         uint sr;
2210
2211 #if M68K_LOG_1010_1111 == OPT_ON
2212         M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n",
2213                                          m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
2214                                          m68ki_disassemble_quick(ADDRESS_68K(REG_PPC),CPU_TYPE)));
2215 #endif
2216
2217         sr = m68ki_init_exception();
2218         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1111);
2219         m68ki_jump_vector(EXCEPTION_1111);
2220
2221         /* Use up some clock cycles and undo the instruction's cycles */
2222         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]);
2223 }
2224
2225 #if M68K_ILLG_HAS_CALLBACK == OPT_SPECIFY_HANDLER
2226 extern int m68ki_illg_callback(int);
2227 #endif
2228
2229 /* Exception for illegal instructions */
2230 static inline void m68ki_exception_illegal(void)
2231 {
2232         uint sr;
2233
2234         M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n",
2235                                  m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
2236                                  m68ki_disassemble_quick(ADDRESS_68K(REG_PPC),CPU_TYPE)));
2237         if (m68ki_illg_callback(REG_IR))
2238             return;
2239
2240         sr = m68ki_init_exception();
2241
2242         #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
2243         if(CPU_TYPE_IS_000(CPU_TYPE))
2244         {
2245                 CPU_INSTR_MODE = INSTRUCTION_NO;
2246         }
2247         #endif /* M68K_EMULATE_ADDRESS_ERROR */
2248
2249         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_ILLEGAL_INSTRUCTION);
2250         m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION);
2251
2252         /* Use up some clock cycles and undo the instruction's cycles */
2253         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]);
2254 }
2255
2256 /* Exception for format errror in RTE */
2257 static inline void m68ki_exception_format_error(void)
2258 {
2259         uint sr = m68ki_init_exception();
2260         m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR);
2261         m68ki_jump_vector(EXCEPTION_FORMAT_ERROR);
2262
2263         /* Use up some clock cycles and undo the instruction's cycles */
2264         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]);
2265 }
2266
2267 /* Exception for address error */
2268 static inline void m68ki_exception_address_error(void)
2269 {
2270         uint32 sr = m68ki_init_exception();
2271
2272         /* If we were processing a bus error, address error, or reset,
2273          * this is a catastrophic failure.
2274          * Halt the CPU
2275          */
2276         if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET_WSF)
2277         {
2278                 m68k_read_memory_8(0x00ffff01);
2279                 CPU_STOPPED = STOP_LEVEL_HALT;
2280                 return;
2281         }
2282         CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
2283
2284         /* Note: This is implemented for 68000 only! */
2285         m68ki_stack_frame_buserr(sr);
2286
2287         m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR);
2288
2289         /* Use up some clock cycles. Note that we don't need to undo the
2290         instruction's cycles here as we've longjmp:ed directly from the
2291         instruction handler without passing the part of the excecute loop
2292         that deducts instruction cycles */
2293         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR]);
2294 }
2295
2296
2297 /* Service an interrupt request and start exception processing */
2298 static inline void m68ki_exception_interrupt(uint int_level)
2299 {
2300         uint vector;
2301         uint sr;
2302         uint new_pc;
2303
2304         #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
2305         if(CPU_TYPE_IS_000(CPU_TYPE))
2306         {
2307                 CPU_INSTR_MODE = INSTRUCTION_NO;
2308         }
2309         #endif /* M68K_EMULATE_ADDRESS_ERROR */
2310
2311         /* Turn off the stopped state */
2312         CPU_STOPPED &= ~STOP_LEVEL_STOP;
2313
2314         /* If we are halted, don't do anything */
2315         if(CPU_STOPPED)
2316                 return;
2317
2318         /* Acknowledge the interrupt */
2319         vector = m68ki_int_ack(int_level);
2320
2321         /* Get the interrupt vector */
2322         if(vector == M68K_INT_ACK_AUTOVECTOR)
2323                 /* Use the autovectors.  This is the most commonly used implementation */
2324                 vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
2325         else if(vector == M68K_INT_ACK_SPURIOUS)
2326                 /* Called if no devices respond to the interrupt acknowledge */
2327                 vector = EXCEPTION_SPURIOUS_INTERRUPT;
2328         else if(vector > 255)
2329         {
2330                 M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n",
2331                                  m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector));
2332                 return;
2333         }
2334
2335         /* Start exception processing */
2336         sr = m68ki_init_exception();
2337
2338         /* Set the interrupt mask to the level of the one being serviced */
2339         FLAG_INT_MASK = int_level<<8;
2340
2341         /* Get the new PC */
2342         new_pc = m68ki_read_data_32((vector<<2) + REG_VBR);
2343
2344         /* If vector is uninitialized, call the uninitialized interrupt vector */
2345         if(new_pc == 0)
2346                 new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR);
2347
2348         /* Generate a stack frame */
2349         m68ki_stack_frame_0000(REG_PC, sr, vector);
2350         if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
2351         {
2352                 /* Create throwaway frame */
2353                 m68ki_set_sm_flag(FLAG_S);      /* clear M */
2354                 sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */
2355                 m68ki_stack_frame_0001(REG_PC, sr, vector);
2356         }
2357
2358         m68ki_jump(new_pc);
2359
2360         /* Defer cycle counting until later */
2361         USE_CYCLES(CYC_EXCEPTION[vector]);
2362
2363 #if !M68K_EMULATE_INT_ACK
2364         /* Automatically clear IRQ if we are not using an acknowledge scheme */
2365         CPU_INT_LEVEL = 0;
2366 #endif /* M68K_EMULATE_INT_ACK */
2367 }
2368
2369
2370 /* ASG: Check for interrupts */
2371 static inline void m68ki_check_interrupts(void)
2372 {
2373         if(m68ki_cpu.nmi_pending)
2374         {
2375                 m68ki_cpu.nmi_pending = FALSE;
2376                 m68ki_exception_interrupt(7);
2377         }
2378         else if(CPU_INT_LEVEL > FLAG_INT_MASK)
2379                 m68ki_exception_interrupt(CPU_INT_LEVEL>>8);
2380 }
2381
2382
2383
2384 /* ======================================================================== */
2385 /* ============================== END OF FILE ============================= */
2386 /* ======================================================================== */
2387
2388 #ifdef __cplusplus
2389 }
2390 #endif
2391
2392 #endif /* M68KCPU__HEADER */