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