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