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