]> Shamusworld >> Repos - virtualjaguar/blob - src/m68kcpu.h
Initial revision
[virtualjaguar] / src / m68kcpu.h
1 #include <stdio.h>
2 /* ======================================================================== */
3 /* ========================= LICENSING & COPYRIGHT ======================== */
4 /* ======================================================================== */
5 /*
6  *                                  MUSASHI
7  *                                Version 3.3
8  *
9  * A portable Motorola M680x0 processor emulation engine.
10  * Copyright 1998-2001 Karl Stenerud.  All rights reserved.
11  *
12  * This code may be freely used for non-commercial purposes as long as this
13  * copyright notice remains unaltered in the source code and any binary files
14  * containing this code in compiled form.
15  *
16  * All other lisencing terms must be negotiated with the author
17  * (Karl Stenerud).
18  *
19  * The latest version of this code can be obtained at:
20  * http://kstenerud.cjb.net
21  */
22
23
24
25
26 #ifndef M68KCPU__HEADER
27 #define M68KCPU__HEADER
28
29 #include "m68k.h"
30 #include <limits.h>
31
32 #if M68K_EMULATE_ADDRESS_ERROR
33 #include <setjmp.h>
34 #endif /* M68K_EMULATE_ADDRESS_ERROR */
35
36 /* ======================================================================== */
37 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
38 /* ======================================================================== */
39
40 /* Check for > 32bit sizes */
41 #if UINT_MAX > 0xffffffff
42         #define M68K_INT_GT_32_BIT  1
43 #endif
44
45 /* Data types used in this emulation core */
46 #undef sint8
47 #undef sint16
48 #undef sint32
49 #undef sint64
50 #undef uint8
51 #undef uint16
52 #undef uint32
53 #undef uint64
54 #undef sint
55 #undef uint
56
57 #define sint8  signed   char                    /* ASG: changed from char to signed char */
58 #define sint16 signed   short
59 #define sint32 signed   long
60 #define uint8  unsigned char
61 #define uint16 unsigned short
62 #define uint32 unsigned long
63
64 /* signed and unsigned int must be at least 32 bits wide */
65 #define sint   signed   int
66 #define uint   unsigned int
67
68
69 #if M68K_USE_64_BIT
70 #define sint64 signed   long long
71 #define uint64 unsigned long long
72 #else
73 #define sint64 sint32
74 #define uint64 uint32
75 #endif /* M68K_USE_64_BIT */
76
77
78
79 /* Allow for architectures that don't have 8-bit sizes */
80 #if UCHAR_MAX == 0xff
81         #define MAKE_INT_8(A) (sint8)(A)
82 #else
83         #undef  sint8
84         #define sint8  signed   int
85         #undef  uint8
86         #define uint8  unsigned int
87         INLINE sint MAKE_INT_8(uint value)
88         {
89                 return (value & 0x80) ? value | ~0xff : value & 0xff;
90         }
91 #endif /* UCHAR_MAX == 0xff */
92
93
94 /* Allow for architectures that don't have 16-bit sizes */
95 #if USHRT_MAX == 0xffff
96         #define MAKE_INT_16(A) (sint16)(A)
97 #else
98         #undef  sint16
99         #define sint16 signed   int
100         #undef  uint16
101         #define uint16 unsigned int
102         INLINE sint MAKE_INT_16(uint value)
103         {
104                 return (value & 0x8000) ? value | ~0xffff : value & 0xffff;
105         }
106 #endif /* USHRT_MAX == 0xffff */
107
108
109 /* Allow for architectures that don't have 32-bit sizes */
110 #if ULONG_MAX == 0xffffffff
111         #define MAKE_INT_32(A) (sint32)(A)
112 #else
113         #undef  sint32
114         #define sint32  signed   int
115         #undef  uint32
116         #define uint32  unsigned int
117         INLINE sint MAKE_INT_32(uint value)
118         {
119                 return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff;
120         }
121 #endif /* ULONG_MAX == 0xffffffff */
122
123
124
125
126 /* ======================================================================== */
127 /* ============================ GENERAL DEFINES =========================== */
128 /* ======================================================================== */
129
130 /* Exception Vectors handled by emulation */
131 #define EXCEPTION_BUS_ERROR                2 /* This one is not emulated! */
132 #define EXCEPTION_ADDRESS_ERROR            3 /* This one is partially emulated (doesn't stack a proper frame yet) */
133 #define EXCEPTION_ILLEGAL_INSTRUCTION      4
134 #define EXCEPTION_ZERO_DIVIDE              5
135 #define EXCEPTION_CHK                      6
136 #define EXCEPTION_TRAPV                    7
137 #define EXCEPTION_PRIVILEGE_VIOLATION      8
138 #define EXCEPTION_TRACE                    9
139 #define EXCEPTION_1010                    10
140 #define EXCEPTION_1111                    11
141 #define EXCEPTION_FORMAT_ERROR            14
142 #define EXCEPTION_UNINITIALIZED_INTERRUPT 15
143 #define EXCEPTION_SPURIOUS_INTERRUPT      24
144 #define EXCEPTION_INTERRUPT_AUTOVECTOR    24
145 #define EXCEPTION_TRAP_BASE               32
146
147 /* Function codes set by CPU during data/address bus activity */
148 #define FUNCTION_CODE_USER_DATA          1
149 #define FUNCTION_CODE_USER_PROGRAM       2
150 #define FUNCTION_CODE_SUPERVISOR_DATA    5
151 #define FUNCTION_CODE_SUPERVISOR_PROGRAM 6
152 #define FUNCTION_CODE_CPU_SPACE          7
153
154 /* CPU types for deciding what to emulate */
155 #define CPU_TYPE_000   1
156 #define CPU_TYPE_010   2
157 #define CPU_TYPE_EC020 4
158 #define CPU_TYPE_020   8
159
160 /* Different ways to stop the CPU */
161 #define STOP_LEVEL_STOP 1
162 #define STOP_LEVEL_HALT 2
163
164 #ifndef NULL
165 #define NULL ((void*)0)
166 #endif
167
168 /* ======================================================================== */
169 /* ================================ MACROS ================================ */
170 /* ======================================================================== */
171
172
173 /* ---------------------------- General Macros ---------------------------- */
174
175 /* Bit Isolation Macros */
176 #define BIT_0(A)  ((A) & 0x00000001)
177 #define BIT_1(A)  ((A) & 0x00000002)
178 #define BIT_2(A)  ((A) & 0x00000004)
179 #define BIT_3(A)  ((A) & 0x00000008)
180 #define BIT_4(A)  ((A) & 0x00000010)
181 #define BIT_5(A)  ((A) & 0x00000020)
182 #define BIT_6(A)  ((A) & 0x00000040)
183 #define BIT_7(A)  ((A) & 0x00000080)
184 #define BIT_8(A)  ((A) & 0x00000100)
185 #define BIT_9(A)  ((A) & 0x00000200)
186 #define BIT_A(A)  ((A) & 0x00000400)
187 #define BIT_B(A)  ((A) & 0x00000800)
188 #define BIT_C(A)  ((A) & 0x00001000)
189 #define BIT_D(A)  ((A) & 0x00002000)
190 #define BIT_E(A)  ((A) & 0x00004000)
191 #define BIT_F(A)  ((A) & 0x00008000)
192 #define BIT_10(A) ((A) & 0x00010000)
193 #define BIT_11(A) ((A) & 0x00020000)
194 #define BIT_12(A) ((A) & 0x00040000)
195 #define BIT_13(A) ((A) & 0x00080000)
196 #define BIT_14(A) ((A) & 0x00100000)
197 #define BIT_15(A) ((A) & 0x00200000)
198 #define BIT_16(A) ((A) & 0x00400000)
199 #define BIT_17(A) ((A) & 0x00800000)
200 #define BIT_18(A) ((A) & 0x01000000)
201 #define BIT_19(A) ((A) & 0x02000000)
202 #define BIT_1A(A) ((A) & 0x04000000)
203 #define BIT_1B(A) ((A) & 0x08000000)
204 #define BIT_1C(A) ((A) & 0x10000000)
205 #define BIT_1D(A) ((A) & 0x20000000)
206 #define BIT_1E(A) ((A) & 0x40000000)
207 #define BIT_1F(A) ((A) & 0x80000000)
208
209 /* Get the most significant bit for specific sizes */
210 #define GET_MSB_8(A)  ((A) & 0x80)
211 #define GET_MSB_9(A)  ((A) & 0x100)
212 #define GET_MSB_16(A) ((A) & 0x8000)
213 #define GET_MSB_17(A) ((A) & 0x10000)
214 #define GET_MSB_32(A) ((A) & 0x80000000)
215 #if M68K_USE_64_BIT
216 #define GET_MSB_33(A) ((A) & 0x100000000)
217 #endif /* M68K_USE_64_BIT */
218
219 /* Isolate nibbles */
220 #define LOW_NIBBLE(A)  ((A) & 0x0f)
221 #define HIGH_NIBBLE(A) ((A) & 0xf0)
222
223 /* These are used to isolate 8, 16, and 32 bit sizes */
224 #define MASK_OUT_ABOVE_2(A)  ((A) & 3)
225 #define MASK_OUT_ABOVE_8(A)  ((A) & 0xff)
226 #define MASK_OUT_ABOVE_16(A) ((A) & 0xffff)
227 #define MASK_OUT_BELOW_2(A)  ((A) & ~3)
228 #define MASK_OUT_BELOW_8(A)  ((A) & ~0xff)
229 #define MASK_OUT_BELOW_16(A) ((A) & ~0xffff)
230
231 /* No need to mask if we are 32 bit */
232 #if M68K_INT_GT_32BIT || M68K_USE_64_BIT
233         #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff)
234         #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff)
235 #else
236         #define MASK_OUT_ABOVE_32(A) (A)
237         #define MASK_OUT_BELOW_32(A) 0
238 #endif /* M68K_INT_GT_32BIT || M68K_USE_64_BIT */
239
240 /* Simulate address lines of 68k family */
241 #define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK)
242
243
244 /* Shift & Rotate Macros. */
245 #define LSL(A, C) ((A) << (C))
246 #define LSR(A, C) ((A) >> (C))
247
248 /* Some > 32-bit optimizations */
249 #if M68K_INT_GT_32BIT
250         /* Shift left and right */
251         #define LSR_32(A, C) ((A) >> (C))
252         #define LSL_32(A, C) ((A) << (C))
253 #else
254         /* We have to do this because the morons at ANSI decided that shifts
255          * by >= data size are undefined.
256          */
257         #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
258         #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
259 #endif /* M68K_INT_GT_32BIT */
260
261 #if M68K_USE_64_BIT
262         #define LSL_32_64(A, C) ((A) << (C))
263         #define LSR_32_64(A, C) ((A) >> (C))
264         #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C)))
265         #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C)))
266 #endif /* M68K_USE_64_BIT */
267
268 #define ROL_8(A, C)      MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C)))
269 #define ROL_9(A, C)                      (LSL(A, C) | LSR(A, 9-(C)))
270 #define ROL_16(A, C)    MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C)))
271 #define ROL_17(A, C)                     (LSL(A, C) | LSR(A, 17-(C)))
272 #define ROL_32(A, C)    MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C)))
273 #define ROL_33(A, C)                     (LSL_32(A, C) | LSR_32(A, 33-(C)))
274
275 #define ROR_8(A, C)      MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C)))
276 #define ROR_9(A, C)                      (LSR(A, C) | LSL(A, 9-(C)))
277 #define ROR_16(A, C)    MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C)))
278 #define ROR_17(A, C)                     (LSR(A, C) | LSL(A, 17-(C)))
279 #define ROR_32(A, C)    MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C)))
280 #define ROR_33(A, C)                     (LSR_32(A, C) | LSL_32(A, 33-(C)))
281
282
283
284 /* ------------------------------ CPU Access ------------------------------ */
285
286 /* Access the CPU registers */
287 #define CPU_TYPE         m68ki_cpu.cpu_type
288
289 #define REG_DA           m68ki_cpu.dar /* easy access to data and address regs */
290 #define REG_D            m68ki_cpu.dar
291 #define REG_A            (m68ki_cpu.dar+8)
292 #define REG_PPC                  m68ki_cpu.ppc
293 #define REG_PC           m68ki_cpu.pc
294 #define REG_SP_BASE      m68ki_cpu.sp
295 #define REG_USP          m68ki_cpu.sp[0]
296 #define REG_ISP          m68ki_cpu.sp[4]
297 #define REG_MSP          m68ki_cpu.sp[6]
298 #define REG_SP           m68ki_cpu.dar[15]
299 #define REG_VBR          m68ki_cpu.vbr
300 #define REG_SFC          m68ki_cpu.sfc
301 #define REG_DFC          m68ki_cpu.dfc
302 #define REG_CACR         m68ki_cpu.cacr
303 #define REG_CAAR         m68ki_cpu.caar
304 #define REG_IR           m68ki_cpu.ir
305
306 #define FLAG_T1          m68ki_cpu.t1_flag
307 #define FLAG_T0          m68ki_cpu.t0_flag
308 #define FLAG_S           m68ki_cpu.s_flag
309 #define FLAG_M           m68ki_cpu.m_flag
310 #define FLAG_X           m68ki_cpu.x_flag
311 #define FLAG_N           m68ki_cpu.n_flag
312 #define FLAG_Z           m68ki_cpu.not_z_flag
313 #define FLAG_V           m68ki_cpu.v_flag
314 #define FLAG_C           m68ki_cpu.c_flag
315 #define FLAG_INT_MASK    m68ki_cpu.int_mask
316
317 #define CPU_INT_LEVEL    m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */
318 #define CPU_INT_CYCLES   m68ki_cpu.int_cycles /* ASG */
319 #define CPU_STOPPED      m68ki_cpu.stopped
320 #define CPU_PREF_ADDR    m68ki_cpu.pref_addr
321 #define CPU_PREF_DATA    m68ki_cpu.pref_data
322 #define CPU_ADDRESS_MASK m68ki_cpu.address_mask
323 #define CPU_SR_MASK      m68ki_cpu.sr_mask
324
325 #define CYC_INSTRUCTION  m68ki_cpu.cyc_instruction
326 #define CYC_EXCEPTION    m68ki_cpu.cyc_exception
327 #define CYC_BCC_NOTAKE_B m68ki_cpu.cyc_bcc_notake_b
328 #define CYC_BCC_NOTAKE_W m68ki_cpu.cyc_bcc_notake_w
329 #define CYC_DBCC_F_NOEXP m68ki_cpu.cyc_dbcc_f_noexp
330 #define CYC_DBCC_F_EXP   m68ki_cpu.cyc_dbcc_f_exp
331 #define CYC_SCC_R_FALSE  m68ki_cpu.cyc_scc_r_false
332 #define CYC_MOVEM_W      m68ki_cpu.cyc_movem_w
333 #define CYC_MOVEM_L      m68ki_cpu.cyc_movem_l
334 #define CYC_SHIFT        m68ki_cpu.cyc_shift
335 #define CYC_RESET        m68ki_cpu.cyc_reset
336
337
338 #define CALLBACK_INT_ACK     m68ki_cpu.int_ack_callback
339 #define CALLBACK_BKPT_ACK    m68ki_cpu.bkpt_ack_callback
340 #define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback
341 #define CALLBACK_PC_CHANGED  m68ki_cpu.pc_changed_callback
342 #define CALLBACK_SET_FC      m68ki_cpu.set_fc_callback
343 #define CALLBACK_INSTR_HOOK  m68ki_cpu.instr_hook_callback
344
345
346
347 /* ----------------------------- Configuration ---------------------------- */
348
349 /* These defines are dependant on the configuration defines in m68kconf.h */
350
351 /* Disable certain comparisons if we're not using all CPU types */
352 #if M68K_EMULATE_020
353         #define CPU_TYPE_IS_020_PLUS(A)    ((A) & CPU_TYPE_020)
354         #define CPU_TYPE_IS_020_LESS(A)    1
355 #else
356         #define CPU_TYPE_IS_020_PLUS(A)    0
357         #define CPU_TYPE_IS_020_LESS(A)    1
358 #endif
359
360 #if M68K_EMULATE_EC020
361         #define CPU_TYPE_IS_EC020_PLUS(A)  ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
362         #define CPU_TYPE_IS_EC020_LESS(A)  ((A) & (CPU_TYPE_000 | CPU_TYPE_010 | CPU_TYPE_EC020))
363 #else
364         #define CPU_TYPE_IS_EC020_PLUS(A)  CPU_TYPE_IS_020_PLUS(A)
365         #define CPU_TYPE_IS_EC020_LESS(A)  CPU_TYPE_IS_020_LESS(A)
366 #endif
367
368 #if M68K_EMULATE_010
369         #define CPU_TYPE_IS_010(A)         ((A) == CPU_TYPE_010)
370         #define CPU_TYPE_IS_010_PLUS(A)    ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020))
371         #define CPU_TYPE_IS_010_LESS(A)    ((A) & (CPU_TYPE_000 | CPU_TYPE_010))
372 #else
373         #define CPU_TYPE_IS_010(A)         0
374         #define CPU_TYPE_IS_010_PLUS(A)    CPU_TYPE_IS_EC020_PLUS(A)
375         #define CPU_TYPE_IS_010_LESS(A)    CPU_TYPE_IS_EC020_LESS(A)
376 #endif
377
378 #if M68K_EMULATE_020 || M68K_EMULATE_EC020
379         #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
380 #else
381         #define CPU_TYPE_IS_020_VARIANT(A) 0
382 #endif
383
384 #if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010
385         #define CPU_TYPE_IS_000(A)         ((A) == CPU_TYPE_000)
386 #else
387         #define CPU_TYPE_IS_000(A)         1
388 #endif
389
390
391 #if !M68K_SEPARATE_READS
392 #define m68k_read_immediate_16(A) m68ki_read_program_16(A)
393 #define m68k_read_immediate_32(A) m68ki_read_program_32(A)
394
395 #define m68k_read_pcrelative_8(A) m68ki_read_program_8(A)
396 #define m68k_read_pcrelative_16(A) m68ki_read_program_16(A)
397 #define m68k_read_pcrelative_32(A) m68ki_read_program_32(A)
398 #endif /* M68K_SEPARATE_READS */
399
400
401 /* Enable or disable callback functions */
402 #if M68K_EMULATE_INT_ACK
403         #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER
404                 #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A)
405         #else
406                 #define m68ki_int_ack(A) CALLBACK_INT_ACK(A)
407         #endif
408 #else
409         /* Default action is to used autovector mode, which is most common */
410         #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR
411 #endif /* M68K_EMULATE_INT_ACK */
412
413 #if M68K_EMULATE_BKPT_ACK
414         #if M68K_EMULATE_BKPT_ACK == OPT_SPECIFY_HANDLER
415                 #define m68ki_bkpt_ack(A) M68K_BKPT_ACK_CALLBACK(A)
416         #else
417                 #define m68ki_bkpt_ack(A) CALLBACK_BKPT_ACK(A)
418         #endif
419 #else
420         #define m68ki_bkpt_ack(A)
421 #endif /* M68K_EMULATE_BKPT_ACK */
422
423 #if M68K_EMULATE_RESET
424         #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER
425                 #define m68ki_output_reset() M68K_RESET_CALLBACK()
426         #else
427                 #define m68ki_output_reset() CALLBACK_RESET_INSTR()
428         #endif
429 #else
430         #define m68ki_output_reset()
431 #endif /* M68K_EMULATE_RESET */
432
433 #if M68K_INSTRUCTION_HOOK
434         #if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
435                 #define m68ki_instr_hook() M68K_INSTRUCTION_CALLBACK()
436         #else
437                 #define m68ki_instr_hook() CALLBACK_INSTR_HOOK()
438         #endif
439 #else
440         #define m68ki_instr_hook()
441 #endif /* M68K_INSTRUCTION_HOOK */
442
443 #if M68K_MONITOR_PC
444         #if M68K_MONITOR_PC == OPT_SPECIFY_HANDLER
445                 #define m68ki_pc_changed(A) M68K_SET_PC_CALLBACK(ADDRESS_68K(A))
446         #else
447                 #define m68ki_pc_changed(A) CALLBACK_PC_CHANGED(ADDRESS_68K(A))
448         #endif
449 #else
450         #define m68ki_pc_changed(A)
451 #endif /* M68K_MONITOR_PC */
452
453
454 /* Enable or disable function code emulation */
455 #if M68K_EMULATE_FC
456         #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER
457                 #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A)
458         #else
459                 #define m68ki_set_fc(A) CALLBACK_SET_FC(A)
460         #endif
461         #define m68ki_use_data_space() m68ki_address_space = FUNCTION_CODE_USER_DATA
462         #define m68ki_use_program_space() m68ki_address_space = FUNCTION_CODE_USER_PROGRAM
463         #define m68ki_get_address_space() m68ki_address_space
464 #else
465         #define m68ki_set_fc(A)
466         #define m68ki_use_data_space()
467         #define m68ki_use_program_space()
468         #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA
469 #endif /* M68K_EMULATE_FC */
470
471
472 /* Enable or disable trace emulation */
473 #if M68K_EMULATE_TRACE
474         /* Initiates trace checking before each instruction (t1) */
475         #define m68ki_trace_t1() m68ki_tracing = FLAG_T1
476         /* adds t0 to trace checking if we encounter change of flow */
477         #define m68ki_trace_t0() m68ki_tracing |= FLAG_T0
478         /* Clear all tracing */
479         #define m68ki_clear_trace() m68ki_tracing = 0
480         /* Cause a trace exception if we are tracing */
481         #define m68ki_exception_if_trace() if(m68ki_tracing) m68ki_exception_trace()
482 #else
483         #define m68ki_trace_t1()
484         #define m68ki_trace_t0()
485         #define m68ki_clear_trace()
486         #define m68ki_exception_if_trace()
487 #endif /* M68K_EMULATE_TRACE */
488
489
490
491 /* Address error */
492 #if M68K_EMULATE_ADDRESS_ERROR
493         extern jmp_buf m68ki_address_error_trap;
494         #define m68ki_set_address_error_trap() if(setjmp(m68ki_address_error_trap)) m68ki_exception_address_error();
495         #define m68ki_check_address_error(A) if((A)&1) longjmp(m68ki_address_error_jump, 1);
496 #else
497         #define m68ki_set_address_error_trap()
498         #define m68ki_check_address_error(A)
499 #endif /* M68K_ADDRESS_ERROR */
500
501 /* Logging */
502 #if M68K_LOG_ENABLE
503         #include <stdio.h>
504         extern FILE* M68K_LOG_FILEHANDLE
505         extern char* m68ki_cpu_names[];
506
507         #define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A
508         #if M68K_LOG_1010_1111
509                 #define M68K_DO_LOG_EMU(A) if(M68K_LOG_FILEHANDLE) fprintf A
510         #else
511                 #define M68K_DO_LOG_EMU(A)
512         #endif
513 #else
514         #define M68K_DO_LOG(A)
515         #define M68K_DO_LOG_EMU(A)
516 #endif
517
518
519
520 /* -------------------------- EA / Operand Access ------------------------- */
521
522 /*
523  * The general instruction format follows this pattern:
524  * .... XXX. .... .YYY
525  * where XXX is register X and YYY is register Y
526  */
527 /* Data Register Isolation */
528 #define DX (REG_D[(REG_IR >> 9) & 7])
529 #define DY (REG_D[REG_IR & 7])
530 /* Address Register Isolation */
531 #define AX (REG_A[(REG_IR >> 9) & 7])
532 #define AY (REG_A[REG_IR & 7])
533
534
535 /* Effective Address Calculations */
536 #define EA_AY_AI_8()   AY                                    /* address register indirect */
537 #define EA_AY_AI_16()  EA_AY_AI_8()
538 #define EA_AY_AI_32()  EA_AY_AI_8()
539 #define EA_AY_PI_8()   (AY++)                                /* postincrement (size = byte) */
540 #define EA_AY_PI_16()  ((AY+=2)-2)                           /* postincrement (size = word) */
541 #define EA_AY_PI_32()  ((AY+=4)-4)                           /* postincrement (size = long) */
542 #define EA_AY_PD_8()   (--AY)                                /* predecrement (size = byte) */
543 #define EA_AY_PD_16()  (AY-=2)                               /* predecrement (size = word) */
544 #define EA_AY_PD_32()  (AY-=4)                               /* predecrement (size = long) */
545 #define EA_AY_DI_8()   (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */
546 #define EA_AY_DI_16()  EA_AY_DI_8()
547 #define EA_AY_DI_32()  EA_AY_DI_8()
548 #define EA_AY_IX_8()   m68ki_get_ea_ix(AY)                   /* indirect + index */
549 #define EA_AY_IX_16()  EA_AY_IX_8()
550 #define EA_AY_IX_32()  EA_AY_IX_8()
551
552 #define EA_AX_AI_8()   AX
553 #define EA_AX_AI_16()  EA_AX_AI_8()
554 #define EA_AX_AI_32()  EA_AX_AI_8()
555 #define EA_AX_PI_8()   (AX++)
556 #define EA_AX_PI_16()  ((AX+=2)-2)
557 #define EA_AX_PI_32()  ((AX+=4)-4)
558 #define EA_AX_PD_8()   (--AX)
559 #define EA_AX_PD_16()  (AX-=2)
560 #define EA_AX_PD_32()  (AX-=4)
561 #define EA_AX_DI_8()   (AX+MAKE_INT_16(m68ki_read_imm_16()))
562 #define EA_AX_DI_16()  EA_AX_DI_8()
563 #define EA_AX_DI_32()  EA_AX_DI_8()
564 #define EA_AX_IX_8()   m68ki_get_ea_ix(AX)
565 #define EA_AX_IX_16()  EA_AX_IX_8()
566 #define EA_AX_IX_32()  EA_AX_IX_8()
567
568 #define EA_A7_PI_8()   ((REG_A[7]+=2)-2)
569 #define EA_A7_PD_8()   (REG_A[7]-=2)
570
571 #define EA_AW_8()      MAKE_INT_16(m68ki_read_imm_16())      /* absolute word */
572 #define EA_AW_16()     EA_AW_8()
573 #define EA_AW_32()     EA_AW_8()
574 #define EA_AL_8()      m68ki_read_imm_32()                   /* absolute long */
575 #define EA_AL_16()     EA_AL_8()
576 #define EA_AL_32()     EA_AL_8()
577 #define EA_PCDI_8()    m68ki_get_ea_pcdi()                   /* pc indirect + displacement */
578 #define EA_PCDI_16()   EA_PCDI_8()
579 #define EA_PCDI_32()   EA_PCDI_8()
580 #define EA_PCIX_8()    m68ki_get_ea_pcix()                   /* pc indirect + index */
581 #define EA_PCIX_16()   EA_PCIX_8()
582 #define EA_PCIX_32()   EA_PCIX_8()
583
584
585 #define OPER_I_8()     m68ki_read_imm_8()
586 #define OPER_I_16()    m68ki_read_imm_16()
587 #define OPER_I_32()    m68ki_read_imm_32()
588
589
590
591 /* --------------------------- Status Register ---------------------------- */
592
593 /* Flag Calculation Macros */
594 #define CFLAG_8(A) (A)
595 #define CFLAG_16(A) ((A)>>8)
596
597 #if M68K_INT_GT_32_BIT
598         #define CFLAG_ADD_32(S, D, R) ((R)>>24)
599         #define CFLAG_SUB_32(S, D, R) ((R)>>24)
600 #else
601         #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23)
602         #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23)
603 #endif /* M68K_INT_GT_32_BIT */
604
605 #define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R))
606 #define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
607 #define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24)
608
609 #define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D))
610 #define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
611 #define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24)
612
613 #define NFLAG_8(A) (A)
614 #define NFLAG_16(A) ((A)>>8)
615 #define NFLAG_32(A) ((A)>>24)
616 #define NFLAG_64(A) ((A)>>56)
617
618 #define ZFLAG_8(A) MASK_OUT_ABOVE_8(A)
619 #define ZFLAG_16(A) MASK_OUT_ABOVE_16(A)
620 #define ZFLAG_32(A) MASK_OUT_ABOVE_32(A)
621
622
623 /* Flag values */
624 #define NFLAG_SET   0x80
625 #define NFLAG_CLEAR 0
626 #define CFLAG_SET   0x100
627 #define CFLAG_CLEAR 0
628 #define XFLAG_SET   0x100
629 #define XFLAG_CLEAR 0
630 #define VFLAG_SET   0x80
631 #define VFLAG_CLEAR 0
632 #define ZFLAG_SET   0
633 #define ZFLAG_CLEAR 0xffffffff
634
635 #define SFLAG_SET   4
636 #define SFLAG_CLEAR 0
637 #define MFLAG_SET   2
638 #define MFLAG_CLEAR 0
639
640 /* Turn flag values into 1 or 0 */
641 #define XFLAG_AS_1() ((FLAG_X>>8)&1)
642 #define NFLAG_AS_1() ((FLAG_N>>7)&1)
643 #define VFLAG_AS_1() ((FLAG_V>>7)&1)
644 #define ZFLAG_AS_1() (!FLAG_Z)
645 #define CFLAG_AS_1() ((FLAG_C>>8)&1)
646
647
648 /* Conditions */
649 #define COND_CS() (FLAG_C&0x100)
650 #define COND_CC() (!COND_CS())
651 #define COND_VS() (FLAG_V&0x80)
652 #define COND_VC() (!COND_VS())
653 #define COND_NE() FLAG_Z
654 #define COND_EQ() (!COND_NE())
655 #define COND_MI() (FLAG_N&0x80)
656 #define COND_PL() (!COND_MI())
657 #define COND_LT() ((FLAG_N^FLAG_V)&0x80)
658 #define COND_GE() (!COND_LT())
659 #define COND_HI() (COND_CC() && COND_NE())
660 #define COND_LS() (COND_CS() || COND_EQ())
661 #define COND_GT() (COND_GE() && COND_NE())
662 #define COND_LE() (COND_LT() || COND_EQ())
663
664 /* Reversed conditions */
665 #define COND_NOT_CS() COND_CC()
666 #define COND_NOT_CC() COND_CS()
667 #define COND_NOT_VS() COND_VC()
668 #define COND_NOT_VC() COND_VS()
669 #define COND_NOT_NE() COND_EQ()
670 #define COND_NOT_EQ() COND_NE()
671 #define COND_NOT_MI() COND_PL()
672 #define COND_NOT_PL() COND_MI()
673 #define COND_NOT_LT() COND_GE()
674 #define COND_NOT_GE() COND_LT()
675 #define COND_NOT_HI() COND_LS()
676 #define COND_NOT_LS() COND_HI()
677 #define COND_NOT_GT() COND_LE()
678 #define COND_NOT_LE() COND_GT()
679
680 /* Not real conditions, but here for convenience */
681 #define COND_XS() (FLAG_X&0x100)
682 #define COND_XC() (!COND_XS)
683
684
685 /* Get the condition code register */
686 #define m68ki_get_ccr() ((COND_XS() >> 4) | \
687                                                  (COND_MI() >> 4) | \
688                                                  (COND_EQ() << 2) | \
689                                                  (COND_VS() >> 6) | \
690                                                  (COND_CS() >> 8))
691
692 /* Get the status register */
693 #define m68ki_get_sr() ( FLAG_T1              | \
694                                                  FLAG_T0              | \
695                                                 (FLAG_S        << 11) | \
696                                                 (FLAG_M        << 11) | \
697                                                  FLAG_INT_MASK        | \
698                                                  m68ki_get_ccr())
699
700
701
702 /* ---------------------------- Cycle Counting ---------------------------- */
703
704 #define ADD_CYCLES(A)    m68ki_remaining_cycles += (A)
705 #define USE_CYCLES(A)    m68ki_remaining_cycles -= (A)
706 #define SET_CYCLES(A)    m68ki_remaining_cycles = A
707 #define GET_CYCLES()     m68ki_remaining_cycles
708 #define USE_ALL_CYCLES() m68ki_remaining_cycles = 0
709
710
711
712 /* ----------------------------- Read / Write ----------------------------- */
713
714 /* Read from the current address space */
715 #define m68ki_read_8(A)  m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space())
716 #define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space())
717 #define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space())
718
719 /* Write to the current data space */
720 #define m68ki_write_8(A, V)  m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
721 #define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
722 #define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
723
724 /* map read immediate 8 to read immediate 16 */
725 #define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16())
726
727 /* Map PC-relative reads */
728 #define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A)
729 #define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A)
730 #define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A)
731
732 /* Read from the program space */
733 #define m68ki_read_program_8(A)         m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
734 #define m68ki_read_program_16(A)        m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
735 #define m68ki_read_program_32(A)        m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
736
737 /* Read from the data space */
738 #define m68ki_read_data_8(A)    m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
739 #define m68ki_read_data_16(A)   m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
740 #define m68ki_read_data_32(A)   m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
741
742
743
744 /* ======================================================================== */
745 /* =============================== PROTOTYPES ============================= */
746 /* ======================================================================== */
747
748 typedef struct
749 {
750         uint cpu_type;     /* CPU Type: 68000, 68010, 68EC020, or 68020 */
751         uint dar[16];      /* Data and Address Registers */
752         uint ppc;                  /* Previous program counter */
753         uint pc;           /* Program Counter */
754         uint sp[7];        /* User, Interrupt, and Master Stack Pointers */
755         uint vbr;          /* Vector Base Register (m68010+) */
756         uint sfc;          /* Source Function Code Register (m68010+) */
757         uint dfc;          /* Destination Function Code Register (m68010+) */
758         uint cacr;         /* Cache Control Register (m68020, unemulated) */
759         uint caar;         /* Cache Address Register (m68020, unemulated) */
760         uint ir;           /* Instruction Register */
761         uint t1_flag;      /* Trace 1 */
762         uint t0_flag;      /* Trace 0 */
763         uint s_flag;       /* Supervisor */
764         uint m_flag;       /* Master/Interrupt state */
765         uint x_flag;       /* Extend */
766         uint n_flag;       /* Negative */
767         uint not_z_flag;   /* Zero, inverted for speedups */
768         uint v_flag;       /* Overflow */
769         uint c_flag;       /* Carry */
770         uint int_mask;     /* I0-I2 */
771         uint int_level;    /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */
772         uint int_cycles;   /* ASG: extra cycles from generated interrupts */
773         uint stopped;      /* Stopped state */
774         uint pref_addr;    /* Last prefetch address */
775         uint pref_data;    /* Data in the prefetch queue */
776         uint address_mask; /* Available address pins */
777         uint sr_mask;      /* Implemented status register bits */
778
779         /* Clocks required for instructions / exceptions */
780         uint cyc_bcc_notake_b;
781         uint cyc_bcc_notake_w;
782         uint cyc_dbcc_f_noexp;
783         uint cyc_dbcc_f_exp;
784         uint cyc_scc_r_false;
785         uint cyc_movem_w;
786         uint cyc_movem_l;
787         uint cyc_shift;
788         uint cyc_reset;
789         uint8* cyc_instruction;
790         uint8* cyc_exception;
791
792         /* Callbacks to host */
793         int  (*int_ack_callback)(int int_line);           /* Interrupt Acknowledge */
794         void (*bkpt_ack_callback)(unsigned int data);     /* Breakpoint Acknowledge */
795         void (*reset_instr_callback)(void);               /* Called when a RESET instruction is encountered */
796         void (*pc_changed_callback)(unsigned int new_pc); /* Called when the PC changes by a large amount */
797         void (*set_fc_callback)(unsigned int new_fc);     /* Called when the CPU function code changes */
798         void (*instr_hook_callback)(void);                /* Called every instruction cycle prior to execution */
799
800 } m68ki_cpu_core;
801
802
803 extern m68ki_cpu_core m68ki_cpu;
804 extern sint           m68ki_remaining_cycles;
805 extern uint           m68ki_tracing;
806 extern uint8          m68ki_shift_8_table[];
807 extern uint16         m68ki_shift_16_table[];
808 extern uint           m68ki_shift_32_table[];
809 extern uint8          m68ki_exception_cycle_table[][256];
810 extern uint           m68ki_address_space;
811 extern uint8          m68ki_ea_idx_cycle_table[];
812
813
814 /* Read data immediately after the program counter */
815 INLINE uint m68ki_read_imm_16(void);
816 INLINE uint m68ki_read_imm_32(void);
817
818 /* Read data with specific function code */
819 INLINE uint m68ki_read_8_fc  (uint address, uint fc);
820 INLINE uint m68ki_read_16_fc (uint address, uint fc);
821 INLINE uint m68ki_read_32_fc (uint address, uint fc);
822
823 /* Write data with specific function code */
824 INLINE void m68ki_write_8_fc (uint address, uint fc, uint value);
825 INLINE void m68ki_write_16_fc(uint address, uint fc, uint value);
826 INLINE void m68ki_write_32_fc(uint address, uint fc, uint value);
827
828 /* Indexed and PC-relative ea fetching */
829 INLINE uint m68ki_get_ea_pcdi(void);
830 INLINE uint m68ki_get_ea_pcix(void);
831 INLINE uint m68ki_get_ea_ix(uint An);
832
833 /* Operand fetching */
834 INLINE uint OPER_AY_AI_8(void);
835 INLINE uint OPER_AY_AI_16(void);
836 INLINE uint OPER_AY_AI_32(void);
837 INLINE uint OPER_AY_PI_8(void);
838 INLINE uint OPER_AY_PI_16(void);
839 INLINE uint OPER_AY_PI_32(void);
840 INLINE uint OPER_AY_PD_8(void);
841 INLINE uint OPER_AY_PD_16(void);
842 INLINE uint OPER_AY_PD_32(void);
843 INLINE uint OPER_AY_DI_8(void);
844 INLINE uint OPER_AY_DI_16(void);
845 INLINE uint OPER_AY_DI_32(void);
846 INLINE uint OPER_AY_IX_8(void);
847 INLINE uint OPER_AY_IX_16(void);
848 INLINE uint OPER_AY_IX_32(void);
849
850 INLINE uint OPER_AX_AI_8(void);
851 INLINE uint OPER_AX_AI_16(void);
852 INLINE uint OPER_AX_AI_32(void);
853 INLINE uint OPER_AX_PI_8(void);
854 INLINE uint OPER_AX_PI_16(void);
855 INLINE uint OPER_AX_PI_32(void);
856 INLINE uint OPER_AX_PD_8(void);
857 INLINE uint OPER_AX_PD_16(void);
858 INLINE uint OPER_AX_PD_32(void);
859 INLINE uint OPER_AX_DI_8(void);
860 INLINE uint OPER_AX_DI_16(void);
861 INLINE uint OPER_AX_DI_32(void);
862 INLINE uint OPER_AX_IX_8(void);
863 INLINE uint OPER_AX_IX_16(void);
864 INLINE uint OPER_AX_IX_32(void);
865
866 INLINE uint OPER_A7_PI_8(void);
867 INLINE uint OPER_A7_PD_8(void);
868
869 INLINE uint OPER_AW_8(void);
870 INLINE uint OPER_AW_16(void);
871 INLINE uint OPER_AW_32(void);
872 INLINE uint OPER_AL_8(void);
873 INLINE uint OPER_AL_16(void);
874 INLINE uint OPER_AL_32(void);
875 INLINE uint OPER_PCDI_8(void);
876 INLINE uint OPER_PCDI_16(void);
877 INLINE uint OPER_PCDI_32(void);
878 INLINE uint OPER_PCIX_8(void);
879 INLINE uint OPER_PCIX_16(void);
880 INLINE uint OPER_PCIX_32(void);
881
882 /* Stack operations */
883 INLINE void m68ki_push_16(uint value);
884 INLINE void m68ki_push_32(uint value);
885 INLINE uint m68ki_pull_16(void);
886 INLINE uint m68ki_pull_32(void);
887
888 /* Program flow operations */
889 INLINE void m68ki_jump(uint new_pc);
890 INLINE void m68ki_jump_vector(uint vector);
891 INLINE void m68ki_branch_8(uint offset);
892 INLINE void m68ki_branch_16(uint offset);
893 INLINE void m68ki_branch_32(uint offset);
894
895 /* Status register operations. */
896 INLINE void m68ki_set_s_flag(uint value);            /* Only bit 2 of value should be set (i.e. 4 or 0) */
897 INLINE void m68ki_set_sm_flag(uint value);           /* only bits 1 and 2 of value should be set */
898 INLINE void m68ki_set_ccr(uint value);               /* set the condition code register */
899 INLINE void m68ki_set_sr(uint value);                /* set the status register */
900 INLINE void m68ki_set_sr_noint(uint value);          /* set the status register */
901
902 /* Exception processing */
903 INLINE uint m68ki_init_exception(void);              /* Initial exception processing */
904
905 INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */
906 INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc);
907
908 INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector);
909 INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector);
910 INLINE void m68ki_stack_frame_0010(uint sr, uint vector);
911 INLINE void m68ki_stack_frame_1000(uint pc, uint sr, uint vector);
912 INLINE void m68ki_stack_frame_1010(uint sr, uint vector, uint pc);
913 INLINE void m68ki_stack_frame_1011(uint sr, uint vector, uint pc);
914
915 INLINE void m68ki_exception_trap(uint vector);
916 INLINE void m68ki_exception_trapN(uint vector);
917 INLINE void m68ki_exception_trace(void);
918 INLINE void m68ki_exception_privilege_violation(void);
919 INLINE void m68ki_exception_1010(void);
920 INLINE void m68ki_exception_1111(void);
921 INLINE void m68ki_exception_illegal(void);
922 INLINE void m68ki_exception_format_error(void);
923 INLINE void m68ki_exception_address_error(void);
924 INLINE void m68ki_exception_interrupt(uint int_level);
925 INLINE void m68ki_check_interrupts(void);            /* ASG: check for interrupts */
926
927 /* quick disassembly (used for logging) */
928 char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type);
929
930
931 /* ======================================================================== */
932 /* =========================== UTILITY FUNCTIONS ========================== */
933 /* ======================================================================== */
934
935
936 /* ---------------------------- Read Immediate ---------------------------- */
937
938 /* Handles all immediate reads, does address error check, function code setting,
939  * and prefetching if they are enabled in m68kconf.h
940  */
941 INLINE uint m68ki_read_imm_16(void)
942 {
943         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
944         m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */
945 #if M68K_EMULATE_PREFETCH
946         if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
947         {
948                 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
949                 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
950         }
951         REG_PC += 2;
952         return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3));
953 #else
954         REG_PC += 2;
955         return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2));
956 #endif /* M68K_EMULATE_PREFETCH */
957 }
958 INLINE uint m68ki_read_imm_32(void)
959 {
960 #if M68K_EMULATE_PREFETCH
961         uint temp_val;
962
963         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
964         m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */
965         if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
966         {
967                 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
968                 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
969         }
970         temp_val = CPU_PREF_DATA;
971         REG_PC += 2;
972         if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
973         {
974                 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
975                 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
976                 temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16));
977         }
978         REG_PC += 2;
979
980         return temp_val;
981 #else
982         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
983         m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */
984         REG_PC += 4;
985         return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4));
986 #endif /* M68K_EMULATE_PREFETCH */
987 }
988
989
990
991 /* ------------------------- Top level read/write ------------------------- */
992
993 /* Handles all memory accesses (except for immediate reads if they are
994  * configured to use separate functions in m68kconf.h).
995  * All memory accesses must go through these top level functions.
996  * These functions will also check for address error and set the function
997  * code if they are enabled in m68kconf.h.
998  */
999 INLINE uint m68ki_read_8_fc(uint address, uint fc)
1000 {
1001         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1002         return m68k_read_memory_8(ADDRESS_68K(address));
1003 }
1004 INLINE uint m68ki_read_16_fc(uint address, uint fc)
1005 {
1006         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1007         m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1008         return m68k_read_memory_16(ADDRESS_68K(address));
1009 }
1010 INLINE uint m68ki_read_32_fc(uint address, uint fc)
1011 {
1012         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1013         m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1014         return m68k_read_memory_32(ADDRESS_68K(address));
1015 }
1016
1017 INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
1018 {
1019         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1020         m68k_write_memory_8(ADDRESS_68K(address), value);
1021 }
1022 INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
1023 {
1024         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1025         m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1026         m68k_write_memory_16(ADDRESS_68K(address), value);
1027 }
1028 INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
1029 {
1030         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1031         m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1032         m68k_write_memory_32(ADDRESS_68K(address), value);
1033 }
1034
1035
1036
1037 /* --------------------- Effective Address Calculation -------------------- */
1038
1039 /* The program counter relative addressing modes cause operands to be
1040  * retrieved from program space, not data space.
1041  */
1042 INLINE uint m68ki_get_ea_pcdi(void)
1043 {
1044         uint old_pc = REG_PC;
1045         m68ki_use_program_space(); /* auto-disable */
1046         return old_pc + MAKE_INT_16(m68ki_read_imm_16());
1047 }
1048
1049
1050 INLINE uint m68ki_get_ea_pcix(void)
1051 {
1052         m68ki_use_program_space(); /* auto-disable */
1053         return m68ki_get_ea_ix(REG_PC);
1054 }
1055
1056 /* Indexed addressing modes are encoded as follows:
1057  *
1058  * Base instruction format:
1059  * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0
1060  * x x x x x x x x x x | 1 1 0 | BASE REGISTER      (An)
1061  *
1062  * Base instruction format for destination EA in move instructions:
1063  * F E D C | B A 9    | 8 7 6 | 5 4 3 2 1 0
1064  * x x x x | BASE REG | 1 1 0 | X X X X X X       (An)
1065  *
1066  * Brief extension format:
1067  *  F  |  E D C   |  B  |  A 9  | 8 | 7 6 5 4 3 2 1 0
1068  * D/A | REGISTER | W/L | SCALE | 0 |  DISPLACEMENT
1069  *
1070  * Full extension format:
1071  *  F     E D C      B     A 9    8   7    6    5 4       3   2 1 0
1072  * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS
1073  * BASE DISPLACEMENT (0, 16, 32 bit)                (bd)
1074  * OUTER DISPLACEMENT (0, 16, 32 bit)               (od)
1075  *
1076  * D/A:     0 = Dn, 1 = An                          (Xn)
1077  * W/L:     0 = W (sign extend), 1 = L              (.SIZE)
1078  * SCALE:   00=1, 01=2, 10=4, 11=8                  (*SCALE)
1079  * BS:      0=add base reg, 1=suppress base reg     (An suppressed)
1080  * IS:      0=add index, 1=suppress index           (Xn suppressed)
1081  * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long  (size of bd)
1082  *
1083  * IS I/IS Operation
1084  * 0  000  No Memory Indirect
1085  * 0  001  indir prex with null outer
1086  * 0  010  indir prex with word outer
1087  * 0  011  indir prex with long outer
1088  * 0  100  reserved
1089  * 0  101  indir postx with null outer
1090  * 0  110  indir postx with word outer
1091  * 0  111  indir postx with long outer
1092  * 1  000  no memory indirect
1093  * 1  001  mem indir with null outer
1094  * 1  010  mem indir with word outer
1095  * 1  011  mem indir with long outer
1096  * 1  100-111  reserved
1097  */
1098 INLINE uint m68ki_get_ea_ix(uint An)
1099 {
1100         /* An = base register */
1101         uint extension = m68ki_read_imm_16();
1102         uint Xn = 0;                        /* Index register */
1103         uint bd = 0;                        /* Base Displacement */
1104         uint od = 0;                        /* Outer Displacement */
1105
1106         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
1107         {
1108                 /* Calculate index */
1109                 Xn = REG_DA[extension>>12];     /* Xn */
1110                 if(!BIT_B(extension))           /* W/L */
1111                         Xn = MAKE_INT_16(Xn);
1112
1113                 /* Add base register and displacement and return */
1114                 return An + Xn + MAKE_INT_8(extension);
1115         }
1116
1117         /* Brief extension format */
1118         if(!BIT_8(extension))
1119         {
1120                 /* Calculate index */
1121                 Xn = REG_DA[extension>>12];     /* Xn */
1122                 if(!BIT_B(extension))           /* W/L */
1123                         Xn = MAKE_INT_16(Xn);
1124                 /* Add scale if proper CPU type */
1125                 if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
1126                         Xn <<= (extension>>9) & 3;  /* SCALE */
1127
1128                 /* Add base register and displacement and return */
1129                 return An + Xn + MAKE_INT_8(extension);
1130         }
1131
1132         /* Full extension format */
1133
1134         USE_CYCLES(m68ki_ea_idx_cycle_table[extension&0x3f]);
1135
1136         /* Check if base register is present */
1137         if(BIT_7(extension))                /* BS */
1138                 An = 0;                         /* An */
1139
1140         /* Check if index is present */
1141         if(!BIT_6(extension))               /* IS */
1142         {
1143                 Xn = REG_DA[extension>>12];     /* Xn */
1144                 if(!BIT_B(extension))           /* W/L */
1145                         Xn = MAKE_INT_16(Xn);
1146                 Xn <<= (extension>>9) & 3;      /* SCALE */
1147         }
1148
1149         /* Check if base displacement is present */
1150         if(BIT_5(extension))                /* BD SIZE */
1151                 bd = BIT_4(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
1152
1153         /* If no indirect action, we are done */
1154         if(!(extension&7))                  /* No Memory Indirect */
1155                 return An + bd + Xn;
1156
1157         /* Check if outer displacement is present */
1158         if(BIT_1(extension))                /* I/IS:  od */
1159                 od = BIT_0(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
1160
1161         /* Postindex */
1162         if(BIT_2(extension))                /* I/IS:  0 = preindex, 1 = postindex */
1163                 return m68ki_read_32(An + bd) + Xn + od;
1164
1165         /* Preindex */
1166         return m68ki_read_32(An + bd + Xn) + od;
1167 }
1168
1169
1170 /* Fetch operands */
1171 INLINE uint OPER_AY_AI_8(void)  {uint ea = EA_AY_AI_8();  return m68ki_read_8(ea); }
1172 INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);}
1173 INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);}
1174 INLINE uint OPER_AY_PI_8(void)  {uint ea = EA_AY_PI_8();  return m68ki_read_8(ea); }
1175 INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);}
1176 INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);}
1177 INLINE uint OPER_AY_PD_8(void)  {uint ea = EA_AY_PD_8();  return m68ki_read_8(ea); }
1178 INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);}
1179 INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);}
1180 INLINE uint OPER_AY_DI_8(void)  {uint ea = EA_AY_DI_8();  return m68ki_read_8(ea); }
1181 INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);}
1182 INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);}
1183 INLINE uint OPER_AY_IX_8(void)  {uint ea = EA_AY_IX_8();  return m68ki_read_8(ea); }
1184 INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);}
1185 INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);}
1186
1187 INLINE uint OPER_AX_AI_8(void)  {uint ea = EA_AX_AI_8();  return m68ki_read_8(ea); }
1188 INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);}
1189 INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);}
1190 INLINE uint OPER_AX_PI_8(void)  {uint ea = EA_AX_PI_8();  return m68ki_read_8(ea); }
1191 INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);}
1192 INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);}
1193 INLINE uint OPER_AX_PD_8(void)  {uint ea = EA_AX_PD_8();  return m68ki_read_8(ea); }
1194 INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);}
1195 INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);}
1196 INLINE uint OPER_AX_DI_8(void)  {uint ea = EA_AX_DI_8();  return m68ki_read_8(ea); }
1197 INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);}
1198 INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);}
1199 INLINE uint OPER_AX_IX_8(void)  {uint ea = EA_AX_IX_8();  return m68ki_read_8(ea); }
1200 INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);}
1201 INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);}
1202
1203 INLINE uint OPER_A7_PI_8(void)  {uint ea = EA_A7_PI_8();  return m68ki_read_8(ea); }
1204 INLINE uint OPER_A7_PD_8(void)  {uint ea = EA_A7_PD_8();  return m68ki_read_8(ea); }
1205
1206 INLINE uint OPER_AW_8(void)     {uint ea = EA_AW_8();     return m68ki_read_8(ea); }
1207 INLINE uint OPER_AW_16(void)    {uint ea = EA_AW_16();    return m68ki_read_16(ea);}
1208 INLINE uint OPER_AW_32(void)    {uint ea = EA_AW_32();    return m68ki_read_32(ea);}
1209 INLINE uint OPER_AL_8(void)     {uint ea = EA_AL_8();     return m68ki_read_8(ea); }
1210 INLINE uint OPER_AL_16(void)    {uint ea = EA_AL_16();    return m68ki_read_16(ea);}
1211 INLINE uint OPER_AL_32(void)    {uint ea = EA_AL_32();    return m68ki_read_32(ea);}
1212 INLINE uint OPER_PCDI_8(void)   {uint ea = EA_PCDI_8();   return m68ki_read_pcrel_8(ea); }
1213 INLINE uint OPER_PCDI_16(void)  {uint ea = EA_PCDI_16();  return m68ki_read_pcrel_16(ea);}
1214 INLINE uint OPER_PCDI_32(void)  {uint ea = EA_PCDI_32();  return m68ki_read_pcrel_32(ea);}
1215 INLINE uint OPER_PCIX_8(void)   {uint ea = EA_PCIX_8();   return m68ki_read_pcrel_8(ea); }
1216 INLINE uint OPER_PCIX_16(void)  {uint ea = EA_PCIX_16();  return m68ki_read_pcrel_16(ea);}
1217 INLINE uint OPER_PCIX_32(void)  {uint ea = EA_PCIX_32();  return m68ki_read_pcrel_32(ea);}
1218
1219
1220
1221 /* ---------------------------- Stack Functions --------------------------- */
1222
1223 /* Push/pull data from the stack */
1224 INLINE void m68ki_push_16(uint value)
1225 {
1226         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1227         m68ki_write_16(REG_SP, value);
1228 }
1229
1230 INLINE void m68ki_push_32(uint value)
1231 {
1232         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1233         m68ki_write_32(REG_SP, value);
1234 }
1235
1236 INLINE uint m68ki_pull_16(void)
1237 {
1238         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1239         return m68ki_read_16(REG_SP-2);
1240 }
1241
1242 INLINE uint m68ki_pull_32(void)
1243 {
1244         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1245         return m68ki_read_32(REG_SP-4);
1246 }
1247
1248
1249 /* Increment/decrement the stack as if doing a push/pull but
1250  * don't do any memory access.
1251  */
1252 INLINE void m68ki_fake_push_16(void)
1253 {
1254         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1255 }
1256
1257 INLINE void m68ki_fake_push_32(void)
1258 {
1259         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1260 }
1261
1262 INLINE void m68ki_fake_pull_16(void)
1263 {
1264         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1265 }
1266
1267 INLINE void m68ki_fake_pull_32(void)
1268 {
1269         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1270 }
1271
1272
1273 /* ----------------------------- Program Flow ----------------------------- */
1274
1275 /* Jump to a new program location or vector.
1276  * These functions will also call the pc_changed callback if it was enabled
1277  * in m68kconf.h.
1278  */
1279 INLINE void m68ki_jump(uint new_pc)
1280 {
1281         REG_PC = new_pc;
1282         m68ki_pc_changed(REG_PC);
1283 }
1284
1285 INLINE void m68ki_jump_vector(uint vector)
1286 {
1287         REG_PC = (vector<<2) + REG_VBR;
1288         REG_PC = m68ki_read_data_32(REG_PC);
1289         m68ki_pc_changed(REG_PC);
1290 }
1291
1292
1293 /* Branch to a new memory location.
1294  * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h.
1295  * So far I've found no problems with not calling pc_changed for 8 or 16
1296  * bit branches.
1297  */
1298 INLINE void m68ki_branch_8(uint offset)
1299 {
1300         REG_PC += MAKE_INT_8(offset);
1301 }
1302
1303 INLINE void m68ki_branch_16(uint offset)
1304 {
1305         REG_PC += MAKE_INT_16(offset);
1306 }
1307
1308 INLINE void m68ki_branch_32(uint offset)
1309 {
1310         REG_PC += offset;
1311         m68ki_pc_changed(REG_PC);
1312 }
1313
1314
1315
1316 /* ---------------------------- Status Register --------------------------- */
1317
1318 /* Set the S flag and change the active stack pointer.
1319  * Note that value MUST be 4 or 0.
1320  */
1321 INLINE void m68ki_set_s_flag(uint value)
1322 {
1323         /* Backup the old stack pointer */
1324         REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
1325         /* Set the S flag */
1326         FLAG_S = value;
1327         /* Set the new stack pointer */
1328         REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];
1329 }
1330
1331 /* Set the S and M flags and change the active stack pointer.
1332  * Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M).
1333  */
1334 INLINE void m68ki_set_sm_flag(uint value)
1335 {
1336         /* Backup the old stack pointer */
1337         REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
1338         /* Set the S and M flags */
1339         FLAG_S = value & SFLAG_SET;
1340         FLAG_M = value & MFLAG_SET;
1341         /* Set the new stack pointer */
1342         REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];
1343 }
1344
1345
1346 /* Set the condition code register */
1347 INLINE void m68ki_set_ccr(uint value)
1348 {
1349         FLAG_X = BIT_4(value)  << 4;
1350         FLAG_N = BIT_3(value)  << 4;
1351         FLAG_Z = !BIT_2(value);
1352         FLAG_V = BIT_1(value)  << 6;
1353         FLAG_C = BIT_0(value)  << 8;
1354 }
1355
1356 /* Set the status register but don't check for interrupts */
1357 INLINE void m68ki_set_sr_noint(uint value)
1358 {
1359         /* Mask out the "unimplemented" bits */
1360         value &= CPU_SR_MASK;
1361
1362         /* Now set the status register */
1363         FLAG_T1 = BIT_F(value);
1364         FLAG_T0 = BIT_E(value);
1365         FLAG_INT_MASK = value & 0x0700;
1366         m68ki_set_ccr(value);
1367         m68ki_set_sm_flag((value >> 11) & 6);
1368 }
1369
1370 /* Set the status register and check for interrupts */
1371 INLINE void m68ki_set_sr(uint value)
1372 {
1373         m68ki_set_sr_noint(value);
1374         m68ki_check_interrupts();
1375 }
1376
1377
1378 /* ------------------------- Exception Processing ------------------------- */
1379
1380 /* Initiate exception processing */
1381 INLINE uint m68ki_init_exception(void)
1382 {
1383         /* Save the old status register */
1384         uint sr = m68ki_get_sr();
1385
1386         /* Turn off trace flag, clear pending traces */
1387         FLAG_T1 = FLAG_T0 = 0;
1388         m68ki_clear_trace();
1389         /* Enter supervisor mode */
1390         m68ki_set_s_flag(SFLAG_SET);
1391
1392         return sr;
1393 }
1394
1395 /* 3 word stack frame (68000 only) */
1396 INLINE void m68ki_stack_frame_3word(uint pc, uint sr)
1397 {
1398         m68ki_push_32(pc);
1399         m68ki_push_16(sr);
1400 }
1401
1402 /* Format 0 stack frame.
1403  * This is the standard stack frame for 68010+.
1404  */
1405 INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector)
1406 {
1407         /* Stack a 3-word frame if we are 68000 */
1408         if(CPU_TYPE == CPU_TYPE_000)
1409         {
1410                 m68ki_stack_frame_3word(pc, sr);
1411                 return;
1412         }
1413         m68ki_push_16(vector<<2);
1414         m68ki_push_32(pc);
1415         m68ki_push_16(sr);
1416 }
1417
1418 /* Format 1 stack frame (68020).
1419  * For 68020, this is the 4 word throwaway frame.
1420  */
1421 INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)
1422 {
1423         m68ki_push_16(0x1000 | (vector<<2));
1424         m68ki_push_32(pc);
1425         m68ki_push_16(sr);
1426 }
1427
1428 /* Format 2 stack frame.
1429  * This is used only by 68020 for trap exceptions.
1430  */
1431 INLINE void m68ki_stack_frame_0010(uint sr, uint vector)
1432 {
1433         m68ki_push_32(REG_PPC);
1434         m68ki_push_16(0x2000 | (vector<<2));
1435         m68ki_push_32(REG_PC);
1436         m68ki_push_16(sr);
1437 }
1438
1439
1440 /* Bus error stack frame (68000 only).
1441  */
1442 INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc)
1443 {
1444         m68ki_push_32(pc);
1445         m68ki_push_16(sr);
1446         m68ki_push_16(REG_IR);
1447         m68ki_push_32(address); /* access address */
1448         /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC
1449          * R/W  0 = write, 1 = read
1450          * I/N  0 = instruction, 1 = not
1451          * FC   3-bit function code
1452          */
1453         m68ki_push_16(((!write)<<4) | ((!instruction)<<3) | fc);
1454 }
1455
1456 /* Format 8 stack frame (68010).
1457  * 68010 only.  This is the 29 word bus/address error frame.
1458  */
1459 void m68ki_stack_frame_1000(uint pc, uint sr, uint vector)
1460 {
1461         /* VERSION
1462          * NUMBER
1463          * INTERNAL INFORMATION, 16 WORDS
1464          */
1465         m68ki_fake_push_32();
1466         m68ki_fake_push_32();
1467         m68ki_fake_push_32();
1468         m68ki_fake_push_32();
1469         m68ki_fake_push_32();
1470         m68ki_fake_push_32();
1471         m68ki_fake_push_32();
1472         m68ki_fake_push_32();
1473
1474         /* INSTRUCTION INPUT BUFFER */
1475         m68ki_push_16(0);
1476
1477         /* UNUSED, RESERVED (not written) */
1478         m68ki_fake_push_16();
1479
1480         /* DATA INPUT BUFFER */
1481         m68ki_push_16(0);
1482
1483         /* UNUSED, RESERVED (not written) */
1484         m68ki_fake_push_16();
1485
1486         /* DATA OUTPUT BUFFER */
1487         m68ki_push_16(0);
1488
1489         /* UNUSED, RESERVED (not written) */
1490         m68ki_fake_push_16();
1491
1492         /* FAULT ADDRESS */
1493         m68ki_push_32(0);
1494
1495         /* SPECIAL STATUS WORD */
1496         m68ki_push_16(0);
1497
1498         /* 1000, VECTOR OFFSET */
1499         m68ki_push_16(0x8000 | (vector<<2));
1500
1501         /* PROGRAM COUNTER */
1502         m68ki_push_32(pc);
1503
1504         /* STATUS REGISTER */
1505         m68ki_push_16(sr);
1506 }
1507
1508 /* Format A stack frame (short bus fault).
1509  * This is used only by 68020 for bus fault and address error
1510  * if the error happens at an instruction boundary.
1511  * PC stacked is address of next instruction.
1512  */
1513 void m68ki_stack_frame_1010(uint sr, uint vector, uint pc)
1514 {
1515         /* INTERNAL REGISTER */
1516         m68ki_push_16(0);
1517
1518         /* INTERNAL REGISTER */
1519         m68ki_push_16(0);
1520
1521         /* DATA OUTPUT BUFFER (2 words) */
1522         m68ki_push_32(0);
1523
1524         /* INTERNAL REGISTER */
1525         m68ki_push_16(0);
1526
1527         /* INTERNAL REGISTER */
1528         m68ki_push_16(0);
1529
1530         /* DATA CYCLE FAULT ADDRESS (2 words) */
1531         m68ki_push_32(0);
1532
1533         /* INSTRUCTION PIPE STAGE B */
1534         m68ki_push_16(0);
1535
1536         /* INSTRUCTION PIPE STAGE C */
1537         m68ki_push_16(0);
1538
1539         /* SPECIAL STATUS REGISTER */
1540         m68ki_push_16(0);
1541
1542         /* INTERNAL REGISTER */
1543         m68ki_push_16(0);
1544
1545         /* 1010, VECTOR OFFSET */
1546         m68ki_push_16(0xa000 | (vector<<2));
1547
1548         /* PROGRAM COUNTER */
1549         m68ki_push_32(pc);
1550
1551         /* STATUS REGISTER */
1552         m68ki_push_16(sr);
1553 }
1554
1555 /* Format B stack frame (long bus fault).
1556  * This is used only by 68020 for bus fault and address error
1557  * if the error happens during instruction execution.
1558  * PC stacked is address of instruction in progress.
1559  */
1560 void m68ki_stack_frame_1011(uint sr, uint vector, uint pc)
1561 {
1562         /* INTERNAL REGISTERS (18 words) */
1563         m68ki_push_32(0);
1564         m68ki_push_32(0);
1565         m68ki_push_32(0);
1566         m68ki_push_32(0);
1567         m68ki_push_32(0);
1568         m68ki_push_32(0);
1569         m68ki_push_32(0);
1570         m68ki_push_32(0);
1571         m68ki_push_32(0);
1572
1573         /* VERSION# (4 bits), INTERNAL INFORMATION */
1574         m68ki_push_16(0);
1575
1576         /* INTERNAL REGISTERS (3 words) */
1577         m68ki_push_32(0);
1578         m68ki_push_16(0);
1579
1580         /* DATA INTPUT BUFFER (2 words) */
1581         m68ki_push_32(0);
1582
1583         /* INTERNAL REGISTERS (2 words) */
1584         m68ki_push_32(0);
1585
1586         /* STAGE B ADDRESS (2 words) */
1587         m68ki_push_32(0);
1588
1589         /* INTERNAL REGISTER (4 words) */
1590         m68ki_push_32(0);
1591         m68ki_push_32(0);
1592
1593         /* DATA OUTPUT BUFFER (2 words) */
1594         m68ki_push_32(0);
1595
1596         /* INTERNAL REGISTER */
1597         m68ki_push_16(0);
1598
1599         /* INTERNAL REGISTER */
1600         m68ki_push_16(0);
1601
1602         /* DATA CYCLE FAULT ADDRESS (2 words) */
1603         m68ki_push_32(0);
1604
1605         /* INSTRUCTION PIPE STAGE B */
1606         m68ki_push_16(0);
1607
1608         /* INSTRUCTION PIPE STAGE C */
1609         m68ki_push_16(0);
1610
1611         /* SPECIAL STATUS REGISTER */
1612         m68ki_push_16(0);
1613
1614         /* INTERNAL REGISTER */
1615         m68ki_push_16(0);
1616
1617         /* 1011, VECTOR OFFSET */
1618         m68ki_push_16(0xb000 | (vector<<2));
1619
1620         /* PROGRAM COUNTER */
1621         m68ki_push_32(pc);
1622
1623         /* STATUS REGISTER */
1624         m68ki_push_16(sr);
1625 }
1626
1627
1628 /* Used for Group 2 exceptions.
1629  * These stack a type 2 frame on the 020.
1630  */
1631 INLINE void m68ki_exception_trap(uint vector)
1632 {
1633         uint sr = m68ki_init_exception();
1634
1635         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
1636                 m68ki_stack_frame_0000(REG_PC, sr, vector);
1637         else
1638                 m68ki_stack_frame_0010(sr, vector);
1639
1640         m68ki_jump_vector(vector);
1641
1642         /* Use up some clock cycles */
1643         USE_CYCLES(CYC_EXCEPTION[vector]);
1644 }
1645
1646 /* Trap#n stacks a 0 frame but behaves like group2 otherwise */
1647 INLINE void m68ki_exception_trapN(uint vector)
1648 {
1649         uint sr = m68ki_init_exception();
1650         m68ki_stack_frame_0000(REG_PC, sr, vector);
1651         m68ki_jump_vector(vector);
1652
1653         /* Use up some clock cycles */
1654         USE_CYCLES(CYC_EXCEPTION[vector]);
1655 }
1656
1657 /* Exception for trace mode */
1658 INLINE void m68ki_exception_trace(void)
1659 {
1660         uint sr = m68ki_init_exception();
1661
1662         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
1663                 m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE);
1664         else
1665                 m68ki_stack_frame_0010(sr, EXCEPTION_TRACE);
1666
1667         m68ki_jump_vector(EXCEPTION_TRACE);
1668
1669         /* Trace nullifies a STOP instruction */
1670         CPU_STOPPED &= ~STOP_LEVEL_STOP;
1671
1672         /* Use up some clock cycles */
1673         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]);
1674 }
1675
1676 /* Exception for privilege violation */
1677 INLINE void m68ki_exception_privilege_violation(void)
1678 {
1679         uint sr = m68ki_init_exception();
1680         m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_PRIVILEGE_VIOLATION);
1681         m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION);
1682
1683         /* Use up some clock cycles and undo the instruction's cycles */
1684         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]);
1685 }
1686
1687 /* Exception for A-Line instructions */
1688 INLINE void m68ki_exception_1010(void)
1689 {
1690         uint sr;
1691 #if M68K_LOG_1010_1111 == OPT_ON
1692         M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n",
1693                                          m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
1694                                          m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));
1695 #endif
1696
1697         sr = m68ki_init_exception();
1698         m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1010);
1699         m68ki_jump_vector(EXCEPTION_1010);
1700
1701         /* Use up some clock cycles and undo the instruction's cycles */
1702         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]);
1703 }
1704
1705 /* Exception for F-Line instructions */
1706 INLINE void m68ki_exception_1111(void)
1707 {
1708         uint sr;
1709
1710 #if M68K_LOG_1010_1111 == OPT_ON
1711         M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n",
1712                                          m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
1713                                          m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));
1714 #endif
1715
1716         sr = m68ki_init_exception();
1717         m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1111);
1718         m68ki_jump_vector(EXCEPTION_1111);
1719
1720         /* Use up some clock cycles and undo the instruction's cycles */
1721         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]);
1722 }
1723
1724 /* Exception for illegal instructions */
1725 INLINE void m68ki_exception_illegal(void)
1726 {
1727         uint sr;
1728
1729         M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n",
1730                                  m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
1731                                  m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));
1732
1733         sr = m68ki_init_exception();
1734         m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_ILLEGAL_INSTRUCTION);
1735         m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION);
1736
1737         /* Use up some clock cycles and undo the instruction's cycles */
1738         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]);
1739 }
1740
1741 /* Exception for format errror in RTE */
1742 INLINE void m68ki_exception_format_error(void)
1743 {
1744         uint sr = m68ki_init_exception();
1745         m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR);
1746         m68ki_jump_vector(EXCEPTION_FORMAT_ERROR);
1747
1748         /* Use up some clock cycles and undo the instruction's cycles */
1749         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]);
1750 }
1751
1752 /* Exception for address error */
1753 INLINE void m68ki_exception_address_error(void)
1754 {
1755         /* Not emulated yet */
1756 }
1757
1758
1759 /* Service an interrupt request and start exception processing */
1760 void m68ki_exception_interrupt(uint int_level)
1761 {
1762         uint vector;
1763         uint sr;
1764         uint new_pc;
1765
1766         /* Turn off the stopped state */
1767         CPU_STOPPED &= ~STOP_LEVEL_STOP;
1768
1769         /* If we are halted, don't do anything */
1770         if(CPU_STOPPED)
1771                 return;
1772
1773         /* Acknowledge the interrupt */
1774         vector = m68ki_int_ack(int_level);
1775
1776         /* Get the interrupt vector */
1777         if(vector == M68K_INT_ACK_AUTOVECTOR)
1778                 /* Use the autovectors.  This is the most commonly used implementation */
1779                 vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
1780         else if(vector == M68K_INT_ACK_SPURIOUS)
1781                 /* Called if no devices respond to the interrupt acknowledge */
1782                 vector = EXCEPTION_SPURIOUS_INTERRUPT;
1783         else if(vector > 255)
1784         {
1785                 M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n",
1786                                  m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector));
1787                 return;
1788         }
1789
1790         /* Start exception processing */
1791         sr = m68ki_init_exception();
1792
1793         /* Set the interrupt mask to the level of the one being serviced */
1794         FLAG_INT_MASK = int_level<<8;
1795
1796         /* Get the new PC */
1797         new_pc = m68ki_read_data_32((vector<<2) + REG_VBR);
1798
1799         /* If vector is uninitialized, call the uninitialized interrupt vector */
1800         if(new_pc == 0)
1801                 new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR);
1802
1803         /* Generate a stack frame */
1804         m68ki_stack_frame_0000(REG_PC, sr, vector);
1805         if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
1806         {
1807                 /* Create throwaway frame */
1808                 m68ki_set_sm_flag(FLAG_S);      /* clear M */
1809                 sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */
1810                 m68ki_stack_frame_0001(REG_PC, sr, vector);
1811         }
1812
1813         m68ki_jump(new_pc);
1814
1815         /* Defer cycle counting until later */
1816         CPU_INT_CYCLES += CYC_EXCEPTION[vector];
1817
1818 #if !M68K_EMULATE_INT_ACK
1819         /* Automatically clear IRQ if we are not using an acknowledge scheme */
1820         CPU_INT_LEVEL = 0;
1821 #endif /* M68K_EMULATE_INT_ACK */
1822 }
1823
1824
1825 /* ASG: Check for interrupts */
1826 INLINE void m68ki_check_interrupts(void)
1827 {
1828         if(CPU_INT_LEVEL > FLAG_INT_MASK)
1829                 m68ki_exception_interrupt(CPU_INT_LEVEL>>8);
1830 }
1831
1832
1833
1834 /* ======================================================================== */
1835 /* ============================== END OF FILE ============================= */
1836 /* ======================================================================== */
1837
1838 #endif /* M68KCPU__HEADER */