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