1
/* ======================================================================== */
2
/* ========================= LICENSING & COPYRIGHT ======================== */
3
/* ======================================================================== */
8
* A portable Motorola M680x0 processor emulation engine.
9
* Copyright Karl Stenerud. All rights reserved.
11
* This code may be freely used for non-commercial purposes as long as this
12
* copyright notice remains unaltered in the source code and any binary files
13
* containing this code in compiled form.
15
* All other licensing terms must be negotiated with the author
18
* The latest version of this code can be obtained at:
19
* http://kstenerud.cjb.net
28
typedef struct _m68ki_cpu_core m68ki_cpu_core;
32
#include "../../../lib/softfloat/milieu.h"
33
#include "../../../lib/softfloat/softfloat.h"
38
/* ======================================================================== */
39
/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
40
/* ======================================================================== */
42
/* Check for > 32bit sizes */
43
#define MAKE_INT_8(A) (INT8)(A)
44
#define MAKE_INT_16(A) (INT16)(A)
45
#define MAKE_INT_32(A) (INT32)(A)
48
/* ======================================================================== */
49
/* ============================ GENERAL DEFINES =========================== */
50
/* ======================================================================== */
52
/* Exception Vectors handled by emulation */
53
#define EXCEPTION_RESET 0
54
#define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */
55
#define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */
56
#define EXCEPTION_ILLEGAL_INSTRUCTION 4
57
#define EXCEPTION_ZERO_DIVIDE 5
58
#define EXCEPTION_CHK 6
59
#define EXCEPTION_TRAPV 7
60
#define EXCEPTION_PRIVILEGE_VIOLATION 8
61
#define EXCEPTION_TRACE 9
62
#define EXCEPTION_1010 10
63
#define EXCEPTION_1111 11
64
#define EXCEPTION_FORMAT_ERROR 14
65
#define EXCEPTION_UNINITIALIZED_INTERRUPT 15
66
#define EXCEPTION_SPURIOUS_INTERRUPT 24
67
#define EXCEPTION_INTERRUPT_AUTOVECTOR 24
68
#define EXCEPTION_TRAP_BASE 32
70
/* Function codes set by CPU during data/address bus activity */
71
#define FUNCTION_CODE_USER_DATA 1
72
#define FUNCTION_CODE_USER_PROGRAM 2
73
#define FUNCTION_CODE_SUPERVISOR_DATA 5
74
#define FUNCTION_CODE_SUPERVISOR_PROGRAM 6
75
#define FUNCTION_CODE_CPU_SPACE 7
77
/* CPU types for deciding what to emulate */
78
#define CPU_TYPE_000 (0x00000001)
79
#define CPU_TYPE_008 (0x00000002)
80
#define CPU_TYPE_010 (0x00000004)
81
#define CPU_TYPE_EC020 (0x00000008)
82
#define CPU_TYPE_020 (0x00000010)
83
#define CPU_TYPE_EC030 (0x00000020)
84
#define CPU_TYPE_030 (0x00000040)
85
#define CPU_TYPE_EC040 (0x00000080)
86
#define CPU_TYPE_LC040 (0x00000100)
87
#define CPU_TYPE_040 (0x00000200)
88
#define CPU_TYPE_SCC070 (0x00000400)
90
/* Different ways to stop the CPU */
91
#define STOP_LEVEL_STOP 1
92
#define STOP_LEVEL_HALT 2
94
/* Used for 68000 address error processing */
95
#define INSTRUCTION_YES 0
96
#define INSTRUCTION_NO 0x08
97
#define MODE_READ 0x10
100
#define RUN_MODE_NORMAL 0
101
#define RUN_MODE_BERR_AERR_RESET 1
104
#define MMU_ATC_ENTRIES (22) // 68851 has 64, 030 has 22
106
/* instruction cache constants */
107
#define M68K_IC_SIZE 128
109
#define M68K_CACR_IBE 0x10 // Instruction Burst Enable
110
#define M68K_CACR_CI 0x08 // Clear Instruction Cache
111
#define M68K_CACR_CEI 0x04 // Clear Entry in Instruction Cache
112
#define M68K_CACR_FI 0x02 // Freeze Instruction Cache
113
#define M68K_CACR_EI 0x01 // Enable Instruction Cache
115
/* ======================================================================== */
116
/* ================================ MACROS ================================ */
117
/* ======================================================================== */
120
/* ---------------------------- General Macros ---------------------------- */
122
/* Bit Isolation Macros */
123
#define BIT_0(A) ((A) & 0x00000001)
124
#define BIT_1(A) ((A) & 0x00000002)
125
#define BIT_2(A) ((A) & 0x00000004)
126
#define BIT_3(A) ((A) & 0x00000008)
127
#define BIT_4(A) ((A) & 0x00000010)
128
#define BIT_5(A) ((A) & 0x00000020)
129
#define BIT_6(A) ((A) & 0x00000040)
130
#define BIT_7(A) ((A) & 0x00000080)
131
#define BIT_8(A) ((A) & 0x00000100)
132
#define BIT_9(A) ((A) & 0x00000200)
133
#define BIT_A(A) ((A) & 0x00000400)
134
#define BIT_B(A) ((A) & 0x00000800)
135
#define BIT_C(A) ((A) & 0x00001000)
136
#define BIT_D(A) ((A) & 0x00002000)
137
#define BIT_E(A) ((A) & 0x00004000)
138
#define BIT_F(A) ((A) & 0x00008000)
139
#define BIT_10(A) ((A) & 0x00010000)
140
#define BIT_11(A) ((A) & 0x00020000)
141
#define BIT_12(A) ((A) & 0x00040000)
142
#define BIT_13(A) ((A) & 0x00080000)
143
#define BIT_14(A) ((A) & 0x00100000)
144
#define BIT_15(A) ((A) & 0x00200000)
145
#define BIT_16(A) ((A) & 0x00400000)
146
#define BIT_17(A) ((A) & 0x00800000)
147
#define BIT_18(A) ((A) & 0x01000000)
148
#define BIT_19(A) ((A) & 0x02000000)
149
#define BIT_1A(A) ((A) & 0x04000000)
150
#define BIT_1B(A) ((A) & 0x08000000)
151
#define BIT_1C(A) ((A) & 0x10000000)
152
#define BIT_1D(A) ((A) & 0x20000000)
153
#define BIT_1E(A) ((A) & 0x40000000)
154
#define BIT_1F(A) ((A) & 0x80000000)
156
/* Get the most significant bit for specific sizes */
157
#define GET_MSB_8(A) ((A) & 0x80)
158
#define GET_MSB_9(A) ((A) & 0x100)
159
#define GET_MSB_16(A) ((A) & 0x8000)
160
#define GET_MSB_17(A) ((A) & 0x10000)
161
#define GET_MSB_32(A) ((A) & 0x80000000)
162
#define GET_MSB_33(A) ((A) & U64(0x100000000))
164
/* Isolate nibbles */
165
#define LOW_NIBBLE(A) ((A) & 0x0f)
166
#define HIGH_NIBBLE(A) ((A) & 0xf0)
168
/* These are used to isolate 8, 16, and 32 bit sizes */
169
#define MASK_OUT_ABOVE_2(A) ((A) & 3)
170
#define MASK_OUT_ABOVE_8(A) ((A) & 0xff)
171
#define MASK_OUT_ABOVE_16(A) ((A) & 0xffff)
172
#define MASK_OUT_BELOW_2(A) ((A) & ~3)
173
#define MASK_OUT_BELOW_8(A) ((A) & ~0xff)
174
#define MASK_OUT_BELOW_16(A) ((A) & ~0xffff)
176
/* No need to mask if we are 32 bit */
177
#define MASK_OUT_ABOVE_32(A) ((A) & U64(0xffffffff))
178
#define MASK_OUT_BELOW_32(A) ((A) & ~U64(0xffffffff))
180
/* Shift & Rotate Macros. */
181
#define LSL(A, C) ((A) << (C))
182
#define LSR(A, C) ((A) >> (C))
184
/* We have to do this because the morons at ANSI decided that shifts
185
* by >= data size are undefined.
187
#define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
188
#define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
190
#define LSL_32_64(A, C) ((A) << (C))
191
#define LSR_32_64(A, C) ((A) >> (C))
192
#define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C)))
193
#define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C)))
195
#define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C)))
196
#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C)))
197
#define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C)))
198
#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C)))
199
#define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C)))
200
#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C)))
202
#define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C)))
203
#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C)))
204
#define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C)))
205
#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C)))
206
#define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C)))
207
#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C)))
211
/* ------------------------------ CPU Access ------------------------------ */
213
/* Access the CPU registers */
214
#define REG_DA m68k->dar /* easy access to data and address regs */
215
#define REG_D m68k->dar
216
#define REG_A (m68k->dar+8)
217
#define REG_PPC m68k->ppc
218
#define REG_PC m68k->pc
219
#define REG_SP_BASE m68k->sp
220
#define REG_USP m68k->sp[0]
221
#define REG_ISP m68k->sp[4]
222
#define REG_MSP m68k->sp[6]
223
#define REG_SP m68k->dar[15]
225
#define REG_FP m68k->fpr
226
#define REG_FPCR m68k->fpcr
227
#define REG_FPSR m68k->fpsr
228
#define REG_FPIAR m68k->fpiar
231
/* ----------------------------- Configuration ---------------------------- */
233
/* These defines are dependant on the configuration defines in m68kconf.h */
235
/* Disable certain comparisons if we're not using all CPU types */
236
#define CPU_TYPE_IS_040_PLUS(A) ((A) & (CPU_TYPE_040 | CPU_TYPE_EC040))
237
#define CPU_TYPE_IS_040_LESS(A) 1
239
#define CPU_TYPE_IS_030_PLUS(A) ((A) & (CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040))
240
#define CPU_TYPE_IS_030_LESS(A) 1
242
#define CPU_TYPE_IS_020_PLUS(A) ((A) & (CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040))
243
#define CPU_TYPE_IS_020_LESS(A) 1
245
#define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
247
#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))
248
#define CPU_TYPE_IS_EC020_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020))
250
#define CPU_TYPE_IS_010(A) ((A) == CPU_TYPE_010)
251
#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))
252
#define CPU_TYPE_IS_010_LESS(A) ((A) & (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010))
254
#define CPU_TYPE_IS_000(A) ((A) == CPU_TYPE_000 || (A) == CPU_TYPE_008)
257
/* Configuration switches (see m68kconf.h for explanation) */
258
#define M68K_EMULATE_TRACE 0
260
/* Enable or disable trace emulation */
261
#if M68K_EMULATE_TRACE
262
/* Initiates trace checking before each instruction (t1) */
263
#define m68ki_trace_t1() m68ki_tracing = m68k->t1_flag
264
/* adds t0 to trace checking if we encounter change of flow */
265
#define m68ki_trace_t0() m68ki_tracing |= m68k->t0_flag
266
/* Clear all tracing */
267
#define m68ki_clear_trace() m68ki_tracing = 0
268
/* Cause a trace exception if we are tracing */
269
#define m68ki_exception_if_trace() if(m68ki_tracing) m68ki_exception_trace(m68k)
271
#define m68ki_trace_t1()
272
#define m68ki_trace_t0()
273
#define m68ki_clear_trace()
274
#define m68ki_exception_if_trace()
275
#endif /* M68K_EMULATE_TRACE */
280
/* sigjmp() on Mac OS X and *BSD in general saves signal contexts and is super-slow, use sigsetjmp() to tell it not to */
282
#define m68ki_set_address_error_trap(m68k) \
283
if(sigsetjmp(m68k->aerr_trap, 0) != 0) \
285
m68ki_exception_address_error(m68k); \
288
if (m68k->remaining_cycles > 0) \
289
m68k->remaining_cycles = 0; \
294
#define m68ki_check_address_error(m68k, ADDR, WRITE_MODE, FC) \
297
m68k->aerr_address = ADDR; \
298
m68k->aerr_write_mode = WRITE_MODE; \
299
m68k->aerr_fc = FC; \
300
siglongjmp(m68k->aerr_trap, 1); \
303
#define m68ki_set_address_error_trap(m68k) \
304
if(setjmp(m68k->aerr_trap) != 0) \
306
m68ki_exception_address_error(m68k); \
309
if (m68k->remaining_cycles > 0) \
310
m68k->remaining_cycles = 0; \
315
#define m68ki_check_address_error(m68k, ADDR, WRITE_MODE, FC) \
318
m68k->aerr_address = ADDR; \
319
m68k->aerr_write_mode = WRITE_MODE; \
320
m68k->aerr_fc = FC; \
321
longjmp(m68k->aerr_trap, 1); \
326
/* -------------------------- EA / Operand Access ------------------------- */
329
* The general instruction format follows this pattern:
330
* .... XXX. .... .YYY
331
* where XXX is register X and YYY is register Y
333
/* Data Register Isolation */
334
#define DX (REG_D[(m68k->ir >> 9) & 7])
335
#define DY (REG_D[m68k->ir & 7])
336
/* Address Register Isolation */
337
#define AX (REG_A[(m68k->ir >> 9) & 7])
338
#define AY (REG_A[m68k->ir & 7])
341
/* Effective Address Calculations */
342
#define EA_AY_AI_8(m68k) AY /* address register indirect */
343
#define EA_AY_AI_16(m68k) EA_AY_AI_8(m68k)
344
#define EA_AY_AI_32(m68k) EA_AY_AI_8(m68k)
345
#define EA_AY_PI_8(m68k) (AY++) /* postincrement (size = byte) */
346
#define EA_AY_PI_16(m68k) ((AY+=2)-2) /* postincrement (size = word) */
347
#define EA_AY_PI_32(m68k) ((AY+=4)-4) /* postincrement (size = long) */
348
#define EA_AY_PD_8(m68k) (--AY) /* predecrement (size = byte) */
349
#define EA_AY_PD_16(m68k) (AY-=2) /* predecrement (size = word) */
350
#define EA_AY_PD_32(m68k) (AY-=4) /* predecrement (size = long) */
351
#define EA_AY_DI_8(m68k) (AY+MAKE_INT_16(m68ki_read_imm_16(m68k))) /* displacement */
352
#define EA_AY_DI_16(m68k) EA_AY_DI_8(m68k)
353
#define EA_AY_DI_32(m68k) EA_AY_DI_8(m68k)
354
#define EA_AY_IX_8(m68k) m68ki_get_ea_ix(m68k, AY) /* indirect + index */
355
#define EA_AY_IX_16(m68k) EA_AY_IX_8(m68k)
356
#define EA_AY_IX_32(m68k) EA_AY_IX_8(m68k)
358
#define EA_AX_AI_8(m68k) AX
359
#define EA_AX_AI_16(m68k) EA_AX_AI_8(m68k)
360
#define EA_AX_AI_32(m68k) EA_AX_AI_8(m68k)
361
#define EA_AX_PI_8(m68k) (AX++)
362
#define EA_AX_PI_16(m68k) ((AX+=2)-2)
363
#define EA_AX_PI_32(m68k) ((AX+=4)-4)
364
#define EA_AX_PD_8(m68k) (--AX)
365
#define EA_AX_PD_16(m68k) (AX-=2)
366
#define EA_AX_PD_32(m68k) (AX-=4)
367
#define EA_AX_DI_8(m68k) (AX+MAKE_INT_16(m68ki_read_imm_16(m68k)))
368
#define EA_AX_DI_16(m68k) EA_AX_DI_8(m68k)
369
#define EA_AX_DI_32(m68k) EA_AX_DI_8(m68k)
370
#define EA_AX_IX_8(m68k) m68ki_get_ea_ix(m68k, AX)
371
#define EA_AX_IX_16(m68k) EA_AX_IX_8(m68k)
372
#define EA_AX_IX_32(m68k) EA_AX_IX_8(m68k)
374
#define EA_A7_PI_8(m68k) ((REG_A[7]+=2)-2)
375
#define EA_A7_PD_8(m68k) (REG_A[7]-=2)
377
#define EA_AW_8(m68k) MAKE_INT_16(m68ki_read_imm_16(m68k)) /* absolute word */
378
#define EA_AW_16(m68k) EA_AW_8(m68k)
379
#define EA_AW_32(m68k) EA_AW_8(m68k)
380
#define EA_AL_8(m68k) m68ki_read_imm_32(m68k) /* absolute long */
381
#define EA_AL_16(m68k) EA_AL_8(m68k)
382
#define EA_AL_32(m68k) EA_AL_8(m68k)
383
#define EA_PCDI_8(m68k) m68ki_get_ea_pcdi(m68k) /* pc indirect + displacement */
384
#define EA_PCDI_16(m68k) EA_PCDI_8(m68k)
385
#define EA_PCDI_32(m68k) EA_PCDI_8(m68k)
386
#define EA_PCIX_8(m68k) m68ki_get_ea_pcix(m68k) /* pc indirect + index */
387
#define EA_PCIX_16(m68k) EA_PCIX_8(m68k)
388
#define EA_PCIX_32(m68k) EA_PCIX_8(m68k)
391
#define OPER_I_8(m68k) m68ki_read_imm_8(m68k)
392
#define OPER_I_16(m68k) m68ki_read_imm_16(m68k)
393
#define OPER_I_32(m68k) m68ki_read_imm_32(m68k)
397
/* --------------------------- Status Register ---------------------------- */
399
/* Flag Calculation Macros */
400
#define CFLAG_8(A) (A)
401
#define CFLAG_16(A) ((A)>>8)
403
#define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23)
404
#define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23)
406
#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R))
407
#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
408
#define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24)
410
#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D))
411
#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
412
#define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24)
414
#define NFLAG_8(A) (A)
415
#define NFLAG_16(A) ((A)>>8)
416
#define NFLAG_32(A) ((A)>>24)
417
#define NFLAG_64(A) ((A)>>56)
419
#define ZFLAG_8(A) MASK_OUT_ABOVE_8(A)
420
#define ZFLAG_16(A) MASK_OUT_ABOVE_16(A)
421
#define ZFLAG_32(A) MASK_OUT_ABOVE_32(A)
425
#define NFLAG_SET 0x80
426
#define NFLAG_CLEAR 0
427
#define CFLAG_SET 0x100
428
#define CFLAG_CLEAR 0
429
#define XFLAG_SET 0x100
430
#define XFLAG_CLEAR 0
431
#define VFLAG_SET 0x80
432
#define VFLAG_CLEAR 0
434
#define ZFLAG_CLEAR 0xffffffff
437
#define SFLAG_CLEAR 0
439
#define MFLAG_CLEAR 0
441
/* Turn flag values into 1 or 0 */
442
#define XFLAG_AS_1(M) (((M)->x_flag>>8)&1)
443
#define NFLAG_AS_1(M) (((M)->n_flag>>7)&1)
444
#define VFLAG_AS_1(M) (((M)->v_flag>>7)&1)
445
#define ZFLAG_AS_1(M) (!(M)->not_z_flag)
446
#define CFLAG_AS_1(M) (((M)->c_flag>>8)&1)
450
#define COND_CS(M) ((M)->c_flag&0x100)
451
#define COND_CC(M) (!COND_CS(M))
452
#define COND_VS(M) ((M)->v_flag&0x80)
453
#define COND_VC(M) (!COND_VS(M))
454
#define COND_NE(M) (M)->not_z_flag
455
#define COND_EQ(M) (!COND_NE(M))
456
#define COND_MI(M) ((M)->n_flag&0x80)
457
#define COND_PL(M) (!COND_MI(M))
458
#define COND_LT(M) (((M)->n_flag^(M)->v_flag)&0x80)
459
#define COND_GE(M) (!COND_LT(M))
460
#define COND_HI(M) (COND_CC(M) && COND_NE(M))
461
#define COND_LS(M) (COND_CS(M) || COND_EQ(M))
462
#define COND_GT(M) (COND_GE(M) && COND_NE(M))
463
#define COND_LE(M) (COND_LT(M) || COND_EQ(M))
465
/* Reversed conditions */
466
#define COND_NOT_CS(M) COND_CC(M)
467
#define COND_NOT_CC(M) COND_CS(M)
468
#define COND_NOT_VS(M) COND_VC(M)
469
#define COND_NOT_VC(M) COND_VS(M)
470
#define COND_NOT_NE(M) COND_EQ(M)
471
#define COND_NOT_EQ(M) COND_NE(M)
472
#define COND_NOT_MI(M) COND_PL(M)
473
#define COND_NOT_PL(M) COND_MI(M)
474
#define COND_NOT_LT(M) COND_GE(M)
475
#define COND_NOT_GE(M) COND_LT(M)
476
#define COND_NOT_HI(M) COND_LS(M)
477
#define COND_NOT_LS(M) COND_HI(M)
478
#define COND_NOT_GT(M) COND_LE(M)
479
#define COND_NOT_LE(M) COND_GT(M)
481
/* Not real conditions, but here for convenience */
482
#define COND_XS(M) ((M)->x_flag&0x100)
483
#define COND_XC(M) (!COND_XS)
486
/* Get the condition code register */
487
#define m68ki_get_ccr(M) ((COND_XS(M) >> 4) | \
488
(COND_MI(M) >> 4) | \
489
(COND_EQ(M) << 2) | \
490
(COND_VS(M) >> 6) | \
493
/* Get the status register */
494
#define m68ki_get_sr(M) ((M)->t1_flag | \
496
((M)->s_flag << 11) | \
497
((M)->m_flag << 11) | \
503
/* ----------------------------- Read / Write ----------------------------- */
505
/* Read from the current address space */
506
#define m68ki_read_8(M, A) m68ki_read_8_fc (M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA)
507
#define m68ki_read_16(M, A) m68ki_read_16_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA)
508
#define m68ki_read_32(M, A) m68ki_read_32_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA)
510
/* Write to the current data space */
511
#define m68ki_write_8(M, A, V) m68ki_write_8_fc (M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA, V)
512
#define m68ki_write_16(M, A, V) m68ki_write_16_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA, V)
513
#define m68ki_write_32(M, A, V) m68ki_write_32_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA, V)
514
#define m68ki_write_32_pd(M, A, V) m68ki_write_32_pd_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA, V)
516
/* map read immediate 8 to read immediate 16 */
517
#define m68ki_read_imm_8(M) MASK_OUT_ABOVE_8(m68ki_read_imm_16(M))
519
/* Map PC-relative reads */
520
#define m68ki_read_pcrel_8(M, A) m68k_read_pcrelative_8(M, A)
521
#define m68ki_read_pcrel_16(M, A) m68k_read_pcrelative_16(M, A)
522
#define m68ki_read_pcrel_32(M, A) m68k_read_pcrelative_32(M, A)
524
/* Read from the program space */
525
#define m68ki_read_program_8(M, A) m68ki_read_8_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_PROGRAM)
526
#define m68ki_read_program_16(M, A) m68ki_read_16_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_PROGRAM)
527
#define m68ki_read_program_32(M, A) m68ki_read_32_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_PROGRAM)
529
/* Read from the data space */
530
#define m68ki_read_data_8(M, A) m68ki_read_8_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA)
531
#define m68ki_read_data_16(M, A) m68ki_read_16_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA)
532
#define m68ki_read_data_32(M, A) m68ki_read_32_fc(M, A, m68k->s_flag | FUNCTION_CODE_USER_DATA)
536
/* ======================================================================== */
537
/* =============================== PROTOTYPES ============================= */
538
/* ======================================================================== */
540
typedef union _fp_reg fp_reg;
547
/* Redirect memory calls */
549
typedef delegate<UINT8 (offs_t)> m68k_read8_delegate;
550
typedef delegate<UINT16 (offs_t)> m68k_readimm16_delegate;
551
typedef delegate<UINT16 (offs_t)> m68k_read16_delegate;
552
typedef delegate<UINT32 (offs_t)> m68k_read32_delegate;
553
typedef delegate<void (offs_t, UINT8)> m68k_write8_delegate;
554
typedef delegate<void (offs_t, UINT16)> m68k_write16_delegate;
555
typedef delegate<void (offs_t, UINT32)> m68k_write32_delegate;
557
class m68k_memory_interface
560
void init8(address_space &space);
561
void init16(address_space &space);
562
void init32(address_space &space);
563
void init32mmu(address_space &space);
564
void init32hmmu(address_space &space);
566
offs_t opcode_xor; // Address Calculation
567
m68k_readimm16_delegate readimm16; // Immediate read 16 bit
568
m68k_read8_delegate read8;
569
m68k_read16_delegate read16;
570
m68k_read32_delegate read32;
571
m68k_write8_delegate write8;
572
m68k_write16_delegate write16;
573
m68k_write32_delegate write32;
576
UINT16 m68008_read_immediate_16(offs_t address);
577
UINT16 read_immediate_16(offs_t address);
578
UINT16 simple_read_immediate_16(offs_t address);
580
UINT8 read_byte_32_mmu(offs_t address);
581
void write_byte_32_mmu(offs_t address, UINT8 data);
582
UINT16 read_immediate_16_mmu(offs_t address);
583
UINT16 readword_d32_mmu(offs_t address);
584
void writeword_d32_mmu(offs_t address, UINT16 data);
585
UINT32 readlong_d32_mmu(offs_t address);
586
void writelong_d32_mmu(offs_t address, UINT32 data);
588
UINT8 read_byte_32_hmmu(offs_t address);
589
void write_byte_32_hmmu(offs_t address, UINT8 data);
590
UINT16 read_immediate_16_hmmu(offs_t address);
591
UINT16 readword_d32_hmmu(offs_t address);
592
void writeword_d32_hmmu(offs_t address, UINT16 data);
593
UINT32 readlong_d32_hmmu(offs_t address);
594
void writelong_d32_hmmu(offs_t address, UINT32 data);
596
address_space *m_space;
597
direct_read_data *m_direct;
598
m68ki_cpu_core *m_cpustate;
601
struct _m68ki_cpu_core
603
UINT32 cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */
604
UINT32 dasm_type; /* disassembly type */
605
UINT32 dar[16]; /* Data and Address Registers */
606
UINT32 ppc; /* Previous program counter */
607
UINT32 pc; /* Program Counter */
608
UINT32 sp[7]; /* User, Interrupt, and Master Stack Pointers */
609
UINT32 vbr; /* Vector Base Register (m68010+) */
610
UINT32 sfc; /* Source Function Code Register (m68010+) */
611
UINT32 dfc; /* Destination Function Code Register (m68010+) */
612
UINT32 cacr; /* Cache Control Register (m68020, unemulated) */
613
UINT32 caar; /* Cache Address Register (m68020, unemulated) */
614
UINT32 ir; /* Instruction Register */
615
floatx80 fpr[8]; /* FPU Data Register (m68030/040) */
616
UINT32 fpiar; /* FPU Instruction Address Register (m68040) */
617
UINT32 fpsr; /* FPU Status Register (m68040) */
618
UINT32 fpcr; /* FPU Control Register (m68040) */
619
UINT32 t1_flag; /* Trace 1 */
620
UINT32 t0_flag; /* Trace 0 */
621
UINT32 s_flag; /* Supervisor */
622
UINT32 m_flag; /* Master/Interrupt state */
623
UINT32 x_flag; /* Extend */
624
UINT32 n_flag; /* Negative */
625
UINT32 not_z_flag; /* Zero, inverted for speedups */
626
UINT32 v_flag; /* Overflow */
627
UINT32 c_flag; /* Carry */
628
UINT32 int_mask; /* I0-I2 */
629
UINT32 int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */
630
UINT32 stopped; /* Stopped state */
631
UINT32 pref_addr; /* Last prefetch address */
632
UINT32 pref_data; /* Data in the prefetch queue */
633
UINT32 sr_mask; /* Implemented status register bits */
634
UINT32 instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */
635
UINT32 run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */
636
int has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */
637
int has_hmmu; /* Indicates if an Apple HMMU is available in place of the 68851 (020 only) */
638
int pmmu_enabled; /* Indicates if the PMMU is enabled */
639
int hmmu_enabled; /* Indicates if the HMMU is enabled */
640
int has_fpu; /* Indicates if a FPU is available (yes on 030, 040, may be on 020) */
641
int fpu_just_reset; /* Indicates the FPU was just reset */
643
/* Clocks required for instructions / exceptions */
644
UINT32 cyc_bcc_notake_b;
645
UINT32 cyc_bcc_notake_w;
646
UINT32 cyc_dbcc_f_noexp;
647
UINT32 cyc_dbcc_f_exp;
648
UINT32 cyc_scc_r_true;
655
int remaining_cycles; /* Number of clocks remaining */
660
sigjmp_buf aerr_trap;
665
UINT32 aerr_write_mode;
668
/* Virtual IRQ lines state */
672
const UINT8* cyc_instruction;
673
const UINT8* cyc_exception;
675
/* Callbacks to host */
676
device_irq_callback int_ack_callback; /* Interrupt Acknowledge */
677
m68k_bkpt_ack_func bkpt_ack_callback; /* Breakpoint Acknowledge */
678
m68k_reset_func reset_instr_callback; /* Called when a RESET instruction is encountered */
679
m68k_cmpild_func cmpild_instr_callback; /* Called when a CMPI.L #v, Dn instruction is encountered */
680
m68k_rte_func rte_instr_callback; /* Called when a RTE instruction is encountered */
681
m68k_tas_func tas_instr_callback; /* Called when a TAS instruction is encountered, allows / disallows writeback */
683
legacy_cpu_device *device;
684
address_space *program;
685
m68k_memory_interface memory;
686
offs_t encrypted_start;
687
offs_t encrypted_end;
691
/* save state data */
697
UINT32 mmu_crp_aptr, mmu_crp_limit;
698
UINT32 mmu_srp_aptr, mmu_srp_limit;
701
UINT32 mmu_atc_tag[MMU_ATC_ENTRIES], mmu_atc_data[MMU_ATC_ENTRIES];
703
UINT32 mmu_tt0, mmu_tt1;
705
UINT16 mmu_tmp_sr; /* temporary hack: status code for ptest and to handle write protection */
706
UINT16 mmu_tmp_fc; /* temporary hack: function code for the mmu (moves) */
707
UINT16 mmu_tmp_rw; /* temporary hack: read/write (1/0) for the mmu */
708
UINT32 mmu_tmp_buserror_address; /* temporary hack: (first) bus error address */
709
UINT16 mmu_tmp_buserror_occurred; /* temporary hack: flag that bus error has occurred from mmu */
711
UINT32 ic_address[M68K_IC_SIZE]; /* instruction cache address data */
712
UINT16 ic_data[M68K_IC_SIZE]; /* instruction cache content data */
714
/* external instruction hook (does not depend on debug mode) */
715
typedef int (*instruction_hook_t)(device_t *device, offs_t curpc);
716
instruction_hook_t instruction_hook;
720
extern const UINT8 m68ki_shift_8_table[];
721
extern const UINT16 m68ki_shift_16_table[];
722
extern const UINT32 m68ki_shift_32_table[];
723
extern const UINT8 m68ki_exception_cycle_table[][256];
724
extern const UINT8 m68ki_ea_idx_cycle_table[];
726
/* Read data immediately after the program counter */
727
INLINE UINT32 m68ki_read_imm_16(m68ki_cpu_core *m68k);
728
INLINE UINT32 m68ki_read_imm_32(m68ki_cpu_core *m68k);
730
/* Read data with specific function code */
731
INLINE UINT32 m68ki_read_8_fc (m68ki_cpu_core *m68k, UINT32 address, UINT32 fc);
732
INLINE UINT32 m68ki_read_16_fc (m68ki_cpu_core *m68k, UINT32 address, UINT32 fc);
733
INLINE UINT32 m68ki_read_32_fc (m68ki_cpu_core *m68k, UINT32 address, UINT32 fc);
735
/* Write data with specific function code */
736
INLINE void m68ki_write_8_fc (m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value);
737
INLINE void m68ki_write_16_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value);
738
INLINE void m68ki_write_32_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value);
739
INLINE void m68ki_write_32_pd_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value);
741
/* Indexed and PC-relative ea fetching */
742
INLINE UINT32 m68ki_get_ea_pcdi(m68ki_cpu_core *m68k);
743
INLINE UINT32 m68ki_get_ea_pcix(m68ki_cpu_core *m68k);
744
INLINE UINT32 m68ki_get_ea_ix(m68ki_cpu_core *m68k, UINT32 An);
746
/* Operand fetching */
747
INLINE UINT32 OPER_AY_AI_8(m68ki_cpu_core *m68k);
748
INLINE UINT32 OPER_AY_AI_16(m68ki_cpu_core *m68k);
749
INLINE UINT32 OPER_AY_AI_32(m68ki_cpu_core *m68k);
750
INLINE UINT32 OPER_AY_PI_8(m68ki_cpu_core *m68k);
751
INLINE UINT32 OPER_AY_PI_16(m68ki_cpu_core *m68k);
752
INLINE UINT32 OPER_AY_PI_32(m68ki_cpu_core *m68k);
753
INLINE UINT32 OPER_AY_PD_8(m68ki_cpu_core *m68k);
754
INLINE UINT32 OPER_AY_PD_16(m68ki_cpu_core *m68k);
755
INLINE UINT32 OPER_AY_PD_32(m68ki_cpu_core *m68k);
756
INLINE UINT32 OPER_AY_DI_8(m68ki_cpu_core *m68k);
757
INLINE UINT32 OPER_AY_DI_16(m68ki_cpu_core *m68k);
758
INLINE UINT32 OPER_AY_DI_32(m68ki_cpu_core *m68k);
759
INLINE UINT32 OPER_AY_IX_8(m68ki_cpu_core *m68k);
760
INLINE UINT32 OPER_AY_IX_16(m68ki_cpu_core *m68k);
761
INLINE UINT32 OPER_AY_IX_32(m68ki_cpu_core *m68k);
763
INLINE UINT32 OPER_AX_AI_8(m68ki_cpu_core *m68k);
764
INLINE UINT32 OPER_AX_AI_16(m68ki_cpu_core *m68k);
765
INLINE UINT32 OPER_AX_AI_32(m68ki_cpu_core *m68k);
766
INLINE UINT32 OPER_AX_PI_8(m68ki_cpu_core *m68k);
767
INLINE UINT32 OPER_AX_PI_16(m68ki_cpu_core *m68k);
768
INLINE UINT32 OPER_AX_PI_32(m68ki_cpu_core *m68k);
769
INLINE UINT32 OPER_AX_PD_8(m68ki_cpu_core *m68k);
770
INLINE UINT32 OPER_AX_PD_16(m68ki_cpu_core *m68k);
771
INLINE UINT32 OPER_AX_PD_32(m68ki_cpu_core *m68k);
772
INLINE UINT32 OPER_AX_DI_8(m68ki_cpu_core *m68k);
773
INLINE UINT32 OPER_AX_DI_16(m68ki_cpu_core *m68k);
774
INLINE UINT32 OPER_AX_DI_32(m68ki_cpu_core *m68k);
775
INLINE UINT32 OPER_AX_IX_8(m68ki_cpu_core *m68k);
776
INLINE UINT32 OPER_AX_IX_16(m68ki_cpu_core *m68k);
777
INLINE UINT32 OPER_AX_IX_32(m68ki_cpu_core *m68k);
779
INLINE UINT32 OPER_A7_PI_8(m68ki_cpu_core *m68k);
780
INLINE UINT32 OPER_A7_PD_8(m68ki_cpu_core *m68k);
782
INLINE UINT32 OPER_AW_8(m68ki_cpu_core *m68k);
783
INLINE UINT32 OPER_AW_16(m68ki_cpu_core *m68k);
784
INLINE UINT32 OPER_AW_32(m68ki_cpu_core *m68k);
785
INLINE UINT32 OPER_AL_8(m68ki_cpu_core *m68k);
786
INLINE UINT32 OPER_AL_16(m68ki_cpu_core *m68k);
787
INLINE UINT32 OPER_AL_32(m68ki_cpu_core *m68k);
788
INLINE UINT32 OPER_PCDI_8(m68ki_cpu_core *m68k);
789
INLINE UINT32 OPER_PCDI_16(m68ki_cpu_core *m68k);
790
INLINE UINT32 OPER_PCDI_32(m68ki_cpu_core *m68k);
791
INLINE UINT32 OPER_PCIX_8(m68ki_cpu_core *m68k);
792
INLINE UINT32 OPER_PCIX_16(m68ki_cpu_core *m68k);
793
INLINE UINT32 OPER_PCIX_32(m68ki_cpu_core *m68k);
795
/* Stack operations */
796
INLINE void m68ki_push_16(m68ki_cpu_core *m68k, UINT32 value);
797
INLINE void m68ki_push_32(m68ki_cpu_core *m68k, UINT32 value);
798
INLINE UINT32 m68ki_pull_16(m68ki_cpu_core *m68k);
799
INLINE UINT32 m68ki_pull_32(m68ki_cpu_core *m68k);
801
/* Program flow operations */
802
INLINE void m68ki_jump(m68ki_cpu_core *m68k, UINT32 new_pc);
803
INLINE void m68ki_jump_vector(m68ki_cpu_core *m68k, UINT32 vector);
804
INLINE void m68ki_branch_8(m68ki_cpu_core *m68k, UINT32 offset);
805
INLINE void m68ki_branch_16(m68ki_cpu_core *m68k, UINT32 offset);
806
INLINE void m68ki_branch_32(m68ki_cpu_core *m68k, UINT32 offset);
808
/* Status register operations. */
809
INLINE void m68ki_set_s_flag(m68ki_cpu_core *m68k, UINT32 value); /* Only bit 2 of value should be set (i.e. 4 or 0) */
810
INLINE void m68ki_set_sm_flag(m68ki_cpu_core *m68k, UINT32 value); /* only bits 1 and 2 of value should be set */
811
INLINE void m68ki_set_ccr(m68ki_cpu_core *m68k, UINT32 value); /* set the condition code register */
812
INLINE void m68ki_set_sr(m68ki_cpu_core *m68k, UINT32 value); /* set the status register */
813
INLINE void m68ki_set_sr_noint(m68ki_cpu_core *m68k, UINT32 value); /* set the status register */
815
/* Exception processing */
816
INLINE UINT32 m68ki_init_exception(m68ki_cpu_core *m68k); /* Initial exception processing */
818
INLINE void m68ki_stack_frame_3word(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr); /* Stack various frame types */
819
INLINE void m68ki_stack_frame_buserr(m68ki_cpu_core *m68k, UINT32 sr);
821
INLINE void m68ki_stack_frame_0000(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector);
822
INLINE void m68ki_stack_frame_0001(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector);
823
INLINE void m68ki_stack_frame_0010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector);
824
INLINE void m68ki_stack_frame_1000(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector);
825
INLINE void m68ki_stack_frame_1010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT32 pc, UINT32 fault_address);
826
INLINE void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT32 pc, UINT32 fault_address);
828
INLINE void m68ki_exception_trap(m68ki_cpu_core *m68k, UINT32 vector);
829
INLINE void m68ki_exception_trapN(m68ki_cpu_core *m68k, UINT32 vector);
830
INLINE void m68ki_exception_trace(m68ki_cpu_core *m68k);
831
INLINE void m68ki_exception_privilege_violation(m68ki_cpu_core *m68k);
832
INLINE void m68ki_exception_1010(m68ki_cpu_core *m68k);
833
INLINE void m68ki_exception_1111(m68ki_cpu_core *m68k);
834
INLINE void m68ki_exception_illegal(m68ki_cpu_core *m68k);
835
INLINE void m68ki_exception_format_error(m68ki_cpu_core *m68k);
836
INLINE void m68ki_exception_address_error(m68ki_cpu_core *m68k);
837
INLINE void m68ki_exception_interrupt(m68ki_cpu_core *m68k, UINT32 int_level);
838
INLINE void m68ki_check_interrupts(m68ki_cpu_core *m68k); /* ASG: check for interrupts */
840
/* quick disassembly (used for logging) */
841
char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type);
844
/* ======================================================================== */
845
/* =========================== UTILITY FUNCTIONS ========================== */
846
/* ======================================================================== */
849
INLINE unsigned int m68k_read_immediate_32(m68ki_cpu_core *m68k, unsigned int address)
851
return (m68k->memory.readimm16(address) << 16) | m68k->memory.readimm16(address + 2);
854
INLINE unsigned int m68k_read_pcrelative_8(m68ki_cpu_core *m68k, unsigned int address)
856
if (address >= m68k->encrypted_start && address < m68k->encrypted_end)
857
return ((m68k->memory.readimm16(address&~1)>>(8*(1-(address & 1))))&0xff);
859
return m68k->memory.read8(address);
862
INLINE unsigned int m68k_read_pcrelative_16(m68ki_cpu_core *m68k, unsigned int address)
864
if (address >= m68k->encrypted_start && address < m68k->encrypted_end)
865
return m68k->memory.readimm16(address);
867
return m68k->memory.read16(address);
870
INLINE unsigned int m68k_read_pcrelative_32(m68ki_cpu_core *m68k, unsigned int address)
872
if (address >= m68k->encrypted_start && address < m68k->encrypted_end)
873
return m68k_read_immediate_32(m68k, address);
875
return m68k->memory.read32(address);
879
/* Special call to simulate undocumented 68k behavior when move.l with a
880
* predecrement destination mode is executed.
881
* A real 68k first writes the high word to [address+2], and then writes the
882
* low word to [address].
884
INLINE void m68kx_write_memory_32_pd(m68ki_cpu_core *m68k, unsigned int address, unsigned int value)
886
m68k->memory.write16(address+2, value>>16);
887
m68k->memory.write16(address, value&0xffff);
891
/* ---------------------------- Read Immediate ---------------------------- */
893
// clear the instruction cache
894
INLINE void m68ki_ic_clear(m68ki_cpu_core *m68k)
897
for (i=0; i< M68K_IC_SIZE; i++) {
898
m68k->ic_address[i] = ~0;
902
// read immediate word using the instruction cache
904
INLINE UINT32 m68ki_ic_readimm16(m68ki_cpu_core *m68k, UINT32 address)
906
if(CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type) && (m68k->cacr & M68K_CACR_EI))
908
UINT32 ic_offset = (address >> 1) % M68K_IC_SIZE;
909
if (m68k->ic_address[ic_offset] == address)
911
return m68k->ic_data[ic_offset];
915
UINT32 data = m68k->memory.readimm16(address);
916
if (!m68k->mmu_tmp_buserror_occurred)
918
m68k->ic_data[ic_offset] = data;
919
m68k->ic_address[ic_offset] = address;
926
return m68k->memory.readimm16(address);
929
// this can't happen, but Apple GCC insists
933
/* Handles all immediate reads, does address error check, function code setting,
934
* and prefetching if they are enabled in m68kconf.h
936
INLINE UINT32 m68ki_read_imm_16(m68ki_cpu_core *m68k)
940
m68k->mmu_tmp_fc = m68k->s_flag | FUNCTION_CODE_USER_PROGRAM;
941
m68k->mmu_tmp_rw = 1;
943
m68ki_check_address_error(m68k, REG_PC, MODE_READ, m68k->s_flag | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
945
if(REG_PC != m68k->pref_addr)
947
m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
948
m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
950
result = MASK_OUT_ABOVE_16(m68k->pref_data);
952
if (!m68k->mmu_tmp_buserror_occurred) {
953
// prefetch only if no bus error occurred in opcode fetch
954
m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
955
m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
956
// ignore bus error on prefetch
957
m68k->mmu_tmp_buserror_occurred = 0;
963
INLINE UINT32 m68ki_read_imm_32(m68ki_cpu_core *m68k)
967
m68k->mmu_tmp_fc = m68k->s_flag | FUNCTION_CODE_USER_PROGRAM;
968
m68k->mmu_tmp_rw = 1;
970
m68ki_check_address_error(m68k, REG_PC, MODE_READ, m68k->s_flag | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
972
if(REG_PC != m68k->pref_addr)
974
m68k->pref_addr = REG_PC;
975
m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr);
977
temp_val = MASK_OUT_ABOVE_16(m68k->pref_data);
979
m68k->pref_addr = REG_PC;
980
m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr);
982
temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(m68k->pref_data));
984
m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
985
m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
992
/* ------------------------- Top level read/write ------------------------- */
994
/* Handles all memory accesses (except for immediate reads if they are
995
* configured to use separate functions in m68kconf.h).
996
* All memory accesses must go through these top level functions.
997
* These functions will also check for address error and set the function
998
* code if they are enabled in m68kconf.h.
1000
INLINE UINT32 m68ki_read_8_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc)
1002
m68k->mmu_tmp_fc = fc;
1003
m68k->mmu_tmp_rw = 1;
1004
return m68k->memory.read8(address);
1006
INLINE UINT32 m68ki_read_16_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc)
1008
if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1010
m68ki_check_address_error(m68k, address, MODE_READ, fc);
1012
m68k->mmu_tmp_fc = fc;
1013
m68k->mmu_tmp_rw = 1;
1014
return m68k->memory.read16(address);
1016
INLINE UINT32 m68ki_read_32_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc)
1018
if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1020
m68ki_check_address_error(m68k, address, MODE_READ, fc);
1022
m68k->mmu_tmp_fc = fc;
1023
m68k->mmu_tmp_rw = 1;
1024
return m68k->memory.read32(address);
1027
INLINE void m68ki_write_8_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1029
m68k->mmu_tmp_fc = fc;
1030
m68k->mmu_tmp_rw = 0;
1031
m68k->memory.write8(address, value);
1033
INLINE void m68ki_write_16_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1035
if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1037
m68ki_check_address_error(m68k, address, MODE_WRITE, fc);
1039
m68k->mmu_tmp_fc = fc;
1040
m68k->mmu_tmp_rw = 0;
1041
m68k->memory.write16(address, value);
1043
INLINE void m68ki_write_32_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1045
if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1047
m68ki_check_address_error(m68k, address, MODE_WRITE, fc);
1049
m68k->mmu_tmp_fc = fc;
1050
m68k->mmu_tmp_rw = 0;
1051
m68k->memory.write32(address, value);
1054
/* Special call to simulate undocumented 68k behavior when move.l with a
1055
* predecrement destination mode is executed.
1056
* A real 68k first writes the high word to [address+2], and then writes the
1057
* low word to [address].
1059
INLINE void m68ki_write_32_pd_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1061
if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1063
m68ki_check_address_error(m68k, address, MODE_WRITE, fc);
1065
m68k->mmu_tmp_fc = fc;
1066
m68k->mmu_tmp_rw = 0;
1067
m68k->memory.write16(address+2, value>>16);
1068
m68k->memory.write16(address, value&0xffff);
1072
/* --------------------- Effective Address Calculation -------------------- */
1074
/* The program counter relative addressing modes cause operands to be
1075
* retrieved from program space, not data space.
1077
INLINE UINT32 m68ki_get_ea_pcdi(m68ki_cpu_core *m68k)
1079
UINT32 old_pc = REG_PC;
1080
return old_pc + MAKE_INT_16(m68ki_read_imm_16(m68k));
1084
INLINE UINT32 m68ki_get_ea_pcix(m68ki_cpu_core *m68k)
1086
return m68ki_get_ea_ix(m68k, REG_PC);
1089
/* Indexed addressing modes are encoded as follows:
1091
* Base instruction format:
1092
* F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0
1093
* x x x x x x x x x x | 1 1 0 | BASE REGISTER (An)
1095
* Base instruction format for destination EA in move instructions:
1096
* F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0
1097
* x x x x | BASE REG | 1 1 0 | X X X X X X (An)
1099
* Brief extension format:
1100
* F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0
1101
* D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT
1103
* Full extension format:
1104
* F E D C B A 9 8 7 6 5 4 3 2 1 0
1105
* D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS
1106
* BASE DISPLACEMENT (0, 16, 32 bit) (bd)
1107
* OUTER DISPLACEMENT (0, 16, 32 bit) (od)
1109
* D/A: 0 = Dn, 1 = An (Xn)
1110
* W/L: 0 = W (sign extend), 1 = L (.SIZE)
1111
* SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE)
1112
* BS: 0=add base reg, 1=suppress base reg (An suppressed)
1113
* IS: 0=add index, 1=suppress index (Xn suppressed)
1114
* BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd)
1117
* 0 000 No Memory Indirect
1118
* 0 001 indir prex with null outer
1119
* 0 010 indir prex with word outer
1120
* 0 011 indir prex with long outer
1122
* 0 101 indir postx with null outer
1123
* 0 110 indir postx with word outer
1124
* 0 111 indir postx with long outer
1125
* 1 000 no memory indirect
1126
* 1 001 mem indir with null outer
1127
* 1 010 mem indir with word outer
1128
* 1 011 mem indir with long outer
1129
* 1 100-111 reserved
1131
INLINE UINT32 m68ki_get_ea_ix(m68ki_cpu_core *m68k, UINT32 An)
1133
/* An = base register */
1134
UINT32 extension = m68ki_read_imm_16(m68k);
1135
UINT32 Xn = 0; /* Index register */
1136
UINT32 bd = 0; /* Base Displacement */
1137
UINT32 od = 0; /* Outer Displacement */
1139
if(CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1141
/* Calculate index */
1142
Xn = REG_DA[extension>>12]; /* Xn */
1143
if(!BIT_B(extension)) /* W/L */
1144
Xn = MAKE_INT_16(Xn);
1146
/* Add base register and displacement and return */
1147
return An + Xn + MAKE_INT_8(extension);
1150
/* Brief extension format */
1151
if(!BIT_8(extension))
1153
/* Calculate index */
1154
Xn = REG_DA[extension>>12]; /* Xn */
1155
if(!BIT_B(extension)) /* W/L */
1156
Xn = MAKE_INT_16(Xn);
1157
/* Add scale if proper CPU type */
1158
if(CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type))
1159
Xn <<= (extension>>9) & 3; /* SCALE */
1161
/* Add base register and displacement and return */
1162
return An + Xn + MAKE_INT_8(extension);
1165
/* Full extension format */
1167
m68k->remaining_cycles -= m68ki_ea_idx_cycle_table[extension&0x3f];
1169
/* Check if base register is present */
1170
if(BIT_7(extension)) /* BS */
1173
/* Check if index is present */
1174
if(!BIT_6(extension)) /* IS */
1176
Xn = REG_DA[extension>>12]; /* Xn */
1177
if(!BIT_B(extension)) /* W/L */
1178
Xn = MAKE_INT_16(Xn);
1179
Xn <<= (extension>>9) & 3; /* SCALE */
1182
/* Check if base displacement is present */
1183
if(BIT_5(extension)) /* BD SIZE */
1184
bd = BIT_4(extension) ? m68ki_read_imm_32(m68k) : MAKE_INT_16(m68ki_read_imm_16(m68k));
1186
/* If no indirect action, we are done */
1187
if(!(extension&7)) /* No Memory Indirect */
1188
return An + bd + Xn;
1190
/* Check if outer displacement is present */
1191
if(BIT_1(extension)) /* I/IS: od */
1192
od = BIT_0(extension) ? m68ki_read_imm_32(m68k) : MAKE_INT_16(m68ki_read_imm_16(m68k));
1195
if(BIT_2(extension)) /* I/IS: 0 = preindex, 1 = postindex */
1196
return m68ki_read_32(m68k, An + bd) + Xn + od;
1199
return m68ki_read_32(m68k, An + bd + Xn) + od;
1203
/* Fetch operands */
1204
INLINE UINT32 OPER_AY_AI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_AI_8(m68k); return m68ki_read_8(m68k, ea); }
1205
INLINE UINT32 OPER_AY_AI_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_AI_16(m68k); return m68ki_read_16(m68k, ea);}
1206
INLINE UINT32 OPER_AY_AI_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_AI_32(m68k); return m68ki_read_32(m68k, ea);}
1207
INLINE UINT32 OPER_AY_PI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_PI_8(m68k); return m68ki_read_8(m68k, ea); }
1208
INLINE UINT32 OPER_AY_PI_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_PI_16(m68k); return m68ki_read_16(m68k, ea);}
1209
INLINE UINT32 OPER_AY_PI_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_PI_32(m68k); return m68ki_read_32(m68k, ea);}
1210
INLINE UINT32 OPER_AY_PD_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_PD_8(m68k); return m68ki_read_8(m68k, ea); }
1211
INLINE UINT32 OPER_AY_PD_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_PD_16(m68k); return m68ki_read_16(m68k, ea);}
1212
INLINE UINT32 OPER_AY_PD_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_PD_32(m68k); return m68ki_read_32(m68k, ea);}
1213
INLINE UINT32 OPER_AY_DI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_DI_8(m68k); return m68ki_read_8(m68k, ea); }
1214
INLINE UINT32 OPER_AY_DI_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_DI_16(m68k); return m68ki_read_16(m68k, ea);}
1215
INLINE UINT32 OPER_AY_DI_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_DI_32(m68k); return m68ki_read_32(m68k, ea);}
1216
INLINE UINT32 OPER_AY_IX_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_IX_8(m68k); return m68ki_read_8(m68k, ea); }
1217
INLINE UINT32 OPER_AY_IX_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_IX_16(m68k); return m68ki_read_16(m68k, ea);}
1218
INLINE UINT32 OPER_AY_IX_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AY_IX_32(m68k); return m68ki_read_32(m68k, ea);}
1220
INLINE UINT32 OPER_AX_AI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_AI_8(m68k); return m68ki_read_8(m68k, ea); }
1221
INLINE UINT32 OPER_AX_AI_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_AI_16(m68k); return m68ki_read_16(m68k, ea);}
1222
INLINE UINT32 OPER_AX_AI_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_AI_32(m68k); return m68ki_read_32(m68k, ea);}
1223
INLINE UINT32 OPER_AX_PI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_PI_8(m68k); return m68ki_read_8(m68k, ea); }
1224
INLINE UINT32 OPER_AX_PI_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_PI_16(m68k); return m68ki_read_16(m68k, ea);}
1225
INLINE UINT32 OPER_AX_PI_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_PI_32(m68k); return m68ki_read_32(m68k, ea);}
1226
INLINE UINT32 OPER_AX_PD_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_PD_8(m68k); return m68ki_read_8(m68k, ea); }
1227
INLINE UINT32 OPER_AX_PD_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_PD_16(m68k); return m68ki_read_16(m68k, ea);}
1228
INLINE UINT32 OPER_AX_PD_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_PD_32(m68k); return m68ki_read_32(m68k, ea);}
1229
INLINE UINT32 OPER_AX_DI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_DI_8(m68k); return m68ki_read_8(m68k, ea); }
1230
INLINE UINT32 OPER_AX_DI_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_DI_16(m68k); return m68ki_read_16(m68k, ea);}
1231
INLINE UINT32 OPER_AX_DI_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_DI_32(m68k); return m68ki_read_32(m68k, ea);}
1232
INLINE UINT32 OPER_AX_IX_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_IX_8(m68k); return m68ki_read_8(m68k, ea); }
1233
INLINE UINT32 OPER_AX_IX_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_IX_16(m68k); return m68ki_read_16(m68k, ea);}
1234
INLINE UINT32 OPER_AX_IX_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AX_IX_32(m68k); return m68ki_read_32(m68k, ea);}
1236
INLINE UINT32 OPER_A7_PI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_A7_PI_8(m68k); return m68ki_read_8(m68k, ea); }
1237
INLINE UINT32 OPER_A7_PD_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_A7_PD_8(m68k); return m68ki_read_8(m68k, ea); }
1239
INLINE UINT32 OPER_AW_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AW_8(m68k); return m68ki_read_8(m68k, ea); }
1240
INLINE UINT32 OPER_AW_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AW_16(m68k); return m68ki_read_16(m68k, ea);}
1241
INLINE UINT32 OPER_AW_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AW_32(m68k); return m68ki_read_32(m68k, ea);}
1242
INLINE UINT32 OPER_AL_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_AL_8(m68k); return m68ki_read_8(m68k, ea); }
1243
INLINE UINT32 OPER_AL_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_AL_16(m68k); return m68ki_read_16(m68k, ea);}
1244
INLINE UINT32 OPER_AL_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_AL_32(m68k); return m68ki_read_32(m68k, ea);}
1245
INLINE UINT32 OPER_PCDI_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_PCDI_8(m68k); return m68ki_read_pcrel_8(m68k, ea); }
1246
INLINE UINT32 OPER_PCDI_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_PCDI_16(m68k); return m68ki_read_pcrel_16(m68k, ea);}
1247
INLINE UINT32 OPER_PCDI_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_PCDI_32(m68k); return m68ki_read_pcrel_32(m68k, ea);}
1248
INLINE UINT32 OPER_PCIX_8(m68ki_cpu_core *m68k) {UINT32 ea = EA_PCIX_8(m68k); return m68ki_read_pcrel_8(m68k, ea); }
1249
INLINE UINT32 OPER_PCIX_16(m68ki_cpu_core *m68k) {UINT32 ea = EA_PCIX_16(m68k); return m68ki_read_pcrel_16(m68k, ea);}
1250
INLINE UINT32 OPER_PCIX_32(m68ki_cpu_core *m68k) {UINT32 ea = EA_PCIX_32(m68k); return m68ki_read_pcrel_32(m68k, ea);}
1254
/* ---------------------------- Stack Functions --------------------------- */
1256
/* Push/pull data from the stack */
1257
INLINE void m68ki_push_16(m68ki_cpu_core *m68k, UINT32 value)
1259
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1260
m68ki_write_16(m68k, REG_SP, value);
1263
INLINE void m68ki_push_32(m68ki_cpu_core *m68k, UINT32 value)
1265
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1266
m68ki_write_32(m68k, REG_SP, value);
1269
INLINE UINT32 m68ki_pull_16(m68ki_cpu_core *m68k)
1271
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1272
return m68ki_read_16(m68k, REG_SP-2);
1275
INLINE UINT32 m68ki_pull_32(m68ki_cpu_core *m68k)
1277
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1278
return m68ki_read_32(m68k, REG_SP-4);
1282
/* Increment/decrement the stack as if doing a push/pull but
1283
* don't do any memory access.
1285
INLINE void m68ki_fake_push_16(m68ki_cpu_core *m68k)
1287
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1290
INLINE void m68ki_fake_push_32(m68ki_cpu_core *m68k)
1292
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1295
INLINE void m68ki_fake_pull_16(m68ki_cpu_core *m68k)
1297
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1300
INLINE void m68ki_fake_pull_32(m68ki_cpu_core *m68k)
1302
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1306
/* ----------------------------- Program Flow ----------------------------- */
1308
/* Jump to a new program location or vector.
1309
* These functions will also call the pc_changed callback if it was enabled
1312
INLINE void m68ki_jump(m68ki_cpu_core *m68k, UINT32 new_pc)
1317
INLINE void m68ki_jump_vector(m68ki_cpu_core *m68k, UINT32 vector)
1319
REG_PC = (vector<<2) + m68k->vbr;
1320
REG_PC = m68ki_read_data_32(m68k, REG_PC);
1324
/* Branch to a new memory location.
1325
* The 32-bit branch will call pc_changed if it was enabled in m68kconf.h.
1326
* So far I've found no problems with not calling pc_changed for 8 or 16
1329
INLINE void m68ki_branch_8(m68ki_cpu_core *m68k, UINT32 offset)
1331
REG_PC += MAKE_INT_8(offset);
1334
INLINE void m68ki_branch_16(m68ki_cpu_core *m68k, UINT32 offset)
1336
REG_PC += MAKE_INT_16(offset);
1339
INLINE void m68ki_branch_32(m68ki_cpu_core *m68k, UINT32 offset)
1346
/* ---------------------------- Status Register --------------------------- */
1348
/* Set the S flag and change the active stack pointer.
1349
* Note that value MUST be 4 or 0.
1351
INLINE void m68ki_set_s_flag(m68ki_cpu_core *m68k, UINT32 value)
1353
/* Backup the old stack pointer */
1354
REG_SP_BASE[m68k->s_flag | ((m68k->s_flag>>1) & m68k->m_flag)] = REG_SP;
1355
/* Set the S flag */
1356
m68k->s_flag = value;
1357
/* Set the new stack pointer */
1358
REG_SP = REG_SP_BASE[m68k->s_flag | ((m68k->s_flag>>1) & m68k->m_flag)];
1361
/* Set the S and M flags and change the active stack pointer.
1362
* Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M).
1364
INLINE void m68ki_set_sm_flag(m68ki_cpu_core *m68k, UINT32 value)
1366
/* Backup the old stack pointer */
1367
REG_SP_BASE[m68k->s_flag | ((m68k->s_flag>>1) & m68k->m_flag)] = REG_SP;
1368
/* Set the S and M flags */
1369
m68k->s_flag = value & SFLAG_SET;
1370
m68k->m_flag = value & MFLAG_SET;
1371
/* Set the new stack pointer */
1372
REG_SP = REG_SP_BASE[m68k->s_flag | ((m68k->s_flag>>1) & m68k->m_flag)];
1375
/* Set the S and M flags. Don't touch the stack pointer. */
1376
INLINE void m68ki_set_sm_flag_nosp(m68ki_cpu_core *m68k, UINT32 value)
1378
/* Set the S and M flags */
1379
m68k->s_flag = value & SFLAG_SET;
1380
m68k->m_flag = value & MFLAG_SET;
1384
/* Set the condition code register */
1385
INLINE void m68ki_set_ccr(m68ki_cpu_core *m68k, UINT32 value)
1387
m68k->x_flag = BIT_4(value) << 4;
1388
m68k->n_flag = BIT_3(value) << 4;
1389
m68k->not_z_flag = !BIT_2(value);
1390
m68k->v_flag = BIT_1(value) << 6;
1391
m68k->c_flag = BIT_0(value) << 8;
1394
/* Set the status register but don't check for interrupts */
1395
INLINE void m68ki_set_sr_noint(m68ki_cpu_core *m68k, UINT32 value)
1397
/* Mask out the "unimplemented" bits */
1398
value &= m68k->sr_mask;
1400
/* Now set the status register */
1401
m68k->t1_flag = BIT_F(value);
1402
m68k->t0_flag = BIT_E(value);
1403
m68k->int_mask = value & 0x0700;
1404
m68ki_set_ccr(m68k, value);
1405
m68ki_set_sm_flag(m68k, (value >> 11) & 6);
1408
/* Set the status register but don't check for interrupts nor
1409
* change the stack pointer
1411
INLINE void m68ki_set_sr_noint_nosp(m68ki_cpu_core *m68k, UINT32 value)
1413
/* Mask out the "unimplemented" bits */
1414
value &= m68k->sr_mask;
1416
/* Now set the status register */
1417
m68k->t1_flag = BIT_F(value);
1418
m68k->t0_flag = BIT_E(value);
1419
m68k->int_mask = value & 0x0700;
1420
m68ki_set_ccr(m68k, value);
1421
m68ki_set_sm_flag_nosp(m68k, (value >> 11) & 6);
1424
/* Set the status register and check for interrupts */
1425
INLINE void m68ki_set_sr(m68ki_cpu_core *m68k, UINT32 value)
1427
m68ki_set_sr_noint(m68k, value);
1428
m68ki_check_interrupts(m68k);
1432
/* ------------------------- Exception Processing ------------------------- */
1434
/* Initiate exception processing */
1435
INLINE UINT32 m68ki_init_exception(m68ki_cpu_core *m68k)
1437
/* Save the old status register */
1438
UINT32 sr = m68ki_get_sr(m68k);
1440
/* Turn off trace flag, clear pending traces */
1441
m68k->t1_flag = m68k->t0_flag = 0;
1442
m68ki_clear_trace();
1443
/* Enter supervisor mode */
1444
m68ki_set_s_flag(m68k, SFLAG_SET);
1449
/* 3 word stack frame (68000 only) */
1450
INLINE void m68ki_stack_frame_3word(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr)
1452
m68ki_push_32(m68k, pc);
1453
m68ki_push_16(m68k, sr);
1456
/* Format 0 stack frame.
1457
* This is the standard stack frame for 68010+.
1459
INLINE void m68ki_stack_frame_0000(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector)
1461
/* Stack a 3-word frame if we are 68000 */
1462
if(m68k->cpu_type == CPU_TYPE_000 || m68k->cpu_type == CPU_TYPE_008)
1464
m68ki_stack_frame_3word(m68k, pc, sr);
1467
m68ki_push_16(m68k, vector<<2);
1468
m68ki_push_32(m68k, pc);
1469
m68ki_push_16(m68k, sr);
1472
/* Format 1 stack frame (68020).
1473
* For 68020, this is the 4 word throwaway frame.
1475
INLINE void m68ki_stack_frame_0001(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector)
1477
m68ki_push_16(m68k, 0x1000 | (vector<<2));
1478
m68ki_push_32(m68k, pc);
1479
m68ki_push_16(m68k, sr);
1482
/* Format 2 stack frame.
1483
* This is used only by 68020 for trap exceptions.
1485
INLINE void m68ki_stack_frame_0010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector)
1487
m68ki_push_32(m68k, REG_PPC);
1488
m68ki_push_16(m68k, 0x2000 | (vector<<2));
1489
m68ki_push_32(m68k, REG_PC);
1490
m68ki_push_16(m68k, sr);
1494
/* Bus error stack frame (68000 only).
1496
INLINE void m68ki_stack_frame_buserr(m68ki_cpu_core *m68k, UINT32 sr)
1498
m68ki_push_32(m68k, REG_PC);
1499
m68ki_push_16(m68k, sr);
1500
m68ki_push_16(m68k, m68k->ir);
1501
m68ki_push_32(m68k, m68k->aerr_address); /* access address */
1502
/* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC
1503
* R/W 0 = write, 1 = read
1504
* I/N 0 = instruction, 1 = not
1505
* FC 3-bit function code
1507
m68ki_push_16(m68k, m68k->aerr_write_mode | m68k->instr_mode | m68k->aerr_fc);
1510
/* Format 8 stack frame (68010).
1511
* 68010 only. This is the 29 word bus/address error frame.
1513
void m68ki_stack_frame_1000(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector)
1517
* INTERNAL INFORMATION, 16 WORDS
1519
m68ki_fake_push_32(m68k);
1520
m68ki_fake_push_32(m68k);
1521
m68ki_fake_push_32(m68k);
1522
m68ki_fake_push_32(m68k);
1523
m68ki_fake_push_32(m68k);
1524
m68ki_fake_push_32(m68k);
1525
m68ki_fake_push_32(m68k);
1526
m68ki_fake_push_32(m68k);
1528
/* INSTRUCTION INPUT BUFFER */
1529
m68ki_push_16(m68k, 0);
1531
/* UNUSED, RESERVED (not written) */
1532
m68ki_fake_push_16(m68k);
1534
/* DATA INPUT BUFFER */
1535
m68ki_push_16(m68k, 0);
1537
/* UNUSED, RESERVED (not written) */
1538
m68ki_fake_push_16(m68k);
1540
/* DATA OUTPUT BUFFER */
1541
m68ki_push_16(m68k, 0);
1543
/* UNUSED, RESERVED (not written) */
1544
m68ki_fake_push_16(m68k);
1547
m68ki_push_32(m68k, 0);
1549
/* SPECIAL STATUS WORD */
1550
m68ki_push_16(m68k, 0);
1552
/* 1000, VECTOR OFFSET */
1553
m68ki_push_16(m68k, 0x8000 | (vector<<2));
1555
/* PROGRAM COUNTER */
1556
m68ki_push_32(m68k, pc);
1558
/* STATUS REGISTER */
1559
m68ki_push_16(m68k, sr);
1562
/* Format A stack frame (short bus fault).
1563
* This is used only by 68020 for bus fault and address error
1564
* if the error happens at an instruction boundary.
1565
* PC stacked is address of next instruction.
1567
void m68ki_stack_frame_1010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT32 pc, UINT32 fault_address)
1569
/* INTERNAL REGISTER */
1570
m68ki_push_16(m68k, 0);
1572
/* INTERNAL REGISTER */
1573
m68ki_push_16(m68k, 0);
1575
/* DATA OUTPUT BUFFER (2 words) */
1576
m68ki_push_32(m68k, 0);
1578
/* INTERNAL REGISTER */
1579
m68ki_push_16(m68k, 0);
1581
/* INTERNAL REGISTER */
1582
m68ki_push_16(m68k, 0);
1584
/* DATA CYCLE FAULT ADDRESS (2 words) */
1585
m68ki_push_32(m68k, fault_address);
1587
/* INSTRUCTION PIPE STAGE B */
1588
m68ki_push_16(m68k, 0);
1590
/* INSTRUCTION PIPE STAGE C */
1591
m68ki_push_16(m68k, 0);
1593
/* SPECIAL STATUS REGISTER */
1594
// set bit for: Rerun Faulted bus Cycle, or run pending prefetch
1596
m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc );
1598
/* INTERNAL REGISTER */
1599
m68ki_push_16(m68k, 0);
1601
/* 1010, VECTOR OFFSET */
1602
m68ki_push_16(m68k, 0xa000 | (vector<<2));
1604
/* PROGRAM COUNTER */
1605
m68ki_push_32(m68k, pc);
1607
/* STATUS REGISTER */
1608
m68ki_push_16(m68k, sr);
1611
/* Format B stack frame (long bus fault).
1612
* This is used only by 68020 for bus fault and address error
1613
* if the error happens during instruction execution.
1614
* PC stacked is address of instruction in progress.
1616
void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT32 pc, UINT32 fault_address)
1618
/* INTERNAL REGISTERS (18 words) */
1619
m68ki_push_32(m68k, 0);
1620
m68ki_push_32(m68k, 0);
1621
m68ki_push_32(m68k, 0);
1622
m68ki_push_32(m68k, 0);
1623
m68ki_push_32(m68k, 0);
1624
m68ki_push_32(m68k, 0);
1625
m68ki_push_32(m68k, 0);
1626
m68ki_push_32(m68k, 0);
1627
m68ki_push_32(m68k, 0);
1629
/* VERSION# (4 bits), INTERNAL INFORMATION */
1630
m68ki_push_16(m68k, 0);
1632
/* INTERNAL REGISTERS (3 words) */
1633
m68ki_push_32(m68k, 0);
1634
m68ki_push_16(m68k, 0);
1636
/* DATA INTPUT BUFFER (2 words) */
1637
m68ki_push_32(m68k, 0);
1639
/* INTERNAL REGISTERS (2 words) */
1640
m68ki_push_32(m68k, 0);
1642
/* STAGE B ADDRESS (2 words) */
1643
m68ki_push_32(m68k, 0);
1645
/* INTERNAL REGISTER (4 words) */
1646
m68ki_push_32(m68k, 0);
1647
m68ki_push_32(m68k, 0);
1649
/* DATA OUTPUT BUFFER (2 words) */
1650
m68ki_push_32(m68k, 0);
1652
/* INTERNAL REGISTER */
1653
m68ki_push_16(m68k, 0);
1655
/* INTERNAL REGISTER */
1656
m68ki_push_16(m68k, 0);
1658
/* DATA CYCLE FAULT ADDRESS (2 words) */
1659
m68ki_push_32(m68k, fault_address);
1661
/* INSTRUCTION PIPE STAGE B */
1662
m68ki_push_16(m68k, 0);
1664
/* INSTRUCTION PIPE STAGE C */
1665
m68ki_push_16(m68k, 0);
1667
/* SPECIAL STATUS REGISTER */
1668
m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc);
1670
/* INTERNAL REGISTER */
1671
m68ki_push_16(m68k, 0);
1673
/* 1011, VECTOR OFFSET */
1674
m68ki_push_16(m68k, 0xb000 | (vector<<2));
1676
/* PROGRAM COUNTER */
1677
m68ki_push_32(m68k, pc);
1679
/* STATUS REGISTER */
1680
m68ki_push_16(m68k, sr);
1684
/* Used for Group 2 exceptions.
1685
* These stack a type 2 frame on the 020.
1687
INLINE void m68ki_exception_trap(m68ki_cpu_core *m68k, UINT32 vector)
1689
UINT32 sr = m68ki_init_exception(m68k);
1691
if(CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1692
m68ki_stack_frame_0000(m68k, REG_PC, sr, vector);
1694
m68ki_stack_frame_0010(m68k, sr, vector);
1696
m68ki_jump_vector(m68k, vector);
1698
/* Use up some clock cycles */
1699
m68k->remaining_cycles -= m68k->cyc_exception[vector];
1702
/* Trap#n stacks a 0 frame but behaves like group2 otherwise */
1703
INLINE void m68ki_exception_trapN(m68ki_cpu_core *m68k, UINT32 vector)
1705
UINT32 sr = m68ki_init_exception(m68k);
1706
m68ki_stack_frame_0000(m68k, REG_PC, sr, vector);
1707
m68ki_jump_vector(m68k, vector);
1709
/* Use up some clock cycles */
1710
m68k->remaining_cycles -= m68k->cyc_exception[vector];
1713
/* Exception for trace mode */
1714
INLINE void m68ki_exception_trace(m68ki_cpu_core *m68k)
1716
UINT32 sr = m68ki_init_exception(m68k);
1718
if(CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1720
if(CPU_TYPE_IS_000(m68k->cpu_type))
1722
m68k->instr_mode = INSTRUCTION_NO;
1724
m68ki_stack_frame_0000(m68k, REG_PC, sr, EXCEPTION_TRACE);
1727
m68ki_stack_frame_0010(m68k, sr, EXCEPTION_TRACE);
1729
m68ki_jump_vector(m68k, EXCEPTION_TRACE);
1731
/* Trace nullifies a STOP instruction */
1732
m68k->stopped &= ~STOP_LEVEL_STOP;
1734
/* Use up some clock cycles */
1735
m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_TRACE];
1738
/* Exception for privilege violation */
1739
INLINE void m68ki_exception_privilege_violation(m68ki_cpu_core *m68k)
1741
UINT32 sr = m68ki_init_exception(m68k);
1743
if(CPU_TYPE_IS_000(m68k->cpu_type))
1745
m68k->instr_mode = INSTRUCTION_NO;
1748
m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_PRIVILEGE_VIOLATION);
1749
m68ki_jump_vector(m68k, EXCEPTION_PRIVILEGE_VIOLATION);
1751
/* Use up some clock cycles and undo the instruction's cycles */
1752
m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_PRIVILEGE_VIOLATION] - m68k->cyc_instruction[m68k->ir];
1755
/* Exception for A-Line instructions */
1756
INLINE void m68ki_exception_1010(m68ki_cpu_core *m68k)
1760
sr = m68ki_init_exception(m68k);
1761
m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_1010);
1762
m68ki_jump_vector(m68k, EXCEPTION_1010);
1764
/* Use up some clock cycles and undo the instruction's cycles */
1765
m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_1010] - m68k->cyc_instruction[m68k->ir];
1768
/* Exception for F-Line instructions */
1769
INLINE void m68ki_exception_1111(m68ki_cpu_core *m68k)
1773
sr = m68ki_init_exception(m68k);
1774
m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_1111);
1775
m68ki_jump_vector(m68k, EXCEPTION_1111);
1777
/* Use up some clock cycles and undo the instruction's cycles */
1778
m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_1111] - m68k->cyc_instruction[m68k->ir];
1781
/* Exception for illegal instructions */
1782
INLINE void m68ki_exception_illegal(m68ki_cpu_core *m68k)
1786
sr = m68ki_init_exception(m68k);
1788
if(CPU_TYPE_IS_000(m68k->cpu_type))
1790
m68k->instr_mode = INSTRUCTION_NO;
1793
m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_ILLEGAL_INSTRUCTION);
1794
m68ki_jump_vector(m68k, EXCEPTION_ILLEGAL_INSTRUCTION);
1796
/* Use up some clock cycles and undo the instruction's cycles */
1797
m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_ILLEGAL_INSTRUCTION] - m68k->cyc_instruction[m68k->ir];
1800
/* Exception for format errror in RTE */
1801
INLINE void m68ki_exception_format_error(m68ki_cpu_core *m68k)
1803
UINT32 sr = m68ki_init_exception(m68k);
1804
m68ki_stack_frame_0000(m68k, REG_PC, sr, EXCEPTION_FORMAT_ERROR);
1805
m68ki_jump_vector(m68k, EXCEPTION_FORMAT_ERROR);
1807
/* Use up some clock cycles and undo the instruction's cycles */
1808
m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_FORMAT_ERROR] - m68k->cyc_instruction[m68k->ir];
1811
/* Exception for address error */
1812
INLINE void m68ki_exception_address_error(m68ki_cpu_core *m68k)
1814
UINT32 sr = m68ki_init_exception(m68k);
1816
/* If we were processing a bus error, address error, or reset,
1817
* this is a catastrophic failure.
1820
if(m68k->run_mode == RUN_MODE_BERR_AERR_RESET)
1822
m68k->memory.read8(0x00ffff01);
1823
m68k->stopped = STOP_LEVEL_HALT;
1826
m68k->run_mode = RUN_MODE_BERR_AERR_RESET;
1828
/* Note: This is implemented for 68000 only! */
1829
m68ki_stack_frame_buserr(m68k, sr);
1831
m68ki_jump_vector(m68k, EXCEPTION_ADDRESS_ERROR);
1833
/* Use up some clock cycles and undo the instruction's cycles */
1834
m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_ADDRESS_ERROR] - m68k->cyc_instruction[m68k->ir];
1838
/* Service an interrupt request and start exception processing */
1839
void m68ki_exception_interrupt(m68ki_cpu_core *m68k, UINT32 int_level)
1845
if(CPU_TYPE_IS_000(m68k->cpu_type))
1847
m68k->instr_mode = INSTRUCTION_NO;
1850
/* Turn off the stopped state */
1851
m68k->stopped &= ~STOP_LEVEL_STOP;
1853
/* If we are halted, don't do anything */
1857
/* Acknowledge the interrupt */
1858
vector = (*m68k->int_ack_callback)(m68k->device, int_level);
1860
/* Get the interrupt vector */
1861
if(vector == M68K_INT_ACK_AUTOVECTOR)
1862
/* Use the autovectors. This is the most commonly used implementation */
1863
vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
1864
else if(vector == M68K_INT_ACK_SPURIOUS)
1865
/* Called if no devices respond to the interrupt acknowledge */
1866
vector = EXCEPTION_SPURIOUS_INTERRUPT;
1867
else if(vector > 255)
1870
/* Start exception processing */
1871
sr = m68ki_init_exception(m68k);
1873
/* Set the interrupt mask to the level of the one being serviced */
1874
m68k->int_mask = int_level<<8;
1876
/* Get the new PC */
1877
new_pc = m68ki_read_data_32(m68k, (vector<<2) + m68k->vbr);
1879
/* If vector is uninitialized, call the uninitialized interrupt vector */
1881
new_pc = m68ki_read_data_32(m68k, (EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + m68k->vbr);
1883
/* Generate a stack frame */
1884
m68ki_stack_frame_0000(m68k, REG_PC, sr, vector);
1885
if(m68k->m_flag && CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type))
1887
/* Create throwaway frame */
1888
m68ki_set_sm_flag(m68k, m68k->s_flag); /* clear M */
1889
sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */
1890
m68ki_stack_frame_0001(m68k, REG_PC, sr, vector);
1893
m68ki_jump(m68k, new_pc);
1895
/* Defer cycle counting until later */
1896
m68k->remaining_cycles -= m68k->cyc_exception[vector];
1900
/* ASG: Check for interrupts */
1901
INLINE void m68ki_check_interrupts(m68ki_cpu_core *m68k)
1903
if(m68k->nmi_pending)
1905
m68k->nmi_pending = FALSE;
1906
m68ki_exception_interrupt(m68k, 7);
1908
else if(m68k->int_level > m68k->int_mask)
1909
m68ki_exception_interrupt(m68k, m68k->int_level>>8);
1914
/* ======================================================================== */
1915
/* ============================== END OF FILE ============================= */
1916
/* ======================================================================== */
1918
#endif /* __M68KCPU_H__ */