~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/emu/cpu/m68000/m68kcpu.h

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ======================================================================== */
2
 
/* ========================= LICENSING & COPYRIGHT ======================== */
3
 
/* ======================================================================== */
4
 
/*
5
 
 *                                  MUSASHI
6
 
 *                                Version 4.50
7
 
 *
8
 
 * A portable Motorola M680x0 processor emulation engine.
9
 
 * Copyright Karl Stenerud.  All rights reserved.
10
 
 *
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.
14
 
 *
15
 
 * All other licensing terms must be negotiated with the author
16
 
 * (Karl Stenerud).
17
 
 *
18
 
 * The latest version of this code can be obtained at:
19
 
 * http://kstenerud.cjb.net
20
 
 */
21
 
 
22
 
 
23
 
#pragma once
24
 
 
25
 
#ifndef __M68KCPU_H__
26
 
#define __M68KCPU_H__
27
 
 
28
 
typedef struct _m68ki_cpu_core m68ki_cpu_core;
29
 
 
30
 
 
31
 
#include "m68000.h"
32
 
#include "../../../lib/softfloat/milieu.h"
33
 
#include "../../../lib/softfloat/softfloat.h"
34
 
 
35
 
#include <limits.h>
36
 
#include <setjmp.h>
37
 
 
38
 
/* ======================================================================== */
39
 
/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
40
 
/* ======================================================================== */
41
 
 
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)
46
 
 
47
 
 
48
 
/* ======================================================================== */
49
 
/* ============================ GENERAL DEFINES =========================== */
50
 
/* ======================================================================== */
51
 
 
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
69
 
 
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
76
 
 
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)
89
 
 
90
 
/* Different ways to stop the CPU */
91
 
#define STOP_LEVEL_STOP 1
92
 
#define STOP_LEVEL_HALT 2
93
 
 
94
 
/* Used for 68000 address error processing */
95
 
#define INSTRUCTION_YES 0
96
 
#define INSTRUCTION_NO  0x08
97
 
#define MODE_READ       0x10
98
 
#define MODE_WRITE      0
99
 
 
100
 
#define RUN_MODE_NORMAL          0
101
 
#define RUN_MODE_BERR_AERR_RESET 1
102
 
 
103
 
/* MMU constants */
104
 
#define MMU_ATC_ENTRIES (22)    // 68851 has 64, 030 has 22
105
 
 
106
 
/* instruction cache constants */
107
 
#define M68K_IC_SIZE 128
108
 
 
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
114
 
 
115
 
/* ======================================================================== */
116
 
/* ================================ MACROS ================================ */
117
 
/* ======================================================================== */
118
 
 
119
 
 
120
 
/* ---------------------------- General Macros ---------------------------- */
121
 
 
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)
155
 
 
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))
163
 
 
164
 
/* Isolate nibbles */
165
 
#define LOW_NIBBLE(A)  ((A) & 0x0f)
166
 
#define HIGH_NIBBLE(A) ((A) & 0xf0)
167
 
 
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)
175
 
 
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))
179
 
 
180
 
/* Shift & Rotate Macros. */
181
 
#define LSL(A, C) ((A) << (C))
182
 
#define LSR(A, C) ((A) >> (C))
183
 
 
184
 
/* We have to do this because the morons at ANSI decided that shifts
185
 
* by >= data size are undefined.
186
 
*/
187
 
#define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0)
188
 
#define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0)
189
 
 
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)))
194
 
 
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)))
201
 
 
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)))
208
 
 
209
 
 
210
 
 
211
 
/* ------------------------------ CPU Access ------------------------------ */
212
 
 
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]
224
 
 
225
 
#define REG_FP           m68k->fpr
226
 
#define REG_FPCR         m68k->fpcr
227
 
#define REG_FPSR         m68k->fpsr
228
 
#define REG_FPIAR        m68k->fpiar
229
 
 
230
 
 
231
 
/* ----------------------------- Configuration ---------------------------- */
232
 
 
233
 
/* These defines are dependant on the configuration defines in m68kconf.h */
234
 
 
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
238
 
 
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
241
 
 
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
244
 
 
245
 
#define CPU_TYPE_IS_020_VARIANT(A) ((A) & (CPU_TYPE_EC020 | CPU_TYPE_020))
246
 
 
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))
249
 
 
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))
253
 
 
254
 
#define CPU_TYPE_IS_000(A)         ((A) == CPU_TYPE_000 || (A) == CPU_TYPE_008)
255
 
 
256
 
 
257
 
/* Configuration switches (see m68kconf.h for explanation) */
258
 
#define M68K_EMULATE_TRACE          0
259
 
 
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)
270
 
#else
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 */
276
 
 
277
 
 
278
 
 
279
 
/* Address error */
280
 
/* sigjmp() on Mac OS X and *BSD in general saves signal contexts and is super-slow, use sigsetjmp() to tell it not to */
281
 
#ifdef _BSD_SETJMP_H
282
 
#define m68ki_set_address_error_trap(m68k) \
283
 
        if(sigsetjmp(m68k->aerr_trap, 0) != 0) \
284
 
        { \
285
 
                m68ki_exception_address_error(m68k); \
286
 
                if(m68k->stopped) \
287
 
                { \
288
 
                        if (m68k->remaining_cycles > 0) \
289
 
                                m68k->remaining_cycles = 0; \
290
 
                        return; \
291
 
                } \
292
 
        }
293
 
 
294
 
#define m68ki_check_address_error(m68k, ADDR, WRITE_MODE, FC) \
295
 
        if((ADDR)&1) \
296
 
        { \
297
 
                m68k->aerr_address = ADDR; \
298
 
                m68k->aerr_write_mode = WRITE_MODE; \
299
 
                m68k->aerr_fc = FC; \
300
 
                siglongjmp(m68k->aerr_trap, 1); \
301
 
        }
302
 
#else
303
 
#define m68ki_set_address_error_trap(m68k) \
304
 
        if(setjmp(m68k->aerr_trap) != 0) \
305
 
        { \
306
 
                m68ki_exception_address_error(m68k); \
307
 
                if(m68k->stopped) \
308
 
                { \
309
 
                        if (m68k->remaining_cycles > 0) \
310
 
                                m68k->remaining_cycles = 0; \
311
 
                        return; \
312
 
                } \
313
 
        }
314
 
 
315
 
#define m68ki_check_address_error(m68k, ADDR, WRITE_MODE, FC) \
316
 
        if((ADDR)&1) \
317
 
        { \
318
 
                m68k->aerr_address = ADDR; \
319
 
                m68k->aerr_write_mode = WRITE_MODE; \
320
 
                m68k->aerr_fc = FC; \
321
 
                longjmp(m68k->aerr_trap, 1); \
322
 
        }
323
 
#endif
324
 
 
325
 
 
326
 
/* -------------------------- EA / Operand Access ------------------------- */
327
 
 
328
 
/*
329
 
 * The general instruction format follows this pattern:
330
 
 * .... XXX. .... .YYY
331
 
 * where XXX is register X and YYY is register Y
332
 
 */
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])
339
 
 
340
 
 
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)
357
 
 
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)
373
 
 
374
 
#define EA_A7_PI_8(m68k)   ((REG_A[7]+=2)-2)
375
 
#define EA_A7_PD_8(m68k)   (REG_A[7]-=2)
376
 
 
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)
389
 
 
390
 
 
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)
394
 
 
395
 
 
396
 
 
397
 
/* --------------------------- Status Register ---------------------------- */
398
 
 
399
 
/* Flag Calculation Macros */
400
 
#define CFLAG_8(A) (A)
401
 
#define CFLAG_16(A) ((A)>>8)
402
 
 
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)
405
 
 
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)
409
 
 
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)
413
 
 
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)
418
 
 
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)
422
 
 
423
 
 
424
 
/* Flag values */
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
433
 
#define ZFLAG_SET   0
434
 
#define ZFLAG_CLEAR 0xffffffff
435
 
 
436
 
#define SFLAG_SET   4
437
 
#define SFLAG_CLEAR 0
438
 
#define MFLAG_SET   2
439
 
#define MFLAG_CLEAR 0
440
 
 
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)
447
 
 
448
 
 
449
 
/* Conditions */
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))
464
 
 
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)
480
 
 
481
 
/* Not real conditions, but here for convenience */
482
 
#define COND_XS(M) ((M)->x_flag&0x100)
483
 
#define COND_XC(M) (!COND_XS)
484
 
 
485
 
 
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) | \
491
 
                                                     (COND_CS(M) >> 8))
492
 
 
493
 
/* Get the status register */
494
 
#define m68ki_get_sr(M)         ((M)->t1_flag         | \
495
 
                                                     (M)->t0_flag         | \
496
 
                                                    ((M)->s_flag   << 11) | \
497
 
                                                    ((M)->m_flag   << 11) | \
498
 
                                                     (M)->int_mask        | \
499
 
                                                     m68ki_get_ccr(M))
500
 
 
501
 
 
502
 
 
503
 
/* ----------------------------- Read / Write ----------------------------- */
504
 
 
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)
509
 
 
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)
515
 
 
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))
518
 
 
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)
523
 
 
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)
528
 
 
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)
533
 
 
534
 
 
535
 
 
536
 
/* ======================================================================== */
537
 
/* =============================== PROTOTYPES ============================= */
538
 
/* ======================================================================== */
539
 
 
540
 
typedef union _fp_reg fp_reg;
541
 
union _fp_reg
542
 
{
543
 
        UINT64 i;
544
 
        double f;
545
 
};
546
 
 
547
 
/* Redirect memory calls */
548
 
 
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;
556
 
 
557
 
class m68k_memory_interface
558
 
{
559
 
public:
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);
565
 
 
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;
574
 
 
575
 
private:
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);
579
 
 
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);
587
 
 
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);
595
 
 
596
 
        address_space *m_space;
597
 
        direct_read_data *m_direct;
598
 
        m68ki_cpu_core *m_cpustate;
599
 
};
600
 
 
601
 
struct _m68ki_cpu_core
602
 
{
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 */
642
 
 
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;
649
 
        UINT32 cyc_movem_w;
650
 
        UINT32 cyc_movem_l;
651
 
        UINT32 cyc_shift;
652
 
        UINT32 cyc_reset;
653
 
 
654
 
        int  initial_cycles;
655
 
        int  remaining_cycles;                     /* Number of clocks remaining */
656
 
        int  reset_cycles;
657
 
        UINT32 tracing;
658
 
 
659
 
#ifdef _BSD_SETJMP_H
660
 
        sigjmp_buf aerr_trap;
661
 
#else
662
 
        jmp_buf aerr_trap;
663
 
#endif
664
 
        UINT32    aerr_address;
665
 
        UINT32    aerr_write_mode;
666
 
        UINT32    aerr_fc;
667
 
 
668
 
        /* Virtual IRQ lines state */
669
 
        UINT32 virq_state;
670
 
        UINT32 nmi_pending;
671
 
 
672
 
        const UINT8* cyc_instruction;
673
 
        const UINT8* cyc_exception;
674
 
 
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 */
682
 
 
683
 
        legacy_cpu_device *device;
684
 
        address_space *program;
685
 
        m68k_memory_interface memory;
686
 
        offs_t encrypted_start;
687
 
        offs_t encrypted_end;
688
 
 
689
 
        UINT32          iotemp;
690
 
 
691
 
        /* save state data */
692
 
        UINT16 save_sr;
693
 
        UINT8 save_stopped;
694
 
        UINT8 save_halted;
695
 
 
696
 
        /* PMMU registers */
697
 
        UINT32 mmu_crp_aptr, mmu_crp_limit;
698
 
        UINT32 mmu_srp_aptr, mmu_srp_limit;
699
 
        UINT32 mmu_tc;
700
 
        UINT16 mmu_sr;
701
 
        UINT32 mmu_atc_tag[MMU_ATC_ENTRIES], mmu_atc_data[MMU_ATC_ENTRIES];
702
 
        UINT32 mmu_atc_rr;
703
 
        UINT32 mmu_tt0, mmu_tt1;
704
 
 
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 */
710
 
 
711
 
        UINT32 ic_address[M68K_IC_SIZE];   /* instruction cache address data */
712
 
        UINT16 ic_data[M68K_IC_SIZE];      /* instruction cache content data */
713
 
 
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;
717
 
};
718
 
 
719
 
 
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[];
725
 
 
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);
729
 
 
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);
734
 
 
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);
740
 
 
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);
745
 
 
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);
762
 
 
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);
778
 
 
779
 
INLINE UINT32 OPER_A7_PI_8(m68ki_cpu_core *m68k);
780
 
INLINE UINT32 OPER_A7_PD_8(m68ki_cpu_core *m68k);
781
 
 
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);
794
 
 
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);
800
 
 
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);
807
 
 
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 */
814
 
 
815
 
/* Exception processing */
816
 
INLINE UINT32 m68ki_init_exception(m68ki_cpu_core *m68k);              /* Initial exception processing */
817
 
 
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);
820
 
 
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);
827
 
 
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 */
839
 
 
840
 
/* quick disassembly (used for logging) */
841
 
char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type);
842
 
 
843
 
 
844
 
/* ======================================================================== */
845
 
/* =========================== UTILITY FUNCTIONS ========================== */
846
 
/* ======================================================================== */
847
 
 
848
 
 
849
 
INLINE unsigned int m68k_read_immediate_32(m68ki_cpu_core *m68k, unsigned int address)
850
 
{
851
 
        return (m68k->memory.readimm16(address) << 16) | m68k->memory.readimm16(address + 2);
852
 
}
853
 
 
854
 
INLINE unsigned int m68k_read_pcrelative_8(m68ki_cpu_core *m68k, unsigned int address)
855
 
{
856
 
        if (address >= m68k->encrypted_start && address < m68k->encrypted_end)
857
 
                return ((m68k->memory.readimm16(address&~1)>>(8*(1-(address & 1))))&0xff);
858
 
 
859
 
        return m68k->memory.read8(address);
860
 
}
861
 
 
862
 
INLINE unsigned int m68k_read_pcrelative_16(m68ki_cpu_core *m68k, unsigned int address)
863
 
{
864
 
        if (address >= m68k->encrypted_start && address < m68k->encrypted_end)
865
 
                return m68k->memory.readimm16(address);
866
 
 
867
 
        return m68k->memory.read16(address);
868
 
}
869
 
 
870
 
INLINE unsigned int m68k_read_pcrelative_32(m68ki_cpu_core *m68k, unsigned int address)
871
 
{
872
 
        if (address >= m68k->encrypted_start && address < m68k->encrypted_end)
873
 
                return m68k_read_immediate_32(m68k, address);
874
 
 
875
 
        return m68k->memory.read32(address);
876
 
}
877
 
 
878
 
 
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].
883
 
 */
884
 
INLINE void m68kx_write_memory_32_pd(m68ki_cpu_core *m68k, unsigned int address, unsigned int value)
885
 
{
886
 
        m68k->memory.write16(address+2, value>>16);
887
 
        m68k->memory.write16(address, value&0xffff);
888
 
}
889
 
 
890
 
 
891
 
/* ---------------------------- Read Immediate ---------------------------- */
892
 
 
893
 
// clear the instruction cache
894
 
INLINE void m68ki_ic_clear(m68ki_cpu_core *m68k)
895
 
{
896
 
        int i;
897
 
        for (i=0; i< M68K_IC_SIZE; i++) {
898
 
                m68k->ic_address[i] = ~0;
899
 
        }
900
 
}
901
 
 
902
 
// read immediate word using the instruction cache
903
 
 
904
 
INLINE UINT32 m68ki_ic_readimm16(m68ki_cpu_core *m68k, UINT32 address)
905
 
{
906
 
        if(CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type) && (m68k->cacr & M68K_CACR_EI))
907
 
        {
908
 
                UINT32 ic_offset = (address >> 1) % M68K_IC_SIZE;
909
 
                if (m68k->ic_address[ic_offset] == address)
910
 
                {
911
 
                        return m68k->ic_data[ic_offset];
912
 
                }
913
 
                else
914
 
                {
915
 
                        UINT32 data = m68k->memory.readimm16(address);
916
 
                        if (!m68k->mmu_tmp_buserror_occurred)
917
 
                        {
918
 
                                m68k->ic_data[ic_offset] = data;
919
 
                                m68k->ic_address[ic_offset] = address;
920
 
                        }
921
 
                        return data;
922
 
                }
923
 
        }
924
 
        else
925
 
        {
926
 
                return m68k->memory.readimm16(address);
927
 
        }
928
 
 
929
 
        // this can't happen, but Apple GCC insists
930
 
        return 0;
931
 
}
932
 
 
933
 
/* Handles all immediate reads, does address error check, function code setting,
934
 
 * and prefetching if they are enabled in m68kconf.h
935
 
 */
936
 
INLINE UINT32 m68ki_read_imm_16(m68ki_cpu_core *m68k)
937
 
{
938
 
        UINT32 result;
939
 
 
940
 
        m68k->mmu_tmp_fc = m68k->s_flag | FUNCTION_CODE_USER_PROGRAM;
941
 
        m68k->mmu_tmp_rw = 1;
942
 
 
943
 
        m68ki_check_address_error(m68k, REG_PC, MODE_READ, m68k->s_flag | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
944
 
 
945
 
        if(REG_PC != m68k->pref_addr)
946
 
        {
947
 
                m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
948
 
                m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
949
 
        }
950
 
        result = MASK_OUT_ABOVE_16(m68k->pref_data);
951
 
        REG_PC += 2;
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;
958
 
        }
959
 
 
960
 
        return result;
961
 
}
962
 
 
963
 
INLINE UINT32 m68ki_read_imm_32(m68ki_cpu_core *m68k)
964
 
{
965
 
        UINT32 temp_val;
966
 
 
967
 
        m68k->mmu_tmp_fc = m68k->s_flag | FUNCTION_CODE_USER_PROGRAM;
968
 
        m68k->mmu_tmp_rw = 1;
969
 
 
970
 
        m68ki_check_address_error(m68k, REG_PC, MODE_READ, m68k->s_flag | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
971
 
 
972
 
        if(REG_PC != m68k->pref_addr)
973
 
        {
974
 
                m68k->pref_addr = REG_PC;
975
 
                m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr);
976
 
        }
977
 
        temp_val = MASK_OUT_ABOVE_16(m68k->pref_data);
978
 
        REG_PC += 2;
979
 
        m68k->pref_addr = REG_PC;
980
 
        m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr);
981
 
 
982
 
        temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(m68k->pref_data));
983
 
        REG_PC += 2;
984
 
        m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
985
 
        m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
986
 
 
987
 
        return temp_val;
988
 
}
989
 
 
990
 
 
991
 
 
992
 
/* ------------------------- Top level read/write ------------------------- */
993
 
 
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.
999
 
 */
1000
 
INLINE UINT32 m68ki_read_8_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc)
1001
 
{
1002
 
        m68k->mmu_tmp_fc = fc;
1003
 
        m68k->mmu_tmp_rw = 1;
1004
 
        return m68k->memory.read8(address);
1005
 
}
1006
 
INLINE UINT32 m68ki_read_16_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc)
1007
 
{
1008
 
        if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1009
 
        {
1010
 
                m68ki_check_address_error(m68k, address, MODE_READ, fc);
1011
 
        }
1012
 
        m68k->mmu_tmp_fc = fc;
1013
 
        m68k->mmu_tmp_rw = 1;
1014
 
        return m68k->memory.read16(address);
1015
 
}
1016
 
INLINE UINT32 m68ki_read_32_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc)
1017
 
{
1018
 
        if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1019
 
        {
1020
 
                m68ki_check_address_error(m68k, address, MODE_READ, fc);
1021
 
        }
1022
 
        m68k->mmu_tmp_fc = fc;
1023
 
        m68k->mmu_tmp_rw = 1;
1024
 
        return m68k->memory.read32(address);
1025
 
}
1026
 
 
1027
 
INLINE void m68ki_write_8_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1028
 
{
1029
 
        m68k->mmu_tmp_fc = fc;
1030
 
        m68k->mmu_tmp_rw = 0;
1031
 
        m68k->memory.write8(address, value);
1032
 
}
1033
 
INLINE void m68ki_write_16_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1034
 
{
1035
 
        if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1036
 
        {
1037
 
                m68ki_check_address_error(m68k, address, MODE_WRITE, fc);
1038
 
        }
1039
 
        m68k->mmu_tmp_fc = fc;
1040
 
        m68k->mmu_tmp_rw = 0;
1041
 
        m68k->memory.write16(address, value);
1042
 
}
1043
 
INLINE void m68ki_write_32_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1044
 
{
1045
 
        if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1046
 
        {
1047
 
                m68ki_check_address_error(m68k, address, MODE_WRITE, fc);
1048
 
        }
1049
 
        m68k->mmu_tmp_fc = fc;
1050
 
        m68k->mmu_tmp_rw = 0;
1051
 
        m68k->memory.write32(address, value);
1052
 
}
1053
 
 
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].
1058
 
 */
1059
 
INLINE void m68ki_write_32_pd_fc(m68ki_cpu_core *m68k, UINT32 address, UINT32 fc, UINT32 value)
1060
 
{
1061
 
        if (CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1062
 
        {
1063
 
                m68ki_check_address_error(m68k, address, MODE_WRITE, fc);
1064
 
        }
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);
1069
 
}
1070
 
 
1071
 
 
1072
 
/* --------------------- Effective Address Calculation -------------------- */
1073
 
 
1074
 
/* The program counter relative addressing modes cause operands to be
1075
 
 * retrieved from program space, not data space.
1076
 
 */
1077
 
INLINE UINT32 m68ki_get_ea_pcdi(m68ki_cpu_core *m68k)
1078
 
{
1079
 
        UINT32 old_pc = REG_PC;
1080
 
        return old_pc + MAKE_INT_16(m68ki_read_imm_16(m68k));
1081
 
}
1082
 
 
1083
 
 
1084
 
INLINE UINT32 m68ki_get_ea_pcix(m68ki_cpu_core *m68k)
1085
 
{
1086
 
        return m68ki_get_ea_ix(m68k, REG_PC);
1087
 
}
1088
 
 
1089
 
/* Indexed addressing modes are encoded as follows:
1090
 
 *
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)
1094
 
 *
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)
1098
 
 *
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
1102
 
 *
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)
1108
 
 *
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)
1115
 
 *
1116
 
 * IS I/IS Operation
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
1121
 
 * 0  100  reserved
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
1130
 
 */
1131
 
INLINE UINT32 m68ki_get_ea_ix(m68ki_cpu_core *m68k, UINT32 An)
1132
 
{
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 */
1138
 
 
1139
 
        if(CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1140
 
        {
1141
 
                /* Calculate index */
1142
 
                Xn = REG_DA[extension>>12];     /* Xn */
1143
 
                if(!BIT_B(extension))           /* W/L */
1144
 
                        Xn = MAKE_INT_16(Xn);
1145
 
 
1146
 
                /* Add base register and displacement and return */
1147
 
                return An + Xn + MAKE_INT_8(extension);
1148
 
        }
1149
 
 
1150
 
        /* Brief extension format */
1151
 
        if(!BIT_8(extension))
1152
 
        {
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 */
1160
 
 
1161
 
                /* Add base register and displacement and return */
1162
 
                return An + Xn + MAKE_INT_8(extension);
1163
 
        }
1164
 
 
1165
 
        /* Full extension format */
1166
 
 
1167
 
        m68k->remaining_cycles -= m68ki_ea_idx_cycle_table[extension&0x3f];
1168
 
 
1169
 
        /* Check if base register is present */
1170
 
        if(BIT_7(extension))                /* BS */
1171
 
                An = 0;                         /* An */
1172
 
 
1173
 
        /* Check if index is present */
1174
 
        if(!BIT_6(extension))               /* IS */
1175
 
        {
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 */
1180
 
        }
1181
 
 
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));
1185
 
 
1186
 
        /* If no indirect action, we are done */
1187
 
        if(!(extension&7))                  /* No Memory Indirect */
1188
 
                return An + bd + Xn;
1189
 
 
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));
1193
 
 
1194
 
        /* Postindex */
1195
 
        if(BIT_2(extension))                /* I/IS:  0 = preindex, 1 = postindex */
1196
 
                return m68ki_read_32(m68k, An + bd) + Xn + od;
1197
 
 
1198
 
        /* Preindex */
1199
 
        return m68ki_read_32(m68k, An + bd + Xn) + od;
1200
 
}
1201
 
 
1202
 
 
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);}
1219
 
 
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);}
1235
 
 
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); }
1238
 
 
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);}
1251
 
 
1252
 
 
1253
 
 
1254
 
/* ---------------------------- Stack Functions --------------------------- */
1255
 
 
1256
 
/* Push/pull data from the stack */
1257
 
INLINE void m68ki_push_16(m68ki_cpu_core *m68k, UINT32 value)
1258
 
{
1259
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1260
 
        m68ki_write_16(m68k, REG_SP, value);
1261
 
}
1262
 
 
1263
 
INLINE void m68ki_push_32(m68ki_cpu_core *m68k, UINT32 value)
1264
 
{
1265
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1266
 
        m68ki_write_32(m68k, REG_SP, value);
1267
 
}
1268
 
 
1269
 
INLINE UINT32 m68ki_pull_16(m68ki_cpu_core *m68k)
1270
 
{
1271
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1272
 
        return m68ki_read_16(m68k, REG_SP-2);
1273
 
}
1274
 
 
1275
 
INLINE UINT32 m68ki_pull_32(m68ki_cpu_core *m68k)
1276
 
{
1277
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1278
 
        return m68ki_read_32(m68k, REG_SP-4);
1279
 
}
1280
 
 
1281
 
 
1282
 
/* Increment/decrement the stack as if doing a push/pull but
1283
 
 * don't do any memory access.
1284
 
 */
1285
 
INLINE void m68ki_fake_push_16(m68ki_cpu_core *m68k)
1286
 
{
1287
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
1288
 
}
1289
 
 
1290
 
INLINE void m68ki_fake_push_32(m68ki_cpu_core *m68k)
1291
 
{
1292
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
1293
 
}
1294
 
 
1295
 
INLINE void m68ki_fake_pull_16(m68ki_cpu_core *m68k)
1296
 
{
1297
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
1298
 
}
1299
 
 
1300
 
INLINE void m68ki_fake_pull_32(m68ki_cpu_core *m68k)
1301
 
{
1302
 
        REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
1303
 
}
1304
 
 
1305
 
 
1306
 
/* ----------------------------- Program Flow ----------------------------- */
1307
 
 
1308
 
/* Jump to a new program location or vector.
1309
 
 * These functions will also call the pc_changed callback if it was enabled
1310
 
 * in m68kconf.h.
1311
 
 */
1312
 
INLINE void m68ki_jump(m68ki_cpu_core *m68k, UINT32 new_pc)
1313
 
{
1314
 
        REG_PC = new_pc;
1315
 
}
1316
 
 
1317
 
INLINE void m68ki_jump_vector(m68ki_cpu_core *m68k, UINT32 vector)
1318
 
{
1319
 
        REG_PC = (vector<<2) + m68k->vbr;
1320
 
        REG_PC = m68ki_read_data_32(m68k, REG_PC);
1321
 
}
1322
 
 
1323
 
 
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
1327
 
 * bit branches.
1328
 
 */
1329
 
INLINE void m68ki_branch_8(m68ki_cpu_core *m68k, UINT32 offset)
1330
 
{
1331
 
        REG_PC += MAKE_INT_8(offset);
1332
 
}
1333
 
 
1334
 
INLINE void m68ki_branch_16(m68ki_cpu_core *m68k, UINT32 offset)
1335
 
{
1336
 
        REG_PC += MAKE_INT_16(offset);
1337
 
}
1338
 
 
1339
 
INLINE void m68ki_branch_32(m68ki_cpu_core *m68k, UINT32 offset)
1340
 
{
1341
 
        REG_PC += offset;
1342
 
}
1343
 
 
1344
 
 
1345
 
 
1346
 
/* ---------------------------- Status Register --------------------------- */
1347
 
 
1348
 
/* Set the S flag and change the active stack pointer.
1349
 
 * Note that value MUST be 4 or 0.
1350
 
 */
1351
 
INLINE void m68ki_set_s_flag(m68ki_cpu_core *m68k, UINT32 value)
1352
 
{
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)];
1359
 
}
1360
 
 
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).
1363
 
 */
1364
 
INLINE void m68ki_set_sm_flag(m68ki_cpu_core *m68k, UINT32 value)
1365
 
{
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)];
1373
 
}
1374
 
 
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)
1377
 
{
1378
 
        /* Set the S and M flags */
1379
 
        m68k->s_flag = value & SFLAG_SET;
1380
 
        m68k->m_flag = value & MFLAG_SET;
1381
 
}
1382
 
 
1383
 
 
1384
 
/* Set the condition code register */
1385
 
INLINE void m68ki_set_ccr(m68ki_cpu_core *m68k, UINT32 value)
1386
 
{
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;
1392
 
}
1393
 
 
1394
 
/* Set the status register but don't check for interrupts */
1395
 
INLINE void m68ki_set_sr_noint(m68ki_cpu_core *m68k, UINT32 value)
1396
 
{
1397
 
        /* Mask out the "unimplemented" bits */
1398
 
        value &= m68k->sr_mask;
1399
 
 
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);
1406
 
}
1407
 
 
1408
 
/* Set the status register but don't check for interrupts nor
1409
 
 * change the stack pointer
1410
 
 */
1411
 
INLINE void m68ki_set_sr_noint_nosp(m68ki_cpu_core *m68k, UINT32 value)
1412
 
{
1413
 
        /* Mask out the "unimplemented" bits */
1414
 
        value &= m68k->sr_mask;
1415
 
 
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);
1422
 
}
1423
 
 
1424
 
/* Set the status register and check for interrupts */
1425
 
INLINE void m68ki_set_sr(m68ki_cpu_core *m68k, UINT32 value)
1426
 
{
1427
 
        m68ki_set_sr_noint(m68k, value);
1428
 
        m68ki_check_interrupts(m68k);
1429
 
}
1430
 
 
1431
 
 
1432
 
/* ------------------------- Exception Processing ------------------------- */
1433
 
 
1434
 
/* Initiate exception processing */
1435
 
INLINE UINT32 m68ki_init_exception(m68ki_cpu_core *m68k)
1436
 
{
1437
 
        /* Save the old status register */
1438
 
        UINT32 sr = m68ki_get_sr(m68k);
1439
 
 
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);
1445
 
 
1446
 
        return sr;
1447
 
}
1448
 
 
1449
 
/* 3 word stack frame (68000 only) */
1450
 
INLINE void m68ki_stack_frame_3word(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr)
1451
 
{
1452
 
        m68ki_push_32(m68k, pc);
1453
 
        m68ki_push_16(m68k, sr);
1454
 
}
1455
 
 
1456
 
/* Format 0 stack frame.
1457
 
 * This is the standard stack frame for 68010+.
1458
 
 */
1459
 
INLINE void m68ki_stack_frame_0000(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector)
1460
 
{
1461
 
        /* Stack a 3-word frame if we are 68000 */
1462
 
        if(m68k->cpu_type == CPU_TYPE_000 || m68k->cpu_type == CPU_TYPE_008)
1463
 
        {
1464
 
                m68ki_stack_frame_3word(m68k, pc, sr);
1465
 
                return;
1466
 
        }
1467
 
        m68ki_push_16(m68k, vector<<2);
1468
 
        m68ki_push_32(m68k, pc);
1469
 
        m68ki_push_16(m68k, sr);
1470
 
}
1471
 
 
1472
 
/* Format 1 stack frame (68020).
1473
 
 * For 68020, this is the 4 word throwaway frame.
1474
 
 */
1475
 
INLINE void m68ki_stack_frame_0001(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector)
1476
 
{
1477
 
        m68ki_push_16(m68k, 0x1000 | (vector<<2));
1478
 
        m68ki_push_32(m68k, pc);
1479
 
        m68ki_push_16(m68k, sr);
1480
 
}
1481
 
 
1482
 
/* Format 2 stack frame.
1483
 
 * This is used only by 68020 for trap exceptions.
1484
 
 */
1485
 
INLINE void m68ki_stack_frame_0010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector)
1486
 
{
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);
1491
 
}
1492
 
 
1493
 
 
1494
 
/* Bus error stack frame (68000 only).
1495
 
 */
1496
 
INLINE void m68ki_stack_frame_buserr(m68ki_cpu_core *m68k, UINT32 sr)
1497
 
{
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
1506
 
     */
1507
 
        m68ki_push_16(m68k, m68k->aerr_write_mode | m68k->instr_mode | m68k->aerr_fc);
1508
 
}
1509
 
 
1510
 
/* Format 8 stack frame (68010).
1511
 
 * 68010 only.  This is the 29 word bus/address error frame.
1512
 
 */
1513
 
void m68ki_stack_frame_1000(m68ki_cpu_core *m68k, UINT32 pc, UINT32 sr, UINT32 vector)
1514
 
{
1515
 
        /* VERSION
1516
 
     * NUMBER
1517
 
     * INTERNAL INFORMATION, 16 WORDS
1518
 
     */
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);
1527
 
 
1528
 
        /* INSTRUCTION INPUT BUFFER */
1529
 
        m68ki_push_16(m68k, 0);
1530
 
 
1531
 
        /* UNUSED, RESERVED (not written) */
1532
 
        m68ki_fake_push_16(m68k);
1533
 
 
1534
 
        /* DATA INPUT BUFFER */
1535
 
        m68ki_push_16(m68k, 0);
1536
 
 
1537
 
        /* UNUSED, RESERVED (not written) */
1538
 
        m68ki_fake_push_16(m68k);
1539
 
 
1540
 
        /* DATA OUTPUT BUFFER */
1541
 
        m68ki_push_16(m68k, 0);
1542
 
 
1543
 
        /* UNUSED, RESERVED (not written) */
1544
 
        m68ki_fake_push_16(m68k);
1545
 
 
1546
 
        /* FAULT ADDRESS */
1547
 
        m68ki_push_32(m68k, 0);
1548
 
 
1549
 
        /* SPECIAL STATUS WORD */
1550
 
        m68ki_push_16(m68k, 0);
1551
 
 
1552
 
        /* 1000, VECTOR OFFSET */
1553
 
        m68ki_push_16(m68k, 0x8000 | (vector<<2));
1554
 
 
1555
 
        /* PROGRAM COUNTER */
1556
 
        m68ki_push_32(m68k, pc);
1557
 
 
1558
 
        /* STATUS REGISTER */
1559
 
        m68ki_push_16(m68k, sr);
1560
 
}
1561
 
 
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.
1566
 
 */
1567
 
void m68ki_stack_frame_1010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT32 pc, UINT32 fault_address)
1568
 
{
1569
 
        /* INTERNAL REGISTER */
1570
 
        m68ki_push_16(m68k, 0);
1571
 
 
1572
 
        /* INTERNAL REGISTER */
1573
 
        m68ki_push_16(m68k, 0);
1574
 
 
1575
 
        /* DATA OUTPUT BUFFER (2 words) */
1576
 
        m68ki_push_32(m68k, 0);
1577
 
 
1578
 
        /* INTERNAL REGISTER */
1579
 
        m68ki_push_16(m68k, 0);
1580
 
 
1581
 
        /* INTERNAL REGISTER */
1582
 
        m68ki_push_16(m68k, 0);
1583
 
 
1584
 
        /* DATA CYCLE FAULT ADDRESS (2 words) */
1585
 
        m68ki_push_32(m68k, fault_address);
1586
 
 
1587
 
        /* INSTRUCTION PIPE STAGE B */
1588
 
        m68ki_push_16(m68k, 0);
1589
 
 
1590
 
        /* INSTRUCTION PIPE STAGE C */
1591
 
        m68ki_push_16(m68k, 0);
1592
 
 
1593
 
        /* SPECIAL STATUS REGISTER */
1594
 
        // set bit for: Rerun Faulted bus Cycle, or run pending prefetch
1595
 
        // set FC
1596
 
        m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc );
1597
 
 
1598
 
        /* INTERNAL REGISTER */
1599
 
        m68ki_push_16(m68k, 0);
1600
 
 
1601
 
        /* 1010, VECTOR OFFSET */
1602
 
        m68ki_push_16(m68k, 0xa000 | (vector<<2));
1603
 
 
1604
 
        /* PROGRAM COUNTER */
1605
 
        m68ki_push_32(m68k, pc);
1606
 
 
1607
 
        /* STATUS REGISTER */
1608
 
        m68ki_push_16(m68k, sr);
1609
 
}
1610
 
 
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.
1615
 
 */
1616
 
void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT32 pc, UINT32 fault_address)
1617
 
{
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);
1628
 
 
1629
 
        /* VERSION# (4 bits), INTERNAL INFORMATION */
1630
 
        m68ki_push_16(m68k, 0);
1631
 
 
1632
 
        /* INTERNAL REGISTERS (3 words) */
1633
 
        m68ki_push_32(m68k, 0);
1634
 
        m68ki_push_16(m68k, 0);
1635
 
 
1636
 
        /* DATA INTPUT BUFFER (2 words) */
1637
 
        m68ki_push_32(m68k, 0);
1638
 
 
1639
 
        /* INTERNAL REGISTERS (2 words) */
1640
 
        m68ki_push_32(m68k, 0);
1641
 
 
1642
 
        /* STAGE B ADDRESS (2 words) */
1643
 
        m68ki_push_32(m68k, 0);
1644
 
 
1645
 
        /* INTERNAL REGISTER (4 words) */
1646
 
        m68ki_push_32(m68k, 0);
1647
 
        m68ki_push_32(m68k, 0);
1648
 
 
1649
 
        /* DATA OUTPUT BUFFER (2 words) */
1650
 
        m68ki_push_32(m68k, 0);
1651
 
 
1652
 
        /* INTERNAL REGISTER */
1653
 
        m68ki_push_16(m68k, 0);
1654
 
 
1655
 
        /* INTERNAL REGISTER */
1656
 
        m68ki_push_16(m68k, 0);
1657
 
 
1658
 
        /* DATA CYCLE FAULT ADDRESS (2 words) */
1659
 
        m68ki_push_32(m68k, fault_address);
1660
 
 
1661
 
        /* INSTRUCTION PIPE STAGE B */
1662
 
        m68ki_push_16(m68k, 0);
1663
 
 
1664
 
        /* INSTRUCTION PIPE STAGE C */
1665
 
        m68ki_push_16(m68k, 0);
1666
 
 
1667
 
        /* SPECIAL STATUS REGISTER */
1668
 
        m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc);
1669
 
 
1670
 
        /* INTERNAL REGISTER */
1671
 
        m68ki_push_16(m68k, 0);
1672
 
 
1673
 
        /* 1011, VECTOR OFFSET */
1674
 
        m68ki_push_16(m68k, 0xb000 | (vector<<2));
1675
 
 
1676
 
        /* PROGRAM COUNTER */
1677
 
        m68ki_push_32(m68k, pc);
1678
 
 
1679
 
        /* STATUS REGISTER */
1680
 
        m68ki_push_16(m68k, sr);
1681
 
}
1682
 
 
1683
 
 
1684
 
/* Used for Group 2 exceptions.
1685
 
 * These stack a type 2 frame on the 020.
1686
 
 */
1687
 
INLINE void m68ki_exception_trap(m68ki_cpu_core *m68k, UINT32 vector)
1688
 
{
1689
 
        UINT32 sr = m68ki_init_exception(m68k);
1690
 
 
1691
 
        if(CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1692
 
                m68ki_stack_frame_0000(m68k, REG_PC, sr, vector);
1693
 
        else
1694
 
                m68ki_stack_frame_0010(m68k, sr, vector);
1695
 
 
1696
 
        m68ki_jump_vector(m68k, vector);
1697
 
 
1698
 
        /* Use up some clock cycles */
1699
 
        m68k->remaining_cycles -= m68k->cyc_exception[vector];
1700
 
}
1701
 
 
1702
 
/* Trap#n stacks a 0 frame but behaves like group2 otherwise */
1703
 
INLINE void m68ki_exception_trapN(m68ki_cpu_core *m68k, UINT32 vector)
1704
 
{
1705
 
        UINT32 sr = m68ki_init_exception(m68k);
1706
 
        m68ki_stack_frame_0000(m68k, REG_PC, sr, vector);
1707
 
        m68ki_jump_vector(m68k, vector);
1708
 
 
1709
 
        /* Use up some clock cycles */
1710
 
        m68k->remaining_cycles -= m68k->cyc_exception[vector];
1711
 
}
1712
 
 
1713
 
/* Exception for trace mode */
1714
 
INLINE void m68ki_exception_trace(m68ki_cpu_core *m68k)
1715
 
{
1716
 
        UINT32 sr = m68ki_init_exception(m68k);
1717
 
 
1718
 
        if(CPU_TYPE_IS_010_LESS(m68k->cpu_type))
1719
 
        {
1720
 
                if(CPU_TYPE_IS_000(m68k->cpu_type))
1721
 
                {
1722
 
                        m68k->instr_mode = INSTRUCTION_NO;
1723
 
                }
1724
 
                m68ki_stack_frame_0000(m68k, REG_PC, sr, EXCEPTION_TRACE);
1725
 
        }
1726
 
        else
1727
 
                m68ki_stack_frame_0010(m68k, sr, EXCEPTION_TRACE);
1728
 
 
1729
 
        m68ki_jump_vector(m68k, EXCEPTION_TRACE);
1730
 
 
1731
 
        /* Trace nullifies a STOP instruction */
1732
 
        m68k->stopped &= ~STOP_LEVEL_STOP;
1733
 
 
1734
 
        /* Use up some clock cycles */
1735
 
        m68k->remaining_cycles -= m68k->cyc_exception[EXCEPTION_TRACE];
1736
 
}
1737
 
 
1738
 
/* Exception for privilege violation */
1739
 
INLINE void m68ki_exception_privilege_violation(m68ki_cpu_core *m68k)
1740
 
{
1741
 
        UINT32 sr = m68ki_init_exception(m68k);
1742
 
 
1743
 
        if(CPU_TYPE_IS_000(m68k->cpu_type))
1744
 
        {
1745
 
                m68k->instr_mode = INSTRUCTION_NO;
1746
 
        }
1747
 
 
1748
 
        m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_PRIVILEGE_VIOLATION);
1749
 
        m68ki_jump_vector(m68k, EXCEPTION_PRIVILEGE_VIOLATION);
1750
 
 
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];
1753
 
}
1754
 
 
1755
 
/* Exception for A-Line instructions */
1756
 
INLINE void m68ki_exception_1010(m68ki_cpu_core *m68k)
1757
 
{
1758
 
        UINT32 sr;
1759
 
 
1760
 
        sr = m68ki_init_exception(m68k);
1761
 
        m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_1010);
1762
 
        m68ki_jump_vector(m68k, EXCEPTION_1010);
1763
 
 
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];
1766
 
}
1767
 
 
1768
 
/* Exception for F-Line instructions */
1769
 
INLINE void m68ki_exception_1111(m68ki_cpu_core *m68k)
1770
 
{
1771
 
        UINT32 sr;
1772
 
 
1773
 
        sr = m68ki_init_exception(m68k);
1774
 
        m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_1111);
1775
 
        m68ki_jump_vector(m68k, EXCEPTION_1111);
1776
 
 
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];
1779
 
}
1780
 
 
1781
 
/* Exception for illegal instructions */
1782
 
INLINE void m68ki_exception_illegal(m68ki_cpu_core *m68k)
1783
 
{
1784
 
        UINT32 sr;
1785
 
 
1786
 
        sr = m68ki_init_exception(m68k);
1787
 
 
1788
 
        if(CPU_TYPE_IS_000(m68k->cpu_type))
1789
 
        {
1790
 
                m68k->instr_mode = INSTRUCTION_NO;
1791
 
        }
1792
 
 
1793
 
        m68ki_stack_frame_0000(m68k, REG_PPC, sr, EXCEPTION_ILLEGAL_INSTRUCTION);
1794
 
        m68ki_jump_vector(m68k, EXCEPTION_ILLEGAL_INSTRUCTION);
1795
 
 
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];
1798
 
}
1799
 
 
1800
 
/* Exception for format errror in RTE */
1801
 
INLINE void m68ki_exception_format_error(m68ki_cpu_core *m68k)
1802
 
{
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);
1806
 
 
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];
1809
 
}
1810
 
 
1811
 
/* Exception for address error */
1812
 
INLINE void m68ki_exception_address_error(m68ki_cpu_core *m68k)
1813
 
{
1814
 
        UINT32 sr = m68ki_init_exception(m68k);
1815
 
 
1816
 
        /* If we were processing a bus error, address error, or reset,
1817
 
     * this is a catastrophic failure.
1818
 
     * Halt the CPU
1819
 
     */
1820
 
        if(m68k->run_mode == RUN_MODE_BERR_AERR_RESET)
1821
 
        {
1822
 
                m68k->memory.read8(0x00ffff01);
1823
 
                m68k->stopped = STOP_LEVEL_HALT;
1824
 
                return;
1825
 
        }
1826
 
        m68k->run_mode = RUN_MODE_BERR_AERR_RESET;
1827
 
 
1828
 
        /* Note: This is implemented for 68000 only! */
1829
 
        m68ki_stack_frame_buserr(m68k, sr);
1830
 
 
1831
 
        m68ki_jump_vector(m68k, EXCEPTION_ADDRESS_ERROR);
1832
 
 
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];
1835
 
}
1836
 
 
1837
 
 
1838
 
/* Service an interrupt request and start exception processing */
1839
 
void m68ki_exception_interrupt(m68ki_cpu_core *m68k, UINT32 int_level)
1840
 
{
1841
 
        UINT32 vector;
1842
 
        UINT32 sr;
1843
 
        UINT32 new_pc;
1844
 
 
1845
 
        if(CPU_TYPE_IS_000(m68k->cpu_type))
1846
 
        {
1847
 
                m68k->instr_mode = INSTRUCTION_NO;
1848
 
        }
1849
 
 
1850
 
        /* Turn off the stopped state */
1851
 
        m68k->stopped &= ~STOP_LEVEL_STOP;
1852
 
 
1853
 
        /* If we are halted, don't do anything */
1854
 
        if(m68k->stopped)
1855
 
                return;
1856
 
 
1857
 
        /* Acknowledge the interrupt */
1858
 
        vector = (*m68k->int_ack_callback)(m68k->device, int_level);
1859
 
 
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)
1868
 
                return;
1869
 
 
1870
 
        /* Start exception processing */
1871
 
        sr = m68ki_init_exception(m68k);
1872
 
 
1873
 
        /* Set the interrupt mask to the level of the one being serviced */
1874
 
        m68k->int_mask = int_level<<8;
1875
 
 
1876
 
        /* Get the new PC */
1877
 
        new_pc = m68ki_read_data_32(m68k, (vector<<2) + m68k->vbr);
1878
 
 
1879
 
        /* If vector is uninitialized, call the uninitialized interrupt vector */
1880
 
        if(new_pc == 0)
1881
 
                new_pc = m68ki_read_data_32(m68k, (EXCEPTION_UNINITIALIZED_INTERRUPT<<2) + m68k->vbr);
1882
 
 
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))
1886
 
        {
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);
1891
 
        }
1892
 
 
1893
 
        m68ki_jump(m68k, new_pc);
1894
 
 
1895
 
        /* Defer cycle counting until later */
1896
 
        m68k->remaining_cycles -= m68k->cyc_exception[vector];
1897
 
}
1898
 
 
1899
 
 
1900
 
/* ASG: Check for interrupts */
1901
 
INLINE void m68ki_check_interrupts(m68ki_cpu_core *m68k)
1902
 
{
1903
 
        if(m68k->nmi_pending)
1904
 
        {
1905
 
                m68k->nmi_pending = FALSE;
1906
 
                m68ki_exception_interrupt(m68k, 7);
1907
 
        }
1908
 
        else if(m68k->int_level > m68k->int_mask)
1909
 
                m68ki_exception_interrupt(m68k, m68k->int_level>>8);
1910
 
}
1911
 
 
1912
 
 
1913
 
 
1914
 
/* ======================================================================== */
1915
 
/* ============================== END OF FILE ============================= */
1916
 
/* ======================================================================== */
1917
 
 
1918
 
#endif /* __M68KCPU_H__ */