]> git.sesse.net Git - pistorm/blob - m68kcpu.c
Fix config reload?
[pistorm] / m68kcpu.c
1 /* ======================================================================== */
2 /* ========================= LICENSING & COPYRIGHT ======================== */
3 /* ======================================================================== */
4 /*
5  *                                  MUSASHI
6  *                                Version 4.60
7  *
8  * A portable Motorola M680x0 processor emulation engine.
9  * Copyright Karl Stenerud.  All rights reserved.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27  * THE SOFTWARE.
28  */
29
30
31 /* ======================================================================== */
32 /* ================================= NOTES ================================ */
33 /* ======================================================================== */
34
35
36
37 /* ======================================================================== */
38 /* ================================ INCLUDES ============================== */
39 /* ======================================================================== */
40
41 extern void m68040_fpu_op0(void);
42 extern void m68040_fpu_op1(void);
43 extern void m68851_mmu_ops();
44 extern unsigned char m68ki_cycles[][0x10000];
45 extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
46 extern void m68ki_build_opcode_table(void);
47
48 #include "m68kops.h"
49 #include "m68kcpu.h"
50
51 #include "m68kfpu.c"
52 #include "m68kmmu.h" // uses some functions from m68kfpu.c which are static !
53
54 /* ======================================================================== */
55 /* ================================= DATA ================================= */
56 /* ======================================================================== */
57
58 int  m68ki_initial_cycles;
59 int  m68ki_remaining_cycles = 0;                     /* Number of clocks remaining */
60 uint m68ki_tracing = 0;
61 uint m68ki_address_space;
62
63 #ifdef M68K_LOG_ENABLE
64 const char *const m68ki_cpu_names[] =
65 {
66         "Invalid CPU",
67         "M68000",
68         "M68010",
69         "Invalid CPU",
70         "M68EC020"
71         "Invalid CPU",
72         "Invalid CPU",
73         "Invalid CPU",
74         "M68020"
75 };
76 #endif /* M68K_LOG_ENABLE */
77
78 /* The CPU core */
79 m68ki_cpu_core m68ki_cpu = {0};
80
81 #if M68K_EMULATE_ADDRESS_ERROR
82 #ifdef _BSD_SETJMP_H
83 sigjmp_buf m68ki_aerr_trap;
84 #else
85 jmp_buf m68ki_aerr_trap;
86 #endif
87 #endif /* M68K_EMULATE_ADDRESS_ERROR */
88
89 uint    m68ki_aerr_address;
90 uint    m68ki_aerr_write_mode;
91 uint    m68ki_aerr_fc;
92
93 jmp_buf m68ki_bus_error_jmp_buf;
94
95 /* Used by shift & rotate instructions */
96 const uint8 m68ki_shift_8_table[65] =
97 {
98         0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,
99         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
100         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
101         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
102         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
103         0xff, 0xff, 0xff, 0xff, 0xff
104 };
105 const uint16 m68ki_shift_16_table[65] =
106 {
107         0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
108         0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,
109         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
110         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
111         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
112         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
113         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
114         0xffff, 0xffff
115 };
116 const uint m68ki_shift_32_table[65] =
117 {
118         0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
119         0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
120         0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
121         0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
122         0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
123         0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
124         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
125         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
126         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
127         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
128         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
129 };
130
131
132 /* Number of clock cycles to use for exception processing.
133  * I used 4 for any vectors that are undocumented for processing times.
134  */
135 const uint8 m68ki_exception_cycle_table[5][256] =
136 {
137         { /* 000 */
138                  40, /*  0: Reset - Initial Stack Pointer                      */
139                   4, /*  1: Reset - Initial Program Counter                    */
140                  50, /*  2: Bus Error                             (unemulated) */
141                  50, /*  3: Address Error                         (unemulated) */
142                  34, /*  4: Illegal Instruction                                */
143                  38, /*  5: Divide by Zero                                     */
144                  40, /*  6: CHK                                                */
145                  34, /*  7: TRAPV                                              */
146                  34, /*  8: Privilege Violation                                */
147                  34, /*  9: Trace                                              */
148                   4, /* 10: 1010                                               */
149                   4, /* 11: 1111                                               */
150                   4, /* 12: RESERVED                                           */
151                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
152                   4, /* 14: Format Error                                       */
153                  44, /* 15: Uninitialized Interrupt                            */
154                   4, /* 16: RESERVED                                           */
155                   4, /* 17: RESERVED                                           */
156                   4, /* 18: RESERVED                                           */
157                   4, /* 19: RESERVED                                           */
158                   4, /* 20: RESERVED                                           */
159                   4, /* 21: RESERVED                                           */
160                   4, /* 22: RESERVED                                           */
161                   4, /* 23: RESERVED                                           */
162                  44, /* 24: Spurious Interrupt                                 */
163                  44, /* 25: Level 1 Interrupt Autovector                       */
164                  44, /* 26: Level 2 Interrupt Autovector                       */
165                  44, /* 27: Level 3 Interrupt Autovector                       */
166                  44, /* 28: Level 4 Interrupt Autovector                       */
167                  44, /* 29: Level 5 Interrupt Autovector                       */
168                  44, /* 30: Level 6 Interrupt Autovector                       */
169                  44, /* 31: Level 7 Interrupt Autovector                       */
170                  34, /* 32: TRAP #0                                            */
171                  34, /* 33: TRAP #1                                            */
172                  34, /* 34: TRAP #2                                            */
173                  34, /* 35: TRAP #3                                            */
174                  34, /* 36: TRAP #4                                            */
175                  34, /* 37: TRAP #5                                            */
176                  34, /* 38: TRAP #6                                            */
177                  34, /* 39: TRAP #7                                            */
178                  34, /* 40: TRAP #8                                            */
179                  34, /* 41: TRAP #9                                            */
180                  34, /* 42: TRAP #10                                           */
181                  34, /* 43: TRAP #11                                           */
182                  34, /* 44: TRAP #12                                           */
183                  34, /* 45: TRAP #13                                           */
184                  34, /* 46: TRAP #14                                           */
185                  34, /* 47: TRAP #15                                           */
186                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
187                   4, /* 49: FP Inexact Result                     (unemulated) */
188                   4, /* 50: FP Divide by Zero                     (unemulated) */
189                   4, /* 51: FP Underflow                          (unemulated) */
190                   4, /* 52: FP Operand Error                      (unemulated) */
191                   4, /* 53: FP Overflow                           (unemulated) */
192                   4, /* 54: FP Signaling NAN                      (unemulated) */
193                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
194                   4, /* 56: MMU Configuration Error               (unemulated) */
195                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
196                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
197                   4, /* 59: RESERVED                                           */
198                   4, /* 60: RESERVED                                           */
199                   4, /* 61: RESERVED                                           */
200                   4, /* 62: RESERVED                                           */
201                   4, /* 63: RESERVED                                           */
202                      /* 64-255: User Defined                                   */
203                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
204                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
205                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
206                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
207                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
208                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
209         },
210         { /* 010 */
211                  40, /*  0: Reset - Initial Stack Pointer                      */
212                   4, /*  1: Reset - Initial Program Counter                    */
213                 126, /*  2: Bus Error                             (unemulated) */
214                 126, /*  3: Address Error                         (unemulated) */
215                  38, /*  4: Illegal Instruction                                */
216                  44, /*  5: Divide by Zero                                     */
217                  44, /*  6: CHK                                                */
218                  34, /*  7: TRAPV                                              */
219                  38, /*  8: Privilege Violation                                */
220                  38, /*  9: Trace                                              */
221                   4, /* 10: 1010                                               */
222                   4, /* 11: 1111                                               */
223                   4, /* 12: RESERVED                                           */
224                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
225                   4, /* 14: Format Error                                       */
226                  44, /* 15: Uninitialized Interrupt                            */
227                   4, /* 16: RESERVED                                           */
228                   4, /* 17: RESERVED                                           */
229                   4, /* 18: RESERVED                                           */
230                   4, /* 19: RESERVED                                           */
231                   4, /* 20: RESERVED                                           */
232                   4, /* 21: RESERVED                                           */
233                   4, /* 22: RESERVED                                           */
234                   4, /* 23: RESERVED                                           */
235                  46, /* 24: Spurious Interrupt                                 */
236                  46, /* 25: Level 1 Interrupt Autovector                       */
237                  46, /* 26: Level 2 Interrupt Autovector                       */
238                  46, /* 27: Level 3 Interrupt Autovector                       */
239                  46, /* 28: Level 4 Interrupt Autovector                       */
240                  46, /* 29: Level 5 Interrupt Autovector                       */
241                  46, /* 30: Level 6 Interrupt Autovector                       */
242                  46, /* 31: Level 7 Interrupt Autovector                       */
243                  38, /* 32: TRAP #0                                            */
244                  38, /* 33: TRAP #1                                            */
245                  38, /* 34: TRAP #2                                            */
246                  38, /* 35: TRAP #3                                            */
247                  38, /* 36: TRAP #4                                            */
248                  38, /* 37: TRAP #5                                            */
249                  38, /* 38: TRAP #6                                            */
250                  38, /* 39: TRAP #7                                            */
251                  38, /* 40: TRAP #8                                            */
252                  38, /* 41: TRAP #9                                            */
253                  38, /* 42: TRAP #10                                           */
254                  38, /* 43: TRAP #11                                           */
255                  38, /* 44: TRAP #12                                           */
256                  38, /* 45: TRAP #13                                           */
257                  38, /* 46: TRAP #14                                           */
258                  38, /* 47: TRAP #15                                           */
259                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
260                   4, /* 49: FP Inexact Result                     (unemulated) */
261                   4, /* 50: FP Divide by Zero                     (unemulated) */
262                   4, /* 51: FP Underflow                          (unemulated) */
263                   4, /* 52: FP Operand Error                      (unemulated) */
264                   4, /* 53: FP Overflow                           (unemulated) */
265                   4, /* 54: FP Signaling NAN                      (unemulated) */
266                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
267                   4, /* 56: MMU Configuration Error               (unemulated) */
268                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
269                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
270                   4, /* 59: RESERVED                                           */
271                   4, /* 60: RESERVED                                           */
272                   4, /* 61: RESERVED                                           */
273                   4, /* 62: RESERVED                                           */
274                   4, /* 63: RESERVED                                           */
275                      /* 64-255: User Defined                                   */
276                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
277                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
278                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
279                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
280                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
281                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
282         },
283         { /* 020 */
284                   4, /*  0: Reset - Initial Stack Pointer                      */
285                   4, /*  1: Reset - Initial Program Counter                    */
286                  50, /*  2: Bus Error                             (unemulated) */
287                  50, /*  3: Address Error                         (unemulated) */
288                  20, /*  4: Illegal Instruction                                */
289                  38, /*  5: Divide by Zero                                     */
290                  40, /*  6: CHK                                                */
291                  20, /*  7: TRAPV                                              */
292                  34, /*  8: Privilege Violation                                */
293                  25, /*  9: Trace                                              */
294                  20, /* 10: 1010                                               */
295                  20, /* 11: 1111                                               */
296                   4, /* 12: RESERVED                                           */
297                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
298                   4, /* 14: Format Error                                       */
299                  30, /* 15: Uninitialized Interrupt                            */
300                   4, /* 16: RESERVED                                           */
301                   4, /* 17: RESERVED                                           */
302                   4, /* 18: RESERVED                                           */
303                   4, /* 19: RESERVED                                           */
304                   4, /* 20: RESERVED                                           */
305                   4, /* 21: RESERVED                                           */
306                   4, /* 22: RESERVED                                           */
307                   4, /* 23: RESERVED                                           */
308                  30, /* 24: Spurious Interrupt                                 */
309                  30, /* 25: Level 1 Interrupt Autovector                       */
310                  30, /* 26: Level 2 Interrupt Autovector                       */
311                  30, /* 27: Level 3 Interrupt Autovector                       */
312                  30, /* 28: Level 4 Interrupt Autovector                       */
313                  30, /* 29: Level 5 Interrupt Autovector                       */
314                  30, /* 30: Level 6 Interrupt Autovector                       */
315                  30, /* 31: Level 7 Interrupt Autovector                       */
316                  20, /* 32: TRAP #0                                            */
317                  20, /* 33: TRAP #1                                            */
318                  20, /* 34: TRAP #2                                            */
319                  20, /* 35: TRAP #3                                            */
320                  20, /* 36: TRAP #4                                            */
321                  20, /* 37: TRAP #5                                            */
322                  20, /* 38: TRAP #6                                            */
323                  20, /* 39: TRAP #7                                            */
324                  20, /* 40: TRAP #8                                            */
325                  20, /* 41: TRAP #9                                            */
326                  20, /* 42: TRAP #10                                           */
327                  20, /* 43: TRAP #11                                           */
328                  20, /* 44: TRAP #12                                           */
329                  20, /* 45: TRAP #13                                           */
330                  20, /* 46: TRAP #14                                           */
331                  20, /* 47: TRAP #15                                           */
332                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
333                   4, /* 49: FP Inexact Result                     (unemulated) */
334                   4, /* 50: FP Divide by Zero                     (unemulated) */
335                   4, /* 51: FP Underflow                          (unemulated) */
336                   4, /* 52: FP Operand Error                      (unemulated) */
337                   4, /* 53: FP Overflow                           (unemulated) */
338                   4, /* 54: FP Signaling NAN                      (unemulated) */
339                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
340                   4, /* 56: MMU Configuration Error               (unemulated) */
341                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
342                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
343                   4, /* 59: RESERVED                                           */
344                   4, /* 60: RESERVED                                           */
345                   4, /* 61: RESERVED                                           */
346                   4, /* 62: RESERVED                                           */
347                   4, /* 63: RESERVED                                           */
348                      /* 64-255: User Defined                                   */
349                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
350                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
351                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
352                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
353                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
354                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
355         },
356         { /* 030 - not correct */
357                   4, /*  0: Reset - Initial Stack Pointer                      */
358                   4, /*  1: Reset - Initial Program Counter                    */
359                  50, /*  2: Bus Error                             (unemulated) */
360                  50, /*  3: Address Error                         (unemulated) */
361                  20, /*  4: Illegal Instruction                                */
362                  38, /*  5: Divide by Zero                                     */
363                  40, /*  6: CHK                                                */
364                  20, /*  7: TRAPV                                              */
365                  34, /*  8: Privilege Violation                                */
366                  25, /*  9: Trace                                              */
367                  20, /* 10: 1010                                               */
368                  20, /* 11: 1111                                               */
369                   4, /* 12: RESERVED                                           */
370                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
371                   4, /* 14: Format Error                                       */
372                  30, /* 15: Uninitialized Interrupt                            */
373                   4, /* 16: RESERVED                                           */
374                   4, /* 17: RESERVED                                           */
375                   4, /* 18: RESERVED                                           */
376                   4, /* 19: RESERVED                                           */
377                   4, /* 20: RESERVED                                           */
378                   4, /* 21: RESERVED                                           */
379                   4, /* 22: RESERVED                                           */
380                   4, /* 23: RESERVED                                           */
381                  30, /* 24: Spurious Interrupt                                 */
382                  30, /* 25: Level 1 Interrupt Autovector                       */
383                  30, /* 26: Level 2 Interrupt Autovector                       */
384                  30, /* 27: Level 3 Interrupt Autovector                       */
385                  30, /* 28: Level 4 Interrupt Autovector                       */
386                  30, /* 29: Level 5 Interrupt Autovector                       */
387                  30, /* 30: Level 6 Interrupt Autovector                       */
388                  30, /* 31: Level 7 Interrupt Autovector                       */
389                  20, /* 32: TRAP #0                                            */
390                  20, /* 33: TRAP #1                                            */
391                  20, /* 34: TRAP #2                                            */
392                  20, /* 35: TRAP #3                                            */
393                  20, /* 36: TRAP #4                                            */
394                  20, /* 37: TRAP #5                                            */
395                  20, /* 38: TRAP #6                                            */
396                  20, /* 39: TRAP #7                                            */
397                  20, /* 40: TRAP #8                                            */
398                  20, /* 41: TRAP #9                                            */
399                  20, /* 42: TRAP #10                                           */
400                  20, /* 43: TRAP #11                                           */
401                  20, /* 44: TRAP #12                                           */
402                  20, /* 45: TRAP #13                                           */
403                  20, /* 46: TRAP #14                                           */
404                  20, /* 47: TRAP #15                                           */
405                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
406                   4, /* 49: FP Inexact Result                     (unemulated) */
407                   4, /* 50: FP Divide by Zero                     (unemulated) */
408                   4, /* 51: FP Underflow                          (unemulated) */
409                   4, /* 52: FP Operand Error                      (unemulated) */
410                   4, /* 53: FP Overflow                           (unemulated) */
411                   4, /* 54: FP Signaling NAN                      (unemulated) */
412                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
413                   4, /* 56: MMU Configuration Error               (unemulated) */
414                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
415                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
416                   4, /* 59: RESERVED                                           */
417                   4, /* 60: RESERVED                                           */
418                   4, /* 61: RESERVED                                           */
419                   4, /* 62: RESERVED                                           */
420                   4, /* 63: RESERVED                                           */
421                      /* 64-255: User Defined                                   */
422                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
423                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
424                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
425                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
426                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
427                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
428         },
429         { /* 040 */ // TODO: these values are not correct
430                   4, /*  0: Reset - Initial Stack Pointer                      */
431                   4, /*  1: Reset - Initial Program Counter                    */
432                  50, /*  2: Bus Error                             (unemulated) */
433                  50, /*  3: Address Error                         (unemulated) */
434                  20, /*  4: Illegal Instruction                                */
435                  38, /*  5: Divide by Zero                                     */
436                  40, /*  6: CHK                                                */
437                  20, /*  7: TRAPV                                              */
438                  34, /*  8: Privilege Violation                                */
439                  25, /*  9: Trace                                              */
440                  20, /* 10: 1010                                               */
441                  20, /* 11: 1111                                               */
442                   4, /* 12: RESERVED                                           */
443                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
444                   4, /* 14: Format Error                                       */
445                  30, /* 15: Uninitialized Interrupt                            */
446                   4, /* 16: RESERVED                                           */
447                   4, /* 17: RESERVED                                           */
448                   4, /* 18: RESERVED                                           */
449                   4, /* 19: RESERVED                                           */
450                   4, /* 20: RESERVED                                           */
451                   4, /* 21: RESERVED                                           */
452                   4, /* 22: RESERVED                                           */
453                   4, /* 23: RESERVED                                           */
454                  30, /* 24: Spurious Interrupt                                 */
455                  30, /* 25: Level 1 Interrupt Autovector                       */
456                  30, /* 26: Level 2 Interrupt Autovector                       */
457                  30, /* 27: Level 3 Interrupt Autovector                       */
458                  30, /* 28: Level 4 Interrupt Autovector                       */
459                  30, /* 29: Level 5 Interrupt Autovector                       */
460                  30, /* 30: Level 6 Interrupt Autovector                       */
461                  30, /* 31: Level 7 Interrupt Autovector                       */
462                  20, /* 32: TRAP #0                                            */
463                  20, /* 33: TRAP #1                                            */
464                  20, /* 34: TRAP #2                                            */
465                  20, /* 35: TRAP #3                                            */
466                  20, /* 36: TRAP #4                                            */
467                  20, /* 37: TRAP #5                                            */
468                  20, /* 38: TRAP #6                                            */
469                  20, /* 39: TRAP #7                                            */
470                  20, /* 40: TRAP #8                                            */
471                  20, /* 41: TRAP #9                                            */
472                  20, /* 42: TRAP #10                                           */
473                  20, /* 43: TRAP #11                                           */
474                  20, /* 44: TRAP #12                                           */
475                  20, /* 45: TRAP #13                                           */
476                  20, /* 46: TRAP #14                                           */
477                  20, /* 47: TRAP #15                                           */
478                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
479                   4, /* 49: FP Inexact Result                     (unemulated) */
480                   4, /* 50: FP Divide by Zero                     (unemulated) */
481                   4, /* 51: FP Underflow                          (unemulated) */
482                   4, /* 52: FP Operand Error                      (unemulated) */
483                   4, /* 53: FP Overflow                           (unemulated) */
484                   4, /* 54: FP Signaling NAN                      (unemulated) */
485                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
486                   4, /* 56: MMU Configuration Error               (unemulated) */
487                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
488                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
489                   4, /* 59: RESERVED                                           */
490                   4, /* 60: RESERVED                                           */
491                   4, /* 61: RESERVED                                           */
492                   4, /* 62: RESERVED                                           */
493                   4, /* 63: RESERVED                                           */
494                      /* 64-255: User Defined                                   */
495                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
496                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
497                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
498                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
499                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
500                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
501         }
502 };
503
504 const uint8 m68ki_ea_idx_cycle_table[64] =
505 {
506          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
507          0, /* ..01.000 no memory indirect, base NULL             */
508          5, /* ..01..01 memory indirect,    base NULL, outer NULL */
509          7, /* ..01..10 memory indirect,    base NULL, outer 16   */
510          7, /* ..01..11 memory indirect,    base NULL, outer 32   */
511          0,  5,  7,  7,  0,  5,  7,  7,  0,  5,  7,  7,
512          2, /* ..10.000 no memory indirect, base 16               */
513          7, /* ..10..01 memory indirect,    base 16,   outer NULL */
514          9, /* ..10..10 memory indirect,    base 16,   outer 16   */
515          9, /* ..10..11 memory indirect,    base 16,   outer 32   */
516          0,  7,  9,  9,  0,  7,  9,  9,  0,  7,  9,  9,
517          6, /* ..11.000 no memory indirect, base 32               */
518         11, /* ..11..01 memory indirect,    base 32,   outer NULL */
519         13, /* ..11..10 memory indirect,    base 32,   outer 16   */
520         13, /* ..11..11 memory indirect,    base 32,   outer 32   */
521          0, 11, 13, 13,  0, 11, 13, 13,  0, 11, 13, 13
522 };
523
524
525
526 /* ======================================================================== */
527 /* =============================== CALLBACKS ============================== */
528 /* ======================================================================== */
529
530 /* Default callbacks used if the callback hasn't been set yet, or if the
531  * callback is set to NULL
532  */
533
534 /* Interrupt acknowledge */
535 static int default_int_ack_callback_data;
536 static int default_int_ack_callback(int int_level)
537 {
538         default_int_ack_callback_data = int_level;
539         CPU_INT_LEVEL = 0;
540         return M68K_INT_ACK_AUTOVECTOR;
541 }
542
543 /* Breakpoint acknowledge */
544 static unsigned int default_bkpt_ack_callback_data;
545 static void default_bkpt_ack_callback(unsigned int data)
546 {
547         default_bkpt_ack_callback_data = data;
548 }
549
550 /* Called when a reset instruction is executed */
551 static void default_reset_instr_callback(void)
552 {
553 }
554
555 /* Called when a cmpi.l #v, dn instruction is executed */
556 static void default_cmpild_instr_callback(unsigned int val, int reg)
557 {
558         (void)val;
559         (void)reg;
560 }
561
562 /* Called when a rte instruction is executed */
563 static void default_rte_instr_callback(void)
564 {
565 }
566
567 /* Called when a tas instruction is executed */
568 static int default_tas_instr_callback(void)
569 {
570         return 1; // allow writeback
571 }
572
573 /* Called when an illegal instruction is encountered */
574 static int default_illg_instr_callback(int opcode)
575 {
576         (void)opcode;
577         return 0; // not handled : exception will occur
578 }
579
580 /* Called when the program counter changed by a large value */
581 static unsigned int default_pc_changed_callback_data;
582 static void default_pc_changed_callback(unsigned int new_pc)
583 {
584         default_pc_changed_callback_data = new_pc;
585 }
586
587 /* Called every time there's bus activity (read/write to/from memory */
588 static unsigned int default_set_fc_callback_data;
589 static void default_set_fc_callback(unsigned int new_fc)
590 {
591         default_set_fc_callback_data = new_fc;
592 }
593
594 /* Called every instruction cycle prior to execution */
595 static void default_instr_hook_callback(unsigned int pc)
596 {
597         (void)pc;
598 }
599
600
601 #if M68K_EMULATE_ADDRESS_ERROR
602         #include <setjmp.h>
603         #ifdef _BSD_SETJMP_H
604         sigjmp_buf m68ki_aerr_trap;
605         #else
606         jmp_buf m68ki_aerr_trap;
607         #endif
608 #endif /* M68K_EMULATE_ADDRESS_ERROR */
609
610 /* ======================================================================== */
611 /* ================================= API ================================== */
612 /* ======================================================================== */
613
614 /* Access the internals of the CPU */
615 unsigned int m68k_get_reg(void* context, m68k_register_t regnum)
616 {
617         m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu;
618
619         switch(regnum)
620         {
621                 case M68K_REG_D0:       return cpu->dar[0];
622                 case M68K_REG_D1:       return cpu->dar[1];
623                 case M68K_REG_D2:       return cpu->dar[2];
624                 case M68K_REG_D3:       return cpu->dar[3];
625                 case M68K_REG_D4:       return cpu->dar[4];
626                 case M68K_REG_D5:       return cpu->dar[5];
627                 case M68K_REG_D6:       return cpu->dar[6];
628                 case M68K_REG_D7:       return cpu->dar[7];
629                 case M68K_REG_A0:       return cpu->dar[8];
630                 case M68K_REG_A1:       return cpu->dar[9];
631                 case M68K_REG_A2:       return cpu->dar[10];
632                 case M68K_REG_A3:       return cpu->dar[11];
633                 case M68K_REG_A4:       return cpu->dar[12];
634                 case M68K_REG_A5:       return cpu->dar[13];
635                 case M68K_REG_A6:       return cpu->dar[14];
636                 case M68K_REG_A7:       return cpu->dar[15];
637                 case M68K_REG_PC:       return MASK_OUT_ABOVE_32(cpu->pc);
638                 case M68K_REG_SR:       return  cpu->t1_flag                                    |
639                                                                         cpu->t0_flag                                                    |
640                                                                         (cpu->s_flag << 11)                                     |
641                                                                         (cpu->m_flag << 11)                                     |
642                                                                         cpu->int_mask                                                   |
643                                                                         ((cpu->x_flag & XFLAG_SET) >> 4)        |
644                                                                         ((cpu->n_flag & NFLAG_SET) >> 4)        |
645                                                                         ((!cpu->not_z_flag) << 2)                       |
646                                                                         ((cpu->v_flag & VFLAG_SET) >> 6)        |
647                                                                         ((cpu->c_flag & CFLAG_SET) >> 8);
648                 case M68K_REG_SP:       return cpu->dar[15];
649                 case M68K_REG_USP:      return cpu->s_flag ? cpu->sp[0] : cpu->dar[15];
650                 case M68K_REG_ISP:      return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4];
651                 case M68K_REG_MSP:      return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6];
652                 case M68K_REG_SFC:      return cpu->sfc;
653                 case M68K_REG_DFC:      return cpu->dfc;
654                 case M68K_REG_VBR:      return cpu->vbr;
655                 case M68K_REG_CACR:     return cpu->cacr;
656                 case M68K_REG_CAAR:     return cpu->caar;
657                 case M68K_REG_PREF_ADDR:        return cpu->pref_addr;
658                 case M68K_REG_PREF_DATA:        return cpu->pref_data;
659                 case M68K_REG_PPC:      return MASK_OUT_ABOVE_32(cpu->ppc);
660                 case M68K_REG_IR:       return cpu->ir;
661                 case M68K_REG_CPU_TYPE:
662                         switch(cpu->cpu_type)
663                         {
664                                 case CPU_TYPE_000:              return (unsigned int)M68K_CPU_TYPE_68000;
665                                 case CPU_TYPE_010:              return (unsigned int)M68K_CPU_TYPE_68010;
666                                 case CPU_TYPE_EC020:            return (unsigned int)M68K_CPU_TYPE_68EC020;
667                                 case CPU_TYPE_020:              return (unsigned int)M68K_CPU_TYPE_68020;
668                                 case CPU_TYPE_EC030:            return (unsigned int)M68K_CPU_TYPE_68EC030;
669                                 case CPU_TYPE_030:              return (unsigned int)M68K_CPU_TYPE_68030;
670                                 case CPU_TYPE_EC040:            return (unsigned int)M68K_CPU_TYPE_68EC040;
671                                 case CPU_TYPE_LC040:            return (unsigned int)M68K_CPU_TYPE_68LC040;
672                                 case CPU_TYPE_040:              return (unsigned int)M68K_CPU_TYPE_68040;
673                         }
674                         return M68K_CPU_TYPE_INVALID;
675                 default:                        return 0;
676         }
677         return 0;
678 }
679
680 void m68k_set_reg(m68k_register_t regnum, unsigned int value)
681 {
682         switch(regnum)
683         {
684                 case M68K_REG_D0:       REG_D[0] = MASK_OUT_ABOVE_32(value); return;
685                 case M68K_REG_D1:       REG_D[1] = MASK_OUT_ABOVE_32(value); return;
686                 case M68K_REG_D2:       REG_D[2] = MASK_OUT_ABOVE_32(value); return;
687                 case M68K_REG_D3:       REG_D[3] = MASK_OUT_ABOVE_32(value); return;
688                 case M68K_REG_D4:       REG_D[4] = MASK_OUT_ABOVE_32(value); return;
689                 case M68K_REG_D5:       REG_D[5] = MASK_OUT_ABOVE_32(value); return;
690                 case M68K_REG_D6:       REG_D[6] = MASK_OUT_ABOVE_32(value); return;
691                 case M68K_REG_D7:       REG_D[7] = MASK_OUT_ABOVE_32(value); return;
692                 case M68K_REG_A0:       REG_A[0] = MASK_OUT_ABOVE_32(value); return;
693                 case M68K_REG_A1:       REG_A[1] = MASK_OUT_ABOVE_32(value); return;
694                 case M68K_REG_A2:       REG_A[2] = MASK_OUT_ABOVE_32(value); return;
695                 case M68K_REG_A3:       REG_A[3] = MASK_OUT_ABOVE_32(value); return;
696                 case M68K_REG_A4:       REG_A[4] = MASK_OUT_ABOVE_32(value); return;
697                 case M68K_REG_A5:       REG_A[5] = MASK_OUT_ABOVE_32(value); return;
698                 case M68K_REG_A6:       REG_A[6] = MASK_OUT_ABOVE_32(value); return;
699                 case M68K_REG_A7:       REG_A[7] = MASK_OUT_ABOVE_32(value); return;
700                 case M68K_REG_PC:       m68ki_jump(MASK_OUT_ABOVE_32(value)); return;
701                 case M68K_REG_SR:       m68ki_set_sr_noint_nosp(value); return;
702                 case M68K_REG_SP:       REG_SP = MASK_OUT_ABOVE_32(value); return;
703                 case M68K_REG_USP:      if(FLAG_S)
704                                                                 REG_USP = MASK_OUT_ABOVE_32(value);
705                                                         else
706                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
707                                                         return;
708                 case M68K_REG_ISP:      if(FLAG_S && !FLAG_M)
709                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
710                                                         else
711                                                                 REG_ISP = MASK_OUT_ABOVE_32(value);
712                                                         return;
713                 case M68K_REG_MSP:      if(FLAG_S && FLAG_M)
714                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
715                                                         else
716                                                                 REG_MSP = MASK_OUT_ABOVE_32(value);
717                                                         return;
718                 case M68K_REG_VBR:      REG_VBR = MASK_OUT_ABOVE_32(value); return;
719                 case M68K_REG_SFC:      REG_SFC = value & 7; return;
720                 case M68K_REG_DFC:      REG_DFC = value & 7; return;
721                 case M68K_REG_CACR:     REG_CACR = MASK_OUT_ABOVE_32(value); return;
722                 case M68K_REG_CAAR:     REG_CAAR = MASK_OUT_ABOVE_32(value); return;
723                 case M68K_REG_PPC:      REG_PPC = MASK_OUT_ABOVE_32(value); return;
724                 case M68K_REG_IR:       REG_IR = MASK_OUT_ABOVE_16(value); return;
725                 case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return;
726                 default:                        return;
727         }
728 }
729
730 /* Set the callbacks */
731 void m68k_set_int_ack_callback(int  (*callback)(int int_level))
732 {
733         CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback;
734 }
735
736 void m68k_set_bkpt_ack_callback(void  (*callback)(unsigned int data))
737 {
738         CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback;
739 }
740
741 void m68k_set_reset_instr_callback(void  (*callback)(void))
742 {
743         CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback;
744 }
745
746 void m68k_set_cmpild_instr_callback(void  (*callback)(unsigned int, int))
747 {
748         CALLBACK_CMPILD_INSTR = callback ? callback : default_cmpild_instr_callback;
749 }
750
751 void m68k_set_rte_instr_callback(void  (*callback)(void))
752 {
753         CALLBACK_RTE_INSTR = callback ? callback : default_rte_instr_callback;
754 }
755
756 void m68k_set_tas_instr_callback(int  (*callback)(void))
757 {
758         CALLBACK_TAS_INSTR = callback ? callback : default_tas_instr_callback;
759 }
760
761 void m68k_set_illg_instr_callback(int  (*callback)(int))
762 {
763         CALLBACK_ILLG_INSTR = callback ? callback : default_illg_instr_callback;
764 }
765
766 void m68k_set_pc_changed_callback(void  (*callback)(unsigned int new_pc))
767 {
768         CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback;
769 }
770
771 void m68k_set_fc_callback(void  (*callback)(unsigned int new_fc))
772 {
773         CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;
774 }
775
776 void m68k_set_instr_hook_callback(void  (*callback)(unsigned int pc))
777 {
778         CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
779 }
780
781 /* Set the CPU type. */
782 void m68k_set_cpu_type(unsigned int cpu_type)
783 {
784         switch(cpu_type)
785         {
786                 case M68K_CPU_TYPE_68000:
787                         CPU_TYPE         = CPU_TYPE_000;
788                         CPU_ADDRESS_MASK = 0x00ffffff;
789                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
790                         CYC_INSTRUCTION  = m68ki_cycles[0];
791                         CYC_EXCEPTION    = m68ki_exception_cycle_table[0];
792                         CYC_BCC_NOTAKE_B = -2;
793                         CYC_BCC_NOTAKE_W = 2;
794                         CYC_DBCC_F_NOEXP = -2;
795                         CYC_DBCC_F_EXP   = 2;
796                         CYC_SCC_R_TRUE   = 2;
797                         CYC_MOVEM_W      = 2;
798                         CYC_MOVEM_L      = 3;
799                         CYC_SHIFT        = 1;
800                         CYC_RESET        = 132;
801                         HAS_PMMU         = 0;
802                         HAS_FPU          = 0;
803                         return;
804                 case M68K_CPU_TYPE_SCC68070:
805                         m68k_set_cpu_type(M68K_CPU_TYPE_68010);
806                         CPU_ADDRESS_MASK = 0xffffffff;
807                         CPU_TYPE         = CPU_TYPE_SCC070;
808                         return;
809                 case M68K_CPU_TYPE_68010:
810                         CPU_TYPE         = CPU_TYPE_010;
811                         CPU_ADDRESS_MASK = 0x00ffffff;
812                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
813                         CYC_INSTRUCTION  = m68ki_cycles[1];
814                         CYC_EXCEPTION    = m68ki_exception_cycle_table[1];
815                         CYC_BCC_NOTAKE_B = -4;
816                         CYC_BCC_NOTAKE_W = 0;
817                         CYC_DBCC_F_NOEXP = 0;
818                         CYC_DBCC_F_EXP   = 6;
819                         CYC_SCC_R_TRUE   = 0;
820                         CYC_MOVEM_W      = 2;
821                         CYC_MOVEM_L      = 3;
822                         CYC_SHIFT        = 1;
823                         CYC_RESET        = 130;
824                         HAS_PMMU         = 0;
825                         HAS_FPU          = 0;
826                         return;
827                 case M68K_CPU_TYPE_68EC020:
828                         CPU_TYPE         = CPU_TYPE_EC020;
829                         CPU_ADDRESS_MASK = 0x00ffffff;
830                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
831                         CYC_INSTRUCTION  = m68ki_cycles[2];
832                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
833                         CYC_BCC_NOTAKE_B = -2;
834                         CYC_BCC_NOTAKE_W = 0;
835                         CYC_DBCC_F_NOEXP = 0;
836                         CYC_DBCC_F_EXP   = 4;
837                         CYC_SCC_R_TRUE   = 0;
838                         CYC_MOVEM_W      = 2;
839                         CYC_MOVEM_L      = 2;
840                         CYC_SHIFT        = 0;
841                         CYC_RESET        = 518;
842                         HAS_PMMU         = 0;
843                         HAS_FPU          = 0;
844                         return;
845                 case M68K_CPU_TYPE_68020:
846                         CPU_TYPE         = CPU_TYPE_020;
847                         CPU_ADDRESS_MASK = 0xffffffff;
848                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
849                         CYC_INSTRUCTION  = m68ki_cycles[2];
850                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
851                         CYC_BCC_NOTAKE_B = -2;
852                         CYC_BCC_NOTAKE_W = 0;
853                         CYC_DBCC_F_NOEXP = 0;
854                         CYC_DBCC_F_EXP   = 4;
855                         CYC_SCC_R_TRUE   = 0;
856                         CYC_MOVEM_W      = 2;
857                         CYC_MOVEM_L      = 2;
858                         CYC_SHIFT        = 0;
859                         CYC_RESET        = 518;
860                         HAS_PMMU         = 0;
861                         HAS_FPU          = 0;
862                         return;
863                 case M68K_CPU_TYPE_68030:
864                         CPU_TYPE         = CPU_TYPE_030;
865                         CPU_ADDRESS_MASK = 0xffffffff;
866                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
867                         CYC_INSTRUCTION  = m68ki_cycles[3];
868                         CYC_EXCEPTION    = m68ki_exception_cycle_table[3];
869                         CYC_BCC_NOTAKE_B = -2;
870                         CYC_BCC_NOTAKE_W = 0;
871                         CYC_DBCC_F_NOEXP = 0;
872                         CYC_DBCC_F_EXP   = 4;
873                         CYC_SCC_R_TRUE   = 0;
874                         CYC_MOVEM_W      = 2;
875                         CYC_MOVEM_L      = 2;
876                         CYC_SHIFT        = 0;
877                         CYC_RESET        = 518;
878                         HAS_PMMU         = 1;
879                         HAS_FPU          = 1;
880                         return;
881                 case M68K_CPU_TYPE_68EC030:
882                         CPU_TYPE         = CPU_TYPE_EC030;
883                         CPU_ADDRESS_MASK = 0xffffffff;
884                         CPU_SR_MASK          = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
885                         CYC_INSTRUCTION  = m68ki_cycles[3];
886                         CYC_EXCEPTION    = m68ki_exception_cycle_table[3];
887                         CYC_BCC_NOTAKE_B = -2;
888                         CYC_BCC_NOTAKE_W = 0;
889                         CYC_DBCC_F_NOEXP = 0;
890                         CYC_DBCC_F_EXP   = 4;
891                         CYC_SCC_R_TRUE   = 0;
892                         CYC_MOVEM_W      = 2;
893                         CYC_MOVEM_L      = 2;
894                         CYC_SHIFT        = 0;
895                         CYC_RESET        = 518;
896                         HAS_PMMU         = 0;           /* EC030 lacks the PMMU and is effectively a die-shrink 68020 */
897                         HAS_FPU          = 1;
898                         return;
899                 case M68K_CPU_TYPE_68040:               // TODO: these values are not correct
900                         CPU_TYPE         = CPU_TYPE_040;
901                         CPU_ADDRESS_MASK = 0xffffffff;
902                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
903                         CYC_INSTRUCTION  = m68ki_cycles[4];
904                         CYC_EXCEPTION    = m68ki_exception_cycle_table[4];
905                         CYC_BCC_NOTAKE_B = -2;
906                         CYC_BCC_NOTAKE_W = 0;
907                         CYC_DBCC_F_NOEXP = 0;
908                         CYC_DBCC_F_EXP   = 4;
909                         CYC_SCC_R_TRUE   = 0;
910                         CYC_MOVEM_W      = 2;
911                         CYC_MOVEM_L      = 2;
912                         CYC_SHIFT        = 0;
913                         CYC_RESET        = 518;
914                         HAS_PMMU         = 1;
915                         HAS_FPU          = 1;
916                         return;
917                 case M68K_CPU_TYPE_68EC040: // Just a 68040 without pmmu apparently...
918                         CPU_TYPE         = CPU_TYPE_EC040;
919                         CPU_ADDRESS_MASK = 0xffffffff;
920                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
921                         CYC_INSTRUCTION  = m68ki_cycles[4];
922                         CYC_EXCEPTION    = m68ki_exception_cycle_table[4];
923                         CYC_BCC_NOTAKE_B = -2;
924                         CYC_BCC_NOTAKE_W = 0;
925                         CYC_DBCC_F_NOEXP = 0;
926                         CYC_DBCC_F_EXP   = 4;
927                         CYC_SCC_R_TRUE   = 0;
928                         CYC_MOVEM_W      = 2;
929                         CYC_MOVEM_L      = 2;
930                         CYC_SHIFT        = 0;
931                         CYC_RESET        = 518;
932                         HAS_PMMU         = 0;
933                         HAS_FPU          = 0;
934                         return;
935                 case M68K_CPU_TYPE_68LC040:
936                         CPU_TYPE         = CPU_TYPE_LC040;
937                         CPU_ADDRESS_MASK = 0xffffffff;
938                         m68ki_cpu.sr_mask          = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
939                         m68ki_cpu.cyc_instruction  = m68ki_cycles[4];
940                         m68ki_cpu.cyc_exception    = m68ki_exception_cycle_table[4];
941                         m68ki_cpu.cyc_bcc_notake_b = -2;
942                         m68ki_cpu.cyc_bcc_notake_w = 0;
943                         m68ki_cpu.cyc_dbcc_f_noexp = 0;
944                         m68ki_cpu.cyc_dbcc_f_exp   = 4;
945                         m68ki_cpu.cyc_scc_r_true   = 0;
946                         m68ki_cpu.cyc_movem_w      = 2;
947                         m68ki_cpu.cyc_movem_l      = 2;
948                         m68ki_cpu.cyc_shift        = 0;
949                         m68ki_cpu.cyc_reset        = 518;
950                         HAS_PMMU         = 1;
951                         HAS_FPU          = 0;
952                         return;
953         }
954 }
955
956 uint m68k_get_address_mask() {
957         return m68ki_cpu.address_mask;
958 }
959
960 /* Execute some instructions until we use up num_cycles clock cycles */
961 /* ASG: removed per-instruction interrupt checks */
962 int m68k_execute(int num_cycles)
963 {
964         /* eat up any reset cycles */
965         if (RESET_CYCLES) {
966             int rc = RESET_CYCLES;
967             RESET_CYCLES = 0;
968             num_cycles -= rc;
969             if (num_cycles <= 0)
970                 return rc;
971         }
972
973         /* Set our pool of clock cycles available */
974         SET_CYCLES(num_cycles);
975         m68ki_initial_cycles = num_cycles;
976
977         /* See if interrupts came in */
978         m68ki_check_interrupts();
979
980         /* Make sure we're not stopped */
981         if(!CPU_STOPPED)
982         {
983                 /* Return point if we had an address error */
984                 m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
985
986 #ifdef M68K_BUSERR_THING
987                 m68ki_check_bus_error_trap();
988 #endif
989
990                 /* Main loop.  Keep going until we run out of clock cycles */
991                 do
992                 {
993                         /* Set tracing accodring to T1. (T0 is done inside instruction) */
994                         m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
995
996                         /* Set the address space for reads */
997                         m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
998
999                         /* Call external hook to peek at CPU */
1000                         m68ki_instr_hook(REG_PC); /* auto-disable (see m68kcpu.h) */
1001
1002                         /* Record previous program counter */
1003                         REG_PPC = REG_PC;
1004
1005                         /* Record previous D/A register state (in case of bus error) */
1006 //#define M68K_BUSERR_THING
1007 #ifdef M68K_BUSERR_THING
1008                         for (int i = 15; i >= 0; i--){
1009                                 REG_DA_SAVE[i] = REG_DA[i];
1010                         }
1011 #endif
1012
1013                         /* Read an instruction and call its handler */
1014                         REG_IR = m68ki_read_imm_16();
1015                         m68ki_instruction_jump_table[REG_IR]();
1016                         USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
1017
1018                         /* Trace m68k_exception, if necessary */
1019                         m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
1020                 } while(GET_CYCLES() > 0);
1021
1022                 /* set previous PC to current PC for the next entry into the loop */
1023                 REG_PPC = REG_PC;
1024         }
1025         else
1026                 SET_CYCLES(0);
1027
1028         /* return how many clocks we used */
1029         return m68ki_initial_cycles - GET_CYCLES();
1030 }
1031
1032
1033 int m68k_cycles_run(void)
1034 {
1035         return m68ki_initial_cycles - GET_CYCLES();
1036 }
1037
1038 int m68k_cycles_remaining(void)
1039 {
1040         return GET_CYCLES();
1041 }
1042
1043 /* Change the timeslice */
1044 void m68k_modify_timeslice(int cycles)
1045 {
1046         m68ki_initial_cycles += cycles;
1047         ADD_CYCLES(cycles);
1048 }
1049
1050
1051 void m68k_end_timeslice(void)
1052 {
1053         m68ki_initial_cycles = GET_CYCLES();
1054         SET_CYCLES(0);
1055 }
1056
1057
1058 /* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
1059 /* KS: Modified so that IPL* bits match with mask positions in the SR
1060  *     and cleaned out remenants of the interrupt controller.
1061  */
1062 void m68k_set_irq(unsigned int int_level)
1063 {
1064         uint old_level = CPU_INT_LEVEL;
1065         CPU_INT_LEVEL = int_level << 8;
1066
1067         /* A transition from < 7 to 7 always interrupts (NMI) */
1068         /* Note: Level 7 can also level trigger like a normal IRQ */
1069         if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
1070                 m68ki_cpu.nmi_pending = TRUE;
1071 }
1072
1073 void m68k_set_virq(unsigned int level, unsigned int active)
1074 {
1075         uint state = m68ki_cpu.virq_state;
1076         uint blevel;
1077
1078         if(active)
1079                 state |= 1 << level;
1080         else
1081                 state &= ~(1 << level);
1082         m68ki_cpu.virq_state = state;
1083
1084         for(blevel = 7; blevel > 0; blevel--)
1085                 if(state & (1 << blevel))
1086                         break;
1087         m68k_set_irq(blevel);
1088 }
1089
1090 unsigned int m68k_get_virq(unsigned int level)
1091 {
1092         return (m68ki_cpu.virq_state & (1 << level)) ? 1 : 0;
1093 }
1094
1095 void m68k_init(void)
1096 {
1097         static uint emulation_initialized = 0;
1098
1099         /* The first call to this function initializes the opcode handler jump table */
1100         if(!emulation_initialized)
1101         {
1102                 m68ki_build_opcode_table();
1103                 emulation_initialized = 1;
1104         }
1105
1106         m68k_set_int_ack_callback(NULL);
1107         m68k_set_bkpt_ack_callback(NULL);
1108         m68k_set_reset_instr_callback(NULL);
1109         m68k_set_cmpild_instr_callback(NULL);
1110         m68k_set_rte_instr_callback(NULL);
1111         m68k_set_tas_instr_callback(NULL);
1112         m68k_set_illg_instr_callback(NULL);
1113         m68k_set_pc_changed_callback(NULL);
1114         m68k_set_fc_callback(NULL);
1115         m68k_set_instr_hook_callback(NULL);
1116 }
1117
1118 /* Trigger a Bus Error exception */
1119 void m68k_pulse_bus_error(void)
1120 {
1121         m68ki_exception_bus_error();
1122 }
1123
1124 /* Pulse the RESET line on the CPU */
1125 void m68k_pulse_reset(void)
1126 {
1127         /* Disable the PMMU/HMMU on reset, if any */
1128         m68ki_cpu.pmmu_enabled = 0;
1129 //      m68ki_cpu.hmmu_enabled = 0;
1130
1131         m68ki_cpu.mmu_tc = 0;
1132         m68ki_cpu.mmu_tt0 = 0;
1133         m68ki_cpu.mmu_tt1 = 0;
1134
1135         /* Clear all stop levels and eat up all remaining cycles */
1136         CPU_STOPPED = 0;
1137         SET_CYCLES(0);
1138
1139         CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
1140         CPU_INSTR_MODE = INSTRUCTION_YES;
1141
1142         /* Turn off tracing */
1143         FLAG_T1 = FLAG_T0 = 0;
1144         m68ki_clear_trace();
1145         /* Interrupt mask to level 7 */
1146         FLAG_INT_MASK = 0x0700;
1147         CPU_INT_LEVEL = 0;
1148         m68ki_cpu.virq_state = 0;
1149         /* Reset VBR */
1150         REG_VBR = 0;
1151         /* Go to supervisor mode */
1152         m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);
1153
1154         /* Invalidate the prefetch queue */
1155 #if M68K_EMULATE_PREFETCH
1156         /* Set to arbitrary number since our first fetch is from 0 */
1157         CPU_PREF_ADDR = 0x1000;
1158 #endif /* M68K_EMULATE_PREFETCH */
1159
1160         /* Read the initial stack pointer and program counter */
1161         m68ki_jump(0);
1162         REG_SP = m68ki_read_imm_32();
1163         REG_PC = m68ki_read_imm_32();
1164         m68ki_jump(REG_PC);
1165
1166         CPU_RUN_MODE = RUN_MODE_NORMAL;
1167
1168         RESET_CYCLES = CYC_EXCEPTION[EXCEPTION_RESET];
1169
1170         /* flush the MMU's cache */
1171         pmmu_atc_flush();
1172
1173         if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
1174         {
1175                 // clear instruction cache
1176                 m68ki_ic_clear();
1177         }
1178 }
1179
1180 /* Pulse the HALT line on the CPU */
1181 void m68k_pulse_halt(void)
1182 {
1183         CPU_STOPPED |= STOP_LEVEL_HALT;
1184 }
1185
1186 /* Get and set the current CPU context */
1187 /* This is to allow for multiple CPUs */
1188 unsigned int m68k_context_size()
1189 {
1190         return sizeof(m68ki_cpu_core);
1191 }
1192
1193 unsigned int m68k_get_context(void* dst)
1194 {
1195         if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;
1196         return sizeof(m68ki_cpu_core);
1197 }
1198
1199 void m68k_set_context(void* src)
1200 {
1201         if(src) m68ki_cpu = *(m68ki_cpu_core*)src;
1202 }
1203
1204 #if M68K_SEPARATE_READS
1205 /* Read data immediately following the PC */
1206 inline unsigned int  m68k_read_immediate_16(unsigned int address) {
1207 #if M68K_EMULATE_PREFETCH == OPT_ON
1208         for (int i = 0; i < read_ranges; i++) {
1209                 if(address >= read_addr[i] && address < read_upper[i]) {
1210                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1211                 }
1212         }
1213 #endif
1214
1215         return m68k_read_memory_16(address);
1216 }
1217 inline unsigned int  m68k_read_immediate_32(unsigned int address) {
1218 #if M68K_EMULATE_PREFETCH == OPT_ON
1219         for (int i = 0; i < read_ranges; i++) {
1220                 if(address >= read_addr[i] && address < read_upper[i]) {
1221                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1222                 }
1223         }
1224 #endif
1225
1226         return m68k_read_memory_32(address);
1227 }
1228
1229 /* Read data relative to the PC */
1230 inline unsigned int  m68k_read_pcrelative_8(unsigned int address) {
1231         for (int i = 0; i < read_ranges; i++) {
1232                 if(address >= read_addr[i] && address < read_upper[i]) {
1233                         return read_data[i][address - read_addr[i]];
1234                 }
1235         }
1236
1237         return m68k_read_memory_8(address);
1238 }
1239 inline unsigned int  m68k_read_pcrelative_16(unsigned int address) {
1240         for (int i = 0; i < read_ranges; i++) {
1241                 if(address >= read_addr[i] && address < read_upper[i]) {
1242                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1243                 }
1244         }
1245
1246         return m68k_read_memory_16(address);
1247 }
1248 inline unsigned int  m68k_read_pcrelative_32(unsigned int address) {
1249         for (int i = 0; i < read_ranges; i++) {
1250                 if(address >= read_addr[i] && address < read_upper[i]) {
1251                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1252                 }
1253         }
1254
1255     return m68k_read_memory_32(address);
1256 }
1257 #endif
1258
1259
1260 uint m68ki_read_imm6_addr_slowpath(uint32_t pc, address_translation_cache *cache)
1261 {
1262     uint32_t address = ADDRESS_68K(pc);
1263     uint32_t pc_address_diff = pc - address;
1264         for (int i = 0; i < read_ranges; i++) {
1265                 if(address >= read_addr[i] && address < read_upper[i]) {
1266             cache->lower = read_addr[i] + pc_address_diff;
1267             cache->upper = read_upper[i] + pc_address_diff;
1268             cache->data = read_data[i];
1269                         REG_PC += 2;
1270                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1271                 }
1272         }
1273
1274         m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1275         m68ki_cpu.mmu_tmp_fc = FLAG_S | FUNCTION_CODE_USER_PROGRAM;
1276         m68ki_cpu.mmu_tmp_rw = 1;
1277         m68ki_cpu.mmu_tmp_sz = M68K_SZ_WORD;
1278         m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
1279
1280 #if M68K_EMULATE_PREFETCH
1281 {
1282         uint result;
1283         if(REG_PC != CPU_PREF_ADDR)
1284         {
1285                 CPU_PREF_DATA = m68ki_ic_readimm16(REG_PC);
1286                 CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
1287         }
1288         result = MASK_OUT_ABOVE_16(CPU_PREF_DATA);
1289         REG_PC += 2;
1290         if (!m68ki_cpu.mmu_tmp_buserror_occurred) {
1291                 // prefetch only if no bus error occurred in opcode fetch
1292                 CPU_PREF_DATA = m68ki_ic_readimm16(REG_PC);
1293                 CPU_PREF_ADDR = m68ki_cpu.mmu_tmp_buserror_occurred ? ((uint32)~0) : REG_PC;
1294                 // ignore bus error on prefetch
1295                 m68ki_cpu.mmu_tmp_buserror_occurred = 0;
1296         }
1297         return result;
1298 }
1299 #else
1300         REG_PC += 2;
1301
1302         return m68k_read_immediate_16(address);
1303 #endif /* M68K_EMULATE_PREFETCH */
1304 }
1305
1306
1307
1308 void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
1309 {
1310     code_translation_cache.lower = 0;
1311     code_translation_cache.upper = 0;
1312         if ((addr == 0 && upper == 0) || upper < addr)
1313                 return;
1314
1315         for (int i = 0; i < write_ranges; i++) {
1316                 if (write_addr[i] == addr) {
1317                         uint8_t changed = 0;
1318                         if (write_upper[i] != upper) {
1319                                 write_upper[i] = upper;
1320                                 changed = 1;
1321                         }
1322                         if (write_data[i] != ptr) {
1323                                 write_data[i] = ptr;
1324                                 changed = 1;
1325                         }
1326                         if (changed) {
1327                                 printf("[MUSASHI] Adjusted mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr);
1328                         }
1329                         return;
1330                 }
1331         }
1332
1333         if (read_ranges + 1 < 8) {
1334                 read_addr[read_ranges] = addr;
1335                 read_upper[read_ranges] = upper;
1336                 read_data[read_ranges] = ptr;
1337                 read_ranges++;
1338                 printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1339         }
1340         else {
1341                 printf("Can't Musashi map more than eight RAM/ROM read ranges.\n");
1342         }
1343         if (write_ranges + 1 < 8) {
1344                 write_addr[write_ranges] = addr;
1345                 write_upper[write_ranges] = upper;
1346                 write_data[write_ranges] = ptr;
1347                 write_ranges++;
1348                 printf("[MUSASHI] Mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr);
1349         }
1350         else {
1351                 printf("Can't Musashi map more than eight RAM write ranges.\n");
1352         }
1353 }
1354
1355 void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
1356 {
1357     code_translation_cache.lower = 0;
1358     code_translation_cache.upper = 0;
1359         if ((addr == 0 && upper == 0) || upper < addr)
1360                 return;
1361
1362         for (int i = 0; i < read_ranges; i++) {
1363                 if (read_addr[i] == addr) {
1364                         uint8_t changed = 0;
1365                         if (read_upper[i] != upper) {
1366                                 read_upper[i] = upper;
1367                                 changed = 1;
1368                         }
1369                         if (read_data[i] != ptr) {
1370                                 read_data[i] = ptr;
1371                                 changed = 1;
1372                         }
1373                         if (changed) {
1374                                 printf("[MUSASHI] Adjusted mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1375                         }
1376                         return;
1377                 }
1378         }
1379
1380         if (read_ranges + 1 < 8) {
1381                 read_addr[read_ranges] = addr;
1382                 read_upper[read_ranges] = upper;
1383                 read_data[read_ranges] = ptr;
1384                 read_ranges++;
1385                 printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1386         }
1387         else {
1388                 printf("Can't Musashi map more than eight RAM/ROM read ranges.\n");
1389         }
1390 }
1391
1392 void m68k_clear_ranges()
1393 {
1394         printf("[MUSASHI] Clearing all reads/write memory ranges.\n");
1395         for (int i = 0; i < 8; i++) {
1396                 read_upper[i] = 0;
1397                 read_addr[i] = 0;
1398                 read_data[i] = NULL;
1399                 write_upper[i] = 0;
1400                 write_addr[i] = 0;
1401                 write_data[i] = NULL;
1402         }
1403         write_ranges = 0;
1404         read_ranges = 0;
1405 }
1406
1407 /* ======================================================================== */
1408 /* ============================== MAME STUFF ============================== */
1409 /* ======================================================================== */
1410
1411 #if M68K_COMPILE_FOR_MAME == OPT_ON
1412
1413 static struct {
1414         UINT16 sr;
1415         UINT8 stopped;
1416         UINT8 halted;
1417 } m68k_substate;
1418
1419 static void m68k_prepare_substate(void)
1420 {
1421         m68k_substate.sr = m68ki_get_sr();
1422         m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;
1423         m68k_substate.halted  = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;
1424 }
1425
1426 static void m68k_post_load(void)
1427 {
1428         m68ki_set_sr_noint_nosp(m68k_substate.sr);
1429         CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0
1430                         | m68k_substate.halted  ? STOP_LEVEL_HALT : 0;
1431         m68ki_jump(REG_PC);
1432 }
1433
1434 void m68k_state_register(const char *type, int index)
1435 {
1436         /* Note, D covers A because the dar array is common, REG_A=REG_D+8 */
1437         state_save_register_item_array(type, index, REG_D);
1438         state_save_register_item(type, index, REG_PPC);
1439         state_save_register_item(type, index, REG_PC);
1440         state_save_register_item(type, index, REG_USP);
1441         state_save_register_item(type, index, REG_ISP);
1442         state_save_register_item(type, index, REG_MSP);
1443         state_save_register_item(type, index, REG_VBR);
1444         state_save_register_item(type, index, REG_SFC);
1445         state_save_register_item(type, index, REG_DFC);
1446         state_save_register_item(type, index, REG_CACR);
1447         state_save_register_item(type, index, REG_CAAR);
1448         state_save_register_item(type, index, m68k_substate.sr);
1449         state_save_register_item(type, index, CPU_INT_LEVEL);
1450         state_save_register_item(type, index, m68k_substate.stopped);
1451         state_save_register_item(type, index, m68k_substate.halted);
1452         state_save_register_item(type, index, CPU_PREF_ADDR);
1453         state_save_register_item(type, index, CPU_PREF_DATA);
1454         state_save_register_func_presave(m68k_prepare_substate);
1455         state_save_register_func_postload(m68k_post_load);
1456 }
1457
1458 #endif /* M68K_COMPILE_FOR_MAME */
1459
1460 /* ======================================================================== */
1461 /* ============================== END OF FILE ============================= */
1462 /* ======================================================================== */