0.0088 release
[picodrive.git] / cpu / musashi / m68kcpu.c
CommitLineData
cc68a136 1/* ======================================================================== */\r
2/* ========================= LICENSING & COPYRIGHT ======================== */\r
3/* ======================================================================== */\r
4\r
5#if 0\r
6static const char* copyright_notice =\r
7"MUSASHI\n"\r
c6a4c892 8"Version 3.31 (2007-07-09)\n"\r
cc68a136 9"A portable Motorola M680x0 processor emulation engine.\n"\r
c6a4c892 10"Copyright 1998-2007 Karl Stenerud. All rights reserved.\n"\r
cc68a136 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
c6a4c892 35extern void m68040_fpu_op0(void);\r
36extern void m68040_fpu_op1(void);\r
37\r
cc68a136 38#include "m68kops.h"\r
39#include "m68kcpu.h"\r
c6a4c892 40//#include "m68kfpu.c"\r
cc68a136 41\r
42/* ======================================================================== */\r
43/* ================================= DATA ================================= */\r
44/* ======================================================================== */\r
45\r
c6a4c892 46int m68ki_initial_cycles;\r
47//int m68ki_remaining_cycles = 0; /* Number of clocks remaining */\r
cc68a136 48uint m68ki_tracing = 0;\r
49uint m68ki_address_space;\r
50\r
51#ifdef M68K_LOG_ENABLE\r
52const 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
c6a4c892 75// notaz\r
cc68a136 76m68ki_cpu_core *m68ki_cpu_p = NULL;\r
c6a4c892 77//m68ki_cpu_core m68ki_cpu = {0};\r
cc68a136 78\r
79\r
80#if M68K_EMULATE_ADDRESS_ERROR\r
81jmp_buf m68ki_aerr_trap;\r
82#endif /* M68K_EMULATE_ADDRESS_ERROR */\r
83\r
84uint m68ki_aerr_address;\r
85uint m68ki_aerr_write_mode;\r
86uint m68ki_aerr_fc;\r
87\r
88/* Used by shift & rotate instructions */\r
89uint8 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
98uint16 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
109uint 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
128uint8 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
424uint8 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
455static int default_int_ack_callback_data;\r
456static 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
464static unsigned int default_bkpt_ack_callback_data;\r
465static 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
471static 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
476static 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
481static void default_rte_instr_callback(void)\r
482{\r
483}\r
484\r
c6a4c892 485/* Called when a tas instruction is executed */\r
486static int default_tas_instr_callback(void)\r
487{\r
488 return 1; // allow writeback\r
489}\r
490\r
cc68a136 491/* Called when the program counter changed by a large value */\r
492static unsigned int default_pc_changed_callback_data;\r
493static 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
499static unsigned int default_set_fc_callback_data;\r
500static 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
506static 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
522unsigned 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
584void 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
636void 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
641void 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
646void 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
651void 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
656void 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
c6a4c892 661void 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
cc68a136 666void 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
671void 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
676void 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
683void 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
788int m68k_execute(int num_cycles)\r
789{\r
790 /* Make sure we're not stopped */\r
791 if(!CPU_STOPPED)\r
792 {\r
793 /* Set our pool of clock cycles available */\r
794 SET_CYCLES(num_cycles);\r
795 m68ki_initial_cycles = num_cycles;\r
796\r
797 /* ASG: update cycles */\r
798 USE_CYCLES(CPU_INT_CYCLES);\r
799 CPU_INT_CYCLES = 0;\r
800\r
801 /* Return point if we had an address error */\r
802 m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */\r
803\r
804 /* Main loop. Keep going until we run out of clock cycles */\r
c6a4c892 805 // notaz\r
d9153729 806 while(GET_CYCLES() >= 0)\r
c6a4c892 807// do\r
cc68a136 808 {\r
809 /* Set tracing accodring to T1. (T0 is done inside instruction) */\r
810 m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */\r
811\r
812 /* Set the address space for reads */\r
813 m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */\r
814\r
815 /* Call external hook to peek at CPU */\r
816 m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */\r
817\r
818 /* Record previous program counter */\r
819 REG_PPC = REG_PC;\r
820\r
821 /* Read an instruction and call its handler */\r
822 REG_IR = m68ki_read_imm_16();\r
823 m68ki_instruction_jump_table[REG_IR]();\r
824 USE_CYCLES(CYC_INSTRUCTION[REG_IR]);\r
825\r
826 /* Trace m68k_exception, if necessary */\r
827 m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */\r
c6a4c892 828 } // while(GET_CYCLES() > 0); // notaz\r
cc68a136 829\r
830 /* set previous PC to current PC for the next entry into the loop */\r
831 REG_PPC = REG_PC;\r
832\r
833 /* ASG: update cycles */\r
834 USE_CYCLES(CPU_INT_CYCLES);\r
835 CPU_INT_CYCLES = 0;\r
836\r
837 /* return how many clocks we used */\r
838 return m68ki_initial_cycles - GET_CYCLES();\r
839 }\r
840\r
841 /* We get here if the CPU is stopped or halted */\r
842 SET_CYCLES(0);\r
843 CPU_INT_CYCLES = 0;\r
844\r
845 return num_cycles;\r
846}\r
847\r
c6a4c892 848\r
cc68a136 849int m68k_cycles_run(void)\r
850{\r
851 return m68ki_initial_cycles - GET_CYCLES();\r
852}\r
853\r
854int m68k_cycles_remaining(void)\r
855{\r
856 return GET_CYCLES();\r
857}\r
858\r
859/* Change the timeslice */\r
860void m68k_modify_timeslice(int cycles)\r
861{\r
862 m68ki_initial_cycles += cycles;\r
863 ADD_CYCLES(cycles);\r
864}\r
865\r
866\r
867void m68k_end_timeslice(void)\r
868{\r
869 m68ki_initial_cycles = GET_CYCLES();\r
870 SET_CYCLES(0);\r
871}\r
c6a4c892 872\r
cc68a136 873\r
874/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */\r
875/* KS: Modified so that IPL* bits match with mask positions in the SR\r
876 * and cleaned out remenants of the interrupt controller.\r
877 */\r
878void m68k_set_irq(unsigned int int_level)\r
879{\r
880 uint old_level = CPU_INT_LEVEL;\r
881 CPU_INT_LEVEL = int_level << 8;\r
882\r
883 /* A transition from < 7 to 7 always interrupts (NMI) */\r
884 /* Note: Level 7 can also level trigger like a normal IRQ */\r
885 if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)\r
886 m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */\r
887 else\r
888 m68ki_check_interrupts(); /* Level triggered (IRQ) */\r
889}\r
890\r
891void m68k_init(void)\r
892{\r
893 static uint emulation_initialized = 0;\r
894\r
895 /* The first call to this function initializes the opcode handler jump table */\r
896 if(!emulation_initialized)\r
897 {\r
898 m68ki_build_opcode_table();\r
899 emulation_initialized = 1;\r
900 }\r
901\r
902 m68k_set_int_ack_callback(NULL);\r
903 m68k_set_bkpt_ack_callback(NULL);\r
904 m68k_set_reset_instr_callback(NULL);\r
905 m68k_set_cmpild_instr_callback(NULL);\r
906 m68k_set_rte_instr_callback(NULL);\r
c6a4c892 907 m68k_set_tas_instr_callback(NULL);\r
cc68a136 908 m68k_set_pc_changed_callback(NULL);\r
909 m68k_set_fc_callback(NULL);\r
910 m68k_set_instr_hook_callback(NULL);\r
911}\r
912\r
913/* Pulse the RESET line on the CPU */\r
914void m68k_pulse_reset(void)\r
915{\r
916 /* Clear all stop levels and eat up all remaining cycles */\r
917 CPU_STOPPED = 0;\r
918 SET_CYCLES(0);\r
919\r
920 CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;\r
921\r
922 /* Turn off tracing */\r
923 FLAG_T1 = FLAG_T0 = 0;\r
924 m68ki_clear_trace();\r
925 /* Interrupt mask to level 7 */\r
926 FLAG_INT_MASK = 0x0700;\r
927 /* Reset VBR */\r
928 REG_VBR = 0;\r
929 /* Go to supervisor mode */\r
930 m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);\r
931\r
932 /* Invalidate the prefetch queue */\r
933#if M68K_EMULATE_PREFETCH\r
934 /* Set to arbitrary number since our first fetch is from 0 */\r
935 CPU_PREF_ADDR = 0x1000;\r
936#endif /* M68K_EMULATE_PREFETCH */\r
937\r
938 /* Read the initial stack pointer and program counter */\r
939 m68ki_jump(0);\r
940 REG_SP = m68ki_read_imm_32();\r
941 REG_PC = m68ki_read_imm_32();\r
942 m68ki_jump(REG_PC);\r
943\r
944 CPU_RUN_MODE = RUN_MODE_NORMAL;\r
945}\r
946\r
947/* Pulse the HALT line on the CPU */\r
948void m68k_pulse_halt(void)\r
949{\r
950 CPU_STOPPED |= STOP_LEVEL_HALT;\r
951}\r
952\r
953\r
954/* Get and set the current CPU context */\r
955/* This is to allow for multiple CPUs */\r
956unsigned int m68k_context_size()\r
957{\r
958 return sizeof(m68ki_cpu_core);\r
959}\r
960\r
cc68a136 961unsigned int m68k_get_context(void* dst)\r
962{\r
963 if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;\r
964 return sizeof(m68ki_cpu_core);\r
965}\r
cc68a136 966\r
967void m68k_set_context(void* src)\r
968{\r
c6a4c892 969 // notaz\r
cc68a136 970 if(src) m68ki_cpu_p = src;\r
c6a4c892 971// if(src) m68ki_cpu = *(m68ki_cpu_core*)src;\r
cc68a136 972}\r
973\r
974\r
975\r
976/* ======================================================================== */\r
977/* ============================== MAME STUFF ============================== */\r
978/* ======================================================================== */\r
979\r
980#if M68K_COMPILE_FOR_MAME == OPT_ON\r
981\r
cc68a136 982static struct {\r
983 UINT16 sr;\r
984 UINT8 stopped;\r
985 UINT8 halted;\r
986} m68k_substate;\r
987\r
988static void m68k_prepare_substate(void)\r
989{\r
990 m68k_substate.sr = m68ki_get_sr();\r
991 m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;\r
992 m68k_substate.halted = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;\r
993}\r
994\r
995static void m68k_post_load(void)\r
996{\r
997 m68ki_set_sr_noint_nosp(m68k_substate.sr);\r
998 CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0\r
999 | m68k_substate.halted ? STOP_LEVEL_HALT : 0;\r
1000 m68ki_jump(REG_PC);\r
1001}\r
1002\r
1003void m68k_state_register(const char *type, int index)\r
1004{\r
1005 state_save_register_item_array(type, index, REG_D);\r
1006 state_save_register_item_array(type, index, REG_A);\r
1007 state_save_register_item(type, index, REG_PPC);\r
1008 state_save_register_item(type, index, REG_PC);\r
1009 state_save_register_item(type, index, REG_USP);\r
1010 state_save_register_item(type, index, REG_ISP);\r
1011 state_save_register_item(type, index, REG_MSP);\r
1012 state_save_register_item(type, index, REG_VBR);\r
1013 state_save_register_item(type, index, REG_SFC);\r
1014 state_save_register_item(type, index, REG_DFC);\r
1015 state_save_register_item(type, index, REG_CACR);\r
1016 state_save_register_item(type, index, REG_CAAR);\r
1017 state_save_register_item(type, index, m68k_substate.sr);\r
1018 state_save_register_item(type, index, CPU_INT_LEVEL);\r
1019 state_save_register_item(type, index, CPU_INT_CYCLES);\r
1020 state_save_register_item(type, index, m68k_substate.stopped);\r
1021 state_save_register_item(type, index, m68k_substate.halted);\r
1022 state_save_register_item(type, index, CPU_PREF_ADDR);\r
1023 state_save_register_item(type, index, CPU_PREF_DATA);\r
1024 state_save_register_func_presave(m68k_prepare_substate);\r
1025 state_save_register_func_postload(m68k_post_load);\r
1026}\r
1027\r
1028#endif /* M68K_COMPILE_FOR_MAME */\r
1029\r
1030/* ======================================================================== */\r
1031/* ============================== END OF FILE ============================= */\r
1032/* ======================================================================== */\r