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