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