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