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