1.1 diff -r 000000000000 -r 8bf1bf91a36d src/musashi/m68kcpu.h 1.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 +++ b/src/musashi/m68kcpu.h Sat Nov 27 01:13:12 2010 +0000 1.4 @@ -0,0 +1,1838 @@ 1.5 +#include <stdio.h> 1.6 +/* ======================================================================== */ 1.7 +/* ========================= LICENSING & COPYRIGHT ======================== */ 1.8 +/* ======================================================================== */ 1.9 +/* 1.10 + * MUSASHI 1.11 + * Version 3.3 1.12 + * 1.13 + * A portable Motorola M680x0 processor emulation engine. 1.14 + * Copyright 1998-2001 Karl Stenerud. All rights reserved. 1.15 + * 1.16 + * This code may be freely used for non-commercial purposes as long as this 1.17 + * copyright notice remains unaltered in the source code and any binary files 1.18 + * containing this code in compiled form. 1.19 + * 1.20 + * All other lisencing terms must be negotiated with the author 1.21 + * (Karl Stenerud). 1.22 + * 1.23 + * The latest version of this code can be obtained at: 1.24 + * http://kstenerud.cjb.net 1.25 + */ 1.26 + 1.27 + 1.28 + 1.29 + 1.30 +#ifndef M68KCPU__HEADER 1.31 +#define M68KCPU__HEADER 1.32 + 1.33 +#include "m68k.h" 1.34 +#include <limits.h> 1.35 + 1.36 +#if M68K_EMULATE_ADDRESS_ERROR 1.37 +#include <setjmp.h> 1.38 +#endif /* M68K_EMULATE_ADDRESS_ERROR */ 1.39 + 1.40 +/* ======================================================================== */ 1.41 +/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */ 1.42 +/* ======================================================================== */ 1.43 + 1.44 +/* Check for > 32bit sizes */ 1.45 +#if UINT_MAX > 0xffffffff 1.46 + #define M68K_INT_GT_32_BIT 1 1.47 +#endif 1.48 + 1.49 +/* Data types used in this emulation core */ 1.50 +#undef sint8 1.51 +#undef sint16 1.52 +#undef sint32 1.53 +#undef sint64 1.54 +#undef uint8 1.55 +#undef uint16 1.56 +#undef uint32 1.57 +#undef uint64 1.58 +#undef sint 1.59 +#undef uint 1.60 + 1.61 +#define sint8 signed char /* ASG: changed from char to signed char */ 1.62 +#define sint16 signed short 1.63 +#define sint32 signed long 1.64 +#define uint8 unsigned char 1.65 +#define uint16 unsigned short 1.66 +#define uint32 unsigned long 1.67 + 1.68 +/* signed and unsigned int must be at least 32 bits wide */ 1.69 +#define sint signed int 1.70 +#define uint unsigned int 1.71 + 1.72 + 1.73 +#if M68K_USE_64_BIT 1.74 +#define sint64 signed long long 1.75 +#define uint64 unsigned long long 1.76 +#else 1.77 +#define sint64 sint32 1.78 +#define uint64 uint32 1.79 +#endif /* M68K_USE_64_BIT */ 1.80 + 1.81 + 1.82 + 1.83 +/* Allow for architectures that don't have 8-bit sizes */ 1.84 +#if UCHAR_MAX == 0xff 1.85 + #define MAKE_INT_8(A) (sint8)(A) 1.86 +#else 1.87 + #undef sint8 1.88 + #define sint8 signed int 1.89 + #undef uint8 1.90 + #define uint8 unsigned int 1.91 + INLINE sint MAKE_INT_8(uint value) 1.92 + { 1.93 + return (value & 0x80) ? value | ~0xff : value & 0xff; 1.94 + } 1.95 +#endif /* UCHAR_MAX == 0xff */ 1.96 + 1.97 + 1.98 +/* Allow for architectures that don't have 16-bit sizes */ 1.99 +#if USHRT_MAX == 0xffff 1.100 + #define MAKE_INT_16(A) (sint16)(A) 1.101 +#else 1.102 + #undef sint16 1.103 + #define sint16 signed int 1.104 + #undef uint16 1.105 + #define uint16 unsigned int 1.106 + INLINE sint MAKE_INT_16(uint value) 1.107 + { 1.108 + return (value & 0x8000) ? value | ~0xffff : value & 0xffff; 1.109 + } 1.110 +#endif /* USHRT_MAX == 0xffff */ 1.111 + 1.112 + 1.113 +/* Allow for architectures that don't have 32-bit sizes */ 1.114 +#if ULONG_MAX == 0xffffffff 1.115 + #define MAKE_INT_32(A) (sint32)(A) 1.116 +#else 1.117 + #undef sint32 1.118 + #define sint32 signed int 1.119 + #undef uint32 1.120 + #define uint32 unsigned int 1.121 + INLINE sint MAKE_INT_32(uint value) 1.122 + { 1.123 + return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; 1.124 + } 1.125 +#endif /* ULONG_MAX == 0xffffffff */ 1.126 + 1.127 + 1.128 + 1.129 + 1.130 +/* ======================================================================== */ 1.131 +/* ============================ GENERAL DEFINES =========================== */ 1.132 +/* ======================================================================== */ 1.133 + 1.134 +/* Exception Vectors handled by emulation */ 1.135 +#define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */ 1.136 +#define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */ 1.137 +#define EXCEPTION_ILLEGAL_INSTRUCTION 4 1.138 +#define EXCEPTION_ZERO_DIVIDE 5 1.139 +#define EXCEPTION_CHK 6 1.140 +#define EXCEPTION_TRAPV 7 1.141 +#define EXCEPTION_PRIVILEGE_VIOLATION 8 1.142 +#define EXCEPTION_TRACE 9 1.143 +#define EXCEPTION_1010 10 1.144 +#define EXCEPTION_1111 11 1.145 +#define EXCEPTION_FORMAT_ERROR 14 1.146 +#define EXCEPTION_UNINITIALIZED_INTERRUPT 15 1.147 +#define EXCEPTION_SPURIOUS_INTERRUPT 24 1.148 +#define EXCEPTION_INTERRUPT_AUTOVECTOR 24 1.149 +#define EXCEPTION_TRAP_BASE 32 1.150 + 1.151 +/* Function codes set by CPU during data/address bus activity */ 1.152 +#define FUNCTION_CODE_USER_DATA 1 1.153 +#define FUNCTION_CODE_USER_PROGRAM 2 1.154 +#define FUNCTION_CODE_SUPERVISOR_DATA 5 1.155 +#define FUNCTION_CODE_SUPERVISOR_PROGRAM 6 1.156 +#define FUNCTION_CODE_CPU_SPACE 7 1.157 + 1.158 +/* CPU types for deciding what to emulate */ 1.159 +#define CPU_TYPE_000 1 1.160 +#define CPU_TYPE_010 2 1.161 +#define CPU_TYPE_EC020 4 1.162 +#define CPU_TYPE_020 8 1.163 + 1.164 +/* Different ways to stop the CPU */ 1.165 +#define STOP_LEVEL_STOP 1 1.166 +#define STOP_LEVEL_HALT 2 1.167 + 1.168 +#ifndef NULL 1.169 +#define NULL ((void*)0) 1.170 +#endif 1.171 + 1.172 +/* ======================================================================== */ 1.173 +/* ================================ MACROS ================================ */ 1.174 +/* ======================================================================== */ 1.175 + 1.176 + 1.177 +/* ---------------------------- General Macros ---------------------------- */ 1.178 + 1.179 +/* Bit Isolation Macros */ 1.180 +#define BIT_0(A) ((A) & 0x00000001) 1.181 +#define BIT_1(A) ((A) & 0x00000002) 1.182 +#define BIT_2(A) ((A) & 0x00000004) 1.183 +#define BIT_3(A) ((A) & 0x00000008) 1.184 +#define BIT_4(A) ((A) & 0x00000010) 1.185 +#define BIT_5(A) ((A) & 0x00000020) 1.186 +#define BIT_6(A) ((A) & 0x00000040) 1.187 +#define BIT_7(A) ((A) & 0x00000080) 1.188 +#define BIT_8(A) ((A) & 0x00000100) 1.189 +#define BIT_9(A) ((A) & 0x00000200) 1.190 +#define BIT_A(A) ((A) & 0x00000400) 1.191 +#define BIT_B(A) ((A) & 0x00000800) 1.192 +#define BIT_C(A) ((A) & 0x00001000) 1.193 +#define BIT_D(A) ((A) & 0x00002000) 1.194 +#define BIT_E(A) ((A) & 0x00004000) 1.195 +#define BIT_F(A) ((A) & 0x00008000) 1.196 +#define BIT_10(A) ((A) & 0x00010000) 1.197 +#define BIT_11(A) ((A) & 0x00020000) 1.198 +#define BIT_12(A) ((A) & 0x00040000) 1.199 +#define BIT_13(A) ((A) & 0x00080000) 1.200 +#define BIT_14(A) ((A) & 0x00100000) 1.201 +#define BIT_15(A) ((A) & 0x00200000) 1.202 +#define BIT_16(A) ((A) & 0x00400000) 1.203 +#define BIT_17(A) ((A) & 0x00800000) 1.204 +#define BIT_18(A) ((A) & 0x01000000) 1.205 +#define BIT_19(A) ((A) & 0x02000000) 1.206 +#define BIT_1A(A) ((A) & 0x04000000) 1.207 +#define BIT_1B(A) ((A) & 0x08000000) 1.208 +#define BIT_1C(A) ((A) & 0x10000000) 1.209 +#define BIT_1D(A) ((A) & 0x20000000) 1.210 +#define BIT_1E(A) ((A) & 0x40000000) 1.211 +#define BIT_1F(A) ((A) & 0x80000000) 1.212 + 1.213 +/* Get the most significant bit for specific sizes */ 1.214 +#define GET_MSB_8(A) ((A) & 0x80) 1.215 +#define GET_MSB_9(A) ((A) & 0x100) 1.216 +#define GET_MSB_16(A) ((A) & 0x8000) 1.217 +#define GET_MSB_17(A) ((A) & 0x10000) 1.218 +#define GET_MSB_32(A) ((A) & 0x80000000) 1.219 +#if M68K_USE_64_BIT 1.220 +#define GET_MSB_33(A) ((A) & 0x100000000) 1.221 +#endif /* M68K_USE_64_BIT */ 1.222 + 1.223 +/* Isolate nibbles */ 1.224 +#define LOW_NIBBLE(A) ((A) & 0x0f) 1.225 +#define HIGH_NIBBLE(A) ((A) & 0xf0) 1.226 + 1.227 +/* These are used to isolate 8, 16, and 32 bit sizes */ 1.228 +#define MASK_OUT_ABOVE_2(A) ((A) & 3) 1.229 +#define MASK_OUT_ABOVE_8(A) ((A) & 0xff) 1.230 +#define MASK_OUT_ABOVE_16(A) ((A) & 0xffff) 1.231 +#define MASK_OUT_BELOW_2(A) ((A) & ~3) 1.232 +#define MASK_OUT_BELOW_8(A) ((A) & ~0xff) 1.233 +#define MASK_OUT_BELOW_16(A) ((A) & ~0xffff) 1.234 + 1.235 +/* No need to mask if we are 32 bit */ 1.236 +#if M68K_INT_GT_32BIT || M68K_USE_64_BIT 1.237 + #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff) 1.238 + #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff) 1.239 +#else 1.240 + #define MASK_OUT_ABOVE_32(A) (A) 1.241 + #define MASK_OUT_BELOW_32(A) 0 1.242 +#endif /* M68K_INT_GT_32BIT || M68K_USE_64_BIT */ 1.243 + 1.244 +/* Simulate address lines of 68k family */ 1.245 +#define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK) 1.246 + 1.247 + 1.248 +/* Shift & Rotate Macros. */ 1.249 +#define LSL(A, C) ((A) << (C)) 1.250 +#define LSR(A, C) ((A) >> (C)) 1.251 + 1.252 +/* Some > 32-bit optimizations */ 1.253 +#if M68K_INT_GT_32BIT 1.254 + /* Shift left and right */ 1.255 + #define LSR_32(A, C) ((A) >> (C)) 1.256 + #define LSL_32(A, C) ((A) << (C)) 1.257 +#else 1.258 + /* We have to do this because the morons at ANSI decided that shifts 1.259 + * by >= data size are undefined. 1.260 + */ 1.261 + #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) 1.262 + #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) 1.263 +#endif /* M68K_INT_GT_32BIT */ 1.264 + 1.265 +#if M68K_USE_64_BIT 1.266 + #define LSL_32_64(A, C) ((A) << (C)) 1.267 + #define LSR_32_64(A, C) ((A) >> (C)) 1.268 + #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C))) 1.269 + #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C))) 1.270 +#endif /* M68K_USE_64_BIT */ 1.271 + 1.272 +#define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C))) 1.273 +#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) 1.274 +#define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C))) 1.275 +#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) 1.276 +#define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C))) 1.277 +#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) 1.278 + 1.279 +#define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C))) 1.280 +#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) 1.281 +#define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C))) 1.282 +#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) 1.283 +#define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C))) 1.284 +#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) 1.285 + 1.286 + 1.287 + 1.288 +/* ------------------------------ CPU Access ------------------------------ */ 1.289 + 1.290 +/* Access the CPU registers */ 1.291 +#define CPU_TYPE m68ki_cpu.cpu_type 1.292 + 1.293 +#define REG_DA m68ki_cpu.dar /* easy access to data and address regs */ 1.294 +#define REG_D m68ki_cpu.dar 1.295 +#define REG_A (m68ki_cpu.dar+8) 1.296 +#define REG_PPC m68ki_cpu.ppc 1.297 +#define REG_PC m68ki_cpu.pc 1.298 +#define REG_SP_BASE m68ki_cpu.sp 1.299 +#define REG_USP m68ki_cpu.sp[0] 1.300 +#define REG_ISP m68ki_cpu.sp[4] 1.301 +#define REG_MSP m68ki_cpu.sp[6] 1.302 +#define REG_SP m68ki_cpu.dar[15] 1.303 +#define REG_VBR m68ki_cpu.vbr 1.304 +#define REG_SFC m68ki_cpu.sfc 1.305 +#define REG_DFC m68ki_cpu.dfc 1.306 +#define REG_CACR m68ki_cpu.cacr 1.307 +#define REG_CAAR m68ki_cpu.caar 1.308 +#define REG_IR m68ki_cpu.ir 1.309 + 1.310 +#define FLAG_T1 m68ki_cpu.t1_flag 1.311 +#define FLAG_T0 m68ki_cpu.t0_flag 1.312 +#define FLAG_S m68ki_cpu.s_flag 1.313 +#define FLAG_M m68ki_cpu.m_flag 1.314 +#define FLAG_X m68ki_cpu.x_flag 1.315 +#define FLAG_N m68ki_cpu.n_flag 1.316 +#define FLAG_Z m68ki_cpu.not_z_flag 1.317 +#define FLAG_V m68ki_cpu.v_flag 1.318 +#define FLAG_C m68ki_cpu.c_flag 1.319 +#define FLAG_INT_MASK m68ki_cpu.int_mask 1.320 + 1.321 +#define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */ 1.322 +#define CPU_INT_CYCLES m68ki_cpu.int_cycles /* ASG */ 1.323 +#define CPU_STOPPED m68ki_cpu.stopped 1.324 +#define CPU_PREF_ADDR m68ki_cpu.pref_addr 1.325 +#define CPU_PREF_DATA m68ki_cpu.pref_data 1.326 +#define CPU_ADDRESS_MASK m68ki_cpu.address_mask 1.327 +#define CPU_SR_MASK m68ki_cpu.sr_mask 1.328 + 1.329 +#define CYC_INSTRUCTION m68ki_cpu.cyc_instruction 1.330 +#define CYC_EXCEPTION m68ki_cpu.cyc_exception 1.331 +#define CYC_BCC_NOTAKE_B m68ki_cpu.cyc_bcc_notake_b 1.332 +#define CYC_BCC_NOTAKE_W m68ki_cpu.cyc_bcc_notake_w 1.333 +#define CYC_DBCC_F_NOEXP m68ki_cpu.cyc_dbcc_f_noexp 1.334 +#define CYC_DBCC_F_EXP m68ki_cpu.cyc_dbcc_f_exp 1.335 +#define CYC_SCC_R_FALSE m68ki_cpu.cyc_scc_r_false 1.336 +#define CYC_MOVEM_W m68ki_cpu.cyc_movem_w 1.337 +#define CYC_MOVEM_L m68ki_cpu.cyc_movem_l 1.338 +#define CYC_SHIFT m68ki_cpu.cyc_shift 1.339 +#define CYC_RESET m68ki_cpu.cyc_reset 1.340 + 1.341 + 1.342 +#define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback 1.343 +#define CALLBACK_BKPT_ACK m68ki_cpu.bkpt_ack_callback 1.344 +#define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback 1.345 +#define CALLBACK_PC_CHANGED m68ki_cpu.pc_changed_callback 1.346 +#define CALLBACK_SET_FC m68ki_cpu.set_fc_callback 1.347 +#define CALLBACK_INSTR_HOOK m68ki_cpu.instr_hook_callback 1.348 + 1.349 + 1.350 + 1.351 +/* ----------------------------- Configuration ---------------------------- */ 1.352 + 1.353 +/* These defines are dependant on the configuration defines in m68kconf.h */ 1.354 + 1.355 +/* Disable certain comparisons if we're not using all CPU types */ 1.356 +#if M68K_EMULATE_020 1.357 + #define CPU_TYPE_IS_020_PLUS(A) ((A) & CPU_TYPE_020) 1.358 + #define CPU_TYPE_IS_020_LESS(A) 1 1.359 +#else 1.360 + #define CPU_TYPE_IS_020_PLUS(A) 0 1.361 + #define CPU_TYPE_IS_020_LESS(A) 1 1.362 +#endif 1.363 + 1.364 +#if M68K_EMULATE_EC020 1.365 + #define CPU_TYPE_IS_EC020_PLUS(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020)) 1.366 + #define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_010 | CPU_TYPE_EC020)) 1.367 +#else 1.368 + #define CPU_TYPE_IS_EC020_PLUS(A) CPU_TYPE_IS_020_PLUS(A) 1.369 + #define CPU_TYPE_IS_EC020_LESS(A) CPU_TYPE_IS_020_LESS(A) 1.370 +#endif 1.371 + 1.372 +#if M68K_EMULATE_010 1.373 + #define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010) 1.374 + #define CPU_TYPE_IS_010_PLUS(A) ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020)) 1.375 + #define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_010)) 1.376 +#else 1.377 + #define CPU_TYPE_IS_010(A) 0 1.378 + #define CPU_TYPE_IS_010_PLUS(A) CPU_TYPE_IS_EC020_PLUS(A) 1.379 + #define CPU_TYPE_IS_010_LESS(A) CPU_TYPE_IS_EC020_LESS(A) 1.380 +#endif 1.381 + 1.382 +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 1.383 + #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020)) 1.384 +#else 1.385 + #define CPU_TYPE_IS_020_VARIANT(A) 0 1.386 +#endif 1.387 + 1.388 +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_010 1.389 + #define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000) 1.390 +#else 1.391 + #define CPU_TYPE_IS_000(A) 1 1.392 +#endif 1.393 + 1.394 + 1.395 +#if !M68K_SEPARATE_READS 1.396 +#define m68k_read_immediate_16(A) m68ki_read_program_16(A) 1.397 +#define m68k_read_immediate_32(A) m68ki_read_program_32(A) 1.398 + 1.399 +#define m68k_read_pcrelative_8(A) m68ki_read_program_8(A) 1.400 +#define m68k_read_pcrelative_16(A) m68ki_read_program_16(A) 1.401 +#define m68k_read_pcrelative_32(A) m68ki_read_program_32(A) 1.402 +#endif /* M68K_SEPARATE_READS */ 1.403 + 1.404 + 1.405 +/* Enable or disable callback functions */ 1.406 +#if M68K_EMULATE_INT_ACK 1.407 + #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER 1.408 + #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A) 1.409 + #else 1.410 + #define m68ki_int_ack(A) CALLBACK_INT_ACK(A) 1.411 + #endif 1.412 +#else 1.413 + /* Default action is to used autovector mode, which is most common */ 1.414 + #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR 1.415 +#endif /* M68K_EMULATE_INT_ACK */ 1.416 + 1.417 +#if M68K_EMULATE_BKPT_ACK 1.418 + #if M68K_EMULATE_BKPT_ACK == OPT_SPECIFY_HANDLER 1.419 + #define m68ki_bkpt_ack(A) M68K_BKPT_ACK_CALLBACK(A) 1.420 + #else 1.421 + #define m68ki_bkpt_ack(A) CALLBACK_BKPT_ACK(A) 1.422 + #endif 1.423 +#else 1.424 + #define m68ki_bkpt_ack(A) 1.425 +#endif /* M68K_EMULATE_BKPT_ACK */ 1.426 + 1.427 +#if M68K_EMULATE_RESET 1.428 + #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER 1.429 + #define m68ki_output_reset() M68K_RESET_CALLBACK() 1.430 + #else 1.431 + #define m68ki_output_reset() CALLBACK_RESET_INSTR() 1.432 + #endif 1.433 +#else 1.434 + #define m68ki_output_reset() 1.435 +#endif /* M68K_EMULATE_RESET */ 1.436 + 1.437 +#if M68K_INSTRUCTION_HOOK 1.438 + #if M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER 1.439 + #define m68ki_instr_hook() M68K_INSTRUCTION_CALLBACK() 1.440 + #else 1.441 + #define m68ki_instr_hook() CALLBACK_INSTR_HOOK() 1.442 + #endif 1.443 +#else 1.444 + #define m68ki_instr_hook() 1.445 +#endif /* M68K_INSTRUCTION_HOOK */ 1.446 + 1.447 +#if M68K_MONITOR_PC 1.448 + #if M68K_MONITOR_PC == OPT_SPECIFY_HANDLER 1.449 + #define m68ki_pc_changed(A) M68K_SET_PC_CALLBACK(ADDRESS_68K(A)) 1.450 + #else 1.451 + #define m68ki_pc_changed(A) CALLBACK_PC_CHANGED(ADDRESS_68K(A)) 1.452 + #endif 1.453 +#else 1.454 + #define m68ki_pc_changed(A) 1.455 +#endif /* M68K_MONITOR_PC */ 1.456 + 1.457 + 1.458 +/* Enable or disable function code emulation */ 1.459 +#if M68K_EMULATE_FC 1.460 + #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER 1.461 + #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A) 1.462 + #else 1.463 + #define m68ki_set_fc(A) CALLBACK_SET_FC(A) 1.464 + #endif 1.465 + #define m68ki_use_data_space() m68ki_address_space = FUNCTION_CODE_USER_DATA 1.466 + #define m68ki_use_program_space() m68ki_address_space = FUNCTION_CODE_USER_PROGRAM 1.467 + #define m68ki_get_address_space() m68ki_address_space 1.468 +#else 1.469 + #define m68ki_set_fc(A) 1.470 + #define m68ki_use_data_space() 1.471 + #define m68ki_use_program_space() 1.472 + #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA 1.473 +#endif /* M68K_EMULATE_FC */ 1.474 + 1.475 + 1.476 +/* Enable or disable trace emulation */ 1.477 +#if M68K_EMULATE_TRACE 1.478 + /* Initiates trace checking before each instruction (t1) */ 1.479 + #define m68ki_trace_t1() m68ki_tracing = FLAG_T1 1.480 + /* adds t0 to trace checking if we encounter change of flow */ 1.481 + #define m68ki_trace_t0() m68ki_tracing |= FLAG_T0 1.482 + /* Clear all tracing */ 1.483 + #define m68ki_clear_trace() m68ki_tracing = 0 1.484 + /* Cause a trace exception if we are tracing */ 1.485 + #define m68ki_exception_if_trace() if(m68ki_tracing) m68ki_exception_trace() 1.486 +#else 1.487 + #define m68ki_trace_t1() 1.488 + #define m68ki_trace_t0() 1.489 + #define m68ki_clear_trace() 1.490 + #define m68ki_exception_if_trace() 1.491 +#endif /* M68K_EMULATE_TRACE */ 1.492 + 1.493 + 1.494 + 1.495 +/* Address error */ 1.496 +#if M68K_EMULATE_ADDRESS_ERROR 1.497 + extern jmp_buf m68ki_address_error_trap; 1.498 + #define m68ki_set_address_error_trap() if(setjmp(m68ki_address_error_trap)) m68ki_exception_address_error(); 1.499 + #define m68ki_check_address_error(A) if((A)&1) longjmp(m68ki_address_error_jump, 1); 1.500 +#else 1.501 + #define m68ki_set_address_error_trap() 1.502 + #define m68ki_check_address_error(A) 1.503 +#endif /* M68K_ADDRESS_ERROR */ 1.504 + 1.505 +/* Logging */ 1.506 +#if M68K_LOG_ENABLE 1.507 + #include <stdio.h> 1.508 + extern FILE* M68K_LOG_FILEHANDLE 1.509 + extern char* m68ki_cpu_names[]; 1.510 + 1.511 + #define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A 1.512 + #if M68K_LOG_1010_1111 1.513 + #define M68K_DO_LOG_EMU(A) if(M68K_LOG_FILEHANDLE) fprintf A 1.514 + #else 1.515 + #define M68K_DO_LOG_EMU(A) 1.516 + #endif 1.517 +#else 1.518 + #define M68K_DO_LOG(A) 1.519 + #define M68K_DO_LOG_EMU(A) 1.520 +#endif 1.521 + 1.522 + 1.523 + 1.524 +/* -------------------------- EA / Operand Access ------------------------- */ 1.525 + 1.526 +/* 1.527 + * The general instruction format follows this pattern: 1.528 + * .... XXX. .... .YYY 1.529 + * where XXX is register X and YYY is register Y 1.530 + */ 1.531 +/* Data Register Isolation */ 1.532 +#define DX (REG_D[(REG_IR >> 9) & 7]) 1.533 +#define DY (REG_D[REG_IR & 7]) 1.534 +/* Address Register Isolation */ 1.535 +#define AX (REG_A[(REG_IR >> 9) & 7]) 1.536 +#define AY (REG_A[REG_IR & 7]) 1.537 + 1.538 + 1.539 +/* Effective Address Calculations */ 1.540 +#define EA_AY_AI_8() AY /* address register indirect */ 1.541 +#define EA_AY_AI_16() EA_AY_AI_8() 1.542 +#define EA_AY_AI_32() EA_AY_AI_8() 1.543 +#define EA_AY_PI_8() (AY++) /* postincrement (size = byte) */ 1.544 +#define EA_AY_PI_16() ((AY+=2)-2) /* postincrement (size = word) */ 1.545 +#define EA_AY_PI_32() ((AY+=4)-4) /* postincrement (size = long) */ 1.546 +#define EA_AY_PD_8() (--AY) /* predecrement (size = byte) */ 1.547 +#define EA_AY_PD_16() (AY-=2) /* predecrement (size = word) */ 1.548 +#define EA_AY_PD_32() (AY-=4) /* predecrement (size = long) */ 1.549 +#define EA_AY_DI_8() (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */ 1.550 +#define EA_AY_DI_16() EA_AY_DI_8() 1.551 +#define EA_AY_DI_32() EA_AY_DI_8() 1.552 +#define EA_AY_IX_8() m68ki_get_ea_ix(AY) /* indirect + index */ 1.553 +#define EA_AY_IX_16() EA_AY_IX_8() 1.554 +#define EA_AY_IX_32() EA_AY_IX_8() 1.555 + 1.556 +#define EA_AX_AI_8() AX 1.557 +#define EA_AX_AI_16() EA_AX_AI_8() 1.558 +#define EA_AX_AI_32() EA_AX_AI_8() 1.559 +#define EA_AX_PI_8() (AX++) 1.560 +#define EA_AX_PI_16() ((AX+=2)-2) 1.561 +#define EA_AX_PI_32() ((AX+=4)-4) 1.562 +#define EA_AX_PD_8() (--AX) 1.563 +#define EA_AX_PD_16() (AX-=2) 1.564 +#define EA_AX_PD_32() (AX-=4) 1.565 +#define EA_AX_DI_8() (AX+MAKE_INT_16(m68ki_read_imm_16())) 1.566 +#define EA_AX_DI_16() EA_AX_DI_8() 1.567 +#define EA_AX_DI_32() EA_AX_DI_8() 1.568 +#define EA_AX_IX_8() m68ki_get_ea_ix(AX) 1.569 +#define EA_AX_IX_16() EA_AX_IX_8() 1.570 +#define EA_AX_IX_32() EA_AX_IX_8() 1.571 + 1.572 +#define EA_A7_PI_8() ((REG_A[7]+=2)-2) 1.573 +#define EA_A7_PD_8() (REG_A[7]-=2) 1.574 + 1.575 +#define EA_AW_8() MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */ 1.576 +#define EA_AW_16() EA_AW_8() 1.577 +#define EA_AW_32() EA_AW_8() 1.578 +#define EA_AL_8() m68ki_read_imm_32() /* absolute long */ 1.579 +#define EA_AL_16() EA_AL_8() 1.580 +#define EA_AL_32() EA_AL_8() 1.581 +#define EA_PCDI_8() m68ki_get_ea_pcdi() /* pc indirect + displacement */ 1.582 +#define EA_PCDI_16() EA_PCDI_8() 1.583 +#define EA_PCDI_32() EA_PCDI_8() 1.584 +#define EA_PCIX_8() m68ki_get_ea_pcix() /* pc indirect + index */ 1.585 +#define EA_PCIX_16() EA_PCIX_8() 1.586 +#define EA_PCIX_32() EA_PCIX_8() 1.587 + 1.588 + 1.589 +#define OPER_I_8() m68ki_read_imm_8() 1.590 +#define OPER_I_16() m68ki_read_imm_16() 1.591 +#define OPER_I_32() m68ki_read_imm_32() 1.592 + 1.593 + 1.594 + 1.595 +/* --------------------------- Status Register ---------------------------- */ 1.596 + 1.597 +/* Flag Calculation Macros */ 1.598 +#define CFLAG_8(A) (A) 1.599 +#define CFLAG_16(A) ((A)>>8) 1.600 + 1.601 +#if M68K_INT_GT_32_BIT 1.602 + #define CFLAG_ADD_32(S, D, R) ((R)>>24) 1.603 + #define CFLAG_SUB_32(S, D, R) ((R)>>24) 1.604 +#else 1.605 + #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23) 1.606 + #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23) 1.607 +#endif /* M68K_INT_GT_32_BIT */ 1.608 + 1.609 +#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R)) 1.610 +#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8) 1.611 +#define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24) 1.612 + 1.613 +#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D)) 1.614 +#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8) 1.615 +#define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24) 1.616 + 1.617 +#define NFLAG_8(A) (A) 1.618 +#define NFLAG_16(A) ((A)>>8) 1.619 +#define NFLAG_32(A) ((A)>>24) 1.620 +#define NFLAG_64(A) ((A)>>56) 1.621 + 1.622 +#define ZFLAG_8(A) MASK_OUT_ABOVE_8(A) 1.623 +#define ZFLAG_16(A) MASK_OUT_ABOVE_16(A) 1.624 +#define ZFLAG_32(A) MASK_OUT_ABOVE_32(A) 1.625 + 1.626 + 1.627 +/* Flag values */ 1.628 +#define NFLAG_SET 0x80 1.629 +#define NFLAG_CLEAR 0 1.630 +#define CFLAG_SET 0x100 1.631 +#define CFLAG_CLEAR 0 1.632 +#define XFLAG_SET 0x100 1.633 +#define XFLAG_CLEAR 0 1.634 +#define VFLAG_SET 0x80 1.635 +#define VFLAG_CLEAR 0 1.636 +#define ZFLAG_SET 0 1.637 +#define ZFLAG_CLEAR 0xffffffff 1.638 + 1.639 +#define SFLAG_SET 4 1.640 +#define SFLAG_CLEAR 0 1.641 +#define MFLAG_SET 2 1.642 +#define MFLAG_CLEAR 0 1.643 + 1.644 +/* Turn flag values into 1 or 0 */ 1.645 +#define XFLAG_AS_1() ((FLAG_X>>8)&1) 1.646 +#define NFLAG_AS_1() ((FLAG_N>>7)&1) 1.647 +#define VFLAG_AS_1() ((FLAG_V>>7)&1) 1.648 +#define ZFLAG_AS_1() (!FLAG_Z) 1.649 +#define CFLAG_AS_1() ((FLAG_C>>8)&1) 1.650 + 1.651 + 1.652 +/* Conditions */ 1.653 +#define COND_CS() (FLAG_C&0x100) 1.654 +#define COND_CC() (!COND_CS()) 1.655 +#define COND_VS() (FLAG_V&0x80) 1.656 +#define COND_VC() (!COND_VS()) 1.657 +#define COND_NE() FLAG_Z 1.658 +#define COND_EQ() (!COND_NE()) 1.659 +#define COND_MI() (FLAG_N&0x80) 1.660 +#define COND_PL() (!COND_MI()) 1.661 +#define COND_LT() ((FLAG_N^FLAG_V)&0x80) 1.662 +#define COND_GE() (!COND_LT()) 1.663 +#define COND_HI() (COND_CC() && COND_NE()) 1.664 +#define COND_LS() (COND_CS() || COND_EQ()) 1.665 +#define COND_GT() (COND_GE() && COND_NE()) 1.666 +#define COND_LE() (COND_LT() || COND_EQ()) 1.667 + 1.668 +/* Reversed conditions */ 1.669 +#define COND_NOT_CS() COND_CC() 1.670 +#define COND_NOT_CC() COND_CS() 1.671 +#define COND_NOT_VS() COND_VC() 1.672 +#define COND_NOT_VC() COND_VS() 1.673 +#define COND_NOT_NE() COND_EQ() 1.674 +#define COND_NOT_EQ() COND_NE() 1.675 +#define COND_NOT_MI() COND_PL() 1.676 +#define COND_NOT_PL() COND_MI() 1.677 +#define COND_NOT_LT() COND_GE() 1.678 +#define COND_NOT_GE() COND_LT() 1.679 +#define COND_NOT_HI() COND_LS() 1.680 +#define COND_NOT_LS() COND_HI() 1.681 +#define COND_NOT_GT() COND_LE() 1.682 +#define COND_NOT_LE() COND_GT() 1.683 + 1.684 +/* Not real conditions, but here for convenience */ 1.685 +#define COND_XS() (FLAG_X&0x100) 1.686 +#define COND_XC() (!COND_XS) 1.687 + 1.688 + 1.689 +/* Get the condition code register */ 1.690 +#define m68ki_get_ccr() ((COND_XS() >> 4) | \ 1.691 + (COND_MI() >> 4) | \ 1.692 + (COND_EQ() << 2) | \ 1.693 + (COND_VS() >> 6) | \ 1.694 + (COND_CS() >> 8)) 1.695 + 1.696 +/* Get the status register */ 1.697 +#define m68ki_get_sr() ( FLAG_T1 | \ 1.698 + FLAG_T0 | \ 1.699 + (FLAG_S << 11) | \ 1.700 + (FLAG_M << 11) | \ 1.701 + FLAG_INT_MASK | \ 1.702 + m68ki_get_ccr()) 1.703 + 1.704 + 1.705 + 1.706 +/* ---------------------------- Cycle Counting ---------------------------- */ 1.707 + 1.708 +#define ADD_CYCLES(A) m68ki_remaining_cycles += (A) 1.709 +#define USE_CYCLES(A) m68ki_remaining_cycles -= (A) 1.710 +#define SET_CYCLES(A) m68ki_remaining_cycles = A 1.711 +#define GET_CYCLES() m68ki_remaining_cycles 1.712 +#define USE_ALL_CYCLES() m68ki_remaining_cycles = 0 1.713 + 1.714 + 1.715 + 1.716 +/* ----------------------------- Read / Write ----------------------------- */ 1.717 + 1.718 +/* Read from the current address space */ 1.719 +#define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space()) 1.720 +#define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space()) 1.721 +#define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space()) 1.722 + 1.723 +/* Write to the current data space */ 1.724 +#define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V) 1.725 +#define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) 1.726 +#define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) 1.727 + 1.728 +/* map read immediate 8 to read immediate 16 */ 1.729 +#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16()) 1.730 + 1.731 +/* Map PC-relative reads */ 1.732 +#define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A) 1.733 +#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A) 1.734 +#define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A) 1.735 + 1.736 +/* Read from the program space */ 1.737 +#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) 1.738 +#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) 1.739 +#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) 1.740 + 1.741 +/* Read from the data space */ 1.742 +#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) 1.743 +#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) 1.744 +#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) 1.745 + 1.746 + 1.747 + 1.748 +/* ======================================================================== */ 1.749 +/* =============================== PROTOTYPES ============================= */ 1.750 +/* ======================================================================== */ 1.751 + 1.752 +typedef struct 1.753 +{ 1.754 + uint cpu_type; /* CPU Type: 68000, 68010, 68EC020, or 68020 */ 1.755 + uint dar[16]; /* Data and Address Registers */ 1.756 + uint ppc; /* Previous program counter */ 1.757 + uint pc; /* Program Counter */ 1.758 + uint sp[7]; /* User, Interrupt, and Master Stack Pointers */ 1.759 + uint vbr; /* Vector Base Register (m68010+) */ 1.760 + uint sfc; /* Source Function Code Register (m68010+) */ 1.761 + uint dfc; /* Destination Function Code Register (m68010+) */ 1.762 + uint cacr; /* Cache Control Register (m68020, unemulated) */ 1.763 + uint caar; /* Cache Address Register (m68020, unemulated) */ 1.764 + uint ir; /* Instruction Register */ 1.765 + uint t1_flag; /* Trace 1 */ 1.766 + uint t0_flag; /* Trace 0 */ 1.767 + uint s_flag; /* Supervisor */ 1.768 + uint m_flag; /* Master/Interrupt state */ 1.769 + uint x_flag; /* Extend */ 1.770 + uint n_flag; /* Negative */ 1.771 + uint not_z_flag; /* Zero, inverted for speedups */ 1.772 + uint v_flag; /* Overflow */ 1.773 + uint c_flag; /* Carry */ 1.774 + uint int_mask; /* I0-I2 */ 1.775 + uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */ 1.776 + uint int_cycles; /* ASG: extra cycles from generated interrupts */ 1.777 + uint stopped; /* Stopped state */ 1.778 + uint pref_addr; /* Last prefetch address */ 1.779 + uint pref_data; /* Data in the prefetch queue */ 1.780 + uint address_mask; /* Available address pins */ 1.781 + uint sr_mask; /* Implemented status register bits */ 1.782 + 1.783 + /* Clocks required for instructions / exceptions */ 1.784 + uint cyc_bcc_notake_b; 1.785 + uint cyc_bcc_notake_w; 1.786 + uint cyc_dbcc_f_noexp; 1.787 + uint cyc_dbcc_f_exp; 1.788 + uint cyc_scc_r_false; 1.789 + uint cyc_movem_w; 1.790 + uint cyc_movem_l; 1.791 + uint cyc_shift; 1.792 + uint cyc_reset; 1.793 + uint8* cyc_instruction; 1.794 + uint8* cyc_exception; 1.795 + 1.796 + /* Callbacks to host */ 1.797 + int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */ 1.798 + void (*bkpt_ack_callback)(unsigned int data); /* Breakpoint Acknowledge */ 1.799 + void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */ 1.800 + void (*pc_changed_callback)(unsigned int new_pc); /* Called when the PC changes by a large amount */ 1.801 + void (*set_fc_callback)(unsigned int new_fc); /* Called when the CPU function code changes */ 1.802 + void (*instr_hook_callback)(void); /* Called every instruction cycle prior to execution */ 1.803 + 1.804 +} m68ki_cpu_core; 1.805 + 1.806 + 1.807 +extern m68ki_cpu_core m68ki_cpu; 1.808 +extern sint m68ki_remaining_cycles; 1.809 +extern uint m68ki_tracing; 1.810 +extern uint8 m68ki_shift_8_table[]; 1.811 +extern uint16 m68ki_shift_16_table[]; 1.812 +extern uint m68ki_shift_32_table[]; 1.813 +extern uint8 m68ki_exception_cycle_table[][256]; 1.814 +extern uint m68ki_address_space; 1.815 +extern uint8 m68ki_ea_idx_cycle_table[]; 1.816 + 1.817 + 1.818 +/* Read data immediately after the program counter */ 1.819 +INLINE uint m68ki_read_imm_16(void); 1.820 +INLINE uint m68ki_read_imm_32(void); 1.821 + 1.822 +/* Read data with specific function code */ 1.823 +INLINE uint m68ki_read_8_fc (uint address, uint fc); 1.824 +INLINE uint m68ki_read_16_fc (uint address, uint fc); 1.825 +INLINE uint m68ki_read_32_fc (uint address, uint fc); 1.826 + 1.827 +/* Write data with specific function code */ 1.828 +INLINE void m68ki_write_8_fc (uint address, uint fc, uint value); 1.829 +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value); 1.830 +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value); 1.831 + 1.832 +/* Indexed and PC-relative ea fetching */ 1.833 +INLINE uint m68ki_get_ea_pcdi(void); 1.834 +INLINE uint m68ki_get_ea_pcix(void); 1.835 +INLINE uint m68ki_get_ea_ix(uint An); 1.836 + 1.837 +/* Operand fetching */ 1.838 +INLINE uint OPER_AY_AI_8(void); 1.839 +INLINE uint OPER_AY_AI_16(void); 1.840 +INLINE uint OPER_AY_AI_32(void); 1.841 +INLINE uint OPER_AY_PI_8(void); 1.842 +INLINE uint OPER_AY_PI_16(void); 1.843 +INLINE uint OPER_AY_PI_32(void); 1.844 +INLINE uint OPER_AY_PD_8(void); 1.845 +INLINE uint OPER_AY_PD_16(void); 1.846 +INLINE uint OPER_AY_PD_32(void); 1.847 +INLINE uint OPER_AY_DI_8(void); 1.848 +INLINE uint OPER_AY_DI_16(void); 1.849 +INLINE uint OPER_AY_DI_32(void); 1.850 +INLINE uint OPER_AY_IX_8(void); 1.851 +INLINE uint OPER_AY_IX_16(void); 1.852 +INLINE uint OPER_AY_IX_32(void); 1.853 + 1.854 +INLINE uint OPER_AX_AI_8(void); 1.855 +INLINE uint OPER_AX_AI_16(void); 1.856 +INLINE uint OPER_AX_AI_32(void); 1.857 +INLINE uint OPER_AX_PI_8(void); 1.858 +INLINE uint OPER_AX_PI_16(void); 1.859 +INLINE uint OPER_AX_PI_32(void); 1.860 +INLINE uint OPER_AX_PD_8(void); 1.861 +INLINE uint OPER_AX_PD_16(void); 1.862 +INLINE uint OPER_AX_PD_32(void); 1.863 +INLINE uint OPER_AX_DI_8(void); 1.864 +INLINE uint OPER_AX_DI_16(void); 1.865 +INLINE uint OPER_AX_DI_32(void); 1.866 +INLINE uint OPER_AX_IX_8(void); 1.867 +INLINE uint OPER_AX_IX_16(void); 1.868 +INLINE uint OPER_AX_IX_32(void); 1.869 + 1.870 +INLINE uint OPER_A7_PI_8(void); 1.871 +INLINE uint OPER_A7_PD_8(void); 1.872 + 1.873 +INLINE uint OPER_AW_8(void); 1.874 +INLINE uint OPER_AW_16(void); 1.875 +INLINE uint OPER_AW_32(void); 1.876 +INLINE uint OPER_AL_8(void); 1.877 +INLINE uint OPER_AL_16(void); 1.878 +INLINE uint OPER_AL_32(void); 1.879 +INLINE uint OPER_PCDI_8(void); 1.880 +INLINE uint OPER_PCDI_16(void); 1.881 +INLINE uint OPER_PCDI_32(void); 1.882 +INLINE uint OPER_PCIX_8(void); 1.883 +INLINE uint OPER_PCIX_16(void); 1.884 +INLINE uint OPER_PCIX_32(void); 1.885 + 1.886 +/* Stack operations */ 1.887 +INLINE void m68ki_push_16(uint value); 1.888 +INLINE void m68ki_push_32(uint value); 1.889 +INLINE uint m68ki_pull_16(void); 1.890 +INLINE uint m68ki_pull_32(void); 1.891 + 1.892 +/* Program flow operations */ 1.893 +INLINE void m68ki_jump(uint new_pc); 1.894 +INLINE void m68ki_jump_vector(uint vector); 1.895 +INLINE void m68ki_branch_8(uint offset); 1.896 +INLINE void m68ki_branch_16(uint offset); 1.897 +INLINE void m68ki_branch_32(uint offset); 1.898 + 1.899 +/* Status register operations. */ 1.900 +INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */ 1.901 +INLINE void m68ki_set_sm_flag(uint value); /* only bits 1 and 2 of value should be set */ 1.902 +INLINE void m68ki_set_ccr(uint value); /* set the condition code register */ 1.903 +INLINE void m68ki_set_sr(uint value); /* set the status register */ 1.904 +INLINE void m68ki_set_sr_noint(uint value); /* set the status register */ 1.905 + 1.906 +/* Exception processing */ 1.907 +INLINE uint m68ki_init_exception(void); /* Initial exception processing */ 1.908 + 1.909 +INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */ 1.910 +INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc); 1.911 + 1.912 +INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector); 1.913 +INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector); 1.914 +INLINE void m68ki_stack_frame_0010(uint sr, uint vector); 1.915 +INLINE void m68ki_stack_frame_1000(uint pc, uint sr, uint vector); 1.916 +INLINE void m68ki_stack_frame_1010(uint sr, uint vector, uint pc); 1.917 +INLINE void m68ki_stack_frame_1011(uint sr, uint vector, uint pc); 1.918 + 1.919 +INLINE void m68ki_exception_trap(uint vector); 1.920 +INLINE void m68ki_exception_trapN(uint vector); 1.921 +INLINE void m68ki_exception_trace(void); 1.922 +INLINE void m68ki_exception_privilege_violation(void); 1.923 +INLINE void m68ki_exception_1010(void); 1.924 +INLINE void m68ki_exception_1111(void); 1.925 +INLINE void m68ki_exception_illegal(void); 1.926 +INLINE void m68ki_exception_format_error(void); 1.927 +INLINE void m68ki_exception_address_error(void); 1.928 +INLINE void m68ki_exception_interrupt(uint int_level); 1.929 +INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */ 1.930 + 1.931 +/* quick disassembly (used for logging) */ 1.932 +char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type); 1.933 + 1.934 + 1.935 +/* ======================================================================== */ 1.936 +/* =========================== UTILITY FUNCTIONS ========================== */ 1.937 +/* ======================================================================== */ 1.938 + 1.939 + 1.940 +/* ---------------------------- Read Immediate ---------------------------- */ 1.941 + 1.942 +/* Handles all immediate reads, does address error check, function code setting, 1.943 + * and prefetching if they are enabled in m68kconf.h 1.944 + */ 1.945 +INLINE uint m68ki_read_imm_16(void) 1.946 +{ 1.947 + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ 1.948 + m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */ 1.949 +#if M68K_EMULATE_PREFETCH 1.950 + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) 1.951 + { 1.952 + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); 1.953 + CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); 1.954 + } 1.955 + REG_PC += 2; 1.956 + return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3)); 1.957 +#else 1.958 + REG_PC += 2; 1.959 + return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2)); 1.960 +#endif /* M68K_EMULATE_PREFETCH */ 1.961 +} 1.962 +INLINE uint m68ki_read_imm_32(void) 1.963 +{ 1.964 +#if M68K_EMULATE_PREFETCH 1.965 + uint temp_val; 1.966 + 1.967 + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ 1.968 + m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */ 1.969 + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) 1.970 + { 1.971 + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); 1.972 + CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); 1.973 + } 1.974 + temp_val = CPU_PREF_DATA; 1.975 + REG_PC += 2; 1.976 + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) 1.977 + { 1.978 + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); 1.979 + CPU_PREF_DATA = m68k_read_immediate_32(ADDRESS_68K(CPU_PREF_ADDR)); 1.980 + temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16)); 1.981 + } 1.982 + REG_PC += 2; 1.983 + 1.984 + return temp_val; 1.985 +#else 1.986 + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */ 1.987 + m68ki_check_address_error(REG_PC); /* auto-disable (see m68kcpu.h) */ 1.988 + REG_PC += 4; 1.989 + return m68k_read_immediate_32(ADDRESS_68K(REG_PC-4)); 1.990 +#endif /* M68K_EMULATE_PREFETCH */ 1.991 +} 1.992 + 1.993 + 1.994 + 1.995 +/* ------------------------- Top level read/write ------------------------- */ 1.996 + 1.997 +/* Handles all memory accesses (except for immediate reads if they are 1.998 + * configured to use separate functions in m68kconf.h). 1.999 + * All memory accesses must go through these top level functions. 1.1000 + * These functions will also check for address error and set the function 1.1001 + * code if they are enabled in m68kconf.h. 1.1002 + */ 1.1003 +INLINE uint m68ki_read_8_fc(uint address, uint fc) 1.1004 +{ 1.1005 + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ 1.1006 + return m68k_read_memory_8(ADDRESS_68K(address)); 1.1007 +} 1.1008 +INLINE uint m68ki_read_16_fc(uint address, uint fc) 1.1009 +{ 1.1010 + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ 1.1011 + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ 1.1012 + return m68k_read_memory_16(ADDRESS_68K(address)); 1.1013 +} 1.1014 +INLINE uint m68ki_read_32_fc(uint address, uint fc) 1.1015 +{ 1.1016 + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ 1.1017 + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ 1.1018 + return m68k_read_memory_32(ADDRESS_68K(address)); 1.1019 +} 1.1020 + 1.1021 +INLINE void m68ki_write_8_fc(uint address, uint fc, uint value) 1.1022 +{ 1.1023 + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ 1.1024 + m68k_write_memory_8(ADDRESS_68K(address), value); 1.1025 +} 1.1026 +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value) 1.1027 +{ 1.1028 + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ 1.1029 + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ 1.1030 + m68k_write_memory_16(ADDRESS_68K(address), value); 1.1031 +} 1.1032 +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value) 1.1033 +{ 1.1034 + m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ 1.1035 + m68ki_check_address_error(address); /* auto-disable (see m68kcpu.h) */ 1.1036 + m68k_write_memory_32(ADDRESS_68K(address), value); 1.1037 +} 1.1038 + 1.1039 + 1.1040 + 1.1041 +/* --------------------- Effective Address Calculation -------------------- */ 1.1042 + 1.1043 +/* The program counter relative addressing modes cause operands to be 1.1044 + * retrieved from program space, not data space. 1.1045 + */ 1.1046 +INLINE uint m68ki_get_ea_pcdi(void) 1.1047 +{ 1.1048 + uint old_pc = REG_PC; 1.1049 + m68ki_use_program_space(); /* auto-disable */ 1.1050 + return old_pc + MAKE_INT_16(m68ki_read_imm_16()); 1.1051 +} 1.1052 + 1.1053 + 1.1054 +INLINE uint m68ki_get_ea_pcix(void) 1.1055 +{ 1.1056 + m68ki_use_program_space(); /* auto-disable */ 1.1057 + return m68ki_get_ea_ix(REG_PC); 1.1058 +} 1.1059 + 1.1060 +/* Indexed addressing modes are encoded as follows: 1.1061 + * 1.1062 + * Base instruction format: 1.1063 + * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 1.1064 + * x x x x x x x x x x | 1 1 0 | BASE REGISTER (An) 1.1065 + * 1.1066 + * Base instruction format for destination EA in move instructions: 1.1067 + * F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0 1.1068 + * x x x x | BASE REG | 1 1 0 | X X X X X X (An) 1.1069 + * 1.1070 + * Brief extension format: 1.1071 + * F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0 1.1072 + * D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT 1.1073 + * 1.1074 + * Full extension format: 1.1075 + * F E D C B A 9 8 7 6 5 4 3 2 1 0 1.1076 + * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS 1.1077 + * BASE DISPLACEMENT (0, 16, 32 bit) (bd) 1.1078 + * OUTER DISPLACEMENT (0, 16, 32 bit) (od) 1.1079 + * 1.1080 + * D/A: 0 = Dn, 1 = An (Xn) 1.1081 + * W/L: 0 = W (sign extend), 1 = L (.SIZE) 1.1082 + * SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE) 1.1083 + * BS: 0=add base reg, 1=suppress base reg (An suppressed) 1.1084 + * IS: 0=add index, 1=suppress index (Xn suppressed) 1.1085 + * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd) 1.1086 + * 1.1087 + * IS I/IS Operation 1.1088 + * 0 000 No Memory Indirect 1.1089 + * 0 001 indir prex with null outer 1.1090 + * 0 010 indir prex with word outer 1.1091 + * 0 011 indir prex with long outer 1.1092 + * 0 100 reserved 1.1093 + * 0 101 indir postx with null outer 1.1094 + * 0 110 indir postx with word outer 1.1095 + * 0 111 indir postx with long outer 1.1096 + * 1 000 no memory indirect 1.1097 + * 1 001 mem indir with null outer 1.1098 + * 1 010 mem indir with word outer 1.1099 + * 1 011 mem indir with long outer 1.1100 + * 1 100-111 reserved 1.1101 + */ 1.1102 +INLINE uint m68ki_get_ea_ix(uint An) 1.1103 +{ 1.1104 + /* An = base register */ 1.1105 + uint extension = m68ki_read_imm_16(); 1.1106 + uint Xn = 0; /* Index register */ 1.1107 + uint bd = 0; /* Base Displacement */ 1.1108 + uint od = 0; /* Outer Displacement */ 1.1109 + 1.1110 + if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) 1.1111 + { 1.1112 + /* Calculate index */ 1.1113 + Xn = REG_DA[extension>>12]; /* Xn */ 1.1114 + if(!BIT_B(extension)) /* W/L */ 1.1115 + Xn = MAKE_INT_16(Xn); 1.1116 + 1.1117 + /* Add base register and displacement and return */ 1.1118 + return An + Xn + MAKE_INT_8(extension); 1.1119 + } 1.1120 + 1.1121 + /* Brief extension format */ 1.1122 + if(!BIT_8(extension)) 1.1123 + { 1.1124 + /* Calculate index */ 1.1125 + Xn = REG_DA[extension>>12]; /* Xn */ 1.1126 + if(!BIT_B(extension)) /* W/L */ 1.1127 + Xn = MAKE_INT_16(Xn); 1.1128 + /* Add scale if proper CPU type */ 1.1129 + if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) 1.1130 + Xn <<= (extension>>9) & 3; /* SCALE */ 1.1131 + 1.1132 + /* Add base register and displacement and return */ 1.1133 + return An + Xn + MAKE_INT_8(extension); 1.1134 + } 1.1135 + 1.1136 + /* Full extension format */ 1.1137 + 1.1138 + USE_CYCLES(m68ki_ea_idx_cycle_table[extension&0x3f]); 1.1139 + 1.1140 + /* Check if base register is present */ 1.1141 + if(BIT_7(extension)) /* BS */ 1.1142 + An = 0; /* An */ 1.1143 + 1.1144 + /* Check if index is present */ 1.1145 + if(!BIT_6(extension)) /* IS */ 1.1146 + { 1.1147 + Xn = REG_DA[extension>>12]; /* Xn */ 1.1148 + if(!BIT_B(extension)) /* W/L */ 1.1149 + Xn = MAKE_INT_16(Xn); 1.1150 + Xn <<= (extension>>9) & 3; /* SCALE */ 1.1151 + } 1.1152 + 1.1153 + /* Check if base displacement is present */ 1.1154 + if(BIT_5(extension)) /* BD SIZE */ 1.1155 + bd = BIT_4(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16()); 1.1156 + 1.1157 + /* If no indirect action, we are done */ 1.1158 + if(!(extension&7)) /* No Memory Indirect */ 1.1159 + return An + bd + Xn; 1.1160 + 1.1161 + /* Check if outer displacement is present */ 1.1162 + if(BIT_1(extension)) /* I/IS: od */ 1.1163 + od = BIT_0(extension) ? m68ki_read_imm_32() : MAKE_INT_16(m68ki_read_imm_16()); 1.1164 + 1.1165 + /* Postindex */ 1.1166 + if(BIT_2(extension)) /* I/IS: 0 = preindex, 1 = postindex */ 1.1167 + return m68ki_read_32(An + bd) + Xn + od; 1.1168 + 1.1169 + /* Preindex */ 1.1170 + return m68ki_read_32(An + bd + Xn) + od; 1.1171 +} 1.1172 + 1.1173 + 1.1174 +/* Fetch operands */ 1.1175 +INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); } 1.1176 +INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);} 1.1177 +INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);} 1.1178 +INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); } 1.1179 +INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);} 1.1180 +INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);} 1.1181 +INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); } 1.1182 +INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);} 1.1183 +INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);} 1.1184 +INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); } 1.1185 +INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);} 1.1186 +INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);} 1.1187 +INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); } 1.1188 +INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);} 1.1189 +INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);} 1.1190 + 1.1191 +INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); } 1.1192 +INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);} 1.1193 +INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);} 1.1194 +INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); } 1.1195 +INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);} 1.1196 +INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);} 1.1197 +INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); } 1.1198 +INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);} 1.1199 +INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);} 1.1200 +INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); } 1.1201 +INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);} 1.1202 +INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);} 1.1203 +INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); } 1.1204 +INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);} 1.1205 +INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);} 1.1206 + 1.1207 +INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); } 1.1208 +INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); } 1.1209 + 1.1210 +INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); } 1.1211 +INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);} 1.1212 +INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);} 1.1213 +INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); } 1.1214 +INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);} 1.1215 +INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);} 1.1216 +INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); } 1.1217 +INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);} 1.1218 +INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);} 1.1219 +INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); } 1.1220 +INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);} 1.1221 +INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);} 1.1222 + 1.1223 + 1.1224 + 1.1225 +/* ---------------------------- Stack Functions --------------------------- */ 1.1226 + 1.1227 +/* Push/pull data from the stack */ 1.1228 +INLINE void m68ki_push_16(uint value) 1.1229 +{ 1.1230 + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); 1.1231 + m68ki_write_16(REG_SP, value); 1.1232 +} 1.1233 + 1.1234 +INLINE void m68ki_push_32(uint value) 1.1235 +{ 1.1236 + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); 1.1237 + m68ki_write_32(REG_SP, value); 1.1238 +} 1.1239 + 1.1240 +INLINE uint m68ki_pull_16(void) 1.1241 +{ 1.1242 + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); 1.1243 + return m68ki_read_16(REG_SP-2); 1.1244 +} 1.1245 + 1.1246 +INLINE uint m68ki_pull_32(void) 1.1247 +{ 1.1248 + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); 1.1249 + return m68ki_read_32(REG_SP-4); 1.1250 +} 1.1251 + 1.1252 + 1.1253 +/* Increment/decrement the stack as if doing a push/pull but 1.1254 + * don't do any memory access. 1.1255 + */ 1.1256 +INLINE void m68ki_fake_push_16(void) 1.1257 +{ 1.1258 + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); 1.1259 +} 1.1260 + 1.1261 +INLINE void m68ki_fake_push_32(void) 1.1262 +{ 1.1263 + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); 1.1264 +} 1.1265 + 1.1266 +INLINE void m68ki_fake_pull_16(void) 1.1267 +{ 1.1268 + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); 1.1269 +} 1.1270 + 1.1271 +INLINE void m68ki_fake_pull_32(void) 1.1272 +{ 1.1273 + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); 1.1274 +} 1.1275 + 1.1276 + 1.1277 +/* ----------------------------- Program Flow ----------------------------- */ 1.1278 + 1.1279 +/* Jump to a new program location or vector. 1.1280 + * These functions will also call the pc_changed callback if it was enabled 1.1281 + * in m68kconf.h. 1.1282 + */ 1.1283 +INLINE void m68ki_jump(uint new_pc) 1.1284 +{ 1.1285 + REG_PC = new_pc; 1.1286 + m68ki_pc_changed(REG_PC); 1.1287 +} 1.1288 + 1.1289 +INLINE void m68ki_jump_vector(uint vector) 1.1290 +{ 1.1291 + REG_PC = (vector<<2) + REG_VBR; 1.1292 + REG_PC = m68ki_read_data_32(REG_PC); 1.1293 + m68ki_pc_changed(REG_PC); 1.1294 +} 1.1295 + 1.1296 + 1.1297 +/* Branch to a new memory location. 1.1298 + * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h. 1.1299 + * So far I've found no problems with not calling pc_changed for 8 or 16 1.1300 + * bit branches. 1.1301 + */ 1.1302 +INLINE void m68ki_branch_8(uint offset) 1.1303 +{ 1.1304 + REG_PC += MAKE_INT_8(offset); 1.1305 +} 1.1306 + 1.1307 +INLINE void m68ki_branch_16(uint offset) 1.1308 +{ 1.1309 + REG_PC += MAKE_INT_16(offset); 1.1310 +} 1.1311 + 1.1312 +INLINE void m68ki_branch_32(uint offset) 1.1313 +{ 1.1314 + REG_PC += offset; 1.1315 + m68ki_pc_changed(REG_PC); 1.1316 +} 1.1317 + 1.1318 + 1.1319 + 1.1320 +/* ---------------------------- Status Register --------------------------- */ 1.1321 + 1.1322 +/* Set the S flag and change the active stack pointer. 1.1323 + * Note that value MUST be 4 or 0. 1.1324 + */ 1.1325 +INLINE void m68ki_set_s_flag(uint value) 1.1326 +{ 1.1327 + /* Backup the old stack pointer */ 1.1328 + REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP; 1.1329 + /* Set the S flag */ 1.1330 + FLAG_S = value; 1.1331 + /* Set the new stack pointer */ 1.1332 + REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)]; 1.1333 +} 1.1334 + 1.1335 +/* Set the S and M flags and change the active stack pointer. 1.1336 + * Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M). 1.1337 + */ 1.1338 +INLINE void m68ki_set_sm_flag(uint value) 1.1339 +{ 1.1340 + /* Backup the old stack pointer */ 1.1341 + REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP; 1.1342 + /* Set the S and M flags */ 1.1343 + FLAG_S = value & SFLAG_SET; 1.1344 + FLAG_M = value & MFLAG_SET; 1.1345 + /* Set the new stack pointer */ 1.1346 + REG_SP = REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)]; 1.1347 +} 1.1348 + 1.1349 + 1.1350 +/* Set the condition code register */ 1.1351 +INLINE void m68ki_set_ccr(uint value) 1.1352 +{ 1.1353 + FLAG_X = BIT_4(value) << 4; 1.1354 + FLAG_N = BIT_3(value) << 4; 1.1355 + FLAG_Z = !BIT_2(value); 1.1356 + FLAG_V = BIT_1(value) << 6; 1.1357 + FLAG_C = BIT_0(value) << 8; 1.1358 +} 1.1359 + 1.1360 +/* Set the status register but don't check for interrupts */ 1.1361 +INLINE void m68ki_set_sr_noint(uint value) 1.1362 +{ 1.1363 + /* Mask out the "unimplemented" bits */ 1.1364 + value &= CPU_SR_MASK; 1.1365 + 1.1366 + /* Now set the status register */ 1.1367 + FLAG_T1 = BIT_F(value); 1.1368 + FLAG_T0 = BIT_E(value); 1.1369 + FLAG_INT_MASK = value & 0x0700; 1.1370 + m68ki_set_ccr(value); 1.1371 + m68ki_set_sm_flag((value >> 11) & 6); 1.1372 +} 1.1373 + 1.1374 +/* Set the status register and check for interrupts */ 1.1375 +INLINE void m68ki_set_sr(uint value) 1.1376 +{ 1.1377 + m68ki_set_sr_noint(value); 1.1378 + m68ki_check_interrupts(); 1.1379 +} 1.1380 + 1.1381 + 1.1382 +/* ------------------------- Exception Processing ------------------------- */ 1.1383 + 1.1384 +/* Initiate exception processing */ 1.1385 +INLINE uint m68ki_init_exception(void) 1.1386 +{ 1.1387 + /* Save the old status register */ 1.1388 + uint sr = m68ki_get_sr(); 1.1389 + 1.1390 + /* Turn off trace flag, clear pending traces */ 1.1391 + FLAG_T1 = FLAG_T0 = 0; 1.1392 + m68ki_clear_trace(); 1.1393 + /* Enter supervisor mode */ 1.1394 + m68ki_set_s_flag(SFLAG_SET); 1.1395 + 1.1396 + return sr; 1.1397 +} 1.1398 + 1.1399 +/* 3 word stack frame (68000 only) */ 1.1400 +INLINE void m68ki_stack_frame_3word(uint pc, uint sr) 1.1401 +{ 1.1402 + m68ki_push_32(pc); 1.1403 + m68ki_push_16(sr); 1.1404 +} 1.1405 + 1.1406 +/* Format 0 stack frame. 1.1407 + * This is the standard stack frame for 68010+. 1.1408 + */ 1.1409 +INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector) 1.1410 +{ 1.1411 + /* Stack a 3-word frame if we are 68000 */ 1.1412 + if(CPU_TYPE == CPU_TYPE_000) 1.1413 + { 1.1414 + m68ki_stack_frame_3word(pc, sr); 1.1415 + return; 1.1416 + } 1.1417 + m68ki_push_16(vector<<2); 1.1418 + m68ki_push_32(pc); 1.1419 + m68ki_push_16(sr); 1.1420 +} 1.1421 + 1.1422 +/* Format 1 stack frame (68020). 1.1423 + * For 68020, this is the 4 word throwaway frame. 1.1424 + */ 1.1425 +INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector) 1.1426 +{ 1.1427 + m68ki_push_16(0x1000 | (vector<<2)); 1.1428 + m68ki_push_32(pc); 1.1429 + m68ki_push_16(sr); 1.1430 +} 1.1431 + 1.1432 +/* Format 2 stack frame. 1.1433 + * This is used only by 68020 for trap exceptions. 1.1434 + */ 1.1435 +INLINE void m68ki_stack_frame_0010(uint sr, uint vector) 1.1436 +{ 1.1437 + m68ki_push_32(REG_PPC); 1.1438 + m68ki_push_16(0x2000 | (vector<<2)); 1.1439 + m68ki_push_32(REG_PC); 1.1440 + m68ki_push_16(sr); 1.1441 +} 1.1442 + 1.1443 + 1.1444 +/* Bus error stack frame (68000 only). 1.1445 + */ 1.1446 +INLINE void m68ki_stack_frame_buserr(uint pc, uint sr, uint address, uint write, uint instruction, uint fc) 1.1447 +{ 1.1448 + m68ki_push_32(pc); 1.1449 + m68ki_push_16(sr); 1.1450 + m68ki_push_16(REG_IR); 1.1451 + m68ki_push_32(address); /* access address */ 1.1452 + /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC 1.1453 + * R/W 0 = write, 1 = read 1.1454 + * I/N 0 = instruction, 1 = not 1.1455 + * FC 3-bit function code 1.1456 + */ 1.1457 + m68ki_push_16(((!write)<<4) | ((!instruction)<<3) | fc); 1.1458 +} 1.1459 + 1.1460 +/* Format 8 stack frame (68010). 1.1461 + * 68010 only. This is the 29 word bus/address error frame. 1.1462 + */ 1.1463 +void m68ki_stack_frame_1000(uint pc, uint sr, uint vector) 1.1464 +{ 1.1465 + /* VERSION 1.1466 + * NUMBER 1.1467 + * INTERNAL INFORMATION, 16 WORDS 1.1468 + */ 1.1469 + m68ki_fake_push_32(); 1.1470 + m68ki_fake_push_32(); 1.1471 + m68ki_fake_push_32(); 1.1472 + m68ki_fake_push_32(); 1.1473 + m68ki_fake_push_32(); 1.1474 + m68ki_fake_push_32(); 1.1475 + m68ki_fake_push_32(); 1.1476 + m68ki_fake_push_32(); 1.1477 + 1.1478 + /* INSTRUCTION INPUT BUFFER */ 1.1479 + m68ki_push_16(0); 1.1480 + 1.1481 + /* UNUSED, RESERVED (not written) */ 1.1482 + m68ki_fake_push_16(); 1.1483 + 1.1484 + /* DATA INPUT BUFFER */ 1.1485 + m68ki_push_16(0); 1.1486 + 1.1487 + /* UNUSED, RESERVED (not written) */ 1.1488 + m68ki_fake_push_16(); 1.1489 + 1.1490 + /* DATA OUTPUT BUFFER */ 1.1491 + m68ki_push_16(0); 1.1492 + 1.1493 + /* UNUSED, RESERVED (not written) */ 1.1494 + m68ki_fake_push_16(); 1.1495 + 1.1496 + /* FAULT ADDRESS */ 1.1497 + m68ki_push_32(0); 1.1498 + 1.1499 + /* SPECIAL STATUS WORD */ 1.1500 + m68ki_push_16(0); 1.1501 + 1.1502 + /* 1000, VECTOR OFFSET */ 1.1503 + m68ki_push_16(0x8000 | (vector<<2)); 1.1504 + 1.1505 + /* PROGRAM COUNTER */ 1.1506 + m68ki_push_32(pc); 1.1507 + 1.1508 + /* STATUS REGISTER */ 1.1509 + m68ki_push_16(sr); 1.1510 +} 1.1511 + 1.1512 +/* Format A stack frame (short bus fault). 1.1513 + * This is used only by 68020 for bus fault and address error 1.1514 + * if the error happens at an instruction boundary. 1.1515 + * PC stacked is address of next instruction. 1.1516 + */ 1.1517 +void m68ki_stack_frame_1010(uint sr, uint vector, uint pc) 1.1518 +{ 1.1519 + /* INTERNAL REGISTER */ 1.1520 + m68ki_push_16(0); 1.1521 + 1.1522 + /* INTERNAL REGISTER */ 1.1523 + m68ki_push_16(0); 1.1524 + 1.1525 + /* DATA OUTPUT BUFFER (2 words) */ 1.1526 + m68ki_push_32(0); 1.1527 + 1.1528 + /* INTERNAL REGISTER */ 1.1529 + m68ki_push_16(0); 1.1530 + 1.1531 + /* INTERNAL REGISTER */ 1.1532 + m68ki_push_16(0); 1.1533 + 1.1534 + /* DATA CYCLE FAULT ADDRESS (2 words) */ 1.1535 + m68ki_push_32(0); 1.1536 + 1.1537 + /* INSTRUCTION PIPE STAGE B */ 1.1538 + m68ki_push_16(0); 1.1539 + 1.1540 + /* INSTRUCTION PIPE STAGE C */ 1.1541 + m68ki_push_16(0); 1.1542 + 1.1543 + /* SPECIAL STATUS REGISTER */ 1.1544 + m68ki_push_16(0); 1.1545 + 1.1546 + /* INTERNAL REGISTER */ 1.1547 + m68ki_push_16(0); 1.1548 + 1.1549 + /* 1010, VECTOR OFFSET */ 1.1550 + m68ki_push_16(0xa000 | (vector<<2)); 1.1551 + 1.1552 + /* PROGRAM COUNTER */ 1.1553 + m68ki_push_32(pc); 1.1554 + 1.1555 + /* STATUS REGISTER */ 1.1556 + m68ki_push_16(sr); 1.1557 +} 1.1558 + 1.1559 +/* Format B stack frame (long bus fault). 1.1560 + * This is used only by 68020 for bus fault and address error 1.1561 + * if the error happens during instruction execution. 1.1562 + * PC stacked is address of instruction in progress. 1.1563 + */ 1.1564 +void m68ki_stack_frame_1011(uint sr, uint vector, uint pc) 1.1565 +{ 1.1566 + /* INTERNAL REGISTERS (18 words) */ 1.1567 + m68ki_push_32(0); 1.1568 + m68ki_push_32(0); 1.1569 + m68ki_push_32(0); 1.1570 + m68ki_push_32(0); 1.1571 + m68ki_push_32(0); 1.1572 + m68ki_push_32(0); 1.1573 + m68ki_push_32(0); 1.1574 + m68ki_push_32(0); 1.1575 + m68ki_push_32(0); 1.1576 + 1.1577 + /* VERSION# (4 bits), INTERNAL INFORMATION */ 1.1578 + m68ki_push_16(0); 1.1579 + 1.1580 + /* INTERNAL REGISTERS (3 words) */ 1.1581 + m68ki_push_32(0); 1.1582 + m68ki_push_16(0); 1.1583 + 1.1584 + /* DATA INTPUT BUFFER (2 words) */ 1.1585 + m68ki_push_32(0); 1.1586 + 1.1587 + /* INTERNAL REGISTERS (2 words) */ 1.1588 + m68ki_push_32(0); 1.1589 + 1.1590 + /* STAGE B ADDRESS (2 words) */ 1.1591 + m68ki_push_32(0); 1.1592 + 1.1593 + /* INTERNAL REGISTER (4 words) */ 1.1594 + m68ki_push_32(0); 1.1595 + m68ki_push_32(0); 1.1596 + 1.1597 + /* DATA OUTPUT BUFFER (2 words) */ 1.1598 + m68ki_push_32(0); 1.1599 + 1.1600 + /* INTERNAL REGISTER */ 1.1601 + m68ki_push_16(0); 1.1602 + 1.1603 + /* INTERNAL REGISTER */ 1.1604 + m68ki_push_16(0); 1.1605 + 1.1606 + /* DATA CYCLE FAULT ADDRESS (2 words) */ 1.1607 + m68ki_push_32(0); 1.1608 + 1.1609 + /* INSTRUCTION PIPE STAGE B */ 1.1610 + m68ki_push_16(0); 1.1611 + 1.1612 + /* INSTRUCTION PIPE STAGE C */ 1.1613 + m68ki_push_16(0); 1.1614 + 1.1615 + /* SPECIAL STATUS REGISTER */ 1.1616 + m68ki_push_16(0); 1.1617 + 1.1618 + /* INTERNAL REGISTER */ 1.1619 + m68ki_push_16(0); 1.1620 + 1.1621 + /* 1011, VECTOR OFFSET */ 1.1622 + m68ki_push_16(0xb000 | (vector<<2)); 1.1623 + 1.1624 + /* PROGRAM COUNTER */ 1.1625 + m68ki_push_32(pc); 1.1626 + 1.1627 + /* STATUS REGISTER */ 1.1628 + m68ki_push_16(sr); 1.1629 +} 1.1630 + 1.1631 + 1.1632 +/* Used for Group 2 exceptions. 1.1633 + * These stack a type 2 frame on the 020. 1.1634 + */ 1.1635 +INLINE void m68ki_exception_trap(uint vector) 1.1636 +{ 1.1637 + uint sr = m68ki_init_exception(); 1.1638 + 1.1639 + if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) 1.1640 + m68ki_stack_frame_0000(REG_PC, sr, vector); 1.1641 + else 1.1642 + m68ki_stack_frame_0010(sr, vector); 1.1643 + 1.1644 + m68ki_jump_vector(vector); 1.1645 + 1.1646 + /* Use up some clock cycles */ 1.1647 + USE_CYCLES(CYC_EXCEPTION[vector]); 1.1648 +} 1.1649 + 1.1650 +/* Trap#n stacks a 0 frame but behaves like group2 otherwise */ 1.1651 +INLINE void m68ki_exception_trapN(uint vector) 1.1652 +{ 1.1653 + uint sr = m68ki_init_exception(); 1.1654 + m68ki_stack_frame_0000(REG_PC, sr, vector); 1.1655 + m68ki_jump_vector(vector); 1.1656 + 1.1657 + /* Use up some clock cycles */ 1.1658 + USE_CYCLES(CYC_EXCEPTION[vector]); 1.1659 +} 1.1660 + 1.1661 +/* Exception for trace mode */ 1.1662 +INLINE void m68ki_exception_trace(void) 1.1663 +{ 1.1664 + uint sr = m68ki_init_exception(); 1.1665 + 1.1666 + if(CPU_TYPE_IS_010_LESS(CPU_TYPE)) 1.1667 + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_TRACE); 1.1668 + else 1.1669 + m68ki_stack_frame_0010(sr, EXCEPTION_TRACE); 1.1670 + 1.1671 + m68ki_jump_vector(EXCEPTION_TRACE); 1.1672 + 1.1673 + /* Trace nullifies a STOP instruction */ 1.1674 + CPU_STOPPED &= ~STOP_LEVEL_STOP; 1.1675 + 1.1676 + /* Use up some clock cycles */ 1.1677 + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]); 1.1678 +} 1.1679 + 1.1680 +/* Exception for privilege violation */ 1.1681 +INLINE void m68ki_exception_privilege_violation(void) 1.1682 +{ 1.1683 + uint sr = m68ki_init_exception(); 1.1684 + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_PRIVILEGE_VIOLATION); 1.1685 + m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION); 1.1686 + 1.1687 + /* Use up some clock cycles and undo the instruction's cycles */ 1.1688 + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]); 1.1689 +} 1.1690 + 1.1691 +/* Exception for A-Line instructions */ 1.1692 +INLINE void m68ki_exception_1010(void) 1.1693 +{ 1.1694 + uint sr; 1.1695 +#if M68K_LOG_1010_1111 == OPT_ON 1.1696 + M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n", 1.1697 + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, 1.1698 + m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); 1.1699 +#endif 1.1700 + 1.1701 + sr = m68ki_init_exception(); 1.1702 + m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1010); 1.1703 + m68ki_jump_vector(EXCEPTION_1010); 1.1704 + 1.1705 + /* Use up some clock cycles and undo the instruction's cycles */ 1.1706 + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]); 1.1707 +} 1.1708 + 1.1709 +/* Exception for F-Line instructions */ 1.1710 +INLINE void m68ki_exception_1111(void) 1.1711 +{ 1.1712 + uint sr; 1.1713 + 1.1714 +#if M68K_LOG_1010_1111 == OPT_ON 1.1715 + M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n", 1.1716 + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, 1.1717 + m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); 1.1718 +#endif 1.1719 + 1.1720 + sr = m68ki_init_exception(); 1.1721 + m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1111); 1.1722 + m68ki_jump_vector(EXCEPTION_1111); 1.1723 + 1.1724 + /* Use up some clock cycles and undo the instruction's cycles */ 1.1725 + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]); 1.1726 +} 1.1727 + 1.1728 +/* Exception for illegal instructions */ 1.1729 +INLINE void m68ki_exception_illegal(void) 1.1730 +{ 1.1731 + uint sr; 1.1732 + 1.1733 + M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n", 1.1734 + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, 1.1735 + m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); 1.1736 + 1.1737 + sr = m68ki_init_exception(); 1.1738 + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_ILLEGAL_INSTRUCTION); 1.1739 + m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION); 1.1740 + 1.1741 + /* Use up some clock cycles and undo the instruction's cycles */ 1.1742 + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]); 1.1743 +} 1.1744 + 1.1745 +/* Exception for format errror in RTE */ 1.1746 +INLINE void m68ki_exception_format_error(void) 1.1747 +{ 1.1748 + uint sr = m68ki_init_exception(); 1.1749 + m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR); 1.1750 + m68ki_jump_vector(EXCEPTION_FORMAT_ERROR); 1.1751 + 1.1752 + /* Use up some clock cycles and undo the instruction's cycles */ 1.1753 + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]); 1.1754 +} 1.1755 + 1.1756 +/* Exception for address error */ 1.1757 +INLINE void m68ki_exception_address_error(void) 1.1758 +{ 1.1759 + /* Not emulated yet */ 1.1760 +} 1.1761 + 1.1762 + 1.1763 +/* Service an interrupt request and start exception processing */ 1.1764 +void m68ki_exception_interrupt(uint int_level) 1.1765 +{ 1.1766 + uint vector; 1.1767 + uint sr; 1.1768 + uint new_pc; 1.1769 + 1.1770 + /* Turn off the stopped state */ 1.1771 + CPU_STOPPED &= ~STOP_LEVEL_STOP; 1.1772 + 1.1773 + /* If we are halted, don't do anything */ 1.1774 + if(CPU_STOPPED) 1.1775 + return; 1.1776 + 1.1777 + /* Acknowledge the interrupt */ 1.1778 + vector = m68ki_int_ack(int_level); 1.1779 + 1.1780 + /* Get the interrupt vector */ 1.1781 + if(vector == M68K_INT_ACK_AUTOVECTOR) 1.1782 + /* Use the autovectors. This is the most commonly used implementation */ 1.1783 + vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level; 1.1784 + else if(vector == M68K_INT_ACK_SPURIOUS) 1.1785 + /* Called if no devices respond to the interrupt acknowledge */ 1.1786 + vector = EXCEPTION_SPURIOUS_INTERRUPT; 1.1787 + else if(vector > 255) 1.1788 + { 1.1789 + M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: Interrupt acknowledge returned invalid vector $%x\n", 1.1790 + m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC), vector)); 1.1791 + return; 1.1792 + } 1.1793 + 1.1794 + /* Start exception processing */ 1.1795 + sr = m68ki_init_exception(); 1.1796 + 1.1797 + /* Set the interrupt mask to the level of the one being serviced */ 1.1798 + FLAG_INT_MASK = int_level<<8; 1.1799 + 1.1800 + /* Get the new PC */ 1.1801 + new_pc = m68ki_read_data_32((vector<<2) + REG_VBR); 1.1802 + 1.1803 + /* If vector is uninitialized, call the uninitialized interrupt vector */ 1.1804 + if(new_pc == 0) 1.1805 + new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + REG_VBR); 1.1806 + 1.1807 + /* Generate a stack frame */ 1.1808 + m68ki_stack_frame_0000(REG_PC, sr, vector); 1.1809 + if(FLAG_M && CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) 1.1810 + { 1.1811 + /* Create throwaway frame */ 1.1812 + m68ki_set_sm_flag(FLAG_S); /* clear M */ 1.1813 + sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */ 1.1814 + m68ki_stack_frame_0001(REG_PC, sr, vector); 1.1815 + } 1.1816 + 1.1817 + m68ki_jump(new_pc); 1.1818 + 1.1819 + /* Defer cycle counting until later */ 1.1820 + CPU_INT_CYCLES += CYC_EXCEPTION[vector]; 1.1821 + 1.1822 +#if !M68K_EMULATE_INT_ACK 1.1823 + /* Automatically clear IRQ if we are not using an acknowledge scheme */ 1.1824 + CPU_INT_LEVEL = 0; 1.1825 +#endif /* M68K_EMULATE_INT_ACK */ 1.1826 +} 1.1827 + 1.1828 + 1.1829 +/* ASG: Check for interrupts */ 1.1830 +INLINE void m68ki_check_interrupts(void) 1.1831 +{ 1.1832 + if(CPU_INT_LEVEL > FLAG_INT_MASK) 1.1833 + m68ki_exception_interrupt(CPU_INT_LEVEL>>8); 1.1834 +} 1.1835 + 1.1836 + 1.1837 + 1.1838 +/* ======================================================================== */ 1.1839 +/* ============================== END OF FILE ============================= */ 1.1840 +/* ======================================================================== */ 1.1841 + 1.1842 +#endif /* M68KCPU__HEADER */