comparison musashi/m68kcpu.c @ 1506:ded16f3d7eb4 mame_interp

Super hacky integration of the version of Musashi from MAME
author Michael Pavone <pavone@retrodev.com>
date Wed, 27 Dec 2017 13:46:52 -0800
parents
children 2455662378ed
comparison
equal deleted inserted replaced
1471:2e6320d261ff 1506:ded16f3d7eb4
1 // license:BSD-3-Clause
2 // copyright-holders:Karl Stenerud
3 /* ======================================================================== */
4 /* ========================= LICENSING & COPYRIGHT ======================== */
5 /* ======================================================================== */
6
7 #if 0
8 static const char copyright_notice[] =
9 "MUSASHI\n"
10 "Version 4.95 (2012-02-19)\n"
11 "A portable Motorola M68xxx/CPU32/ColdFire processor emulation engine.\n"
12 "Copyright Karl Stenerud. All rights reserved.\n"
13 ;
14 #endif
15
16
17 /* ======================================================================== */
18 /* ================================= NOTES ================================ */
19 /* ======================================================================== */
20
21
22
23 /* ======================================================================== */
24 /* ================================ INCLUDES ============================== */
25 /* ======================================================================== */
26
27 #include "m68kcpu.h"
28 #include "m68kops.h"
29 #include <stdlib.h>
30 #include <string.h>
31
32
33 /* ======================================================================== */
34 /* ================================= DATA ================================= */
35 /* ======================================================================== */
36
37 /* Used by shift & rotate instructions */
38 const uint8_t m68ki_shift_8_table[65] =
39 {
40 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,
41 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
44 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0xff
46 };
47 const uint16_t m68ki_shift_16_table[65] =
48 {
49 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
50 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,
51 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
52 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
53 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
54 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
55 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
56 0xffff, 0xffff
57 };
58 const uint32_t m68ki_shift_32_table[65] =
59 {
60 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
61 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
62 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
63 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
64 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
65 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
66 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
67 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
68 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
69 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
70 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
71 };
72
73
74 /* Number of clock cycles to use for exception processing.
75 * I used 4 for any vectors that are undocumented for processing times.
76 */
77 const uint8_t m68ki_exception_cycle_table[7][256] =
78 {
79 { /* 000 */
80 40, /* 0: Reset - Initial Stack Pointer */
81 4, /* 1: Reset - Initial Program Counter */
82 50, /* 2: Bus Error (unemulated) */
83 50, /* 3: Address Error (unemulated) */
84 34, /* 4: Illegal Instruction */
85 38, /* 5: Divide by Zero */
86 40, /* 6: CHK */
87 34, /* 7: TRAPV */
88 34, /* 8: Privilege Violation */
89 34, /* 9: Trace */
90 4, /* 10: 1010 */
91 4, /* 11: 1111 */
92 4, /* 12: RESERVED */
93 4, /* 13: Coprocessor Protocol Violation (unemulated) */
94 4, /* 14: Format Error */
95 44, /* 15: Uninitialized Interrupt */
96 4, /* 16: RESERVED */
97 4, /* 17: RESERVED */
98 4, /* 18: RESERVED */
99 4, /* 19: RESERVED */
100 4, /* 20: RESERVED */
101 4, /* 21: RESERVED */
102 4, /* 22: RESERVED */
103 4, /* 23: RESERVED */
104 44, /* 24: Spurious Interrupt */
105 44, /* 25: Level 1 Interrupt Autovector */
106 44, /* 26: Level 2 Interrupt Autovector */
107 44, /* 27: Level 3 Interrupt Autovector */
108 44, /* 28: Level 4 Interrupt Autovector */
109 44, /* 29: Level 5 Interrupt Autovector */
110 44, /* 30: Level 6 Interrupt Autovector */
111 44, /* 31: Level 7 Interrupt Autovector */
112 34, /* 32: TRAP #0 */
113 34, /* 33: TRAP #1 */
114 34, /* 34: TRAP #2 */
115 34, /* 35: TRAP #3 */
116 34, /* 36: TRAP #4 */
117 34, /* 37: TRAP #5 */
118 34, /* 38: TRAP #6 */
119 34, /* 39: TRAP #7 */
120 34, /* 40: TRAP #8 */
121 34, /* 41: TRAP #9 */
122 34, /* 42: TRAP #10 */
123 34, /* 43: TRAP #11 */
124 34, /* 44: TRAP #12 */
125 34, /* 45: TRAP #13 */
126 34, /* 46: TRAP #14 */
127 34, /* 47: TRAP #15 */
128 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
129 4, /* 49: FP Inexact Result (unemulated) */
130 4, /* 50: FP Divide by Zero (unemulated) */
131 4, /* 51: FP Underflow (unemulated) */
132 4, /* 52: FP Operand Error (unemulated) */
133 4, /* 53: FP Overflow (unemulated) */
134 4, /* 54: FP Signaling NAN (unemulated) */
135 4, /* 55: FP Unimplemented Data Type (unemulated) */
136 4, /* 56: MMU Configuration Error (unemulated) */
137 4, /* 57: MMU Illegal Operation Error (unemulated) */
138 4, /* 58: MMU Access Level Violation Error (unemulated) */
139 4, /* 59: RESERVED */
140 4, /* 60: RESERVED */
141 4, /* 61: RESERVED */
142 4, /* 62: RESERVED */
143 4, /* 63: RESERVED */
144 /* 64-255: User Defined */
145 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
146 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
147 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
148 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
149 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
150 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
151 },
152 { /* 010 */
153 40, /* 0: Reset - Initial Stack Pointer */
154 4, /* 1: Reset - Initial Program Counter */
155 126, /* 2: Bus Error (unemulated) */
156 126, /* 3: Address Error (unemulated) */
157 38, /* 4: Illegal Instruction */
158 44, /* 5: Divide by Zero */
159 44, /* 6: CHK */
160 34, /* 7: TRAPV */
161 38, /* 8: Privilege Violation */
162 38, /* 9: Trace */
163 4, /* 10: 1010 */
164 4, /* 11: 1111 */
165 4, /* 12: RESERVED */
166 4, /* 13: Coprocessor Protocol Violation (unemulated) */
167 4, /* 14: Format Error */
168 44, /* 15: Uninitialized Interrupt */
169 4, /* 16: RESERVED */
170 4, /* 17: RESERVED */
171 4, /* 18: RESERVED */
172 4, /* 19: RESERVED */
173 4, /* 20: RESERVED */
174 4, /* 21: RESERVED */
175 4, /* 22: RESERVED */
176 4, /* 23: RESERVED */
177 46, /* 24: Spurious Interrupt */
178 46, /* 25: Level 1 Interrupt Autovector */
179 46, /* 26: Level 2 Interrupt Autovector */
180 46, /* 27: Level 3 Interrupt Autovector */
181 46, /* 28: Level 4 Interrupt Autovector */
182 46, /* 29: Level 5 Interrupt Autovector */
183 46, /* 30: Level 6 Interrupt Autovector */
184 46, /* 31: Level 7 Interrupt Autovector */
185 38, /* 32: TRAP #0 */
186 38, /* 33: TRAP #1 */
187 38, /* 34: TRAP #2 */
188 38, /* 35: TRAP #3 */
189 38, /* 36: TRAP #4 */
190 38, /* 37: TRAP #5 */
191 38, /* 38: TRAP #6 */
192 38, /* 39: TRAP #7 */
193 38, /* 40: TRAP #8 */
194 38, /* 41: TRAP #9 */
195 38, /* 42: TRAP #10 */
196 38, /* 43: TRAP #11 */
197 38, /* 44: TRAP #12 */
198 38, /* 45: TRAP #13 */
199 38, /* 46: TRAP #14 */
200 38, /* 47: TRAP #15 */
201 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
202 4, /* 49: FP Inexact Result (unemulated) */
203 4, /* 50: FP Divide by Zero (unemulated) */
204 4, /* 51: FP Underflow (unemulated) */
205 4, /* 52: FP Operand Error (unemulated) */
206 4, /* 53: FP Overflow (unemulated) */
207 4, /* 54: FP Signaling NAN (unemulated) */
208 4, /* 55: FP Unimplemented Data Type (unemulated) */
209 4, /* 56: MMU Configuration Error (unemulated) */
210 4, /* 57: MMU Illegal Operation Error (unemulated) */
211 4, /* 58: MMU Access Level Violation Error (unemulated) */
212 4, /* 59: RESERVED */
213 4, /* 60: RESERVED */
214 4, /* 61: RESERVED */
215 4, /* 62: RESERVED */
216 4, /* 63: RESERVED */
217 /* 64-255: User Defined */
218 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
219 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
220 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
221 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
222 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
223 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
224 },
225 { /* 020 */
226 4, /* 0: Reset - Initial Stack Pointer */
227 4, /* 1: Reset - Initial Program Counter */
228 50, /* 2: Bus Error (unemulated) */
229 50, /* 3: Address Error (unemulated) */
230 20, /* 4: Illegal Instruction */
231 38, /* 5: Divide by Zero */
232 40, /* 6: CHK */
233 20, /* 7: TRAPV */
234 34, /* 8: Privilege Violation */
235 25, /* 9: Trace */
236 20, /* 10: 1010 */
237 20, /* 11: 1111 */
238 4, /* 12: RESERVED */
239 4, /* 13: Coprocessor Protocol Violation (unemulated) */
240 4, /* 14: Format Error */
241 30, /* 15: Uninitialized Interrupt */
242 4, /* 16: RESERVED */
243 4, /* 17: RESERVED */
244 4, /* 18: RESERVED */
245 4, /* 19: RESERVED */
246 4, /* 20: RESERVED */
247 4, /* 21: RESERVED */
248 4, /* 22: RESERVED */
249 4, /* 23: RESERVED */
250 30, /* 24: Spurious Interrupt */
251 30, /* 25: Level 1 Interrupt Autovector */
252 30, /* 26: Level 2 Interrupt Autovector */
253 30, /* 27: Level 3 Interrupt Autovector */
254 30, /* 28: Level 4 Interrupt Autovector */
255 30, /* 29: Level 5 Interrupt Autovector */
256 30, /* 30: Level 6 Interrupt Autovector */
257 30, /* 31: Level 7 Interrupt Autovector */
258 20, /* 32: TRAP #0 */
259 20, /* 33: TRAP #1 */
260 20, /* 34: TRAP #2 */
261 20, /* 35: TRAP #3 */
262 20, /* 36: TRAP #4 */
263 20, /* 37: TRAP #5 */
264 20, /* 38: TRAP #6 */
265 20, /* 39: TRAP #7 */
266 20, /* 40: TRAP #8 */
267 20, /* 41: TRAP #9 */
268 20, /* 42: TRAP #10 */
269 20, /* 43: TRAP #11 */
270 20, /* 44: TRAP #12 */
271 20, /* 45: TRAP #13 */
272 20, /* 46: TRAP #14 */
273 20, /* 47: TRAP #15 */
274 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
275 4, /* 49: FP Inexact Result (unemulated) */
276 4, /* 50: FP Divide by Zero (unemulated) */
277 4, /* 51: FP Underflow (unemulated) */
278 4, /* 52: FP Operand Error (unemulated) */
279 4, /* 53: FP Overflow (unemulated) */
280 4, /* 54: FP Signaling NAN (unemulated) */
281 4, /* 55: FP Unimplemented Data Type (unemulated) */
282 4, /* 56: MMU Configuration Error (unemulated) */
283 4, /* 57: MMU Illegal Operation Error (unemulated) */
284 4, /* 58: MMU Access Level Violation Error (unemulated) */
285 4, /* 59: RESERVED */
286 4, /* 60: RESERVED */
287 4, /* 61: RESERVED */
288 4, /* 62: RESERVED */
289 4, /* 63: RESERVED */
290 /* 64-255: User Defined */
291 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
292 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
293 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
294 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
295 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
296 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
297 },
298 { /* 030 - not correct */
299 4, /* 0: Reset - Initial Stack Pointer */
300 4, /* 1: Reset - Initial Program Counter */
301 50, /* 2: Bus Error (unemulated) */
302 50, /* 3: Address Error (unemulated) */
303 20, /* 4: Illegal Instruction */
304 38, /* 5: Divide by Zero */
305 40, /* 6: CHK */
306 20, /* 7: TRAPV */
307 34, /* 8: Privilege Violation */
308 25, /* 9: Trace */
309 20, /* 10: 1010 */
310 20, /* 11: 1111 */
311 4, /* 12: RESERVED */
312 4, /* 13: Coprocessor Protocol Violation (unemulated) */
313 4, /* 14: Format Error */
314 30, /* 15: Uninitialized Interrupt */
315 4, /* 16: RESERVED */
316 4, /* 17: RESERVED */
317 4, /* 18: RESERVED */
318 4, /* 19: RESERVED */
319 4, /* 20: RESERVED */
320 4, /* 21: RESERVED */
321 4, /* 22: RESERVED */
322 4, /* 23: RESERVED */
323 30, /* 24: Spurious Interrupt */
324 30, /* 25: Level 1 Interrupt Autovector */
325 30, /* 26: Level 2 Interrupt Autovector */
326 30, /* 27: Level 3 Interrupt Autovector */
327 30, /* 28: Level 4 Interrupt Autovector */
328 30, /* 29: Level 5 Interrupt Autovector */
329 30, /* 30: Level 6 Interrupt Autovector */
330 30, /* 31: Level 7 Interrupt Autovector */
331 20, /* 32: TRAP #0 */
332 20, /* 33: TRAP #1 */
333 20, /* 34: TRAP #2 */
334 20, /* 35: TRAP #3 */
335 20, /* 36: TRAP #4 */
336 20, /* 37: TRAP #5 */
337 20, /* 38: TRAP #6 */
338 20, /* 39: TRAP #7 */
339 20, /* 40: TRAP #8 */
340 20, /* 41: TRAP #9 */
341 20, /* 42: TRAP #10 */
342 20, /* 43: TRAP #11 */
343 20, /* 44: TRAP #12 */
344 20, /* 45: TRAP #13 */
345 20, /* 46: TRAP #14 */
346 20, /* 47: TRAP #15 */
347 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
348 4, /* 49: FP Inexact Result (unemulated) */
349 4, /* 50: FP Divide by Zero (unemulated) */
350 4, /* 51: FP Underflow (unemulated) */
351 4, /* 52: FP Operand Error (unemulated) */
352 4, /* 53: FP Overflow (unemulated) */
353 4, /* 54: FP Signaling NAN (unemulated) */
354 4, /* 55: FP Unimplemented Data Type (unemulated) */
355 4, /* 56: MMU Configuration Error (unemulated) */
356 4, /* 57: MMU Illegal Operation Error (unemulated) */
357 4, /* 58: MMU Access Level Violation Error (unemulated) */
358 4, /* 59: RESERVED */
359 4, /* 60: RESERVED */
360 4, /* 61: RESERVED */
361 4, /* 62: RESERVED */
362 4, /* 63: RESERVED */
363 /* 64-255: User Defined */
364 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
365 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
366 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
367 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
368 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
369 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
370 },
371 { /* 040 */ // TODO: these values are not correct
372 4, /* 0: Reset - Initial Stack Pointer */
373 4, /* 1: Reset - Initial Program Counter */
374 50, /* 2: Bus Error (unemulated) */
375 50, /* 3: Address Error (unemulated) */
376 20, /* 4: Illegal Instruction */
377 38, /* 5: Divide by Zero */
378 40, /* 6: CHK */
379 20, /* 7: TRAPV */
380 34, /* 8: Privilege Violation */
381 25, /* 9: Trace */
382 20, /* 10: 1010 */
383 20, /* 11: 1111 */
384 4, /* 12: RESERVED */
385 4, /* 13: Coprocessor Protocol Violation (unemulated) */
386 4, /* 14: Format Error */
387 30, /* 15: Uninitialized Interrupt */
388 4, /* 16: RESERVED */
389 4, /* 17: RESERVED */
390 4, /* 18: RESERVED */
391 4, /* 19: RESERVED */
392 4, /* 20: RESERVED */
393 4, /* 21: RESERVED */
394 4, /* 22: RESERVED */
395 4, /* 23: RESERVED */
396 30, /* 24: Spurious Interrupt */
397 30, /* 25: Level 1 Interrupt Autovector */
398 30, /* 26: Level 2 Interrupt Autovector */
399 30, /* 27: Level 3 Interrupt Autovector */
400 30, /* 28: Level 4 Interrupt Autovector */
401 30, /* 29: Level 5 Interrupt Autovector */
402 30, /* 30: Level 6 Interrupt Autovector */
403 30, /* 31: Level 7 Interrupt Autovector */
404 20, /* 32: TRAP #0 */
405 20, /* 33: TRAP #1 */
406 20, /* 34: TRAP #2 */
407 20, /* 35: TRAP #3 */
408 20, /* 36: TRAP #4 */
409 20, /* 37: TRAP #5 */
410 20, /* 38: TRAP #6 */
411 20, /* 39: TRAP #7 */
412 20, /* 40: TRAP #8 */
413 20, /* 41: TRAP #9 */
414 20, /* 42: TRAP #10 */
415 20, /* 43: TRAP #11 */
416 20, /* 44: TRAP #12 */
417 20, /* 45: TRAP #13 */
418 20, /* 46: TRAP #14 */
419 20, /* 47: TRAP #15 */
420 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
421 4, /* 49: FP Inexact Result (unemulated) */
422 4, /* 50: FP Divide by Zero (unemulated) */
423 4, /* 51: FP Underflow (unemulated) */
424 4, /* 52: FP Operand Error (unemulated) */
425 4, /* 53: FP Overflow (unemulated) */
426 4, /* 54: FP Signaling NAN (unemulated) */
427 4, /* 55: FP Unimplemented Data Type (unemulated) */
428 4, /* 56: MMU Configuration Error (unemulated) */
429 4, /* 57: MMU Illegal Operation Error (unemulated) */
430 4, /* 58: MMU Access Level Violation Error (unemulated) */
431 4, /* 59: RESERVED */
432 4, /* 60: RESERVED */
433 4, /* 61: RESERVED */
434 4, /* 62: RESERVED */
435 4, /* 63: RESERVED */
436 /* 64-255: User Defined */
437 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
438 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
439 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
440 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
441 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
442 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
443 },
444 { /* CPU32 */
445 4, /* 0: Reset - Initial Stack Pointer */
446 4, /* 1: Reset - Initial Program Counter */
447 50, /* 2: Bus Error (unemulated) */
448 50, /* 3: Address Error (unemulated) */
449 20, /* 4: Illegal Instruction */
450 38, /* 5: Divide by Zero */
451 40, /* 6: CHK */
452 20, /* 7: TRAPV */
453 34, /* 8: Privilege Violation */
454 25, /* 9: Trace */
455 20, /* 10: 1010 */
456 20, /* 11: 1111 */
457 4, /* 12: RESERVED */
458 4, /* 13: Coprocessor Protocol Violation (unemulated) */
459 4, /* 14: Format Error */
460 30, /* 15: Uninitialized Interrupt */
461 4, /* 16: RESERVED */
462 4, /* 17: RESERVED */
463 4, /* 18: RESERVED */
464 4, /* 19: RESERVED */
465 4, /* 20: RESERVED */
466 4, /* 21: RESERVED */
467 4, /* 22: RESERVED */
468 4, /* 23: RESERVED */
469 30, /* 24: Spurious Interrupt */
470 30, /* 25: Level 1 Interrupt Autovector */
471 30, /* 26: Level 2 Interrupt Autovector */
472 30, /* 27: Level 3 Interrupt Autovector */
473 30, /* 28: Level 4 Interrupt Autovector */
474 30, /* 29: Level 5 Interrupt Autovector */
475 30, /* 30: Level 6 Interrupt Autovector */
476 30, /* 31: Level 7 Interrupt Autovector */
477 20, /* 32: TRAP #0 */
478 20, /* 33: TRAP #1 */
479 20, /* 34: TRAP #2 */
480 20, /* 35: TRAP #3 */
481 20, /* 36: TRAP #4 */
482 20, /* 37: TRAP #5 */
483 20, /* 38: TRAP #6 */
484 20, /* 39: TRAP #7 */
485 20, /* 40: TRAP #8 */
486 20, /* 41: TRAP #9 */
487 20, /* 42: TRAP #10 */
488 20, /* 43: TRAP #11 */
489 20, /* 44: TRAP #12 */
490 20, /* 45: TRAP #13 */
491 20, /* 46: TRAP #14 */
492 20, /* 47: TRAP #15 */
493 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
494 4, /* 49: FP Inexact Result (unemulated) */
495 4, /* 50: FP Divide by Zero (unemulated) */
496 4, /* 51: FP Underflow (unemulated) */
497 4, /* 52: FP Operand Error (unemulated) */
498 4, /* 53: FP Overflow (unemulated) */
499 4, /* 54: FP Signaling NAN (unemulated) */
500 4, /* 55: FP Unimplemented Data Type (unemulated) */
501 4, /* 56: MMU Configuration Error (unemulated) */
502 4, /* 57: MMU Illegal Operation Error (unemulated) */
503 4, /* 58: MMU Access Level Violation Error (unemulated) */
504 4, /* 59: RESERVED */
505 4, /* 60: RESERVED */
506 4, /* 61: RESERVED */
507 4, /* 62: RESERVED */
508 4, /* 63: RESERVED */
509 /* 64-255: User Defined */
510 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
511 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
512 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
513 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
514 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
515 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
516 },
517 { /* ColdFire - not correct */
518 4, /* 0: Reset - Initial Stack Pointer */
519 4, /* 1: Reset - Initial Program Counter */
520 50, /* 2: Bus Error (unemulated) */
521 50, /* 3: Address Error (unemulated) */
522 20, /* 4: Illegal Instruction */
523 38, /* 5: Divide by Zero */
524 40, /* 6: CHK */
525 20, /* 7: TRAPV */
526 34, /* 8: Privilege Violation */
527 25, /* 9: Trace */
528 20, /* 10: 1010 */
529 20, /* 11: 1111 */
530 4, /* 12: RESERVED */
531 4, /* 13: Coprocessor Protocol Violation (unemulated) */
532 4, /* 14: Format Error */
533 30, /* 15: Uninitialized Interrupt */
534 4, /* 16: RESERVED */
535 4, /* 17: RESERVED */
536 4, /* 18: RESERVED */
537 4, /* 19: RESERVED */
538 4, /* 20: RESERVED */
539 4, /* 21: RESERVED */
540 4, /* 22: RESERVED */
541 4, /* 23: RESERVED */
542 30, /* 24: Spurious Interrupt */
543 30, /* 25: Level 1 Interrupt Autovector */
544 30, /* 26: Level 2 Interrupt Autovector */
545 30, /* 27: Level 3 Interrupt Autovector */
546 30, /* 28: Level 4 Interrupt Autovector */
547 30, /* 29: Level 5 Interrupt Autovector */
548 30, /* 30: Level 6 Interrupt Autovector */
549 30, /* 31: Level 7 Interrupt Autovector */
550 20, /* 32: TRAP #0 */
551 20, /* 33: TRAP #1 */
552 20, /* 34: TRAP #2 */
553 20, /* 35: TRAP #3 */
554 20, /* 36: TRAP #4 */
555 20, /* 37: TRAP #5 */
556 20, /* 38: TRAP #6 */
557 20, /* 39: TRAP #7 */
558 20, /* 40: TRAP #8 */
559 20, /* 41: TRAP #9 */
560 20, /* 42: TRAP #10 */
561 20, /* 43: TRAP #11 */
562 20, /* 44: TRAP #12 */
563 20, /* 45: TRAP #13 */
564 20, /* 46: TRAP #14 */
565 20, /* 47: TRAP #15 */
566 4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
567 4, /* 49: FP Inexact Result (unemulated) */
568 4, /* 50: FP Divide by Zero (unemulated) */
569 4, /* 51: FP Underflow (unemulated) */
570 4, /* 52: FP Operand Error (unemulated) */
571 4, /* 53: FP Overflow (unemulated) */
572 4, /* 54: FP Signaling NAN (unemulated) */
573 4, /* 55: FP Unimplemented Data Type (unemulated) */
574 4, /* 56: MMU Configuration Error (unemulated) */
575 4, /* 57: MMU Illegal Operation Error (unemulated) */
576 4, /* 58: MMU Access Level Violation Error (unemulated) */
577 4, /* 59: RESERVED */
578 4, /* 60: RESERVED */
579 4, /* 61: RESERVED */
580 4, /* 62: RESERVED */
581 4, /* 63: RESERVED */
582 /* 64-255: User Defined */
583 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
584 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
585 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
586 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
587 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
588 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
589 },
590 };
591
592 const uint8_t m68ki_ea_idx_cycle_table[64] =
593 {
594 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
595 0, /* ..01.000 no memory indirect, base nullptr */
596 5, /* ..01..01 memory indirect, base nullptr, outer nullptr */
597 7, /* ..01..10 memory indirect, base nullptr, outer 16 */
598 7, /* ..01..11 memory indirect, base nullptr, outer 32 */
599 0, 5, 7, 7, 0, 5, 7, 7, 0, 5, 7, 7,
600 2, /* ..10.000 no memory indirect, base 16 */
601 7, /* ..10..01 memory indirect, base 16, outer nullptr */
602 9, /* ..10..10 memory indirect, base 16, outer 16 */
603 9, /* ..10..11 memory indirect, base 16, outer 32 */
604 0, 7, 9, 9, 0, 7, 9, 9, 0, 7, 9, 9,
605 6, /* ..11.000 no memory indirect, base 32 */
606 11, /* ..11..01 memory indirect, base 32, outer nullptr */
607 13, /* ..11..10 memory indirect, base 32, outer 16 */
608 13, /* ..11..11 memory indirect, base 32, outer 32 */
609 0, 11, 13, 13, 0, 11, 13, 13, 0, 11, 13, 13
610 };
611
612
613
614 /***************************************************************************
615 CPU STATE DESCRIPTION
616 ***************************************************************************/
617
618 #define MASK_ALL (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_EC040 | CPU_TYPE_040 | CPU_TYPE_FSCPU32 )
619 #define MASK_24BIT_SPACE (CPU_TYPE_000 | CPU_TYPE_008 | CPU_TYPE_010 | CPU_TYPE_EC020)
620 #define MASK_32BIT_SPACE (CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_EC040 | CPU_TYPE_040 | CPU_TYPE_FSCPU32 )
621 #define MASK_010_OR_LATER (CPU_TYPE_010 | CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040 | CPU_TYPE_FSCPU32 )
622 #define MASK_020_OR_LATER (CPU_TYPE_EC020 | CPU_TYPE_020 | CPU_TYPE_EC030 | CPU_TYPE_030 | CPU_TYPE_EC040 | CPU_TYPE_040 | CPU_TYPE_FSCPU32 )
623 #define MASK_030_OR_LATER (CPU_TYPE_030 | CPU_TYPE_EC030 | CPU_TYPE_040 | CPU_TYPE_EC040)
624 #define MASK_040_OR_LATER (CPU_TYPE_040 | CPU_TYPE_EC040)
625
626
627
628 /* ======================================================================== */
629 /* ================================= API ================================== */
630 /* ======================================================================== */
631
632
633
634 void m68k_cpu_execute(m68000_base_device *this)
635 {
636 //this->initial_cycles = this->remaining_cycles;
637
638 /* eat up any reset cycles */
639 /*if (this->reset_cycles) {
640 int rc = this->reset_cycles;
641 this->reset_cycles = 0;
642 this->remaining_cycles -= rc;
643
644 if (this->remaining_cycles <= 0) return;
645 }*/
646
647 /* See if interrupts came in */
648 m68ki_check_interrupts(this);
649
650 /* Make sure we're not stopped */
651 if(!this->stopped)
652 {
653 /* Return point if we had an address error */
654 /*check_address_error:
655 if (this->m_address_error==1)
656 {
657 this->m_address_error = 0;
658 try {
659 m68ki_exception_address_error(this);
660 }
661 catch(int error)
662 {
663 if (error==10)
664 {
665 this->m_address_error = 1;
666 REG_PPC(this) = REG_PC(this);
667 goto check_address_error;
668 }
669 else
670 throw;
671 }
672 if(stopped)
673 {
674 if (remaining_cycles > 0)
675 remaining_cycles = 0;
676 return;
677 }
678 }*/
679
680
681 /* Main loop. Keep going until we run out of clock cycles */
682 while (this->c.current_cycle < this->c.target_cycle)
683 {
684 /* Set tracing accodring to T1. (T0 is done inside instruction) */
685 m68ki_trace_t1(this); /* auto-disable (see m68kcpu.h) */
686
687 /* Record previous program counter */
688 REG_PPC(this) = REG_PC(this);
689
690
691 this->run_mode = RUN_MODE_NORMAL;
692 /* Read an instruction and call its handler */
693 this->ir = m68ki_read_imm_16(this);
694 this->jump_table[this->ir](this);
695 this->c.current_cycle += this->cyc_instruction[this->ir];
696
697 /*}
698 catch (int error)
699 {
700 if (error==10)
701 {
702 m_address_error = 1;
703 goto check_address_error;
704 }
705 else
706 throw;
707 }*/
708
709
710 /* Trace m68k_exception, if necessary */
711 //m68ki_exception_if_trace(this); /* auto-disable (see m68kcpu.h) */
712 }
713
714 /* set previous PC to current PC for the next entry into the loop */
715 REG_PPC(this) = REG_PC(this);
716 }
717 else if (this->c.current_cycle < this->c.target_cycle)
718 this->c.current_cycle = this->c.target_cycle;
719 this->c.status = m68ki_get_sr(this) >> 8;
720 }
721
722
723
724 void m68k_init_cpu_common(m68000_base_device *this)
725 {
726 static uint32_t emulation_initialized = 0;
727
728
729 /* The first call to this function initializes the opcode handler jump table */
730 if(!emulation_initialized)
731 {
732 m68ki_build_opcode_table();
733 emulation_initialized = 1;
734 }
735
736
737
738 //m_icountptr = &remaining_cycles;
739 this->c.current_cycle = 0;
740
741 }
742
743 void m68k_reset_cpu(m68000_base_device *this)
744 {
745
746
747 /* Clear all stop levels and eat up all remaining cycles */
748 this->stopped = 0;
749
750 this->run_mode = RUN_MODE_BERR_AERR_RESET;
751 /* Go to supervisor mode */
752 m68ki_set_sm_flag(this, SFLAG_SET | MFLAG_CLEAR);
753
754 /* Invalidate the prefetch queue */
755 /* Set to arbitrary number since our first fetch is from 0 */
756 this->pref_addr = 0x1000;
757
758 /* Read the initial stack pointer and program counter */
759 m68ki_jump(this, 0);
760 REG_SP(this) = m68ki_read_imm_32(this);
761 REG_PC(this) = m68ki_read_imm_32(this);
762 m68ki_jump(this, REG_PC(this));
763
764 this->run_mode = RUN_MODE_NORMAL;
765
766 this->c.current_cycle += this->cyc_exception[EXCEPTION_RESET];
767
768 }
769
770 /****************************************************************************
771 * 8-bit data memory interface
772 ****************************************************************************/
773
774 uint8_t m68ki_read_8(m68000_base_device *m68k, uint32_t address)
775 {
776 return read_byte(address, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
777 }
778
779 void m68ki_write_8(m68000_base_device *m68k, uint32_t address, uint8_t value)
780 {
781 write_byte(address, value, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
782 }
783
784 /****************************************************************************
785 * 16-bit data memory interface
786 ****************************************************************************/
787
788 uint16_t m68ki_read_16(m68000_base_device *m68k, uint32_t address)
789 {
790 return read_word(address, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
791 }
792
793 void m68ki_write_16(m68000_base_device *m68k, uint32_t address, uint16_t value)
794 {
795 write_word(address, value, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
796 }
797
798
799 /****************
800 CPU Inits
801 ****************/
802
803
804 void m68k_init_cpu_m68000(m68000_base_device *this)
805 {
806 m68k_init_cpu_common(this);
807
808 this->cpu_type = CPU_TYPE_000;
809 // dasm_type = M68K_CPU_TYPE_68000;
810
811 this->sr_mask = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
812 this->jump_table = m68ki_instruction_jump_table[0];
813 uint8_t *tmp = malloc(sizeof(m68ki_cycles[0]));
814 for (uint32_t i = 0; i < sizeof(m68ki_cycles[0]); i++)
815 {
816 tmp[i] = m68ki_cycles[0][i] * this->c.options->gen.clock_divider;
817 }
818 this->cyc_instruction = tmp;
819 tmp = malloc(sizeof(m68ki_exception_cycle_table[0]));
820 for (uint32_t i = 0; i < sizeof(m68ki_exception_cycle_table[0]); i++)
821 {
822 tmp[i] = m68ki_exception_cycle_table[0][i] * this->c.options->gen.clock_divider;
823 }
824 this->cyc_exception = tmp;
825 this->cyc_bcc_notake_b = -2 * this->c.options->gen.clock_divider;
826 this->cyc_bcc_notake_w = 2 * this->c.options->gen.clock_divider;
827 this->cyc_dbcc_f_noexp = -2 * this->c.options->gen.clock_divider;
828 this->cyc_dbcc_f_exp = 2 * this->c.options->gen.clock_divider;
829 this->cyc_scc_r_true = 2 * this->c.options->gen.clock_divider;
830 this->cyc_movem_w = 2;// * this->c.options->gen.clock_divider;
831 this->cyc_movem_l = 3;// * this->c.options->gen.clock_divider;
832 this->cyc_shift = 1;// * this->c.options->gen.clock_divider;
833 this->cyc_reset = 132 * this->c.options->gen.clock_divider;
834 this->int_mask = 7 << 8;
835 this->c.status = m68ki_get_sr(this) >> 8;
836 }
837
838 /* Service an interrupt request and start exception processing */
839 void m68ki_exception_interrupt(m68000_base_device *this, uint32_t int_level)
840 {
841 uint32_t vector;
842 uint32_t sr;
843 uint32_t new_pc;
844
845 if(CPU_TYPE_IS_000(this->cpu_type))
846 {
847 this->instr_mode = INSTRUCTION_NO;
848 }
849
850 /* Turn off the stopped state */
851 this->stopped &= ~STOP_LEVEL_STOP;
852
853 /* If we are halted, don't do anything */
854 if(this->stopped)
855 return;
856
857 /* Acknowledge the interrupt */
858 this->c.int_ack = int_level;
859
860 vector = M68K_INT_ACK_AUTOVECTOR;//int_ack_callback(*this, int_level);
861
862 /* Get the interrupt vector */
863 if(vector == M68K_INT_ACK_AUTOVECTOR)
864 /* Use the autovectors. This is the most commonly used implementation */
865 vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
866 else if(vector == M68K_INT_ACK_SPURIOUS)
867 /* Called if no devices respond to the interrupt acknowledge */
868 vector = EXCEPTION_SPURIOUS_INTERRUPT;
869 else if(vector > 255)
870 return;
871
872 /* Start exception processing */
873 sr = m68ki_init_exception(this);
874
875 /* Set the interrupt mask to the level of the one being serviced */
876 this->int_mask = int_level<<8;
877
878 /* Get the new PC */
879 new_pc = m68ki_read_32(this, (vector<<2) /*+ vbr*/);
880
881 /* If vector is uninitialized, call the uninitialized interrupt vector */
882 if(new_pc == 0)
883 new_pc = m68ki_read_32(this, (EXCEPTION_UNINITIALIZED_INTERRUPT<<2) /*+ vbr*/);
884
885 /* Generate a stack frame */
886 m68ki_stack_frame_0000(this, REG_PC(this), sr, vector);
887 if(this->m_flag && CPU_TYPE_IS_EC020_PLUS(this->cpu_type))
888 {
889 /* Create throwaway frame */
890 m68ki_set_sm_flag(this, this->s_flag); /* clear M */
891 sr |= 0x2000; /* Same as SR in master stack frame except S is forced high */
892 m68ki_stack_frame_0001(this, REG_PC(this), sr, vector);
893 }
894
895 m68ki_jump(this, new_pc);
896
897 /* Defer cycle counting until later */
898 this->c.current_cycle += this->cyc_exception[vector];
899 }
900
901