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