]> git.sesse.net Git - pistorm/blob - m68kcpu.c
FPU update as latest MAME
[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 m68881_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                  34, /* 10: 1010                                               */
149                  34, /* 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_040:              return (unsigned int)M68K_CPU_TYPE_68040;
669                         }
670                         return M68K_CPU_TYPE_INVALID;
671                 default:                        return 0;
672         }
673         return 0;
674 }
675
676 void m68k_set_reg(m68k_register_t regnum, unsigned int value)
677 {
678         switch(regnum)
679         {
680                 case M68K_REG_D0:       REG_D[0] = MASK_OUT_ABOVE_32(value); return;
681                 case M68K_REG_D1:       REG_D[1] = MASK_OUT_ABOVE_32(value); return;
682                 case M68K_REG_D2:       REG_D[2] = MASK_OUT_ABOVE_32(value); return;
683                 case M68K_REG_D3:       REG_D[3] = MASK_OUT_ABOVE_32(value); return;
684                 case M68K_REG_D4:       REG_D[4] = MASK_OUT_ABOVE_32(value); return;
685                 case M68K_REG_D5:       REG_D[5] = MASK_OUT_ABOVE_32(value); return;
686                 case M68K_REG_D6:       REG_D[6] = MASK_OUT_ABOVE_32(value); return;
687                 case M68K_REG_D7:       REG_D[7] = MASK_OUT_ABOVE_32(value); return;
688                 case M68K_REG_A0:       REG_A[0] = MASK_OUT_ABOVE_32(value); return;
689                 case M68K_REG_A1:       REG_A[1] = MASK_OUT_ABOVE_32(value); return;
690                 case M68K_REG_A2:       REG_A[2] = MASK_OUT_ABOVE_32(value); return;
691                 case M68K_REG_A3:       REG_A[3] = MASK_OUT_ABOVE_32(value); return;
692                 case M68K_REG_A4:       REG_A[4] = MASK_OUT_ABOVE_32(value); return;
693                 case M68K_REG_A5:       REG_A[5] = MASK_OUT_ABOVE_32(value); return;
694                 case M68K_REG_A6:       REG_A[6] = MASK_OUT_ABOVE_32(value); return;
695                 case M68K_REG_A7:       REG_A[7] = MASK_OUT_ABOVE_32(value); return;
696                 case M68K_REG_PC:       m68ki_jump(MASK_OUT_ABOVE_32(value)); return;
697                 case M68K_REG_SR:       m68ki_set_sr_noint_nosp(value); return;
698                 case M68K_REG_SP:       REG_SP = MASK_OUT_ABOVE_32(value); return;
699                 case M68K_REG_USP:      if(FLAG_S)
700                                                                 REG_USP = MASK_OUT_ABOVE_32(value);
701                                                         else
702                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
703                                                         return;
704                 case M68K_REG_ISP:      if(FLAG_S && !FLAG_M)
705                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
706                                                         else
707                                                                 REG_ISP = MASK_OUT_ABOVE_32(value);
708                                                         return;
709                 case M68K_REG_MSP:      if(FLAG_S && FLAG_M)
710                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
711                                                         else
712                                                                 REG_MSP = MASK_OUT_ABOVE_32(value);
713                                                         return;
714                 case M68K_REG_VBR:      REG_VBR = MASK_OUT_ABOVE_32(value); return;
715                 case M68K_REG_SFC:      REG_SFC = value & 7; return;
716                 case M68K_REG_DFC:      REG_DFC = value & 7; return;
717                 case M68K_REG_CACR:     REG_CACR = MASK_OUT_ABOVE_32(value); return;
718                 case M68K_REG_CAAR:     REG_CAAR = MASK_OUT_ABOVE_32(value); return;
719                 case M68K_REG_PPC:      REG_PPC = MASK_OUT_ABOVE_32(value); return;
720                 case M68K_REG_IR:       REG_IR = MASK_OUT_ABOVE_16(value); return;
721                 case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return;
722                 default:                        return;
723         }
724 }
725
726 /* Set the callbacks */
727 void m68k_set_int_ack_callback(int  (*callback)(int int_level))
728 {
729         CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback;
730 }
731
732 void m68k_set_bkpt_ack_callback(void  (*callback)(unsigned int data))
733 {
734         CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback;
735 }
736
737 void m68k_set_reset_instr_callback(void  (*callback)(void))
738 {
739         CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback;
740 }
741
742 void m68k_set_cmpild_instr_callback(void  (*callback)(unsigned int, int))
743 {
744         CALLBACK_CMPILD_INSTR = callback ? callback : default_cmpild_instr_callback;
745 }
746
747 void m68k_set_rte_instr_callback(void  (*callback)(void))
748 {
749         CALLBACK_RTE_INSTR = callback ? callback : default_rte_instr_callback;
750 }
751
752 void m68k_set_tas_instr_callback(int  (*callback)(void))
753 {
754         CALLBACK_TAS_INSTR = callback ? callback : default_tas_instr_callback;
755 }
756
757 void m68k_set_illg_instr_callback(int  (*callback)(int))
758 {
759         CALLBACK_ILLG_INSTR = callback ? callback : default_illg_instr_callback;
760 }
761
762 void m68k_set_pc_changed_callback(void  (*callback)(unsigned int new_pc))
763 {
764         CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback;
765 }
766
767 void m68k_set_fc_callback(void  (*callback)(unsigned int new_fc))
768 {
769         CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;
770 }
771
772 void m68k_set_instr_hook_callback(void  (*callback)(unsigned int pc))
773 {
774         CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
775 }
776
777 /* Set the CPU type. */
778 void m68k_set_cpu_type(unsigned int cpu_type)
779 {
780         switch(cpu_type)
781         {
782                 case M68K_CPU_TYPE_68000:
783                         CPU_TYPE         = CPU_TYPE_000;
784                         CPU_ADDRESS_MASK = 0x00ffffff;
785                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
786                         CYC_INSTRUCTION  = m68ki_cycles[0];
787                         CYC_EXCEPTION    = m68ki_exception_cycle_table[0];
788                         CYC_BCC_NOTAKE_B = -2;
789                         CYC_BCC_NOTAKE_W = 2;
790                         CYC_DBCC_F_NOEXP = -2;
791                         CYC_DBCC_F_EXP   = 2;
792                         CYC_SCC_R_TRUE   = 2;
793                         CYC_MOVEM_W      = 2;
794                         CYC_MOVEM_L      = 3;
795                         CYC_SHIFT        = 1;
796                         CYC_RESET        = 132;
797                         HAS_PMMU         = 0;
798                         HAS_FPU          = 0;
799                         return;
800                 case M68K_CPU_TYPE_SCC68070:
801                         m68k_set_cpu_type(M68K_CPU_TYPE_68010);
802                         CPU_ADDRESS_MASK = 0xffffffff;
803                         CPU_TYPE         = CPU_TYPE_SCC070;
804                         return;
805                 case M68K_CPU_TYPE_68010:
806                         CPU_TYPE         = CPU_TYPE_010;
807                         CPU_ADDRESS_MASK = 0x00ffffff;
808                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
809                         CYC_INSTRUCTION  = m68ki_cycles[1];
810                         CYC_EXCEPTION    = m68ki_exception_cycle_table[1];
811                         CYC_BCC_NOTAKE_B = -4;
812                         CYC_BCC_NOTAKE_W = 0;
813                         CYC_DBCC_F_NOEXP = 0;
814                         CYC_DBCC_F_EXP   = 6;
815                         CYC_SCC_R_TRUE   = 0;
816                         CYC_MOVEM_W      = 2;
817                         CYC_MOVEM_L      = 3;
818                         CYC_SHIFT        = 1;
819                         CYC_RESET        = 130;
820                         HAS_PMMU         = 0;
821                         HAS_FPU          = 0;
822                         return;
823                 case M68K_CPU_TYPE_68EC020:
824                         CPU_TYPE         = CPU_TYPE_EC020;
825                         CPU_ADDRESS_MASK = 0x00ffffff;
826                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
827                         CYC_INSTRUCTION  = m68ki_cycles[2];
828                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
829                         CYC_BCC_NOTAKE_B = -2;
830                         CYC_BCC_NOTAKE_W = 0;
831                         CYC_DBCC_F_NOEXP = 0;
832                         CYC_DBCC_F_EXP   = 4;
833                         CYC_SCC_R_TRUE   = 0;
834                         CYC_MOVEM_W      = 2;
835                         CYC_MOVEM_L      = 2;
836                         CYC_SHIFT        = 0;
837                         CYC_RESET        = 518;
838                         HAS_PMMU         = 0;
839                         HAS_FPU          = 0;
840                         return;
841                 case M68K_CPU_TYPE_68020:
842                         CPU_TYPE         = CPU_TYPE_020;
843                         CPU_ADDRESS_MASK = 0xffffffff;
844                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
845                         CYC_INSTRUCTION  = m68ki_cycles[2];
846                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
847                         CYC_BCC_NOTAKE_B = -2;
848                         CYC_BCC_NOTAKE_W = 0;
849                         CYC_DBCC_F_NOEXP = 0;
850                         CYC_DBCC_F_EXP   = 4;
851                         CYC_SCC_R_TRUE   = 0;
852                         CYC_MOVEM_W      = 2;
853                         CYC_MOVEM_L      = 2;
854                         CYC_SHIFT        = 0;
855                         CYC_RESET        = 518;
856                         HAS_PMMU         = 0;
857                         HAS_FPU          = 0;
858                         return;
859                 case M68K_CPU_TYPE_68030:
860                         CPU_TYPE         = CPU_TYPE_030;
861                         CPU_ADDRESS_MASK = 0xffffffff;
862                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
863                         CYC_INSTRUCTION  = m68ki_cycles[3];
864                         CYC_EXCEPTION    = m68ki_exception_cycle_table[3];
865                         CYC_BCC_NOTAKE_B = -2;
866                         CYC_BCC_NOTAKE_W = 0;
867                         CYC_DBCC_F_NOEXP = 0;
868                         CYC_DBCC_F_EXP   = 4;
869                         CYC_SCC_R_TRUE   = 0;
870                         CYC_MOVEM_W      = 2;
871                         CYC_MOVEM_L      = 2;
872                         CYC_SHIFT        = 0;
873                         CYC_RESET        = 518;
874                         HAS_PMMU         = 1;
875                         HAS_FPU          = 1;
876                         return;
877                 case M68K_CPU_TYPE_68EC030:
878                         CPU_TYPE         = CPU_TYPE_EC030;
879                         CPU_ADDRESS_MASK = 0xffffffff;
880                         CPU_SR_MASK          = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
881                         CYC_INSTRUCTION  = m68ki_cycles[3];
882                         CYC_EXCEPTION    = m68ki_exception_cycle_table[3];
883                         CYC_BCC_NOTAKE_B = -2;
884                         CYC_BCC_NOTAKE_W = 0;
885                         CYC_DBCC_F_NOEXP = 0;
886                         CYC_DBCC_F_EXP   = 4;
887                         CYC_SCC_R_TRUE   = 0;
888                         CYC_MOVEM_W      = 2;
889                         CYC_MOVEM_L      = 2;
890                         CYC_SHIFT        = 0;
891                         CYC_RESET        = 518;
892                         HAS_PMMU         = 0;           /* EC030 lacks the PMMU and is effectively a die-shrink 68020 */
893                         HAS_FPU          = 1;
894                         return;
895                 case M68K_CPU_TYPE_68040:               // TODO: these values are not correct
896                         CPU_TYPE         = CPU_TYPE_040;
897                         CPU_ADDRESS_MASK = 0xffffffff;
898                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
899                         CYC_INSTRUCTION  = m68ki_cycles[4];
900                         CYC_EXCEPTION    = m68ki_exception_cycle_table[4];
901                         CYC_BCC_NOTAKE_B = -2;
902                         CYC_BCC_NOTAKE_W = 0;
903                         CYC_DBCC_F_NOEXP = 0;
904                         CYC_DBCC_F_EXP   = 4;
905                         CYC_SCC_R_TRUE   = 0;
906                         CYC_MOVEM_W      = 2;
907                         CYC_MOVEM_L      = 2;
908                         CYC_SHIFT        = 0;
909                         CYC_RESET        = 518;
910                         HAS_PMMU         = 1;
911                         HAS_FPU          = 1;
912                         return;
913                 case M68K_CPU_TYPE_68EC040: // Just a 68040 without pmmu apparently...
914                         CPU_TYPE         = CPU_TYPE_EC040;
915                         CPU_ADDRESS_MASK = 0xffffffff;
916                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
917                         CYC_INSTRUCTION  = m68ki_cycles[4];
918                         CYC_EXCEPTION    = m68ki_exception_cycle_table[4];
919                         CYC_BCC_NOTAKE_B = -2;
920                         CYC_BCC_NOTAKE_W = 0;
921                         CYC_DBCC_F_NOEXP = 0;
922                         CYC_DBCC_F_EXP   = 4;
923                         CYC_SCC_R_TRUE   = 0;
924                         CYC_MOVEM_W      = 2;
925                         CYC_MOVEM_L      = 2;
926                         CYC_SHIFT        = 0;
927                         CYC_RESET        = 518;
928                         HAS_PMMU         = 0;
929                         HAS_FPU          = 0;
930                         return;
931                 case M68K_CPU_TYPE_68LC040:
932                         CPU_TYPE         = CPU_TYPE_LC040;
933                         CPU_ADDRESS_MASK = 0xffffffff;
934                         m68ki_cpu.sr_mask          = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
935                         m68ki_cpu.cyc_instruction  = m68ki_cycles[4];
936                         m68ki_cpu.cyc_exception    = m68ki_exception_cycle_table[4];
937                         m68ki_cpu.cyc_bcc_notake_b = -2;
938                         m68ki_cpu.cyc_bcc_notake_w = 0;
939                         m68ki_cpu.cyc_dbcc_f_noexp = 0;
940                         m68ki_cpu.cyc_dbcc_f_exp   = 4;
941                         m68ki_cpu.cyc_scc_r_true   = 0;
942                         m68ki_cpu.cyc_movem_w      = 2;
943                         m68ki_cpu.cyc_movem_l      = 2;
944                         m68ki_cpu.cyc_shift        = 0;
945                         m68ki_cpu.cyc_reset        = 518;
946                         HAS_PMMU         = 1;
947                         HAS_FPU          = 0;
948                         return;
949         }
950 }
951
952 uint m68k_get_address_mask() {
953         return m68ki_cpu.address_mask;
954 }
955
956 /* Execute some instructions until we use up num_cycles clock cycles */
957 /* ASG: removed per-instruction interrupt checks */
958 int m68k_execute(int num_cycles)
959 {
960         /* eat up any reset cycles */
961         if (RESET_CYCLES) {
962             int rc = RESET_CYCLES;
963             RESET_CYCLES = 0;
964             num_cycles -= rc;
965             if (num_cycles <= 0)
966                 return rc;
967         }
968
969         /* Set our pool of clock cycles available */
970         SET_CYCLES(num_cycles);
971         m68ki_initial_cycles = num_cycles;
972
973         /* See if interrupts came in */
974         m68ki_check_interrupts();
975
976         /* Make sure we're not stopped */
977         if(!CPU_STOPPED)
978         {
979                 /* Return point if we had an address error */
980                 m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
981
982 #ifdef M68K_BUSERR_THING
983                 m68ki_check_bus_error_trap();
984 #endif
985
986                 /* Main loop.  Keep going until we run out of clock cycles */
987                 do
988                 {
989 #ifdef M68K_BUSERR_THING
990                         int i;
991 #endif
992                         /* Set tracing accodring to T1. (T0 is done inside instruction) */
993                         m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
994
995                         /* Set the address space for reads */
996                         m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
997
998                         /* Call external hook to peek at CPU */
999                         m68ki_instr_hook(REG_PC); /* auto-disable (see m68kcpu.h) */
1000
1001                         /* Record previous program counter */
1002                         REG_PPC = REG_PC;
1003
1004                         /* Record previous D/A register state (in case of bus error) */
1005 #ifdef M68K_BUSERR_THING
1006                         for (i = 15; i >= 0; i--){
1007                                 REG_DA_SAVE[i] = REG_DA[i];
1008                         }
1009 #endif
1010
1011                         /* Read an instruction and call its handler */
1012                         REG_IR = m68ki_read_imm_16();
1013                         m68ki_instruction_jump_table[REG_IR]();
1014                         USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
1015
1016                         /* Trace m68k_exception, if necessary */
1017                         m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
1018                 } while(GET_CYCLES() > 0);
1019
1020                 /* set previous PC to current PC for the next entry into the loop */
1021                 REG_PPC = REG_PC;
1022         }
1023         else
1024                 SET_CYCLES(0);
1025
1026         /* return how many clocks we used */
1027         return m68ki_initial_cycles - GET_CYCLES();
1028 }
1029
1030
1031 int m68k_cycles_run(void)
1032 {
1033         return m68ki_initial_cycles - GET_CYCLES();
1034 }
1035
1036 int m68k_cycles_remaining(void)
1037 {
1038         return GET_CYCLES();
1039 }
1040
1041 /* Change the timeslice */
1042 void m68k_modify_timeslice(int cycles)
1043 {
1044         m68ki_initial_cycles += cycles;
1045         ADD_CYCLES(cycles);
1046 }
1047
1048
1049 void m68k_end_timeslice(void)
1050 {
1051         m68ki_initial_cycles = GET_CYCLES();
1052         SET_CYCLES(0);
1053 }
1054
1055
1056 /* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
1057 /* KS: Modified so that IPL* bits match with mask positions in the SR
1058  *     and cleaned out remenants of the interrupt controller.
1059  */
1060 void m68k_set_irq(unsigned int int_level)
1061 {
1062         uint old_level = CPU_INT_LEVEL;
1063         CPU_INT_LEVEL = int_level << 8;
1064
1065         /* A transition from < 7 to 7 always interrupts (NMI) */
1066         /* Note: Level 7 can also level trigger like a normal IRQ */
1067         if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
1068                 m68ki_cpu.nmi_pending = TRUE;
1069 }
1070
1071 void m68k_set_virq(unsigned int level, unsigned int active)
1072 {
1073         uint state = m68ki_cpu.virq_state;
1074         uint blevel;
1075
1076         if(active)
1077                 state |= 1 << level;
1078         else
1079                 state &= ~(1 << level);
1080         m68ki_cpu.virq_state = state;
1081
1082         for(blevel = 7; blevel > 0; blevel--)
1083                 if(state & (1 << blevel))
1084                         break;
1085         m68k_set_irq(blevel);
1086 }
1087
1088 unsigned int m68k_get_virq(unsigned int level)
1089 {
1090         return (m68ki_cpu.virq_state & (1 << level)) ? 1 : 0;
1091 }
1092
1093 void m68k_init(void)
1094 {
1095         static uint emulation_initialized = 0;
1096
1097         /* The first call to this function initializes the opcode handler jump table */
1098         if(!emulation_initialized)
1099                 {
1100                 m68ki_build_opcode_table();
1101                 emulation_initialized = 1;
1102         }
1103
1104         m68k_set_int_ack_callback(NULL);
1105         m68k_set_bkpt_ack_callback(NULL);
1106         m68k_set_reset_instr_callback(NULL);
1107         m68k_set_cmpild_instr_callback(NULL);
1108         m68k_set_rte_instr_callback(NULL);
1109         m68k_set_tas_instr_callback(NULL);
1110         m68k_set_illg_instr_callback(NULL);
1111         m68k_set_pc_changed_callback(NULL);
1112         m68k_set_fc_callback(NULL);
1113         m68k_set_instr_hook_callback(NULL);
1114 }
1115
1116 /* Trigger a Bus Error exception */
1117 void m68k_pulse_bus_error(void)
1118 {
1119         m68ki_exception_bus_error();
1120 }
1121
1122 /* Pulse the RESET line on the CPU */
1123 void m68k_pulse_reset(void)
1124 {
1125         /* Disable the PMMU on reset */
1126         m68ki_cpu.pmmu_enabled = 0;
1127
1128         /* Clear all stop levels and eat up all remaining cycles */
1129         CPU_STOPPED = 0;
1130         SET_CYCLES(0);
1131
1132         CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
1133         CPU_INSTR_MODE = INSTRUCTION_YES;
1134
1135         /* Turn off tracing */
1136         FLAG_T1 = FLAG_T0 = 0;
1137         m68ki_clear_trace();
1138         /* Interrupt mask to level 7 */
1139         FLAG_INT_MASK = 0x0700;
1140         CPU_INT_LEVEL = 0;
1141         m68ki_cpu.virq_state = 0;
1142         /* Reset VBR */
1143         REG_VBR = 0;
1144         /* Go to supervisor mode */
1145         m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);
1146
1147         /* Invalidate the prefetch queue */
1148 #if M68K_EMULATE_PREFETCH
1149         /* Set to arbitrary number since our first fetch is from 0 */
1150         CPU_PREF_ADDR = 0x1000;
1151 #endif /* M68K_EMULATE_PREFETCH */
1152
1153         /* Read the initial stack pointer and program counter */
1154         m68ki_jump(0);
1155         REG_SP = m68ki_read_imm_32();
1156         REG_PC = m68ki_read_imm_32();
1157         m68ki_jump(REG_PC);
1158
1159         CPU_RUN_MODE = RUN_MODE_NORMAL;
1160
1161         RESET_CYCLES = CYC_EXCEPTION[EXCEPTION_RESET];
1162 }
1163
1164 /* Pulse the HALT line on the CPU */
1165 void m68k_pulse_halt(void)
1166 {
1167         CPU_STOPPED |= STOP_LEVEL_HALT;
1168 }
1169
1170 /* Get and set the current CPU context */
1171 /* This is to allow for multiple CPUs */
1172 unsigned int m68k_context_size()
1173 {
1174         return sizeof(m68ki_cpu_core);
1175 }
1176
1177 unsigned int m68k_get_context(void* dst)
1178 {
1179         if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;
1180         return sizeof(m68ki_cpu_core);
1181 }
1182
1183 void m68k_set_context(void* src)
1184 {
1185         if(src) m68ki_cpu = *(m68ki_cpu_core*)src;
1186 }
1187
1188 #if M68K_SEPARATE_READS
1189 /* Read data immediately following the PC */
1190 inline unsigned int  m68k_read_immediate_16(unsigned int address) {
1191 #if M68K_EMULATE_PREFETCH == OPT_ON
1192         for (int i = 0; i < read_ranges; i++) {
1193                 if(address >= read_addr[i] && address < read_upper[i]) {
1194                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1195                 }
1196         }
1197 #endif
1198         
1199         return m68k_read_memory_16(address);
1200 }
1201 inline unsigned int  m68k_read_immediate_32(unsigned int address) {
1202 #if M68K_EMULATE_PREFETCH == OPT_ON
1203         for (int i = 0; i < read_ranges; i++) {
1204                 if(address >= read_addr[i] && address < read_upper[i]) {
1205                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1206                 }
1207         }
1208 #endif
1209
1210         return m68k_read_memory_32(address);
1211 }
1212
1213 /* Read data relative to the PC */
1214 inline unsigned int  m68k_read_pcrelative_8(unsigned int address) {
1215         for (int i = 0; i < read_ranges; i++) {
1216                 if(address >= read_addr[i] && address < read_upper[i]) {
1217                         return read_data[i][address - read_addr[i]];
1218                 }
1219         }
1220         
1221         return m68k_read_memory_8(address);
1222 }
1223 inline unsigned int  m68k_read_pcrelative_16(unsigned int address) {
1224         for (int i = 0; i < read_ranges; i++) {
1225                 if(address >= read_addr[i] && address < read_upper[i]) {
1226                         return be16toh(((unsigned short *)(read_data[i] + (address - read_addr[i])))[0]);
1227                 }
1228         }
1229
1230         return m68k_read_memory_16(address);
1231 }
1232 inline unsigned int  m68k_read_pcrelative_32(unsigned int address) {
1233         for (int i = 0; i < read_ranges; i++) {
1234                 if(address >= read_addr[i] && address < read_upper[i]) {
1235                         return be32toh(((unsigned int *)(read_data[i] + (address - read_addr[i])))[0]);
1236                 }
1237         }
1238
1239     return m68k_read_memory_32(address);
1240 }
1241 #endif
1242
1243 void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
1244 {
1245         if ((addr == 0 && upper == 0) || upper < addr)
1246                 return;
1247
1248         for (int i = 0; i < write_ranges; i++) {
1249                 if (write_addr[i] == addr) {
1250                         uint8_t changed = 0;
1251                         if (write_upper[i] != upper) {
1252                                 write_upper[i] = upper;
1253                                 changed = 1;
1254                         }
1255                         if (write_data[i] != ptr) {
1256                                 write_data[i] = ptr;
1257                                 changed = 1;
1258                         }
1259                         if (changed) {
1260                                 printf("[MUSASHI] Adjusted mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr);
1261                         }
1262                         return;
1263                 }
1264         }
1265
1266         if (read_ranges + 1 < 8) {
1267                 read_addr[read_ranges] = addr;
1268                 read_upper[read_ranges] = upper;
1269                 read_data[read_ranges] = ptr;
1270                 read_ranges++;
1271                 printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1272         }
1273         else {
1274                 printf("Can't Musashi map more than eight RAM/ROM read ranges.\n");
1275         }
1276         if (write_ranges + 1 < 8) {
1277                 write_addr[write_ranges] = addr;
1278                 write_upper[write_ranges] = upper;
1279                 write_data[write_ranges] = ptr;
1280                 write_ranges++;
1281                 printf("[MUSASHI] Mapped write range %d: %.8X-%.8X (%p)\n", write_ranges, addr, upper, ptr);
1282         }
1283         else {
1284                 printf("Can't Musashi map more than eight RAM write ranges.\n");
1285         }
1286 }
1287
1288 void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr)
1289 {
1290         if ((addr == 0 && upper == 0) || upper < addr)
1291                 return;
1292
1293         for (int i = 0; i < read_ranges; i++) {
1294                 if (read_addr[i] == addr) {
1295                         uint8_t changed = 0;
1296                         if (read_upper[i] != upper) {
1297                                 read_upper[i] = upper;
1298                                 changed = 1;
1299                         }
1300                         if (read_data[i] != ptr) {
1301                                 read_data[i] = ptr;
1302                                 changed = 1;
1303                         }
1304                         if (changed) {
1305                                 printf("[MUSASHI] Adjusted mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1306                         }
1307                         return;
1308                 }
1309         }
1310
1311         if (read_ranges + 1 < 8) {
1312                 read_addr[read_ranges] = addr;
1313                 read_upper[read_ranges] = upper;
1314                 read_data[read_ranges] = ptr;
1315                 read_ranges++;
1316                 printf("[MUSASHI] Mapped read range %d: %.8X-%.8X (%p)\n", read_ranges, addr, upper, ptr);
1317         }
1318         else {
1319                 printf("Can't Musashi map more than eight RAM/ROM read ranges.\n");
1320         }
1321 }
1322
1323 /* ======================================================================== */
1324 /* ============================== MAME STUFF ============================== */
1325 /* ======================================================================== */
1326
1327 #if M68K_COMPILE_FOR_MAME == OPT_ON
1328
1329 static struct {
1330         UINT16 sr;
1331         UINT8 stopped;
1332         UINT8 halted;
1333 } m68k_substate;
1334
1335 static void m68k_prepare_substate(void)
1336 {
1337         m68k_substate.sr = m68ki_get_sr();
1338         m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;
1339         m68k_substate.halted  = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;
1340 }
1341
1342 static void m68k_post_load(void)
1343 {
1344         m68ki_set_sr_noint_nosp(m68k_substate.sr);
1345         CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0
1346                         | m68k_substate.halted  ? STOP_LEVEL_HALT : 0;
1347         m68ki_jump(REG_PC);
1348 }
1349
1350 void m68k_state_register(const char *type, int index)
1351 {
1352         /* Note, D covers A because the dar array is common, REG_A=REG_D+8 */
1353         state_save_register_item_array(type, index, REG_D);
1354         state_save_register_item(type, index, REG_PPC);
1355         state_save_register_item(type, index, REG_PC);
1356         state_save_register_item(type, index, REG_USP);
1357         state_save_register_item(type, index, REG_ISP);
1358         state_save_register_item(type, index, REG_MSP);
1359         state_save_register_item(type, index, REG_VBR);
1360         state_save_register_item(type, index, REG_SFC);
1361         state_save_register_item(type, index, REG_DFC);
1362         state_save_register_item(type, index, REG_CACR);
1363         state_save_register_item(type, index, REG_CAAR);
1364         state_save_register_item(type, index, m68k_substate.sr);
1365         state_save_register_item(type, index, CPU_INT_LEVEL);
1366         state_save_register_item(type, index, m68k_substate.stopped);
1367         state_save_register_item(type, index, m68k_substate.halted);
1368         state_save_register_item(type, index, CPU_PREF_ADDR);
1369         state_save_register_item(type, index, CPU_PREF_DATA);
1370         state_save_register_func_presave(m68k_prepare_substate);
1371         state_save_register_func_postload(m68k_post_load);
1372 }
1373
1374 #endif /* M68K_COMPILE_FOR_MAME */
1375
1376 /* ======================================================================== */
1377 /* ============================== END OF FILE ============================= */
1378 /* ======================================================================== */