Mercurial > repos > blastem
comparison musashi/m68kcpu.h @ 1506:ded16f3d7eb4 mame_interp
Super hacky integration of the version of Musashi from MAME
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 27 Dec 2017 13:46:52 -0800 |
parents | |
children | 2455662378ed |
comparison
equal
deleted
inserted
replaced
1471:2e6320d261ff | 1506:ded16f3d7eb4 |
---|---|
1 // license:BSD-3-Clause | |
2 // copyright-holders:Karl Stenerud | |
3 /* ======================================================================== */ | |
4 /* ========================= LICENSING & COPYRIGHT ======================== */ | |
5 /* ======================================================================== */ | |
6 /* | |
7 * MUSASHI | |
8 * Version 4.50 | |
9 * | |
10 * A portable Motorola M680x0 processor emulation engine. | |
11 * Copyright Karl Stenerud. All rights reserved. | |
12 * | |
13 */ | |
14 | |
15 | |
16 #pragma once | |
17 | |
18 #ifndef __M68KCPU_H__ | |
19 #define __M68KCPU_H__ | |
20 | |
21 #include "../m68k_core.h" | |
22 typedef struct m68000_base_device m68000_base_device; | |
23 struct m68000_base_device { | |
24 m68k_context c; | |
25 uint32_t cpu_type; | |
26 uint32_t pc; | |
27 uint32_t ppc; | |
28 uint32_t stopped; /* Stopped state */ | |
29 uint32_t pref_addr; | |
30 uint32_t pref_data; | |
31 uint32_t sr_mask; /* Implemented status register bits */ | |
32 uint32_t instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ | |
33 uint32_t run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ | |
34 uint32_t s_flag; /* Supervisor */ | |
35 uint32_t m_flag; /* Master/Interrupt state */ | |
36 uint32_t x_flag; /* Extend */ | |
37 uint32_t n_flag; /* Negative */ | |
38 uint32_t not_z_flag; /* Zero, inverted for speedups */ | |
39 uint32_t v_flag; /* Overflow */ | |
40 uint32_t c_flag; /* Carry */ | |
41 uint32_t int_mask; /* I0-I2 */ | |
42 uint32_t ir; | |
43 uint32_t cyc_bcc_notake_b; | |
44 uint32_t cyc_bcc_notake_w; | |
45 uint32_t cyc_dbcc_f_noexp; | |
46 uint32_t cyc_dbcc_f_exp; | |
47 uint32_t cyc_scc_r_true; | |
48 uint32_t cyc_movem_w; | |
49 uint32_t cyc_movem_l; | |
50 uint32_t cyc_shift; | |
51 uint32_t cyc_reset; | |
52 | |
53 void (**jump_table)(m68000_base_device *m68k); | |
54 const uint8_t* cyc_instruction; | |
55 const uint8_t* cyc_exception; | |
56 }; | |
57 | |
58 /* Special interrupt acknowledge values. | |
59 * Use these as special returns from the interrupt acknowledge callback | |
60 * (specified later in this header). | |
61 */ | |
62 | |
63 /* Causes an interrupt autovector (0x18 + interrupt level) to be taken. | |
64 * This happens in a real 68K if VPA or AVEC is asserted during an interrupt | |
65 * acknowledge cycle instead of DTACK. | |
66 */ | |
67 #define M68K_INT_ACK_AUTOVECTOR 0xffffffff | |
68 | |
69 /* Causes the spurious interrupt vector (0x18) to be taken | |
70 * This happens in a real 68K if BERR is asserted during the interrupt | |
71 * acknowledge cycle (i.e. no devices responded to the acknowledge). | |
72 */ | |
73 #define M68K_INT_ACK_SPURIOUS 0xfffffffe | |
74 | |
75 #include <limits.h> | |
76 | |
77 #if defined(__sun__) && defined(__svr4__) | |
78 #undef REG_SP | |
79 #undef REG_PC | |
80 #undef REG_FP | |
81 #endif | |
82 | |
83 /* ======================================================================== */ | |
84 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */ | |
85 /* ======================================================================== */ | |
86 | |
87 /* Check for > 32bit sizes */ | |
88 #define MAKE_INT_8(A) (int8_t)(A) | |
89 #define MAKE_INT_16(A) (int16_t)(A) | |
90 #define MAKE_INT_32(A) (int32_t)(A) | |
91 | |
92 | |
93 /* ======================================================================== */ | |
94 /* ============================ GENERAL DEFINES =========================== */ | |
95 /* ======================================================================== */ | |
96 | |
97 /* Exception Vectors handled by emulation */ | |
98 #define EXCEPTION_RESET 0 | |
99 #define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */ | |
100 #define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */ | |
101 #define EXCEPTION_ILLEGAL_INSTRUCTION 4 | |
102 #define EXCEPTION_ZERO_DIVIDE 5 | |
103 #define EXCEPTION_CHK 6 | |
104 #define EXCEPTION_TRAPV 7 | |
105 #define EXCEPTION_PRIVILEGE_VIOLATION 8 | |
106 #define EXCEPTION_TRACE 9 | |
107 #define EXCEPTION_1010 10 | |
108 #define EXCEPTION_1111 11 | |
109 #define EXCEPTION_FORMAT_ERROR 14 | |
110 #define EXCEPTION_UNINITIALIZED_INTERRUPT 15 | |
111 #define EXCEPTION_SPURIOUS_INTERRUPT 24 | |
112 #define EXCEPTION_INTERRUPT_AUTOVECTOR 24 | |
113 #define EXCEPTION_TRAP_BASE 32 | |
114 | |
115 /* Function codes set by CPU during data/address bus activity */ | |
116 #define FUNCTION_CODE_USER_DATA 1 | |
117 #define FUNCTION_CODE_USER_PROGRAM 2 | |
118 #define FUNCTION_CODE_SUPERVISOR_DATA 5 | |
119 #define FUNCTION_CODE_SUPERVISOR_PROGRAM 6 | |
120 #define FUNCTION_CODE_CPU_SPACE 7 | |
121 | |
122 /* CPU types for deciding what to emulate */ | |
123 #define CPU_TYPE_000 (0x00000001) | |
124 #define CPU_TYPE_008 (0x00000002) | |
125 #define CPU_TYPE_010 (0x00000004) | |
126 #define CPU_TYPE_EC020 (0x00000008) | |
127 #define CPU_TYPE_020 (0x00000010) | |
128 #define CPU_TYPE_EC030 (0x00000020) | |
129 #define CPU_TYPE_030 (0x00000040) | |
130 #define CPU_TYPE_EC040 (0x00000080) | |
131 #define CPU_TYPE_LC040 (0x00000100) | |
132 #define CPU_TYPE_040 (0x00000200) | |
133 #define CPU_TYPE_SCC070 (0x00000400) | |
134 #define CPU_TYPE_FSCPU32 (0x00000800) | |
135 #define CPU_TYPE_COLDFIRE (0x00001000) | |
136 | |
137 /* Different ways to stop the CPU */ | |
138 #define STOP_LEVEL_STOP 1 | |
139 #define STOP_LEVEL_HALT 2 | |
140 | |
141 /* Used for 68000 address error processing */ | |
142 #define INSTRUCTION_YES 0 | |
143 #define INSTRUCTION_NO 0x08 | |
144 #define MODE_READ 0x10 | |
145 #define MODE_WRITE 0 | |
146 | |
147 #define RUN_MODE_NORMAL 0 | |
148 #define RUN_MODE_BERR_AERR_RESET 1 | |
149 | |
150 | |
151 | |
152 #define M68K_CACR_IBE 0x10 // Instruction Burst Enable | |
153 #define M68K_CACR_CI 0x08 // Clear Instruction Cache | |
154 #define M68K_CACR_CEI 0x04 // Clear Entry in Instruction Cache | |
155 #define M68K_CACR_FI 0x02 // Freeze Instruction Cache | |
156 #define M68K_CACR_EI 0x01 // Enable Instruction Cache | |
157 | |
158 /* ======================================================================== */ | |
159 /* ================================ MACROS ================================ */ | |
160 /* ======================================================================== */ | |
161 | |
162 | |
163 /* ---------------------------- General Macros ---------------------------- */ | |
164 | |
165 /* Bit Isolation Macros */ | |
166 #define BIT_0(A) ((A) & 0x00000001) | |
167 #define BIT_1(A) ((A) & 0x00000002) | |
168 #define BIT_2(A) ((A) & 0x00000004) | |
169 #define BIT_3(A) ((A) & 0x00000008) | |
170 #define BIT_4(A) ((A) & 0x00000010) | |
171 #define BIT_5(A) ((A) & 0x00000020) | |
172 #define BIT_6(A) ((A) & 0x00000040) | |
173 #define BIT_7(A) ((A) & 0x00000080) | |
174 #define BIT_8(A) ((A) & 0x00000100) | |
175 #define BIT_9(A) ((A) & 0x00000200) | |
176 #define BIT_A(A) ((A) & 0x00000400) | |
177 #define BIT_B(A) ((A) & 0x00000800) | |
178 #define BIT_C(A) ((A) & 0x00001000) | |
179 #define BIT_D(A) ((A) & 0x00002000) | |
180 #define BIT_E(A) ((A) & 0x00004000) | |
181 #define BIT_F(A) ((A) & 0x00008000) | |
182 #define BIT_10(A) ((A) & 0x00010000) | |
183 #define BIT_11(A) ((A) & 0x00020000) | |
184 #define BIT_12(A) ((A) & 0x00040000) | |
185 #define BIT_13(A) ((A) & 0x00080000) | |
186 #define BIT_14(A) ((A) & 0x00100000) | |
187 #define BIT_15(A) ((A) & 0x00200000) | |
188 #define BIT_16(A) ((A) & 0x00400000) | |
189 #define BIT_17(A) ((A) & 0x00800000) | |
190 #define BIT_18(A) ((A) & 0x01000000) | |
191 #define BIT_19(A) ((A) & 0x02000000) | |
192 #define BIT_1A(A) ((A) & 0x04000000) | |
193 #define BIT_1B(A) ((A) & 0x08000000) | |
194 #define BIT_1C(A) ((A) & 0x10000000) | |
195 #define BIT_1D(A) ((A) & 0x20000000) | |
196 #define BIT_1E(A) ((A) & 0x40000000) | |
197 #define BIT_1F(A) ((A) & 0x80000000) | |
198 | |
199 /* Get the most significant bit for specific sizes */ | |
200 #define GET_MSB_8(A) ((A) & 0x80) | |
201 #define GET_MSB_9(A) ((A) & 0x100) | |
202 #define GET_MSB_16(A) ((A) & 0x8000) | |
203 #define GET_MSB_17(A) ((A) & 0x10000) | |
204 #define GET_MSB_32(A) ((A) & 0x80000000) | |
205 #define GET_MSB_33(A) ((A) & 0x100000000U) | |
206 | |
207 /* Isolate nibbles */ | |
208 #define LOW_NIBBLE(A) ((A) & 0x0f) | |
209 #define HIGH_NIBBLE(A) ((A) & 0xf0) | |
210 | |
211 /* These are used to isolate 8, 16, and 32 bit sizes */ | |
212 #define MASK_OUT_ABOVE_2(A) ((A) & 3) | |
213 #define MASK_OUT_ABOVE_8(A) ((A) & 0xff) | |
214 #define MASK_OUT_ABOVE_16(A) ((A) & 0xffff) | |
215 #define MASK_OUT_BELOW_2(A) ((A) & ~3) | |
216 #define MASK_OUT_BELOW_8(A) ((A) & ~0xff) | |
217 #define MASK_OUT_BELOW_16(A) ((A) & ~0xffff) | |
218 | |
219 /* No need to mask if we are 32 bit */ | |
220 #define MASK_OUT_ABOVE_32(A) ((A) & ((uint64_t)0xffffffffU)) | |
221 #define MASK_OUT_BELOW_32(A) ((A) & ~((uint64_t)0xffffffffU)) | |
222 | |
223 /* Shift & Rotate Macros. */ | |
224 #define LSL(A, C) ((A) << (C)) | |
225 #define LSR(A, C) ((A) >> (C)) | |
226 | |
227 /* We have to do this because the morons at ANSI decided that shifts | |
228 * by >= data size are undefined. | |
229 */ | |
230 #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) | |
231 #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) | |
232 | |
233 #define LSL_32_64(A, C) ((A) << (C)) | |
234 #define LSR_32_64(A, C) ((A) >> (C)) | |
235 #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C))) | |
236 #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C))) | |
237 | |
238 #define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C))) | |
239 #define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) | |
240 #define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C))) | |
241 #define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) | |
242 #define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C))) | |
243 #define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) | |
244 | |
245 #define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C))) | |
246 #define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) | |
247 #define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C))) | |
248 #define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) | |
249 #define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C))) | |
250 #define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) | |
251 | |
252 | |
253 | |
254 /* ------------------------------ CPU Access ------------------------------ */ | |
255 | |
256 /* Access the CPU registers */ | |
257 #define REG_DA(M) (M)->c.dregs /* easy access to data and address regs */ | |
258 #define REG_D(M) (M)->c.dregs | |
259 #define REG_A(M) (M)->c.aregs | |
260 #define REG_PPC(M) (M)->ppc | |
261 #define REG_PC(M) (M)->pc | |
262 #define REG_USP(M) (M)->c.aregs[8] | |
263 #define REG_ISP(M) (M)->c.aregs[7] | |
264 #define REG_MSP(M) (M)->c.aregs[7] | |
265 #define REG_SP(M) (M)->c.aregs[7] | |
266 | |
267 | |
268 | |
269 /* ----------------------------- Configuration ---------------------------- */ | |
270 | |
271 /* These defines are dependant on the configuration defines in m68kconf.h */ | |
272 | |
273 /* Disable certain comparisons if we're not using all CPU types */ | |
274 #define CPU_TYPE_IS_COLDFIRE(A) ((A) & (CPU_TYPE_COLDFIRE)) | |
275 | |
276 #define CPU_TYPE_IS_040_PLUS(A) ((A) & (CPU_TYPE_040 | CPU_TYPE_EC040)) | |
277 #define CPU_TYPE_IS_040_LESS(A) 1 | |
278 | |
279 #define CPU_TYPE_IS_030_PLUS(A) ((A) & (CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040)) | |
280 #define CPU_TYPE_IS_030_LESS(A) 1 | |
281 | |
282 #define CPU_TYPE_IS_020_PLUS(A) ((A) & (CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_FSCPU32 | CPU_TYPE_COLDFIRE)) | |
283 #define CPU_TYPE_IS_020_LESS(A) 1 | |
284 | |
285 #define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_FSCPU32)) | |
286 | |
287 #define CPU_TYPE_IS_EC020_PLUS(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_FSCPU32 | CPU_TYPE_COLDFIRE)) | |
288 #define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020)) | |
289 | |
290 #define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010) | |
291 #define CPU_TYPE_IS_010_PLUS(A) ((A) & (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_FSCPU32 | CPU_TYPE_COLDFIRE)) | |
292 #define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010)) | |
293 | |
294 #define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000 || (A) == CPU_TYPE_008) | |
295 | |
296 | |
297 /* -------------------------- EA / Operand Access ------------------------- */ | |
298 | |
299 /* | |
300 * The general instruction format follows this pattern: | |
301 * .... XXX. .... .YYY | |
302 * where XXX is register X and YYY is register Y | |
303 */ | |
304 /* Data Register Isolation */ | |
305 #define DX(M) (REG_D(M)[((M)->ir >> 9) & 7]) | |
306 #define DY(M) (REG_D(M)[(M)->ir & 7]) | |
307 /* Address Register Isolation */ | |
308 #define AX(M) (REG_A(M)[((M)->ir >> 9) & 7]) | |
309 #define AY(M) (REG_A(M)[(M)->ir & 7]) | |
310 | |
311 | |
312 /* Effective Address Calculations */ | |
313 #define EA_AY_AI_8(M) AY(M) /* address register indirect */ | |
314 #define EA_AY_AI_16(M) EA_AY_AI_8(M) | |
315 #define EA_AY_AI_32(M) EA_AY_AI_8(M) | |
316 #define EA_AY_PI_8(M) (AY(M)++) /* postincrement (size = byte) */ | |
317 #define EA_AY_PI_16(M) ((AY(M)+=2)-2) /* postincrement (size = word) */ | |
318 #define EA_AY_PI_32(M) ((AY(M)+=4)-4) /* postincrement (size = long) */ | |
319 #define EA_AY_PD_8(M) (--AY(M)) /* predecrement (size = byte) */ | |
320 #define EA_AY_PD_16(M) (AY(M)-=2) /* predecrement (size = word) */ | |
321 #define EA_AY_PD_32(M) (AY(M)-=4) /* predecrement (size = long) */ | |
322 #define EA_AY_DI_8(M) (AY(M)+MAKE_INT_16(m68ki_read_imm_16(M))) /* displacement */ | |
323 #define EA_AY_DI_16(M) EA_AY_DI_8(M) | |
324 #define EA_AY_DI_32(M) EA_AY_DI_8(M) | |
325 #define EA_AY_IX_8(M) m68ki_get_ea_ix(M, AY(M)) /* indirect + index */ | |
326 #define EA_AY_IX_16(M) EA_AY_IX_8(M) | |
327 #define EA_AY_IX_32(M) EA_AY_IX_8(M) | |
328 | |
329 #define EA_AX_AI_8(M) AX(M) | |
330 #define EA_AX_AI_16(M) EA_AX_AI_8(M) | |
331 #define EA_AX_AI_32(M) EA_AX_AI_8(M) | |
332 #define EA_AX_PI_8(M) (AX(M)++) | |
333 #define EA_AX_PI_16(M) ((AX(M)+=2)-2) | |
334 #define EA_AX_PI_32(M) ((AX(M)+=4)-4) | |
335 #define EA_AX_PD_8(M) (--AX(M)) | |
336 #define EA_AX_PD_16(M) (AX(M)-=2) | |
337 #define EA_AX_PD_32(M) (AX(M)-=4) | |
338 #define EA_AX_DI_8(M) (AX(M)+MAKE_INT_16(m68ki_read_imm_16(M))) | |
339 #define EA_AX_DI_16(M) EA_AX_DI_8(M) | |
340 #define EA_AX_DI_32(M) EA_AX_DI_8(M) | |
341 #define EA_AX_IX_8(M) m68ki_get_ea_ix(M, AX(M)) | |
342 #define EA_AX_IX_16(M) EA_AX_IX_8(M) | |
343 #define EA_AX_IX_32(M) EA_AX_IX_8(M) | |
344 | |
345 #define EA_A7_PI_8(m68k) ((REG_A(m68k)[7]+=2)-2) | |
346 #define EA_A7_PD_8(m68k) (REG_A(m68k)[7]-=2) | |
347 | |
348 #define EA_AW_8(m68k) MAKE_INT_16(m68ki_read_imm_16(m68k)) /* absolute word */ | |
349 #define EA_AW_16(m68k) EA_AW_8(m68k) | |
350 #define EA_AW_32(m68k) EA_AW_8(m68k) | |
351 #define EA_AL_8(m68k) m68ki_read_imm_32(m68k) /* absolute long */ | |
352 #define EA_AL_16(m68k) EA_AL_8(m68k) | |
353 #define EA_AL_32(m68k) EA_AL_8(m68k) | |
354 #define EA_PCDI_8(m68k) m68ki_get_ea_pcdi(m68k) /* pc indirect + displacement */ | |
355 #define EA_PCDI_16(m68k) EA_PCDI_8(m68k) | |
356 #define EA_PCDI_32(m68k) EA_PCDI_8(m68k) | |
357 #define EA_PCIX_8(m68k) m68ki_get_ea_pcix(m68k) /* pc indirect + index */ | |
358 #define EA_PCIX_16(m68k) EA_PCIX_8(m68k) | |
359 #define EA_PCIX_32(m68k) EA_PCIX_8(m68k) | |
360 | |
361 | |
362 #define OPER_I_8(m68k) m68ki_read_imm_8(m68k) | |
363 #define OPER_I_16(m68k) m68ki_read_imm_16(m68k) | |
364 #define OPER_I_32(m68k) m68ki_read_imm_32(m68k) | |
365 | |
366 | |
367 | |
368 /* --------------------------- Status Register ---------------------------- */ | |
369 | |
370 /* Flag Calculation Macros */ | |
371 #define CFLAG_8(A) (A) | |
372 #define CFLAG_16(A) ((A)>>8) | |
373 | |
374 #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23) | |
375 #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23) | |
376 | |
377 #define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R)) | |
378 #define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8) | |
379 #define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24) | |
380 | |
381 #define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D)) | |
382 #define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8) | |
383 #define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24) | |
384 | |
385 #define NFLAG_8(A) (A) | |
386 #define NFLAG_16(A) ((A)>>8) | |
387 #define NFLAG_32(A) ((A)>>24) | |
388 #define NFLAG_64(A) ((A)>>56) | |
389 | |
390 #define ZFLAG_8(A) MASK_OUT_ABOVE_8(A) | |
391 #define ZFLAG_16(A) MASK_OUT_ABOVE_16(A) | |
392 #define ZFLAG_32(A) MASK_OUT_ABOVE_32(A) | |
393 | |
394 | |
395 /* Flag values */ | |
396 #define NFLAG_SET 0x80 | |
397 #define NFLAG_CLEAR 0 | |
398 #define CFLAG_SET 0x100 | |
399 #define CFLAG_CLEAR 0 | |
400 #define XFLAG_SET 0x100 | |
401 #define XFLAG_CLEAR 0 | |
402 #define VFLAG_SET 0x80 | |
403 #define VFLAG_CLEAR 0 | |
404 #define ZFLAG_SET 0 | |
405 #define ZFLAG_CLEAR 0xffffffff | |
406 | |
407 #define SFLAG_SET 4 | |
408 #define SFLAG_CLEAR 0 | |
409 #define MFLAG_SET 2 | |
410 #define MFLAG_CLEAR 0 | |
411 | |
412 /* Turn flag values into 1 or 0 */ | |
413 #define XFLAG_AS_1(M) (((M)->x_flag>>8)&1) | |
414 #define NFLAG_AS_1(M) (((M)->n_flag>>7)&1) | |
415 #define VFLAG_AS_1(M) (((M)->v_flag>>7)&1) | |
416 #define ZFLAG_AS_1(M) (!(M)->not_z_flag) | |
417 #define CFLAG_AS_1(M) (((M)->c_flag>>8)&1) | |
418 | |
419 | |
420 /* Conditions */ | |
421 #define COND_CS(M) ((M)->c_flag&0x100) | |
422 #define COND_CC(M) (!COND_CS(M)) | |
423 #define COND_VS(M) ((M)->v_flag&0x80) | |
424 #define COND_VC(M) (!COND_VS(M)) | |
425 #define COND_NE(M) (M)->not_z_flag | |
426 #define COND_EQ(M) (!COND_NE(M)) | |
427 #define COND_MI(M) ((M)->n_flag&0x80) | |
428 #define COND_PL(M) (!COND_MI(M)) | |
429 #define COND_LT(M) (((M)->n_flag^(M)->v_flag)&0x80) | |
430 #define COND_GE(M) (!COND_LT(M)) | |
431 #define COND_HI(M) (COND_CC(M) && COND_NE(M)) | |
432 #define COND_LS(M) (COND_CS(M) || COND_EQ(M)) | |
433 #define COND_GT(M) (COND_GE(M) && COND_NE(M)) | |
434 #define COND_LE(M) (COND_LT(M) || COND_EQ(M)) | |
435 | |
436 /* Reversed conditions */ | |
437 #define COND_NOT_CS(M) COND_CC(M) | |
438 #define COND_NOT_CC(M) COND_CS(M) | |
439 #define COND_NOT_VS(M) COND_VC(M) | |
440 #define COND_NOT_VC(M) COND_VS(M) | |
441 #define COND_NOT_NE(M) COND_EQ(M) | |
442 #define COND_NOT_EQ(M) COND_NE(M) | |
443 #define COND_NOT_MI(M) COND_PL(M) | |
444 #define COND_NOT_PL(M) COND_MI(M) | |
445 #define COND_NOT_LT(M) COND_GE(M) | |
446 #define COND_NOT_GE(M) COND_LT(M) | |
447 #define COND_NOT_HI(M) COND_LS(M) | |
448 #define COND_NOT_LS(M) COND_HI(M) | |
449 #define COND_NOT_GT(M) COND_LE(M) | |
450 #define COND_NOT_LE(M) COND_GT(M) | |
451 | |
452 /* Not real conditions, but here for convenience */ | |
453 #define COND_XS(M) ((M)->x_flag&0x100) | |
454 #define COND_XC(M) (!COND_XS) | |
455 | |
456 | |
457 /* Get the condition code register */ | |
458 #define m68ki_get_ccr(M) ((COND_XS(M) >> 4) | \ | |
459 (COND_MI(M) >> 4) | \ | |
460 (COND_EQ(M) << 2) | \ | |
461 (COND_VS(M) >> 6) | \ | |
462 (COND_CS(M) >> 8)) | |
463 | |
464 /* Get the status register */ | |
465 #define m68ki_get_sr(M) (/*(M)->t1_flag |*/ \ | |
466 /*(M)->t0_flag |*/ \ | |
467 ((M)->s_flag << 11) | \ | |
468 ((M)->m_flag << 11) | \ | |
469 (M)->int_mask | \ | |
470 m68ki_get_ccr(M)) | |
471 | |
472 | |
473 | |
474 /* ----------------------------- Read / Write ----------------------------- */ | |
475 | |
476 /* Read from the current address space */ | |
477 uint8_t m68ki_read_8(m68000_base_device *m68k, uint32_t address); | |
478 uint16_t m68ki_read_16(m68000_base_device *m68k, uint32_t address); | |
479 static inline uint32_t m68ki_read_32(m68000_base_device *m68k, uint32_t address) | |
480 { | |
481 return m68ki_read_16(m68k, address) << 16 | m68ki_read_16(m68k, address+2); | |
482 } | |
483 /*#define m68ki_read_8(M, A) m68ki_read_8_fc (M, A, (M)->s_flag | FUNCTION_CODE_USER_DATA) | |
484 #define m68ki_read_16(M, A) m68ki_read_16_fc(M, A, (M)->s_flag | FUNCTION_CODE_USER_DATA) | |
485 #define m68ki_read_32(M, A) m68ki_read_32_fc(M, A, (M)->s_flag | FUNCTION_CODE_USER_DATA)*/ | |
486 | |
487 /* Write to the current data space */ | |
488 void m68ki_write_8(m68000_base_device *m68k, uint32_t address, uint8_t value); | |
489 void m68ki_write_16(m68000_base_device *m68k, uint32_t address, uint16_t value); | |
490 static inline void m68ki_write_32(m68000_base_device *m68k, uint32_t address, uint32_t value) | |
491 { | |
492 m68ki_write_16(m68k, address, value >> 16); | |
493 m68ki_write_16(m68k, address+2, value); | |
494 } | |
495 /* | |
496 #define m68ki_write_8(M, A, V) m68ki_write_8_fc (M, A, (M)->s_flag | FUNCTION_CODE_USER_DATA, V) | |
497 #define m68ki_write_16(M, A, V) m68ki_write_16_fc(M, A, (M)->s_flag | FUNCTION_CODE_USER_DATA, V) | |
498 #define m68ki_write_32(M, A, V) m68ki_write_32_fc(M, A, (M)->s_flag | FUNCTION_CODE_USER_DATA, V) | |
499 #define m68ki_write_32_pd(M, A, V) m68ki_write_32_pd_fc(M, A, (M)->s_flag | FUNCTION_CODE_USER_DATA, V)*/ | |
500 | |
501 /* map read immediate 8 to read immediate 16 */ | |
502 #define m68ki_read_imm_8(M) MASK_OUT_ABOVE_8(m68ki_read_imm_16(M)) | |
503 | |
504 | |
505 /* ======================================================================== */ | |
506 /* =============================== PROTOTYPES ============================= */ | |
507 /* ======================================================================== */ | |
508 | |
509 union fp_reg | |
510 { | |
511 uint64_t i; | |
512 double f; | |
513 }; | |
514 | |
515 void m68ki_exception_interrupt(m68000_base_device *m68k, uint32_t int_level); | |
516 | |
517 | |
518 extern const uint8_t m68ki_shift_8_table[]; | |
519 extern const uint16_t m68ki_shift_16_table[]; | |
520 extern const uint32_t m68ki_shift_32_table[]; | |
521 extern const uint8_t m68ki_exception_cycle_table[][256]; | |
522 extern const uint8_t m68ki_ea_idx_cycle_table[]; | |
523 | |
524 /* Read data immediately after the program counter */ | |
525 static inline uint32_t m68ki_read_imm_16(m68000_base_device *m68k); | |
526 static inline uint32_t m68ki_read_imm_32(m68000_base_device *m68k); | |
527 | |
528 /* Write data with specific function code */ | |
529 static inline void m68ki_write_8_fc (m68000_base_device *m68k, uint32_t address, uint32_t fc, uint32_t value); | |
530 static inline void m68ki_write_16_fc(m68000_base_device *m68k, uint32_t address, uint32_t fc, uint32_t value); | |
531 static inline void m68ki_write_32_fc(m68000_base_device *m68k, uint32_t address, uint32_t fc, uint32_t value); | |
532 | |
533 /* Indexed and PC-relative ea fetching */ | |
534 static inline uint32_t m68ki_get_ea_pcdi(m68000_base_device *m68k); | |
535 static inline uint32_t m68ki_get_ea_pcix(m68000_base_device *m68k); | |
536 static inline uint32_t m68ki_get_ea_ix(m68000_base_device *m68k, uint32_t An); | |
537 | |
538 /* Operand fetching */ | |
539 static inline uint32_t OPER_AY_AI_8(m68000_base_device *m68k); | |
540 static inline uint32_t OPER_AY_AI_16(m68000_base_device *m68k); | |
541 static inline uint32_t OPER_AY_AI_32(m68000_base_device *m68k); | |
542 static inline uint32_t OPER_AY_PI_8(m68000_base_device *m68k); | |
543 static inline uint32_t OPER_AY_PI_16(m68000_base_device *m68k); | |
544 static inline uint32_t OPER_AY_PI_32(m68000_base_device *m68k); | |
545 static inline uint32_t OPER_AY_PD_8(m68000_base_device *m68k); | |
546 static inline uint32_t OPER_AY_PD_16(m68000_base_device *m68k); | |
547 static inline uint32_t OPER_AY_PD_32(m68000_base_device *m68k); | |
548 static inline uint32_t OPER_AY_DI_8(m68000_base_device *m68k); | |
549 static inline uint32_t OPER_AY_DI_16(m68000_base_device *m68k); | |
550 static inline uint32_t OPER_AY_DI_32(m68000_base_device *m68k); | |
551 static inline uint32_t OPER_AY_IX_8(m68000_base_device *m68k); | |
552 static inline uint32_t OPER_AY_IX_16(m68000_base_device *m68k); | |
553 static inline uint32_t OPER_AY_IX_32(m68000_base_device *m68k); | |
554 | |
555 static inline uint32_t OPER_AX_AI_8(m68000_base_device *m68k); | |
556 static inline uint32_t OPER_AX_AI_16(m68000_base_device *m68k); | |
557 static inline uint32_t OPER_AX_AI_32(m68000_base_device *m68k); | |
558 static inline uint32_t OPER_AX_PI_8(m68000_base_device *m68k); | |
559 static inline uint32_t OPER_AX_PI_16(m68000_base_device *m68k); | |
560 static inline uint32_t OPER_AX_PI_32(m68000_base_device *m68k); | |
561 static inline uint32_t OPER_AX_PD_8(m68000_base_device *m68k); | |
562 static inline uint32_t OPER_AX_PD_16(m68000_base_device *m68k); | |
563 static inline uint32_t OPER_AX_PD_32(m68000_base_device *m68k); | |
564 static inline uint32_t OPER_AX_DI_8(m68000_base_device *m68k); | |
565 static inline uint32_t OPER_AX_DI_16(m68000_base_device *m68k); | |
566 static inline uint32_t OPER_AX_DI_32(m68000_base_device *m68k); | |
567 static inline uint32_t OPER_AX_IX_8(m68000_base_device *m68k); | |
568 static inline uint32_t OPER_AX_IX_16(m68000_base_device *m68k); | |
569 static inline uint32_t OPER_AX_IX_32(m68000_base_device *m68k); | |
570 | |
571 static inline uint32_t OPER_A7_PI_8(m68000_base_device *m68k); | |
572 static inline uint32_t OPER_A7_PD_8(m68000_base_device *m68k); | |
573 | |
574 static inline uint32_t OPER_AW_8(m68000_base_device *m68k); | |
575 static inline uint32_t OPER_AW_16(m68000_base_device *m68k); | |
576 static inline uint32_t OPER_AW_32(m68000_base_device *m68k); | |
577 static inline uint32_t OPER_AL_8(m68000_base_device *m68k); | |
578 static inline uint32_t OPER_AL_16(m68000_base_device *m68k); | |
579 static inline uint32_t OPER_AL_32(m68000_base_device *m68k); | |
580 static inline uint32_t OPER_PCDI_8(m68000_base_device *m68k); | |
581 static inline uint32_t OPER_PCDI_16(m68000_base_device *m68k); | |
582 static inline uint32_t OPER_PCDI_32(m68000_base_device *m68k); | |
583 static inline uint32_t OPER_PCIX_8(m68000_base_device *m68k); | |
584 static inline uint32_t OPER_PCIX_16(m68000_base_device *m68k); | |
585 static inline uint32_t OPER_PCIX_32(m68000_base_device *m68k); | |
586 | |
587 /* Stack operations */ | |
588 static inline void m68ki_push_16(m68000_base_device *m68k, uint32_t value); | |
589 static inline void m68ki_push_32(m68000_base_device *m68k, uint32_t value); | |
590 static inline uint32_t m68ki_pull_16(m68000_base_device *m68k); | |
591 static inline uint32_t m68ki_pull_32(m68000_base_device *m68k); | |
592 | |
593 /* Program flow operations */ | |
594 static inline void m68ki_jump(m68000_base_device *m68k, uint32_t new_pc); | |
595 static inline void m68ki_jump_vector(m68000_base_device *m68k, uint32_t vector); | |
596 static inline void m68ki_branch_8(m68000_base_device *m68k, uint32_t offset); | |
597 static inline void m68ki_branch_16(m68000_base_device *m68k, uint32_t offset); | |
598 static inline void m68ki_branch_32(m68000_base_device *m68k, uint32_t offset); | |
599 | |
600 /* Status register operations. */ | |
601 static inline void m68ki_set_s_flag(m68000_base_device *m68k, uint32_t value); /* Only bit 2 of value should be set (i.e. 4 or 0) */ | |
602 static inline void m68ki_set_sm_flag(m68000_base_device *m68k, uint32_t value); /* only bits 1 and 2 of value should be set */ | |
603 static inline void m68ki_set_ccr(m68000_base_device *m68k, uint32_t value); /* set the condition code register */ | |
604 static inline void m68ki_set_sr(m68000_base_device *m68k, uint32_t value); /* set the status register */ | |
605 static inline void m68ki_set_sr_noint(m68000_base_device *m68k, uint32_t value); /* set the status register */ | |
606 | |
607 /* Exception processing */ | |
608 static inline uint32_t m68ki_init_exception(m68000_base_device *m68k); /* Initial exception processing */ | |
609 | |
610 static inline void m68ki_stack_frame_3word(m68000_base_device *m68k, uint32_t pc, uint32_t sr); /* Stack various frame types */ | |
611 static inline void m68ki_stack_frame_buserr(m68000_base_device *m68k, uint32_t sr); | |
612 | |
613 static inline void m68ki_stack_frame_0000(m68000_base_device *m68k, uint32_t pc, uint32_t sr, uint32_t vector); | |
614 static inline void m68ki_stack_frame_0001(m68000_base_device *m68k, uint32_t pc, uint32_t sr, uint32_t vector); | |
615 static inline void m68ki_stack_frame_0010(m68000_base_device *m68k, uint32_t sr, uint32_t vector); | |
616 static inline void m68ki_stack_frame_1000(m68000_base_device *m68k, uint32_t pc, uint32_t sr, uint32_t vector); | |
617 static inline void m68ki_stack_frame_1010(m68000_base_device *m68k, uint32_t sr, uint32_t vector, uint32_t pc, uint32_t fault_address); | |
618 static inline void m68ki_stack_frame_1011(m68000_base_device *m68k, uint32_t sr, uint32_t vector, uint32_t pc, uint32_t fault_address); | |
619 static inline void m68ki_stack_frame_0111(m68000_base_device *m68k, uint32_t sr, uint32_t vector, uint32_t pc, uint32_t fault_address, uint8_t in_mmu); | |
620 | |
621 static inline void m68ki_exception_trap(m68000_base_device *m68k, uint32_t vector); | |
622 static inline void m68ki_exception_trapN(m68000_base_device *m68k, uint32_t vector); | |
623 static inline void m68ki_exception_trace(m68000_base_device *m68k); | |
624 static inline void m68ki_exception_privilege_violation(m68000_base_device *m68k); | |
625 static inline void m68ki_exception_1010(m68000_base_device *m68k); | |
626 static inline void m68ki_exception_1111(m68000_base_device *m68k); | |
627 static inline void m68ki_exception_illegal(m68000_base_device *m68k); | |
628 static inline void m68ki_exception_format_error(m68000_base_device *m68k); | |
629 static inline void m68ki_exception_address_error(m68000_base_device *m68k); | |
630 | |
631 static inline void m68ki_check_interrupts(m68000_base_device *m68k); /* ASG: check for interrupts */ | |
632 | |
633 /* quick disassembly (used for logging) */ | |
634 char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type); | |
635 | |
636 void m68k_cpu_execute(m68000_base_device *this); | |
637 void m68k_reset_cpu(m68000_base_device *this); | |
638 void m68k_init_cpu_m68000(m68000_base_device *this); | |
639 | |
640 #define m68ki_trace_t0(M) | |
641 #define m68ki_trace_t1(M) | |
642 | |
643 | |
644 /* ======================================================================== */ | |
645 /* =========================== UTILITY FUNCTIONS ========================== */ | |
646 /* ======================================================================== */ | |
647 | |
648 | |
649 /* Special call to simulate undocumented 68k behavior when move.l with a | |
650 * predecrement destination mode is executed. | |
651 * A real 68k first writes the high word to [address+2], and then writes the | |
652 * low word to [address]. | |
653 */ | |
654 static inline void m68kx_write_memory_32_pd(m68000_base_device *m68k, unsigned int address, unsigned int value) | |
655 { | |
656 m68ki_write_16(m68k, address, value); | |
657 m68ki_write_16(m68k, address, value >> 16); | |
658 } | |
659 | |
660 | |
661 /* ---------------------------- Read Immediate ---------------------------- */ | |
662 | |
663 | |
664 /* Handles all immediate reads, does address error check, function code setting, | |
665 * and prefetching if they are enabled in m68kconf.h | |
666 */ | |
667 static inline uint32_t m68ki_read_imm_16(m68000_base_device *m68k) | |
668 { | |
669 uint32_t result; | |
670 | |
671 if(REG_PC(m68k) != m68k->pref_addr) | |
672 { | |
673 m68k->pref_data = m68ki_read_16(m68k, REG_PC(m68k)); | |
674 m68k->pref_addr = REG_PC(m68k); | |
675 } | |
676 result = MASK_OUT_ABOVE_16(m68k->pref_data); | |
677 REG_PC(m68k) += 2; | |
678 | |
679 return result; | |
680 } | |
681 | |
682 static inline uint32_t m68ki_read_imm_32(m68000_base_device *m68k) | |
683 { | |
684 uint32_t temp_val; | |
685 if(REG_PC(m68k) != m68k->pref_addr) | |
686 { | |
687 m68k->pref_addr = REG_PC(m68k); | |
688 m68k->pref_data = m68ki_read_16(m68k, m68k->pref_addr); | |
689 } | |
690 temp_val = MASK_OUT_ABOVE_16(m68k->pref_data); | |
691 REG_PC(m68k) += 2; | |
692 m68k->pref_addr = REG_PC(m68k); | |
693 m68k->pref_data = m68ki_read_16(m68k, m68k->pref_addr); | |
694 | |
695 temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(m68k->pref_data)); | |
696 REG_PC(m68k) += 2; | |
697 m68k->pref_data = m68ki_read_16(m68k, REG_PC(m68k)); | |
698 m68k->pref_addr = REG_PC(m68k); | |
699 | |
700 return temp_val; | |
701 } | |
702 | |
703 | |
704 /* --------------------- Effective Address Calculation -------------------- */ | |
705 | |
706 /* The program counter relative addressing modes cause operands to be | |
707 * retrieved from program space, not data space. | |
708 */ | |
709 static inline uint32_t m68ki_get_ea_pcdi(m68000_base_device *m68k) | |
710 { | |
711 uint32_t old_pc = REG_PC(m68k); | |
712 return old_pc + MAKE_INT_16(m68ki_read_imm_16(m68k)); | |
713 } | |
714 | |
715 | |
716 static inline uint32_t m68ki_get_ea_pcix(m68000_base_device *m68k) | |
717 { | |
718 return m68ki_get_ea_ix(m68k, REG_PC(m68k)); | |
719 } | |
720 | |
721 /* Indexed addressing modes are encoded as follows: | |
722 * | |
723 * Base instruction format: | |
724 * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 | |
725 * x x x x x x x x x x | 1 1 0 | BASE REGISTER (An) | |
726 * | |
727 * Base instruction format for destination EA in move instructions: | |
728 * F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0 | |
729 * x x x x | BASE REG | 1 1 0 | X X X X X X (An) | |
730 * | |
731 * Brief extension format: | |
732 * F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0 | |
733 * D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT | |
734 * | |
735 * Full extension format: | |
736 * F E D C B A 9 8 7 6 5 4 3 2 1 0 | |
737 * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS | |
738 * BASE DISPLACEMENT (0, 16, 32 bit) (bd) | |
739 * OUTER DISPLACEMENT (0, 16, 32 bit) (od) | |
740 * | |
741 * D/A: 0 = Dn, 1 = An (Xn) | |
742 * W/L: 0 = W (sign extend), 1 = L (.SIZE) | |
743 * SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE) | |
744 * BS: 0=add base reg, 1=suppress base reg (An suppressed) | |
745 * IS: 0=add index, 1=suppress index (Xn suppressed) | |
746 * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd) | |
747 * | |
748 * IS I/IS Operation | |
749 * 0 000 No Memory Indirect | |
750 * 0 001 indir prex with null outer | |
751 * 0 010 indir prex with word outer | |
752 * 0 011 indir prex with long outer | |
753 * 0 100 reserved | |
754 * 0 101 indir postx with null outer | |
755 * 0 110 indir postx with word outer | |
756 * 0 111 indir postx with long outer | |
757 * 1 000 no memory indirect | |
758 * 1 001 mem indir with null outer | |
759 * 1 010 mem indir with word outer | |
760 * 1 011 mem indir with long outer | |
761 * 1 100-111 reserved | |
762 */ | |
763 static inline uint32_t m68ki_get_ea_ix(m68000_base_device *m68k, uint32_t An) | |
764 { | |
765 /* An = base register */ | |
766 uint32_t extension = m68ki_read_imm_16(m68k); | |
767 uint32_t Xn = 0; /* Index register */ | |
768 uint32_t bd = 0; /* Base Displacement */ | |
769 uint32_t od = 0; /* Outer Displacement */ | |
770 | |
771 /* Calculate index */ | |
772 Xn = REG_DA(m68k)[extension>>12]; /* Xn */ | |
773 if(!BIT_B(extension)) /* W/L */ | |
774 Xn = MAKE_INT_16(Xn); | |
775 | |
776 /* Add base register and displacement and return */ | |
777 return An + Xn + MAKE_INT_8(extension); | |
778 } | |
779 | |
780 | |
781 /* Fetch operands */ | |
782 static inline uint32_t OPER_AY_AI_8(m68000_base_device *m68k) {uint32_t ea = EA_AY_AI_8(m68k); return m68ki_read_8(m68k, ea); } | |
783 static inline uint32_t OPER_AY_AI_16(m68000_base_device *m68k) {uint32_t ea = EA_AY_AI_16(m68k); return m68ki_read_16(m68k, ea);} | |
784 static inline uint32_t OPER_AY_AI_32(m68000_base_device *m68k) {uint32_t ea = EA_AY_AI_32(m68k); return m68ki_read_32(m68k, ea);} | |
785 static inline uint32_t OPER_AY_PI_8(m68000_base_device *m68k) {uint32_t ea = EA_AY_PI_8(m68k); return m68ki_read_8(m68k, ea); } | |
786 static inline uint32_t OPER_AY_PI_16(m68000_base_device *m68k) {uint32_t ea = EA_AY_PI_16(m68k); return m68ki_read_16(m68k, ea);} | |
787 static inline uint32_t OPER_AY_PI_32(m68000_base_device *m68k) {uint32_t ea = EA_AY_PI_32(m68k); return m68ki_read_32(m68k, ea);} | |
788 static inline uint32_t OPER_AY_PD_8(m68000_base_device *m68k) {uint32_t ea = EA_AY_PD_8(m68k); return m68ki_read_8(m68k, ea); } | |
789 static inline uint32_t OPER_AY_PD_16(m68000_base_device *m68k) {uint32_t ea = EA_AY_PD_16(m68k); return m68ki_read_16(m68k, ea);} | |
790 static inline uint32_t OPER_AY_PD_32(m68000_base_device *m68k) {uint32_t ea = EA_AY_PD_32(m68k); return m68ki_read_32(m68k, ea);} | |
791 static inline uint32_t OPER_AY_DI_8(m68000_base_device *m68k) {uint32_t ea = EA_AY_DI_8(m68k); return m68ki_read_8(m68k, ea); } | |
792 static inline uint32_t OPER_AY_DI_16(m68000_base_device *m68k) {uint32_t ea = EA_AY_DI_16(m68k); return m68ki_read_16(m68k, ea);} | |
793 static inline uint32_t OPER_AY_DI_32(m68000_base_device *m68k) {uint32_t ea = EA_AY_DI_32(m68k); return m68ki_read_32(m68k, ea);} | |
794 static inline uint32_t OPER_AY_IX_8(m68000_base_device *m68k) {uint32_t ea = EA_AY_IX_8(m68k); return m68ki_read_8(m68k, ea); } | |
795 static inline uint32_t OPER_AY_IX_16(m68000_base_device *m68k) {uint32_t ea = EA_AY_IX_16(m68k); return m68ki_read_16(m68k, ea);} | |
796 static inline uint32_t OPER_AY_IX_32(m68000_base_device *m68k) {uint32_t ea = EA_AY_IX_32(m68k); return m68ki_read_32(m68k, ea);} | |
797 | |
798 static inline uint32_t OPER_AX_AI_8(m68000_base_device *m68k) {uint32_t ea = EA_AX_AI_8(m68k); return m68ki_read_8(m68k, ea); } | |
799 static inline uint32_t OPER_AX_AI_16(m68000_base_device *m68k) {uint32_t ea = EA_AX_AI_16(m68k); return m68ki_read_16(m68k, ea);} | |
800 static inline uint32_t OPER_AX_AI_32(m68000_base_device *m68k) {uint32_t ea = EA_AX_AI_32(m68k); return m68ki_read_32(m68k, ea);} | |
801 static inline uint32_t OPER_AX_PI_8(m68000_base_device *m68k) {uint32_t ea = EA_AX_PI_8(m68k); return m68ki_read_8(m68k, ea); } | |
802 static inline uint32_t OPER_AX_PI_16(m68000_base_device *m68k) {uint32_t ea = EA_AX_PI_16(m68k); return m68ki_read_16(m68k, ea);} | |
803 static inline uint32_t OPER_AX_PI_32(m68000_base_device *m68k) {uint32_t ea = EA_AX_PI_32(m68k); return m68ki_read_32(m68k, ea);} | |
804 static inline uint32_t OPER_AX_PD_8(m68000_base_device *m68k) {uint32_t ea = EA_AX_PD_8(m68k); return m68ki_read_8(m68k, ea); } | |
805 static inline uint32_t OPER_AX_PD_16(m68000_base_device *m68k) {uint32_t ea = EA_AX_PD_16(m68k); return m68ki_read_16(m68k, ea);} | |
806 static inline uint32_t OPER_AX_PD_32(m68000_base_device *m68k) {uint32_t ea = EA_AX_PD_32(m68k); return m68ki_read_32(m68k, ea);} | |
807 static inline uint32_t OPER_AX_DI_8(m68000_base_device *m68k) {uint32_t ea = EA_AX_DI_8(m68k); return m68ki_read_8(m68k, ea); } | |
808 static inline uint32_t OPER_AX_DI_16(m68000_base_device *m68k) {uint32_t ea = EA_AX_DI_16(m68k); return m68ki_read_16(m68k, ea);} | |
809 static inline uint32_t OPER_AX_DI_32(m68000_base_device *m68k) {uint32_t ea = EA_AX_DI_32(m68k); return m68ki_read_32(m68k, ea);} | |
810 static inline uint32_t OPER_AX_IX_8(m68000_base_device *m68k) {uint32_t ea = EA_AX_IX_8(m68k); return m68ki_read_8(m68k, ea); } | |
811 static inline uint32_t OPER_AX_IX_16(m68000_base_device *m68k) {uint32_t ea = EA_AX_IX_16(m68k); return m68ki_read_16(m68k, ea);} | |
812 static inline uint32_t OPER_AX_IX_32(m68000_base_device *m68k) {uint32_t ea = EA_AX_IX_32(m68k); return m68ki_read_32(m68k, ea);} | |
813 | |
814 static inline uint32_t OPER_A7_PI_8(m68000_base_device *m68k) {uint32_t ea = EA_A7_PI_8(m68k); return m68ki_read_8(m68k, ea); } | |
815 static inline uint32_t OPER_A7_PD_8(m68000_base_device *m68k) {uint32_t ea = EA_A7_PD_8(m68k); return m68ki_read_8(m68k, ea); } | |
816 | |
817 static inline uint32_t OPER_AW_8(m68000_base_device *m68k) {uint32_t ea = EA_AW_8(m68k); return m68ki_read_8(m68k, ea); } | |
818 static inline uint32_t OPER_AW_16(m68000_base_device *m68k) {uint32_t ea = EA_AW_16(m68k); return m68ki_read_16(m68k, ea);} | |
819 static inline uint32_t OPER_AW_32(m68000_base_device *m68k) {uint32_t ea = EA_AW_32(m68k); return m68ki_read_32(m68k, ea);} | |
820 static inline uint32_t OPER_AL_8(m68000_base_device *m68k) {uint32_t ea = EA_AL_8(m68k); return m68ki_read_8(m68k, ea); } | |
821 static inline uint32_t OPER_AL_16(m68000_base_device *m68k) {uint32_t ea = EA_AL_16(m68k); return m68ki_read_16(m68k, ea);} | |
822 static inline uint32_t OPER_AL_32(m68000_base_device *m68k) {uint32_t ea = EA_AL_32(m68k); return m68ki_read_32(m68k, ea);} | |
823 static inline uint32_t OPER_PCDI_8(m68000_base_device *m68k) {uint32_t ea = EA_PCDI_8(m68k); return m68ki_read_8(m68k, ea); } | |
824 static inline uint32_t OPER_PCDI_16(m68000_base_device *m68k) {uint32_t ea = EA_PCDI_16(m68k); return m68ki_read_16(m68k, ea);} | |
825 static inline uint32_t OPER_PCDI_32(m68000_base_device *m68k) {uint32_t ea = EA_PCDI_32(m68k); return m68ki_read_32(m68k, ea);} | |
826 static inline uint32_t OPER_PCIX_8(m68000_base_device *m68k) {uint32_t ea = EA_PCIX_8(m68k); return m68ki_read_8(m68k, ea); } | |
827 static inline uint32_t OPER_PCIX_16(m68000_base_device *m68k) {uint32_t ea = EA_PCIX_16(m68k); return m68ki_read_16(m68k, ea);} | |
828 static inline uint32_t OPER_PCIX_32(m68000_base_device *m68k) {uint32_t ea = EA_PCIX_32(m68k); return m68ki_read_32(m68k, ea);} | |
829 | |
830 | |
831 | |
832 /* ---------------------------- Stack Functions --------------------------- */ | |
833 | |
834 /* Push/pull data from the stack */ | |
835 static inline void m68ki_push_16(m68000_base_device *m68k, uint32_t value) | |
836 { | |
837 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) - 2); | |
838 m68ki_write_16(m68k, REG_SP(m68k), value); | |
839 } | |
840 | |
841 static inline void m68ki_push_32(m68000_base_device *m68k, uint32_t value) | |
842 { | |
843 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) - 4); | |
844 m68ki_write_32(m68k, REG_SP(m68k), value); | |
845 } | |
846 | |
847 static inline uint32_t m68ki_pull_16(m68000_base_device *m68k) | |
848 { | |
849 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) + 2); | |
850 return m68ki_read_16(m68k, REG_SP(m68k)-2); | |
851 } | |
852 | |
853 static inline uint32_t m68ki_pull_32(m68000_base_device *m68k) | |
854 { | |
855 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) + 4); | |
856 return m68ki_read_32(m68k, REG_SP(m68k)-4); | |
857 } | |
858 | |
859 | |
860 /* Increment/decrement the stack as if doing a push/pull but | |
861 * don't do any memory access. | |
862 */ | |
863 static inline void m68ki_fake_push_16(m68000_base_device *m68k) | |
864 { | |
865 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) - 2); | |
866 } | |
867 | |
868 static inline void m68ki_fake_push_32(m68000_base_device *m68k) | |
869 { | |
870 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) - 4); | |
871 } | |
872 | |
873 static inline void m68ki_fake_pull_16(m68000_base_device *m68k) | |
874 { | |
875 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) + 2); | |
876 } | |
877 | |
878 static inline void m68ki_fake_pull_32(m68000_base_device *m68k) | |
879 { | |
880 REG_SP(m68k) = MASK_OUT_ABOVE_32(REG_SP(m68k) + 4); | |
881 } | |
882 | |
883 | |
884 /* ----------------------------- Program Flow ----------------------------- */ | |
885 | |
886 /* Jump to a new program location or vector. | |
887 * These functions will also call the pc_changed callback if it was enabled | |
888 * in m68kconf.h. | |
889 */ | |
890 static inline void m68ki_jump(m68000_base_device *m68k, uint32_t new_pc) | |
891 { | |
892 REG_PC(m68k) = new_pc; | |
893 } | |
894 | |
895 static inline void m68ki_jump_vector(m68000_base_device *m68k, uint32_t vector) | |
896 { | |
897 REG_PC(m68k) = (vector<<2); | |
898 REG_PC(m68k) = m68ki_read_32(m68k, REG_PC(m68k)); | |
899 } | |
900 | |
901 | |
902 /* Branch to a new memory location. | |
903 * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h. | |
904 * So far I've found no problems with not calling pc_changed for 8 or 16 | |
905 * bit branches. | |
906 */ | |
907 static inline void m68ki_branch_8(m68000_base_device *m68k, uint32_t offset) | |
908 { | |
909 REG_PC(m68k) += MAKE_INT_8(offset); | |
910 } | |
911 | |
912 static inline void m68ki_branch_16(m68000_base_device *m68k, uint32_t offset) | |
913 { | |
914 REG_PC(m68k) += MAKE_INT_16(offset); | |
915 } | |
916 | |
917 static inline void m68ki_branch_32(m68000_base_device *m68k, uint32_t offset) | |
918 { | |
919 REG_PC(m68k) += offset; | |
920 } | |
921 | |
922 | |
923 | |
924 /* ---------------------------- Status Register --------------------------- */ | |
925 | |
926 /* Set the S flag and change the active stack pointer. | |
927 * Note that value MUST be 4 or 0. | |
928 */ | |
929 static inline void m68ki_set_s_flag(m68000_base_device *m68k, uint32_t value) | |
930 { | |
931 /* Backup the old stack pointer */ | |
932 uint32_t old = REG_SP(m68k); | |
933 //REG_SP_BASE(m68k)[m68k->s_flag | ((m68k->s_flag>>1) & m68k->m_flag)] = REG_SP(m68k); | |
934 /* Set the S flag */ | |
935 if (value != m68k->s_flag) { | |
936 m68k->s_flag = value; | |
937 /* Set the new stack pointer */ | |
938 REG_SP(m68k) = REG_USP(m68k); | |
939 REG_USP(m68k) = old; | |
940 } | |
941 //REG_SP(m68k) = REG_SP_BASE(m68k)[m68k->s_flag | ((m68k->s_flag>>1) & m68k->m_flag)]; | |
942 } | |
943 | |
944 /* Set the S and M flags and change the active stack pointer. | |
945 * Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M). | |
946 */ | |
947 static inline void m68ki_set_sm_flag(m68000_base_device *m68k, uint32_t value) | |
948 { | |
949 m68ki_set_s_flag(m68k, value & 4); | |
950 } | |
951 | |
952 /* Set the S and M flags. Don't touch the stack pointer. */ | |
953 static inline void m68ki_set_sm_flag_nosp(m68000_base_device *m68k, uint32_t value) | |
954 { | |
955 /* Set the S and M flags */ | |
956 m68k->s_flag = value & SFLAG_SET; | |
957 //m68k->m_flag = value & MFLAG_SET; | |
958 } | |
959 | |
960 | |
961 /* Set the condition code register */ | |
962 static inline void m68ki_set_ccr(m68000_base_device *m68k, uint32_t value) | |
963 { | |
964 m68k->x_flag = BIT_4(value) << 4; | |
965 m68k->n_flag = BIT_3(value) << 4; | |
966 m68k->not_z_flag = !BIT_2(value); | |
967 m68k->v_flag = BIT_1(value) << 6; | |
968 m68k->c_flag = BIT_0(value) << 8; | |
969 } | |
970 | |
971 /* Set the status register but don't check for interrupts */ | |
972 static inline void m68ki_set_sr_noint(m68000_base_device *m68k, uint32_t value) | |
973 { | |
974 /* Mask out the "unimplemented" bits */ | |
975 value &= m68k->sr_mask; | |
976 | |
977 /* Now set the status register */ | |
978 /* m68k->t1_flag = BIT_F(value); | |
979 m68k->t0_flag = BIT_E(value);*/ | |
980 m68k->int_mask = value & 0x0700; | |
981 m68k->c.target_cycle = m68k->c.current_cycle; | |
982 m68ki_set_ccr(m68k, value); | |
983 m68ki_set_sm_flag(m68k, (value >> 11) & 6); | |
984 } | |
985 | |
986 /* Set the status register but don't check for interrupts nor | |
987 * change the stack pointer | |
988 */ | |
989 static inline void m68ki_set_sr_noint_nosp(m68000_base_device *m68k, uint32_t value) | |
990 { | |
991 /* Mask out the "unimplemented" bits */ | |
992 value &= m68k->sr_mask; | |
993 | |
994 /* Now set the status register */ | |
995 /*m68k->t1_flag = BIT_F(value); | |
996 m68k->t0_flag = BIT_E(value);*/ | |
997 m68k->int_mask = value & 0x0700; | |
998 m68k->c.target_cycle = m68k->c.current_cycle; | |
999 m68ki_set_ccr(m68k, value); | |
1000 m68ki_set_sm_flag_nosp(m68k, (value >> 11) & 6); | |
1001 } | |
1002 | |
1003 /* Set the status register and check for interrupts */ | |
1004 static inline void m68ki_set_sr(m68000_base_device *m68k, uint32_t value) | |
1005 { | |
1006 m68ki_set_sr_noint(m68k, value); | |
1007 m68ki_check_interrupts(m68k); | |
1008 } | |
1009 | |
1010 | |
1011 /* ------------------------- Exception Processing ------------------------- */ | |
1012 | |
1013 /* Initiate exception processing */ | |
1014 static inline uint32_t m68ki_init_exception(m68000_base_device *m68k) | |
1015 { | |
1016 /* Save the old status register */ | |
1017 uint32_t sr = m68ki_get_sr(m68k); | |
1018 | |
1019 /* Turn off trace flag, clear pending traces */ | |
1020 /*m68k->t1_flag = m68k->t0_flag = 0; | |
1021 m68ki_clear_trace(m68k);*/ | |
1022 /* Enter supervisor mode */ | |
1023 m68ki_set_s_flag(m68k, SFLAG_SET); | |
1024 | |
1025 return sr; | |
1026 } | |
1027 | |
1028 /* 3 word stack frame (68000 only) */ | |
1029 static inline void m68ki_stack_frame_3word(m68000_base_device *m68k, uint32_t pc, uint32_t sr) | |
1030 { | |
1031 m68ki_push_32(m68k, pc); | |
1032 m68ki_push_16(m68k, sr); | |
1033 } | |
1034 | |
1035 /* Format 0 stack frame. | |
1036 * This is the standard stack frame for 68010+. | |
1037 */ | |
1038 static inline void m68ki_stack_frame_0000(m68000_base_device *m68k, uint32_t pc, uint32_t sr, uint32_t vector) | |
1039 { | |
1040 /* Stack a 3-word frame if we are 68000 */ | |
1041 if(m68k->cpu_type == CPU_TYPE_000 || m68k->cpu_type == CPU_TYPE_008) | |
1042 { | |
1043 m68ki_stack_frame_3word(m68k, pc, sr); | |
1044 return; | |
1045 } | |
1046 m68ki_push_16(m68k, vector<<2); | |
1047 m68ki_push_32(m68k, pc); | |
1048 m68ki_push_16(m68k, sr); | |
1049 } | |
1050 | |
1051 /* Format 1 stack frame (68020). | |
1052 * For 68020, this is the 4 word throwaway frame. | |
1053 */ | |
1054 static inline void m68ki_stack_frame_0001(m68000_base_device *m68k, uint32_t pc, uint32_t sr, uint32_t vector) | |
1055 { | |
1056 m68ki_push_16(m68k, 0x1000 | (vector<<2)); | |
1057 m68ki_push_32(m68k, pc); | |
1058 m68ki_push_16(m68k, sr); | |
1059 } | |
1060 | |
1061 /* Format 2 stack frame. | |
1062 * This is used only by 68020 for trap exceptions. | |
1063 */ | |
1064 static inline void m68ki_stack_frame_0010(m68000_base_device *m68k, uint32_t sr, uint32_t vector) | |
1065 { | |
1066 m68ki_push_32(m68k, REG_PPC(m68k)); | |
1067 m68ki_push_16(m68k, 0x2000 | (vector<<2)); | |
1068 m68ki_push_32(m68k, REG_PC(m68k)); | |
1069 m68ki_push_16(m68k, sr); | |
1070 } | |
1071 | |
1072 | |
1073 /* Bus error stack frame (68000 only). | |
1074 */ | |
1075 static inline void m68ki_stack_frame_buserr(m68000_base_device *m68k, uint32_t sr) | |
1076 { | |
1077 m68ki_push_32(m68k, REG_PC(m68k)); | |
1078 m68ki_push_16(m68k, sr); | |
1079 m68ki_push_16(m68k, m68k->ir); | |
1080 m68ki_push_32(m68k, 0/*m68k->aerr_address*/); /* access address */ | |
1081 /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC | |
1082 * R/W 0 = write, 1 = read | |
1083 * I/N 0 = instruction, 1 = not | |
1084 * FC 3-bit function code | |
1085 */ | |
1086 m68ki_push_16(m68k, 0/*m68k->aerr_write_mode | m68k->instr_mode | m68k->aerr_fc*/); | |
1087 } | |
1088 | |
1089 /* Format 8 stack frame (68010). | |
1090 * 68010 only. This is the 29 word bus/address error frame. | |
1091 */ | |
1092 static inline void m68ki_stack_frame_1000(m68000_base_device *m68k, uint32_t pc, uint32_t sr, uint32_t vector) | |
1093 { | |
1094 /* VERSION | |
1095 * NUMBER | |
1096 * INTERNAL INFORMATION, 16 WORDS | |
1097 */ | |
1098 m68ki_fake_push_32(m68k); | |
1099 m68ki_fake_push_32(m68k); | |
1100 m68ki_fake_push_32(m68k); | |
1101 m68ki_fake_push_32(m68k); | |
1102 m68ki_fake_push_32(m68k); | |
1103 m68ki_fake_push_32(m68k); | |
1104 m68ki_fake_push_32(m68k); | |
1105 m68ki_fake_push_32(m68k); | |
1106 | |
1107 /* INSTRUCTION INPUT BUFFER */ | |
1108 m68ki_push_16(m68k, 0); | |
1109 | |
1110 /* UNUSED, RESERVED (not written) */ | |
1111 m68ki_fake_push_16(m68k); | |
1112 | |
1113 /* DATA INPUT BUFFER */ | |
1114 m68ki_push_16(m68k, 0); | |
1115 | |
1116 /* UNUSED, RESERVED (not written) */ | |
1117 m68ki_fake_push_16(m68k); | |
1118 | |
1119 /* DATA OUTPUT BUFFER */ | |
1120 m68ki_push_16(m68k, 0); | |
1121 | |
1122 /* UNUSED, RESERVED (not written) */ | |
1123 m68ki_fake_push_16(m68k); | |
1124 | |
1125 /* FAULT ADDRESS */ | |
1126 m68ki_push_32(m68k, 0); | |
1127 | |
1128 /* SPECIAL STATUS WORD */ | |
1129 m68ki_push_16(m68k, 0); | |
1130 | |
1131 /* 1000, VECTOR OFFSET */ | |
1132 m68ki_push_16(m68k, 0x8000 | (vector<<2)); | |
1133 | |
1134 /* PROGRAM COUNTER */ | |
1135 m68ki_push_32(m68k, pc); | |
1136 | |
1137 /* STATUS REGISTER */ | |
1138 m68ki_push_16(m68k, sr); | |
1139 } | |
1140 | |
1141 /* Format A stack frame (short bus fault). | |
1142 * This is used only by 68020 for bus fault and address error | |
1143 * if the error happens at an instruction boundary. | |
1144 * PC stacked is address of next instruction. | |
1145 */ | |
1146 static inline void m68ki_stack_frame_1010(m68000_base_device *m68k, uint32_t sr, uint32_t vector, uint32_t pc, uint32_t fault_address) | |
1147 { | |
1148 //int orig_rw = m68k->mmu_tmp_buserror_rw; // this gets splatted by the following pushes, so save it now | |
1149 //int orig_fc = m68k->mmu_tmp_buserror_fc; | |
1150 | |
1151 /* INTERNAL REGISTER */ | |
1152 m68ki_push_16(m68k, 0); | |
1153 | |
1154 /* INTERNAL REGISTER */ | |
1155 m68ki_push_16(m68k, 0); | |
1156 | |
1157 /* DATA OUTPUT BUFFER (2 words) */ | |
1158 m68ki_push_32(m68k, 0); | |
1159 | |
1160 /* INTERNAL REGISTER */ | |
1161 m68ki_push_16(m68k, 0); | |
1162 | |
1163 /* INTERNAL REGISTER */ | |
1164 m68ki_push_16(m68k, 0); | |
1165 | |
1166 /* DATA CYCLE FAULT ADDRESS (2 words) */ | |
1167 m68ki_push_32(m68k, fault_address); | |
1168 | |
1169 /* INSTRUCTION PIPE STAGE B */ | |
1170 m68ki_push_16(m68k, 0); | |
1171 | |
1172 /* INSTRUCTION PIPE STAGE C */ | |
1173 m68ki_push_16(m68k, 0); | |
1174 | |
1175 /* SPECIAL STATUS REGISTER */ | |
1176 // set bit for: Rerun Faulted bus Cycle, or run pending prefetch | |
1177 // set FC | |
1178 m68ki_push_16(m68k, 0x0100 /*| orig_fc | orig_rw<<6*/); | |
1179 | |
1180 /* INTERNAL REGISTER */ | |
1181 m68ki_push_16(m68k, 0); | |
1182 | |
1183 /* 1010, VECTOR OFFSET */ | |
1184 m68ki_push_16(m68k, 0xa000 | (vector<<2)); | |
1185 | |
1186 /* PROGRAM COUNTER */ | |
1187 m68ki_push_32(m68k, pc); | |
1188 | |
1189 /* STATUS REGISTER */ | |
1190 m68ki_push_16(m68k, sr); | |
1191 } | |
1192 | |
1193 /* Format B stack frame (long bus fault). | |
1194 * This is used only by 68020 for bus fault and address error | |
1195 * if the error happens during instruction execution. | |
1196 * PC stacked is address of instruction in progress. | |
1197 */ | |
1198 static inline void m68ki_stack_frame_1011(m68000_base_device *m68k, uint32_t sr, uint32_t vector, uint32_t pc, uint32_t fault_address) | |
1199 { | |
1200 /*int orig_rw = m68k->mmu_tmp_buserror_rw; // this gets splatted by the following pushes, so save it now | |
1201 int orig_fc = m68k->mmu_tmp_buserror_fc;*/ | |
1202 | |
1203 /* INTERNAL REGISTERS (18 words) */ | |
1204 m68ki_push_32(m68k, 0); | |
1205 m68ki_push_32(m68k, 0); | |
1206 m68ki_push_32(m68k, 0); | |
1207 m68ki_push_32(m68k, 0); | |
1208 m68ki_push_32(m68k, 0); | |
1209 m68ki_push_32(m68k, 0); | |
1210 m68ki_push_32(m68k, 0); | |
1211 m68ki_push_32(m68k, 0); | |
1212 m68ki_push_32(m68k, 0); | |
1213 | |
1214 /* VERSION# (4 bits), INTERNAL INFORMATION */ | |
1215 m68ki_push_16(m68k, 0); | |
1216 | |
1217 /* INTERNAL REGISTERS (3 words) */ | |
1218 m68ki_push_32(m68k, 0); | |
1219 m68ki_push_16(m68k, 0); | |
1220 | |
1221 /* DATA INTPUT BUFFER (2 words) */ | |
1222 m68ki_push_32(m68k, 0); | |
1223 | |
1224 /* INTERNAL REGISTERS (2 words) */ | |
1225 m68ki_push_32(m68k, 0); | |
1226 | |
1227 /* STAGE B ADDRESS (2 words) */ | |
1228 m68ki_push_32(m68k, 0); | |
1229 | |
1230 /* INTERNAL REGISTER (4 words) */ | |
1231 m68ki_push_32(m68k, 0); | |
1232 m68ki_push_32(m68k, 0); | |
1233 | |
1234 /* DATA OUTPUT BUFFER (2 words) */ | |
1235 m68ki_push_32(m68k, 0); | |
1236 | |
1237 /* INTERNAL REGISTER */ | |
1238 m68ki_push_16(m68k, 0); | |
1239 | |
1240 /* INTERNAL REGISTER */ | |
1241 m68ki_push_16(m68k, 0); | |
1242 | |
1243 /* DATA CYCLE FAULT ADDRESS (2 words) */ | |
1244 m68ki_push_32(m68k, fault_address); | |
1245 | |
1246 /* INSTRUCTION PIPE STAGE B */ | |
1247 m68ki_push_16(m68k, 0); | |
1248 | |
1249 /* INSTRUCTION PIPE STAGE C */ | |
1250 m68ki_push_16(m68k, 0); | |
1251 | |
1252 /* SPECIAL STATUS REGISTER */ | |
1253 m68ki_push_16(m68k, 0x0100/* | orig_fc | orig_rw<<6*/); | |
1254 | |
1255 /* INTERNAL REGISTER */ | |
1256 m68ki_push_16(m68k, 0); | |
1257 | |
1258 /* 1011, VECTOR OFFSET */ | |
1259 m68ki_push_16(m68k, 0xb000 | (vector<<2)); | |
1260 | |
1261 /* PROGRAM COUNTER */ | |
1262 m68ki_push_32(m68k, pc); | |
1263 | |
1264 /* STATUS REGISTER */ | |
1265 m68ki_push_16(m68k, sr); | |
1266 } | |
1267 | |
1268 /* Type 7 stack frame (access fault). | |
1269 * This is used by the 68040 for bus fault and mmu trap | |
1270 * 30 words | |
1271 */ | |
1272 static inline void m68ki_stack_frame_0111(m68000_base_device *m68k, uint32_t sr, uint32_t vector, uint32_t pc, uint32_t fault_address, uint8_t in_mmu) | |
1273 { | |
1274 /*int orig_rw = m68k->mmu_tmp_buserror_rw; // this gets splatted by the following pushes, so save it now | |
1275 int orig_fc = m68k->mmu_tmp_buserror_fc;*/ | |
1276 | |
1277 /* INTERNAL REGISTERS (18 words) */ | |
1278 m68ki_push_32(m68k, 0); | |
1279 m68ki_push_32(m68k, 0); | |
1280 m68ki_push_32(m68k, 0); | |
1281 m68ki_push_32(m68k, 0); | |
1282 m68ki_push_32(m68k, 0); | |
1283 m68ki_push_32(m68k, 0); | |
1284 m68ki_push_32(m68k, 0); | |
1285 m68ki_push_32(m68k, 0); | |
1286 m68ki_push_32(m68k, 0); | |
1287 | |
1288 /* FAULT ADDRESS (2 words) */ | |
1289 m68ki_push_32(m68k, fault_address); | |
1290 | |
1291 /* INTERNAL REGISTERS (3 words) */ | |
1292 m68ki_push_32(m68k, 0); | |
1293 m68ki_push_16(m68k, 0); | |
1294 | |
1295 /* SPECIAL STATUS REGISTER (1 word) */ | |
1296 m68ki_push_16(m68k, 0/*(in_mmu ? 0x400 : 0) | orig_fc | (orig_rw<<8)*/); | |
1297 | |
1298 /* EFFECTIVE ADDRESS (2 words) */ | |
1299 m68ki_push_32(m68k, fault_address); | |
1300 | |
1301 /* 0111, VECTOR OFFSET (1 word) */ | |
1302 m68ki_push_16(m68k, 0x7000 | (vector<<2)); | |
1303 | |
1304 /* PROGRAM COUNTER (2 words) */ | |
1305 m68ki_push_32(m68k, pc); | |
1306 | |
1307 /* STATUS REGISTER (1 word) */ | |
1308 m68ki_push_16(m68k, sr); | |
1309 } | |
1310 | |
1311 | |
1312 /* Used for Group 2 exceptions. | |
1313 * These stack a type 2 frame on the 020. | |
1314 */ | |
1315 static inline void m68ki_exception_trap(m68000_base_device *m68k, uint32_t vector) | |
1316 { | |
1317 uint32_t sr = m68ki_init_exception(m68k); | |
1318 | |
1319 if(CPU_TYPE_IS_010_LESS(m68k->cpu_type)) | |
1320 m68ki_stack_frame_0000(m68k, REG_PC(m68k), sr, vector); | |
1321 else | |
1322 m68ki_stack_frame_0010(m68k, sr, vector); | |
1323 | |
1324 m68ki_jump_vector(m68k, vector); | |
1325 | |
1326 /* Use up some clock cycles */ | |
1327 m68k->c.current_cycle += m68k->cyc_exception[vector]; | |
1328 } | |
1329 | |
1330 /* Trap#n stacks a 0 frame but behaves like group2 otherwise */ | |
1331 static inline void m68ki_exception_trapN(m68000_base_device *m68k, uint32_t vector) | |
1332 { | |
1333 uint32_t sr = m68ki_init_exception(m68k); | |
1334 m68ki_stack_frame_0000(m68k, REG_PC(m68k), sr, vector); | |
1335 m68ki_jump_vector(m68k, vector); | |
1336 | |
1337 /* Use up some clock cycles */ | |
1338 m68k->c.current_cycle += m68k->cyc_exception[vector]; | |
1339 } | |
1340 | |
1341 /* Exception for trace mode */ | |
1342 static inline void m68ki_exception_trace(m68000_base_device *m68k) | |
1343 { | |
1344 uint32_t sr = m68ki_init_exception(m68k); | |
1345 | |
1346 if(CPU_TYPE_IS_010_LESS(m68k->cpu_type)) | |
1347 { | |
1348 if(CPU_TYPE_IS_000(m68k->cpu_type)) | |
1349 { | |
1350 m68k->instr_mode = INSTRUCTION_NO; | |
1351 } | |
1352 m68ki_stack_frame_0000(m68k, REG_PC(m68k), sr, EXCEPTION_TRACE); | |
1353 } | |
1354 else | |
1355 m68ki_stack_frame_0010(m68k, sr, EXCEPTION_TRACE); | |
1356 | |
1357 m68ki_jump_vector(m68k, EXCEPTION_TRACE); | |
1358 | |
1359 /* Trace nullifies a STOP instruction */ | |
1360 m68k->stopped &= ~STOP_LEVEL_STOP; | |
1361 | |
1362 /* Use up some clock cycles */ | |
1363 m68k->c.current_cycle += m68k->cyc_exception[EXCEPTION_TRACE]; | |
1364 } | |
1365 | |
1366 /* Exception for privilege violation */ | |
1367 static inline void m68ki_exception_privilege_violation(m68000_base_device *m68k) | |
1368 { | |
1369 uint32_t sr = m68ki_init_exception(m68k); | |
1370 | |
1371 if(CPU_TYPE_IS_000(m68k->cpu_type)) | |
1372 { | |
1373 m68k->instr_mode = INSTRUCTION_NO; | |
1374 } | |
1375 | |
1376 m68ki_stack_frame_0000(m68k, REG_PPC(m68k), sr, EXCEPTION_PRIVILEGE_VIOLATION); | |
1377 m68ki_jump_vector(m68k, EXCEPTION_PRIVILEGE_VIOLATION); | |
1378 | |
1379 /* Use up some clock cycles and undo the instruction's cycles */ | |
1380 m68k->c.current_cycle += m68k->cyc_exception[EXCEPTION_PRIVILEGE_VIOLATION] - m68k->cyc_instruction[m68k->ir]; | |
1381 } | |
1382 | |
1383 /* Exception for A-Line instructions */ | |
1384 static inline void m68ki_exception_1010(m68000_base_device *m68k) | |
1385 { | |
1386 uint32_t sr; | |
1387 | |
1388 sr = m68ki_init_exception(m68k); | |
1389 m68ki_stack_frame_0000(m68k, REG_PPC(m68k), sr, EXCEPTION_1010); | |
1390 m68ki_jump_vector(m68k, EXCEPTION_1010); | |
1391 | |
1392 /* Use up some clock cycles and undo the instruction's cycles */ | |
1393 m68k->c.current_cycle += m68k->cyc_exception[EXCEPTION_1010] - m68k->cyc_instruction[m68k->ir]; | |
1394 } | |
1395 | |
1396 /* Exception for F-Line instructions */ | |
1397 static inline void m68ki_exception_1111(m68000_base_device *m68k) | |
1398 { | |
1399 uint32_t sr; | |
1400 | |
1401 sr = m68ki_init_exception(m68k); | |
1402 m68ki_stack_frame_0000(m68k, REG_PPC(m68k), sr, EXCEPTION_1111); | |
1403 m68ki_jump_vector(m68k, EXCEPTION_1111); | |
1404 | |
1405 /* Use up some clock cycles and undo the instruction's cycles */ | |
1406 m68k->c.current_cycle += m68k->cyc_exception[EXCEPTION_1111] - m68k->cyc_instruction[m68k->ir]; | |
1407 } | |
1408 | |
1409 /* Exception for illegal instructions */ | |
1410 static inline void m68ki_exception_illegal(m68000_base_device *m68k) | |
1411 { | |
1412 uint32_t sr; | |
1413 | |
1414 sr = m68ki_init_exception(m68k); | |
1415 | |
1416 if(CPU_TYPE_IS_000(m68k->cpu_type)) | |
1417 { | |
1418 m68k->instr_mode = INSTRUCTION_NO; | |
1419 } | |
1420 | |
1421 m68ki_stack_frame_0000(m68k, REG_PPC(m68k), sr, EXCEPTION_ILLEGAL_INSTRUCTION); | |
1422 m68ki_jump_vector(m68k, EXCEPTION_ILLEGAL_INSTRUCTION); | |
1423 | |
1424 /* Use up some clock cycles and undo the instruction's cycles */ | |
1425 m68k->c.current_cycle += m68k->cyc_exception[EXCEPTION_ILLEGAL_INSTRUCTION] - m68k->cyc_instruction[m68k->ir]; | |
1426 } | |
1427 | |
1428 /* Exception for format errror in RTE */ | |
1429 static inline void m68ki_exception_format_error(m68000_base_device *m68k) | |
1430 { | |
1431 uint32_t sr = m68ki_init_exception(m68k); | |
1432 m68ki_stack_frame_0000(m68k, REG_PC(m68k), sr, EXCEPTION_FORMAT_ERROR); | |
1433 m68ki_jump_vector(m68k, EXCEPTION_FORMAT_ERROR); | |
1434 | |
1435 /* Use up some clock cycles and undo the instruction's cycles */ | |
1436 m68k->c.current_cycle += m68k->cyc_exception[EXCEPTION_FORMAT_ERROR] - m68k->cyc_instruction[m68k->ir]; | |
1437 } | |
1438 | |
1439 /* Exception for address error */ | |
1440 static inline void m68ki_exception_address_error(m68000_base_device *m68k) | |
1441 { | |
1442 uint32_t sr = m68ki_init_exception(m68k); | |
1443 | |
1444 /* If we were processing a bus error, address error, or reset, | |
1445 * this is a catastrophic failure. | |
1446 * Halt the CPU | |
1447 */ | |
1448 if(m68k->run_mode == RUN_MODE_BERR_AERR_RESET) | |
1449 { | |
1450 //m68k->/*memory.*/read8(0x00ffff01); | |
1451 m68k->stopped = STOP_LEVEL_HALT; | |
1452 return; | |
1453 } | |
1454 m68k->run_mode = RUN_MODE_BERR_AERR_RESET; | |
1455 | |
1456 /* Note: This is implemented for 68000 only! */ | |
1457 m68ki_stack_frame_buserr(m68k, sr); | |
1458 | |
1459 m68ki_jump_vector(m68k, EXCEPTION_ADDRESS_ERROR); | |
1460 | |
1461 /* Use up some clock cycles and undo the instruction's cycles */ | |
1462 m68k->c.current_cycle += m68k->cyc_exception[EXCEPTION_ADDRESS_ERROR] - m68k->cyc_instruction[m68k->ir]; | |
1463 } | |
1464 | |
1465 | |
1466 | |
1467 /* ASG: Check for interrupts */ | |
1468 static inline void m68ki_check_interrupts(m68000_base_device *m68k) | |
1469 { | |
1470 /*if(m68k->nmi_pending) | |
1471 { | |
1472 m68k->nmi_pending = false; | |
1473 m68k->m68ki_exception_interrupt(m68k, 7); | |
1474 } | |
1475 else if(m68k->int_level > m68k->int_mask) | |
1476 m68k->m68ki_exception_interrupt(m68k, m68k->int_level>>8);*/ | |
1477 if (m68k->c.current_cycle >= m68k->c.int_cycle) { | |
1478 m68ki_exception_interrupt(m68k, m68k->c.int_num); | |
1479 } | |
1480 } | |
1481 | |
1482 | |
1483 | |
1484 /* ======================================================================== */ | |
1485 /* ============================== END OF FILE ============================= */ | |
1486 /* ======================================================================== */ | |
1487 | |
1488 #endif /* __M68KCPU_H__ */ |