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