OVR: Change the way to walk and rotate with the controller
[mercenary-reloaded.git] / src / libcpu / m68kcpu.c
1 /* ======================================================================== */
2 /* ========================= LICENSING & COPYRIGHT ======================== */
3 /* ======================================================================== */
4 /*
5  *                                  MUSASHI
6  *                                Version 3.4
7  *
8  * A portable Motorola M680x0 processor emulation engine.
9  * Copyright 1998-2001 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 #include "m68kops.h"
42 #include "m68kcpu.h"
43
44 /* ======================================================================== */
45 /* ================================= DATA ================================= */
46 /* ======================================================================== */
47
48 int  m68ki_initial_cycles;
49 int  m68ki_remaining_cycles = 0;                     /* Number of clocks remaining */
50 uint m68ki_tracing = 0;
51 uint m68ki_address_space;
52
53 #ifdef M68K_LOG_ENABLE
54 char* m68ki_cpu_names[9] =
55 {
56         "Invalid CPU",
57         "M68000",
58         "M68010",
59         "Invalid CPU",
60         "M68EC020"
61         "Invalid CPU",
62         "Invalid CPU",
63         "Invalid CPU",
64         "M68020"
65 };
66 #endif /* M68K_LOG_ENABLE */
67
68 /* The CPU core */
69 m68ki_cpu_core m68ki_cpu = {0};
70
71 #if M68K_EMULATE_ADDRESS_ERROR
72 jmp_buf m68ki_aerr_trap;
73 #endif /* M68K_EMULATE_ADDRESS_ERROR */
74
75 uint    m68ki_aerr_address;
76 uint    m68ki_aerr_write_mode;
77 uint    m68ki_aerr_fc;
78
79 /* Used by shift & rotate instructions */
80 uint8 m68ki_shift_8_table[65] =
81 {
82         0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,
83         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
84         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
85         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
86         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87         0xff, 0xff, 0xff, 0xff, 0xff
88 };
89 uint16 m68ki_shift_16_table[65] =
90 {
91         0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
92         0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,
93         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
94         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
95         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
96         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
97         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
98         0xffff, 0xffff
99 };
100 uint m68ki_shift_32_table[65] =
101 {
102         0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
103         0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
104         0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
105         0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
106         0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
107         0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
108         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
109         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
110         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
111         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
112         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
113 };
114
115
116 /* Number of clock cycles to use for exception processing.
117  * I used 4 for any vectors that are undocumented for processing times.
118  */
119 uint8 m68ki_exception_cycle_table[3][256] =
120 {
121         { /* 000 */
122                   4, /*  0: Reset - Initial Stack Pointer                      */
123                   4, /*  1: Reset - Initial Program Counter                    */
124                  50, /*  2: Bus Error                             (unemulated) */
125                  50, /*  3: Address Error                         (unemulated) */
126                  34, /*  4: Illegal Instruction                                */
127                  38, /*  5: Divide by Zero -- ASG: changed from 42             */
128                  40, /*  6: CHK -- ASG: chanaged from 44                       */
129                  34, /*  7: TRAPV                                              */
130                  34, /*  8: Privilege Violation                                */
131                  34, /*  9: Trace                                              */
132                  34, /* 10: 1010                                               */
133                  34, /* 11: 1111                                               */
134                   4, /* 12: RESERVED                                           */
135                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
136                   4, /* 14: Format Error                                       */
137                  44, /* 15: Uninitialized Interrupt                            */
138                   4, /* 16: RESERVED                                           */
139                   4, /* 17: RESERVED                                           */
140                   4, /* 18: RESERVED                                           */
141                   4, /* 19: RESERVED                                           */
142                   4, /* 20: RESERVED                                           */
143                   4, /* 21: RESERVED                                           */
144                   4, /* 22: RESERVED                                           */
145                   4, /* 23: RESERVED                                           */
146                  44, /* 24: Spurious Interrupt                                 */
147                  44, /* 25: Level 1 Interrupt Autovector                       */
148                  44, /* 26: Level 2 Interrupt Autovector                       */
149                  44, /* 27: Level 3 Interrupt Autovector                       */
150                  44, /* 28: Level 4 Interrupt Autovector                       */
151                  44, /* 29: Level 5 Interrupt Autovector                       */
152                  44, /* 30: Level 6 Interrupt Autovector                       */
153                  44, /* 31: Level 7 Interrupt Autovector                       */
154                  34, /* 32: TRAP #0 -- ASG: chanaged from 38                   */
155                  34, /* 33: TRAP #1                                            */
156                  34, /* 34: TRAP #2                                            */
157                  34, /* 35: TRAP #3                                            */
158                  34, /* 36: TRAP #4                                            */
159                  34, /* 37: TRAP #5                                            */
160                  34, /* 38: TRAP #6                                            */
161                  34, /* 39: TRAP #7                                            */
162                  34, /* 40: TRAP #8                                            */
163                  34, /* 41: TRAP #9                                            */
164                  34, /* 42: TRAP #10                                           */
165                  34, /* 43: TRAP #11                                           */
166                  34, /* 44: TRAP #12                                           */
167                  34, /* 45: TRAP #13                                           */
168                  34, /* 46: TRAP #14                                           */
169                  34, /* 47: TRAP #15                                           */
170                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
171                   4, /* 49: FP Inexact Result                     (unemulated) */
172                   4, /* 50: FP Divide by Zero                     (unemulated) */
173                   4, /* 51: FP Underflow                          (unemulated) */
174                   4, /* 52: FP Operand Error                      (unemulated) */
175                   4, /* 53: FP Overflow                           (unemulated) */
176                   4, /* 54: FP Signaling NAN                      (unemulated) */
177                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
178                   4, /* 56: MMU Configuration Error               (unemulated) */
179                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
180                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
181                   4, /* 59: RESERVED                                           */
182                   4, /* 60: RESERVED                                           */
183                   4, /* 61: RESERVED                                           */
184                   4, /* 62: RESERVED                                           */
185                   4, /* 63: RESERVED                                           */
186                      /* 64-255: User Defined                                   */
187                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
188                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
189                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
190                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
191                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
192                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
193         },
194         { /* 010 */
195                   4, /*  0: Reset - Initial Stack Pointer                      */
196                   4, /*  1: Reset - Initial Program Counter                    */
197                 126, /*  2: Bus Error                             (unemulated) */
198                 126, /*  3: Address Error                         (unemulated) */
199                  38, /*  4: Illegal Instruction                                */
200                  44, /*  5: Divide by Zero                                     */
201                  44, /*  6: CHK                                                */
202                  34, /*  7: TRAPV                                              */
203                  38, /*  8: Privilege Violation                                */
204                  38, /*  9: Trace                                              */
205                   4, /* 10: 1010                                               */
206                   4, /* 11: 1111                                               */
207                   4, /* 12: RESERVED                                           */
208                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
209                   4, /* 14: Format Error                                       */
210                  44, /* 15: Uninitialized Interrupt                            */
211                   4, /* 16: RESERVED                                           */
212                   4, /* 17: RESERVED                                           */
213                   4, /* 18: RESERVED                                           */
214                   4, /* 19: RESERVED                                           */
215                   4, /* 20: RESERVED                                           */
216                   4, /* 21: RESERVED                                           */
217                   4, /* 22: RESERVED                                           */
218                   4, /* 23: RESERVED                                           */
219                  46, /* 24: Spurious Interrupt                                 */
220                  46, /* 25: Level 1 Interrupt Autovector                       */
221                  46, /* 26: Level 2 Interrupt Autovector                       */
222                  46, /* 27: Level 3 Interrupt Autovector                       */
223                  46, /* 28: Level 4 Interrupt Autovector                       */
224                  46, /* 29: Level 5 Interrupt Autovector                       */
225                  46, /* 30: Level 6 Interrupt Autovector                       */
226                  46, /* 31: Level 7 Interrupt Autovector                       */
227                  38, /* 32: TRAP #0                                            */
228                  38, /* 33: TRAP #1                                            */
229                  38, /* 34: TRAP #2                                            */
230                  38, /* 35: TRAP #3                                            */
231                  38, /* 36: TRAP #4                                            */
232                  38, /* 37: TRAP #5                                            */
233                  38, /* 38: TRAP #6                                            */
234                  38, /* 39: TRAP #7                                            */
235                  38, /* 40: TRAP #8                                            */
236                  38, /* 41: TRAP #9                                            */
237                  38, /* 42: TRAP #10                                           */
238                  38, /* 43: TRAP #11                                           */
239                  38, /* 44: TRAP #12                                           */
240                  38, /* 45: TRAP #13                                           */
241                  38, /* 46: TRAP #14                                           */
242                  38, /* 47: TRAP #15                                           */
243                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
244                   4, /* 49: FP Inexact Result                     (unemulated) */
245                   4, /* 50: FP Divide by Zero                     (unemulated) */
246                   4, /* 51: FP Underflow                          (unemulated) */
247                   4, /* 52: FP Operand Error                      (unemulated) */
248                   4, /* 53: FP Overflow                           (unemulated) */
249                   4, /* 54: FP Signaling NAN                      (unemulated) */
250                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
251                   4, /* 56: MMU Configuration Error               (unemulated) */
252                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
253                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
254                   4, /* 59: RESERVED                                           */
255                   4, /* 60: RESERVED                                           */
256                   4, /* 61: RESERVED                                           */
257                   4, /* 62: RESERVED                                           */
258                   4, /* 63: RESERVED                                           */
259                      /* 64-255: User Defined                                   */
260                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
261                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
262                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
263                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
264                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
265                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
266         },
267         { /* 020 */
268                   4, /*  0: Reset - Initial Stack Pointer                      */
269                   4, /*  1: Reset - Initial Program Counter                    */
270                  50, /*  2: Bus Error                             (unemulated) */
271                  50, /*  3: Address Error                         (unemulated) */
272                  20, /*  4: Illegal Instruction                                */
273                  38, /*  5: Divide by Zero                                     */
274                  40, /*  6: CHK                                                */
275                  20, /*  7: TRAPV                                              */
276                  34, /*  8: Privilege Violation                                */
277                  25, /*  9: Trace                                              */
278                  20, /* 10: 1010                                               */
279                  20, /* 11: 1111                                               */
280                   4, /* 12: RESERVED                                           */
281                   4, /* 13: Coprocessor Protocol Violation        (unemulated) */
282                   4, /* 14: Format Error                                       */
283                  30, /* 15: Uninitialized Interrupt                            */
284                   4, /* 16: RESERVED                                           */
285                   4, /* 17: RESERVED                                           */
286                   4, /* 18: RESERVED                                           */
287                   4, /* 19: RESERVED                                           */
288                   4, /* 20: RESERVED                                           */
289                   4, /* 21: RESERVED                                           */
290                   4, /* 22: RESERVED                                           */
291                   4, /* 23: RESERVED                                           */
292                  30, /* 24: Spurious Interrupt                                 */
293                  30, /* 25: Level 1 Interrupt Autovector                       */
294                  30, /* 26: Level 2 Interrupt Autovector                       */
295                  30, /* 27: Level 3 Interrupt Autovector                       */
296                  30, /* 28: Level 4 Interrupt Autovector                       */
297                  30, /* 29: Level 5 Interrupt Autovector                       */
298                  30, /* 30: Level 6 Interrupt Autovector                       */
299                  30, /* 31: Level 7 Interrupt Autovector                       */
300                  20, /* 32: TRAP #0                                            */
301                  20, /* 33: TRAP #1                                            */
302                  20, /* 34: TRAP #2                                            */
303                  20, /* 35: TRAP #3                                            */
304                  20, /* 36: TRAP #4                                            */
305                  20, /* 37: TRAP #5                                            */
306                  20, /* 38: TRAP #6                                            */
307                  20, /* 39: TRAP #7                                            */
308                  20, /* 40: TRAP #8                                            */
309                  20, /* 41: TRAP #9                                            */
310                  20, /* 42: TRAP #10                                           */
311                  20, /* 43: TRAP #11                                           */
312                  20, /* 44: TRAP #12                                           */
313                  20, /* 45: TRAP #13                                           */
314                  20, /* 46: TRAP #14                                           */
315                  20, /* 47: TRAP #15                                           */
316                   4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
317                   4, /* 49: FP Inexact Result                     (unemulated) */
318                   4, /* 50: FP Divide by Zero                     (unemulated) */
319                   4, /* 51: FP Underflow                          (unemulated) */
320                   4, /* 52: FP Operand Error                      (unemulated) */
321                   4, /* 53: FP Overflow                           (unemulated) */
322                   4, /* 54: FP Signaling NAN                      (unemulated) */
323                   4, /* 55: FP Unimplemented Data Type            (unemulated) */
324                   4, /* 56: MMU Configuration Error               (unemulated) */
325                   4, /* 57: MMU Illegal Operation Error           (unemulated) */
326                   4, /* 58: MMU Access Level Violation Error      (unemulated) */
327                   4, /* 59: RESERVED                                           */
328                   4, /* 60: RESERVED                                           */
329                   4, /* 61: RESERVED                                           */
330                   4, /* 62: RESERVED                                           */
331                   4, /* 63: RESERVED                                           */
332                      /* 64-255: User Defined                                   */
333                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
334                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
335                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
336                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
337                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
338                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
339         }
340 };
341
342 uint8 m68ki_ea_idx_cycle_table[64] =
343 {
344          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
345          0, /* ..01.000 no memory indirect, base NULL             */
346          5, /* ..01..01 memory indirect,    base NULL, outer NULL */
347          7, /* ..01..10 memory indirect,    base NULL, outer 16   */
348          7, /* ..01..11 memory indirect,    base NULL, outer 32   */
349          0,  5,  7,  7,  0,  5,  7,  7,  0,  5,  7,  7,
350          2, /* ..10.000 no memory indirect, base 16               */
351          7, /* ..10..01 memory indirect,    base 16,   outer NULL */
352          9, /* ..10..10 memory indirect,    base 16,   outer 16   */
353          9, /* ..10..11 memory indirect,    base 16,   outer 32   */
354          0,  7,  9,  9,  0,  7,  9,  9,  0,  7,  9,  9,
355          6, /* ..11.000 no memory indirect, base 32               */
356         11, /* ..11..01 memory indirect,    base 32,   outer NULL */
357         13, /* ..11..10 memory indirect,    base 32,   outer 16   */
358         13, /* ..11..11 memory indirect,    base 32,   outer 32   */
359          0, 11, 13, 13,  0, 11, 13, 13,  0, 11, 13, 13
360 };
361
362
363
364 /* ======================================================================== */
365 /* =============================== CALLBACKS ============================== */
366 /* ======================================================================== */
367
368 /* Default callbacks used if the callback hasn't been set yet, or if the
369  * callback is set to NULL
370  */
371
372 /* Interrupt acknowledge */
373 static int default_int_ack_callback_data;
374 static int default_int_ack_callback(int int_level)
375 {
376         default_int_ack_callback_data = int_level;
377         CPU_INT_LEVEL = 0;
378         return M68K_INT_ACK_AUTOVECTOR;
379 }
380
381 /* Breakpoint acknowledge */
382 static unsigned int default_bkpt_ack_callback_data;
383 static void default_bkpt_ack_callback(unsigned int data)
384 {
385         default_bkpt_ack_callback_data = data;
386 }
387
388 /* Called when a reset instruction is executed */
389 static void default_reset_instr_callback(void)
390 {
391 }
392
393 /* Called when the program counter changed by a large value */
394 static unsigned int default_pc_changed_callback_data;
395 static void default_pc_changed_callback(unsigned int new_pc)
396 {
397         default_pc_changed_callback_data = new_pc;
398 }
399
400 /* Called every time there's bus activity (read/write to/from memory */
401 static unsigned int default_set_fc_callback_data;
402 static void default_set_fc_callback(unsigned int new_fc)
403 {
404         default_set_fc_callback_data = new_fc;
405 }
406
407 /* Called every instruction cycle prior to execution */
408 static void default_instr_hook_callback(void)
409 {
410 }
411
412
413 #if M68K_EMULATE_ADDRESS_ERROR
414         #include <setjmp.h>
415         jmp_buf m68ki_aerr_trap;
416 #endif /* M68K_EMULATE_ADDRESS_ERROR */
417
418
419 /* ======================================================================== */
420 /* ================================= API ================================== */
421 /* ======================================================================== */
422
423 /* Access the internals of the CPU */
424 unsigned int m68k_get_reg(void* context, m68k_register_t regnum)
425 {
426         m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu;
427
428         switch(regnum)
429         {
430                 case M68K_REG_D0:       return cpu->dar[0];
431                 case M68K_REG_D1:       return cpu->dar[1];
432                 case M68K_REG_D2:       return cpu->dar[2];
433                 case M68K_REG_D3:       return cpu->dar[3];
434                 case M68K_REG_D4:       return cpu->dar[4];
435                 case M68K_REG_D5:       return cpu->dar[5];
436                 case M68K_REG_D6:       return cpu->dar[6];
437                 case M68K_REG_D7:       return cpu->dar[7];
438                 case M68K_REG_A0:       return cpu->dar[8];
439                 case M68K_REG_A1:       return cpu->dar[9];
440                 case M68K_REG_A2:       return cpu->dar[10];
441                 case M68K_REG_A3:       return cpu->dar[11];
442                 case M68K_REG_A4:       return cpu->dar[12];
443                 case M68K_REG_A5:       return cpu->dar[13];
444                 case M68K_REG_A6:       return cpu->dar[14];
445                 case M68K_REG_A7:       return cpu->dar[15];
446                 case M68K_REG_PC:       return MASK_OUT_ABOVE_32(cpu->pc);
447                 case M68K_REG_SR:       return  cpu->t1_flag                                            |
448                                                                         cpu->t0_flag                                            |
449                                                                         (cpu->s_flag << 11)                                     |
450                                                                         (cpu->m_flag << 11)                                     |
451                                                                         cpu->int_mask                                           |
452                                                                         ((cpu->x_flag & XFLAG_SET) >> 4)        |
453                                                                         ((cpu->n_flag & NFLAG_SET) >> 4)        |
454                                                                         ((!cpu->not_z_flag) << 2)                       |
455                                                                         ((cpu->v_flag & VFLAG_SET) >> 6)        |
456                                                                         ((cpu->c_flag & CFLAG_SET) >> 8);
457                 case M68K_REG_SP:       return cpu->dar[15];
458                 case M68K_REG_USP:      return cpu->s_flag ? cpu->sp[0] : cpu->dar[15];
459                 case M68K_REG_ISP:      return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4];
460                 case M68K_REG_MSP:      return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6];
461                 case M68K_REG_SFC:      return cpu->sfc;
462                 case M68K_REG_DFC:      return cpu->dfc;
463                 case M68K_REG_VBR:      return cpu->vbr;
464                 case M68K_REG_CACR:     return cpu->cacr;
465                 case M68K_REG_CAAR:     return cpu->caar;
466                 case M68K_REG_PREF_ADDR:        return cpu->pref_addr;
467                 case M68K_REG_PREF_DATA:        return cpu->pref_data;
468                 case M68K_REG_PPC:      return MASK_OUT_ABOVE_32(cpu->ppc);
469                 case M68K_REG_IR:       return cpu->ir;
470                 case M68K_REG_CPU_TYPE:
471                         switch(cpu->cpu_type)
472                         {
473                                 case CPU_TYPE_000:              return (unsigned int)M68K_CPU_TYPE_68000;
474                                 case CPU_TYPE_010:              return (unsigned int)M68K_CPU_TYPE_68010;
475                                 case CPU_TYPE_EC020:    return (unsigned int)M68K_CPU_TYPE_68EC020;
476                                 case CPU_TYPE_020:              return (unsigned int)M68K_CPU_TYPE_68020;
477                         }
478                         return M68K_CPU_TYPE_INVALID;
479                 default:                        return 0;
480         }
481         return 0;
482 }
483
484 void m68k_set_reg(m68k_register_t regnum, unsigned int value)
485 {
486         switch(regnum)
487         {
488                 case M68K_REG_D0:       REG_D[0] = MASK_OUT_ABOVE_32(value); return;
489                 case M68K_REG_D1:       REG_D[1] = MASK_OUT_ABOVE_32(value); return;
490                 case M68K_REG_D2:       REG_D[2] = MASK_OUT_ABOVE_32(value); return;
491                 case M68K_REG_D3:       REG_D[3] = MASK_OUT_ABOVE_32(value); return;
492                 case M68K_REG_D4:       REG_D[4] = MASK_OUT_ABOVE_32(value); return;
493                 case M68K_REG_D5:       REG_D[5] = MASK_OUT_ABOVE_32(value); return;
494                 case M68K_REG_D6:       REG_D[6] = MASK_OUT_ABOVE_32(value); return;
495                 case M68K_REG_D7:       REG_D[7] = MASK_OUT_ABOVE_32(value); return;
496                 case M68K_REG_A0:       REG_A[0] = MASK_OUT_ABOVE_32(value); return;
497                 case M68K_REG_A1:       REG_A[1] = MASK_OUT_ABOVE_32(value); return;
498                 case M68K_REG_A2:       REG_A[2] = MASK_OUT_ABOVE_32(value); return;
499                 case M68K_REG_A3:       REG_A[3] = MASK_OUT_ABOVE_32(value); return;
500                 case M68K_REG_A4:       REG_A[4] = MASK_OUT_ABOVE_32(value); return;
501                 case M68K_REG_A5:       REG_A[5] = MASK_OUT_ABOVE_32(value); return;
502                 case M68K_REG_A6:       REG_A[6] = MASK_OUT_ABOVE_32(value); return;
503                 case M68K_REG_A7:       REG_A[7] = MASK_OUT_ABOVE_32(value); return;
504                 case M68K_REG_PC:       m68ki_jump(MASK_OUT_ABOVE_32(value)); return;
505                 case M68K_REG_SR:       m68ki_set_sr(value); return;
506                 case M68K_REG_SP:       REG_SP = MASK_OUT_ABOVE_32(value); return;
507                 case M68K_REG_USP:      if(FLAG_S)
508                                                                 REG_USP = MASK_OUT_ABOVE_32(value);
509                                                         else
510                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
511                                                         return;
512                 case M68K_REG_ISP:      if(FLAG_S && !FLAG_M)
513                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
514                                                         else
515                                                                 REG_ISP = MASK_OUT_ABOVE_32(value);
516                                                         return;
517                 case M68K_REG_MSP:      if(FLAG_S && FLAG_M)
518                                                                 REG_SP = MASK_OUT_ABOVE_32(value);
519                                                         else
520                                                                 REG_MSP = MASK_OUT_ABOVE_32(value);
521                                                         return;
522                 case M68K_REG_VBR:      REG_VBR = MASK_OUT_ABOVE_32(value); return;
523                 case M68K_REG_SFC:      REG_SFC = value & 7; return;
524                 case M68K_REG_DFC:      REG_DFC = value & 7; return;
525                 case M68K_REG_CACR:     REG_CACR = MASK_OUT_ABOVE_32(value); return;
526                 case M68K_REG_CAAR:     REG_CAAR = MASK_OUT_ABOVE_32(value); return;
527                 case M68K_REG_PPC:      REG_PPC = MASK_OUT_ABOVE_32(value); return;
528                 case M68K_REG_IR:       REG_IR = MASK_OUT_ABOVE_16(value); return;
529                 case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return;
530                 default:                        return;
531         }
532 }
533
534 /* Set the callbacks */
535 void m68k_set_int_ack_callback(int  (*callback)(int int_level))
536 {
537         CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback;
538 }
539
540 void m68k_set_bkpt_ack_callback(void  (*callback)(unsigned int data))
541 {
542         CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback;
543 }
544
545 void m68k_set_reset_instr_callback(void  (*callback)(void))
546 {
547         CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback;
548 }
549
550 void m68k_set_pc_changed_callback(void  (*callback)(unsigned int new_pc))
551 {
552         CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback;
553 }
554
555 void m68k_set_fc_callback(void  (*callback)(unsigned int new_fc))
556 {
557         CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;
558 }
559
560 void m68k_set_instr_hook_callback(void  (*callback)(void))
561 {
562         CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
563 }
564
565 #include <stdio.h>
566 /* Set the CPU type. */
567 void m68k_set_cpu_type(unsigned int cpu_type)
568 {
569         switch(cpu_type)
570         {
571                 case M68K_CPU_TYPE_68000:
572                         CPU_TYPE         = CPU_TYPE_000;
573                         CPU_ADDRESS_MASK = 0x00ffffff;
574                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
575                         CYC_INSTRUCTION  = m68ki_cycles[0];
576                         CYC_EXCEPTION    = m68ki_exception_cycle_table[0];
577                         CYC_BCC_NOTAKE_B = -2;
578                         CYC_BCC_NOTAKE_W = 2;
579                         CYC_DBCC_F_NOEXP = -2;
580                         CYC_DBCC_F_EXP   = 2;
581                         CYC_SCC_R_TRUE   = 2;
582                         CYC_MOVEM_W      = 2;
583                         CYC_MOVEM_L      = 3;
584                         CYC_SHIFT        = 1;
585                         CYC_RESET        = 132;
586                         return;
587                 case M68K_CPU_TYPE_68010:
588                         CPU_TYPE         = CPU_TYPE_010;
589                         CPU_ADDRESS_MASK = 0x00ffffff;
590                         CPU_SR_MASK      = 0xa71f; /* T1 -- S  -- -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
591                         CYC_INSTRUCTION  = m68ki_cycles[1];
592                         CYC_EXCEPTION    = m68ki_exception_cycle_table[1];
593                         CYC_BCC_NOTAKE_B = -4;
594                         CYC_BCC_NOTAKE_W = 0;
595                         CYC_DBCC_F_NOEXP = 0;
596                         CYC_DBCC_F_EXP   = 6;
597                         CYC_SCC_R_TRUE   = 0;
598                         CYC_MOVEM_W      = 2;
599                         CYC_MOVEM_L      = 3;
600                         CYC_SHIFT        = 1;
601                         CYC_RESET        = 130;
602                         return;
603                 case M68K_CPU_TYPE_68EC020:
604                         CPU_TYPE         = CPU_TYPE_EC020;
605                         CPU_ADDRESS_MASK = 0x00ffffff;
606                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
607                         CYC_INSTRUCTION  = m68ki_cycles[2];
608                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
609                         CYC_BCC_NOTAKE_B = -2;
610                         CYC_BCC_NOTAKE_W = 0;
611                         CYC_DBCC_F_NOEXP = 0;
612                         CYC_DBCC_F_EXP   = 4;
613                         CYC_SCC_R_TRUE   = 0;
614                         CYC_MOVEM_W      = 2;
615                         CYC_MOVEM_L      = 2;
616                         CYC_SHIFT        = 0;
617                         CYC_RESET        = 518;
618                         return;
619                 case M68K_CPU_TYPE_68020:
620                         CPU_TYPE         = CPU_TYPE_020;
621                         CPU_ADDRESS_MASK = 0xffffffff;
622                         CPU_SR_MASK      = 0xf71f; /* T1 T0 S  M  -- I2 I1 I0 -- -- -- X  N  Z  V  C  */
623                         CYC_INSTRUCTION  = m68ki_cycles[2];
624                         CYC_EXCEPTION    = m68ki_exception_cycle_table[2];
625                         CYC_BCC_NOTAKE_B = -2;
626                         CYC_BCC_NOTAKE_W = 0;
627                         CYC_DBCC_F_NOEXP = 0;
628                         CYC_DBCC_F_EXP   = 4;
629                         CYC_SCC_R_TRUE   = 0;
630                         CYC_MOVEM_W      = 2;
631                         CYC_MOVEM_L      = 2;
632                         CYC_SHIFT        = 0;
633                         CYC_RESET        = 518;
634                         return;
635         }
636 }
637
638 /* Execute some instructions until we use up num_cycles clock cycles */
639 /* ASG: removed per-instruction interrupt checks */
640 int m68k_execute(int num_cycles)
641 {
642         /* Make sure we're not stopped */
643         if(!CPU_STOPPED)
644         {
645                 /* Set our pool of clock cycles available */
646                 SET_CYCLES(num_cycles);
647                 m68ki_initial_cycles = num_cycles;
648
649                 /* ASG: update cycles */
650                 USE_CYCLES(CPU_INT_CYCLES);
651                 CPU_INT_CYCLES = 0;
652
653                 /* Return point if we had an address error */
654                 m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
655
656                 /* Main loop.  Keep going until we run out of clock cycles */
657                 do
658                 {
659                         /* Set tracing accodring to T1. (T0 is done inside instruction) */
660                         m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
661
662                         /* Set the address space for reads */
663                         m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
664
665                         /* Call external hook to peek at CPU */
666                         m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */
667
668                         /* Record previous program counter */
669                         REG_PPC = REG_PC;
670
671                         /* Read an instruction and call its handler */
672                         REG_IR = m68ki_read_imm_16();
673                         m68ki_instruction_jump_table[REG_IR]();
674                         USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
675
676                         /* Trace m68k_exception, if necessary */
677                         m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
678                 } while(GET_CYCLES() > 0);
679
680                 /* set previous PC to current PC for the next entry into the loop */
681                 REG_PPC = REG_PC;
682
683                 /* ASG: update cycles */
684                 USE_CYCLES(CPU_INT_CYCLES);
685                 CPU_INT_CYCLES = 0;
686
687                 /* return how many clocks we used */
688                 return m68ki_initial_cycles - GET_CYCLES();
689         }
690
691         /* We get here if the CPU is stopped or halted */
692         SET_CYCLES(0);
693         CPU_INT_CYCLES = 0;
694
695         return num_cycles;
696 }
697
698
699 int m68k_cycles_run(void)
700 {
701         return m68ki_initial_cycles - GET_CYCLES();
702 }
703
704 int m68k_cycles_remaining(void)
705 {
706         return GET_CYCLES();
707 }
708
709 /* Change the timeslice */
710 void m68k_modify_timeslice(int cycles)
711 {
712         m68ki_initial_cycles += cycles;
713         ADD_CYCLES(cycles);
714 }
715
716
717 void m68k_end_timeslice(void)
718 {
719         m68ki_initial_cycles = GET_CYCLES();
720         SET_CYCLES(0);
721 }
722
723
724 /* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
725 /* KS: Modified so that IPL* bits match with mask positions in the SR
726  *     and cleaned out remenants of the interrupt controller.
727  */
728 void m68k_set_irq(unsigned int int_level)
729 {
730         uint old_level = CPU_INT_LEVEL;
731         CPU_INT_LEVEL = int_level << 8;
732
733         /* A transition from < 7 to 7 always interrupts (NMI) */
734         /* Note: Level 7 can also level trigger like a normal IRQ */
735         if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
736                 m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */
737         else
738                 m68ki_check_interrupts(); /* Level triggered (IRQ) */
739 }
740
741 void m68k_init(void)
742 {
743         static uint emulation_initialized = 0;
744
745         /* The first call to this function initializes the opcode handler jump table */
746         if(!emulation_initialized)
747                 {
748                 m68ki_build_opcode_table();
749                 emulation_initialized = 1;
750         }
751
752         m68k_set_int_ack_callback(NULL);
753         m68k_set_bkpt_ack_callback(NULL);
754         m68k_set_reset_instr_callback(NULL);
755         m68k_set_pc_changed_callback(NULL);
756         m68k_set_fc_callback(NULL);
757         m68k_set_instr_hook_callback(NULL);
758 }
759
760 /* Pulse the RESET line on the CPU */
761 void m68k_pulse_reset(void)
762 {
763         /* Clear all stop levels and eat up all remaining cycles */
764         CPU_STOPPED = 0;
765         SET_CYCLES(0);
766
767         CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
768         CPU_INSTR_MODE = INSTRUCTION_YES;
769
770         /* Turn off tracing */
771         FLAG_T1 = FLAG_T0 = 0;
772         m68ki_clear_trace();
773         /* Interrupt mask to level 7 */
774         FLAG_INT_MASK = 0x0700;
775         /* Reset VBR */
776         REG_VBR = 0;
777         /* Go to supervisor mode */
778         m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);
779
780         /* Invalidate the prefetch queue */
781 #if M68K_EMULATE_PREFETCH
782         /* Set to arbitrary number since our first fetch is from 0 */
783         CPU_PREF_ADDR = 0x1000;
784 #endif /* M68K_EMULATE_PREFETCH */
785
786         /* Read the initial stack pointer and program counter */
787         m68ki_jump(0);
788         REG_SP = m68ki_read_imm_32();
789         REG_PC = m68ki_read_imm_32();
790         m68ki_jump(REG_PC);
791
792         CPU_RUN_MODE = RUN_MODE_NORMAL;
793 }
794
795 /* Pulse the HALT line on the CPU */
796 void m68k_pulse_halt(void)
797 {
798         CPU_STOPPED |= STOP_LEVEL_HALT;
799 }
800
801
802 /* Get and set the current CPU context */
803 /* This is to allow for multiple CPUs */
804 unsigned int m68k_context_size()
805 {
806         return sizeof(m68ki_cpu_core);
807 }
808
809 unsigned int m68k_get_context(void* dst)
810 {
811         if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;
812         return sizeof(m68ki_cpu_core);
813 }
814
815 void m68k_set_context(void* src)
816 {
817         if(src) m68ki_cpu = *(m68ki_cpu_core*)src;
818 }
819
820
821
822 /* ======================================================================== */
823 /* ============================== MAME STUFF ============================== */
824 /* ======================================================================== */
825
826 #if M68K_COMPILE_FOR_MAME == OPT_ON
827
828 #include "state.h"
829
830 static struct {
831         UINT16 sr;
832         int stopped;
833         int halted;
834 } m68k_substate;
835
836 static void m68k_prepare_substate(void)
837 {
838         m68k_substate.sr = m68ki_get_sr();
839         m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;
840         m68k_substate.halted  = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;
841 }
842
843 static void m68k_post_load(void)
844 {
845         m68ki_set_sr_noint_nosp(m68k_substate.sr);
846         CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0
847                         | m68k_substate.halted  ? STOP_LEVEL_HALT : 0;
848         m68ki_jump(REG_PC);
849 }
850
851 void m68k_state_register(const char *type)
852 {
853         int cpu = cpu_getactivecpu();
854
855         state_save_register_UINT32(type, cpu, "D"         , REG_D, 8);
856         state_save_register_UINT32(type, cpu, "A"         , REG_A, 8);
857         state_save_register_UINT32(type, cpu, "PPC"       , &REG_PPC, 1);
858         state_save_register_UINT32(type, cpu, "PC"        , &REG_PC, 1);
859         state_save_register_UINT32(type, cpu, "USP"       , &REG_USP, 1);
860         state_save_register_UINT32(type, cpu, "ISP"       , &REG_ISP, 1);
861         state_save_register_UINT32(type, cpu, "MSP"       , &REG_MSP, 1);
862         state_save_register_UINT32(type, cpu, "VBR"       , &REG_VBR, 1);
863         state_save_register_UINT32(type, cpu, "SFC"       , &REG_SFC, 1);
864         state_save_register_UINT32(type, cpu, "DFC"       , &REG_DFC, 1);
865         state_save_register_UINT32(type, cpu, "CACR"      , &REG_CACR, 1);
866         state_save_register_UINT32(type, cpu, "CAAR"      , &REG_CAAR, 1);
867         state_save_register_UINT16(type, cpu, "SR"        , &m68k_substate.sr, 1);
868         state_save_register_UINT32(type, cpu, "INT_LEVEL" , &CPU_INT_LEVEL, 1);
869         state_save_register_UINT32(type, cpu, "INT_CYCLES", &CPU_INT_CYCLES, 1);
870         state_save_register_int   (type, cpu, "STOPPED"   , &m68k_substate.stopped);
871         state_save_register_int   (type, cpu, "HALTED"    , &m68k_substate.halted);
872         state_save_register_UINT32(type, cpu, "PREF_ADDR" , &CPU_PREF_ADDR, 1);
873         state_save_register_UINT32(type, cpu, "PREF_DATA" , &CPU_PREF_DATA, 1);
874         state_save_register_func_presave(m68k_prepare_substate);
875         state_save_register_func_postload(m68k_post_load);
876 }
877
878 #endif /* M68K_COMPILE_FOR_MAME */
879
880 /* ======================================================================== */
881 /* ============================== END OF FILE ============================= */
882 /* ======================================================================== */