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