]> git.sesse.net Git - pistorm/blob - m68kcpu.c
MMU and InstructionCache update (MAME's latest code)
[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 #ifdef M68K_BUSERR_THING
994                         int i;
995 #endif
996                         /* Set tracing accodring 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 #ifdef M68K_BUSERR_THING
1010                         for (i = 15; i >= 0; i--){
1011                                 REG_DA_SAVE[i] = REG_DA[i];
1012                         }
1013 #endif
1014
1015                         /* Read an instruction and call its handler */
1016                         REG_IR = m68ki_read_imm_16();
1017                         m68ki_instruction_jump_table[REG_IR]();
1018                         USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
1019
1020                         /* Trace m68k_exception, if necessary */
1021                         m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
1022                 } while(GET_CYCLES() > 0);
1023
1024                 /* set previous PC to current PC for the next entry into the loop */
1025                 REG_PPC = REG_PC;
1026         }
1027         else
1028                 SET_CYCLES(0);
1029
1030         /* return how many clocks we used */
1031         return m68ki_initial_cycles - GET_CYCLES();
1032 }
1033
1034
1035 int m68k_cycles_run(void)
1036 {
1037         return m68ki_initial_cycles - GET_CYCLES();
1038 }
1039
1040 int m68k_cycles_remaining(void)
1041 {
1042         return GET_CYCLES();
1043 }
1044
1045 /* Change the timeslice */
1046 void m68k_modify_timeslice(int cycles)
1047 {
1048         m68ki_initial_cycles += cycles;
1049         ADD_CYCLES(cycles);
1050 }
1051
1052
1053 void m68k_end_timeslice(void)
1054 {
1055         m68ki_initial_cycles = GET_CYCLES();
1056         SET_CYCLES(0);
1057 }
1058
1059
1060 /* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
1061 /* KS: Modified so that IPL* bits match with mask positions in the SR
1062  *     and cleaned out remenants of the interrupt controller.
1063  */
1064 void m68k_set_irq(unsigned int int_level)
1065 {
1066         uint old_level = CPU_INT_LEVEL;
1067         CPU_INT_LEVEL = int_level << 8;
1068
1069         /* A transition from < 7 to 7 always interrupts (NMI) */
1070         /* Note: Level 7 can also level trigger like a normal IRQ */
1071         if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
1072                 m68ki_cpu.nmi_pending = TRUE;
1073 }
1074
1075 void m68k_set_virq(unsigned int level, unsigned int active)
1076 {
1077         uint state = m68ki_cpu.virq_state;
1078         uint blevel;
1079
1080         if(active)
1081                 state |= 1 << level;
1082         else
1083                 state &= ~(1 << level);
1084         m68ki_cpu.virq_state = state;
1085
1086         for(blevel = 7; blevel > 0; blevel--)
1087                 if(state & (1 << blevel))
1088                         break;
1089         m68k_set_irq(blevel);
1090 }
1091
1092 unsigned int m68k_get_virq(unsigned int level)
1093 {
1094         return (m68ki_cpu.virq_state & (1 << level)) ? 1 : 0;
1095 }
1096
1097 void m68k_init(void)
1098 {
1099         static uint emulation_initialized = 0;
1100
1101         /* The first call to this function initializes the opcode handler jump table */
1102         if(!emulation_initialized)
1103         {
1104                 m68ki_build_opcode_table();
1105                 emulation_initialized = 1;
1106         }
1107
1108         m68k_set_int_ack_callback(NULL);
1109         m68k_set_bkpt_ack_callback(NULL);
1110         m68k_set_reset_instr_callback(NULL);
1111         m68k_set_cmpild_instr_callback(NULL);
1112         m68k_set_rte_instr_callback(NULL);
1113         m68k_set_tas_instr_callback(NULL);
1114         m68k_set_illg_instr_callback(NULL);
1115         m68k_set_pc_changed_callback(NULL);
1116         m68k_set_fc_callback(NULL);
1117         m68k_set_instr_hook_callback(NULL);
1118 }
1119
1120 /* Trigger a Bus Error exception */
1121 void m68k_pulse_bus_error(void)
1122 {
1123         m68ki_exception_bus_error();
1124 }
1125
1126 /* Pulse the RESET line on the CPU */
1127 void m68k_pulse_reset(void)
1128 {
1129         /* Disable the PMMU/HMMU on reset, if any */
1130         m68ki_cpu.pmmu_enabled = 0;
1131 //      m68ki_cpu.hmmu_enabled = 0;
1132
1133         m68ki_cpu.mmu_tc = 0;
1134         m68ki_cpu.mmu_tt0 = 0;
1135         m68ki_cpu.mmu_tt1 = 0;
1136
1137         /* Clear all stop levels and eat up all remaining cycles */
1138         CPU_STOPPED = 0;
1139         SET_CYCLES(0);
1140
1141         CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
1142         CPU_INSTR_MODE = INSTRUCTION_YES;
1143
1144         /* Turn off tracing */
1145         FLAG_T1 = FLAG_T0 = 0;
1146         m68ki_clear_trace();
1147         /* Interrupt mask to level 7 */
1148         FLAG_INT_MASK = 0x0700;
1149         CPU_INT_LEVEL = 0;
1150         m68ki_cpu.virq_state = 0;
1151         /* Reset VBR */
1152         REG_VBR = 0;
1153         /* Go to supervisor mode */
1154         m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);
1155
1156         /* Invalidate the prefetch queue */
1157 #if M68K_EMULATE_PREFETCH
1158         /* Set to arbitrary number since our first fetch is from 0 */
1159         CPU_PREF_ADDR = 0x1000;
1160 #endif /* M68K_EMULATE_PREFETCH */
1161
1162         /* Read the initial stack pointer and program counter */
1163         m68ki_jump(0);
1164         REG_SP = m68ki_read_imm_32();
1165         REG_PC = m68ki_read_imm_32();
1166         m68ki_jump(REG_PC);
1167
1168         CPU_RUN_MODE = RUN_MODE_NORMAL;
1169
1170         RESET_CYCLES = CYC_EXCEPTION[EXCEPTION_RESET];
1171
1172         /* flush the MMU's cache */
1173         pmmu_atc_flush();
1174
1175         if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
1176         {
1177                 // clear instruction cache
1178                 m68ki_ic_clear();
1179         }
1180 }
1181
1182 /* Pulse the HALT line on the CPU */
1183 void m68k_pulse_halt(void)
1184 {
1185         CPU_STOPPED |= STOP_LEVEL_HALT;
1186 }
1187
1188 /* Get and set the current CPU context */
1189 /* This is to allow for multiple CPUs */
1190 unsigned int m68k_context_size()
1191 {
1192         return sizeof(m68ki_cpu_core);
1193 }
1194
1195 unsigned int m68k_get_context(void* dst)
1196 {
1197         if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;
1198         return sizeof(m68ki_cpu_core);
1199 }
1200
1201 void m68k_set_context(void* src)
1202 {
1203         if(src) m68ki_cpu = *(m68ki_cpu_core*)src;
1204 }
1205
1206 #if M68K_SEPARATE_READS
1207 /* Read data immediately following the PC */
1208 inline unsigned int  m68k_read_immediate_16(unsigned int address) {
1209 #if M68K_EMULATE_PREFETCH == OPT_ON
1210         for (int i = 0; i < read_ranges; i++) {
1211                 if(address >= read_addr[i] && address < read_upper[i]) {
1212                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1213                 }
1214         }
1215 #endif
1216         
1217         return m68k_read_memory_16(address);
1218 }
1219 inline unsigned int  m68k_read_immediate_32(unsigned int address) {
1220 #if M68K_EMULATE_PREFETCH == OPT_ON
1221         for (int i = 0; i < read_ranges; i++) {
1222                 if(address >= read_addr[i] && address < read_upper[i]) {
1223                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1224                 }
1225         }
1226 #endif
1227
1228         return m68k_read_memory_32(address);
1229 }
1230
1231 /* Read data relative to the PC */
1232 inline unsigned int  m68k_read_pcrelative_8(unsigned int address) {
1233         for (int i = 0; i < read_ranges; i++) {
1234                 if(address >= read_addr[i] && address < read_upper[i]) {
1235                         return read_data[i][address - read_addr[i]];
1236                 }
1237         }
1238         
1239         return m68k_read_memory_8(address);
1240 }
1241 inline unsigned int  m68k_read_pcrelative_16(unsigned int address) {
1242         for (int i = 0; i < read_ranges; i++) {
1243                 if(address >= read_addr[i] && address < read_upper[i]) {
1244                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1245                 }
1246         }
1247
1248         return m68k_read_memory_16(address);
1249 }
1250 inline unsigned int  m68k_read_pcrelative_32(unsigned int address) {
1251         for (int i = 0; i < read_ranges; i++) {
1252                 if(address >= read_addr[i] && address < read_upper[i]) {
1253                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1254                 }
1255         }
1256
1257     return m68k_read_memory_32(address);
1258 }
1259 #endif
1260
1261 void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
1262 {
1263         if ((addr == 0 && upper == 0) || upper < addr)
1264                 return;
1265
1266         for (int i = 0; i < write_ranges; i++) {
1267                 if (write_addr[i] == addr) {
1268                         uint8_t changed = 0;
1269                         if (write_upper[i] != upper) {
1270                                 write_upper[i] = upper;
1271                                 changed = 1;
1272                         }
1273                         if (write_data[i] != ptr) {
1274                                 write_data[i] = ptr;
1275                                 changed = 1;
1276                         }
1277                         if (changed) {
1278                                 printf("[MUSASHI] Adjusted mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr);
1279                         }
1280                         return;
1281                 }
1282         }
1283
1284         if (read_ranges + 1 < 8) {
1285                 read_addr[read_ranges] = addr;
1286                 read_upper[read_ranges] = upper;
1287                 read_data[read_ranges] = ptr;
1288                 read_ranges++;
1289                 printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1290         }
1291         else {
1292                 printf("Can't Musashi map more than eight RAM/ROM read ranges.\n");
1293         }
1294         if (write_ranges + 1 < 8) {
1295                 write_addr[write_ranges] = addr;
1296                 write_upper[write_ranges] = upper;
1297                 write_data[write_ranges] = ptr;
1298                 write_ranges++;
1299                 printf("[MUSASHI] Mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr);
1300         }
1301         else {
1302                 printf("Can't Musashi map more than eight RAM write ranges.\n");
1303         }
1304 }
1305
1306 void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
1307 {
1308         if ((addr == 0 && upper == 0) || upper < addr)
1309                 return;
1310
1311         for (int i = 0; i < read_ranges; i++) {
1312                 if (read_addr[i] == addr) {
1313                         uint8_t changed = 0;
1314                         if (read_upper[i] != upper) {
1315                                 read_upper[i] = upper;
1316                                 changed = 1;
1317                         }
1318                         if (read_data[i] != ptr) {
1319                                 read_data[i] = ptr;
1320                                 changed = 1;
1321                         }
1322                         if (changed) {
1323                                 printf("[MUSASHI] Adjusted mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1324                         }
1325                         return;
1326                 }
1327         }
1328
1329         if (read_ranges + 1 < 8) {
1330                 read_addr[read_ranges] = addr;
1331                 read_upper[read_ranges] = upper;
1332                 read_data[read_ranges] = ptr;
1333                 read_ranges++;
1334                 printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1335         }
1336         else {
1337                 printf("Can't Musashi map more than eight RAM/ROM read ranges.\n");
1338         }
1339 }
1340
1341 /* ======================================================================== */
1342 /* ============================== MAME STUFF ============================== */
1343 /* ======================================================================== */
1344
1345 #if M68K_COMPILE_FOR_MAME == OPT_ON
1346
1347 static struct {
1348         UINT16 sr;
1349         UINT8 stopped;
1350         UINT8 halted;
1351 } m68k_substate;
1352
1353 static void m68k_prepare_substate(void)
1354 {
1355         m68k_substate.sr = m68ki_get_sr();
1356         m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;
1357         m68k_substate.halted  = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;
1358 }
1359
1360 static void m68k_post_load(void)
1361 {
1362         m68ki_set_sr_noint_nosp(m68k_substate.sr);
1363         CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0
1364                         | m68k_substate.halted  ? STOP_LEVEL_HALT : 0;
1365         m68ki_jump(REG_PC);
1366 }
1367
1368 void m68k_state_register(const char *type, int index)
1369 {
1370         /* Note, D covers A because the dar array is common, REG_A=REG_D+8 */
1371         state_save_register_item_array(type, index, REG_D);
1372         state_save_register_item(type, index, REG_PPC);
1373         state_save_register_item(type, index, REG_PC);
1374         state_save_register_item(type, index, REG_USP);
1375         state_save_register_item(type, index, REG_ISP);
1376         state_save_register_item(type, index, REG_MSP);
1377         state_save_register_item(type, index, REG_VBR);
1378         state_save_register_item(type, index, REG_SFC);
1379         state_save_register_item(type, index, REG_DFC);
1380         state_save_register_item(type, index, REG_CACR);
1381         state_save_register_item(type, index, REG_CAAR);
1382         state_save_register_item(type, index, m68k_substate.sr);
1383         state_save_register_item(type, index, CPU_INT_LEVEL);
1384         state_save_register_item(type, index, m68k_substate.stopped);
1385         state_save_register_item(type, index, m68k_substate.halted);
1386         state_save_register_item(type, index, CPU_PREF_ADDR);
1387         state_save_register_item(type, index, CPU_PREF_DATA);
1388         state_save_register_func_presave(m68k_prepare_substate);
1389         state_save_register_func_postload(m68k_post_load);
1390 }
1391
1392 #endif /* M68K_COMPILE_FOR_MAME */
1393
1394 /* ======================================================================== */
1395 /* ============================== END OF FILE ============================= */
1396 /* ======================================================================== */