|
|
1.1.1.3 ! root 1: /* $Id: m68k-impl.h,v 1.16 2005/03/23 12:12:37 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.3 ! root 40: _TME_RCSID("$Id: m68k-impl.h,v 1.16 2005/03/23 12:12:37 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) 258: #define TME_M68K_TLB_ENTRY(ic, function_code, linear_address) \ 259: (TME_ATOMIC_READ(struct tme_m68k_tlb *, (ic)->_tme_m68k_tlb_array) \ 260: + ((linear_address >> 10) & (_TME_M68K_TLB_HASH_SIZE - 1))) 261: 262: /* macros for sequence control: */ 263: #define TME_M68K_SEQUENCE_START \ 264: do { \ 265: ic->_tme_m68k_sequence._tme_m68k_sequence_mode_flags = 0; \ 266: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = 0; \ 267: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1; \ 268: } while (/* CONSTCOND */ 0) 269: #define TME_M68K_SEQUENCE_RESTARTING \ 270: (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted \ 271: >= ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) 272: #define TME_M68K_SEQUENCE_RESTART \ 273: do { \ 274: if (!TME_M68K_SEQUENCE_RESTARTING) \ 275: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = \ 276: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next; \ 277: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1; \ 278: } while (/* CONSTCOND */ 0) 279: #define TME_M68K_SEQUENCE_TRANSFER_STEP \ 280: do { \ 281: ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next++; \ 282: } while (/* CONSTCOND */ 0) 283: 284: /* instruction handler macros: */ 285: #define TME_M68K_INSN_DECL(name) void name _TME_P((struct tme_m68k *, void *, void *)) 286: #ifdef __STDC__ 287: #define TME_M68K_INSN(name) void name(struct tme_m68k *ic, void *_op0, void *_op1) 288: #else /* !__STDC__ */ 289: #define TME_M68K_INSN(name) void name(ic, _op0, _op1) struct tme_m68k *ic; void *_op0, *_op1; 290: #endif /* !__STDC__ */ 291: #define TME_M68K_INSN_OP0(t) (*((t *) _op0)) 292: #define TME_M68K_INSN_OP1(t) (*((t *) _op1)) 293: #define TME_M68K_INSN_OPCODE ic->_tme_m68k_insn_opcode 294: #define TME_M68K_INSN_SPECOP ic->_tme_m68k_insn_specop 295: #define TME_M68K_INSN_OK return 296: #define TME_M68K_INSN_EXCEPTION(e) tme_m68k_exception(ic, e) 297: #define TME_M68K_INSN_PRIV \ 298: if (!TME_M68K_PRIV(ic)) \ 1.1.1.3 ! root 299: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_PRIV) 1.1 root 300: #define TME_M68K_INSN_ILL \ 1.1.1.3 ! root 301: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL) 1.1 root 302: #define TME_M68K_INSN_CANFAULT \ 303: do { \ 304: ic->_tme_m68k_mode_flags \ 305: |= TME_M68K_EXECUTION_INST_CANFAULT; \ 306: } while (/* CONSTCOND */ 0) 307: #define TME_M68K_INSN_BRANCH(pc) \ 308: do { \ 309: tme_m68k_verify_end_branch(ic, pc); \ 310: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next = (pc); \ 1.1.1.3 ! root 311: if (__tme_predict_false((ic->tme_m68k_ireg_sr \ ! 312: & ic->_tme_m68k_sr_mask_t) != 0)) { \ ! 313: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE); \ ! 314: } \ 1.1 root 315: if (tme_m68k_go_slow(ic)) { \ 316: TME_M68K_SEQUENCE_START; \ 317: tme_m68k_redispatch(ic); \ 318: } \ 319: } while (/* CONSTCOND */ 0) 320: #define TME_M68K_INSN_CHANGE_SR(reg) \ 321: do { \ 322: TME_M68K_INSN_PRIV; \ 323: tme_m68k_change_sr(ic, reg); \ 1.1.1.3 ! root 324: tme_m68k_verify_end_branch(ic, ic->tme_m68k_ireg_pc_next); \ ! 325: if (__tme_predict_false((ic->tme_m68k_ireg_sr \ ! 326: & ic->_tme_m68k_sr_mask_t) != 0)) { \ ! 327: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; \ ! 328: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; \ ! 329: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE); \ ! 330: } \ ! 331: if (tme_m68k_go_slow(ic)) { \ ! 332: TME_M68K_SEQUENCE_START; \ ! 333: tme_m68k_redispatch(ic); \ ! 334: } \ 1.1 root 335: } while (/* CONSTCOND */ 0) 336: 337: /* logging: */ 338: #define TME_M68K_LOG_HANDLE(ic) \ 339: (&(ic)->tme_m68k_element->tme_element_log_handle) 340: #define tme_m68k_log_start(ic, level, rc) \ 341: do { \ 342: tme_log_start(TME_M68K_LOG_HANDLE(ic), level, rc) { \ 343: if ((ic)->_tme_m68k_mode != TME_M68K_MODE_EXECUTION) { \ 344: tme_log_part(TME_M68K_LOG_HANDLE(ic), \ 345: "mode=%d ", \ 346: (ic)->_tme_m68k_mode); \ 347: } \ 348: else { \ 349: tme_log_part(TME_M68K_LOG_HANDLE(ic), \ 350: "pc=%c/0x%08x ", \ 351: (((ic)->tme_m68k_ireg_sr \ 352: & (TME_M68K_FLAG_M \ 353: | TME_M68K_FLAG_S)) \ 354: ? 'S' \ 355: : 'U'), \ 356: ic->tme_m68k_ireg_pc); \ 357: } \ 358: do 359: #define tme_m68k_log_finish(ic) \ 360: while (/* CONSTCOND */ 0); \ 361: } tme_log_finish(TME_M68K_LOG_HANDLE(ic)); \ 362: } while (/* CONSTCOND */ 0) 363: #define tme_m68k_log(ic, level, rc, x) \ 364: do { \ 365: tme_m68k_log_start(ic, level, rc) { \ 366: tme_log_part x; \ 367: } tme_m68k_log_finish(ic); \ 368: } while (/* CONSTCOND */ 0) 369: 370: /* miscellaneous: */ 371: #define TME_M68K_PRIV(ic) ((ic)->tme_m68k_ireg_sr & TME_M68K_FLAG_S) 372: #define TME_M68K_FUNCTION_CODE_DATA(ic) \ 373: (TME_M68K_PRIV(ic) ? TME_M68K_FC_SD : TME_M68K_FC_UD) 374: #define TME_M68K_FUNCTION_CODE_PROGRAM(ic) \ 375: (TME_M68K_PRIV(ic) ? TME_M68K_FC_SP : TME_M68K_FC_UP) 376: #define TME_M68K_INSN_WORDS_MAX (11) 377: 378: /* structures: */ 379: struct tme_m68k; 380: 381: /* an memory read or write function: */ 382: typedef void (*_tme_m68k_xfer_memx) _TME_P((struct tme_m68k *)); 383: typedef void (*_tme_m68k_xfer_mem) _TME_P((struct tme_m68k *, int)); 384: 1.1.1.3 ! root 385: /* an insn function: */ ! 386: typedef TME_M68K_INSN_DECL((*_tme_m68k_insn)); 1.1 root 387: 388: /* an m68k sequence: */ 389: struct _tme_m68k_sequence { 390: 391: /* the mode of the emulator: */ 1.1.1.2 root 392: unsigned int _tme_m68k_sequence_mode; 1.1 root 393: 394: /* any mode-specific flags for the sequence: */ 1.1.1.2 root 395: unsigned int _tme_m68k_sequence_mode_flags; 1.1 root 396: 397: /* the ordinal of the next memory transfer. always starts from one: */ 398: unsigned short _tme_m68k_sequence_transfer_next; 399: 400: /* the ordinal of the memory transfer that faulted. if this is 401: greater than or equal to _tme_m68k_sequence_transfer_next, we are 402: restarting, and bus cycles and changes to the m68k state are 403: forbidden: */ 404: unsigned short _tme_m68k_sequence_transfer_faulted; 405: 406: /* the fault happened after this number of bytes were successfully 407: transferred: */ 408: unsigned short _tme_m68k_sequence_transfer_faulted_after; 409: 410: #ifdef _TME_M68K_VERIFY 411: /* the sequence unique identifier: */ 412: unsigned long _tme_m68k_sequence_uid; 413: #endif /* _TME_M68K_VERIFY */ 414: }; 415: 416: /* the m68k state: */ 417: struct tme_m68k { 418: 419: /* the IC data structure. it is beneficial to have this structure 420: first, since register numbers can often simply be scaled and 421: added without an offset to the struct tme_m68k pointer to get 422: to their contents: */ 423: struct tme_ic tme_m68k_ic; 424: 425: /* the m68k type: */ 426: int tme_m68k_type; 427: 428: /* the backpointer to our element: */ 429: struct tme_element *tme_m68k_element; 430: 431: /* our bus connection. if both are defined, the m68k bus connection 432: is an adaptation layer for the generic bus connection: */ 433: struct tme_m68k_bus_connection *_tme_m68k_bus_connection; 434: struct tme_bus_connection *_tme_m68k_bus_generic; 435: 436: /* a jmp_buf back to the dispatcher: */ 437: jmp_buf _tme_m68k_dispatcher; 438: 439: /* the current sequence: */ 440: struct _tme_m68k_sequence _tme_m68k_sequence; 441: #define _tme_m68k_mode _tme_m68k_sequence._tme_m68k_sequence_mode 442: #define _tme_m68k_mode_flags _tme_m68k_sequence._tme_m68k_sequence_mode_flags 443: #define _tme_m68k_insn_uid _tme_m68k_sequence._tme_m68k_sequence_uid 444: 445: /* the CPU-dependent functions for the different modes: */ 446: void (*_tme_m68k_mode_execute) _TME_P((struct tme_m68k *)); 447: void (*_tme_m68k_mode_exception) _TME_P((struct tme_m68k *)); 448: void (*_tme_m68k_mode_rte) _TME_P((struct tme_m68k *)); 449: 1.1.1.3 ! root 450: /* the CPU-dependent status register T bits mask: */ ! 451: tme_uint16_t _tme_m68k_sr_mask_t; ! 452: 1.1.1.2 root 453: /* the instruction decoder root map: */ 1.1 root 454: const struct _tme_m68k_decoder_root *_tme_m68k_decoder_root; 1.1.1.2 root 455: 456: /* the instruction burst count, and the remaining burst: */ 1.1 root 457: unsigned int _tme_m68k_instruction_burst; 1.1.1.2 root 458: unsigned int _tme_m68k_instruction_burst_remaining; 1.1 root 459: 460: /* the effective address: */ 1.1.1.3 ! root 461: #define _tme_m68k_ea_address tme_m68k_ireg_ea 1.1 root 462: unsigned int _tme_m68k_ea_function_code; 463: 464: /* instruction fetch information: */ 465: tme_uint16_t _tme_m68k_insn_opcode; 466: tme_uint16_t _tme_m68k_insn_specop; 467: 468: /* the instruction buffer: */ 469: tme_uint8_t _tme_m68k_insn_buffer[TME_M68K_INSN_WORDS_MAX * sizeof(tme_uint32_t)]; 470: unsigned int _tme_m68k_insn_buffer_off; 471: tme_uint16_t _tme_m68k_insn_buffer_fetch_total; 472: tme_uint16_t _tme_m68k_insn_buffer_fetch_sizes; 473: 474: /* the TLB entry set, and a separate instruction TLB entry set 475: reserved for the executors: */ 476: TME_ATOMIC(struct tme_m68k_tlb *, _tme_m68k_tlb_array); 477: TME_ATOMIC(struct tme_m68k_tlb *, _tme_m68k_itlb); 478: 479: /* exception handling information: */ 480: tme_uint32_t _tme_m68k_exceptions; 481: 482: /* nonzero iff this CPU has a 16-bit bus: */ 483: int _tme_m68k_bus_16bit; 484: 485: /* group 0 exception information: */ 486: void (*_tme_m68k_group0_hook) _TME_P((struct tme_m68k *)); 487: unsigned int _tme_m68k_group0_flags; 488: unsigned int _tme_m68k_group0_function_code; 489: tme_uint32_t _tme_m68k_group0_address; 490: struct _tme_m68k_sequence _tme_m68k_group0_sequence; 491: tme_uint8_t _tme_m68k_group0_buffer_read[sizeof(tme_uint32_t)]; 492: unsigned int _tme_m68k_group0_buffer_read_size; 493: unsigned int _tme_m68k_group0_buffer_read_softrr; 494: tme_uint8_t _tme_m68k_group0_buffer_write[sizeof(tme_uint32_t)]; 495: unsigned int _tme_m68k_group0_buffer_write_size; 496: unsigned int _tme_m68k_group0_buffer_write_softrr; 497: 498: /* the external request lines: */ 499: tme_mutex_t tme_m68k_external_mutex; 500: tme_cond_t tme_m68k_external_cond; 501: unsigned int tme_m68k_external_reset; 502: unsigned int tme_m68k_external_halt; 503: unsigned int tme_m68k_external_ipl; 1.1.1.3 ! root 504: unsigned int tme_m68k_external_ipl_previous_nmi; ! 505: ! 506: /* any FPU state: */ ! 507: int tme_m68k_fpu_enabled; ! 508: int tme_m68k_fpu_type; ! 509: struct tme_ieee754_ctl tme_m68k_fpu_ieee754_ctl; ! 510: _tme_const struct tme_ieee754_ops *tme_m68k_fpu_ieee754_ops; ! 511: struct tme_float tme_m68k_fpu_fpreg[8]; ! 512: tme_uint32_t tme_m68k_fpu_fpcr; ! 513: tme_uint32_t tme_m68k_fpu_fpsr; ! 514: tme_uint32_t tme_m68k_fpu_fpiar; ! 515: int tme_m68k_fpu_incomplete_abort; ! 516: ! 517: #ifdef _TME_M68K_STATS ! 518: /* statistics: */ ! 519: struct { ! 520: ! 521: /* the total number of instructions executed: */ ! 522: tme_uint64_t tme_m68k_stats_insns_total; ! 523: ! 524: /* the total number of instructions executed by the slow executor: */ ! 525: tme_uint64_t tme_m68k_stats_insns_slow; ! 526: ! 527: /* the total number of redispatches: */ ! 528: tme_uint64_t tme_m68k_stats_redispatches; ! 529: ! 530: /* the total number of data memory operations: */ ! 531: tme_uint64_t tme_m68k_stats_memory_total; ! 532: ! 533: /* the total number of ITLB fills: */ ! 534: tme_uint64_t tme_m68k_stats_itlb_fill; ! 535: ! 536: /* the total number of DTLB fills: */ ! 537: tme_uint64_t tme_m68k_stats_dtlb_fill; ! 538: ! 539: } tme_m68k_stats; ! 540: #endif /* _TME_M68K_STATS */ 1.1 root 541: }; 542: 543: /* globals: */ 544: extern const tme_uint16_t _tme_m68k_conditions[32]; 545: extern const _tme_m68k_xfer_memx _tme_m68k_read_memx[5]; 546: extern const _tme_m68k_xfer_memx _tme_m68k_write_memx[5]; 547: extern const _tme_m68k_xfer_mem _tme_m68k_read_mem[5]; 548: extern const _tme_m68k_xfer_mem _tme_m68k_write_mem[5]; 1.1.1.3 ! root 549: extern tme_uint32_t tme_m68k_opcodes_m68000[65536]; ! 550: extern tme_uint32_t tme_m68k_opcodes_m68010[65536]; ! 551: extern tme_uint32_t tme_m68k_opcodes_m68020[65536]; ! 552: extern const _tme_m68k_insn tme_m68k_opcode_insns[]; ! 553: extern const tme_uint8_t _tme_m6888x_fpgen_opmode_bitmap[128 / 8]; 1.1 root 554: 555: /* prototypes: */ 556: int tme_m68k_new _TME_P((struct tme_m68k *, const char * const *, const void *, char **)); 557: void tme_m68k_redispatch _TME_P((struct tme_m68k *)); 558: int tme_m68k_go_slow _TME_P((const struct tme_m68k *)); 559: void tme_m68k_change_sr _TME_P((struct tme_m68k *, tme_uint16_t)); 560: void tme_m68k_external_check _TME_P((struct tme_m68k *, tme_uint32_t)); 561: void tme_m68k_tlb_fill _TME_P((struct tme_m68k *, struct tme_m68k_tlb *, unsigned int, tme_uint32_t, unsigned int)); 562: void tme_m68k_do_reset _TME_P((struct tme_m68k *)); 563: 564: /* exception support: */ 565: void tme_m68k_exception _TME_P((struct tme_m68k *, tme_uint32_t)); 566: void tme_m68k_exception_process_start _TME_P((struct tme_m68k *, unsigned int)); 567: void tme_m68k_exception_process_finish _TME_P((struct tme_m68k *, tme_uint8_t, tme_uint8_t)); 1.1.1.3 ! root 568: void tme_m68000_exception_process _TME_P((struct tme_m68k *)); ! 569: void tme_m68020_exception_process _TME_P((struct tme_m68k *)); 1.1 root 570: 571: /* rte support: */ 572: tme_uint16_t tme_m68k_rte_start _TME_P((struct tme_m68k *)); 573: void tme_m68k_rte_finish _TME_P((struct tme_m68k *, tme_uint32_t)); 574: 575: /* decoder map support: */ 1.1.1.3 ! root 576: void tme_m68k_opcodes_init_m68000 _TME_P((tme_uint32_t *)); ! 577: void tme_m68k_opcodes_init_m68010 _TME_P((tme_uint32_t *)); ! 578: void tme_m68k_opcodes_init_m68020 _TME_P((tme_uint32_t *)); 1.1 root 579: 580: /* read/modify/write cycle support: */ 581: struct tme_m68k_tlb *tme_m68k_rmw_start _TME_P((struct tme_m68k *)); 582: void tme_m68k_rmw_finish _TME_P((struct tme_m68k *, struct tme_m68k_tlb *)); 583: 584: /* group 0 fault support: */ 585: int tme_m68k_insn_buffer_xfer _TME_P((struct tme_m68k *, tme_uint8_t *, unsigned int, int)); 586: void tme_m68k_group0_hook_fast _TME_P((struct tme_m68k *)); 587: #define tme_m68k_insn_buffer_empty(ic, r, ra) \ 588: tme_m68k_insn_buffer_xfer(ic, r, ra, 1) 589: #define tme_m68k_insn_buffer_fill(ic, r, ra) \ 590: tme_m68k_insn_buffer_xfer(ic, r, ra, 2) 591: int tme_m68k_sequence_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int)); 592: int tme_m68k_sequence_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int)); 593: 594: /* bitfield support: */ 595: unsigned int tme_m68k_bitfield_width _TME_P((struct tme_m68k *)); 596: tme_uint32_t _tme_m68k_bitfield_read _TME_P((struct tme_m68k *, int)); 597: #define tme_m68k_bitfield_read_signed(ic) ((tme_int32_t) _tme_m68k_bitfield_read(ic, TRUE)) 598: #define tme_m68k_bitfield_read_unsigned(ic) _tme_m68k_bitfield_read(ic, FALSE) 599: void tme_m68k_bitfield_write_unsigned _TME_P((struct tme_m68k *, tme_uint32_t, int)); 600: #define tme_m68k_bitfield_write_signed(ic, v, sf) tme_m68k_bitfield_write_unsigned(ic, (tme_uint32_t) (v), sf) 601: 1.1.1.3 ! root 602: /* FPU support: */ ! 603: int tme_m68k_fpu_new _TME_P((struct tme_m68k *, const char * const *, int *, int *, char **)); ! 604: void tme_m68k_fpu_reset _TME_P((struct tme_m68k *)); ! 605: void tme_m68k_fpu_usage _TME_P((char **)); ! 606: 1.1 root 607: /* verification: */ 1.1.1.2 root 608: void tme_m68k_verify_hook _TME_P((void)); 1.1 root 609: #ifdef _TME_M68K_VERIFY 610: void tme_m68k_verify_init _TME_P((void)); 611: void tme_m68k_verify_begin _TME_P((const struct tme_m68k *, const tme_uint8_t *)); 612: void tme_m68k_verify_mem_any _TME_P((const struct tme_m68k *, 613: unsigned int, tme_uint32_t, 614: tme_uint8_t *, int, int)); 615: void tme_m68k_verify_end_branch _TME_P((const struct tme_m68k *, tme_uint32_t)); 616: void tme_m68k_verify_end _TME_P((const struct tme_m68k *, 617: void (*)(struct tme_m68k *, void *, void *))); 618: #else /* _TME_M68K_VERIFY */ 619: #define tme_m68k_verify_init() do { } while (/* CONSTCOND */ 0) 620: #define tme_m68k_verify_begin(ic, s) do { } while (/* CONSTCOND */ 0) 621: #define tme_m68k_verify_mem_any(ic, fc, a, v, c, rw) do { } while (/* CONSTCOND */ 0) 622: #define tme_m68k_verify_end_branch(ic, pc) do { } while (/* CONSTCOND */ 0) 623: #define tme_m68k_verify_end(ic, f) do { } while (/* CONSTCOND */ 0) 624: #define tme_m68k_verify_hook() do { } while (/* CONSTCOND */ 0) 625: #endif /* _TME_M68K_VERIFY */ 626: #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) 627: #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) 628: #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) 629: 630: /* instruction functions: */ 631: TME_M68K_INSN_DECL(tme_m68k_illegal); 632: TME_M68K_INSN_DECL(tme_m68k_exg); 633: TME_M68K_INSN_DECL(tme_m68k_extw); 634: TME_M68K_INSN_DECL(tme_m68k_extl); 635: TME_M68K_INSN_DECL(tme_m68k_extbl); 636: TME_M68K_INSN_DECL(tme_m68k_lea); 637: TME_M68K_INSN_DECL(tme_m68k_move_from_ccr); 638: TME_M68K_INSN_DECL(tme_m68k_move_from_sr); 639: TME_M68K_INSN_DECL(tme_m68k_move_from_sr0); 640: TME_M68K_INSN_DECL(tme_m68k_swap); 641: TME_M68K_INSN_DECL(tme_m68k_nop); 642: TME_M68K_INSN_DECL(tme_m68k_scc); 643: TME_M68K_INSN_DECL(tme_m68k_dbcc); 644: TME_M68K_INSN_DECL(tme_m68k_bcc); 1.1.1.3 ! root 645: TME_M68K_INSN_DECL(tme_m68k_bccl); 1.1 root 646: TME_M68K_INSN_DECL(tme_m68k_bsr); 1.1.1.3 ! root 647: TME_M68K_INSN_DECL(tme_m68k_bsrl); 1.1 root 648: TME_M68K_INSN_DECL(tme_m68k_pea); 649: TME_M68K_INSN_DECL(tme_m68k_bkpt); 650: TME_M68K_INSN_DECL(tme_m68k_tas); 651: TME_M68K_INSN_DECL(tme_m68k_tas_r); 652: TME_M68K_INSN_DECL(tme_m68k_move_usp); 653: TME_M68K_INSN_DECL(tme_m68k_trap); 654: TME_M68K_INSN_DECL(tme_m68k_trapv); 655: TME_M68K_INSN_DECL(tme_m68k_link); 656: TME_M68K_INSN_DECL(tme_m68k_unlk); 657: TME_M68K_INSN_DECL(tme_m68k_movec); 658: TME_M68K_INSN_DECL(tme_m68k_reset); 659: TME_M68K_INSN_DECL(tme_m68k_rtd); 660: TME_M68K_INSN_DECL(tme_m68k_rtr); 661: TME_M68K_INSN_DECL(tme_m68k_rts); 662: TME_M68K_INSN_DECL(tme_m68k_jsr); 663: TME_M68K_INSN_DECL(tme_m68k_jmp); 664: TME_M68K_INSN_DECL(tme_m68k_rte); 665: TME_M68K_INSN_DECL(tme_m68k_stop); 666: TME_M68K_INSN_DECL(tme_m68k_priv); 667: TME_M68K_INSN_DECL(tme_m68k_cmp2_chk2); 668: TME_M68K_INSN_DECL(tme_m68k_callm); 669: TME_M68K_INSN_DECL(tme_m68k_rtm); 670: TME_M68K_INSN_DECL(tme_m68k_trapcc); 671: TME_M68K_INSN_DECL(tme_m68k_bfchg); 672: TME_M68K_INSN_DECL(tme_m68k_bfclr); 673: TME_M68K_INSN_DECL(tme_m68k_bfexts); 674: TME_M68K_INSN_DECL(tme_m68k_bfextu); 675: TME_M68K_INSN_DECL(tme_m68k_bfffo); 676: TME_M68K_INSN_DECL(tme_m68k_bfins); 677: TME_M68K_INSN_DECL(tme_m68k_bfset); 678: TME_M68K_INSN_DECL(tme_m68k_bftst); 679: TME_M68K_INSN_DECL(tme_m68k_pack); 680: TME_M68K_INSN_DECL(tme_m68k_unpk); 1.1.1.3 ! root 681: TME_M68K_INSN_DECL(tme_m68k_fpgen); ! 682: TME_M68K_INSN_DECL(tme_m68k_fmovemctl); ! 683: TME_M68K_INSN_DECL(tme_m68k_fmovem); ! 684: TME_M68K_INSN_DECL(tme_m68k_fmove_rm); ! 685: TME_M68K_INSN_DECL(tme_m68k_fdbcc); ! 686: TME_M68K_INSN_DECL(tme_m68k_ftrapcc); ! 687: TME_M68K_INSN_DECL(tme_m68k_fscc); ! 688: TME_M68K_INSN_DECL(tme_m68k_fbcc); ! 689: TME_M68K_INSN_DECL(tme_m68k_fsave); ! 690: TME_M68K_INSN_DECL(tme_m68k_frestore); ! 691: TME_M68K_INSN_DECL(tme_m68k_divl); ! 692: TME_M68K_INSN_DECL(tme_m68k_mull); 1.1 root 693: 694: #endif /* !_IC_M68K_IMPL_H */ 695: 696: /* the automatically-generated header information: */ 697: #include <m68k-auto.h>
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.