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