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