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