Mon, 14 Jan 2013 09:22:12 +0000
More bus error fixes for FreeBee
I have fixed two more bus error handling bugs in FreeBee. First, the CPU core was executing the instruction regardless of whether a bus error occurs when fetching the opcode (which caused it to execute a bogus instruction in such cases). The other one was related to one of my previous fixes - the jump to the bus error vector was at the beginning of the main loop, so it wouldn't be called immediately after the bus error occurred if the timeslot expired, causing the return address to be off.
With these fixes, Unix now runs enough to get into userspace and run the install script (it is also possible to break out and get a shell prompt). However, many commands segfault semi-randomly (or more specifically, it seems that some child processes forked by the shell might be segfaulting before they can exec the command program), so installing the system isn't possible yet. I am not sure exactly what the bug is, but it seems to be related to some function in the shell returning null when the code calling it is assuming that it won't. What the function is, or why it is returning null, I'm not sure (the shell is built without the shared libc and is stripped, making identifying the function harder). I suspect that the function might be in libc, but that is hard to tell.
Author: Andrew Warkentin <andreww591 gmail com>
1 #include <stdio.h>
2 /* ======================================================================== */
3 /* ========================= LICENSING & COPYRIGHT ======================== */
4 /* ======================================================================== */
5 /*
6 * MUSASHI
7 * Version 3.3
8 *
9 * A portable Motorola M680x0 processor emulation engine.
10 * Copyright 1998-2001 Karl Stenerud. All rights reserved.
11 *
12 * This code may be freely used for non-commercial purposes as long as this
13 * copyright notice remains unaltered in the source code and any binary files
14 * containing this code in compiled form.
15 *
16 * All other lisencing terms must be negotiated with the author
17 * (Karl Stenerud).
18 *
19 * The latest version of this code can be obtained at:
20 * http://kstenerud.cjb.net
21 */
26 #ifndef M68KCPU__HEADER
27 #define M68KCPU__HEADER
29 #include "m68k.h"
30 #include <limits.h>
32 #if M68K_EMULATE_ADDRESS_ERROR
33 #include <setjmp.h>
34 #endif /* M68K_EMULATE_ADDRESS_ERROR */
36 /* ======================================================================== */
37 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
38 /* ======================================================================== */
40 /* Check for > 32bit sizes */
41 #if UINT_MAX > 0xffffffff
42 #define M68K_INT_GT_32_BIT 1
43 #endif
45 /* Data types used in this emulation core */
46 #undef sint8
47 #undef sint16
48 #undef sint32
49 #undef sint64
50 #undef uint8
51 #undef uint16
52 #undef uint32
53 #undef uint64
54 #undef sint
55 #undef uint
57 #define sint8 signed char /* ASG: changed from char to signed char */
58 #define sint16 signed short
59 #define sint32 signed long
60 #define uint8 unsigned char
61 #define uint16 unsigned short
62 #define uint32 unsigned long
64 /* signed and unsigned int must be at least 32 bits wide */
65 #define sint signed int
66 #define uint unsigned int
69 #if M68K_USE_64_BIT
70 #define sint64 signed long long
71 #define uint64 unsigned long long
72 #else
73 #define sint64 sint32
74 #define uint64 uint32
75 #endif /* M68K_USE_64_BIT */
79 /* Allow for architectures that don't have 8-bit sizes */
80 #if UCHAR_MAX == 0xff
81 #define MAKE_INT_8(A) (sint8)(A)
82 #else
83 #undef sint8
84 #define sint8 signed int
85 #undef uint8
86 #define uint8 unsigned int
87 INLINE sint MAKE_INT_8(uint value)
88 {
89 return (value & 0x80) ? value | ~0xff : value & 0xff;
90 }
91 #endif /* UCHAR_MAX == 0xff */
94 /* Allow for architectures that don't have 16-bit sizes */
95 #if USHRT_MAX == 0xffff
96 #define MAKE_INT_16(A) (sint16)(A)
97 #else
98 #undef sint16
99 #define sint16 signed int
100 #undef uint16
101 #define uint16 unsigned int
102 INLINE sint MAKE_INT_16(uint value)
103 {
104 return (value & 0x8000) ? value | ~0xffff : value & 0xffff;
105 }
106 #endif /* USHRT_MAX == 0xffff */
109 /* Allow for architectures that don't have 32-bit sizes */
110 #if ULONG_MAX == 0xffffffff
111 #define MAKE_INT_32(A) (sint32)(A)
112 #else
113 #undef sint32
114 #define sint32 signed int
115 #undef uint32
116 #define uint32 unsigned int
117 INLINE sint MAKE_INT_32(uint value)
118 {
119 return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff;
120 }
121 #endif /* ULONG_MAX == 0xffffffff */
126 /* ======================================================================== */
127 /* ============================ GENERAL DEFINES =========================== */
128 /* ======================================================================== */
130 /* Exception Vectors handled by emulation */
131 #define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */
132 #define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */
133 #define EXCEPTION_ILLEGAL_INSTRUCTION 4
134 #define EXCEPTION_ZERO_DIVIDE 5
135 #define EXCEPTION_CHK 6
136 #define EXCEPTION_TRAPV 7
137 #define EXCEPTION_PRIVILEGE_VIOLATION 8
138 #define EXCEPTION_TRACE 9
139 #define EXCEPTION_1010 10
140 #define EXCEPTION_1111 11
141 #define EXCEPTION_FORMAT_ERROR 14
142 #define EXCEPTION_UNINITIALIZED_INTERRUPT 15
143 #define EXCEPTION_SPURIOUS_INTERRUPT 24
144 #define EXCEPTION_INTERRUPT_AUTOVECTOR 24
145 #define EXCEPTION_TRAP_BASE 32
147 /* Function codes set by CPU during data/address bus activity */
148 #define FUNCTION_CODE_USER_DATA 1
149 #define FUNCTION_CODE_USER_PROGRAM 2
150 #define FUNCTION_CODE_SUPERVISOR_DATA 5
151 #define FUNCTION_CODE_SUPERVISOR_PROGRAM 6
152 #define FUNCTION_CODE_CPU_SPACE 7
154 /* CPU types for deciding what to emulate */
155 #define CPU_TYPE_000 1
156 #define CPU_TYPE_010 2
157 #define CPU_TYPE_EC020 4
158 #define CPU_TYPE_020 8
160 /* Different ways to stop the CPU */
161 #define STOP_LEVEL_STOP 1
162 #define STOP_LEVEL_HALT 2
164 #ifndef NULL
165 #define NULL ((void*)0)
166 #endif
168 /* ======================================================================== */
169 /* ================================ MACROS ================================ */
170 /* ======================================================================== */
173 /* ---------------------------- General Macros ---------------------------- */
175 /* Bit Isolation Macros */
176 #define BIT_0(A) ((A) & 0x00000001)
177 #define BIT_1(A) ((A) & 0x00000002)
178 #define BIT_2(A) ((A) & 0x00000004)
179 #define BIT_3(A) ((A) & 0x00000008)
180 #define BIT_4(A) ((A) & 0x00000010)
181 #define BIT_5(A) ((A) & 0x00000020)
182 #define BIT_6(A) ((A) & 0x00000040)
183 #define BIT_7(A) ((A) & 0x00000080)
184 #define BIT_8(A) ((A) & 0x00000100)
185 #define BIT_9(A) ((A) & 0x00000200)
186 #define BIT_A(A) ((A) & 0x00000400)
187 #define BIT_B(A) ((A) & 0x00000800)
188 #define BIT_C(A) ((A) & 0x00001000)
189 #define BIT_D(A) ((A) & 0x00002000)
190 #define BIT_E(A) ((A) & 0x00004000)
191 #define BIT_F(A) ((A) & 0x00008000)
192 #define BIT_10(A) ((A) & 0x00010000)
193 #define BIT_11(A) ((A) & 0x00020000)
194 #define BIT_12(A) ((A) & 0x00040000)
195 #define BIT_13(A) ((A) & 0x00080000)
196 #define BIT_14(A) ((A) & 0x00100000)
197 #define BIT_15(A) ((A) & 0x00200000)
198 #define BIT_16(A) ((A) & 0x00400000)
199 #define BIT_17(A) ((A) & 0x00800000)
200 #define BIT_18(A) ((A) & 0x01000000)
201 #define BIT_19(A) ((A) & 0x02000000)
202 #define BIT_1A(A) ((A) & 0x04000000)
203 #define BIT_1B(A) ((A) & 0x08000000)
204 #define BIT_1C(A) ((A) & 0x10000000)
205 #define BIT_1D(A) ((A) & 0x20000000)
206 #define BIT_1E(A) ((A) & 0x40000000)
207 #define BIT_1F(A) ((A) & 0x80000000)
209 /* Get the most significant bit for specific sizes */
210 #define GET_MSB_8(A) ((A) & 0x80)
211 #define GET_MSB_9(A) ((A) & 0x100)
212 #define GET_MSB_16(A) ((A) & 0x8000)
213 #define GET_MSB_17(A) ((A) & 0x10000)
214 #define GET_MSB_32(A) ((A) & 0x80000000)
215 #if M68K_USE_64_BIT
216 #define GET_MSB_33(A) ((A) & 0x100000000)
217 #endif /* M68K_USE_64_BIT */
219 /* Isolate nibbles */
220 #define LOW_NIBBLE(A) ((A) & 0x0f)
221 #define HIGH_NIBBLE(A) ((A) & 0xf0)
223 /* These are used to isolate 8, 16, and 32 bit sizes */
224 #define MASK_OUT_ABOVE_2(A) ((A) & 3)
225 #define MASK_OUT_ABOVE_8(A) ((A) & 0xff)
226 #define MASK_OUT_ABOVE_16(A) ((A) & 0xffff)
227 #define MASK_OUT_BELOW_2(A) ((A) & ~3)
228 #define MASK_OUT_BELOW_8(A) ((A) & ~0xff)
229 #define MASK_OUT_BELOW_16(A) ((A) & ~0xffff)
231 /* No need to mask if we are 32 bit */
232 #if M68K_INT_GT_32BIT || M68K_USE_64_BIT
233 #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff)
234 #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff)
235 #else
236 #define MASK_OUT_ABOVE_32(A) (A)
237 #define MASK_OUT_BELOW_32(A) 0
238 #endif /* M68K_INT_GT_32BIT || M68K_USE_64_BIT */
240 /* Simulate address lines of 68k family */
241 #define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK)
244 /* Shift & Rotate Macros. */
245 #define LSL(A, C) ((A) << (C))
246 #define LSR(A, C) ((A) >> (C))
248 /* Some > 32-bit optimizations */
249 #if M68K_INT_GT_32BIT
250 /* Shift left and right */
251 #define LSR_32(A, C) ((A) >> (C))
252 #define LSL_32(A, C) ((A) << (C))
253 #else
254 /* We have to do this because the morons at ANSI decided that shifts
255 * by >= data size are undefined.
256 */
257 #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
258 #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
259 #endif /* M68K_INT_GT_32BIT */
261 #if M68K_USE_64_BIT
262 #define LSL_32_64(A, C) ((A) << (C))
263 #define LSR_32_64(A, C) ((A) >> (C))
264 #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C)))
265 #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C)))
266 #endif /* M68K_USE_64_BIT */
268 #define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C)))
269 #define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C)))
270 #define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C)))
271 #define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C)))
272 #define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C)))
273 #define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C)))
275 #define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C)))
276 #define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C)))
277 #define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C)))
278 #define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C)))
279 #define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C)))
280 #define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C)))
284 /* ------------------------------ CPU Access ------------------------------ */
286 /* Access the CPU registers */
287 #define CPU_TYPE m68ki_cpu.cpu_type
289 #define REG_DA m68ki_cpu.dar /* easy access to data and address regs */
290 #define REG_D m68ki_cpu.dar
291 #define REG_A (m68ki_cpu.dar+8)
292 #define REG_PPC m68ki_cpu.ppc
293 #define REG_PC m68ki_cpu.pc
294 #define REG_SP_BASE m68ki_cpu.sp
295 #define REG_USP m68ki_cpu.sp[0]
296 #define REG_ISP m68ki_cpu.sp[4]
297 #define REG_MSP m68ki_cpu.sp[6]
298 #define REG_SP m68ki_cpu.dar[15]
299 #define REG_VBR m68ki_cpu.vbr
300 #define REG_SFC m68ki_cpu.sfc
301 #define REG_DFC m68ki_cpu.dfc
302 #define REG_CACR m68ki_cpu.cacr
303 #define REG_CAAR m68ki_cpu.caar
304 #define REG_IR m68ki_cpu.ir
306 #define FLAG_T1 m68ki_cpu.t1_flag
307 #define FLAG_T0 m68ki_cpu.t0_flag
308 #define FLAG_S m68ki_cpu.s_flag
309 #define FLAG_M m68ki_cpu.m_flag
310 #define FLAG_X m68ki_cpu.x_flag
311 #define FLAG_N m68ki_cpu.n_flag
312 #define FLAG_Z m68ki_cpu.not_z_flag
313 #define FLAG_V m68ki_cpu.v_flag
314 #define FLAG_C m68ki_cpu.c_flag
315 #define FLAG_INT_MASK m68ki_cpu.int_mask
317 #define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */
318 #define CPU_INT_CYCLES m68ki_cpu.int_cycles /* ASG */
319 #define CPU_STOPPED m68ki_cpu.stopped
320 #define CPU_PREF_ADDR m68ki_cpu.pref_addr
321 #define CPU_PREF_DATA m68ki_cpu.pref_data
322 #define CPU_ADDRESS_MASK m68ki_cpu.address_mask
323 #define CPU_SR_MASK m68ki_cpu.sr_mask
325 #define BUS_ERROR_OCCURRED m68ki_cpu.bus_error_occurred
327 #define CYC_INSTRUCTION m68ki_cpu.cyc_instruction
328 #define CYC_EXCEPTION m68ki_cpu.cyc_exception
329 #define CYC_BCC_NOTAKE_B m68ki_cpu.cyc_bcc_notake_b
330 #define CYC_BCC_NOTAKE_W m68ki_cpu.cyc_bcc_notake_w
331 #define CYC_DBCC_F_NOEXP m68ki_cpu.cyc_dbcc_f_noexp
332 #define CYC_DBCC_F_EXP m68ki_cpu.cyc_dbcc_f_exp
333 #define CYC_SCC_R_FALSE m68ki_cpu.cyc_scc_r_false
334 #define CYC_MOVEM_W m68ki_cpu.cyc_movem_w
335 #define CYC_MOVEM_L m68ki_cpu.cyc_movem_l
336 #define CYC_SHIFT m68ki_cpu.cyc_shift
337 #define CYC_RESET m68ki_cpu.cyc_reset
340 #define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback
341 #define CALLBACK_BKPT_ACK m68ki_cpu.bkpt_ack_callback
342 #define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback
343 #define CALLBACK_PC_CHANGED m68ki_cpu.pc_changed_callback
344 #define CALLBACK_SET_FC m68ki_cpu.set_fc_callback
345 #define CALLBACK_INSTR_HOOK m68ki_cpu.instr_hook_callback
349 /* ----------------------------- Configuration ---------------------------- */
351 /* These defines are dependant on the configuration defines in m68kconf.h */
353 /* Disable certain comparisons if we're not using all CPU types */
354 #if M68K_EMULATE_020
355 #define CPU_TYPE_IS_020_PLUS(A) ((A) & CPU_TYPE_020)
356 #define CPU_TYPE_IS_020_LESS(A) 1
357 #else
358 #define CPU_TYPE_IS_020_PLUS(A) 0
359 #define CPU_TYPE_IS_020_LESS(A) 1
360 #endif
362 #if M68K_EMULATE_EC020
363 #define CPU_TYPE_IS_EC020_PLUS(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
364 #define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_010 | CPU_TYPE_EC020))
365 #else
366 #define CPU_TYPE_IS_EC020_PLUS(A) CPU_TYPE_IS_020_PLUS(A)
367 #define CPU_TYPE_IS_EC020_LESS(A) CPU_TYPE_IS_020_LESS(A)
368 #endif
370 #if M68K_EMULATE_010
371 #define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010)
372 #define CPU_TYPE_IS_010_PLUS(A) ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020))
373 #define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_010))
374 #else
375 #define CPU_TYPE_IS_010(A) 0
376 #define CPU_TYPE_IS_010_PLUS(A) CPU_TYPE_IS_EC020_PLUS(A)
377 #define CPU_TYPE_IS_010_LESS(A) CPU_TYPE_IS_EC020_LESS(A)
378 #endif
380 #if M68K_EMULATE_020 || M68K_EMULATE_EC020
381 #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
382 #else
383 #define CPU_TYPE_IS_020_VARIANT(A) 0
384 #endif
386 #if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010
387 #define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000)
388 #else
389 #define CPU_TYPE_IS_000(A) 1
390 #endif
393 #if !M68K_SEPARATE_READS
394 #define m68k_read_immediate_16(A) m68ki_read_program_16(A)
395 #define m68k_read_immediate_32(A) m68ki_read_program_32(A)
397 #define m68k_read_pcrelative_8(A) m68ki_read_program_8(A)
398 #define m68k_read_pcrelative_16(A) m68ki_read_program_16(A)
399 #define m68k_read_pcrelative_32(A) m68ki_read_program_32(A)
400 #endif /* M68K_SEPARATE_READS */
403 /* Enable or disable callback functions */
404 #if M68K_EMULATE_INT_ACK
405 #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER
406 #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A)
407 #else
408 #define m68ki_int_ack(A) CALLBACK_INT_ACK(A)
409 #endif
410 #else
411 /* Default action is to used autovector mode, which is most common */
412 #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR
413 #endif /* M68K_EMULATE_INT_ACK */
415 #if M68K_EMULATE_BKPT_ACK
416 #if M68K_EMULATE_BKPT_ACK == OPT_SPECIFY_HANDLER
417 #define m68ki_bkpt_ack(A) M68K_BKPT_ACK_CALLBACK(A)
418 #else
419 #define m68ki_bkpt_ack(A) CALLBACK_BKPT_ACK(A)
420 #endif
421 #else
422 #define m68ki_bkpt_ack(A)
423 #endif /* M68K_EMULATE_BKPT_ACK */
425 #if M68K_EMULATE_RESET
426 #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER
427 #define m68ki_output_reset() M68K_RESET_CALLBACK()
428 #else
429 #define m68ki_output_reset() CALLBACK_RESET_INSTR()
430 #endif
431 #else
432 #define m68ki_output_reset()
433 #endif /* M68K_EMULATE_RESET */
435 #if M68K_INSTRUCTION_HOOK
436 #if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
437 #define m68ki_instr_hook() M68K_INSTRUCTION_CALLBACK()
438 #else
439 #define m68ki_instr_hook() CALLBACK_INSTR_HOOK()
440 #endif
441 #else
442 #define m68ki_instr_hook()
443 #endif /* M68K_INSTRUCTION_HOOK */
445 #if M68K_MONITOR_PC
446 #if M68K_MONITOR_PC == OPT_SPECIFY_HANDLER
447 #define m68ki_pc_changed(A) M68K_SET_PC_CALLBACK(ADDRESS_68K(A))
448 #else
449 #define m68ki_pc_changed(A) CALLBACK_PC_CHANGED(ADDRESS_68K(A))
450 #endif
451 #else
452 #define m68ki_pc_changed(A)
453 #endif /* M68K_MONITOR_PC */
456 /* Enable or disable function code emulation */
457 #if M68K_EMULATE_FC
458 #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER
459 #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A)
460 #else
461 #define m68ki_set_fc(A) CALLBACK_SET_FC(A)
462 #endif
463 #define m68ki_use_data_space() m68ki_address_space = FUNCTION_CODE_USER_DATA
464 #define m68ki_use_program_space() m68ki_address_space = FUNCTION_CODE_USER_PROGRAM
465 #define m68ki_get_address_space() m68ki_address_space
466 #else
467 #define m68ki_set_fc(A)
468 #define m68ki_use_data_space()
469 #define m68ki_use_program_space()
470 #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA
471 #endif /* M68K_EMULATE_FC */
474 /* Enable or disable trace emulation */
475 #if M68K_EMULATE_TRACE
476 /* Initiates trace checking before each instruction (t1) */
477 #define m68ki_trace_t1() m68ki_tracing = FLAG_T1
478 /* adds t0 to trace checking if we encounter change of flow */
479 #define m68ki_trace_t0() m68ki_tracing |= FLAG_T0
480 /* Clear all tracing */
481 #define m68ki_clear_trace() m68ki_tracing = 0
482 /* Cause a trace exception if we are tracing */
483 #define m68ki_exception_if_trace() if(m68ki_tracing) m68ki_exception_trace()
484 #else
485 #define m68ki_trace_t1()
486 #define m68ki_trace_t0()
487 #define m68ki_clear_trace()
488 #define m68ki_exception_if_trace()
489 #endif /* M68K_EMULATE_TRACE */
493 /* Address error */
494 #if M68K_EMULATE_ADDRESS_ERROR
495 extern jmp_buf m68ki_address_error_trap;
496 #define m68ki_set_address_error_trap() if(setjmp(m68ki_address_error_trap)) m68ki_exception_address_error();
497 #define m68ki_check_address_error(A) if((A)&1) longjmp(m68ki_address_error_jump, 1);
498 #else
499 #define m68ki_set_address_error_trap()
500 #define m68ki_check_address_error(A)
501 #endif /* M68K_ADDRESS_ERROR */
503 /* Logging */
504 #if M68K_LOG_ENABLE
505 #include <stdio.h>
506 extern FILE* M68K_LOG_FILEHANDLE
507 extern char* m68ki_cpu_names[];
509 #define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A
510 #if M68K_LOG_1010_1111
511 #define M68K_DO_LOG_EMU(A) if(M68K_LOG_FILEHANDLE) fprintf A
512 #else
513 #define M68K_DO_LOG_EMU(A)
514 #endif
515 #else
516 #define M68K_DO_LOG(A)
517 #define M68K_DO_LOG_EMU(A)
518 #endif
522 /* -------------------------- EA / Operand Access ------------------------- */
524 /*
525 * The general instruction format follows this pattern:
526 * .... XXX. .... .YYY
527 * where XXX is register X and YYY is register Y
528 */
529 /* Data Register Isolation */
530 #define DX (REG_D[(REG_IR >> 9) & 7])
531 #define DY (REG_D[REG_IR & 7])
532 /* Address Register Isolation */
533 #define AX (REG_A[(REG_IR >> 9) & 7])
534 #define AY (REG_A[REG_IR & 7])
537 /* Effective Address Calculations */
538 #define EA_AY_AI_8() AY /* address register indirect */
539 #define EA_AY_AI_16() EA_AY_AI_8()
540 #define EA_AY_AI_32() EA_AY_AI_8()
541 #define EA_AY_PI_8() (AY++) /* postincrement (size = byte) */
542 #define EA_AY_PI_16() ((AY+=2)-2) /* postincrement (size = word) */
543 #define EA_AY_PI_32() ((AY+=4)-4) /* postincrement (size = long) */
544 #define EA_AY_PD_8() (--AY) /* predecrement (size = byte) */
545 #define EA_AY_PD_16() (AY-=2) /* predecrement (size = word) */
546 #define EA_AY_PD_32() (AY-=4) /* predecrement (size = long) */
547 #define EA_AY_DI_8() (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */
548 #define EA_AY_DI_16() EA_AY_DI_8()
549 #define EA_AY_DI_32() EA_AY_DI_8()
550 #define EA_AY_IX_8() m68ki_get_ea_ix(AY) /* indirect + index */
551 #define EA_AY_IX_16() EA_AY_IX_8()
552 #define EA_AY_IX_32() EA_AY_IX_8()
554 #define EA_AX_AI_8() AX
555 #define EA_AX_AI_16() EA_AX_AI_8()
556 #define EA_AX_AI_32() EA_AX_AI_8()
557 #define EA_AX_PI_8() (AX++)
558 #define EA_AX_PI_16() ((AX+=2)-2)
559 #define EA_AX_PI_32() ((AX+=4)-4)
560 #define EA_AX_PD_8() (--AX)
561 #define EA_AX_PD_16() (AX-=2)
562 #define EA_AX_PD_32() (AX-=4)
563 #define EA_AX_DI_8() (AX+MAKE_INT_16(m68ki_read_imm_16()))
564 #define EA_AX_DI_16() EA_AX_DI_8()
565 #define EA_AX_DI_32() EA_AX_DI_8()
566 #define EA_AX_IX_8() m68ki_get_ea_ix(AX)
567 #define EA_AX_IX_16() EA_AX_IX_8()
568 #define EA_AX_IX_32() EA_AX_IX_8()
570 #define EA_A7_PI_8() ((REG_A[7]+=2)-2)
571 #define EA_A7_PD_8() (REG_A[7]-=2)
573 #define EA_AW_8() MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */
574 #define EA_AW_16() EA_AW_8()
575 #define EA_AW_32() EA_AW_8()
576 #define EA_AL_8() m68ki_read_imm_32() /* absolute long */
577 #define EA_AL_16() EA_AL_8()
578 #define EA_AL_32() EA_AL_8()
579 #define EA_PCDI_8() m68ki_get_ea_pcdi() /* pc indirect + displacement */
580 #define EA_PCDI_16() EA_PCDI_8()
581 #define EA_PCDI_32() EA_PCDI_8()
582 #define EA_PCIX_8() m68ki_get_ea_pcix() /* pc indirect + index */
583 #define EA_PCIX_16() EA_PCIX_8()
584 #define EA_PCIX_32() EA_PCIX_8()
587 #define OPER_I_8() m68ki_read_imm_8()
588 #define OPER_I_16() m68ki_read_imm_16()
589 #define OPER_I_32() m68ki_read_imm_32()
593 /* --------------------------- Status Register ---------------------------- */
595 /* Flag Calculation Macros */
596 #define CFLAG_8(A) (A)
597 #define CFLAG_16(A) ((A)>>8)
599 #if M68K_INT_GT_32_BIT
600 #define CFLAG_ADD_32(S, D, R) ((R)>>24)
601 #define CFLAG_SUB_32(S, D, R) ((R)>>24)
602 #else
603 #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23)
604 #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23)
605 #endif /* M68K_INT_GT_32_BIT */
607 #define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R))
608 #define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
609 #define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24)
611 #define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D))
612 #define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
613 #define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24)
615 #define NFLAG_8(A) (A)
616 #define NFLAG_16(A) ((A)>>8)
617 #define NFLAG_32(A) ((A)>>24)
618 #define NFLAG_64(A) ((A)>>56)
620 #define ZFLAG_8(A) MASK_OUT_ABOVE_8(A)
621 #define ZFLAG_16(A) MASK_OUT_ABOVE_16(A)
622 #define ZFLAG_32(A) MASK_OUT_ABOVE_32(A)
625 /* Flag values */
626 #define NFLAG_SET 0x80
627 #define NFLAG_CLEAR 0
628 #define CFLAG_SET 0x100
629 #define CFLAG_CLEAR 0
630 #define XFLAG_SET 0x100
631 #define XFLAG_CLEAR 0
632 #define VFLAG_SET 0x80
633 #define VFLAG_CLEAR 0
634 #define ZFLAG_SET 0
635 #define ZFLAG_CLEAR 0xffffffff
637 #define SFLAG_SET 4
638 #define SFLAG_CLEAR 0
639 #define MFLAG_SET 2
640 #define MFLAG_CLEAR 0
642 /* Turn flag values into 1 or 0 */
643 #define XFLAG_AS_1() ((FLAG_X>>8)&1)
644 #define NFLAG_AS_1() ((FLAG_N>>7)&1)
645 #define VFLAG_AS_1() ((FLAG_V>>7)&1)
646 #define ZFLAG_AS_1() (!FLAG_Z)
647 #define CFLAG_AS_1() ((FLAG_C>>8)&1)
650 /* Conditions */
651 #define COND_CS() (FLAG_C&0x100)
652 #define COND_CC() (!COND_CS())
653 #define COND_VS() (FLAG_V&0x80)
654 #define COND_VC() (!COND_VS())
655 #define COND_NE() FLAG_Z
656 #define COND_EQ() (!COND_NE())
657 #define COND_MI() (FLAG_N&0x80)
658 #define COND_PL() (!COND_MI())
659 #define COND_LT() ((FLAG_N^FLAG_V)&0x80)
660 #define COND_GE() (!COND_LT())
661 #define COND_HI() (COND_CC() && COND_NE())
662 #define COND_LS() (COND_CS() || COND_EQ())
663 #define COND_GT() (COND_GE() && COND_NE())
664 #define COND_LE() (COND_LT() || COND_EQ())
666 /* Reversed conditions */
667 #define COND_NOT_CS() COND_CC()
668 #define COND_NOT_CC() COND_CS()
669 #define COND_NOT_VS() COND_VC()
670 #define COND_NOT_VC() COND_VS()
671 #define COND_NOT_NE() COND_EQ()
672 #define COND_NOT_EQ() COND_NE()
673 #define COND_NOT_MI() COND_PL()
674 #define COND_NOT_PL() COND_MI()
675 #define COND_NOT_LT() COND_GE()
676 #define COND_NOT_GE() COND_LT()
677 #define COND_NOT_HI() COND_LS()
678 #define COND_NOT_LS() COND_HI()
679 #define COND_NOT_GT() COND_LE()
680 #define COND_NOT_LE() COND_GT()
682 /* Not real conditions, but here for convenience */
683 #define COND_XS() (FLAG_X&0x100)
684 #define COND_XC() (!COND_XS)
687 /* Get the condition code register */
688 #define m68ki_get_ccr() ((COND_XS() >> 4) | \
689 (COND_MI() >> 4) | \
690 (COND_EQ() << 2) | \
691 (COND_VS() >> 6) | \
692 (COND_CS() >> 8))
694 /* Get the status register */
695 #define m68ki_get_sr() ( FLAG_T1 | \
696 FLAG_T0 | \
697 (FLAG_S << 11) | \
698 (FLAG_M << 11) | \
699 FLAG_INT_MASK | \
700 m68ki_get_ccr())
704 /* ---------------------------- Cycle Counting ---------------------------- */
706 #define ADD_CYCLES(A) m68ki_remaining_cycles += (A)
707 #define USE_CYCLES(A) m68ki_remaining_cycles -= (A)
708 #define SET_CYCLES(A) m68ki_remaining_cycles = A
709 #define GET_CYCLES() m68ki_remaining_cycles
710 #define USE_ALL_CYCLES() m68ki_remaining_cycles = 0
714 /* ----------------------------- Read / Write ----------------------------- */
716 /* Read from the current address space */
717 #define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space())
718 #define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space())
719 #define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space())
721 /* Write to the current data space */
722 #define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
723 #define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
724 #define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
726 /* map read immediate 8 to read immediate 16 */
727 #define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16())
729 /* Map PC-relative reads */
730 #define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A)
731 #define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A)
732 #define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A)
734 /* Read from the program space */
735 #define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
736 #define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
737 #define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
739 /* Read from the data space */
740 #define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
741 #define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
742 #define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
746 /* ======================================================================== */
747 /* =============================== PROTOTYPES ============================= */
748 /* ======================================================================== */
750 typedef struct
751 {
752 uint cpu_type; /* CPU Type: 68000, 68010, 68EC020, or 68020 */
753 uint dar[16]; /* Data and Address Registers */
754 uint ppc; /* Previous program counter */
755 uint pc; /* Program Counter */
756 uint sp[7]; /* User, Interrupt, and Master Stack Pointers */
757 uint vbr; /* Vector Base Register (m68010+) */
758 uint sfc; /* Source Function Code Register (m68010+) */
759 uint dfc; /* Destination Function Code Register (m68010+) */
760 uint cacr; /* Cache Control Register (m68020, unemulated) */
761 uint caar; /* Cache Address Register (m68020, unemulated) */
762 uint ir; /* Instruction Register */
763 uint t1_flag; /* Trace 1 */
764 uint t0_flag; /* Trace 0 */
765 uint s_flag; /* Supervisor */
766 uint m_flag; /* Master/Interrupt state */
767 uint x_flag; /* Extend */
768 uint n_flag; /* Negative */
769 uint not_z_flag; /* Zero, inverted for speedups */
770 uint v_flag; /* Overflow */
771 uint c_flag; /* Carry */
772 uint int_mask; /* I0-I2 */
773 uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */
774 uint int_cycles; /* ASG: extra cycles from generated interrupts */
775 uint stopped; /* Stopped state */
776 uint pref_addr; /* Last prefetch address */
777 uint pref_data; /* Data in the prefetch queue */
778 uint address_mask; /* Available address pins */
779 uint sr_mask; /* Implemented status register bits */
781 uint bus_error_occurred;
783 /* Clocks required for instructions / exceptions */
784 uint cyc_bcc_notake_b;
785 uint cyc_bcc_notake_w;
786 uint cyc_dbcc_f_noexp;
787 uint cyc_dbcc_f_exp;
788 uint cyc_scc_r_false;
789 uint cyc_movem_w;
790 uint cyc_movem_l;
791 uint cyc_shift;
792 uint cyc_reset;
793 uint8* cyc_instruction;
794 uint8* cyc_exception;
796 /* Callbacks to host */
797 int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */
798 void (*bkpt_ack_callback)(unsigned int data); /* Breakpoint Acknowledge */
799 void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */
800 void (*pc_changed_callback)(unsigned int new_pc); /* Called when the PC changes by a large amount */
801 void (*set_fc_callback)(unsigned int new_fc); /* Called when the CPU function code changes */
802 void (*instr_hook_callback)(void); /* Called every instruction cycle prior to execution */
804 } m68ki_cpu_core;
807 extern m68ki_cpu_core m68ki_cpu;
808 extern sint m68ki_remaining_cycles;
809 extern uint m68ki_tracing;
810 extern uint8 m68ki_shift_8_table[];
811 extern uint16 m68ki_shift_16_table[];
812 extern uint m68ki_shift_32_table[];
813 extern uint8 m68ki_exception_cycle_table[][256];
814 extern uint m68ki_address_space;
815 extern uint8 m68ki_ea_idx_cycle_table[];
818 /* Read data immediately after the program counter */
819 INLINE uint m68ki_read_imm_16(void);
820 INLINE uint m68ki_read_imm_32(void);
822 /* Read data with specific function code */
823 INLINE uint m68ki_read_8_fc (uint address, uint fc);
824 INLINE uint m68ki_read_16_fc (uint address, uint fc);
825 INLINE uint m68ki_read_32_fc (uint address, uint fc);
827 /* Write data with specific function code */
828 INLINE void m68ki_write_8_fc (uint address, uint fc, uint value);
829 INLINE void m68ki_write_16_fc(uint address, uint fc, uint value);
830 INLINE void m68ki_write_32_fc(uint address, uint fc, uint value);
832 /* Indexed and PC-relative ea fetching */
833 INLINE uint m68ki_get_ea_pcdi(void);
834 INLINE uint m68ki_get_ea_pcix(void);
835 INLINE uint m68ki_get_ea_ix(uint An);
837 /* Operand fetching */
838 INLINE uint OPER_AY_AI_8(void);
839 INLINE uint OPER_AY_AI_16(void);
840 INLINE uint OPER_AY_AI_32(void);
841 INLINE uint OPER_AY_PI_8(void);
842 INLINE uint OPER_AY_PI_16(void);
843 INLINE uint OPER_AY_PI_32(void);
844 INLINE uint OPER_AY_PD_8(void);
845 INLINE uint OPER_AY_PD_16(void);
846 INLINE uint OPER_AY_PD_32(void);
847 INLINE uint OPER_AY_DI_8(void);
848 INLINE uint OPER_AY_DI_16(void);
849 INLINE uint OPER_AY_DI_32(void);
850 INLINE uint OPER_AY_IX_8(void);
851 INLINE uint OPER_AY_IX_16(void);
852 INLINE uint OPER_AY_IX_32(void);
854 INLINE uint OPER_AX_AI_8(void);
855 INLINE uint OPER_AX_AI_16(void);
856 INLINE uint OPER_AX_AI_32(void);
857 INLINE uint OPER_AX_PI_8(void);
858 INLINE uint OPER_AX_PI_16(void);
859 INLINE uint OPER_AX_PI_32(void);
860 INLINE uint OPER_AX_PD_8(void);
861 INLINE uint OPER_AX_PD_16(void);
862 INLINE uint OPER_AX_PD_32(void);
863 INLINE uint OPER_AX_DI_8(void);
864 INLINE uint OPER_AX_DI_16(void);
865 INLINE uint OPER_AX_DI_32(void);
866 INLINE uint OPER_AX_IX_8(void);
867 INLINE uint OPER_AX_IX_16(void);
868 INLINE uint OPER_AX_IX_32(void);
870 INLINE uint OPER_A7_PI_8(void);
871 INLINE uint OPER_A7_PD_8(void);
873 INLINE uint OPER_AW_8(void);
874 INLINE uint OPER_AW_16(void);
875 INLINE uint OPER_AW_32(void);
876 INLINE uint OPER_AL_8(void);
877 INLINE uint OPER_AL_16(void);
878 INLINE uint OPER_AL_32(void);
879 INLINE uint OPER_PCDI_8(void);
880 INLINE uint OPER_PCDI_16(void);
881 INLINE uint OPER_PCDI_32(void);
882 INLINE uint OPER_PCIX_8(void);
883 INLINE uint OPER_PCIX_16(void);
884 INLINE uint OPER_PCIX_32(void);
886 /* Stack operations */
887 INLINE void m68ki_push_16(uint value);
888 INLINE void m68ki_push_32(uint value);
889 INLINE uint m68ki_pull_16(void);
890 INLINE uint m68ki_pull_32(void);
892 /* Program flow operations */
893 INLINE void m68ki_jump(uint new_pc);
894 INLINE void m68ki_jump_vector(uint vector);
895 INLINE void m68ki_branch_8(uint offset);
896 INLINE void m68ki_branch_16(uint offset);
897 INLINE void m68ki_branch_32(uint offset);
899 /* Status register operations. */
900 INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */
901 INLINE void m68ki_set_sm_flag(uint value); /* only bits 1 and 2 of value should be set */
902 INLINE void m68ki_set_ccr(uint value); /* set the condition code register */
903 INLINE void m68ki_set_sr(uint value); /* set the status register */
904 INLINE void m68ki_set_sr_noint(uint value); /* set the status register */
906 /* Exception processing */
907 INLINE uint m68ki_init_exception(void); /* Initial exception processing */
909 INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */
910 INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc);
912 INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector);
913 INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector);
914 INLINE void m68ki_stack_frame_0010(uint sr, uint vector);
915 INLINE void m68ki_stack_frame_1000(uint pc, uint sr, uint vector);
916 INLINE void m68ki_stack_frame_1010(uint sr, uint vector, uint pc);
917 INLINE void m68ki_stack_frame_1011(uint sr, uint vector, uint pc);
919 INLINE void m68ki_exception_trap(uint vector);
920 INLINE void m68ki_exception_trapN(uint vector);
921 INLINE void m68ki_exception_trace(void);
922 INLINE void m68ki_exception_privilege_violation(void);
923 INLINE void m68ki_exception_bus_error(void);
924 INLINE void m68ki_exception_1010(void);
925 INLINE void m68ki_exception_1111(void);
926 INLINE void m68ki_exception_illegal(void);
927 INLINE void m68ki_exception_format_error(void);
928 INLINE void m68ki_exception_address_error(void);
929 INLINE void m68ki_exception_interrupt(uint int_level);
930 INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */
932 /* quick disassembly (used for logging) */
933 char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type);
936 /* ======================================================================== */
937 /* =========================== UTILITY FUNCTIONS ========================== */
938 /* ======================================================================== */
941 /* ---------------------------- Read Immediate ---------------------------- */
943 /* Handles all immediate reads, does address error check, function code setting,
944 * and prefetching if they are enabled in m68kconf.h
945 */
946 INLINE uint m68ki_read_imm_16(void)
947 {
948 m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
949 m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */
950 #if M68K_EMULATE_PREFETCH
951 if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
952 {
953 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
954 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
955 }
956 REG_PC += 2;
957 return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3));
958 #else
959 REG_PC += 2;
960 return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2));
961 #endif /* M68K_EMULATE_PREFETCH */
962 }
963 INLINE uint m68ki_read_imm_32(void)
964 {
965 #if M68K_EMULATE_PREFETCH
966 uint temp_val;
968 m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
969 m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */
970 if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
971 {
972 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
973 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
974 }
975 temp_val = CPU_PREF_DATA;
976 REG_PC += 2;
977 if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
978 {
979 CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
980 CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR));
981 temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16));
982 }
983 REG_PC += 2;
985 return temp_val;
986 #else
987 m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
988 m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */
989 REG_PC += 4;
990 return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4));
991 #endif /* M68K_EMULATE_PREFETCH */
992 }
996 /* ------------------------- Top level read/write ------------------------- */
998 /* Handles all memory accesses (except for immediate reads if they are
999 * configured to use separate functions in m68kconf.h).
1000 * All memory accesses must go through these top level functions.
1001 * These functions will also check for address error and set the function
1002 * code if they are enabled in m68kconf.h.
1003 */
1004 INLINE uint m68ki_read_8_fc(uint address, uint fc)
1005 {
1006 m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1007 return m68k_read_memory_8(ADDRESS_68K(address));
1008 }
1009 INLINE uint m68ki_read_16_fc(uint address, uint fc)
1010 {
1011 m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1012 m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1013 return m68k_read_memory_16(ADDRESS_68K(address));
1014 }
1015 INLINE uint m68ki_read_32_fc(uint address, uint fc)
1016 {
1017 m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1018 m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1019 return m68k_read_memory_32(ADDRESS_68K(address));
1020 }
1022 INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
1023 {
1024 m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1025 m68k_write_memory_8(ADDRESS_68K(address), value);
1026 }
1027 INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
1028 {
1029 m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1030 m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1031 m68k_write_memory_16(ADDRESS_68K(address), value);
1032 }
1033 INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
1034 {
1035 m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
1036 m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */
1037 m68k_write_memory_32(ADDRESS_68K(address), value);
1038 }
1042 /* --------------------- Effective Address Calculation -------------------- */
1044 /* The program counter relative addressing modes cause operands to be
1045 * retrieved from program space, not data space.
1046 */
1047 INLINE uint m68ki_get_ea_pcdi(void)
1048 {
1049 uint old_pc = REG_PC;
1050 m68ki_use_program_space(); /* auto-disable */
1051 return old_pc + MAKE_INT_16(m68ki_read_imm_16());
1052 }
1055 INLINE uint m68ki_get_ea_pcix(void)
1056 {
1057 m68ki_use_program_space(); /* auto-disable */
1058 return m68ki_get_ea_ix(REG_PC);
1059 }
1061 /* Indexed addressing modes are encoded as follows:
1062 *
1063 * Base instruction format:
1064 * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0
1065 * x x x x x x x x x x | 1 1 0 | BASE REGISTER (An)
1066 *
1067 * Base instruction format for destination EA in move instructions:
1068 * F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0
1069 * x x x x | BASE REG | 1 1 0 | X X X X X X (An)
1070 *
1071 * Brief extension format:
1072 * F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0
1073 * D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT
1074 *
1075 * Full extension format:
1076 * F E D C B A 9 8 7 6 5 4 3 2 1 0
1077 * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS
1078 * BASE DISPLACEMENT (0, 16, 32 bit) (bd)
1079 * OUTER DISPLACEMENT (0, 16, 32 bit) (od)
1080 *
1081 * D/A: 0 = Dn, 1 = An (Xn)
1082 * W/L: 0 = W (sign extend), 1 = L (.SIZE)
1083 * SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE)
1084 * BS: 0=add base reg, 1=suppress base reg (An suppressed)
1085 * IS: 0=add index, 1=suppress index (Xn suppressed)
1086 * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd)
1087 *
1088 * IS I/IS Operation
1089 * 0 000 No Memory Indirect
1090 * 0 001 indir prex with null outer
1091 * 0 010 indir prex with word outer
1092 * 0 011 indir prex with long outer
1093 * 0 100 reserved
1094 * 0 101 indir postx with null outer
1095 * 0 110 indir postx with word outer
1096 * 0 111 indir postx with long outer
1097 * 1 000 no memory indirect
1098 * 1 001 mem indir with null outer
1099 * 1 010 mem indir with word outer
1100 * 1 011 mem indir with long outer
1101 * 1 100-111 reserved
1102 */
1103 INLINE uint m68ki_get_ea_ix(uint An)
1104 {
1105 /* An = base register */
1106 uint extension = m68ki_read_imm_16();
1107 uint Xn = 0; /* Index register */
1108 uint bd = 0; /* Base Displacement */
1109 uint od = 0; /* Outer Displacement */
1111 if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
1112 {
1113 /* Calculate index */
1114 Xn = REG_DA[extension>>12]; /* Xn */
1115 if(!BIT_B(extension)) /* W/L */
1116 Xn = MAKE_INT_16(Xn);
1118 /* Add base register and displacement and return */
1119 return An + Xn + MAKE_INT_8(extension);
1120 }
1122 /* Brief extension format */
1123 if(!BIT_8(extension))
1124 {
1125 /* Calculate index */
1126 Xn = REG_DA[extension>>12]; /* Xn */
1127 if(!BIT_B(extension)) /* W/L */
1128 Xn = MAKE_INT_16(Xn);
1129 /* Add scale if proper CPU type */
1130 if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
1131 Xn <<= (extension>>9) & 3; /* SCALE */
1133 /* Add base register and displacement and return */
1134 return An + Xn + MAKE_INT_8(extension);
1135 }
1137 /* Full extension format */
1139 USE_CYCLES(m68ki_ea_idx_cycle_table[extension&0x3f]);
1141 /* Check if base register is present */
1142 if(BIT_7(extension)) /* BS */
1143 An = 0; /* An */
1145 /* Check if index is present */
1146 if(!BIT_6(extension)) /* IS */
1147 {
1148 Xn = REG_DA[extension>>12]; /* Xn */
1149 if(!BIT_B(extension)) /* W/L */
1150 Xn = MAKE_INT_16(Xn);
1151 Xn <<= (extension>>9) & 3; /* SCALE */
1152 }
1154 /* Check if base displacement is present */
1155 if(BIT_5(extension)) /* BD SIZE */
1156 bd = BIT_4(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
1158 /* If no indirect action, we are done */
1159 if(!(extension&7)) /* No Memory Indirect */
1160 return An + bd + Xn;
1162 /* Check if outer displacement is present */
1163 if(BIT_1(extension)) /* I/IS: od */
1164 od = BIT_0(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16());
1166 /* Postindex */
1167 if(BIT_2(extension)) /* I/IS: 0 = preindex, 1 = postindex */
1168 return m68ki_read_32(An + bd) + Xn + od;
1170 /* Preindex */
1171 return m68ki_read_32(An + bd + Xn) + od;
1172 }
1175 /* Fetch operands */
1176 INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); }
1177 INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);}
1178 INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);}
1179 INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); }
1180 INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);}
1181 INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);}
1182 INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); }
1183 INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);}
1184 INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);}
1185 INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); }
1186 INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);}
1187 INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);}
1188 INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); }
1189 INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);}
1190 INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);}
1192 INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); }
1193 INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);}
1194 INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);}
1195 INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); }
1196 INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);}
1197 INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);}
1198 INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); }
1199 INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);}
1200 INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);}
1201 INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); }
1202 INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);}
1203 INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);}
1204 INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); }
1205 INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);}
1206 INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);}
1208 INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); }
1209 INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); }
1211 INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); }
1212 INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);}
1213 INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);}
1214 INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); }
1215 INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);}
1216 INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);}
1217 INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); }
1218 INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);}
1219 INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);}
1220 INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); }
1221 INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);}
1222 INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);}
1226 /* ---------------------------- Stack Functions --------------------------- */
1228 /* Push/pull data from the stack */
1229 INLINE void m68ki_push_16(uint value)
1230 {
1231 REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1232 m68ki_write_16(REG_SP, value);
1233 }
1235 INLINE void m68ki_push_32(uint value)
1236 {
1237 REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1238 m68ki_write_32(REG_SP, value);
1239 }
1241 INLINE uint m68ki_pull_16(void)
1242 {
1243 REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1244 return m68ki_read_16(REG_SP-2);
1245 }
1247 INLINE uint m68ki_pull_32(void)
1248 {
1249 REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1250 return m68ki_read_32(REG_SP-4);
1251 }
1254 /* Increment/decrement the stack as if doing a push/pull but
1255 * don't do any memory access.
1256 */
1257 INLINE void m68ki_fake_push_16(void)
1258 {
1259 REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1260 }
1262 INLINE void m68ki_fake_push_32(void)
1263 {
1264 REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1265 }
1267 INLINE void m68ki_fake_pull_16(void)
1268 {
1269 REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1270 }
1272 INLINE void m68ki_fake_pull_32(void)
1273 {
1274 REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1275 }
1278 /* ----------------------------- Program Flow ----------------------------- */
1280 /* Jump to a new program location or vector.
1281 * These functions will also call the pc_changed callback if it was enabled
1282 * in m68kconf.h.
1283 */
1284 INLINE void m68ki_jump(uint new_pc)
1285 {
1286 REG_PC = new_pc;
1287 m68ki_pc_changed(REG_PC);
1288 }
1290 INLINE void m68ki_jump_vector(uint vector)
1291 {
1292 REG_PC = (vector<<2) + REG_VBR;
1293 REG_PC = m68ki_read_data_32(REG_PC);
1294 m68ki_pc_changed(REG_PC);
1295 }
1298 /* Branch to a new memory location.
1299 * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h.
1300 * So far I've found no problems with not calling pc_changed for 8 or 16
1301 * bit branches.
1302 */
1303 INLINE void m68ki_branch_8(uint offset)
1304 {
1305 REG_PC += MAKE_INT_8(offset);
1306 }
1308 INLINE void m68ki_branch_16(uint offset)
1309 {
1310 REG_PC += MAKE_INT_16(offset);
1311 }
1313 INLINE void m68ki_branch_32(uint offset)
1314 {
1315 REG_PC += offset;
1316 m68ki_pc_changed(REG_PC);
1317 }
1321 /* ---------------------------- Status Register --------------------------- */
1323 /* Set the S flag and change the active stack pointer.
1324 * Note that value MUST be 4 or 0.
1325 */
1326 INLINE void m68ki_set_s_flag(uint value)
1327 {
1328 /* Backup the old stack pointer */
1329 REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
1330 /* Set the S flag */
1331 FLAG_S = value;
1332 /* Set the new stack pointer */
1333 REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];
1334 }
1336 /* Set the S and M flags and change the active stack pointer.
1337 * Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M).
1338 */
1339 INLINE void m68ki_set_sm_flag(uint value)
1340 {
1341 /* Backup the old stack pointer */
1342 REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
1343 /* Set the S and M flags */
1344 FLAG_S = value & SFLAG_SET;
1345 FLAG_M = value & MFLAG_SET;
1346 /* Set the new stack pointer */
1347 REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)];
1348 }
1351 /* Set the condition code register */
1352 INLINE void m68ki_set_ccr(uint value)
1353 {
1354 FLAG_X = BIT_4(value) << 4;
1355 FLAG_N = BIT_3(value) << 4;
1356 FLAG_Z = !BIT_2(value);
1357 FLAG_V = BIT_1(value) << 6;
1358 FLAG_C = BIT_0(value) << 8;
1359 }
1361 /* Set the status register but don't check for interrupts */
1362 INLINE void m68ki_set_sr_noint(uint value)
1363 {
1364 /* Mask out the "unimplemented" bits */
1365 value &= CPU_SR_MASK;
1367 /* Now set the status register */
1368 FLAG_T1 = BIT_F(value);
1369 FLAG_T0 = BIT_E(value);
1370 FLAG_INT_MASK = value & 0x0700;
1371 m68ki_set_ccr(value);
1372 m68ki_set_sm_flag((value >> 11) & 6);
1373 }
1375 /* Set the status register and check for interrupts */
1376 INLINE void m68ki_set_sr(uint value)
1377 {
1378 m68ki_set_sr_noint(value);
1379 m68ki_check_interrupts();
1380 }
1383 /* ------------------------- Exception Processing ------------------------- */
1385 /* Initiate exception processing */
1386 INLINE uint m68ki_init_exception(void)
1387 {
1388 /* Save the old status register */
1389 uint sr = m68ki_get_sr();
1391 /* Turn off trace flag, clear pending traces */
1392 FLAG_T1 = FLAG_T0 = 0;
1393 m68ki_clear_trace();
1394 /* Enter supervisor mode */
1395 m68ki_set_s_flag(SFLAG_SET);
1397 return sr;
1398 }
1400 /* 3 word stack frame (68000 only) */
1401 INLINE void m68ki_stack_frame_3word(uint pc, uint sr)
1402 {
1403 m68ki_push_32(pc);
1404 m68ki_push_16(sr);
1405 }
1407 /* Format 0 stack frame.
1408 * This is the standard stack frame for 68010+.
1409 */
1410 INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector)
1411 {
1412 /* Stack a 3-word frame if we are 68000 */
1413 if(CPU_TYPE == CPU_TYPE_000)
1414 {
1415 m68ki_stack_frame_3word(pc, sr);
1416 return;
1417 }
1418 m68ki_push_16(vector<<2);
1419 m68ki_push_32(pc);
1420 m68ki_push_16(sr);
1421 }
1423 /* Format 1 stack frame (68020).
1424 * For 68020, this is the 4 word throwaway frame.
1425 */
1426 INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)
1427 {
1428 m68ki_push_16(0x1000 | (vector<<2));
1429 m68ki_push_32(pc);
1430 m68ki_push_16(sr);
1431 }
1433 /* Format 2 stack frame.
1434 * This is used only by 68020 for trap exceptions.
1435 */
1436 INLINE void m68ki_stack_frame_0010(uint sr, uint vector)
1437 {
1438 m68ki_push_32(REG_PPC);
1439 m68ki_push_16(0x2000 | (vector<<2));
1440 m68ki_push_32(REG_PC);
1441 m68ki_push_16(sr);
1442 }
1445 /* Bus error stack frame (68000 only).
1446 */
1447 INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc)
1448 {
1449 m68ki_push_32(pc);
1450 m68ki_push_16(sr);
1451 m68ki_push_16(REG_IR);
1452 m68ki_push_32(address); /* access address */
1453 /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC
1454 * R/W 0 = write, 1 = read
1455 * I/N 0 = instruction, 1 = not
1456 * FC 3-bit function code
1457 */
1458 m68ki_push_16(((!write)<<4) | ((!instruction)<<3) | fc);
1459 }
1461 /* Format 8 stack frame (68010).
1462 * 68010 only. This is the 29 word bus/address error frame.
1463 */
1464 void m68ki_stack_frame_1000(uint pc, uint sr, uint vector)
1465 {
1466 /* VERSION
1467 * NUMBER
1468 * INTERNAL INFORMATION, 16 WORDS
1469 */
1470 m68ki_fake_push_32();
1471 m68ki_fake_push_32();
1472 m68ki_fake_push_32();
1473 m68ki_fake_push_32();
1474 m68ki_fake_push_32();
1475 m68ki_fake_push_32();
1476 m68ki_fake_push_32();
1477 m68ki_fake_push_32();
1479 /* INSTRUCTION INPUT BUFFER */
1480 m68ki_push_16(0);
1482 /* UNUSED, RESERVED (not written) */
1483 m68ki_fake_push_16();
1485 /* DATA INPUT BUFFER */
1486 m68ki_push_16(0);
1488 /* UNUSED, RESERVED (not written) */
1489 m68ki_fake_push_16();
1491 /* DATA OUTPUT BUFFER */
1492 m68ki_push_16(0);
1494 /* UNUSED, RESERVED (not written) */
1495 m68ki_fake_push_16();
1497 /* FAULT ADDRESS */
1498 m68ki_push_32(0);
1500 /* SPECIAL STATUS WORD */
1501 m68ki_push_16(0);
1503 /* 1000, VECTOR OFFSET */
1504 m68ki_push_16(0x8000 | (vector<<2));
1506 /* PROGRAM COUNTER */
1507 m68ki_push_32(pc);
1509 /* STATUS REGISTER */
1510 m68ki_push_16(sr);
1511 }
1513 /* Format A stack frame (short bus fault).
1514 * This is used only by 68020 for bus fault and address error
1515 * if the error happens at an instruction boundary.
1516 * PC stacked is address of next instruction.
1517 */
1518 void m68ki_stack_frame_1010(uint sr, uint vector, uint pc)
1519 {
1520 /* INTERNAL REGISTER */
1521 m68ki_push_16(0);
1523 /* INTERNAL REGISTER */
1524 m68ki_push_16(0);
1526 /* DATA OUTPUT BUFFER (2 words) */
1527 m68ki_push_32(0);
1529 /* INTERNAL REGISTER */
1530 m68ki_push_16(0);
1532 /* INTERNAL REGISTER */
1533 m68ki_push_16(0);
1535 /* DATA CYCLE FAULT ADDRESS (2 words) */
1536 m68ki_push_32(0);
1538 /* INSTRUCTION PIPE STAGE B */
1539 m68ki_push_16(0);
1541 /* INSTRUCTION PIPE STAGE C */
1542 m68ki_push_16(0);
1544 /* SPECIAL STATUS REGISTER */
1545 m68ki_push_16(0);
1547 /* INTERNAL REGISTER */
1548 m68ki_push_16(0);
1550 /* 1010, VECTOR OFFSET */
1551 m68ki_push_16(0xa000 | (vector<<2));
1553 /* PROGRAM COUNTER */
1554 m68ki_push_32(pc);
1556 /* STATUS REGISTER */
1557 m68ki_push_16(sr);
1558 }
1560 /* Format B stack frame (long bus fault).
1561 * This is used only by 68020 for bus fault and address error
1562 * if the error happens during instruction execution.
1563 * PC stacked is address of instruction in progress.
1564 */
1565 void m68ki_stack_frame_1011(uint sr, uint vector, uint pc)
1566 {
1567 /* INTERNAL REGISTERS (18 words) */
1568 m68ki_push_32(0);
1569 m68ki_push_32(0);
1570 m68ki_push_32(0);
1571 m68ki_push_32(0);
1572 m68ki_push_32(0);
1573 m68ki_push_32(0);
1574 m68ki_push_32(0);
1575 m68ki_push_32(0);
1576 m68ki_push_32(0);
1578 /* VERSION# (4 bits), INTERNAL INFORMATION */
1579 m68ki_push_16(0);
1581 /* INTERNAL REGISTERS (3 words) */
1582 m68ki_push_32(0);
1583 m68ki_push_16(0);
1585 /* DATA INTPUT BUFFER (2 words) */
1586 m68ki_push_32(0);
1588 /* INTERNAL REGISTERS (2 words) */
1589 m68ki_push_32(0);
1591 /* STAGE B ADDRESS (2 words) */
1592 m68ki_push_32(0);
1594 /* INTERNAL REGISTER (4 words) */
1595 m68ki_push_32(0);
1596 m68ki_push_32(0);
1598 /* DATA OUTPUT BUFFER (2 words) */
1599 m68ki_push_32(0);
1601 /* INTERNAL REGISTER */
1602 m68ki_push_16(0);
1604 /* INTERNAL REGISTER */
1605 m68ki_push_16(0);
1607 /* DATA CYCLE FAULT ADDRESS (2 words) */
1608 m68ki_push_32(0);
1610 /* INSTRUCTION PIPE STAGE B */
1611 m68ki_push_16(0);
1613 /* INSTRUCTION PIPE STAGE C */
1614 m68ki_push_16(0);
1616 /* SPECIAL STATUS REGISTER */
1617 m68ki_push_16(0);
1619 /* INTERNAL REGISTER */
1620 m68ki_push_16(0);
1622 /* 1011, VECTOR OFFSET */
1623 m68ki_push_16(0xb000 | (vector<<2));
1625 /* PROGRAM COUNTER */
1626 m68ki_push_32(pc);
1628 /* STATUS REGISTER */
1629 m68ki_push_16(sr);
1630 }
1633 /* Used for Group 2 exceptions.
1634 * These stack a type 2 frame on the 020.
1635 */
1636 INLINE void m68ki_exception_trap(uint vector)
1637 {
1638 uint sr = m68ki_init_exception();
1640 if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
1641 m68ki_stack_frame_0000(REG_PC, sr, vector);
1642 else
1643 m68ki_stack_frame_0010(sr, vector);
1645 m68ki_jump_vector(vector);
1647 /* Use up some clock cycles */
1648 USE_CYCLES(CYC_EXCEPTION[vector]);
1649 }
1651 /* Trap#n stacks a 0 frame but behaves like group2 otherwise */
1652 INLINE void m68ki_exception_trapN(uint vector)
1653 {
1654 uint sr = m68ki_init_exception();
1655 m68ki_stack_frame_0000(REG_PC, sr, vector);
1656 m68ki_jump_vector(vector);
1658 /* Use up some clock cycles */
1659 USE_CYCLES(CYC_EXCEPTION[vector]);
1660 }
1662 /* Exception for trace mode */
1663 INLINE void m68ki_exception_trace(void)
1664 {
1665 uint sr = m68ki_init_exception();
1667 if(CPU_TYPE_IS_010_LESS(CPU_TYPE))
1668 m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE);
1669 else
1670 m68ki_stack_frame_0010(sr, EXCEPTION_TRACE);
1672 m68ki_jump_vector(EXCEPTION_TRACE);
1674 /* Trace nullifies a STOP instruction */
1675 CPU_STOPPED &= ~STOP_LEVEL_STOP;
1677 /* Use up some clock cycles */
1678 USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]);
1679 }
1681 /* Exception for privilege violation */
1682 INLINE void m68ki_exception_privilege_violation(void)
1683 {
1684 uint sr = m68ki_init_exception();
1685 m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_PRIVILEGE_VIOLATION);
1686 m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION);
1688 /* Use up some clock cycles and undo the instruction's cycles */
1689 USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]);
1690 }
1692 /* Exception for bus error */
1693 INLINE void m68ki_exception_bus_error(void)
1694 {
1695 BUS_ERROR_OCCURRED = 1;
1696 /* Use up some clock cycles and undo the instruction's cycles */
1697 USE_CYCLES(CYC_EXCEPTION[EXCEPTION_BUS_ERROR] - CYC_INSTRUCTION[REG_IR]);
1698 }
1700 INLINE void m68ki_jump_bus_error_vector(void)
1701 {
1702 uint sr = m68ki_init_exception();
1703 m68ki_stack_frame_1000(REG_PPC, sr, EXCEPTION_BUS_ERROR);
1704 m68ki_jump_vector(EXCEPTION_BUS_ERROR);
1705 }
1707 /* Exception for A-Line instructions */
1708 INLINE void m68ki_exception_1010(void)
1709 {
1710 uint sr;
1711 #if M68K_LOG_1010_1111 == OPT_ON
1712 M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n",
1713 m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
1714 m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));
1715 #endif
1717 sr = m68ki_init_exception();
1718 m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1010);
1719 m68ki_jump_vector(EXCEPTION_1010);
1721 /* Use up some clock cycles and undo the instruction's cycles */
1722 USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]);
1723 }
1725 /* Exception for F-Line instructions */
1726 INLINE void m68ki_exception_1111(void)
1727 {
1728 uint sr;
1730 #if M68K_LOG_1010_1111 == OPT_ON
1731 M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n",
1732 m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
1733 m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));
1734 #endif
1736 sr = m68ki_init_exception();
1737 m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1111);
1738 m68ki_jump_vector(EXCEPTION_1111);
1740 /* Use up some clock cycles and undo the instruction's cycles */
1741 USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]);
1742 }
1744 /* Exception for illegal instructions */
1745 INLINE void m68ki_exception_illegal(void)
1746 {
1747 uint sr;
1749 M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n",
1750 m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR,
1751 m68ki_disassemble_quick(ADDRESS_68K(REG_PPC))));
1753 sr = m68ki_init_exception();
1754 m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_ILLEGAL_INSTRUCTION);
1755 m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION);
1757 /* Use up some clock cycles and undo the instruction's cycles */
1758 USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]);
1759 }
1761 /* Exception for format errror in RTE */
1762 INLINE void m68ki_exception_format_error(void)
1763 {
1764 uint sr = m68ki_init_exception();
1765 m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR);
1766 m68ki_jump_vector(EXCEPTION_FORMAT_ERROR);
1768 /* Use up some clock cycles and undo the instruction's cycles */
1769 USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]);
1770 }
1772 /* Exception for address error */
1773 INLINE void m68ki_exception_address_error(void)
1774 {
1775 /* Not emulated yet */
1776 }
1779 /* Service an interrupt request and start exception processing */
1780 void m68ki_exception_interrupt(uint int_level)
1781 {
1782 uint vector;
1783 uint sr;
1784 uint new_pc;
1786 /* Turn off the stopped state */
1787 CPU_STOPPED &= ~STOP_LEVEL_STOP;
1789 /* If we are halted, don't do anything */
1790 if(CPU_STOPPED)
1791 return;
1793 /* Acknowledge the interrupt */
1794 vector = m68ki_int_ack(int_level);
1796 /* Get the interrupt vector */
1797 if(vector == M68K_INT_ACK_AUTOVECTOR)
1798 /* Use the autovectors. This is the most commonly used implementation */
1799 vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
1800 else if(vector == M68K_INT_ACK_SPURIOUS)
1801 /* Called if no devices respond to the interrupt acknowledge */
1802 vector = EXCEPTION_SPURIOUS_INTERRUPT;
1803 else if(vector > 255)
1804 {
1805 M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n",
1806 m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector));
1807 return;
1808 }
1810 /* Start exception processing */
1811 sr = m68ki_init_exception();
1813 /* Set the interrupt mask to the level of the one being serviced */
1814 FLAG_INT_MASK = int_level<<8;
1816 /* Get the new PC */
1817 new_pc = m68ki_read_data_32((vector<<2) + REG_VBR);
1819 /* If vector is uninitialized, call the uninitialized interrupt vector */
1820 if(new_pc == 0)
1821 new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR);
1823 /* Generate a stack frame */
1824 m68ki_stack_frame_0000(REG_PC, sr, vector);
1825 if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
1826 {
1827 /* Create throwaway frame */
1828 m68ki_set_sm_flag(FLAG_S); /* clear M */
1829 sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */
1830 m68ki_stack_frame_0001(REG_PC, sr, vector);
1831 }
1833 m68ki_jump(new_pc);
1835 /* Defer cycle counting until later */
1836 CPU_INT_CYCLES += CYC_EXCEPTION[vector];
1838 #if !M68K_EMULATE_INT_ACK
1839 /* Automatically clear IRQ if we are not using an acknowledge scheme */
1840 CPU_INT_LEVEL = 0;
1841 #endif /* M68K_EMULATE_INT_ACK */
1842 }
1845 /* ASG: Check for interrupts */
1846 INLINE void m68ki_check_interrupts(void)
1847 {
1848 if(CPU_INT_LEVEL > FLAG_INT_MASK)
1849 m68ki_exception_interrupt(CPU_INT_LEVEL>>8);
1850 }
1854 /* ======================================================================== */
1855 /* ============================== END OF FILE ============================= */
1856 /* ======================================================================== */
1858 #endif /* M68KCPU__HEADER */