1 /***************************************************************************
2
3 cpuintrf.c
4
5 Core CPU interface functions and definitions.
6
7 Cleanup phase 1: split into two pieces
8 Cleanup phase 2: simplify CPU core interfaces
9 Cleanup phase 3: phase out old interrupt system
10
11 ***************************************************************************/
12
13 #include "driver.h"
14 #include "state.h"
15 #include "mamedbg.h"
16
17
18
19 /*************************************
20 *
21 * Include headers from all CPUs
22 *
23 *************************************/
24
25 #if (HAS_Z80)
26 #include "cpu/z80/z80.h"
27 #endif
28 #if (HAS_DRZ80)
29 #include "cpu/z80_drz80/drz80_z80.h"
30 #endif
31 #if (HAS_Z180)
32 #include "cpu/z180/z180.h"
33 #endif
34 #if (HAS_8080 || HAS_8085A)
35 #include "cpu/i8085/i8085.h"
36 #endif
37 #if (HAS_M6502 || HAS_M65C02 || HAS_M65SC02 || HAS_M6510 || HAS_M6510T || HAS_M7501 || HAS_M8502 || HAS_N2A03 || HAS_DECO16)
38 #include "cpu/m6502/m6502.h"
39 #endif
40 #if (HAS_M4510)
41 #include "cpu/m6502/m4510.h"
42 #endif
43 #if (HAS_M65CE02)
44 #include "cpu/m6502/m65ce02.h"
45 #endif
46 #if (HAS_M6509)
47 #include "cpu/m6502/m6509.h"
48 #endif
49 #if (HAS_H6280)
50 #include "cpu/h6280/h6280.h"
51 #endif
52 #if (HAS_I86)
53 #include "cpu/i86/i86intf.h"
54 #endif
55 #if (HAS_I88)
56 #include "cpu/i86/i88intf.h"
57 #endif
58 #if (HAS_I186)
59 #include "cpu/i86/i186intf.h"
60 #endif
61 #if (HAS_I188)
62 #include "cpu/i86/i188intf.h"
63 #endif
64 #if (HAS_I286)
65 #include "cpu/i86/i286intf.h"
66 #endif
67 #if (HAS_V20 || HAS_V30 || HAS_V33)
68 #include "cpu/nec/necintrf.h"
69 #endif
70 #if (HAS_V60 || HAS_V70)
71 #include "cpu/v60/v60.h"
72 #endif
73 #if (HAS_I8035 || HAS_I8039 || HAS_I8048 || HAS_N7751)
74 #include "cpu/i8039/i8039.h"
75 #endif
76 #if (HAS_I8X41)
77 #include "cpu/i8x41/i8x41.h"
78 #endif
79 #if (HAS_M6800 || HAS_M6801 || HAS_M6802 || HAS_M6803 || HAS_M6808 || HAS_HD63701)
80 #include "cpu/m6800/m6800.h"
81 #endif
82 #if (HAS_M6805 || HAS_M68705 || HAS_HD63705)
83 #include "cpu/m6805/m6805.h"
84 #endif
85 #if (HAS_M6809)
86 #include "cpu/m6809/m6809.h"
87 #endif
88 #if (HAS_HD6309)
89 #include "cpu/hd6309/hd6309.h"
90 #endif
91 #if (HAS_KONAMI)
92 #include "cpu/konami/konami.h"
93 #endif
94 #if (HAS_M68000 || HAS_M68010 || HAS_M68020 || HAS_M68EC020)
95 #include "cpu/m68000/m68000.h"
96 #endif
97 #if (HAS_CYCLONE)
98 #include "cpu/m68000_cyclone/c68000.h"
99 #endif
100 #if (HAS_T11)
101 #include "cpu/t11/t11.h"
102 #endif
103 #if (HAS_S2650)
104 #include "cpu/s2650/s2650.h"
105 #endif
106 #if (HAS_TMS34010 || HAS_TMS34020)
107 #include "cpu/tms34010/tms34010.h"
108 #endif
109 #if (HAS_TMS9900 || HAS_TMS9940 || HAS_TMS9980 || HAS_TMS9985 || HAS_TMS9989 || HAS_TMS9995 || HAS_TMS99105A || HAS_TMS99110A)
110 #include "cpu/tms9900/tms9900.h"
111 #endif
112 #if (HAS_Z8000)
113 #include "cpu/z8000/z8000.h"
114 #endif
115 #if (HAS_TMS32010)
116 #include "cpu/tms32010/tms32010.h"
117 #endif
118 #if (HAS_TMS32025)
119 #include "cpu/tms32025/tms32025.h"
120 #endif
121 #if (HAS_TMS32031)
122 #include "cpu/tms32031/tms32031.h"
123 #endif
124 #if (HAS_CCPU)
125 #include "cpu/ccpu/ccpu.h"
126 #endif
127 #if (HAS_ADSP2100 || HAS_ADSP2101 || HAS_ADSP2104 || HAS_ADSP2105 || HAS_ADSP2115)
128 #include "cpu/adsp2100/adsp2100.h"
129 #endif
130 #if (HAS_PSXCPU)
131 #include "cpu/mips/psx.h"
132 #endif
133 #if (HAS_ASAP)
134 #include "cpu/asap/asap.h"
135 #endif
136 #if (HAS_UPD7810 || HAS_UPD7807)
137 #include "cpu/upd7810/upd7810.h"
138 #endif
139 #if (HAS_JAGUAR)
140 #include "cpu/jaguar/jaguar.h"
141 #endif
142 #if (HAS_R3000)
143 #include "cpu/mips/r3000.h"
144 #endif
145 #if (HAS_R4600 || HAS_R5000)
146 #include "cpu/mips/mips3.h"
147 #endif
148 #if (HAS_ARM)
149 #include "cpu/arm/arm.h"
150 #endif
151 #if (HAS_SH2)
152 #include "cpu/sh2/sh2.h"
153 #endif
154 #if (HAS_DSP32C)
155 #include "cpu/dsp32/dsp32.h"
156 #endif
157 #if (HAS_PIC16C54 || HAS_PIC16C55 || HAS_PIC16C56 || HAS_PIC16C57 || HAS_PIC16C58)
158 #include "cpu/pic16c5x/pic16c5x.h"
159 #endif
160 #if (HAS_G65816)
161 #include "cpu/g65816/g65816.h"
162 #endif
163 #if (HAS_SPC700)
164 #include "cpu/spc700/spc700.h"
165 #endif
166 #if (HAS_E132XS)
167 #include "cpu/e132xs/e132xs.h"
168 #endif
169
170
171
172 /*************************************
173 *
174 * Macros to help verify active CPU
175 *
176 *************************************/
177
178 #define VERIFY_ACTIVECPU(retval, name) \
179 if (activecpu < 0) \
180 { \
181 return retval; \
182 }
183
184 #define VERIFY_ACTIVECPU_VOID(name) \
185 if (activecpu < 0) \
186 { \
187 return; \
188 }
189
190
191
192 /*************************************
193 *
194 * Macros to help verify CPU index
195 *
196 *************************************/
197
198 #define VERIFY_CPUNUM(retval, name) \
199 if (cpunum < 0 || cpunum >= totalcpu) \
200 { \
201 return retval; \
202 }
203
204 #define VERIFY_CPUNUM_VOID(name) \
205 if (cpunum < 0 || cpunum >= totalcpu) \
206 { \
207 return; \
208 }
209
210
211
212 /*************************************
213 *
214 * Internal CPU info type
215 *
216 *************************************/
217
218 struct cpuinfo
219 {
220 struct cpu_interface intf; /* copy of the interface data */
221 int cputype; /* type index of this CPU */
222 int family; /* family index of this CPU */
223 void *context; /* dynamically allocated context buffer */
224 };
225
226
227
228 /*************************************
229 *
230 * Prototypes for dummy CPU
231 *
232 *************************************/
233
234 static void dummy_init(void);
235 static void dummy_reset(void *param);
236 static void dummy_exit(void);
237 static int dummy_execute(int cycles);
238 static unsigned dummy_get_context(void *regs);
239 static void dummy_set_context(void *regs);
240 static unsigned dummy_get_reg(int regnum);
241 static void dummy_set_reg(int regnum, unsigned val);
242 static void dummy_set_irq_line(int irqline, int state);
243 static void dummy_set_irq_callback(int (*callback)(int irqline));
244 static int dummy_ICount;
245 static const char *dummy_info(void *context, int regnum);
246 static unsigned dummy_dasm(char *buffer, unsigned pc);
247
248
249
250 /*************************************
251 *
252 * Macros to generate CPU entries
253 *
254 *************************************/
255
256 /* most CPUs use this macro */
257 #define CPU0(cpu,name,nirq,dirq,oc,datawidth,mem,shift,bits,endian,align,maxinst) \
258 { \
259 CPU_##cpu, \
260 name##_init, name##_reset, name##_exit, name##_execute, NULL, \
261 name##_get_context, name##_set_context, NULL, NULL, \
262 name##_get_reg, name##_set_reg, \
263 name##_set_irq_line, name##_set_irq_callback, \
264 name##_info, name##_dasm, \
265 nirq, dirq, &name##_ICount, oc, \
266 datawidth, \
267 (mem_read_handler)cpu_readmem##mem, (mem_write_handler)cpu_writemem##mem, NULL, NULL, \
268 0, cpu_setopbase##mem, \
269 shift, bits, CPU_IS_##endian, align, maxinst \
270 }
271
272 /* CPUs which have the _burn function */
273 #define CPU1(cpu,name,nirq,dirq,oc,datawidth,mem,shift,bits,endian,align,maxinst) \
274 { \
275 CPU_##cpu, \
276 name##_init, name##_reset, name##_exit, name##_execute, \
277 name##_burn, \
278 name##_get_context, name##_set_context, \
279 name##_get_cycle_table, name##_set_cycle_table, \
280 name##_get_reg, name##_set_reg, \
281 name##_set_irq_line, name##_set_irq_callback, \
282 name##_info, name##_dasm, \
283 nirq, dirq, &name##_ICount, oc, \
284 datawidth, \
285 (mem_read_handler)cpu_readmem##mem, (mem_write_handler)cpu_writemem##mem, NULL, NULL, \
286 0, cpu_setopbase##mem, \
287 shift, bits, CPU_IS_##endian, align, maxinst \
288 }
289
290 /* like CPU0, but CPU has Harvard-architecture like program/data memory */
291 #define CPU3(cpu,name,nirq,dirq,oc,datawidth,mem,shift,bits,endian,align,maxinst) \
292 { \
293 CPU_##cpu, \
294 name##_init, name##_reset, name##_exit, name##_execute, NULL, \
295 name##_get_context, name##_set_context, NULL, NULL, \
296 name##_get_reg, name##_set_reg, \
297 name##_set_irq_line, name##_set_irq_callback, \
298 name##_info, name##_dasm, \
299 nirq, dirq, &name##_icount, oc, \
300 datawidth, \
301 (mem_read_handler)cpu_readmem##mem, (mem_write_handler)cpu_writemem##mem, NULL, NULL, \
302 cpu##_PGM_OFFSET, cpu_setopbase##mem, \
303 shift, bits, CPU_IS_##endian, align, maxinst \
304 }
305
306 /* like CPU0, but CPU has internal memory (or I/O ports, timers or similiar) */
307 #define CPU4(cpu,name,nirq,dirq,oc,datawidth,mem,shift,bits,endian,align,maxinst) \
308 { \
309 CPU_##cpu, \
310 name##_init, name##_reset, name##_exit, name##_execute, NULL, \
311 name##_get_context, name##_set_context, NULL, NULL, \
312 name##_get_reg, name##_set_reg, \
313 name##_set_irq_line, name##_set_irq_callback, \
314 name##_info, name##_dasm, \
315 nirq, dirq, &name##_icount, oc, \
316 datawidth, \
317 (mem_read_handler)cpu_readmem##mem, (mem_write_handler)cpu_writemem##mem, (mem_read_handler)name##_internal_r, (mem_write_handler)name##_internal_w, \
318 0, cpu_setopbase##mem, \
319 shift, bits, CPU_IS_##endian, align, maxinst \
320 }
321
322
323
324 /*************************************
325 *
326 * The core list of CPU interfaces
327 *
328 *************************************/
329
330 const struct cpu_interface cpuintrf[] =
331 {
332 CPU0(DUMMY, dummy, 1, 0,1.00, 8, 16, 0,16,LE,1, 1 ),
333 #if (HAS_Z80)
334 CPU1(Z80, z80, 1,255,1.00, 8, 16, 0,16,LE,1, 4 ),
335 #endif
336 #if (HAS_DRZ80)
337 CPU1(DRZ80, drz80, 1,255,1.00, 8, 16, 0,16,LE,1, 4 ),
338 #endif
339 #if (HAS_Z180)
340 CPU1(Z180, z180, 1,255,1.00, 8, 20, 0,20,LE,1, 4 ),
341 #endif
342 #if (HAS_8080)
343 CPU0(8080, i8080, 4,255,1.00, 8, 16, 0,16,LE,1, 3 ),
344 #endif
345 #if (HAS_8085A)
346 CPU0(8085A, i8085, 4,255,1.00, 8, 16, 0,16,LE,1, 3 ),
347 #endif
348 #if (HAS_M6502)
349 CPU0(M6502, m6502, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
350 #endif
351 #if (HAS_M65C02)
352 CPU0(M65C02, m65c02, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
353 #endif
354 #if (HAS_M65SC02)
355 CPU0(M65SC02, m65sc02, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
356 #endif
357 #if (HAS_M65CE02)
358 CPU0(M65CE02, m65ce02, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
359 #endif
360 #if (HAS_M6509)
361 CPU0(M6509, m6509, 1, 0,1.00, 8, 20, 0,20,LE,1, 3 ),
362 #endif
363 #if (HAS_M6510)
364 CPU0(M6510, m6510, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
365 #endif
366 #if (HAS_M6510T)
367 CPU0(M6510T, m6510t, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
368 #endif
369 #if (HAS_M7501)
370 CPU0(M7501, m7501, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
371 #endif
372 #if (HAS_M8502)
373 CPU0(M8502, m8502, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
374 #endif
375 #if (HAS_N2A03)
376 CPU0(N2A03, n2a03, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
377 #endif
378 #if (HAS_DECO16)
379 CPU0(DECO16, deco16, 1, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
380 #endif
381 #if (HAS_M4510)
382 CPU0(M4510, m4510, 1, 0,1.00, 8, 20, 0,20,LE,1, 3 ),
383 #endif
384 #if (HAS_H6280)
385 CPU0(H6280, h6280, 3, 0,1.00, 8, 21, 0,21,LE,1, 3 ),
386 #endif
387 #if (HAS_I86)
388 CPU0(I86, i86, 1,255,1.00, 8, 20, 0,20,LE,1, 5 ),
389 #endif
390 #if (HAS_I88)
391 CPU0(I88, i88, 1,255,1.00, 8, 20, 0,20,LE,1, 5 ),
392 #endif
393 #if (HAS_I186)
394 CPU0(I186, i186, 1,255,1.00, 8, 20, 0,20,LE,1, 5 ),
395 #endif
396 #if (HAS_I188)
397 CPU0(I188, i188, 1,255,1.00, 8, 20, 0,20,LE,1, 5 ),
398 #endif
399 #if (HAS_I286)
400 CPU0(I286, i286, 1,255,1.00, 8, 24, 0,24,LE,1, 5 ),
401 #endif
402 #if (HAS_V20)
403 CPU0(V20, v20, 1,255,1.00, 8, 20, 0,20,LE,1, 5 ),
404 #endif
405 #if (HAS_V30)
406 CPU0(V30, v30, 1,255,1.00, 8, 20, 0,20,LE,1, 5 ),
407 #endif
408 #if (HAS_V33)
409 CPU0(V33, v33, 1,255,1.00, 8, 20, 0,20,LE,1, 5 ),
410 #endif
411 #if (HAS_V60)
412 CPU0(V60, v60, 1, 0,1.00,16, 24lew, 0,24,LE,1, 11 ),
413 #endif
414 #if (HAS_V70)
415 CPU0(V70, v70, 1, 0,1.00,32, 32ledw,0,32,LE,1, 11 ),
416 #endif
417 #if (HAS_I8035)
418 CPU0(I8035, i8035, 1, 0,1.00, 8, 16, 0,16,LE,1, 2 ),
419 #endif
420 #if (HAS_I8039)
421 CPU0(I8039, i8039, 1, 0,1.00, 8, 16, 0,16,LE,1, 2 ),
422 #endif
423 #if (HAS_I8048)
424 CPU0(I8048, i8048, 1, 0,1.00, 8, 16, 0,16,LE,1, 2 ),
425 #endif
426 #if (HAS_N7751)
427 CPU0(N7751, n7751, 1, 0,1.00, 8, 16, 0,16,LE,1, 2 ),
428 #endif
429 #if (HAS_I8X41)
430 CPU0(I8X41, i8x41, 1, 0,1.00, 8, 16, 0,16,LE,1, 2 ),
431 #endif
432 #if (HAS_M6800)
433 CPU0(M6800, m6800, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
434 #endif
435 #if (HAS_M6801)
436 CPU0(M6801, m6801, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
437 #endif
438 #if (HAS_M6802)
439 CPU0(M6802, m6802, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
440 #endif
441 #if (HAS_M6803)
442 CPU0(M6803, m6803, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
443 #endif
444 #if (HAS_M6808)
445 CPU0(M6808, m6808, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
446 #endif
447 #if (HAS_HD63701)
448 CPU0(HD63701, hd63701, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
449 #endif
450 #if (HAS_NSC8105)
451 CPU0(NSC8105, nsc8105, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
452 #endif
453 #if (HAS_M6805)
454 CPU0(M6805, m6805, 1, 0,1.00, 8, 16, 0,11,BE,1, 3 ),
455 #endif
456 #if (HAS_M68705)
457 CPU0(M68705, m68705, 1, 0,1.00, 8, 16, 0,11,BE,1, 3 ),
458 #endif
459 #if (HAS_HD63705)
460 CPU0(HD63705, hd63705, 8, 0,1.00, 8, 16, 0,16,BE,1, 3 ),
461 #endif
462 #if (HAS_HD6309)
463 CPU0(HD6309, hd6309, 2, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
464 #endif
465 #if (HAS_M6809)
466 CPU0(M6809, m6809, 2, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
467 #endif
468 #if (HAS_KONAMI)
469 CPU0(KONAMI, konami, 2, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
470 #endif
471 #if (HAS_M68000)
472 CPU0(M68000, m68000, 8, -1,1.00,16,24bew, 0,24,BE,2,10 ),
473 #endif
474 #if (HAS_CYCLONE)
475 CPU0(CYCLONE, cyclone, 8, -1,1.00,16,24bew, 0,24,BE,2,10 ),
476 #endif
477 #if (HAS_M68010)
478 CPU0(M68010, m68010, 8, -1,1.00,16,24bew, 0,24,BE,2,10 ),
479 #endif
480 #if (HAS_M68EC020)
481 CPU0(M68EC020, m68ec020, 8, -1,1.00,32,24bedw, 0,24,BE,4,10 ),
482 #endif
483 #if (HAS_M68020)
484 CPU0(M68020, m68020, 8, -1,1.00,32,32bedw, 0,32,BE,4,10 ),
485 #endif
486 #if (HAS_T11)
487 CPU0(T11, t11, 4, 0,1.00,16,16lew, 0,16,LE,2, 6 ),
488 #endif
489 #if (HAS_S2650)
490 CPU0(S2650, s2650, 2, 0,1.00, 8, 16, 0,15,LE,1, 3 ),
491 #endif
492 #if (HAS_TMS34010)
493 CPU0(TMS34010, tms34010, 2, 0,1.00,16,29lew, 3,29,LE,2,10 ),
494 #endif
495 #if (HAS_TMS34020)
496 CPU0(TMS34020, tms34020, 2, 0,1.00,16,29lew, 3,29,LE,2,10 ),
497 #endif
498 #if (HAS_TI990_10)
499 /*CPU4*/CPU0(TI990_10, ti990_10, 1, 0,1.00, 16,/*21*/24bew, 0,/*21*/24,BE,2, 6 ),
500 #endif
501 #if (HAS_TMS9900)
502 CPU0(TMS9900, tms9900, 1, 0,1.00,16,16bew, 0,16,BE,2, 6 ),
503 #endif
504 #if (HAS_TMS9940)
505 CPU0(TMS9940, tms9940, 1, 0,1.00,16,16bew, 0,16,BE,2, 6 ),
506 #endif
507 #if (HAS_TMS9980)
508 CPU0(TMS9980, tms9980a, 1, 0,1.00, 8, 16, 0,16,BE,1, 6 ),
509 #endif
510 #if (HAS_TMS9985)
511 CPU0(TMS9985, tms9985, 1, 0,1.00, 8, 16, 0,16,BE,1, 6 ),
512 #endif
513 #if (HAS_TMS9989)
514 CPU0(TMS9989, tms9989, 1, 0,1.00, 8, 16, 0,16,BE,1, 6 ),
515 #endif
516 #if (HAS_TMS9995)
517 CPU0(TMS9995, tms9995, 1, 0,1.00, 8, 16, 0,16,BE,1, 6 ),
518 #endif
519 #if (HAS_TMS99105A)
520 CPU0(TMS99105A,tms99105a,1, 0,1.00,16,16bew, 0,16,BE,2, 6 ),
521 #endif
522 #if (HAS_TMS99110A)
523 CPU0(TMS99110A,tms99110a,1, 0,1.00,16,16bew, 0,16,BE,2, 6 ),
524 #endif
525 #if (HAS_Z8000)
526 CPU0(Z8000, z8000, 2, 0,1.00,16,16bew, 0,16,BE,2, 6 ),
527 #endif
528 #if (HAS_TMS32010)
529 CPU3(TMS32010,tms32010, 1, 0,1.00,16,16bew, -1,16,BE,2, 4 ),
530 #endif
531 #if (HAS_TMS32025)
532 CPU3(TMS32025,tms32025, 3, 0,1.00,16,18bew, -1,18,BE,2, 4 ),
533 #endif
534 #if (HAS_TMS32031)
535 #define tms32031_ICount tms32031_icount
536 CPU0(TMS32031,tms32031, 4, 0,1.00,32,26ledw,-2,26,LE,4, 4 ),
537 #endif
538 #if (HAS_CCPU)
539 CPU3(CCPU, ccpu, 2, 0,1.00,16,16bew, 0,15,BE,2, 3 ),
540 #endif
541 #if (HAS_ADSP2100)
542 CPU3(ADSP2100, adsp2100, 4, 0,1.00,16,17lew, -1,15,LE,2, 4 ),
543 #endif
544 #if (HAS_ADSP2101)
545 CPU3(ADSP2101, adsp2101, 4, 0,1.00,16,17lew, -1,15,LE,2, 4 ),
546 #endif
547 #if (HAS_ADSP2104)
548 CPU3(ADSP2104, adsp2104, 4, 0,1.00,16,17lew, -1,15,LE,2, 4 ),
549 #endif
550 #if (HAS_ADSP2105)
551 CPU3(ADSP2105, adsp2105, 4, 0,1.00,16,17lew, -1,15,LE,2, 4 ),
552 #endif
553 #if (HAS_ADSP2115)
554 CPU3(ADSP2115, adsp2115, 4, 0,1.00,16,17lew, -1,15,LE,2, 4 ),
555 #endif
556 #if (HAS_PSXCPU)
557 CPU0(PSXCPU, mips, 1, 0,1.00,32,32ledw, 0,32,LE,4, 4 ),
558 #endif
559 #if (HAS_ASAP)
560 #define asap_ICount asap_icount
561 CPU0(ASAP, asap, 1, 0,1.00,32,32ledw, 0,32,LE,4, 12 ),
562 #endif
563 #if (HAS_UPD7810)
564 #define upd7810_ICount upd7810_icount
565 CPU0(UPD7810, upd7810, 2, 0,1.00, 8, 16, 0,16,LE,1, 4 ),
566 #endif
567 #if (HAS_UPD7807)
568 #define upd7807_ICount upd7810_icount
569 CPU0(UPD7807, upd7807, 2, 0,1.00, 8, 16, 0,16,LE,1, 4 ),
570 #endif
571 #if (HAS_JAGUAR)
572 #define jaguargpu_ICount jaguar_icount
573 #define jaguardsp_ICount jaguar_icount
574 CPU0(JAGUARGPU,jaguargpu,6, 0,1.00,32,24bedw, 0,24,BE,4, 12 ),
575 CPU0(JAGUARDSP,jaguardsp,6, 0,1.00,32,24bedw, 0,24,BE,4, 12 ),
576 #endif
577 #if (HAS_R3000)
578 #define r3000be_ICount r3000_icount
579 #define r3000le_ICount r3000_icount
580 CPU0(R3000BE, r3000be, 1, 0,1.00,32,29bedw, 0,29,BE,4, 4 ),
581 CPU0(R3000LE, r3000le, 1, 0,1.00,32,29ledw, 0,29,LE,4, 4 ),
582 #endif
583 #if (HAS_R4600)
584 #define r4600be_ICount mips3_icount
585 #define r4600le_ICount mips3_icount
586 CPU0(R4600BE, r4600be, 1, 0,1.00,32,32bedw, 0,32,BE,4, 4 ),
587 CPU0(R4600LE, r4600le, 1, 0,1.00,32,32ledw, 0,32,LE,4, 4 ),
588 #endif
589 #if (HAS_R5000)
590 #define r5000be_ICount mips3_icount
591 #define r5000le_ICount mips3_icount
592 CPU0(R5000BE, r5000be, 1, 0,1.00,32,32bedw, 0,32,BE,4, 4 ),
593 CPU0(R5000LE, r5000le, 1, 0,1.00,32,32ledw, 0,32,LE,4, 4 ),
594 #endif
595 #if (HAS_ARM)
596 CPU0(ARM, arm, 2, 0,1.00,32,26ledw, 0,26,LE,4, 4 ),
597 #endif
598 #if (HAS_SH2)
599 CPU4(SH2, sh2, 16, 0,1.00,32,32bedw, 0,32,BE,2, 2 ),
600 #endif
601 #if (HAS_DSP32C)
602 #define dsp32c_ICount dsp32_icount
603 CPU0(DSP32C, dsp32c, 4, 0,1.00,32,24ledw, 0,24,LE,4, 4 ),
604 #endif
605 #if (HAS_PIC16C54)
606 CPU3(PIC16C54,pic16C54, 0, 0,1.00,8,16lew, 0,13,LE,1, 2 ),
607 #endif
608 #if (HAS_PIC16C55)
609 CPU3(PIC16C55,pic16C55, 0, 0,1.00,8,16lew, 0,13,LE,1, 2 ),
610 #endif
611 #if (HAS_PIC16C56)
612 CPU3(PIC16C56,pic16C56, 0, 0,1.00,8,16lew, 0,13,LE,1, 2 ),
613 #endif
614 #if (HAS_PIC16C57)
615 CPU3(PIC16C57,pic16C57, 0, 0,1.00,8,16lew, 0,13,LE,1, 2 ),
616 #endif
617 #if (HAS_PIC16C58)
618 CPU3(PIC16C58,pic16C58, 0, 0,1.00,8,16lew, 0,13,LE,1, 2 ),
619 #endif
620 #if (HAS_G65816)
621 CPU0(G65816, g65816, 1, 0,1.00, 8, 24, 0,24,BE,1, 3 ),
622 #endif
623 #if (HAS_SPC700)
624 CPU0(SPC700, spc700, 0, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
625 #endif
626 #if (HAS_E132XS)
627 CPU0(E132XS, e132xs, 1,0,1.00, 32, 32bedw, 0,32,BE,2, 6 ),
628 #endif
629
630 };
631
632
633
634 /*************************************
635 *
636 * Default debugger window layout
637 *
638 *************************************/
639
640 UINT8 default_win_layout[] =
641 {
642 0, 0,80, 5, /* register window (top rows) */
643 0, 5,24,17, /* disassembler window (left, middle columns) */
644 25, 5,55, 8, /* memory #1 window (right, upper middle) */
645 25,14,55, 8, /* memory #2 window (right, lower middle) */
646 0,23,80, 1 /* command line window (bottom row) */
647 };
648
649
650
651 /*************************************
652 *
653 * Other variables we own
654 *
655 *************************************/
656
657 int activecpu; /* index of active CPU (or -1) */
658 int executingcpu; /* index of executing CPU (or -1) */
659 int totalcpu; /* total number of CPUs */
660
661 static struct cpuinfo cpu[MAX_CPU];
662
663 static int cpu_active_context[CPU_COUNT];
664 static int cpu_context_stack[4];
665 static int cpu_context_stack_ptr;
666
667 static unsigned (*cpu_dasm_override)(int cpunum, char *buffer, unsigned pc);
668
669
670
671 /*************************************
672 *
673 * Set a new CPU context
674 *
675 *************************************/
676
set_cpu_context(int cpunum)677 static INLINE void set_cpu_context(int cpunum)
678 {
679 int newfamily = cpu[cpunum].family;
680 int oldcontext = cpu_active_context[newfamily];
681
682 /* if we need to change contexts, save the one that was there */
683 if (oldcontext != cpunum && oldcontext != -1)
684 (*cpu[oldcontext].intf.get_context)(cpu[oldcontext].context);
685
686 /* swap memory spaces */
687 activecpu = cpunum;
688 memory_set_context(cpunum);
689
690 /* if the new CPU's context is not swapped in, do it now */
691 if (oldcontext != cpunum)
692 {
693 (*cpu[cpunum].intf.set_context)(cpu[cpunum].context);
694 cpu_active_context[newfamily] = cpunum;
695 }
696 }
697
698
699
700 /*************************************
701 *
702 * Push/pop to a new CPU context
703 *
704 *************************************/
705
cpuintrf_push_context(int cpunum)706 void cpuintrf_push_context(int cpunum)
707 {
708 /* push the old context onto the stack */
709 cpu_context_stack[cpu_context_stack_ptr++] = activecpu;
710
711 /* do the rest only if this isn't the activecpu */
712 if (cpunum != activecpu && cpunum != -1)
713 set_cpu_context(cpunum);
714
715 /* this is now the active CPU */
716 activecpu = cpunum;
717 }
718
719
cpuintrf_pop_context(void)720 void cpuintrf_pop_context(void)
721 {
722 /* push the old context onto the stack */
723 int cpunum = cpu_context_stack[--cpu_context_stack_ptr];
724
725 /* do the rest only if this isn't the activecpu */
726 if (cpunum != activecpu && cpunum != -1)
727 set_cpu_context(cpunum);
728
729 /* this is now the active CPU */
730 activecpu = cpunum;
731 }
732
733
734
735 /*************************************
736 *
737 * Initialize a single CPU
738 *
739 *************************************/
740
cpuintrf_init(void)741 int cpuintrf_init(void)
742 {
743 int cputype;
744
745 /* verify the order of entries in the cpuintrf[] array */
746 for (cputype = 0; cputype < CPU_COUNT; cputype++)
747 {
748 /* make sure the index in the array matches the current index */
749 if (cpuintrf[cputype].cpu_num != cputype)
750 {
751 log_cb(RETRO_LOG_ERROR, LOGPRE "CPU #%d [%s] wrong ID %d: check enum CPU_... in src/cpuintrf.h!\n", cputype, cputype_name(cputype), cpuintrf[cputype].cpu_num);
752 exit(1);
753 }
754
755 /* also reset the active CPU context info */
756 cpu_active_context[cputype] = -1;
757 }
758
759 /* zap the CPU data structure */
760 memset(cpu, 0, sizeof(cpu));
761 totalcpu = 0;
762 cpu_dasm_override = NULL;
763
764 /* reset the context stack */
765 memset(cpu_context_stack, -1, sizeof(cpu_context_stack));
766 cpu_context_stack_ptr = 0;
767
768 /* nothing active, nothing executing */
769 activecpu = -1;
770 executingcpu = -1;
771
772 return 0;
773 }
774
775
776
777 /*************************************
778 *
779 * Set the disassembly override proc
780 *
781 *************************************/
782
cpuintrf_set_dasm_override(unsigned (* dasm_override)(int cpunum,char * buffer,unsigned pc))783 void cpuintrf_set_dasm_override(unsigned (*dasm_override)(int cpunum, char *buffer, unsigned pc))
784 {
785 cpu_dasm_override = dasm_override;
786 }
787
788
789
790 /*************************************
791 *
792 * Initialize a single CPU
793 *
794 *************************************/
795
cpuintrf_init_cpu(int cpunum,int cputype)796 int cpuintrf_init_cpu(int cpunum, int cputype)
797 {
798 char familyname[256];
799 int j, size;
800
801 /* fill in the type and interface */
802 cpu[cpunum].intf = cpuintrf[cputype];
803 cpu[cpunum].cputype = cputype;
804
805 /* determine the family index */
806 strcpy(familyname, cputype_core_file(cputype));
807 for (j = 0; j < CPU_COUNT; j++)
808 if (!strcmp(familyname, cputype_core_file(j)))
809 {
810 cpu[cpunum].family = j;
811 break;
812 }
813
814 /* determine the context size */
815 size = (*cpu[cpunum].intf.get_context)(NULL);
816 if (size == 0)
817 {
818 /* that can't really be true */
819 /*logerror("CPU #%d claims to need no context buffer!\n", cpunum);*/
820 return 1;
821 }
822
823 /* allocate a context buffer for the CPU */
824 cpu[cpunum].context = malloc(size);
825 if (cpu[cpunum].context == NULL)
826 {
827 /* that's really bad :( */
828 /*logerror("CPU #%d failed to allocate context buffer (%d bytes)!\n", cpunum, size);*/
829 return 1;
830 }
831
832 /* zap the context buffer */
833 memset(cpu[cpunum].context, 0, size);
834
835 /* initialize the CPU and stash the context */
836 activecpu = cpunum;
837 (*cpu[cpunum].intf.init)();
838 (*cpu[cpunum].intf.get_context)(cpu[cpunum].context);
839 activecpu = -1;
840
841 /* clear out the registered CPU for this family */
842 cpu_active_context[cpu[cpunum].family] = -1;
843
844 /* make sure the total includes us */
845 totalcpu = cpunum + 1;
846
847 return 0;
848 }
849
850
851
852 /*************************************
853 *
854 * Exit/free a single CPU
855 *
856 *************************************/
857
cpuintrf_exit_cpu(int cpunum)858 void cpuintrf_exit_cpu(int cpunum)
859 {
860 /* if the CPU core defines an exit function, call it now */
861 if (cpu[cpunum].intf.exit)
862 (*cpu[cpunum].intf.exit)();
863
864 /* free the context buffer for that CPU */
865 if (cpu[cpunum].context)
866 free(cpu[cpunum].context);
867 cpu[cpunum].context = NULL;
868 }
869
870
871
872 /*************************************
873 *
874 * Interfaces to the active CPU
875 *
876 *************************************/
877
878 /*--------------------------
879 Adjust/get icount
880 --------------------------*/
881
activecpu_adjust_icount(int delta)882 void activecpu_adjust_icount(int delta)
883 {
884 VERIFY_ACTIVECPU_VOID(activecpu_adjust_icount);
885 *cpu[activecpu].intf.icount += delta;
886 }
887
888
activecpu_get_icount(void)889 int activecpu_get_icount(void)
890 {
891 VERIFY_ACTIVECPU(0, activecpu_get_icount);
892 return *cpu[activecpu].intf.icount;
893 }
894
895
896 /*--------------------------
897 Reset banking pointers
898 --------------------------*/
899
activecpu_reset_banking(void)900 void activecpu_reset_banking(void)
901 {
902 VERIFY_ACTIVECPU_VOID(activecpu_reset_banking);
903 (*cpu[activecpu].intf.set_op_base)(activecpu_get_pc_byte());
904 }
905
906
907 /*--------------------------
908 IRQ line setting
909 --------------------------*/
910
activecpu_set_irq_line(int irqline,int state)911 void activecpu_set_irq_line(int irqline, int state)
912 {
913 VERIFY_ACTIVECPU_VOID(activecpu_set_irq_line);
914 if (state != INTERNAL_CLEAR_LINE && state != INTERNAL_ASSERT_LINE)
915 {
916 /*logerror("activecpu_set_irq_line called when cpu_set_irq_line should have been used!\n");*/
917 return;
918 }
919 (*cpu[activecpu].intf.set_irq_line)(irqline, state - INTERNAL_CLEAR_LINE);
920 }
921
922
923 /*--------------------------
924 Get/set cycle table
925 --------------------------*/
926
activecpu_get_cycle_table(int which)927 const void *activecpu_get_cycle_table(int which)
928 {
929 VERIFY_ACTIVECPU(NULL, activecpu_get_cycle_table);
930 return (*cpu[activecpu].intf.get_cycle_table)(which);
931 }
932
933
activecpu_set_cycle_tbl(int which,void * new_table)934 void activecpu_set_cycle_tbl(int which, void *new_table)
935 {
936 VERIFY_ACTIVECPU_VOID(activecpu_set_cycle_tbl);
937 (*cpu[activecpu].intf.set_cycle_table)(which, new_table);
938 }
939
940
941 /*--------------------------
942 Get/set registers
943 --------------------------*/
944
activecpu_get_reg(int regnum)945 unsigned activecpu_get_reg(int regnum)
946 {
947 VERIFY_ACTIVECPU(0, activecpu_get_reg);
948 return (*cpu[activecpu].intf.get_reg)(regnum);
949 }
950
951
activecpu_set_reg(int regnum,unsigned val)952 void activecpu_set_reg(int regnum, unsigned val)
953 {
954 VERIFY_ACTIVECPU_VOID(activecpu_set_reg);
955 (*cpu[activecpu].intf.set_reg)(regnum, val);
956 }
957
958
959 /*--------------------------
960 Get/set PC
961 --------------------------*/
962
activecpu_get_pc_byte(void)963 offs_t activecpu_get_pc_byte(void)
964 {
965 offs_t base, pc;
966 int shift;
967
968 VERIFY_ACTIVECPU(0, activecpu_get_pc_byte);
969 shift = cpu[activecpu].intf.address_shift;
970 base = cpu[activecpu].intf.pgm_memory_base;
971 pc = (*cpu[activecpu].intf.get_reg)(REG_PC);
972 return base + ((shift < 0) ? (pc << -shift) : (pc >> shift));
973 }
974
975
activecpu_set_op_base(unsigned val)976 void activecpu_set_op_base(unsigned val)
977 {
978 VERIFY_ACTIVECPU_VOID(activecpu_set_op_base);
979 (*cpu[activecpu].intf.set_op_base)(val);
980 }
981
982
983 /*--------------------------
984 Disassembly
985 --------------------------*/
986
internal_dasm(int cpunum,char * buffer,unsigned pc)987 static unsigned internal_dasm(int cpunum, char *buffer, unsigned pc)
988 {
989 unsigned result;
990 if (cpu_dasm_override)
991 {
992 result = cpu_dasm_override(cpunum, buffer, pc);
993 if (result)
994 return result;
995 }
996 return (*cpu[cpunum].intf.cpu_dasm)(buffer, pc);
997 }
998
999
1000
activecpu_dasm(char * buffer,unsigned pc)1001 unsigned activecpu_dasm(char *buffer, unsigned pc)
1002 {
1003 VERIFY_ACTIVECPU(1, activecpu_dasm);
1004 return internal_dasm(activecpu, buffer, pc);
1005 }
1006
1007
1008 /*--------------------------
1009 Register dumps
1010 --------------------------*/
1011
activecpu_flags(void)1012 const char *activecpu_flags(void)
1013 {
1014 VERIFY_ACTIVECPU("", activecpu_flags);
1015 return (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_FLAGS);
1016 }
1017
1018
activecpu_dump_reg(int regnum)1019 const char *activecpu_dump_reg(int regnum)
1020 {
1021 VERIFY_ACTIVECPU("", activecpu_dump_reg);
1022 return (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_REG + regnum);
1023 }
1024
1025
1026 /*--------------------------
1027 State dumps
1028 --------------------------*/
1029
activecpu_dump_state(void)1030 const char *activecpu_dump_state(void)
1031 {
1032 static char buffer[1024+1];
1033 unsigned addr_width = (activecpu_address_bits() + 3) / 4;
1034 char *dst = buffer;
1035 const char *src;
1036 const INT8 *regs;
1037 int width;
1038
1039 VERIFY_ACTIVECPU("", activecpu_dump_state);
1040
1041 dst += sprintf(dst, "CPU #%d [%s]\n", activecpu, activecpu_name());
1042 width = 0;
1043 regs = (INT8 *)activecpu_reg_layout();
1044 while (*regs)
1045 {
1046 if (*regs == -1)
1047 {
1048 dst += sprintf(dst, "\n");
1049 width = 0;
1050 }
1051 else
1052 {
1053 src = activecpu_dump_reg(*regs);
1054 if (*src)
1055 {
1056 if (width + strlen(src) + 1 >= 80)
1057 {
1058 dst += sprintf(dst, "\n");
1059 width = 0;
1060 }
1061 dst += sprintf(dst, "%s ", src);
1062 width += strlen(src) + 1;
1063 }
1064 }
1065 regs++;
1066 }
1067 dst += sprintf(dst, "\n%0*X: ", addr_width, activecpu_get_pc());
1068 activecpu_dasm(dst, activecpu_get_pc());
1069 strcat(dst, "\n\n");
1070
1071 return buffer;
1072 }
1073
1074
1075 /*--------------------------
1076 Get/set static info
1077 --------------------------*/
1078
1079 #define CPU_FUNC(rettype, name, defresult, result) \
1080 rettype name(void) \
1081 { \
1082 VERIFY_ACTIVECPU(defresult, name) \
1083 return result; \
1084 }
1085
1086 CPU_FUNC(int, activecpu_default_irq_vector, 0, cpu[activecpu].intf.default_vector)
1087 CPU_FUNC(unsigned, activecpu_address_bits, 0, cpu[activecpu].intf.address_bits)
1088 CPU_FUNC(unsigned, activecpu_address_mask, 0, 0xffffffffUL >> (32 - cpu[activecpu].intf.address_bits))
1089 CPU_FUNC(int, activecpu_address_shift, 0, cpu[activecpu].intf.address_shift)
1090 CPU_FUNC(unsigned, activecpu_endianess, 0, cpu[activecpu].intf.endianess)
1091 CPU_FUNC(unsigned, activecpu_databus_width, 0, cpu[activecpu].intf.databus_width)
1092 CPU_FUNC(unsigned, activecpu_align_unit, 0, cpu[activecpu].intf.align_unit)
1093 CPU_FUNC(unsigned, activecpu_max_inst_len, 0, cpu[activecpu].intf.max_inst_len)
1094 CPU_FUNC(const char *, activecpu_name, "", (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_NAME))
1095 CPU_FUNC(const char *, activecpu_core_family, "", (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_FAMILY))
1096 CPU_FUNC(const char *, activecpu_core_version, "", (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_VERSION))
1097 CPU_FUNC(const char *, activecpu_core_file, "", (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_FILE))
1098 CPU_FUNC(const char *, activecpu_core_credits, "", (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_CREDITS))
1099 CPU_FUNC(const char *, activecpu_reg_layout, "", (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_REG_LAYOUT))
1100 CPU_FUNC(const char *, activecpu_win_layout, "", (*cpu[activecpu].intf.cpu_info)(NULL, CPU_INFO_WIN_LAYOUT))
1101
1102
1103
1104 /*************************************
1105 *
1106 * Interfaces to a specific CPU
1107 *
1108 *************************************/
1109
1110 /*--------------------------
1111 Execute
1112 --------------------------*/
1113
cpunum_execute(int cpunum,int cycles)1114 int cpunum_execute(int cpunum, int cycles)
1115 {
1116 int ran;
1117 VERIFY_CPUNUM(0, cpunum_execute);
1118 cpuintrf_push_context(cpunum);
1119 executingcpu = cpunum;
1120 (*cpu[cpunum].intf.set_op_base)(activecpu_get_pc_byte());
1121 ran = (*cpu[cpunum].intf.execute)(cycles);
1122 executingcpu = -1;
1123 cpuintrf_pop_context();
1124 return ran;
1125 }
1126
1127
1128 /*--------------------------
1129 Reset and set IRQ ack
1130 --------------------------*/
1131
cpunum_reset(int cpunum,void * param,int (* irqack)(int))1132 void cpunum_reset(int cpunum, void *param, int (*irqack)(int))
1133 {
1134 VERIFY_CPUNUM_VOID(cpunum_reset);
1135 cpuintrf_push_context(cpunum);
1136 (*cpu[cpunum].intf.set_op_base)(0);
1137 (*cpu[cpunum].intf.reset)(param);
1138 if (irqack)
1139 (*cpu[cpunum].intf.set_irq_callback)(irqack);
1140 cpuintrf_pop_context();
1141 }
1142
1143
1144 /*--------------------------
1145 Read a byte
1146 --------------------------*/
1147
cpunum_read_byte(int cpunum,offs_t address)1148 data8_t cpunum_read_byte(int cpunum, offs_t address)
1149 {
1150 int result;
1151 VERIFY_CPUNUM(0, cpunum_read_byte);
1152 cpuintrf_push_context(cpunum);
1153 result = (*cpu[cpunum].intf.memory_read)(address);
1154 cpuintrf_pop_context();
1155 return result;
1156 }
1157
1158
1159 /*--------------------------
1160 Write a byte
1161 --------------------------*/
1162
cpunum_write_byte(int cpunum,offs_t address,data8_t data)1163 void cpunum_write_byte(int cpunum, offs_t address, data8_t data)
1164 {
1165 VERIFY_CPUNUM_VOID(cpunum_write_byte);
1166 cpuintrf_push_context(cpunum);
1167 (*cpu[cpunum].intf.memory_write)(address, data);
1168 cpuintrf_pop_context();
1169 }
1170
1171
1172 /*--------------------------
1173 Get context pointer
1174 --------------------------*/
1175
cpunum_get_context_ptr(int cpunum)1176 void *cpunum_get_context_ptr(int cpunum)
1177 {
1178 VERIFY_CPUNUM(NULL, cpunum_get_context_ptr);
1179 return (cpu_active_context[cpu[cpunum].family] == cpunum) ? NULL : cpu[cpunum].context;
1180 }
1181
1182
1183 /*--------------------------
1184 Get/set cycle table
1185 --------------------------*/
1186
cpunum_get_cycle_table(int cpunum,int which)1187 const void *cpunum_get_cycle_table(int cpunum, int which)
1188 {
1189 const void *result;
1190 VERIFY_CPUNUM(NULL, cpunum_get_cycle_table);
1191 cpuintrf_push_context(cpunum);
1192 result = (*cpu[cpunum].intf.get_cycle_table)(which);
1193 cpuintrf_pop_context();
1194 return result;
1195 }
1196
1197
cpunum_set_cycle_tbl(int cpunum,int which,void * new_table)1198 void cpunum_set_cycle_tbl(int cpunum, int which, void *new_table)
1199 {
1200 VERIFY_CPUNUM_VOID(cpunum_set_cycle_tbl);
1201 cpuintrf_push_context(cpunum);
1202 (*cpu[cpunum].intf.set_cycle_table)(which, new_table);
1203 cpuintrf_pop_context();
1204 }
1205
1206
1207 /*--------------------------
1208 Get/set registers
1209 --------------------------*/
1210
cpunum_get_reg(int cpunum,int regnum)1211 unsigned cpunum_get_reg(int cpunum, int regnum)
1212 {
1213 unsigned result;
1214 VERIFY_CPUNUM(0, cpunum_get_reg);
1215 cpuintrf_push_context(cpunum);
1216 result = (*cpu[cpunum].intf.get_reg)(regnum);
1217 cpuintrf_pop_context();
1218 return result;
1219 }
1220
1221
cpunum_set_reg(int cpunum,int regnum,unsigned val)1222 void cpunum_set_reg(int cpunum, int regnum, unsigned val)
1223 {
1224 VERIFY_CPUNUM_VOID(cpunum_set_reg);
1225 cpuintrf_push_context(cpunum);
1226 (*cpu[cpunum].intf.set_reg)(regnum, val);
1227 cpuintrf_pop_context();
1228 }
1229
1230
1231 /*--------------------------
1232 Get/set PC
1233 --------------------------*/
1234
cpunum_get_pc_byte(int cpunum)1235 offs_t cpunum_get_pc_byte(int cpunum)
1236 {
1237 offs_t base, pc;
1238 int shift;
1239
1240 VERIFY_CPUNUM(0, cpunum_get_pc_byte);
1241 shift = cpu[cpunum].intf.address_shift;
1242 base = cpu[cpunum].intf.pgm_memory_base;
1243 cpuintrf_push_context(cpunum);
1244 pc = (*cpu[cpunum].intf.get_reg)(REG_PC);
1245 cpuintrf_pop_context();
1246 return base + ((shift < 0) ? (pc << -shift) : (pc >> shift));
1247 }
1248
1249
cpunum_set_op_base(int cpunum,unsigned val)1250 void cpunum_set_op_base(int cpunum, unsigned val)
1251 {
1252 VERIFY_CPUNUM_VOID(cpunum_set_op_base);
1253 cpuintrf_push_context(cpunum);
1254 (*cpu[cpunum].intf.set_op_base)(val);
1255 cpuintrf_pop_context();
1256 }
1257
1258
1259 /*--------------------------
1260 Disassembly
1261 --------------------------*/
1262
cpunum_dasm(int cpunum,char * buffer,unsigned pc)1263 unsigned cpunum_dasm(int cpunum, char *buffer, unsigned pc)
1264 {
1265 unsigned result;
1266 VERIFY_CPUNUM(1, cpunum_dasm);
1267 cpuintrf_push_context(cpunum);
1268 result = internal_dasm(cpunum, buffer, pc);
1269 cpuintrf_pop_context();
1270 return result;
1271 }
1272
1273
1274 /*--------------------------
1275 Register dumps
1276 --------------------------*/
1277
cpunum_flags(int cpunum)1278 const char *cpunum_flags(int cpunum)
1279 {
1280 const char *result;
1281 VERIFY_CPUNUM("", cpunum_flags);
1282 cpuintrf_push_context(cpunum);
1283 result = (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_FLAGS);
1284 cpuintrf_pop_context();
1285 return result;
1286 }
1287
1288
cpunum_dump_reg(int cpunum,int regnum)1289 const char *cpunum_dump_reg(int cpunum, int regnum)
1290 {
1291 const char *result;
1292 VERIFY_CPUNUM("", cpunum_dump_reg);
1293 cpuintrf_push_context(cpunum);
1294 result = (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_REG + regnum);
1295 cpuintrf_pop_context();
1296 return result;
1297 }
1298
1299
1300 /*--------------------------
1301 State dumps
1302 --------------------------*/
1303
cpunum_dump_state(int cpunum)1304 const char *cpunum_dump_state(int cpunum)
1305 {
1306 static char buffer[1024+1];
1307 VERIFY_CPUNUM("", cpunum_dump_state);
1308 cpuintrf_push_context(cpunum);
1309 strcpy(buffer, activecpu_dump_state());
1310 cpuintrf_pop_context();
1311 return buffer;
1312 }
1313
1314
1315 /*--------------------------
1316 Get/set static info
1317 --------------------------*/
1318
1319 #define CPUNUM_FUNC(rettype, name, defresult, result) \
1320 rettype name(int cpunum) \
1321 { \
1322 VERIFY_CPUNUM(defresult, name) \
1323 return result; \
1324 }
1325
1326 CPUNUM_FUNC(int, cpunum_default_irq_vector, 0, cpu[cpunum].intf.default_vector)
1327 CPUNUM_FUNC(unsigned, cpunum_address_bits, 0, cpu[cpunum].intf.address_bits)
1328 CPUNUM_FUNC(unsigned, cpunum_address_mask, 0, 0xffffffffUL >> (32 - cpu[cpunum].intf.address_bits))
1329 CPUNUM_FUNC(int, cpunum_address_shift, 0, cpu[cpunum].intf.address_shift)
1330 CPUNUM_FUNC(unsigned, cpunum_endianess, 0, cpu[cpunum].intf.endianess)
1331 CPUNUM_FUNC(unsigned, cpunum_databus_width, 0, cpu[cpunum].intf.databus_width)
1332 CPUNUM_FUNC(unsigned, cpunum_align_unit, 0, cpu[cpunum].intf.align_unit)
1333 CPUNUM_FUNC(unsigned, cpunum_max_inst_len, 0, cpu[cpunum].intf.max_inst_len)
1334 CPUNUM_FUNC(const char *, cpunum_name, "", (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_NAME))
1335 CPUNUM_FUNC(const char *, cpunum_core_family, "", (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_FAMILY))
1336 CPUNUM_FUNC(const char *, cpunum_core_version, "", (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_VERSION))
1337 CPUNUM_FUNC(const char *, cpunum_core_file, "", (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_FILE))
1338 CPUNUM_FUNC(const char *, cpunum_core_credits, "", (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_CREDITS))
1339 CPUNUM_FUNC(const char *, cpunum_reg_layout, "", (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_REG_LAYOUT))
1340 CPUNUM_FUNC(const char *, cpunum_win_layout, "", (*cpu[cpunum].intf.cpu_info)(NULL, CPU_INFO_WIN_LAYOUT))
1341
1342
1343
1344 /*************************************
1345 *
1346 * Static info about a type of CPU
1347 *
1348 *************************************/
1349
1350 #define CPUTYPE_FUNC(rettype, name, defresult, result) \
1351 rettype name(int cputype) \
1352 { \
1353 if (cputype >= 0 && cputype < CPU_COUNT) \
1354 return result; \
1355 return defresult; \
1356 }
1357
1358 CPUTYPE_FUNC(int, cputype_default_irq_vector, 0, cpuintrf[cputype].default_vector)
1359 CPUTYPE_FUNC(unsigned, cputype_address_bits, 0, cpuintrf[cputype].address_bits)
1360 CPUTYPE_FUNC(unsigned, cputype_address_mask, 0, 0xffffffffUL >> (32 - cpuintrf[cputype].address_bits))
1361 CPUTYPE_FUNC(int, cputype_address_shift, 0, cpuintrf[cputype].address_shift)
1362 CPUTYPE_FUNC(unsigned, cputype_endianess, 0, cpuintrf[cputype].endianess)
1363 CPUTYPE_FUNC(unsigned, cputype_databus_width, 0, cpuintrf[cputype].databus_width)
1364 CPUTYPE_FUNC(unsigned, cputype_align_unit, 0, cpuintrf[cputype].align_unit)
1365 CPUTYPE_FUNC(unsigned, cputype_max_inst_len, 0, cpuintrf[cputype].max_inst_len)
1366 CPUTYPE_FUNC(const char *, cputype_name, "", (*cpuintrf[cputype].cpu_info)(NULL, CPU_INFO_NAME))
1367 CPUTYPE_FUNC(const char *, cputype_core_family, "", (*cpuintrf[cputype].cpu_info)(NULL, CPU_INFO_FAMILY))
1368 CPUTYPE_FUNC(const char *, cputype_core_version, "", (*cpuintrf[cputype].cpu_info)(NULL, CPU_INFO_VERSION))
1369 CPUTYPE_FUNC(const char *, cputype_core_file, "", (*cpuintrf[cputype].cpu_info)(NULL, CPU_INFO_FILE))
1370 CPUTYPE_FUNC(const char *, cputype_core_credits, "", (*cpuintrf[cputype].cpu_info)(NULL, CPU_INFO_CREDITS))
1371 CPUTYPE_FUNC(const char *, cputype_reg_layout, "", (*cpuintrf[cputype].cpu_info)(NULL, CPU_INFO_REG_LAYOUT))
1372 CPUTYPE_FUNC(const char *, cputype_win_layout, "", (*cpuintrf[cputype].cpu_info)(NULL, CPU_INFO_WIN_LAYOUT))
1373
1374
1375
1376 /*************************************
1377 *
1378 * Dump states of all CPUs
1379 *
1380 *************************************/
1381
cpu_dump_states(void)1382 void cpu_dump_states(void)
1383 {
1384 int cpunum;
1385
1386 for (cpunum = 0; cpunum < totalcpu; cpunum++)
1387 puts(cpunum_dump_state(cpunum));
1388 fflush(stdout);
1389 }
1390
1391
1392
1393 /*************************************
1394 *
1395 * Dummy CPU definition
1396 *
1397 *************************************/
1398
dummy_init(void)1399 static void dummy_init(void) { }
dummy_reset(void * param)1400 static void dummy_reset(void *param) { }
dummy_exit(void)1401 static void dummy_exit(void) { }
dummy_execute(int cycles)1402 static int dummy_execute(int cycles) { return cycles; }
dummy_get_context(void * regs)1403 static unsigned dummy_get_context(void *regs) { return 0; }
dummy_set_context(void * regs)1404 static void dummy_set_context(void *regs) { }
dummy_get_reg(int regnum)1405 static unsigned dummy_get_reg(int regnum) { return 0; }
dummy_set_reg(int regnum,unsigned val)1406 static void dummy_set_reg(int regnum, unsigned val) { }
dummy_set_irq_line(int irqline,int state)1407 static void dummy_set_irq_line(int irqline, int state) { }
dummy_set_irq_callback(int (* callback)(int irqline))1408 static void dummy_set_irq_callback(int (*callback)(int irqline)) { }
1409
dummy_info(void * context,int regnum)1410 static const char *dummy_info(void *context, int regnum)
1411 {
1412 switch (regnum)
1413 {
1414 case CPU_INFO_NAME: return "";
1415 case CPU_INFO_FAMILY: return "no CPU";
1416 case CPU_INFO_VERSION: return "0.0";
1417 case CPU_INFO_FILE: return __FILE__;
1418 case CPU_INFO_CREDITS: return "The MAME team.";
1419 }
1420 return "";
1421 }
1422
dummy_dasm(char * buffer,unsigned pc)1423 static unsigned dummy_dasm(char *buffer, unsigned pc)
1424 {
1425 strcpy(buffer, "???");
1426 return 1;
1427 }
1428
1429
1430
1431 /*************************************
1432 *
1433 * 68000 reset kludge
1434 *
1435 *************************************/
1436
1437 #if (HAS_M68000 || HAS_M68010 || HAS_M68020 || HAS_M68EC020 || HAS_CYCLONE)
cpu_set_m68k_reset(int cpunum,void (* resetfn)(void))1438 void cpu_set_m68k_reset(int cpunum, void (*resetfn)(void))
1439 {
1440 void m68k_set_reset_instr_callback(void (*callback)(void));
1441 void m68000_set_reset_callback(void (*callback)(void));
1442 void m68020_set_reset_callback(void (*callback)(void));
1443
1444 if ( 1
1445 #if (HAS_M68000)
1446 && cpu[cpunum].cputype != CPU_M68000
1447 #endif
1448 #if (HAS_CYCLONE)
1449 && cpu[cpunum].cputype != CPU_CYCLONE
1450 #endif
1451 #if (HAS_M68010)
1452 && cpu[cpunum].cputype != CPU_M68010
1453 #endif
1454 #if (HAS_M68020)
1455 && cpu[cpunum].cputype != CPU_M68020
1456 #endif
1457 #if (HAS_M68EC020)
1458 && cpu[cpunum].cputype != CPU_M68EC020
1459 #endif
1460 )
1461 {
1462 /*logerror("Trying to set m68k reset vector on non-68k cpu\n");*/
1463 exit(1);
1464 }
1465
1466 cpuintrf_push_context(cpunum);
1467
1468 if ( 0
1469 #if (HAS_M68000)
1470 || cpu[cpunum].cputype == CPU_M68000
1471 #endif
1472 #if (HAS_CYCLONE)
1473 || cpu[cpunum].cputype == CPU_CYCLONE
1474 #endif
1475 #if (HAS_M68010)
1476 || cpu[cpunum].cputype == CPU_M68010
1477 #endif
1478 )
1479 {
1480 #ifdef A68K0
1481 m68000_set_reset_callback(resetfn);
1482 #else
1483 m68k_set_reset_instr_callback(resetfn);
1484 #endif
1485 }
1486 else
1487 {
1488 #ifdef A68K2
1489 m68020_set_reset_callback(resetfn);
1490 #else
1491 m68k_set_reset_instr_callback(resetfn);
1492 #endif
1493 }
1494 cpuintrf_pop_context();
1495 }
1496 #endif
1497