mcd: text shows up
[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         sint cyc_remaining_cycles;\r
895 } m68ki_cpu_core;\r
896 \r
897 \r
898 extern m68ki_cpu_core *m68ki_cpu_p;\r
899 #define m68ki_cpu (*m68ki_cpu_p) // test\r
900 \r
901 // extern sint           m68ki_remaining_cycles;\r
902 #define m68ki_remaining_cycles m68ki_cpu_p->cyc_remaining_cycles\r
903 \r
904 extern uint           m68ki_tracing;\r
905 extern uint8          m68ki_shift_8_table[];\r
906 extern uint16         m68ki_shift_16_table[];\r
907 extern uint           m68ki_shift_32_table[];\r
908 extern uint8          m68ki_exception_cycle_table[][256];\r
909 extern uint           m68ki_address_space;\r
910 extern uint8          m68ki_ea_idx_cycle_table[];\r
911 \r
912 extern uint           m68ki_aerr_address;\r
913 extern uint           m68ki_aerr_write_mode;\r
914 extern uint           m68ki_aerr_fc;\r
915 \r
916 /* Read data immediately after the program counter */\r
917 INLINE uint m68ki_read_imm_16(void);\r
918 INLINE uint m68ki_read_imm_32(void);\r
919 \r
920 /* Read data with specific function code */\r
921 INLINE uint m68ki_read_8_fc  (uint address, uint fc);\r
922 INLINE uint m68ki_read_16_fc (uint address, uint fc);\r
923 INLINE uint m68ki_read_32_fc (uint address, uint fc);\r
924 \r
925 /* Write data with specific function code */\r
926 INLINE void m68ki_write_8_fc (uint address, uint fc, uint value);\r
927 INLINE void m68ki_write_16_fc(uint address, uint fc, uint value);\r
928 INLINE void m68ki_write_32_fc(uint address, uint fc, uint value);\r
929 #if M68K_SIMULATE_PD_WRITES\r
930 INLINE void m68ki_write_32_pd_fc(uint address, uint fc, uint value);\r
931 #endif /* M68K_SIMULATE_PD_WRITES */\r
932 \r
933 /* Indexed and PC-relative ea fetching */\r
934 INLINE uint m68ki_get_ea_pcdi(void);\r
935 INLINE uint m68ki_get_ea_pcix(void);\r
936 INLINE uint m68ki_get_ea_ix(uint An);\r
937 \r
938 /* Operand fetching */\r
939 INLINE uint OPER_AY_AI_8(void);\r
940 INLINE uint OPER_AY_AI_16(void);\r
941 INLINE uint OPER_AY_AI_32(void);\r
942 INLINE uint OPER_AY_PI_8(void);\r
943 INLINE uint OPER_AY_PI_16(void);\r
944 INLINE uint OPER_AY_PI_32(void);\r
945 INLINE uint OPER_AY_PD_8(void);\r
946 INLINE uint OPER_AY_PD_16(void);\r
947 INLINE uint OPER_AY_PD_32(void);\r
948 INLINE uint OPER_AY_DI_8(void);\r
949 INLINE uint OPER_AY_DI_16(void);\r
950 INLINE uint OPER_AY_DI_32(void);\r
951 INLINE uint OPER_AY_IX_8(void);\r
952 INLINE uint OPER_AY_IX_16(void);\r
953 INLINE uint OPER_AY_IX_32(void);\r
954 \r
955 INLINE uint OPER_AX_AI_8(void);\r
956 INLINE uint OPER_AX_AI_16(void);\r
957 INLINE uint OPER_AX_AI_32(void);\r
958 INLINE uint OPER_AX_PI_8(void);\r
959 INLINE uint OPER_AX_PI_16(void);\r
960 INLINE uint OPER_AX_PI_32(void);\r
961 INLINE uint OPER_AX_PD_8(void);\r
962 INLINE uint OPER_AX_PD_16(void);\r
963 INLINE uint OPER_AX_PD_32(void);\r
964 INLINE uint OPER_AX_DI_8(void);\r
965 INLINE uint OPER_AX_DI_16(void);\r
966 INLINE uint OPER_AX_DI_32(void);\r
967 INLINE uint OPER_AX_IX_8(void);\r
968 INLINE uint OPER_AX_IX_16(void);\r
969 INLINE uint OPER_AX_IX_32(void);\r
970 \r
971 INLINE uint OPER_A7_PI_8(void);\r
972 INLINE uint OPER_A7_PD_8(void);\r
973 \r
974 INLINE uint OPER_AW_8(void);\r
975 INLINE uint OPER_AW_16(void);\r
976 INLINE uint OPER_AW_32(void);\r
977 INLINE uint OPER_AL_8(void);\r
978 INLINE uint OPER_AL_16(void);\r
979 INLINE uint OPER_AL_32(void);\r
980 INLINE uint OPER_PCDI_8(void);\r
981 INLINE uint OPER_PCDI_16(void);\r
982 INLINE uint OPER_PCDI_32(void);\r
983 INLINE uint OPER_PCIX_8(void);\r
984 INLINE uint OPER_PCIX_16(void);\r
985 INLINE uint OPER_PCIX_32(void);\r
986 \r
987 /* Stack operations */\r
988 INLINE void m68ki_push_16(uint value);\r
989 INLINE void m68ki_push_32(uint value);\r
990 INLINE uint m68ki_pull_16(void);\r
991 INLINE uint m68ki_pull_32(void);\r
992 \r
993 /* Program flow operations */\r
994 INLINE void m68ki_jump(uint new_pc);\r
995 INLINE void m68ki_jump_vector(uint vector);\r
996 INLINE void m68ki_branch_8(uint offset);\r
997 INLINE void m68ki_branch_16(uint offset);\r
998 INLINE void m68ki_branch_32(uint offset);\r
999 \r
1000 /* Status register operations. */\r
1001 INLINE void m68ki_set_s_flag(uint value);            /* Only bit 2 of value should be set (i.e. 4 or 0) */\r
1002 INLINE void m68ki_set_sm_flag(uint value);           /* only bits 1 and 2 of value should be set */\r
1003 INLINE void m68ki_set_ccr(uint value);               /* set the condition code register */\r
1004 INLINE void m68ki_set_sr(uint value);                /* set the status register */\r
1005 INLINE void m68ki_set_sr_noint(uint value);          /* set the status register */\r
1006 \r
1007 /* Exception processing */\r
1008 INLINE uint m68ki_init_exception(void);              /* Initial exception processing */\r
1009 \r
1010 INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */\r
1011 INLINE void m68ki_stack_frame_buserr(uint sr);\r
1012 \r
1013 INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector);\r
1014 INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector);\r
1015 INLINE void m68ki_stack_frame_0010(uint sr, uint vector);\r
1016 INLINE void m68ki_stack_frame_1000(uint pc, uint sr, uint vector);\r
1017 INLINE void m68ki_stack_frame_1010(uint sr, uint vector, uint pc);\r
1018 INLINE void m68ki_stack_frame_1011(uint sr, uint vector, uint pc);\r
1019 \r
1020 INLINE void m68ki_exception_trap(uint vector);\r
1021 INLINE void m68ki_exception_trapN(uint vector);\r
1022 INLINE void m68ki_exception_trace(void);\r
1023 INLINE void m68ki_exception_privilege_violation(void);\r
1024 INLINE void m68ki_exception_1010(void);\r
1025 INLINE void m68ki_exception_1111(void);\r
1026 INLINE void m68ki_exception_illegal(void);\r
1027 INLINE void m68ki_exception_format_error(void);\r
1028 INLINE void m68ki_exception_address_error(void);\r
1029 INLINE void m68ki_exception_interrupt(uint int_level);\r
1030 INLINE void m68ki_check_interrupts(void);            /* ASG: check for interrupts */\r
1031 \r
1032 /* quick disassembly (used for logging) */\r
1033 char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type);\r
1034 \r
1035 \r
1036 /* ======================================================================== */\r
1037 /* =========================== UTILITY FUNCTIONS ========================== */\r
1038 /* ======================================================================== */\r
1039 \r
1040 \r
1041 /* ---------------------------- Read Immediate ---------------------------- */\r
1042 \r
1043 /* Handles all immediate reads, does address error check, function code setting,\r
1044  * and prefetching if they are enabled in m68kconf.h\r
1045  */\r
1046 INLINE uint m68ki_read_imm_16(void)\r
1047 {\r
1048         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */\r
1049         m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */\r
1050 #if M68K_EMULATE_PREFETCH\r
1051         if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)\r
1052         {\r
1053                 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);\r
1054                 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));\r
1055         }\r
1056         REG_PC += 2;\r
1057         return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3));\r
1058 #else\r
1059         REG_PC += 2;\r
1060         return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2));\r
1061 #endif /* M68K_EMULATE_PREFETCH */\r
1062 }\r
1063 INLINE uint m68ki_read_imm_32(void)\r
1064 {\r
1065 #if M68K_EMULATE_PREFETCH\r
1066         uint temp_val;\r
1067 \r
1068         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */\r
1069         m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */\r
1070         if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)\r
1071         {\r
1072                 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);\r
1073                 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));\r
1074         }\r
1075         temp_val = CPU_PREF_DATA;\r
1076         REG_PC += 2;\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                 temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16));\r
1082         }\r
1083         REG_PC += 2;\r
1084 \r
1085         return temp_val;\r
1086 #else\r
1087         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */\r
1088         m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */\r
1089         REG_PC += 4;\r
1090         return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4));\r
1091 #endif /* M68K_EMULATE_PREFETCH */\r
1092 }\r
1093 \r
1094 \r
1095 \r
1096 /* ------------------------- Top level read/write ------------------------- */\r
1097 \r
1098 /* Handles all memory accesses (except for immediate reads if they are\r
1099  * configured to use separate functions in m68kconf.h).\r
1100  * All memory accesses must go through these top level functions.\r
1101  * These functions will also check for address error and set the function\r
1102  * code if they are enabled in m68kconf.h.\r
1103  */\r
1104 INLINE uint m68ki_read_8_fc(uint address, uint fc)\r
1105 {\r
1106         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */\r
1107         return m68k_read_memory_8(ADDRESS_68K(address));\r
1108 }\r
1109 INLINE uint m68ki_read_16_fc(uint address, uint fc)\r
1110 {\r
1111         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */\r
1112         m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */\r
1113         return m68k_read_memory_16(ADDRESS_68K(address));\r
1114 }\r
1115 INLINE uint m68ki_read_32_fc(uint address, uint fc)\r
1116 {\r
1117         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */\r
1118         m68ki_check_address_error_010_less(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */\r
1119         return m68k_read_memory_32(ADDRESS_68K(address));\r
1120 }\r
1121 \r
1122 INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)\r
1123 {\r
1124         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */\r
1125         m68k_write_memory_8(ADDRESS_68K(address), value);\r
1126 }\r
1127 INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)\r
1128 {\r
1129         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */\r
1130         m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */\r
1131         m68k_write_memory_16(ADDRESS_68K(address), value);\r
1132 }\r
1133 INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)\r
1134 {\r
1135         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */\r
1136         m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */\r
1137         m68k_write_memory_32(ADDRESS_68K(address), value);\r
1138 }\r
1139 \r
1140 #if M68K_SIMULATE_PD_WRITES\r
1141 INLINE void m68ki_write_32_pd_fc(uint address, uint fc, uint value)\r
1142 {\r
1143         m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */\r
1144         m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */\r
1145         m68k_write_memory_32_pd(ADDRESS_68K(address), value);\r
1146 }\r
1147 #endif\r
1148 \r
1149 \r
1150 /* --------------------- Effective Address Calculation -------------------- */\r
1151 \r
1152 /* The program counter relative addressing modes cause operands to be\r
1153  * retrieved from program space, not data space.\r
1154  */\r
1155 INLINE uint m68ki_get_ea_pcdi(void)\r
1156 {\r
1157         uint old_pc = REG_PC;\r
1158         m68ki_use_program_space(); /* auto-disable */\r
1159         return old_pc + MAKE_INT_16(m68ki_read_imm_16());\r
1160 }\r
1161 \r
1162 \r
1163 INLINE uint m68ki_get_ea_pcix(void)\r
1164 {\r
1165         m68ki_use_program_space(); /* auto-disable */\r
1166         return m68ki_get_ea_ix(REG_PC);\r
1167 }\r
1168 \r
1169 /* Indexed addressing modes are encoded as follows:\r
1170  *\r
1171  * Base instruction format:\r
1172  * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0\r
1173  * x x x x x x x x x x | 1 1 0 | BASE REGISTER      (An)\r
1174  *\r
1175  * Base instruction format for destination EA in move instructions:\r
1176  * F E D C | B A 9    | 8 7 6 | 5 4 3 2 1 0\r
1177  * x x x x | BASE REG | 1 1 0 | X X X X X X       (An)\r
1178  *\r
1179  * Brief extension format:\r
1180  *  F  |  E D C   |  B  |  A 9  | 8 | 7 6 5 4 3 2 1 0\r
1181  * D/A | REGISTER | W/L | SCALE | 0 |  DISPLACEMENT\r
1182  *\r
1183  * Full extension format:\r
1184  *  F     E D C      B     A 9    8   7    6    5 4       3   2 1 0\r
1185  * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS\r
1186  * BASE DISPLACEMENT (0, 16, 32 bit)                (bd)\r
1187  * OUTER DISPLACEMENT (0, 16, 32 bit)               (od)\r
1188  *\r
1189  * D/A:     0 = Dn, 1 = An                          (Xn)\r
1190  * W/L:     0 = W (sign extend), 1 = L              (.SIZE)\r
1191  * SCALE:   00=1, 01=2, 10=4, 11=8                  (*SCALE)\r
1192  * BS:      0=add base reg, 1=suppress base reg     (An suppressed)\r
1193  * IS:      0=add index, 1=suppress index           (Xn suppressed)\r
1194  * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long  (size of bd)\r
1195  *\r
1196  * IS I/IS Operation\r
1197  * 0  000  No Memory Indirect\r
1198  * 0  001  indir prex with null outer\r
1199  * 0  010  indir prex with word outer\r
1200  * 0  011  indir prex with long outer\r
1201  * 0  100  reserved\r
1202  * 0  101  indir postx with null outer\r
1203  * 0  110  indir postx with word outer\r
1204  * 0  111  indir postx with long outer\r
1205  * 1  000  no memory indirect\r
1206  * 1  001  mem indir with null outer\r
1207  * 1  010  mem indir with word outer\r
1208  * 1  011  mem indir with long outer\r
1209  * 1  100-111  reserved\r
1210  */\r
1211 INLINE uint m68ki_get_ea_ix(uint An)\r
1212 {\r
1213         /* An = base register */\r
1214         uint extension = m68ki_read_imm_16();\r
1215         uint Xn = 0;                        /* Index register */\r
1216         uint bd = 0;                        /* Base Displacement */\r
1217         uint od = 0;                        /* Outer Displacement */\r
1218 \r
1219         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))\r
1220         {\r
1221                 /* Calculate index */\r
1222                 Xn = REG_DA[extension>>12];     /* Xn */\r
1223                 if(!BIT_B(extension))           /* W/L */\r
1224                         Xn = MAKE_INT_16(Xn);\r
1225 \r
1226                 /* Add base register and displacement and return */\r
1227                 return An + Xn + MAKE_INT_8(extension);\r
1228         }\r
1229 \r
1230         /* Brief extension format */\r
1231         if(!BIT_8(extension))\r
1232         {\r
1233                 /* Calculate index */\r
1234                 Xn = REG_DA[extension>>12];     /* Xn */\r
1235                 if(!BIT_B(extension))           /* W/L */\r
1236                         Xn = MAKE_INT_16(Xn);\r
1237                 /* Add scale if proper CPU type */\r
1238                 if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))\r
1239                         Xn <<= (extension>>9) & 3;  /* SCALE */\r
1240 \r
1241                 /* Add base register and displacement and return */\r
1242                 return An + Xn + MAKE_INT_8(extension);\r
1243         }\r
1244 \r
1245         /* Full extension format */\r
1246 \r
1247         USE_CYCLES(m68ki_ea_idx_cycle_table[extension&0x3f]);\r
1248 \r
1249         /* Check if base register is present */\r
1250         if(BIT_7(extension))                /* BS */\r
1251                 An = 0;                         /* An */\r
1252 \r
1253         /* Check if index is present */\r
1254         if(!BIT_6(extension))               /* IS */\r
1255         {\r
1256                 Xn = REG_DA[extension>>12];     /* Xn */\r
1257                 if(!BIT_B(extension))           /* W/L */\r
1258                         Xn = MAKE_INT_16(Xn);\r
1259                 Xn <<= (extension>>9) & 3;      /* SCALE */\r
1260         }\r
1261 \r
1262         /* Check if base displacement is present */\r
1263         if(BIT_5(extension))                /* BD SIZE */\r
1264                 bd = BIT_4(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());\r
1265 \r
1266         /* If no indirect action, we are done */\r
1267         if(!(extension&7))                  /* No Memory Indirect */\r
1268                 return An + bd + Xn;\r
1269 \r
1270         /* Check if outer displacement is present */\r
1271         if(BIT_1(extension))                /* I/IS:  od */\r
1272                 od = BIT_0(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());\r
1273 \r
1274         /* Postindex */\r
1275         if(BIT_2(extension))                /* I/IS:  0 = preindex, 1 = postindex */\r
1276                 return m68ki_read_32(An + bd) + Xn + od;\r
1277 \r
1278         /* Preindex */\r
1279         return m68ki_read_32(An + bd + Xn) + od;\r
1280 }\r
1281 \r
1282 \r
1283 /* Fetch operands */\r
1284 INLINE uint OPER_AY_AI_8(void)  {uint ea = EA_AY_AI_8();  return m68ki_read_8(ea); }\r
1285 INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);}\r
1286 INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);}\r
1287 INLINE uint OPER_AY_PI_8(void)  {uint ea = EA_AY_PI_8();  return m68ki_read_8(ea); }\r
1288 INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);}\r
1289 INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);}\r
1290 INLINE uint OPER_AY_PD_8(void)  {uint ea = EA_AY_PD_8();  return m68ki_read_8(ea); }\r
1291 INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);}\r
1292 INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);}\r
1293 INLINE uint OPER_AY_DI_8(void)  {uint ea = EA_AY_DI_8();  return m68ki_read_8(ea); }\r
1294 INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);}\r
1295 INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);}\r
1296 INLINE uint OPER_AY_IX_8(void)  {uint ea = EA_AY_IX_8();  return m68ki_read_8(ea); }\r
1297 INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);}\r
1298 INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);}\r
1299 \r
1300 INLINE uint OPER_AX_AI_8(void)  {uint ea = EA_AX_AI_8();  return m68ki_read_8(ea); }\r
1301 INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);}\r
1302 INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);}\r
1303 INLINE uint OPER_AX_PI_8(void)  {uint ea = EA_AX_PI_8();  return m68ki_read_8(ea); }\r
1304 INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);}\r
1305 INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);}\r
1306 INLINE uint OPER_AX_PD_8(void)  {uint ea = EA_AX_PD_8();  return m68ki_read_8(ea); }\r
1307 INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);}\r
1308 INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);}\r
1309 INLINE uint OPER_AX_DI_8(void)  {uint ea = EA_AX_DI_8();  return m68ki_read_8(ea); }\r
1310 INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);}\r
1311 INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);}\r
1312 INLINE uint OPER_AX_IX_8(void)  {uint ea = EA_AX_IX_8();  return m68ki_read_8(ea); }\r
1313 INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);}\r
1314 INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);}\r
1315 \r
1316 INLINE uint OPER_A7_PI_8(void)  {uint ea = EA_A7_PI_8();  return m68ki_read_8(ea); }\r
1317 INLINE uint OPER_A7_PD_8(void)  {uint ea = EA_A7_PD_8();  return m68ki_read_8(ea); }\r
1318 \r
1319 INLINE uint OPER_AW_8(void)     {uint ea = EA_AW_8();     return m68ki_read_8(ea); }\r
1320 INLINE uint OPER_AW_16(void)    {uint ea = EA_AW_16();    return m68ki_read_16(ea);}\r
1321 INLINE uint OPER_AW_32(void)    {uint ea = EA_AW_32();    return m68ki_read_32(ea);}\r
1322 INLINE uint OPER_AL_8(void)     {uint ea = EA_AL_8();     return m68ki_read_8(ea); }\r
1323 INLINE uint OPER_AL_16(void)    {uint ea = EA_AL_16();    return m68ki_read_16(ea);}\r
1324 INLINE uint OPER_AL_32(void)    {uint ea = EA_AL_32();    return m68ki_read_32(ea);}\r
1325 INLINE uint OPER_PCDI_8(void)   {uint ea = EA_PCDI_8();   return m68ki_read_pcrel_8(ea); }\r
1326 INLINE uint OPER_PCDI_16(void)  {uint ea = EA_PCDI_16();  return m68ki_read_pcrel_16(ea);}\r
1327 INLINE uint OPER_PCDI_32(void)  {uint ea = EA_PCDI_32();  return m68ki_read_pcrel_32(ea);}\r
1328 INLINE uint OPER_PCIX_8(void)   {uint ea = EA_PCIX_8();   return m68ki_read_pcrel_8(ea); }\r
1329 INLINE uint OPER_PCIX_16(void)  {uint ea = EA_PCIX_16();  return m68ki_read_pcrel_16(ea);}\r
1330 INLINE uint OPER_PCIX_32(void)  {uint ea = EA_PCIX_32();  return m68ki_read_pcrel_32(ea);}\r
1331 \r
1332 \r
1333 \r
1334 /* ---------------------------- Stack Functions --------------------------- */\r
1335 \r
1336 /* Push/pull data from the stack */\r
1337 INLINE void m68ki_push_16(uint value)\r
1338 {\r
1339         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);\r
1340         m68ki_write_16(REG_SP, value);\r
1341 }\r
1342 \r
1343 INLINE void m68ki_push_32(uint value)\r
1344 {\r
1345         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);\r
1346         m68ki_write_32(REG_SP, value);\r
1347 }\r
1348 \r
1349 INLINE uint m68ki_pull_16(void)\r
1350 {\r
1351         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);\r
1352         return m68ki_read_16(REG_SP-2);\r
1353 }\r
1354 \r
1355 INLINE uint m68ki_pull_32(void)\r
1356 {\r
1357         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);\r
1358         return m68ki_read_32(REG_SP-4);\r
1359 }\r
1360 \r
1361 \r
1362 /* Increment/decrement the stack as if doing a push/pull but\r
1363  * don't do any memory access.\r
1364  */\r
1365 INLINE void m68ki_fake_push_16(void)\r
1366 {\r
1367         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);\r
1368 }\r
1369 \r
1370 INLINE void m68ki_fake_push_32(void)\r
1371 {\r
1372         REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);\r
1373 }\r
1374 \r
1375 INLINE void m68ki_fake_pull_16(void)\r
1376 {\r
1377         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);\r
1378 }\r
1379 \r
1380 INLINE void m68ki_fake_pull_32(void)\r
1381 {\r
1382         REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);\r
1383 }\r
1384 \r
1385 \r
1386 /* ----------------------------- Program Flow ----------------------------- */\r
1387 \r
1388 /* Jump to a new program location or vector.\r
1389  * These functions will also call the pc_changed callback if it was enabled\r
1390  * in m68kconf.h.\r
1391  */\r
1392 INLINE void m68ki_jump(uint new_pc)\r
1393 {\r
1394         REG_PC = new_pc;\r
1395         m68ki_pc_changed(REG_PC);\r
1396 }\r
1397 \r
1398 INLINE void m68ki_jump_vector(uint vector)\r
1399 {\r
1400         REG_PC = (vector<<2) + REG_VBR;\r
1401         REG_PC = m68ki_read_data_32(REG_PC);\r
1402         m68ki_pc_changed(REG_PC);\r
1403 }\r
1404 \r
1405 \r
1406 /* Branch to a new memory location.\r
1407  * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h.\r
1408  * So far I've found no problems with not calling pc_changed for 8 or 16\r
1409  * bit branches.\r
1410  */\r
1411 INLINE void m68ki_branch_8(uint offset)\r
1412 {\r
1413         REG_PC += MAKE_INT_8(offset);\r
1414 }\r
1415 \r
1416 INLINE void m68ki_branch_16(uint offset)\r
1417 {\r
1418         REG_PC += MAKE_INT_16(offset);\r
1419 }\r
1420 \r
1421 INLINE void m68ki_branch_32(uint offset)\r
1422 {\r
1423         REG_PC += offset;\r
1424         m68ki_pc_changed(REG_PC);\r
1425 }\r
1426 \r
1427 \r
1428 \r
1429 /* ---------------------------- Status Register --------------------------- */\r
1430 \r
1431 /* Set the S flag and change the active stack pointer.\r
1432  * Note that value MUST be 4 or 0.\r
1433  */\r
1434 INLINE void m68ki_set_s_flag(uint value)\r
1435 {\r
1436         /* Backup the old stack pointer */\r
1437         REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;\r
1438         /* Set the S flag */\r
1439         FLAG_S = value;\r
1440         /* Set the new stack pointer */\r
1441         REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];\r
1442 }\r
1443 \r
1444 /* Set the S and M flags and change the active stack pointer.\r
1445  * Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M).\r
1446  */\r
1447 INLINE void m68ki_set_sm_flag(uint value)\r
1448 {\r
1449         /* Backup the old stack pointer */\r
1450         REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;\r
1451         /* Set the S and M flags */\r
1452         FLAG_S = value & SFLAG_SET;\r
1453         FLAG_M = value & MFLAG_SET;\r
1454         /* Set the new stack pointer */\r
1455         REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];\r
1456 }\r
1457 \r
1458 /* Set the S and M flags.  Don't touch the stack pointer. */\r
1459 INLINE void m68ki_set_sm_flag_nosp(uint value)\r
1460 {\r
1461         /* Set the S and M flags */\r
1462         FLAG_S = value & SFLAG_SET;\r
1463         FLAG_M = value & MFLAG_SET;\r
1464 }\r
1465 \r
1466 \r
1467 /* Set the condition code register */\r
1468 INLINE void m68ki_set_ccr(uint value)\r
1469 {\r
1470         FLAG_X = BIT_4(value)  << 4;\r
1471         FLAG_N = BIT_3(value)  << 4;\r
1472         FLAG_Z = !BIT_2(value);\r
1473         FLAG_V = BIT_1(value)  << 6;\r
1474         FLAG_C = BIT_0(value)  << 8;\r
1475 }\r
1476 \r
1477 /* Set the status register but don't check for interrupts */\r
1478 INLINE void m68ki_set_sr_noint(uint value)\r
1479 {\r
1480         /* Mask out the "unimplemented" bits */\r
1481         value &= CPU_SR_MASK;\r
1482 \r
1483         /* Now set the status register */\r
1484         FLAG_T1 = BIT_F(value);\r
1485         FLAG_T0 = BIT_E(value);\r
1486         FLAG_INT_MASK = value & 0x0700;\r
1487         m68ki_set_ccr(value);\r
1488         m68ki_set_sm_flag((value >> 11) & 6);\r
1489 }\r
1490 \r
1491 /* Set the status register but don't check for interrupts nor\r
1492  * change the stack pointer\r
1493  */\r
1494 INLINE void m68ki_set_sr_noint_nosp(uint value)\r
1495 {\r
1496         /* Mask out the "unimplemented" bits */\r
1497         value &= CPU_SR_MASK;\r
1498 \r
1499         /* Now set the status register */\r
1500         FLAG_T1 = BIT_F(value);\r
1501         FLAG_T0 = BIT_E(value);\r
1502         FLAG_INT_MASK = value & 0x0700;\r
1503         m68ki_set_ccr(value);\r
1504         m68ki_set_sm_flag_nosp((value >> 11) & 6);\r
1505 }\r
1506 \r
1507 /* Set the status register and check for interrupts */\r
1508 INLINE void m68ki_set_sr(uint value)\r
1509 {\r
1510         m68ki_set_sr_noint(value);\r
1511         m68ki_check_interrupts();\r
1512 }\r
1513 \r
1514 \r
1515 /* ------------------------- Exception Processing ------------------------- */\r
1516 \r
1517 /* Initiate exception processing */\r
1518 INLINE uint m68ki_init_exception(void)\r
1519 {\r
1520         /* Save the old status register */\r
1521         uint sr = m68ki_get_sr();\r
1522 \r
1523         /* Turn off trace flag, clear pending traces */\r
1524         FLAG_T1 = FLAG_T0 = 0;\r
1525         m68ki_clear_trace();\r
1526         /* Enter supervisor mode */\r
1527         m68ki_set_s_flag(SFLAG_SET);\r
1528 \r
1529         return sr;\r
1530 }\r
1531 \r
1532 /* 3 word stack frame (68000 only) */\r
1533 INLINE void m68ki_stack_frame_3word(uint pc, uint sr)\r
1534 {\r
1535         m68ki_push_32(pc);\r
1536         m68ki_push_16(sr);\r
1537 }\r
1538 \r
1539 /* Format 0 stack frame.\r
1540  * This is the standard stack frame for 68010+.\r
1541  */\r
1542 INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector)\r
1543 {\r
1544         /* Stack a 3-word frame if we are 68000 */\r
1545         if(CPU_TYPE == CPU_TYPE_000 || CPU_TYPE == CPU_TYPE_008)\r
1546         {\r
1547                 m68ki_stack_frame_3word(pc, sr);\r
1548                 return;\r
1549         }\r
1550         m68ki_push_16(vector<<2);\r
1551         m68ki_push_32(pc);\r
1552         m68ki_push_16(sr);\r
1553 }\r
1554 \r
1555 /* Format 1 stack frame (68020).\r
1556  * For 68020, this is the 4 word throwaway frame.\r
1557  */\r
1558 INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)\r
1559 {\r
1560         m68ki_push_16(0x1000 | (vector<<2));\r
1561         m68ki_push_32(pc);\r
1562         m68ki_push_16(sr);\r
1563 }\r
1564 \r
1565 /* Format 2 stack frame.\r
1566  * This is used only by 68020 for trap exceptions.\r
1567  */\r
1568 INLINE void m68ki_stack_frame_0010(uint sr, uint vector)\r
1569 {\r
1570         m68ki_push_32(REG_PPC);\r
1571         m68ki_push_16(0x2000 | (vector<<2));\r
1572         m68ki_push_32(REG_PC);\r
1573         m68ki_push_16(sr);\r
1574 }\r
1575 \r
1576 \r
1577 /* Bus error stack frame (68000 only).\r
1578  */\r
1579 INLINE void m68ki_stack_frame_buserr(uint sr)\r
1580 {\r
1581         m68ki_push_32(REG_PC);\r
1582         m68ki_push_16(sr);\r
1583         m68ki_push_16(REG_IR);\r
1584         m68ki_push_32(m68ki_aerr_address);      /* access address */\r
1585         /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC\r
1586      * R/W  0 = write, 1 = read\r
1587      * I/N  0 = instruction, 1 = not\r
1588      * FC   3-bit function code\r
1589      */\r
1590         m68ki_push_16(m68ki_aerr_write_mode | CPU_INSTR_MODE | m68ki_aerr_fc);\r
1591 }\r
1592 \r
1593 /* Format 8 stack frame (68010).\r
1594  * 68010 only.  This is the 29 word bus/address error frame.\r
1595  */\r
1596 void m68ki_stack_frame_1000(uint pc, uint sr, uint vector)\r
1597 {\r
1598         /* VERSION\r
1599      * NUMBER\r
1600      * INTERNAL INFORMATION, 16 WORDS\r
1601      */\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         m68ki_fake_push_32();\r
1608         m68ki_fake_push_32();\r
1609         m68ki_fake_push_32();\r
1610 \r
1611         /* INSTRUCTION INPUT BUFFER */\r
1612         m68ki_push_16(0);\r
1613 \r
1614         /* UNUSED, RESERVED (not written) */\r
1615         m68ki_fake_push_16();\r
1616 \r
1617         /* DATA INPUT BUFFER */\r
1618         m68ki_push_16(0);\r
1619 \r
1620         /* UNUSED, RESERVED (not written) */\r
1621         m68ki_fake_push_16();\r
1622 \r
1623         /* DATA OUTPUT BUFFER */\r
1624         m68ki_push_16(0);\r
1625 \r
1626         /* UNUSED, RESERVED (not written) */\r
1627         m68ki_fake_push_16();\r
1628 \r
1629         /* FAULT ADDRESS */\r
1630         m68ki_push_32(0);\r
1631 \r
1632         /* SPECIAL STATUS WORD */\r
1633         m68ki_push_16(0);\r
1634 \r
1635         /* 1000, VECTOR OFFSET */\r
1636         m68ki_push_16(0x8000 | (vector<<2));\r
1637 \r
1638         /* PROGRAM COUNTER */\r
1639         m68ki_push_32(pc);\r
1640 \r
1641         /* STATUS REGISTER */\r
1642         m68ki_push_16(sr);\r
1643 }\r
1644 \r
1645 /* Format A stack frame (short bus fault).\r
1646  * This is used only by 68020 for bus fault and address error\r
1647  * if the error happens at an instruction boundary.\r
1648  * PC stacked is address of next instruction.\r
1649  */\r
1650 void m68ki_stack_frame_1010(uint sr, uint vector, uint pc)\r
1651 {\r
1652         /* INTERNAL REGISTER */\r
1653         m68ki_push_16(0);\r
1654 \r
1655         /* INTERNAL REGISTER */\r
1656         m68ki_push_16(0);\r
1657 \r
1658         /* DATA OUTPUT BUFFER (2 words) */\r
1659         m68ki_push_32(0);\r
1660 \r
1661         /* INTERNAL REGISTER */\r
1662         m68ki_push_16(0);\r
1663 \r
1664         /* INTERNAL REGISTER */\r
1665         m68ki_push_16(0);\r
1666 \r
1667         /* DATA CYCLE FAULT ADDRESS (2 words) */\r
1668         m68ki_push_32(0);\r
1669 \r
1670         /* INSTRUCTION PIPE STAGE B */\r
1671         m68ki_push_16(0);\r
1672 \r
1673         /* INSTRUCTION PIPE STAGE C */\r
1674         m68ki_push_16(0);\r
1675 \r
1676         /* SPECIAL STATUS REGISTER */\r
1677         m68ki_push_16(0);\r
1678 \r
1679         /* INTERNAL REGISTER */\r
1680         m68ki_push_16(0);\r
1681 \r
1682         /* 1010, VECTOR OFFSET */\r
1683         m68ki_push_16(0xa000 | (vector<<2));\r
1684 \r
1685         /* PROGRAM COUNTER */\r
1686         m68ki_push_32(pc);\r
1687 \r
1688         /* STATUS REGISTER */\r
1689         m68ki_push_16(sr);\r
1690 }\r
1691 \r
1692 /* Format B stack frame (long bus fault).\r
1693  * This is used only by 68020 for bus fault and address error\r
1694  * if the error happens during instruction execution.\r
1695  * PC stacked is address of instruction in progress.\r
1696  */\r
1697 void m68ki_stack_frame_1011(uint sr, uint vector, uint pc)\r
1698 {\r
1699         /* INTERNAL REGISTERS (18 words) */\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         m68ki_push_32(0);\r
1707         m68ki_push_32(0);\r
1708         m68ki_push_32(0);\r
1709 \r
1710         /* VERSION# (4 bits), INTERNAL INFORMATION */\r
1711         m68ki_push_16(0);\r
1712 \r
1713         /* INTERNAL REGISTERS (3 words) */\r
1714         m68ki_push_32(0);\r
1715         m68ki_push_16(0);\r
1716 \r
1717         /* DATA INTPUT BUFFER (2 words) */\r
1718         m68ki_push_32(0);\r
1719 \r
1720         /* INTERNAL REGISTERS (2 words) */\r
1721         m68ki_push_32(0);\r
1722 \r
1723         /* STAGE B ADDRESS (2 words) */\r
1724         m68ki_push_32(0);\r
1725 \r
1726         /* INTERNAL REGISTER (4 words) */\r
1727         m68ki_push_32(0);\r
1728         m68ki_push_32(0);\r
1729 \r
1730         /* DATA OUTPUT BUFFER (2 words) */\r
1731         m68ki_push_32(0);\r
1732 \r
1733         /* INTERNAL REGISTER */\r
1734         m68ki_push_16(0);\r
1735 \r
1736         /* INTERNAL REGISTER */\r
1737         m68ki_push_16(0);\r
1738 \r
1739         /* DATA CYCLE FAULT ADDRESS (2 words) */\r
1740         m68ki_push_32(0);\r
1741 \r
1742         /* INSTRUCTION PIPE STAGE B */\r
1743         m68ki_push_16(0);\r
1744 \r
1745         /* INSTRUCTION PIPE STAGE C */\r
1746         m68ki_push_16(0);\r
1747 \r
1748         /* SPECIAL STATUS REGISTER */\r
1749         m68ki_push_16(0);\r
1750 \r
1751         /* INTERNAL REGISTER */\r
1752         m68ki_push_16(0);\r
1753 \r
1754         /* 1011, VECTOR OFFSET */\r
1755         m68ki_push_16(0xb000 | (vector<<2));\r
1756 \r
1757         /* PROGRAM COUNTER */\r
1758         m68ki_push_32(pc);\r
1759 \r
1760         /* STATUS REGISTER */\r
1761         m68ki_push_16(sr);\r
1762 }\r
1763 \r
1764 \r
1765 /* Used for Group 2 exceptions.\r
1766  * These stack a type 2 frame on the 020.\r
1767  */\r
1768 INLINE void m68ki_exception_trap(uint vector)\r
1769 {\r
1770         uint sr = m68ki_init_exception();\r
1771 \r
1772         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))\r
1773                 m68ki_stack_frame_0000(REG_PC, sr, vector);\r
1774         else\r
1775                 m68ki_stack_frame_0010(sr, vector);\r
1776 \r
1777         m68ki_jump_vector(vector);\r
1778 \r
1779         /* Use up some clock cycles */\r
1780         USE_CYCLES(CYC_EXCEPTION[vector]);\r
1781 }\r
1782 \r
1783 /* Trap#n stacks a 0 frame but behaves like group2 otherwise */\r
1784 INLINE void m68ki_exception_trapN(uint vector)\r
1785 {\r
1786         uint sr = m68ki_init_exception();\r
1787         m68ki_stack_frame_0000(REG_PC, sr, vector);\r
1788         m68ki_jump_vector(vector);\r
1789 \r
1790         /* Use up some clock cycles */\r
1791         USE_CYCLES(CYC_EXCEPTION[vector]);\r
1792 }\r
1793 \r
1794 /* Exception for trace mode */\r
1795 INLINE void m68ki_exception_trace(void)\r
1796 {\r
1797         uint sr = m68ki_init_exception();\r
1798 \r
1799         if(CPU_TYPE_IS_010_LESS(CPU_TYPE))\r
1800         {\r
1801                 #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON\r
1802                 if(CPU_TYPE_IS_000(CPU_TYPE))\r
1803                 {\r
1804                         CPU_INSTR_MODE = INSTRUCTION_NO;\r
1805                 }\r
1806                 #endif /* M68K_EMULATE_ADDRESS_ERROR */\r
1807                 m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE);\r
1808         }\r
1809         else\r
1810                 m68ki_stack_frame_0010(sr, EXCEPTION_TRACE);\r
1811 \r
1812         m68ki_jump_vector(EXCEPTION_TRACE);\r
1813 \r
1814         /* Trace nullifies a STOP instruction */\r
1815         CPU_STOPPED &= ~STOP_LEVEL_STOP;\r
1816 \r
1817         /* Use up some clock cycles */\r
1818         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]);\r
1819 }\r
1820 \r
1821 /* Exception for privilege violation */\r
1822 INLINE void m68ki_exception_privilege_violation(void)\r
1823 {\r
1824         uint sr = m68ki_init_exception();\r
1825 \r
1826         #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON\r
1827         if(CPU_TYPE_IS_000(CPU_TYPE))\r
1828         {\r
1829                 CPU_INSTR_MODE = INSTRUCTION_NO;\r
1830         }\r
1831         #endif /* M68K_EMULATE_ADDRESS_ERROR */\r
1832 \r
1833         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_PRIVILEGE_VIOLATION);\r
1834         m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION);\r
1835 \r
1836         /* Use up some clock cycles and undo the instruction's cycles */\r
1837         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]);\r
1838 }\r
1839 \r
1840 /* Exception for A-Line instructions */\r
1841 INLINE void m68ki_exception_1010(void)\r
1842 {\r
1843         uint sr;\r
1844 #if M68K_LOG_1010_1111 == OPT_ON\r
1845         M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n",\r
1846                                          m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,\r
1847                                          m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));\r
1848 #endif\r
1849 \r
1850         sr = m68ki_init_exception();\r
1851         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1010);\r
1852         m68ki_jump_vector(EXCEPTION_1010);\r
1853 \r
1854         /* Use up some clock cycles and undo the instruction's cycles */\r
1855         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]);\r
1856 }\r
1857 \r
1858 /* Exception for F-Line instructions */\r
1859 INLINE void m68ki_exception_1111(void)\r
1860 {\r
1861         uint sr;\r
1862 \r
1863 #if M68K_LOG_1010_1111 == OPT_ON\r
1864         M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n",\r
1865                                          m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,\r
1866                                          m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));\r
1867 #endif\r
1868 \r
1869         sr = m68ki_init_exception();\r
1870         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1111);\r
1871         m68ki_jump_vector(EXCEPTION_1111);\r
1872 \r
1873         /* Use up some clock cycles and undo the instruction's cycles */\r
1874         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]);\r
1875 }\r
1876 \r
1877 /* Exception for illegal instructions */\r
1878 INLINE void m68ki_exception_illegal(void)\r
1879 {\r
1880         uint sr;\r
1881 \r
1882         M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n",\r
1883                                  m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,\r
1884                                  m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));\r
1885 \r
1886         sr = m68ki_init_exception();\r
1887 \r
1888         #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON\r
1889         if(CPU_TYPE_IS_000(CPU_TYPE))\r
1890         {\r
1891                 CPU_INSTR_MODE = INSTRUCTION_NO;\r
1892         }\r
1893         #endif /* M68K_EMULATE_ADDRESS_ERROR */\r
1894 \r
1895         m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_ILLEGAL_INSTRUCTION);\r
1896         m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION);\r
1897 \r
1898         /* Use up some clock cycles and undo the instruction's cycles */\r
1899         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]);\r
1900 }\r
1901 \r
1902 /* Exception for format errror in RTE */\r
1903 INLINE void m68ki_exception_format_error(void)\r
1904 {\r
1905         uint sr = m68ki_init_exception();\r
1906         m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR);\r
1907         m68ki_jump_vector(EXCEPTION_FORMAT_ERROR);\r
1908 \r
1909         /* Use up some clock cycles and undo the instruction's cycles */\r
1910         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]);\r
1911 }\r
1912 \r
1913 /* Exception for address error */\r
1914 INLINE void m68ki_exception_address_error(void)\r
1915 {\r
1916         uint sr = m68ki_init_exception();\r
1917 \r
1918         /* If we were processing a bus error, address error, or reset,\r
1919      * this is a catastrophic failure.\r
1920      * Halt the CPU\r
1921      */\r
1922         if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET)\r
1923         {\r
1924 m68k_read_memory_8(0x00ffff01);\r
1925                 CPU_STOPPED = STOP_LEVEL_HALT;\r
1926                 return;\r
1927         }\r
1928         CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;\r
1929 \r
1930         /* Note: This is implemented for 68000 only! */\r
1931         m68ki_stack_frame_buserr(sr);\r
1932 \r
1933         m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR);\r
1934 \r
1935         /* Use up some clock cycles and undo the instruction's cycles */\r
1936         USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR] - CYC_INSTRUCTION[REG_IR]);\r
1937 }\r
1938 \r
1939 /* Service an interrupt request and start exception processing */\r
1940 void m68ki_exception_interrupt(uint int_level)\r
1941 {\r
1942         uint vector;\r
1943         uint sr;\r
1944         uint new_pc;\r
1945 \r
1946         #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON\r
1947         if(CPU_TYPE_IS_000(CPU_TYPE))\r
1948         {\r
1949                 CPU_INSTR_MODE = INSTRUCTION_NO;\r
1950         }\r
1951         #endif /* M68K_EMULATE_ADDRESS_ERROR */\r
1952 \r
1953         /* Turn off the stopped state */\r
1954         CPU_STOPPED &= ~STOP_LEVEL_STOP;\r
1955 \r
1956         /* If we are halted, don't do anything */\r
1957         if(CPU_STOPPED)\r
1958                 return;\r
1959 \r
1960         /* Acknowledge the interrupt */\r
1961         vector = m68ki_int_ack(int_level);\r
1962 \r
1963         /* Get the interrupt vector */\r
1964         if(vector == M68K_INT_ACK_AUTOVECTOR)\r
1965                 /* Use the autovectors.  This is the most commonly used implementation */\r
1966                 vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;\r
1967         else if(vector == M68K_INT_ACK_SPURIOUS)\r
1968                 /* Called if no devices respond to the interrupt acknowledge */\r
1969                 vector = EXCEPTION_SPURIOUS_INTERRUPT;\r
1970         else if(vector > 255)\r
1971         {\r
1972                 M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n",\r
1973                                  m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector));\r
1974                 return;\r
1975         }\r
1976 \r
1977         /* Start exception processing */\r
1978         sr = m68ki_init_exception();\r
1979 \r
1980         /* Set the interrupt mask to the level of the one being serviced */\r
1981         FLAG_INT_MASK = int_level<<8;\r
1982 \r
1983         /* Get the new PC */\r
1984         new_pc = m68ki_read_data_32((vector<<2) + REG_VBR);\r
1985 \r
1986         /* If vector is uninitialized, call the uninitialized interrupt vector */\r
1987         if(new_pc == 0)\r
1988                 new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR);\r
1989 \r
1990         /* Generate a stack frame */\r
1991         m68ki_stack_frame_0000(REG_PC, sr, vector);\r
1992         if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))\r
1993         {\r
1994                 /* Create throwaway frame */\r
1995                 m68ki_set_sm_flag(FLAG_S);      /* clear M */\r
1996                 sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */\r
1997                 m68ki_stack_frame_0001(REG_PC, sr, vector);\r
1998         }\r
1999 \r
2000         m68ki_jump(new_pc);\r
2001 \r
2002         /* Defer cycle counting until later */\r
2003         CPU_INT_CYCLES += CYC_EXCEPTION[vector];\r
2004 \r
2005 #if !M68K_EMULATE_INT_ACK\r
2006         /* Automatically clear IRQ if we are not using an acknowledge scheme */\r
2007         CPU_INT_LEVEL = 0;\r
2008 #endif /* M68K_EMULATE_INT_ACK */\r
2009 }\r
2010 \r
2011 \r
2012 /* ASG: Check for interrupts */\r
2013 INLINE void m68ki_check_interrupts(void)\r
2014 {\r
2015         if(CPU_INT_LEVEL > FLAG_INT_MASK)\r
2016                 m68ki_exception_interrupt(CPU_INT_LEVEL>>8);\r
2017 }\r
2018 \r
2019 \r
2020 \r
2021 /* ======================================================================== */\r
2022 /* ============================== END OF FILE ============================= */\r
2023 /* ======================================================================== */\r
2024 \r
2025 #endif /* M68KCPU__HEADER */\r