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