|
|
1.1.1.4 ! root 1: /* $Id: m68k-impl.h,v 1.18 2007/03/29 01:36:10 fredette Exp $ */ 1.1 root 2: 3: /* ic/m68k/m68k-impl.h - implementation header file for Motorola 68k emulation: */ 4: 5: /* 6: * Copyright (c) 2002, 2003 Matt Fredette 7: * All rights reserved. 8: * 9: * Redistribution and use in source and binary forms, with or without 10: * modification, are permitted provided that the following conditions 11: * are met: 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 2. Redistributions in binary form must reproduce the above copyright 15: * notice, this list of conditions and the following disclaimer in the 16: * documentation and/or other materials provided with the distribution. 17: * 3. All advertising materials mentioning features or use of this software 18: * must display the following acknowledgement: 19: * This product includes software developed by Matt Fredette. 20: * 4. The name of the author may not be used to endorse or promote products 21: * derived from this software without specific prior written permission. 22: * 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33: * POSSIBILITY OF SUCH DAMAGE. 34: */ 35: 36: #ifndef _IC_M68K_IMPL_H 37: #define _IC_M68K_IMPL_H 38: 39: #include <tme/common.h> 1.1.1.4 ! root 40: _TME_RCSID("$Id: m68k-impl.h,v 1.18 2007/03/29 01:36:10 fredette Exp $"); 1.1 root 41: 42: /* includes: */ 43: #include <tme/ic/m68k.h> 1.1.1.3 root 44: #include <tme/ic/ieee754.h> 1.1 root 45: #include <tme/generic/ic.h> 46: #include <setjmp.h> 47: 48: /* macros: */ 49: 50: /* CPUs: */ 51: #define TME_M68K_M68000 (0) 52: #define TME_M68K_M68010 (1) 53: #define TME_M68K_M68020 (2) 54: #define TME_M68K_M68030 (3) 1.1.1.3 root 55: #define TME_M68K_M68040 (4) 56: 57: /* FPUs: */ 58: #define TME_M68K_FPU_NONE (0) 59: #define TME_M68K_FPU_M68881 TME_BIT(0) 60: #define TME_M68K_FPU_M68882 TME_BIT(1) 61: #define TME_M68K_FPU_M6888X (TME_M68K_FPU_M68881 | TME_M68K_FPU_M68882) 62: #define TME_M68K_FPU_M68040 TME_BIT(2) 63: #define TME_M68K_FPU_ANY (TME_M68K_FPU_M68881 | TME_M68K_FPU_M68882 | TME_M68K_FPU_M68040) 1.1 root 64: 65: /* generic registers: */ 66: #define tme_m68k_ireg_uint32(x) tme_m68k_ic.tme_ic_ireg_uint32(x) 67: #define tme_m68k_ireg_int32(x) tme_m68k_ic.tme_ic_ireg_int32(x) 68: #define tme_m68k_ireg_uint16(x) tme_m68k_ic.tme_ic_ireg_uint16(x) 69: #define tme_m68k_ireg_int16(x) tme_m68k_ic.tme_ic_ireg_int16(x) 70: #define tme_m68k_ireg_uint8(x) tme_m68k_ic.tme_ic_ireg_uint8(x) 71: #define tme_m68k_ireg_int8(x) tme_m68k_ic.tme_ic_ireg_int8(x) 72: 73: /* flags: */ 74: #define TME_M68K_FLAG_C TME_BIT(0) 75: #define TME_M68K_FLAG_V TME_BIT(1) 76: #define TME_M68K_FLAG_Z TME_BIT(2) 77: #define TME_M68K_FLAG_N TME_BIT(3) 78: #define TME_M68K_FLAG_X TME_BIT(4) 79: #define TME_M68K_FLAG_IPM(x) TME_FIELD_EXTRACTU(x, 8, 3) 80: #define TME_M68K_FLAG_M TME_BIT(12) 81: #define TME_M68K_FLAG_S TME_BIT(13) 1.1.1.3 root 82: #define TME_M68K_FLAG_T0 TME_BIT(14) 83: #define TME_M68K_FLAG_T1 TME_BIT(15) 1.1 root 84: #define TME_M68K_FLAG_CCR (TME_M68K_FLAG_C | TME_M68K_FLAG_V | \ 85: TME_M68K_FLAG_Z | TME_M68K_FLAG_N | \ 86: TME_M68K_FLAG_X) 87: #define TME_M68K_FLAG_SR (TME_M68K_FLAG_CCR | (0x7 << 8) | \ 88: TME_M68K_FLAG_M | TME_M68K_FLAG_S | \ 1.1.1.3 root 89: TME_M68K_FLAG_T0 | TME_M68K_FLAG_T1) 1.1 root 90: 91: /* conditions: */ 92: #define TME_M68K_C_T (0) 93: #define TME_M68K_C_F (1) 94: #define TME_M68K_C_HI (2) 95: #define TME_M68K_C_LS (3) 96: #define TME_M68K_C_CC (4) 97: #define TME_M68K_C_CS (5) 98: #define TME_M68K_C_NE (6) 99: #define TME_M68K_C_EQ (7) 100: #define TME_M68K_C_VC (8) 101: #define TME_M68K_C_VS (9) 102: #define TME_M68K_C_PL (10) 103: #define TME_M68K_C_MI (11) 104: #define TME_M68K_C_GE (12) 105: #define TME_M68K_C_LT (13) 106: #define TME_M68K_C_GT (14) 107: #define TME_M68K_C_LE (15) 108: #define TME_M68K_COND_TRUE(ic, c) (_tme_m68k_conditions[(ic)->tme_m68k_ireg_ccr] & TME_BIT(c)) 109: 110: /* bus cycles: */ 111: #define TME_M68K_BUS_CYCLE_NORMAL (0) 112: #define TME_M68K_BUS_CYCLE_READ TME_BIT(0) 113: #define TME_M68K_BUS_CYCLE_FETCH TME_BIT(1) 114: #define TME_M68K_BUS_CYCLE_RMW TME_BIT(2) 115: #define TME_M68K_BUS_CYCLE_RAW TME_BIT(3) 116: 117: /* exceptions: */ 118: #define TME_M68K_EXCEPTION_NONE (0) 1.1.1.3 root 119: #define TME_M68K_EXCEPTION_RESET TME_BIT(0) 120: #define TME_M68K_EXCEPTION_AERR TME_BIT(1) 121: #define TME_M68K_EXCEPTION_BERR TME_BIT(2) 122: #define TME_M68K_EXCEPTION_TRACE TME_BIT(3) 123: #define TME_M68K_EXCEPTION_INT(ipl, vec) (((ipl) << 4) | ((vec) << 7)) 124: #define TME_M68K_EXCEPTION_IS_INT(x) (((x) >> 4) & 0x7) 125: #define TME_M68K_EXCEPTION_INT_VEC(x) (((x) >> 7) & 0xff) 126: #define TME_M68K_EXCEPTION_ILL TME_BIT(15) 127: #define TME_M68K_EXCEPTION_PRIV TME_BIT(16) 128: #define TME_M68K_EXCEPTION_INST(x) ((x) << 17) 129: #define TME_M68K_EXCEPTION_IS_INST(x) ((x) >> 17) 1.1 root 130: 131: /* exception frame formats: */ 132: #define TME_M68K_FORMAT_0 (0) 1.1.1.3 root 133: #define TME_M68K_FORMAT_1 (1) 134: #define TME_M68K_FORMAT_2 (2) 1.1 root 135: #define TME_M68K_FORMAT_8 (8) 1.1.1.3 root 136: #define TME_M68K_FORMAT_B (0xB) 137: 138: /* exception vectors: */ 139: #define TME_M68K_VECTOR_RESET_PC (0x00) 140: #define TME_M68K_VECTOR_RESET_SP (0x01) 141: #define TME_M68K_VECTOR_BERR (0x02) 142: #define TME_M68K_VECTOR_AERR (0x03) 143: #define TME_M68K_VECTOR_ILL (0x04) 144: #define TME_M68K_VECTOR_DIV0 (0x05) 145: #define TME_M68K_VECTOR_CHK (0x06) 146: #define TME_M68K_VECTOR_TRAP (0x07) 147: #define TME_M68K_VECTOR_PRIV (0x08) 148: #define TME_M68K_VECTOR_TRACE (0x09) 149: #define TME_M68K_VECTOR_LINE_A (0x0a) 150: #define TME_M68K_VECTOR_LINE_F (0x0b) 151: /* (0x0c is unassigned, reserved) */ 152: #define TME_M68K_VECTOR_COPROC (0x0d) 153: #define TME_M68K_VECTOR_FORMAT (0x0e) 154: #define TME_M68K_VECTOR_INT_UNINIT (0x0f) 155: /* (0x10 through 0x17 are unassigned, reserved) */ 156: #define TME_M68K_VECTOR_SPURIOUS (0x18) 157: /* (0x19 through 0x1f are the interrupt autovectors) */ 158: #define TME_M68K_VECTOR_TRAP_0 (0x20) 159: /* (0x21 through 0x2f are also TRAP vectors) */ 160: 161: /* m6888x type specifiers: */ 162: #define TME_M6888X_TYPE_LONG (0) 163: #define TME_M6888X_TYPE_SINGLE (1) 164: #define TME_M6888X_TYPE_EXTENDED80 (2) 165: #define TME_M6888X_TYPE_PACKEDDEC (3) 166: #define TME_M6888X_TYPE_WORD (4) 167: #define TME_M6888X_TYPE_DOUBLE (5) 168: #define TME_M6888X_TYPE_BYTE (6) 169: #define TME_M6888X_TYPE_PACKEDDEC_DK (7) 170: #define TME_M6888X_TYPE_INVALID (TME_M6888X_TYPE_PACKEDDEC_DK) 1.1 root 171: 172: /* sizes: */ 173: #define TME_M68K_SIZE_UNDEF (-1) 174: #define TME_M68K_SIZE_UNSIZED (0) 175: #define TME_M68K_SIZE_8 (1) 176: #define TME_M68K_SIZE_16 (2) 1.1.1.3 root 177: /* 3 unused */ 1.1 root 178: #define TME_M68K_SIZE_32 (4) 1.1.1.3 root 179: /* 5 unused */ 180: /* 6 unused */ 181: /* 7 unused */ 182: #define TME_M68K_SIZE_64 (8) 183: /* 8 unused */ 184: /* 9 unused */ 185: /* 10 unused */ 186: /* 11 unused */ 187: #define TME_M68K_SIZE_96 (12) 188: 189: /* opcode parameters: */ 190: 191: /* bits 0 through 7, in the opcode map, are the instruction index. 192: immediately after the initial decoding, these bits are replaced 193: with the least significant 8 bits of the opcode word, making bits 0 194: through 2 any EA reg value, and bits 3 through 5 any EA mode 195: value: */ 196: #define TME_M68K_OPCODE_INSN(x) ((x) << 0) 197: #define TME_M68K_OPCODE_INSN_MASK TME_M68K_OPCODE_INSN(0xff) 198: #define TME_M68K_OPCODE_INSN_WHICH(params) TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_INSN(0xff)) 199: #define TME_M68K_OPCODE_EA_REG(x) ((x) << 0) 200: #define TME_M68K_OPCODE_EA_MODE(x) ((x) << 3) 201: #define TME_M68K_OPCODE_EA_REG_MASK TME_M68K_OPCODE_EA_REG(0x7) 202: #define TME_M68K_OPCODE_EA_MODE_MASK TME_M68K_OPCODE_EA_MODE(0x7) 203: #define TME_M68K_OPCODE_EA_MODE_WHICH(params) TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_MODE_MASK) 204: #define TME_M68K_OPCODE_EA_REG_WHICH(params) TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_REG_MASK) 205: 206: /* bits 8 through 15 and 16 through 23 are the operands' ic offsets: */ 207: #define _TME_M68K_OPCODE_OP(f) ((tme_uint8_t) (((tme_uint8_t *) &((struct tme_m68k *) 0)->f) - ((tme_uint8_t *) (struct tme_m68k *) 0))) 208: #define TME_M68K_OPCODE_OP1(f) (_TME_M68K_OPCODE_OP(f) << 8) 209: #define TME_M68K_OPCODE_OP0(f) (_TME_M68K_OPCODE_OP(f) << 16) 210: #define TME_M68K_OPCODE_OP1_WHICH(ic, params) (((tme_uint8_t *) (ic)) + TME_FIELD_MASK_EXTRACTU(params, 0x0000ff00)) 211: #define TME_M68K_OPCODE_OP0_WHICH(ic, params) (((tme_uint8_t *) (ic)) + TME_FIELD_MASK_EXTRACTU(params, 0x00ff0000)) 212: 213: /* bits 24 and 25 give the size of any immediate operand: */ 214: #define TME_M68K_OPCODE_IMM_16 TME_BIT(24) 215: #define TME_M68K_OPCODE_IMM_32 TME_BIT(25) 216: #define TME_M68K_OPCODE_HAS_IMM(params) (((params) & (TME_M68K_OPCODE_IMM_16 | TME_M68K_OPCODE_IMM_32)) != 0) 217: 218: /* bit 26 is set for a move instruction with a memory destination 219: ((TME_M68K_OPCODE_SPECOP is additionally set for a 220: move-memory-to-memory instruction). 221: bit 27 is set for an opcode that needs its EA read. 222: bit 28 is set for an opcode that needs its EA written. 223: 224: if the EA needs to be read or written, bits 29 and 30 give the size 225: of the EA, which can be TME_M68K_SIZE_8, TME_M68K_SIZE_16, or 226: TME_M68K_SIZE_32, encoded as (TME_M68K_SIZE_32 - size). if the EA 227: doesn't need to be read or written, but the EA must be calculated, 228: bit 29 is set, and size of the EA is understood to be 229: TME_M68K_SIZE_UNSIZED: */ 230: #define TME_M68K_OPCODE_EA_Y TME_BIT(26) 231: #define TME_M68K_OPCODE_EA_READ TME_BIT(27) 232: #define TME_M68K_OPCODE_EA_WRITE TME_BIT(28) 233: #define TME_M68K_OPCODE_EA_UNSIZED TME_BIT(29) 234: #define TME_M68K_OPCODE_EA_SIZE(x) ((TME_M68K_SIZE_32 - (x)) * TME_M68K_OPCODE_EA_UNSIZED) 235: #define TME_M68K_OPCODE_EA_SIZE_MASK TME_M68K_OPCODE_EA_SIZE(1) 236: #define TME_M68K_OPCODE_HAS_EA(params) ((params) & (TME_M68K_OPCODE_EA_READ | TME_M68K_OPCODE_EA_WRITE | TME_M68K_OPCODE_EA_UNSIZED)) 237: #define TME_M68K_OPCODE_EA_SIZE_WHICH(params) \ 238: (((params) & (TME_M68K_OPCODE_EA_READ | TME_M68K_OPCODE_EA_WRITE)) ? \ 239: (TME_M68K_SIZE_32 \ 240: - TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_SIZE_MASK)) \ 241: : TME_M68K_SIZE_UNSIZED) 1.1 root 242: 1.1.1.3 root 243: /* if the opcode is special, bit 31 is set: */ 244: #define TME_M68K_OPCODE_SPECOP TME_BIT(31) 1.1 root 245: 246: /* major modes of the emulator: */ 247: #define TME_M68K_MODE_EXECUTION (0) 248: #define TME_M68K_MODE_EXCEPTION (1) 249: #define TME_M68K_MODE_RTE (2) 250: #define TME_M68K_MODE_STOP (3) 251: #define TME_M68K_MODE_HALT (4) 252: 253: /* mode-specific flags: */ 254: #define TME_M68K_EXECUTION_INST_CANFAULT TME_BIT(0) 255: 256: /* given a linear address, this hashes it into a TLB entry: */ 257: #define _TME_M68K_TLB_HASH_SIZE (1024) 1.1.1.4 ! root 258: #define TME_M68K_TLB_ADDRESS_BIAS(n) ((n) << 10) ! 259: #define TME_M68K_TLB_ENTRY_SET(set, function_code, linear_address) \ ! 260: (((set) \ ! 261: + (((linear_address) \ ! 262: / TME_M68K_TLB_ADDRESS_BIAS(1)) \ ! 263: % _TME_M68K_TLB_HASH_SIZE)) \ ! 264: + (0 && (function_code))) 1.1 root 265: #define TME_M68K_TLB_ENTRY(ic, function_code, linear_address) \ 1.1.1.4 ! root 266: TME_M68K_TLB_ENTRY_SET(tme_memory_atomic_pointer_read(struct tme_m68k_tlb *,\ ! 267: (ic)->_tme_m68k_tlb_array,\ ! 268: &(ic)->_tme_m68k_tlbs_rwlock),\ ! 269: function_code, linear_address) 1.1 root 270: 271: /* macros for sequence control: */ 272: #define TME_M68K_SEQUENCE_START \ 273: do { \ 274: ic->_tme_m68k_sequence._tme_m68k_sequence_mode_flags = 0; \ 275: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = 0; \ 276: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1; \ 277: } while (/* CONSTCOND */ 0) 278: #define TME_M68K_SEQUENCE_RESTARTING \ 279: (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted \ 280: >= ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) 281: #define TME_M68K_SEQUENCE_RESTART \ 282: do { \ 283: if (!TME_M68K_SEQUENCE_RESTARTING) \ 284: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = \ 285: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next; \ 286: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1; \ 287: } while (/* CONSTCOND */ 0) 288: #define TME_M68K_SEQUENCE_TRANSFER_STEP \ 289: do { \ 290: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next++; \ 291: } while (/* CONSTCOND */ 0) 292: 293: /* instruction handler macros: */ 294: #define TME_M68K_INSN_DECL(name) void name _TME_P((struct tme_m68k *, void *, void *)) 295: #ifdef __STDC__ 296: #define TME_M68K_INSN(name) void name(struct tme_m68k *ic, void *_op0, void *_op1) 297: #else /* !__STDC__ */ 298: #define TME_M68K_INSN(name) void name(ic, _op0, _op1) struct tme_m68k *ic; void *_op0, *_op1; 299: #endif /* !__STDC__ */ 300: #define TME_M68K_INSN_OP0(t) (*((t *) _op0)) 301: #define TME_M68K_INSN_OP1(t) (*((t *) _op1)) 302: #define TME_M68K_INSN_OPCODE ic->_tme_m68k_insn_opcode 303: #define TME_M68K_INSN_SPECOP ic->_tme_m68k_insn_specop 304: #define TME_M68K_INSN_OK return 305: #define TME_M68K_INSN_EXCEPTION(e) tme_m68k_exception(ic, e) 306: #define TME_M68K_INSN_PRIV \ 307: if (!TME_M68K_PRIV(ic)) \ 1.1.1.3 root 308: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_PRIV) 1.1 root 309: #define TME_M68K_INSN_ILL \ 1.1.1.3 root 310: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL) 1.1 root 311: #define TME_M68K_INSN_CANFAULT \ 312: do { \ 313: ic->_tme_m68k_mode_flags \ 314: |= TME_M68K_EXECUTION_INST_CANFAULT; \ 315: } while (/* CONSTCOND */ 0) 316: #define TME_M68K_INSN_BRANCH(pc) \ 317: do { \ 318: tme_m68k_verify_end_branch(ic, pc); \ 319: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next = (pc); \ 1.1.1.3 root 320: if (__tme_predict_false((ic->tme_m68k_ireg_sr \ 321: & ic->_tme_m68k_sr_mask_t) != 0)) { \ 322: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE); \ 323: } \ 1.1 root 324: if (tme_m68k_go_slow(ic)) { \ 325: TME_M68K_SEQUENCE_START; \ 326: tme_m68k_redispatch(ic); \ 327: } \ 328: } while (/* CONSTCOND */ 0) 329: #define TME_M68K_INSN_CHANGE_SR(reg) \ 330: do { \ 331: TME_M68K_INSN_PRIV; \ 332: tme_m68k_change_sr(ic, reg); \ 1.1.1.3 root 333: tme_m68k_verify_end_branch(ic, ic->tme_m68k_ireg_pc_next); \ 334: if (__tme_predict_false((ic->tme_m68k_ireg_sr \ 335: & ic->_tme_m68k_sr_mask_t) != 0)) { \ 336: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; \ 337: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; \ 338: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE); \ 339: } \ 340: if (tme_m68k_go_slow(ic)) { \ 341: TME_M68K_SEQUENCE_START; \ 342: tme_m68k_redispatch(ic); \ 343: } \ 1.1 root 344: } while (/* CONSTCOND */ 0) 345: 346: /* logging: */ 347: #define TME_M68K_LOG_HANDLE(ic) \ 348: (&(ic)->tme_m68k_element->tme_element_log_handle) 349: #define tme_m68k_log_start(ic, level, rc) \ 350: do { \ 351: tme_log_start(TME_M68K_LOG_HANDLE(ic), level, rc) { \ 352: if ((ic)->_tme_m68k_mode != TME_M68K_MODE_EXECUTION) { \ 353: tme_log_part(TME_M68K_LOG_HANDLE(ic), \ 354: "mode=%d ", \ 355: (ic)->_tme_m68k_mode); \ 356: } \ 357: else { \ 358: tme_log_part(TME_M68K_LOG_HANDLE(ic), \ 359: "pc=%c/0x%08x ", \ 360: (((ic)->tme_m68k_ireg_sr \ 361: & (TME_M68K_FLAG_M \ 362: | TME_M68K_FLAG_S)) \ 363: ? 'S' \ 364: : 'U'), \ 365: ic->tme_m68k_ireg_pc); \ 366: } \ 367: do 368: #define tme_m68k_log_finish(ic) \ 369: while (/* CONSTCOND */ 0); \ 370: } tme_log_finish(TME_M68K_LOG_HANDLE(ic)); \ 371: } while (/* CONSTCOND */ 0) 372: #define tme_m68k_log(ic, level, rc, x) \ 373: do { \ 374: tme_m68k_log_start(ic, level, rc) { \ 375: tme_log_part x; \ 376: } tme_m68k_log_finish(ic); \ 377: } while (/* CONSTCOND */ 0) 378: 379: /* miscellaneous: */ 380: #define TME_M68K_PRIV(ic) ((ic)->tme_m68k_ireg_sr & TME_M68K_FLAG_S) 381: #define TME_M68K_FUNCTION_CODE_DATA(ic) \ 382: (TME_M68K_PRIV(ic) ? TME_M68K_FC_SD : TME_M68K_FC_UD) 383: #define TME_M68K_FUNCTION_CODE_PROGRAM(ic) \ 384: (TME_M68K_PRIV(ic) ? TME_M68K_FC_SP : TME_M68K_FC_UP) 385: #define TME_M68K_INSN_WORDS_MAX (11) 386: 387: /* structures: */ 388: struct tme_m68k; 389: 390: /* an memory read or write function: */ 391: typedef void (*_tme_m68k_xfer_memx) _TME_P((struct tme_m68k *)); 392: typedef void (*_tme_m68k_xfer_mem) _TME_P((struct tme_m68k *, int)); 393: 1.1.1.3 root 394: /* an insn function: */ 395: typedef TME_M68K_INSN_DECL((*_tme_m68k_insn)); 1.1 root 396: 397: /* an m68k sequence: */ 398: struct _tme_m68k_sequence { 399: 400: /* the mode of the emulator: */ 1.1.1.2 root 401: unsigned int _tme_m68k_sequence_mode; 1.1 root 402: 403: /* any mode-specific flags for the sequence: */ 1.1.1.2 root 404: unsigned int _tme_m68k_sequence_mode_flags; 1.1 root 405: 406: /* the ordinal of the next memory transfer. always starts from one: */ 407: unsigned short _tme_m68k_sequence_transfer_next; 408: 409: /* the ordinal of the memory transfer that faulted. if this is 410: greater than or equal to _tme_m68k_sequence_transfer_next, we are 411: restarting, and bus cycles and changes to the m68k state are 412: forbidden: */ 413: unsigned short _tme_m68k_sequence_transfer_faulted; 414: 415: /* the fault happened after this number of bytes were successfully 416: transferred: */ 417: unsigned short _tme_m68k_sequence_transfer_faulted_after; 418: 419: #ifdef _TME_M68K_VERIFY 420: /* the sequence unique identifier: */ 421: unsigned long _tme_m68k_sequence_uid; 422: #endif /* _TME_M68K_VERIFY */ 423: }; 424: 425: /* the m68k state: */ 426: struct tme_m68k { 427: 428: /* the IC data structure. it is beneficial to have this structure 429: first, since register numbers can often simply be scaled and 430: added without an offset to the struct tme_m68k pointer to get 431: to their contents: */ 432: struct tme_ic tme_m68k_ic; 433: 434: /* the m68k type: */ 435: int tme_m68k_type; 436: 437: /* the backpointer to our element: */ 438: struct tme_element *tme_m68k_element; 439: 440: /* our bus connection. if both are defined, the m68k bus connection 441: is an adaptation layer for the generic bus connection: */ 442: struct tme_m68k_bus_connection *_tme_m68k_bus_connection; 443: struct tme_bus_connection *_tme_m68k_bus_generic; 444: 445: /* a jmp_buf back to the dispatcher: */ 446: jmp_buf _tme_m68k_dispatcher; 447: 448: /* the current sequence: */ 449: struct _tme_m68k_sequence _tme_m68k_sequence; 450: #define _tme_m68k_mode _tme_m68k_sequence._tme_m68k_sequence_mode 451: #define _tme_m68k_mode_flags _tme_m68k_sequence._tme_m68k_sequence_mode_flags 452: #define _tme_m68k_insn_uid _tme_m68k_sequence._tme_m68k_sequence_uid 453: 454: /* the CPU-dependent functions for the different modes: */ 455: void (*_tme_m68k_mode_execute) _TME_P((struct tme_m68k *)); 456: void (*_tme_m68k_mode_exception) _TME_P((struct tme_m68k *)); 457: void (*_tme_m68k_mode_rte) _TME_P((struct tme_m68k *)); 458: 1.1.1.3 root 459: /* the CPU-dependent status register T bits mask: */ 460: tme_uint16_t _tme_m68k_sr_mask_t; 461: 1.1.1.2 root 462: /* the instruction burst count, and the remaining burst: */ 1.1 root 463: unsigned int _tme_m68k_instruction_burst; 1.1.1.2 root 464: unsigned int _tme_m68k_instruction_burst_remaining; 1.1 root 465: 466: /* the effective address: */ 1.1.1.3 root 467: #define _tme_m68k_ea_address tme_m68k_ireg_ea 1.1 root 468: unsigned int _tme_m68k_ea_function_code; 469: 470: /* instruction fetch information: */ 1.1.1.4 ! root 471: tme_uint16_t _tme_m68k_insn_fetch_buffer[TME_M68K_INSN_WORDS_MAX]; ! 472: #define _tme_m68k_insn_opcode _tme_m68k_insn_fetch_buffer[0] ! 473: #define _tme_m68k_insn_specop _tme_m68k_insn_fetch_buffer[1] ! 474: struct tme_m68k_tlb *_tme_m68k_insn_fetch_fast_itlb; ! 475: const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_start; ! 476: const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_next; ! 477: const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_last; ! 478: unsigned int _tme_m68k_insn_fetch_slow_next; ! 479: unsigned int _tme_m68k_insn_fetch_slow_count_fast; ! 480: unsigned int _tme_m68k_insn_fetch_slow_count_total; 1.1 root 481: 482: /* the TLB entry set, and a separate instruction TLB entry set 483: reserved for the executors: */ 1.1.1.4 ! root 484: union { ! 485: struct tme_m68k_tlb * tme_shared _tme_m68k_tlb_array_u_m68k; ! 486: struct tme_bus_tlb * tme_shared _tme_m68k_tlb_array_u_bus; ! 487: } _tme_m68k_tlb_array_u; ! 488: #define _tme_m68k_tlb_array _tme_m68k_tlb_array_u._tme_m68k_tlb_array_u_m68k ! 489: #define _tme_m68k_tlb_array_bus _tme_m68k_tlb_array_u._tme_m68k_tlb_array_u_bus ! 490: union { ! 491: struct tme_m68k_tlb * tme_shared _tme_m68k_itlb_u_m68k; ! 492: struct tme_bus_tlb * tme_shared _tme_m68k_itlb_u_bus; ! 493: } _tme_m68k_itlb_u; ! 494: #define _tme_m68k_itlb _tme_m68k_itlb_u._tme_m68k_itlb_u_m68k ! 495: #define _tme_m68k_itlb_bus _tme_m68k_itlb_u._tme_m68k_itlb_u_bus ! 496: tme_rwlock_t _tme_m68k_tlbs_rwlock; 1.1 root 497: 498: /* exception handling information: */ 499: tme_uint32_t _tme_m68k_exceptions; 500: 1.1.1.4 ! root 501: /* this must be one iff this CPU has a 16-bit bus, else zero: */ ! 502: tme_uint32_t _tme_m68k_bus_16bit; 1.1 root 503: 504: /* group 0 exception information: */ 505: void (*_tme_m68k_group0_hook) _TME_P((struct tme_m68k *)); 506: unsigned int _tme_m68k_group0_flags; 507: unsigned int _tme_m68k_group0_function_code; 508: tme_uint32_t _tme_m68k_group0_address; 509: struct _tme_m68k_sequence _tme_m68k_group0_sequence; 510: tme_uint8_t _tme_m68k_group0_buffer_read[sizeof(tme_uint32_t)]; 511: unsigned int _tme_m68k_group0_buffer_read_size; 512: unsigned int _tme_m68k_group0_buffer_read_softrr; 513: tme_uint8_t _tme_m68k_group0_buffer_write[sizeof(tme_uint32_t)]; 514: unsigned int _tme_m68k_group0_buffer_write_size; 515: unsigned int _tme_m68k_group0_buffer_write_softrr; 516: 517: /* the external request lines: */ 518: tme_mutex_t tme_m68k_external_mutex; 519: tme_cond_t tme_m68k_external_cond; 520: unsigned int tme_m68k_external_reset; 521: unsigned int tme_m68k_external_halt; 522: unsigned int tme_m68k_external_ipl; 1.1.1.3 root 523: unsigned int tme_m68k_external_ipl_previous_nmi; 524: 525: /* any FPU state: */ 526: int tme_m68k_fpu_enabled; 527: int tme_m68k_fpu_type; 528: struct tme_ieee754_ctl tme_m68k_fpu_ieee754_ctl; 529: _tme_const struct tme_ieee754_ops *tme_m68k_fpu_ieee754_ops; 530: struct tme_float tme_m68k_fpu_fpreg[8]; 531: tme_uint32_t tme_m68k_fpu_fpcr; 532: tme_uint32_t tme_m68k_fpu_fpsr; 533: tme_uint32_t tme_m68k_fpu_fpiar; 534: int tme_m68k_fpu_incomplete_abort; 535: 536: #ifdef _TME_M68K_STATS 537: /* statistics: */ 538: struct { 539: 540: /* the total number of instructions executed: */ 541: tme_uint64_t tme_m68k_stats_insns_total; 542: 543: /* the total number of instructions executed by the slow executor: */ 544: tme_uint64_t tme_m68k_stats_insns_slow; 545: 546: /* the total number of redispatches: */ 547: tme_uint64_t tme_m68k_stats_redispatches; 548: 549: /* the total number of data memory operations: */ 550: tme_uint64_t tme_m68k_stats_memory_total; 551: 552: /* the total number of ITLB fills: */ 553: tme_uint64_t tme_m68k_stats_itlb_fill; 554: 555: /* the total number of DTLB fills: */ 556: tme_uint64_t tme_m68k_stats_dtlb_fill; 557: 558: } tme_m68k_stats; 559: #endif /* _TME_M68K_STATS */ 1.1 root 560: }; 561: 1.1.1.4 ! root 562: /* the read-modify-write cycle state: */ ! 563: struct tme_m68k_rmw { ! 564: ! 565: /* the operand size: */ ! 566: unsigned int tme_m68k_rmw_size; ! 567: ! 568: /* the address count, and up to two addresses: */ ! 569: unsigned int tme_m68k_rmw_address_count; ! 570: tme_uint32_t tme_m68k_rmw_addresses[2]; ! 571: ! 572: /* if nonzero, the operand at the corresponding address has been ! 573: read with a slow bus cycle. address zero is read into the memx ! 574: register, and address one is read into the memy register: */ ! 575: unsigned int tme_m68k_rmw_slow_reads[2]; ! 576: ! 577: /* the TLB entries used by the addresses. if two addresses are ! 578: sharing one TLB entry, that TLB entry is listed twice: */ ! 579: struct tme_m68k_tlb *tme_m68k_rmw_tlbs[2]; ! 580: }; ! 581: 1.1 root 582: /* globals: */ 583: extern const tme_uint16_t _tme_m68k_conditions[32]; 584: extern const _tme_m68k_xfer_memx _tme_m68k_read_memx[5]; 585: extern const _tme_m68k_xfer_memx _tme_m68k_write_memx[5]; 586: extern const _tme_m68k_xfer_mem _tme_m68k_read_mem[5]; 587: extern const _tme_m68k_xfer_mem _tme_m68k_write_mem[5]; 1.1.1.3 root 588: extern tme_uint32_t tme_m68k_opcodes_m68000[65536]; 589: extern tme_uint32_t tme_m68k_opcodes_m68010[65536]; 590: extern tme_uint32_t tme_m68k_opcodes_m68020[65536]; 591: extern const _tme_m68k_insn tme_m68k_opcode_insns[]; 592: extern const tme_uint8_t _tme_m6888x_fpgen_opmode_bitmap[128 / 8]; 1.1 root 593: 594: /* prototypes: */ 595: int tme_m68k_new _TME_P((struct tme_m68k *, const char * const *, const void *, char **)); 596: void tme_m68k_redispatch _TME_P((struct tme_m68k *)); 597: int tme_m68k_go_slow _TME_P((const struct tme_m68k *)); 598: void tme_m68k_change_sr _TME_P((struct tme_m68k *, tme_uint16_t)); 599: void tme_m68k_external_check _TME_P((struct tme_m68k *, tme_uint32_t)); 600: void tme_m68k_tlb_fill _TME_P((struct tme_m68k *, struct tme_m68k_tlb *, unsigned int, tme_uint32_t, unsigned int)); 601: void tme_m68k_do_reset _TME_P((struct tme_m68k *)); 1.1.1.4 ! root 602: void tme_m68k_callout_unlock _TME_P((struct tme_m68k *ic)); ! 603: void tme_m68k_callout_relock _TME_P((struct tme_m68k *ic)); 1.1 root 604: 605: /* exception support: */ 606: void tme_m68k_exception _TME_P((struct tme_m68k *, tme_uint32_t)); 607: void tme_m68k_exception_process_start _TME_P((struct tme_m68k *, unsigned int)); 608: void tme_m68k_exception_process_finish _TME_P((struct tme_m68k *, tme_uint8_t, tme_uint8_t)); 1.1.1.3 root 609: void tme_m68000_exception_process _TME_P((struct tme_m68k *)); 610: void tme_m68020_exception_process _TME_P((struct tme_m68k *)); 1.1 root 611: 612: /* rte support: */ 613: tme_uint16_t tme_m68k_rte_start _TME_P((struct tme_m68k *)); 614: void tme_m68k_rte_finish _TME_P((struct tme_m68k *, tme_uint32_t)); 615: 616: /* decoder map support: */ 1.1.1.3 root 617: void tme_m68k_opcodes_init_m68000 _TME_P((tme_uint32_t *)); 618: void tme_m68k_opcodes_init_m68010 _TME_P((tme_uint32_t *)); 619: void tme_m68k_opcodes_init_m68020 _TME_P((tme_uint32_t *)); 1.1 root 620: 621: /* read/modify/write cycle support: */ 1.1.1.4 ! root 622: int tme_m68k_rmw_start _TME_P((struct tme_m68k *, struct tme_m68k_rmw *)); ! 623: void tme_m68k_rmw_finish _TME_P((struct tme_m68k *, struct tme_m68k_rmw *, int)); 1.1 root 624: 625: /* group 0 fault support: */ 626: void tme_m68k_group0_hook_fast _TME_P((struct tme_m68k *)); 1.1.1.4 ! root 627: unsigned int tme_m68k_insn_buffer_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int)); ! 628: unsigned int tme_m68k_insn_buffer_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int)); ! 629: unsigned int tme_m68k_sequence_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int)); ! 630: unsigned int tme_m68k_sequence_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int)); 1.1 root 631: 632: /* bitfield support: */ 633: unsigned int tme_m68k_bitfield_width _TME_P((struct tme_m68k *)); 634: tme_uint32_t _tme_m68k_bitfield_read _TME_P((struct tme_m68k *, int)); 635: #define tme_m68k_bitfield_read_signed(ic) ((tme_int32_t) _tme_m68k_bitfield_read(ic, TRUE)) 636: #define tme_m68k_bitfield_read_unsigned(ic) _tme_m68k_bitfield_read(ic, FALSE) 637: void tme_m68k_bitfield_write_unsigned _TME_P((struct tme_m68k *, tme_uint32_t, int)); 638: #define tme_m68k_bitfield_write_signed(ic, v, sf) tme_m68k_bitfield_write_unsigned(ic, (tme_uint32_t) (v), sf) 639: 1.1.1.3 root 640: /* FPU support: */ 641: int tme_m68k_fpu_new _TME_P((struct tme_m68k *, const char * const *, int *, int *, char **)); 642: void tme_m68k_fpu_reset _TME_P((struct tme_m68k *)); 643: void tme_m68k_fpu_usage _TME_P((char **)); 644: 1.1 root 645: /* verification: */ 1.1.1.2 root 646: void tme_m68k_verify_hook _TME_P((void)); 1.1 root 647: #ifdef _TME_M68K_VERIFY 648: void tme_m68k_verify_init _TME_P((void)); 649: void tme_m68k_verify_begin _TME_P((const struct tme_m68k *, const tme_uint8_t *)); 650: void tme_m68k_verify_mem_any _TME_P((const struct tme_m68k *, 651: unsigned int, tme_uint32_t, 652: tme_uint8_t *, int, int)); 653: void tme_m68k_verify_end_branch _TME_P((const struct tme_m68k *, tme_uint32_t)); 654: void tme_m68k_verify_end _TME_P((const struct tme_m68k *, 655: void (*)(struct tme_m68k *, void *, void *))); 656: #else /* _TME_M68K_VERIFY */ 657: #define tme_m68k_verify_init() do { } while (/* CONSTCOND */ 0) 658: #define tme_m68k_verify_begin(ic, s) do { } while (/* CONSTCOND */ 0) 659: #define tme_m68k_verify_mem_any(ic, fc, a, v, c, rw) do { } while (/* CONSTCOND */ 0) 660: #define tme_m68k_verify_end_branch(ic, pc) do { } while (/* CONSTCOND */ 0) 661: #define tme_m68k_verify_end(ic, f) do { } while (/* CONSTCOND */ 0) 662: #define tme_m68k_verify_hook() do { } while (/* CONSTCOND */ 0) 663: #endif /* _TME_M68K_VERIFY */ 664: #define tme_m68k_verify_mem8(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint8_t), rw) 665: #define tme_m68k_verify_mem16(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint16_t), rw) 666: #define tme_m68k_verify_mem32(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint32_t), rw) 667: 668: /* instruction functions: */ 669: TME_M68K_INSN_DECL(tme_m68k_illegal); 670: TME_M68K_INSN_DECL(tme_m68k_exg); 671: TME_M68K_INSN_DECL(tme_m68k_extw); 672: TME_M68K_INSN_DECL(tme_m68k_extl); 673: TME_M68K_INSN_DECL(tme_m68k_extbl); 674: TME_M68K_INSN_DECL(tme_m68k_lea); 675: TME_M68K_INSN_DECL(tme_m68k_move_from_ccr); 676: TME_M68K_INSN_DECL(tme_m68k_move_from_sr); 677: TME_M68K_INSN_DECL(tme_m68k_move_from_sr0); 678: TME_M68K_INSN_DECL(tme_m68k_swap); 679: TME_M68K_INSN_DECL(tme_m68k_nop); 680: TME_M68K_INSN_DECL(tme_m68k_scc); 681: TME_M68K_INSN_DECL(tme_m68k_dbcc); 682: TME_M68K_INSN_DECL(tme_m68k_bcc); 1.1.1.3 root 683: TME_M68K_INSN_DECL(tme_m68k_bccl); 1.1 root 684: TME_M68K_INSN_DECL(tme_m68k_bsr); 1.1.1.3 root 685: TME_M68K_INSN_DECL(tme_m68k_bsrl); 1.1 root 686: TME_M68K_INSN_DECL(tme_m68k_pea); 687: TME_M68K_INSN_DECL(tme_m68k_bkpt); 688: TME_M68K_INSN_DECL(tme_m68k_tas); 689: TME_M68K_INSN_DECL(tme_m68k_tas_r); 690: TME_M68K_INSN_DECL(tme_m68k_move_usp); 691: TME_M68K_INSN_DECL(tme_m68k_trap); 692: TME_M68K_INSN_DECL(tme_m68k_trapv); 693: TME_M68K_INSN_DECL(tme_m68k_link); 694: TME_M68K_INSN_DECL(tme_m68k_unlk); 695: TME_M68K_INSN_DECL(tme_m68k_movec); 696: TME_M68K_INSN_DECL(tme_m68k_reset); 697: TME_M68K_INSN_DECL(tme_m68k_rtd); 698: TME_M68K_INSN_DECL(tme_m68k_rtr); 699: TME_M68K_INSN_DECL(tme_m68k_rts); 700: TME_M68K_INSN_DECL(tme_m68k_jsr); 701: TME_M68K_INSN_DECL(tme_m68k_jmp); 702: TME_M68K_INSN_DECL(tme_m68k_rte); 703: TME_M68K_INSN_DECL(tme_m68k_stop); 704: TME_M68K_INSN_DECL(tme_m68k_priv); 705: TME_M68K_INSN_DECL(tme_m68k_cmp2_chk2); 706: TME_M68K_INSN_DECL(tme_m68k_callm); 707: TME_M68K_INSN_DECL(tme_m68k_rtm); 708: TME_M68K_INSN_DECL(tme_m68k_trapcc); 709: TME_M68K_INSN_DECL(tme_m68k_bfchg); 710: TME_M68K_INSN_DECL(tme_m68k_bfclr); 711: TME_M68K_INSN_DECL(tme_m68k_bfexts); 712: TME_M68K_INSN_DECL(tme_m68k_bfextu); 713: TME_M68K_INSN_DECL(tme_m68k_bfffo); 714: TME_M68K_INSN_DECL(tme_m68k_bfins); 715: TME_M68K_INSN_DECL(tme_m68k_bfset); 716: TME_M68K_INSN_DECL(tme_m68k_bftst); 717: TME_M68K_INSN_DECL(tme_m68k_pack); 718: TME_M68K_INSN_DECL(tme_m68k_unpk); 1.1.1.3 root 719: TME_M68K_INSN_DECL(tme_m68k_fpgen); 720: TME_M68K_INSN_DECL(tme_m68k_fmovemctl); 721: TME_M68K_INSN_DECL(tme_m68k_fmovem); 722: TME_M68K_INSN_DECL(tme_m68k_fmove_rm); 723: TME_M68K_INSN_DECL(tme_m68k_fdbcc); 724: TME_M68K_INSN_DECL(tme_m68k_ftrapcc); 725: TME_M68K_INSN_DECL(tme_m68k_fscc); 726: TME_M68K_INSN_DECL(tme_m68k_fbcc); 727: TME_M68K_INSN_DECL(tme_m68k_fsave); 728: TME_M68K_INSN_DECL(tme_m68k_frestore); 729: TME_M68K_INSN_DECL(tme_m68k_divl); 730: TME_M68K_INSN_DECL(tme_m68k_mull); 1.1 root 731: 732: #endif /* !_IC_M68K_IMPL_H */ 733: 734: /* the automatically-generated header information: */ 735: #include <m68k-auto.h>
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.