Mercurial > repos > blastem
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 |