Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/genplus-gx32/core/m68k/m68kcpu.h
2 views
1
#ifndef M68KCPU__HEADER
2
#define M68KCPU__HEADER
3
4
/* ======================================================================== */
5
/* GENERIC 68K CORE */
6
/* ======================================================================== */
7
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <limits.h>
11
12
#if M68K_EMULATE_ADDRESS_ERROR
13
#include <setjmp.h>
14
#endif /* M68K_EMULATE_ADDRESS_ERROR */
15
16
#include "m68k.h"
17
#include "../cinterface/callbacks.h"
18
19
void CDLog68k(uint addr, uint flags);
20
21
/* ======================================================================== */
22
/* ============================ GENERAL DEFINES =========================== */
23
/* ======================================================================== */
24
25
/* Exception Vectors handled by emulation */
26
#define EXCEPTION_RESET 0
27
#define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */
28
#define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */
29
#define EXCEPTION_ILLEGAL_INSTRUCTION 4
30
#define EXCEPTION_ZERO_DIVIDE 5
31
#define EXCEPTION_CHK 6
32
#define EXCEPTION_TRAPV 7
33
#define EXCEPTION_PRIVILEGE_VIOLATION 8
34
#define EXCEPTION_TRACE 9
35
#define EXCEPTION_1010 10
36
#define EXCEPTION_1111 11
37
#define EXCEPTION_FORMAT_ERROR 14
38
#define EXCEPTION_UNINITIALIZED_INTERRUPT 15
39
#define EXCEPTION_SPURIOUS_INTERRUPT 24
40
#define EXCEPTION_INTERRUPT_AUTOVECTOR 24
41
#define EXCEPTION_TRAP_BASE 32
42
43
/* Function codes set by CPU during data/address bus activity */
44
#define FUNCTION_CODE_USER_DATA 1
45
#define FUNCTION_CODE_USER_PROGRAM 2
46
#define FUNCTION_CODE_SUPERVISOR_DATA 5
47
#define FUNCTION_CODE_SUPERVISOR_PROGRAM 6
48
#define FUNCTION_CODE_CPU_SPACE 7
49
50
/* Different ways to stop the CPU */
51
#define STOP_LEVEL_STOP 1
52
#define STOP_LEVEL_HALT 2
53
54
/* Used for 68000 address error processing */
55
#if M68K_EMULATE_ADDRESS_ERROR
56
#define INSTRUCTION_YES 0
57
#define INSTRUCTION_NO 0x08
58
#define MODE_READ 0x10
59
#define MODE_WRITE 0
60
61
#define RUN_MODE_NORMAL 0
62
#define RUN_MODE_BERR_AERR_RESET 1
63
#endif
64
65
#ifndef NULL
66
#define NULL ((void*)0)
67
#endif
68
69
/* ======================================================================== */
70
/* ================================ MACROS ================================ */
71
/* ======================================================================== */
72
73
74
/* ---------------------------- General Macros ---------------------------- */
75
76
/* Bit Isolation Macros */
77
#define BIT_0(A) ((A) & 0x00000001)
78
#define BIT_1(A) ((A) & 0x00000002)
79
#define BIT_2(A) ((A) & 0x00000004)
80
#define BIT_3(A) ((A) & 0x00000008)
81
#define BIT_4(A) ((A) & 0x00000010)
82
#define BIT_5(A) ((A) & 0x00000020)
83
#define BIT_6(A) ((A) & 0x00000040)
84
#define BIT_7(A) ((A) & 0x00000080)
85
#define BIT_8(A) ((A) & 0x00000100)
86
#define BIT_9(A) ((A) & 0x00000200)
87
#define BIT_A(A) ((A) & 0x00000400)
88
#define BIT_B(A) ((A) & 0x00000800)
89
#define BIT_C(A) ((A) & 0x00001000)
90
#define BIT_D(A) ((A) & 0x00002000)
91
#define BIT_E(A) ((A) & 0x00004000)
92
#define BIT_F(A) ((A) & 0x00008000)
93
#define BIT_10(A) ((A) & 0x00010000)
94
#define BIT_11(A) ((A) & 0x00020000)
95
#define BIT_12(A) ((A) & 0x00040000)
96
#define BIT_13(A) ((A) & 0x00080000)
97
#define BIT_14(A) ((A) & 0x00100000)
98
#define BIT_15(A) ((A) & 0x00200000)
99
#define BIT_16(A) ((A) & 0x00400000)
100
#define BIT_17(A) ((A) & 0x00800000)
101
#define BIT_18(A) ((A) & 0x01000000)
102
#define BIT_19(A) ((A) & 0x02000000)
103
#define BIT_1A(A) ((A) & 0x04000000)
104
#define BIT_1B(A) ((A) & 0x08000000)
105
#define BIT_1C(A) ((A) & 0x10000000)
106
#define BIT_1D(A) ((A) & 0x20000000)
107
#define BIT_1E(A) ((A) & 0x40000000)
108
#define BIT_1F(A) ((A) & 0x80000000)
109
110
/* Get the most significant bit for specific sizes */
111
#define GET_MSB_8(A) ((A) & 0x80)
112
#define GET_MSB_9(A) ((A) & 0x100)
113
#define GET_MSB_16(A) ((A) & 0x8000)
114
#define GET_MSB_17(A) ((A) & 0x10000)
115
#define GET_MSB_32(A) ((A) & 0x80000000)
116
#if M68K_USE_64_BIT
117
#define GET_MSB_33(A) ((A) & 0x100000000)
118
#endif /* M68K_USE_64_BIT */
119
120
/* Isolate nibbles */
121
#define LOW_NIBBLE(A) ((A) & 0x0f)
122
#define HIGH_NIBBLE(A) ((A) & 0xf0)
123
124
/* These are used to isolate 8, 16, and 32 bit sizes */
125
#define MASK_OUT_ABOVE_2(A) ((A) & 3)
126
#define MASK_OUT_ABOVE_8(A) ((A) & 0xff)
127
#define MASK_OUT_ABOVE_16(A) ((A) & 0xffff)
128
#define MASK_OUT_BELOW_2(A) ((A) & ~3)
129
#define MASK_OUT_BELOW_8(A) ((A) & ~0xff)
130
#define MASK_OUT_BELOW_16(A) ((A) & ~0xffff)
131
132
/* No need to mask if we are 32 bit */
133
#if M68K_INT_GT_32_BIT || M68K_USE_64_BIT
134
#define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff)
135
#define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff)
136
#else
137
#define MASK_OUT_ABOVE_32(A) (A)
138
#define MASK_OUT_BELOW_32(A) 0
139
#endif /* M68K_INT_GT_32_BIT || M68K_USE_64_BIT */
140
141
/* Simulate address lines of 68k family */
142
#define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK)
143
144
145
/* Shift & Rotate Macros. */
146
#define LSL(A, C) ((A) << (C))
147
#define LSR(A, C) ((A) >> (C))
148
149
/* Some > 32-bit optimizations */
150
#if M68K_INT_GT_32_BIT
151
/* Shift left and right */
152
#define LSR_32(A, C) ((A) >> (C))
153
#define LSL_32(A, C) ((A) << (C))
154
#else
155
/* We have to do this because the morons at ANSI decided that shifts
156
* by >= data size are undefined.
157
*/
158
#define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
159
#define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
160
#endif /* M68K_INT_GT_32_BIT */
161
162
#if M68K_USE_64_BIT
163
#define LSL_32_64(A, C) ((A) << (C))
164
#define LSR_32_64(A, C) ((A) >> (C))
165
#define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C)))
166
#define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C)))
167
#endif /* M68K_USE_64_BIT */
168
169
#define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C)))
170
#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C)))
171
#define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C)))
172
#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C)))
173
#define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C)))
174
#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C)))
175
176
#define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C)))
177
#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C)))
178
#define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C)))
179
#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C)))
180
#define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C)))
181
#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C)))
182
183
184
185
/* ------------------------------ CPU Access ------------------------------ */
186
187
/* Access the CPU registers */
188
#define REG_DA m68ki_cpu.dar /* easy access to data and address regs */
189
#define REG_D m68ki_cpu.dar
190
#define REG_A (m68ki_cpu.dar+8)
191
#define REG_PC m68ki_cpu.pc
192
#define REG_SP_BASE m68ki_cpu.sp
193
#define REG_USP m68ki_cpu.sp[0]
194
#define REG_ISP m68ki_cpu.sp[4]
195
#define REG_SP m68ki_cpu.dar[15]
196
#define REG_IR m68ki_cpu.ir
197
198
#define FLAG_T1 m68ki_cpu.t1_flag
199
#define FLAG_S m68ki_cpu.s_flag
200
#define FLAG_X m68ki_cpu.x_flag
201
#define FLAG_N m68ki_cpu.n_flag
202
#define FLAG_Z m68ki_cpu.not_z_flag
203
#define FLAG_V m68ki_cpu.v_flag
204
#define FLAG_C m68ki_cpu.c_flag
205
#define FLAG_INT_MASK m68ki_cpu.int_mask
206
207
#define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */
208
#define CPU_STOPPED m68ki_cpu.stopped
209
#if M68K_EMULATE_PREFETCH
210
#define CPU_PREF_ADDR m68ki_cpu.pref_addr
211
#define CPU_PREF_DATA m68ki_cpu.pref_data
212
#endif
213
#define CPU_ADDRESS_MASK 0x00ffffff
214
#if M68K_EMULATE_ADDRESS_ERROR
215
#define CPU_INSTR_MODE m68ki_cpu.instr_mode
216
#define CPU_RUN_MODE m68ki_cpu.run_mode
217
#endif
218
219
#define CYC_INSTRUCTION m68ki_cycles
220
#define CYC_EXCEPTION m68ki_exception_cycle_table
221
#define CYC_BCC_NOTAKE_B ( -2 * MUL)
222
#define CYC_BCC_NOTAKE_W ( 2 * MUL)
223
#define CYC_DBCC_F_NOEXP ( -2 * MUL)
224
#define CYC_DBCC_F_EXP ( 2 * MUL)
225
#define CYC_SCC_R_TRUE ( 2 * MUL)
226
#define CYC_MOVEM_W ( 4 * MUL)
227
#define CYC_MOVEM_L ( 8 * MUL)
228
#define CYC_SHIFT ( 2 * MUL)
229
#define CYC_RESET (132 * MUL)
230
231
#if M68K_EMULATE_INT_ACK == OPT_ON
232
#define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback
233
#endif
234
#if M68K_EMULATE_RESET == OPT_ON
235
#define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback
236
#endif
237
#if M68K_TAS_HAS_CALLBACK == OPT_ON
238
#define CALLBACK_TAS_INSTR m68ki_cpu.tas_instr_callback
239
#endif
240
#if M68K_EMULATE_FC == OPT_ON
241
#define CALLBACK_SET_FC m68ki_cpu.set_fc_callback
242
#endif
243
244
245
/* ----------------------------- Configuration ---------------------------- */
246
247
/* These defines are dependant on the configuration defines in m68kconf.h */
248
249
/* Enable or disable callback functions */
250
#if M68K_EMULATE_INT_ACK
251
#if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER
252
#define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A);
253
#else
254
#define m68ki_int_ack(A) CALLBACK_INT_ACK(A);
255
#endif
256
#else
257
/* Default action is to used autovector mode, which is most common */
258
#define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR
259
#endif /* M68K_EMULATE_INT_ACK */
260
261
#if M68K_EMULATE_RESET
262
#if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER
263
#define m68ki_output_reset() M68K_RESET_CALLBACK();
264
#else
265
#define m68ki_output_reset() CALLBACK_RESET_INSTR();
266
#endif
267
#else
268
#define m68ki_output_reset()
269
#endif /* M68K_EMULATE_RESET */
270
271
#if M68K_TAS_HAS_CALLBACK
272
#if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER
273
#define m68ki_tas_callback() M68K_TAS_CALLBACK()
274
#else
275
#define m68ki_tas_callback() CALLBACK_TAS_INSTR()
276
#endif
277
#else
278
#define m68ki_tas_callback() 0
279
#endif /* M68K_TAS_HAS_CALLBACK */
280
281
282
/* Enable or disable function code emulation */
283
#if M68K_EMULATE_FC
284
#if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER
285
#define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A);
286
#else
287
#define m68ki_set_fc(A) CALLBACK_SET_FC(A);
288
#endif
289
#define m68ki_use_data_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_DATA;
290
#define m68ki_use_program_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_PROGRAM;
291
#define m68ki_get_address_space() m68ki_cpu.address_space
292
#else
293
#define m68ki_set_fc(A)
294
#define m68ki_use_data_space()
295
#define m68ki_use_program_space()
296
#define m68ki_get_address_space() FUNCTION_CODE_USER_DATA
297
#endif /* M68K_EMULATE_FC */
298
299
300
/* Enable or disable trace emulation */
301
#if M68K_EMULATE_TRACE
302
/* Initiates trace checking before each instruction (t1) */
303
#define m68ki_trace_t1() m68ki_cpu.tracing = FLAG_T1;
304
/* Clear all tracing */
305
#define m68ki_clear_trace() m68ki_cpu.tracing = 0;
306
/* Cause a trace exception if we are tracing */
307
#define m68ki_exception_if_trace() if(m68ki_cpu.tracing) m68ki_exception_trace();
308
#else
309
#define m68ki_trace_t1()
310
#define m68ki_clear_trace()
311
#define m68ki_exception_if_trace()
312
#endif /* M68K_EMULATE_TRACE */
313
314
315
/* Enable or disable Address error emulation */
316
#if M68K_EMULATE_ADDRESS_ERROR
317
#define m68ki_set_address_error_trap() \
318
if(setjmp(m68ki_cpu.aerr_trap) != 0) \
319
{ \
320
m68ki_exception_address_error(); \
321
}
322
323
#define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \
324
if((ADDR)&1) \
325
{ \
326
if (m68ki_cpu.aerr_enabled) \
327
{ \
328
m68ki_cpu.aerr_address = ADDR; \
329
m68ki_cpu.aerr_write_mode = WRITE_MODE; \
330
m68ki_cpu.aerr_fc = FC; \
331
longjmp(m68ki_cpu.aerr_trap, 1); \
332
} \
333
}
334
#else
335
#define m68ki_set_address_error_trap()
336
#define m68ki_check_address_error(ADDR, WRITE_MODE, FC)
337
#endif /* M68K_ADDRESS_ERROR */
338
339
340
/* -------------------------- EA / Operand Access ------------------------- */
341
342
/*
343
* The general instruction format follows this pattern:
344
* .... XXX. .... .YYY
345
* where XXX is register X and YYY is register Y
346
*/
347
348
/* Data Register Isolation */
349
#define DX (REG_D[(REG_IR >> 9) & 7])
350
#define DY (REG_D[REG_IR & 7])
351
352
/* Address Register Isolation */
353
#define AX (REG_A[(REG_IR >> 9) & 7])
354
#define AY (REG_A[REG_IR & 7])
355
356
/* Effective Address Calculations */
357
#define EA_AY_AI_8() AY /* address register indirect */
358
#define EA_AY_AI_16() EA_AY_AI_8()
359
#define EA_AY_AI_32() EA_AY_AI_8()
360
#define EA_AY_PI_8() (AY++) /* postincrement (size = byte) */
361
#define EA_AY_PI_16() ((AY+=2)-2) /* postincrement (size = word) */
362
#define EA_AY_PI_32() ((AY+=4)-4) /* postincrement (size = long) */
363
#define EA_AY_PD_8() (--AY) /* predecrement (size = byte) */
364
#define EA_AY_PD_16() (AY-=2) /* predecrement (size = word) */
365
#define EA_AY_PD_32() (AY-=4) /* predecrement (size = long) */
366
#define EA_AY_DI_8() (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */
367
#define EA_AY_DI_16() EA_AY_DI_8()
368
#define EA_AY_DI_32() EA_AY_DI_8()
369
#define EA_AY_IX_8() m68ki_get_ea_ix(AY) /* indirect + index */
370
#define EA_AY_IX_16() EA_AY_IX_8()
371
#define EA_AY_IX_32() EA_AY_IX_8()
372
373
#define EA_AX_AI_8() AX
374
#define EA_AX_AI_16() EA_AX_AI_8()
375
#define EA_AX_AI_32() EA_AX_AI_8()
376
#define EA_AX_PI_8() (AX++)
377
#define EA_AX_PI_16() ((AX+=2)-2)
378
#define EA_AX_PI_32() ((AX+=4)-4)
379
#define EA_AX_PD_8() (--AX)
380
#define EA_AX_PD_16() (AX-=2)
381
#define EA_AX_PD_32() (AX-=4)
382
#define EA_AX_DI_8() (AX+MAKE_INT_16(m68ki_read_imm_16()))
383
#define EA_AX_DI_16() EA_AX_DI_8()
384
#define EA_AX_DI_32() EA_AX_DI_8()
385
#define EA_AX_IX_8() m68ki_get_ea_ix(AX)
386
#define EA_AX_IX_16() EA_AX_IX_8()
387
#define EA_AX_IX_32() EA_AX_IX_8()
388
389
#define EA_A7_PI_8() ((REG_A[7]+=2)-2)
390
#define EA_A7_PD_8() (REG_A[7]-=2)
391
392
#define EA_AW_8() MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */
393
#define EA_AW_16() EA_AW_8()
394
#define EA_AW_32() EA_AW_8()
395
#define EA_AL_8() m68ki_read_imm_32() /* absolute long */
396
#define EA_AL_16() EA_AL_8()
397
#define EA_AL_32() EA_AL_8()
398
#define EA_PCDI_8() m68ki_get_ea_pcdi() /* pc indirect + displacement */
399
#define EA_PCDI_16() EA_PCDI_8()
400
#define EA_PCDI_32() EA_PCDI_8()
401
#define EA_PCIX_8() m68ki_get_ea_pcix() /* pc indirect + index */
402
#define EA_PCIX_16() EA_PCIX_8()
403
#define EA_PCIX_32() EA_PCIX_8()
404
405
406
#define OPER_I_8() m68ki_read_imm_8()
407
#define OPER_I_16() m68ki_read_imm_16()
408
#define OPER_I_32() m68ki_read_imm_32()
409
410
411
/* --------------------------- Status Register ---------------------------- */
412
413
/* Flag Calculation Macros */
414
#define CFLAG_8(A) (A)
415
#define CFLAG_16(A) ((A)>>8)
416
417
#if M68K_INT_GT_32_BIT
418
#define CFLAG_ADD_32(S, D, R) ((R)>>24)
419
#define CFLAG_SUB_32(S, D, R) ((R)>>24)
420
#else
421
#define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23)
422
#define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23)
423
#endif /* M68K_INT_GT_32_BIT */
424
425
#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R))
426
#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
427
#define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24)
428
429
#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D))
430
#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
431
#define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24)
432
433
#define NFLAG_8(A) (A)
434
#define NFLAG_16(A) ((A)>>8)
435
#define NFLAG_32(A) ((A)>>24)
436
#define NFLAG_64(A) ((A)>>56)
437
438
#define ZFLAG_8(A) MASK_OUT_ABOVE_8(A)
439
#define ZFLAG_16(A) MASK_OUT_ABOVE_16(A)
440
#define ZFLAG_32(A) MASK_OUT_ABOVE_32(A)
441
442
443
/* Flag values */
444
#define NFLAG_SET 0x80
445
#define NFLAG_CLEAR 0
446
#define CFLAG_SET 0x100
447
#define CFLAG_CLEAR 0
448
#define XFLAG_SET 0x100
449
#define XFLAG_CLEAR 0
450
#define VFLAG_SET 0x80
451
#define VFLAG_CLEAR 0
452
#define ZFLAG_SET 0
453
#define ZFLAG_CLEAR 0xffffffff
454
#define SFLAG_SET 4
455
#define SFLAG_CLEAR 0
456
457
/* Turn flag values into 1 or 0 */
458
#define XFLAG_AS_1() ((FLAG_X>>8)&1)
459
#define NFLAG_AS_1() ((FLAG_N>>7)&1)
460
#define VFLAG_AS_1() ((FLAG_V>>7)&1)
461
#define ZFLAG_AS_1() (!FLAG_Z)
462
#define CFLAG_AS_1() ((FLAG_C>>8)&1)
463
464
465
/* Conditions */
466
#define COND_CS() (FLAG_C&0x100)
467
#define COND_CC() (!COND_CS())
468
#define COND_VS() (FLAG_V&0x80)
469
#define COND_VC() (!COND_VS())
470
#define COND_NE() FLAG_Z
471
#define COND_EQ() (!COND_NE())
472
#define COND_MI() (FLAG_N&0x80)
473
#define COND_PL() (!COND_MI())
474
#define COND_LT() ((FLAG_N^FLAG_V)&0x80)
475
#define COND_GE() (!COND_LT())
476
#define COND_HI() (COND_CC() && COND_NE())
477
#define COND_LS() (COND_CS() || COND_EQ())
478
#define COND_GT() (COND_GE() && COND_NE())
479
#define COND_LE() (COND_LT() || COND_EQ())
480
481
/* Reversed conditions */
482
#define COND_NOT_CS() COND_CC()
483
#define COND_NOT_CC() COND_CS()
484
#define COND_NOT_VS() COND_VC()
485
#define COND_NOT_VC() COND_VS()
486
#define COND_NOT_NE() COND_EQ()
487
#define COND_NOT_EQ() COND_NE()
488
#define COND_NOT_MI() COND_PL()
489
#define COND_NOT_PL() COND_MI()
490
#define COND_NOT_LT() COND_GE()
491
#define COND_NOT_GE() COND_LT()
492
#define COND_NOT_HI() COND_LS()
493
#define COND_NOT_LS() COND_HI()
494
#define COND_NOT_GT() COND_LE()
495
#define COND_NOT_LE() COND_GT()
496
497
/* Not real conditions, but here for convenience */
498
#define COND_XS() (FLAG_X&0x100)
499
#define COND_XC() (!COND_XS)
500
501
502
/* Get the condition code register */
503
#define m68ki_get_ccr() ((COND_XS() >> 4) | \
504
(COND_MI() >> 4) | \
505
(COND_EQ() << 2) | \
506
(COND_VS() >> 6) | \
507
(COND_CS() >> 8))
508
509
/* Get the status register */
510
#define m68ki_get_sr() ( FLAG_T1 | \
511
(FLAG_S << 11) | \
512
FLAG_INT_MASK | \
513
m68ki_get_ccr())
514
515
516
517
/* ---------------------------- Cycle Counting ---------------------------- */
518
519
#define USE_CYCLES(A) m68ki_cpu.cycles += (A)
520
#define SET_CYCLES(A) m68ki_cpu.cycles = (A)
521
522
523
/* ----------------------------- Read / Write ----------------------------- */
524
525
/* Read data immediately following the PC */
526
#define m68k_read_immediate_16(address) *(uint16 *)(m68ki_cpu.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff))
527
#define m68k_read_immediate_32(address) (m68k_read_immediate_16(address) << 16) | (m68k_read_immediate_16(address+2))
528
529
/* Read data relative to the PC */
530
#define m68k_read_pcrelative_8(address) READ_BYTE(m68ki_cpu.memory_map[((address)>>16)&0xff].base, (address) & 0xffff)
531
#define m68k_read_pcrelative_16(address) m68k_read_immediate_16(address)
532
#define m68k_read_pcrelative_32(address) m68k_read_immediate_32(address)
533
534
/* Read from the current address space */
535
#define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space())
536
#define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space())
537
#define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space())
538
539
/* Write to the current data space */
540
#define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
541
#define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
542
#define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V)
543
544
/* map read immediate 8 to read immediate 16 */
545
#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16())
546
547
/* Map PC-relative reads */
548
#define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A)
549
#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A)
550
#define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A)
551
552
/* Read from the program space */
553
#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
554
#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
555
#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM)
556
557
/* Read from the data space */
558
#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
559
#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
560
#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA)
561
562
563
564
/* ======================================================================== */
565
/* =============================== PROTOTYPES ============================= */
566
/* ======================================================================== */
567
568
/* Used by shift & rotate instructions */
569
static const uint8 m68ki_shift_8_table[65] =
570
{
571
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,
572
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
573
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
574
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
575
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
576
0xff, 0xff, 0xff, 0xff, 0xff
577
};
578
579
static const uint16 m68ki_shift_16_table[65] =
580
{
581
0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
582
0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,
583
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
584
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
585
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
586
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
587
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
588
0xffff, 0xffff
589
};
590
591
static const uint m68ki_shift_32_table[65] =
592
{
593
0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
594
0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
595
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
596
0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
597
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
598
0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
599
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
600
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
601
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
602
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
603
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
604
};
605
606
607
/* Number of clock cycles to use for exception processing.
608
* I used 4 for any vectors that are undocumented for processing times.
609
*/
610
static const uint16 m68ki_exception_cycle_table[256] =
611
{
612
40*MUL, /* 0: Reset - Initial Stack Pointer */
613
4*MUL, /* 1: Reset - Initial Program Counter */
614
50*MUL, /* 2: Bus Error (unemulated) */
615
50*MUL, /* 3: Address Error (unemulated) */
616
34*MUL, /* 4: Illegal Instruction */
617
38*MUL, /* 5: Divide by Zero -- ASG: changed from 42 */
618
40*MUL, /* 6: CHK -- ASG: chanaged from 44 */
619
34*MUL, /* 7: TRAPV */
620
34*MUL, /* 8: Privilege Violation */
621
34*MUL, /* 9: Trace */
622
4*MUL, /* 10: 1010 */
623
4*MUL, /* 11: 1111 */
624
4*MUL, /* 12: RESERVED */
625
4*MUL, /* 13: Coprocessor Protocol Violation (unemulated) */
626
4*MUL, /* 14: Format Error */
627
44*MUL, /* 15: Uninitialized Interrupt */
628
4*MUL, /* 16: RESERVED */
629
4*MUL, /* 17: RESERVED */
630
4*MUL, /* 18: RESERVED */
631
4*MUL, /* 19: RESERVED */
632
4*MUL, /* 20: RESERVED */
633
4*MUL, /* 21: RESERVED */
634
4*MUL, /* 22: RESERVED */
635
4*MUL, /* 23: RESERVED */
636
44*MUL, /* 24: Spurious Interrupt */
637
44*MUL, /* 25: Level 1 Interrupt Autovector */
638
44*MUL, /* 26: Level 2 Interrupt Autovector */
639
44*MUL, /* 27: Level 3 Interrupt Autovector */
640
44*MUL, /* 28: Level 4 Interrupt Autovector */
641
44*MUL, /* 29: Level 5 Interrupt Autovector */
642
44*MUL, /* 30: Level 6 Interrupt Autovector */
643
44*MUL, /* 31: Level 7 Interrupt Autovector */
644
34*MUL, /* 32: TRAP #0 -- ASG: chanaged from 38 */
645
34*MUL, /* 33: TRAP #1 */
646
34*MUL, /* 34: TRAP #2 */
647
34*MUL, /* 35: TRAP #3 */
648
34*MUL, /* 36: TRAP #4 */
649
34*MUL, /* 37: TRAP #5 */
650
34*MUL, /* 38: TRAP #6 */
651
34*MUL, /* 39: TRAP #7 */
652
34*MUL, /* 40: TRAP #8 */
653
34*MUL, /* 41: TRAP #9 */
654
34*MUL, /* 42: TRAP #10 */
655
34*MUL, /* 43: TRAP #11 */
656
34*MUL, /* 44: TRAP #12 */
657
34*MUL, /* 45: TRAP #13 */
658
34*MUL, /* 46: TRAP #14 */
659
34*MUL, /* 47: TRAP #15 */
660
4*MUL, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
661
4*MUL, /* 49: FP Inexact Result (unemulated) */
662
4*MUL, /* 50: FP Divide by Zero (unemulated) */
663
4*MUL, /* 51: FP Underflow (unemulated) */
664
4*MUL, /* 52: FP Operand Error (unemulated) */
665
4*MUL, /* 53: FP Overflow (unemulated) */
666
4*MUL, /* 54: FP Signaling NAN (unemulated) */
667
4*MUL, /* 55: FP Unimplemented Data Type (unemulated) */
668
4*MUL, /* 56: MMU Configuration Error (unemulated) */
669
4*MUL, /* 57: MMU Illegal Operation Error (unemulated) */
670
4*MUL, /* 58: MMU Access Level Violation Error (unemulated) */
671
4*MUL, /* 59: RESERVED */
672
4*MUL, /* 60: RESERVED */
673
4*MUL, /* 61: RESERVED */
674
4*MUL, /* 62: RESERVED */
675
4*MUL, /* 63: RESERVED */
676
/* 64-255: User Defined */
677
4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,
678
4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,
679
4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,
680
4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,
681
4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,
682
4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL
683
};
684
685
/* Read data immediately after the program counter */
686
INLINE uint m68ki_read_imm_16(void);
687
INLINE uint m68ki_read_imm_32(void);
688
689
/* Read data with specific function code */
690
INLINE uint m68ki_read_8_fc (uint address, uint fc);
691
INLINE uint m68ki_read_16_fc (uint address, uint fc);
692
INLINE uint m68ki_read_32_fc (uint address, uint fc);
693
694
/* Write data with specific function code */
695
INLINE void m68ki_write_8_fc (uint address, uint fc, uint value);
696
INLINE void m68ki_write_16_fc(uint address, uint fc, uint value);
697
INLINE void m68ki_write_32_fc(uint address, uint fc, uint value);
698
699
/* Indexed and PC-relative ea fetching */
700
INLINE uint m68ki_get_ea_pcdi(void);
701
INLINE uint m68ki_get_ea_pcix(void);
702
INLINE uint m68ki_get_ea_ix(uint An);
703
704
/* Operand fetching */
705
INLINE uint OPER_AY_AI_8(void);
706
INLINE uint OPER_AY_AI_16(void);
707
INLINE uint OPER_AY_AI_32(void);
708
INLINE uint OPER_AY_PI_8(void);
709
INLINE uint OPER_AY_PI_16(void);
710
INLINE uint OPER_AY_PI_32(void);
711
INLINE uint OPER_AY_PD_8(void);
712
INLINE uint OPER_AY_PD_16(void);
713
INLINE uint OPER_AY_PD_32(void);
714
INLINE uint OPER_AY_DI_8(void);
715
INLINE uint OPER_AY_DI_16(void);
716
INLINE uint OPER_AY_DI_32(void);
717
INLINE uint OPER_AY_IX_8(void);
718
INLINE uint OPER_AY_IX_16(void);
719
INLINE uint OPER_AY_IX_32(void);
720
721
INLINE uint OPER_AX_AI_8(void);
722
INLINE uint OPER_AX_AI_16(void);
723
INLINE uint OPER_AX_AI_32(void);
724
INLINE uint OPER_AX_PI_8(void);
725
INLINE uint OPER_AX_PI_16(void);
726
INLINE uint OPER_AX_PI_32(void);
727
INLINE uint OPER_AX_PD_8(void);
728
INLINE uint OPER_AX_PD_16(void);
729
INLINE uint OPER_AX_PD_32(void);
730
INLINE uint OPER_AX_DI_8(void);
731
INLINE uint OPER_AX_DI_16(void);
732
INLINE uint OPER_AX_DI_32(void);
733
INLINE uint OPER_AX_IX_8(void);
734
INLINE uint OPER_AX_IX_16(void);
735
INLINE uint OPER_AX_IX_32(void);
736
737
INLINE uint OPER_A7_PI_8(void);
738
INLINE uint OPER_A7_PD_8(void);
739
740
INLINE uint OPER_AW_8(void);
741
INLINE uint OPER_AW_16(void);
742
INLINE uint OPER_AW_32(void);
743
INLINE uint OPER_AL_8(void);
744
INLINE uint OPER_AL_16(void);
745
INLINE uint OPER_AL_32(void);
746
INLINE uint OPER_PCDI_8(void);
747
INLINE uint OPER_PCDI_16(void);
748
INLINE uint OPER_PCDI_32(void);
749
INLINE uint OPER_PCIX_8(void);
750
INLINE uint OPER_PCIX_16(void);
751
INLINE uint OPER_PCIX_32(void);
752
753
/* Stack operations */
754
INLINE void m68ki_push_16(uint value);
755
INLINE void m68ki_push_32(uint value);
756
INLINE uint m68ki_pull_16(void);
757
INLINE uint m68ki_pull_32(void);
758
759
/* Program flow operations */
760
INLINE void m68ki_jump(uint new_pc);
761
INLINE void m68ki_jump_vector(uint vector);
762
INLINE void m68ki_branch_8(uint offset);
763
INLINE void m68ki_branch_16(uint offset);
764
INLINE void m68ki_branch_32(uint offset);
765
766
/* Status register operations. */
767
INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */
768
INLINE void m68ki_set_ccr(uint value); /* set the condition code register */
769
INLINE void m68ki_set_sr(uint value); /* set the status register */
770
771
/* Exception processing */
772
INLINE uint m68ki_init_exception(void); /* Initial exception processing */
773
INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */
774
#if M68K_EMULATE_ADDRESS_ERROR
775
INLINE void m68ki_stack_frame_buserr(uint sr);
776
#endif
777
INLINE void m68ki_exception_trap(uint vector);
778
INLINE void m68ki_exception_trapN(uint vector);
779
#if M68K_EMULATE_TRACE
780
INLINE void m68ki_exception_trace(void);
781
#endif
782
static void m68ki_exception_privilege_violation(void); /* do not inline in order to reduce function size and allow inlining of read/write functions by the compile */
783
INLINE void m68ki_exception_1010(void);
784
INLINE void m68ki_exception_1111(void);
785
INLINE void m68ki_exception_illegal(void);
786
#if M68K_EMULATE_ADDRESS_ERROR
787
INLINE void m68ki_exception_address_error(void);
788
#endif
789
INLINE void m68ki_exception_interrupt(uint int_level);
790
INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */
791
792
/* ======================================================================== */
793
/* =========================== UTILITY FUNCTIONS ========================== */
794
/* ======================================================================== */
795
796
797
/* ---------------------------- Read Immediate ---------------------------- */
798
799
/* Handles all immediate reads, does address error check, function code setting,
800
* and prefetching if they are enabled in m68kconf.h
801
*/
802
INLINE uint m68ki_read_imm_16(void)
803
{
804
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */
805
#if M68K_CHECK_PC_ADDRESS_ERROR
806
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */
807
#endif
808
#if M68K_EMULATE_PREFETCH
809
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
810
{
811
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
812
CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR);
813
}
814
REG_PC += 2;
815
return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3));
816
#else
817
uint pc = REG_PC;
818
REG_PC += 2;
819
return m68k_read_immediate_16(pc);
820
#endif /* M68K_EMULATE_PREFETCH */
821
}
822
823
INLINE uint m68ki_read_imm_32(void)
824
{
825
#if M68K_EMULATE_PREFETCH
826
uint temp_val;
827
828
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */
829
#if M68K_CHECK_PC_ADDRESS_ERROR
830
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */
831
#endif
832
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
833
{
834
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
835
CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR);
836
}
837
temp_val = CPU_PREF_DATA;
838
REG_PC += 2;
839
if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR)
840
{
841
CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC);
842
CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR);
843
temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16));
844
}
845
REG_PC += 2;
846
847
return temp_val;
848
#else
849
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */
850
#if M68K_CHECK_PC_ADDRESS_ERROR
851
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */
852
#endif
853
uint pc = REG_PC;
854
REG_PC += 4;
855
return m68k_read_immediate_32(pc);
856
#endif /* M68K_EMULATE_PREFETCH */
857
}
858
859
860
861
/* ------------------------- Top level read/write ------------------------- */
862
863
/* Handles all memory accesses (except for immediate reads if they are
864
* configured to use separate functions in m68kconf.h).
865
* All memory accesses must go through these top level functions.
866
* These functions will also check for address error and set the function
867
* code if they are enabled in m68kconf.h.
868
*/
869
INLINE uint m68ki_read_8_fc(uint address, uint fc)
870
{
871
cpu_memory_map *temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];;
872
if (biz_readcb)
873
biz_readcb(address);
874
875
if(biz_cdcallback)
876
CDLog68k(address,eCDLog_Flags_Data68k);
877
878
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
879
880
if (temp->read8) return (*temp->read8)(ADDRESS_68K(address));
881
else return READ_BYTE(temp->base, (address) & 0xffff);
882
}
883
884
INLINE uint m68ki_read_16_fc(uint address, uint fc)
885
{
886
cpu_memory_map *temp;
887
if (biz_readcb)
888
biz_readcb(address);
889
890
if(biz_cdcallback)
891
{
892
CDLog68k(address,eCDLog_Flags_Data68k);
893
CDLog68k(address+1,eCDLog_Flags_Data68k);
894
}
895
896
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
897
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
898
899
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
900
if (temp->read16) return (*temp->read16)(ADDRESS_68K(address));
901
else return *(uint16 *)(temp->base + ((address) & 0xffff));
902
}
903
904
INLINE uint m68ki_read_32_fc(uint address, uint fc)
905
{
906
cpu_memory_map *temp;
907
if (biz_readcb)
908
biz_readcb(address);
909
910
if(biz_cdcallback)
911
{
912
CDLog68k(address,eCDLog_Flags_Data68k);
913
CDLog68k(address+1,eCDLog_Flags_Data68k);
914
CDLog68k(address+2,eCDLog_Flags_Data68k);
915
CDLog68k(address+3,eCDLog_Flags_Data68k);
916
}
917
918
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
919
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
920
921
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
922
if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2)));
923
else return m68k_read_immediate_32(address);
924
}
925
926
INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
927
{
928
cpu_memory_map *temp;
929
if (biz_writecb)
930
biz_writecb(address);
931
932
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
933
934
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
935
if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value);
936
else WRITE_BYTE(temp->base, (address) & 0xffff, value);
937
}
938
939
INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
940
{
941
cpu_memory_map *temp;
942
if (biz_writecb)
943
biz_writecb(address);
944
945
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
946
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
947
948
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
949
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value);
950
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value;
951
}
952
953
INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
954
{
955
cpu_memory_map *temp;
956
if (biz_writecb)
957
biz_writecb(address);
958
959
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
960
m68ki_check_address_error(address, MODE_WRITE, fc) /* auto-disable (see m68kcpu.h) */
961
962
temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];
963
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16);
964
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value >> 16;
965
966
temp = &m68ki_cpu.memory_map[((address + 2)>>16)&0xff];
967
if (temp->write16) (*temp->write16)(ADDRESS_68K(address+2),value&0xffff);
968
else *(uint16 *)(temp->base + ((address + 2) & 0xffff)) = value;
969
}
970
971
972
/* --------------------- Effective Address Calculation -------------------- */
973
974
/* The program counter relative addressing modes cause operands to be
975
* retrieved from program space, not data space.
976
*/
977
INLINE uint m68ki_get_ea_pcdi(void)
978
{
979
uint old_pc = REG_PC;
980
m68ki_use_program_space() /* auto-disable */
981
return old_pc + MAKE_INT_16(m68ki_read_imm_16());
982
}
983
984
985
INLINE uint m68ki_get_ea_pcix(void)
986
{
987
m68ki_use_program_space() /* auto-disable */
988
return m68ki_get_ea_ix(REG_PC);
989
}
990
991
/* Indexed addressing modes are encoded as follows:
992
*
993
* Base instruction format:
994
* F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0
995
* x x x x x x x x x x | 1 1 0 | BASE REGISTER (An)
996
*
997
* Base instruction format for destination EA in move instructions:
998
* F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0
999
* x x x x | BASE REG | 1 1 0 | X X X X X X (An)
1000
*
1001
* Brief extension format:
1002
* F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0
1003
* D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT
1004
*
1005
* Full extension format:
1006
* F E D C B A 9 8 7 6 5 4 3 2 1 0
1007
* D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS
1008
* BASE DISPLACEMENT (0, 16, 32 bit) (bd)
1009
* OUTER DISPLACEMENT (0, 16, 32 bit) (od)
1010
*
1011
* D/A: 0 = Dn, 1 = An (Xn)
1012
* W/L: 0 = W (sign extend), 1 = L (.SIZE)
1013
* SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE)
1014
* BS: 0=add base reg, 1=suppress base reg (An suppressed)
1015
* IS: 0=add index, 1=suppress index (Xn suppressed)
1016
* BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd)
1017
*
1018
* IS I/IS Operation
1019
* 0 000 No Memory Indirect
1020
* 0 001 indir prex with null outer
1021
* 0 010 indir prex with word outer
1022
* 0 011 indir prex with long outer
1023
* 0 100 reserved
1024
* 0 101 indir postx with null outer
1025
* 0 110 indir postx with word outer
1026
* 0 111 indir postx with long outer
1027
* 1 000 no memory indirect
1028
* 1 001 mem indir with null outer
1029
* 1 010 mem indir with word outer
1030
* 1 011 mem indir with long outer
1031
* 1 100-111 reserved
1032
*/
1033
INLINE uint m68ki_get_ea_ix(uint An)
1034
{
1035
/* An = base register */
1036
uint extension = m68ki_read_imm_16();
1037
1038
uint Xn = 0; /* Index register */
1039
1040
/* Calculate index */
1041
Xn = REG_DA[extension>>12]; /* Xn */
1042
if(!BIT_B(extension)) /* W/L */
1043
Xn = MAKE_INT_16(Xn);
1044
1045
/* Add base register and displacement and return */
1046
return An + Xn + MAKE_INT_8(extension);
1047
}
1048
1049
1050
/* Fetch operands */
1051
INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); }
1052
INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);}
1053
INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);}
1054
INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); }
1055
INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);}
1056
INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);}
1057
INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); }
1058
INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);}
1059
INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);}
1060
INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); }
1061
INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);}
1062
INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);}
1063
INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); }
1064
INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);}
1065
INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);}
1066
1067
INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); }
1068
INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);}
1069
INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);}
1070
INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); }
1071
INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);}
1072
INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);}
1073
INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); }
1074
INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);}
1075
INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);}
1076
INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); }
1077
INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);}
1078
INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);}
1079
INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); }
1080
INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);}
1081
INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);}
1082
1083
INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); }
1084
INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); }
1085
1086
INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); }
1087
INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);}
1088
INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);}
1089
INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); }
1090
INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);}
1091
INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);}
1092
INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); }
1093
INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);}
1094
INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);}
1095
INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); }
1096
INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);}
1097
INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);}
1098
1099
1100
1101
/* ---------------------------- Stack Functions --------------------------- */
1102
1103
/* Push/pull data from the stack */
1104
/* Optimized access assuming stack is always located in ROM/RAM [EkeEke] */
1105
INLINE void m68ki_push_16(uint value)
1106
{
1107
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1108
/*m68ki_write_16(REG_SP, value);*/
1109
*(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value;
1110
}
1111
1112
INLINE void m68ki_push_32(uint value)
1113
{
1114
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1115
/*m68ki_write_32(REG_SP, value);*/
1116
*(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value >> 16;
1117
*(uint16 *)(m68ki_cpu.memory_map[((REG_SP + 2)>>16)&0xff].base + ((REG_SP + 2) & 0xffff)) = value & 0xffff;
1118
}
1119
1120
INLINE uint m68ki_pull_16(void)
1121
{
1122
uint sp = REG_SP;
1123
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1124
return m68k_read_immediate_16(sp);
1125
/*return m68ki_read_16(sp);*/
1126
}
1127
1128
INLINE uint m68ki_pull_32(void)
1129
{
1130
uint sp = REG_SP;
1131
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1132
return m68k_read_immediate_32(sp);
1133
/*return m68ki_read_32(sp);*/
1134
}
1135
1136
1137
1138
/* ----------------------------- Program Flow ----------------------------- */
1139
1140
/* Jump to a new program location or vector.
1141
* These functions will also call the pc_changed callback if it was enabled
1142
* in m68kconf.h.
1143
*/
1144
INLINE void m68ki_jump(uint new_pc)
1145
{
1146
REG_PC = new_pc;
1147
}
1148
1149
INLINE void m68ki_jump_vector(uint vector)
1150
{
1151
REG_PC = m68ki_read_data_32(vector<<2);
1152
}
1153
1154
1155
/* Branch to a new memory location.
1156
* The 32-bit branch will call pc_changed if it was enabled in m68kconf.h.
1157
* So far I've found no problems with not calling pc_changed for 8 or 16
1158
* bit branches.
1159
*/
1160
INLINE void m68ki_branch_8(uint offset)
1161
{
1162
REG_PC += MAKE_INT_8(offset);
1163
}
1164
1165
INLINE void m68ki_branch_16(uint offset)
1166
{
1167
REG_PC += MAKE_INT_16(offset);
1168
}
1169
1170
INLINE void m68ki_branch_32(uint offset)
1171
{
1172
REG_PC += offset;
1173
}
1174
1175
1176
1177
/* ---------------------------- Status Register --------------------------- */
1178
1179
/* Set the S flag and change the active stack pointer.
1180
* Note that value MUST be 4 or 0.
1181
*/
1182
INLINE void m68ki_set_s_flag(uint value)
1183
{
1184
/* Backup the old stack pointer */
1185
REG_SP_BASE[FLAG_S] = REG_SP;
1186
/* Set the S flag */
1187
FLAG_S = value;
1188
/* Set the new stack pointer */
1189
REG_SP = REG_SP_BASE[FLAG_S];
1190
}
1191
1192
1193
/* Set the condition code register */
1194
INLINE void m68ki_set_ccr(uint value)
1195
{
1196
FLAG_X = BIT_4(value) << 4;
1197
FLAG_N = BIT_3(value) << 4;
1198
FLAG_Z = !BIT_2(value);
1199
FLAG_V = BIT_1(value) << 6;
1200
FLAG_C = BIT_0(value) << 8;
1201
}
1202
1203
1204
/* Set the status register and check for interrupts */
1205
INLINE void m68ki_set_sr(uint value)
1206
{
1207
/* Set the status register */
1208
FLAG_T1 = BIT_F(value);
1209
FLAG_INT_MASK = value & 0x0700;
1210
m68ki_set_ccr(value);
1211
m68ki_set_s_flag((value >> 11) & 4);
1212
1213
/* Check current IRQ status */
1214
m68ki_check_interrupts();
1215
}
1216
1217
1218
/* ------------------------- Exception Processing ------------------------- */
1219
1220
/* Initiate exception processing */
1221
INLINE uint m68ki_init_exception(void)
1222
{
1223
/* Save the old status register */
1224
uint sr = m68ki_get_sr();
1225
1226
/* Turn off trace flag, clear pending traces */
1227
FLAG_T1 = 0;
1228
m68ki_clear_trace()
1229
1230
/* Enter supervisor mode */
1231
m68ki_set_s_flag(SFLAG_SET);
1232
1233
return sr;
1234
}
1235
1236
/* 3 word stack frame (68000 only) */
1237
INLINE void m68ki_stack_frame_3word(uint pc, uint sr)
1238
{
1239
m68ki_push_32(pc);
1240
m68ki_push_16(sr);
1241
}
1242
1243
#if M68K_EMULATE_ADDRESS_ERROR
1244
/* Bus error stack frame (68000 only).
1245
*/
1246
INLINE void m68ki_stack_frame_buserr(uint sr)
1247
{
1248
m68ki_push_32(REG_PC);
1249
m68ki_push_16(sr);
1250
m68ki_push_16(REG_IR);
1251
m68ki_push_32(m68ki_cpu.aerr_address); /* access address */
1252
/* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC
1253
* R/W 0 = write, 1 = read
1254
* I/N 0 = instruction, 1 = not
1255
* FC 3-bit function code
1256
*/
1257
m68ki_push_16(m68ki_cpu.aerr_write_mode | CPU_INSTR_MODE | m68ki_cpu.aerr_fc);
1258
}
1259
#endif
1260
1261
/* Used for Group 2 exceptions.
1262
*/
1263
INLINE void m68ki_exception_trap(uint vector)
1264
{
1265
uint sr = m68ki_init_exception();
1266
1267
m68ki_stack_frame_3word(REG_PC, sr);
1268
1269
m68ki_jump_vector(vector);
1270
1271
/* Use up some clock cycles */
1272
USE_CYCLES(CYC_EXCEPTION[vector]);
1273
}
1274
1275
/* Trap#n stacks a 0 frame but behaves like group2 otherwise */
1276
INLINE void m68ki_exception_trapN(uint vector)
1277
{
1278
uint sr = m68ki_init_exception();
1279
m68ki_stack_frame_3word(REG_PC, sr);
1280
m68ki_jump_vector(vector);
1281
1282
/* Use up some clock cycles */
1283
USE_CYCLES(CYC_EXCEPTION[vector]);
1284
}
1285
1286
#if M68K_EMULATE_TRACE
1287
/* Exception for trace mode */
1288
INLINE void m68ki_exception_trace(void)
1289
{
1290
uint sr = m68ki_init_exception();
1291
1292
#if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
1293
CPU_INSTR_MODE = INSTRUCTION_NO;
1294
#endif /* M68K_EMULATE_ADDRESS_ERROR */
1295
1296
m68ki_stack_frame_3word(REG_PC, sr);
1297
m68ki_jump_vector(EXCEPTION_TRACE);
1298
1299
/* Trace nullifies a STOP instruction */
1300
CPU_STOPPED &= ~STOP_LEVEL_STOP;
1301
1302
/* Use up some clock cycles */
1303
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]);
1304
}
1305
#endif
1306
1307
/* Exception for privilege violation */
1308
static void m68ki_exception_privilege_violation(void)
1309
{
1310
uint sr = m68ki_init_exception();
1311
1312
#if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
1313
CPU_INSTR_MODE = INSTRUCTION_NO;
1314
#endif /* M68K_EMULATE_ADDRESS_ERROR */
1315
1316
m68ki_stack_frame_3word(REG_PC-2, sr);
1317
m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION);
1318
1319
/* Use up some clock cycles and undo the instruction's cycles */
1320
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]);
1321
}
1322
1323
/* Exception for A-Line instructions */
1324
INLINE void m68ki_exception_1010(void)
1325
{
1326
uint sr = m68ki_init_exception();
1327
m68ki_stack_frame_3word(REG_PC-2, sr);
1328
m68ki_jump_vector(EXCEPTION_1010);
1329
1330
/* Use up some clock cycles and undo the instruction's cycles */
1331
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]);
1332
}
1333
1334
/* Exception for F-Line instructions */
1335
INLINE void m68ki_exception_1111(void)
1336
{
1337
uint sr = m68ki_init_exception();
1338
m68ki_stack_frame_3word(REG_PC-2, sr);
1339
m68ki_jump_vector(EXCEPTION_1111);
1340
1341
/* Use up some clock cycles and undo the instruction's cycles */
1342
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]);
1343
}
1344
1345
/* Exception for illegal instructions */
1346
INLINE void m68ki_exception_illegal(void)
1347
{
1348
uint sr = m68ki_init_exception();
1349
1350
#if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
1351
CPU_INSTR_MODE = INSTRUCTION_NO;
1352
#endif /* M68K_EMULATE_ADDRESS_ERROR */
1353
1354
m68ki_stack_frame_3word(REG_PC-2, sr);
1355
m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION);
1356
1357
/* Use up some clock cycles and undo the instruction's cycles */
1358
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]);
1359
}
1360
1361
1362
#if M68K_EMULATE_ADDRESS_ERROR
1363
/* Exception for address error */
1364
INLINE void m68ki_exception_address_error(void)
1365
{
1366
uint sr = m68ki_init_exception();
1367
1368
/* If we were processing a bus error, address error, or reset,
1369
* this is a catastrophic failure.
1370
* Halt the CPU
1371
*/
1372
if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET)
1373
{
1374
CPU_STOPPED = STOP_LEVEL_HALT;
1375
SET_CYCLES(m68ki_cpu.cycle_end - CYC_INSTRUCTION[REG_IR]);
1376
return;
1377
}
1378
CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
1379
1380
/* Note: This is implemented for 68000 only! */
1381
m68ki_stack_frame_buserr(sr);
1382
1383
m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR);
1384
1385
/* Use up some clock cycles and undo the instruction's cycles */
1386
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR] - CYC_INSTRUCTION[REG_IR]);
1387
}
1388
#endif
1389
1390
/* Service an interrupt request and start exception processing */
1391
INLINE void m68ki_exception_interrupt(uint int_level)
1392
{
1393
uint vector, sr, new_pc;
1394
1395
#if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
1396
CPU_INSTR_MODE = INSTRUCTION_NO;
1397
#endif /* M68K_EMULATE_ADDRESS_ERROR */
1398
1399
/* Turn off the stopped state */
1400
CPU_STOPPED &= STOP_LEVEL_HALT;
1401
1402
/* If we are halted, don't do anything */
1403
if(CPU_STOPPED)
1404
return;
1405
1406
/* Always use the autovectors. */
1407
vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
1408
1409
/* Start exception processing */
1410
sr = m68ki_init_exception();
1411
1412
/* Set the interrupt mask to the level of the one being serviced */
1413
FLAG_INT_MASK = int_level<<8;
1414
1415
/* Acknowledge the interrupt */
1416
m68ki_int_ack(int_level);
1417
1418
/* Get the new PC */
1419
new_pc = m68ki_read_data_32(vector<<2);
1420
1421
/* If vector is uninitialized, call the uninitialized interrupt vector */
1422
if(new_pc == 0)
1423
new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2));
1424
1425
/* Generate a stack frame */
1426
m68ki_stack_frame_3word(REG_PC, sr);
1427
1428
m68ki_jump(new_pc);
1429
1430
/* Update cycle count now */
1431
USE_CYCLES(CYC_EXCEPTION[vector]);
1432
}
1433
1434
/* ASG: Check for interrupts */
1435
INLINE void m68ki_check_interrupts(void)
1436
{
1437
if(CPU_INT_LEVEL > FLAG_INT_MASK)
1438
m68ki_exception_interrupt(CPU_INT_LEVEL>>8);
1439
}
1440
1441
1442
/* ======================================================================== */
1443
/* ============================== END OF FILE ============================= */
1444
/* ======================================================================== */
1445
1446
#endif /* M68KCPU__HEADER */
1447
1448