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