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