1 #ifndef CPUINTRF_H
2 #define CPUINTRF_H
3 
4 #include "osd_cpu.h"
5 #include "memory.h"
6 #include "timer.h"
7 
8 /* The old system is obsolete and no longer supported by the core */
9 #define NEW_INTERRUPT_SYSTEM    1
10 
11 #define MAX_IRQ_LINES   8       /* maximum number of IRQ lines per CPU */
12 
13 #define CLEAR_LINE		0		/* clear (a fired, held or pulsed) line */
14 #define ASSERT_LINE     1       /* assert an interrupt immediately */
15 #define HOLD_LINE       2       /* hold interrupt line until enable is true */
16 #define PULSE_LINE		3		/* pulse interrupt line for one instruction */
17 
18 #define MAX_REGS		128 	/* maximum number of register of any CPU */
19 
20 /* Values passed to the cpu_info function of a core to retrieve information */
21 enum {
22 	CPU_INFO_REG,
23 	CPU_INFO_FLAGS=MAX_REGS,
24 	CPU_INFO_NAME,
25 	CPU_INFO_FAMILY,
26 	CPU_INFO_VERSION,
27 	CPU_INFO_FILE,
28 	CPU_INFO_CREDITS,
29 	CPU_INFO_REG_LAYOUT,
30 	CPU_INFO_WIN_LAYOUT
31 };
32 
33 #define CPU_IS_LE		0	/* emulated CPU is little endian */
34 #define CPU_IS_BE		1	/* emulated CPU is big endian */
35 
36 /*
37  * This value is passed to cpu_get_reg to retrieve the previous
38  * program counter value, ie. before a CPU emulation started
39  * to fetch opcodes and arguments for the current instrution.
40  */
41 #define REG_PREVIOUSPC	-1
42 
43 /*
44  * This value is passed to cpu_get_reg/cpu_set_reg, instead of one of
45  * the names from the enum a CPU core defines for it's registers,
46  * to get or set the contents of the memory pointed to by a stack pointer.
47  * You can specify the n'th element on the stack by (REG_SP_CONTENTS-n),
48  * ie. lower negative values. The actual element size (UINT16 or UINT32)
49  * depends on the CPU core.
50  * This is also used to replace the cpu_geturnpc() function.
51  */
52 #define REG_SP_CONTENTS -2
53 
54 /*
55  * These flags can be defined in the makefile (or project) to
56  * exclude (zero) or include (non zero) specific CPU cores
57  */
58 #ifndef HAS_GENSYNC
59 #define HAS_GENSYNC		0
60 #endif
61 #ifndef HAS_Z80
62 #define HAS_Z80 		0
63 #endif
64 #ifndef HAS_Z80_VM
65 #define HAS_Z80_VM		0
66 #endif
67 #ifndef HAS_8080
68 #define HAS_8080		0
69 #endif
70 #ifndef HAS_8085A
71 #define HAS_8085A		0
72 #endif
73 #ifndef HAS_M6502
74 #define HAS_M6502		0
75 #endif
76 #ifndef HAS_M65C02
77 #define HAS_M65C02		0
78 #endif
79 #ifndef HAS_M65SC02
80 #define HAS_M65SC02		0
81 #endif
82 #ifndef HAS_M65CE02
83 #define HAS_M65CE02		0
84 #endif
85 #ifndef HAS_M6509
86 #define HAS_M6509		0
87 #endif
88 #ifndef HAS_M6510
89 #define HAS_M6510		0
90 #endif
91 #ifndef HAS_M6510T
92 #define HAS_M6510T		0
93 #endif
94 #ifndef HAS_M7501
95 #define HAS_M7501		0
96 #endif
97 #ifndef HAS_M8502
98 #define HAS_M8502		0
99 #endif
100 #ifndef HAS_N2A03
101 #define HAS_N2A03		0
102 #endif
103 #ifndef HAS_M4510
104 #define HAS_M4510		0
105 #endif
106 #ifndef HAS_H6280
107 #define HAS_H6280		0
108 #endif
109 #ifndef HAS_I86
110 #define HAS_I86 		0
111 #endif
112 #ifndef HAS_I88
113 #define HAS_I88 		0
114 #endif
115 #ifndef HAS_I186
116 #define HAS_I186		0
117 #endif
118 #ifndef HAS_I188
119 #define HAS_I188		0
120 #endif
121 #ifndef HAS_I286
122 #define HAS_I286		0
123 #endif
124 #ifndef HAS_V20
125 #define HAS_V20 		0
126 #endif
127 #ifndef HAS_V30
128 #define HAS_V30 		0
129 #endif
130 #ifndef HAS_V33
131 #define HAS_V33 		0
132 #endif
133 #ifndef HAS_ARMNEC
134 #define HAS_ARMNEC 		0
135 #endif
136 #ifndef HAS_I8035
137 #define HAS_I8035		0
138 #endif
139 #ifndef HAS_I8039
140 #define HAS_I8039		0
141 #endif
142 #ifndef HAS_I8048
143 #define HAS_I8048		0
144 #endif
145 #ifndef HAS_N7751
146 #define HAS_N7751		0
147 #endif
148 #ifndef HAS_M6800
149 #define HAS_M6800		0
150 #endif
151 #ifndef HAS_M6801
152 #define HAS_M6801		0
153 #endif
154 #ifndef HAS_M6802
155 #define HAS_M6802		0
156 #endif
157 #ifndef HAS_M6803
158 #define HAS_M6803		0
159 #endif
160 #ifndef HAS_M6808
161 #define HAS_M6808		0
162 #endif
163 #ifndef HAS_HD63701
164 #define HAS_HD63701 	0
165 #endif
166 #ifndef HAS_M6805
167 #define HAS_M6805		0
168 #endif
169 #ifndef HAS_M68705
170 #define HAS_M68705		0
171 #endif
172 #ifndef HAS_HD63705
173 #define HAS_HD63705 	0
174 #endif
175 #ifndef HAS_HD6309
176 #define HAS_HD6309		0
177 #endif
178 #ifndef HAS_M6809
179 #define HAS_M6809		0
180 #endif
181 #ifndef HAS_KONAMI
182 #define HAS_KONAMI		0
183 #endif
184 #ifndef HAS_M68000
185 #define HAS_M68000		0
186 #endif
187 #ifndef HAS_M68010
188 #define HAS_M68010		0
189 #endif
190 #ifndef HAS_M68EC020
191 #define HAS_M68EC020	0
192 #endif
193 #ifndef HAS_M68020
194 #define HAS_M68020		0
195 #endif
196 #ifndef HAS_T11
197 #define HAS_T11 		0
198 #endif
199 #ifndef HAS_S2650
200 #define HAS_S2650		0
201 #endif
202 #ifndef HAS_TMS34010
203 #define HAS_TMS34010	0
204 #endif
205 #ifndef HAS_TMS9900
206 #define HAS_TMS9900 	0
207 #endif
208 #ifndef HAS_TMS9940
209 #define HAS_TMS9940 	0
210 #endif
211 #ifndef HAS_TMS9980
212 #define HAS_TMS9980 	0
213 #endif
214 #ifndef HAS_TMS9985
215 #define HAS_TMS9985 	0
216 #endif
217 #ifndef HAS_TMS9989
218 #define HAS_TMS9989 	0
219 #endif
220 #ifndef HAS_TMS9995
221 #define HAS_TMS9995 	0
222 #endif
223 #ifndef HAS_TMS99105A
224 #define HAS_TMS99105A 	0
225 #endif
226 #ifndef HAS_TMS99110A
227 #define HAS_TMS99110A 	0
228 #endif
229 #ifndef HAS_Z8000
230 #define HAS_Z8000		0
231 #endif
232 #ifndef HAS_TMS320C10
233 #define HAS_TMS320C10	0
234 #endif
235 #ifndef HAS_CCPU
236 #define HAS_CCPU		0
237 #endif
238 #ifndef HAS_PDP1
239 #define HAS_PDP1		0
240 #endif
241 #ifndef HAS_ADSP2100
242 #define HAS_ADSP2100	0
243 #endif
244 #ifndef HAS_ADSP2105
245 #define HAS_ADSP2105	0
246 #endif
247 #ifndef HAS_MIPS
248 #define HAS_MIPS		0
249 #endif
250 #ifndef HAS_SC61860
251 #define HAS_SC61860		0
252 #endif
253 #ifndef HAS_ARM
254 #define HAS_ARM 		0
255 #endif
256 
257 /* ASG 971222 -- added this generic structure */
258 #ifdef _MSC_VER
259 __declspec(align(32))
260 #endif
261 struct cpu_interface
262 {
263 	unsigned cpu_num;
264 	void (*reset)(void *param);
265 	void (*exit)(void);
266 	int (*execute)(int cycles);
267 	void (*burn)(int cycles);
268 	unsigned (*get_context)(void *reg);
269 	void (*set_context)(void *reg);
270 	void *(*get_cycle_table)(int which);
271 	void (*set_cycle_table)(int which, void *new_table);
272     unsigned (*get_pc)(void);
273 	void (*set_pc)(unsigned val);
274 	unsigned (*get_sp)(void);
275 	void (*set_sp)(unsigned val);
276 	unsigned (*get_reg)(int regnum);
277 	void (*set_reg)(int regnum, unsigned val);
278 	void (*set_nmi_line)(int linestate);
279 	void (*set_irq_line)(int irqline, int linestate);
280 	void (*set_irq_callback)(int(*callback)(int irqline));
281 	void (*internal_interrupt)(int type);
282 	void (*cpu_state_save)(void *file);
283 	void (*cpu_state_load)(void *file);
284 	const char* (*cpu_info)(void *context,int regnum);
285 	unsigned (*cpu_dasm)(char *buffer,unsigned pc);
286 	unsigned num_irqs;
287 	int default_vector;
288 	int *icount;
289 	float overclock;
290 	int no_int, irq_int, nmi_int;
291 	mem_read_handler memory_read;
292 	mem_write_handler memory_write;
293 	void (*set_op_base)(int pc);
294 	int address_shift;
295 	unsigned address_bits, endianess, align_unit, max_inst_len;
296 	unsigned abits1, abits2, abitsmin;
297 }
298 #ifndef _MSC_VER
299 __attribute__ ((__aligned__ (32)))
300 #endif
301 ;
302 
303 extern struct cpu_interface cpuintf[];
304 
305 void cpu_init(void);
306 void cpu_run(void);
307 
308 /* optional watchdog */
309 WRITE_HANDLER( watchdog_reset_w );
310 READ_HANDLER( watchdog_reset_r );
311 /* Use this function to reset the machine */
312 void machine_reset(void);
313 /* Use this function to reset a single CPU */
314 void cpu_set_reset_line(int cpu,int state);
315 /* Use this function to halt a single CPU */
316 void cpu_set_halt_line(int cpu,int state);
317 
318 /* This function returns CPUNUM current status (running or halted) */
319 int cpu_getstatus(int cpunum);
320 int cpu_gettotalcpu(void);
321 int cpu_getactivecpu(void);
322 void cpu_setactivecpu(int cpunum);
323 
324 /* Returns the current program counter */
325 unsigned cpu_get_pc(void);
326 /* Set the current program counter */
327 void cpu_set_pc(unsigned val);
328 
329 /* Returns the current stack pointer */
330 unsigned cpu_get_sp(void);
331 /* Set the current stack pointer */
332 void cpu_set_sp(unsigned val);
333 
334 /* Get the active CPUs context and return it's size */
335 unsigned cpu_get_context(void *context);
336 /* Set the active CPUs context */
337 void cpu_set_context(void *context);
338 
339 /* Get a pointer to the active CPUs cycle count lookup table */
340 void *cpu_get_cycle_table(int which);
341 /* Override a pointer to the active CPUs cycle count lookup table */
342 void cpu_set_cycle_tbl(int which, void *new_table);
343 
344 /* Returns a specific register value (mamedbg) */
345 unsigned cpu_get_reg(int regnum);
346 /* Sets a specific register value (mamedbg) */
347 void cpu_set_reg(int regnum, unsigned val);
348 
349 /* Returns previous pc (start of opcode causing read/write) */
350 /* int cpu_getpreviouspc(void); */
351 #define cpu_getpreviouspc() cpu_get_reg(REG_PREVIOUSPC)
352 
353 /* Returns the return address from the top of the stack (Z80 only) */
354 /* int cpu_getreturnpc(void); */
355 /* This can now be handled with a generic function */
356 #define cpu_geturnpc() cpu_get_reg(REG_SP_CONTENTS)
357 
358 int cycles_currently_ran(void);
359 int cycles_left_to_run(void);
360 
361 /* Returns the number of CPU cycles which take place in one video frame */
362 int cpu_gettotalcycles(void);
363 /* Returns the number of CPU cycles before the next interrupt handler call */
364 int cpu_geticount(void);
365 /* Returns the number of CPU cycles before the end of the current video frame */
366 int cpu_getfcount(void);
367 /* Returns the number of CPU cycles in one video frame */
368 int cpu_getfperiod(void);
369 /* Scales a given value by the ratio of fcount / fperiod */
370 int cpu_scalebyfcount(int value);
371 /* Returns the current scanline number */
372 int cpu_getscanline(void);
373 /* Returns the amount of time until a given scanline */
374 timer_tm cpu_getscanlinetime(int scanline);
375 /* Returns the duration of a single scanline */
376 timer_tm cpu_getscanlineperiod(void);
377 /* Returns the duration of a single scanline in cycles */
378 int cpu_getscanlinecycles(void);
379 /* Returns the number of cycles since the beginning of this frame */
380 int cpu_getcurrentcycles(void);
381 /* Returns the current horizontal beam position in pixels */
382 int cpu_gethorzbeampos(void);
383 /*
384   Returns the number of times the interrupt handler will be called before
385   the end of the current video frame. This is can be useful to interrupt
386   handlers to synchronize their operation. If you call this from outside
387   an interrupt handler, add 1 to the result, i.e. if it returns 0, it means
388   that the interrupt handler will be called once.
389 */
390 int cpu_getiloops(void);
391 
392 /* Returns the current VBLANK state */
393 int cpu_getvblank(void);
394 
395 /* Returns the number of the video frame we are currently playing */
396 int cpu_getcurrentframe(void);
397 
398 
399 /* generate a trigger after a specific period of time */
400 void cpu_triggertime (timer_tm duration, int trigger);
401 /* generate a trigger now */
402 void cpu_trigger (int trigger);
403 
404 /* burn CPU cycles until a timer trigger */
405 void cpu_spinuntil_trigger (int trigger);
406 /* burn CPU cycles until the next interrupt */
407 void cpu_spinuntil_int (void);
408 /* burn CPU cycles until our timeslice is up */
409 void cpu_spin (void);
410 /* burn CPU cycles for a specific period of time */
411 void cpu_spinuntil_time (timer_tm duration);
412 
413 /* yield our timeslice for a specific period of time */
414 void cpu_yielduntil_trigger (int trigger);
415 /* yield our timeslice until the next interrupt */
416 void cpu_yielduntil_int (void);
417 /* yield our current timeslice */
418 void cpu_yield (void);
419 /* yield our timeslice for a specific period of time */
420 void cpu_yielduntil_time (timer_tm duration);
421 
422 /* set the NMI line state for a CPU, normally use PULSE_LINE */
423 void cpu_set_nmi_line(int cpunum, int state);
424 /* set the IRQ line state for a specific irq line of a CPU */
425 /* normally use state HOLD_LINE, irqline 0 for first IRQ type of a cpu */
426 void cpu_set_irq_line(int cpunum, int irqline, int state);
427 /* this is to be called by CPU cores only! */
428 void cpu_generate_internal_interrupt(int cpunum, int type);
429 /* set the vector to be returned during a CPU's interrupt acknowledge cycle */
430 void cpu_irq_line_vector_w(int cpunum, int irqline, int vector);
431 
432 /* use this function to install a driver callback for IRQ acknowledge */
433 void cpu_set_irq_callback(int cpunum, int (*callback)(int));
434 
435 /* use these in your write memory/port handles to set an IRQ vector */
436 /* offset corresponds to the irq line number here */
437 WRITE_HANDLER( cpu_0_irq_line_vector_w );
438 WRITE_HANDLER( cpu_1_irq_line_vector_w );
439 WRITE_HANDLER( cpu_2_irq_line_vector_w );
440 WRITE_HANDLER( cpu_3_irq_line_vector_w );
441 WRITE_HANDLER( cpu_4_irq_line_vector_w );
442 WRITE_HANDLER( cpu_5_irq_line_vector_w );
443 WRITE_HANDLER( cpu_6_irq_line_vector_w );
444 WRITE_HANDLER( cpu_7_irq_line_vector_w );
445 
446 /* Obsolete functions: avoid to use them in new drivers if possible. */
447 
448 /* cause an interrupt on a CPU */
449 void cpu_cause_interrupt(int cpu,int type);
450 void cpu_clear_pending_interrupts(int cpu);
451 WRITE_HANDLER( interrupt_enable_w );
452 WRITE_HANDLER( interrupt_vector_w );
453 int interrupt(void);
454 int nmi_interrupt(void);
455 int m68_level1_irq(void);
456 int m68_level2_irq(void);
457 int m68_level3_irq(void);
458 int m68_level4_irq(void);
459 int m68_level5_irq(void);
460 int m68_level6_irq(void);
461 int m68_level7_irq(void);
462 int ignore_interrupt(void);
463 
464 /* CPU context access */
465 void* cpu_getcontext (int _activecpu);
466 int cpu_is_saving_context(int _activecpu);
467 
468 /***************************************************************************
469  * Get information for the currently active CPU
470  * cputype is a value from the CPU enum in driver.h
471  ***************************************************************************/
472 /* Return number of address bits */
473 unsigned cpu_address_bits(void);
474 /* Return address mask */
475 unsigned cpu_address_mask(void);
476 /* Return address shift factor (TMS34010 bit addressing mode) */
477 int cpu_address_shift(void);
478 /* Return endianess of the emulated CPU (CPU_IS_LE or CPU_IS_BE) */
479 unsigned cpu_endianess(void);
480 /* Return opcode align unit (1 byte, 2 word, 4 dword) */
481 unsigned cpu_align_unit(void);
482 /* Return maximum instruction length */
483 unsigned cpu_max_inst_len(void);
484 
485 /* Return name of the active CPU */
486 const char *cpu_name(void);
487 /* Return family name of the active CPU */
488 const char *cpu_core_family(void);
489 /* Return core version of the active CPU */
490 const char *cpu_core_version(void);
491 /* Return core filename of the active CPU */
492 const char *cpu_core_file(void);
493 /* Return credits info for of the active CPU */
494 const char *cpu_core_credits(void);
495 
496 /* Disassemble an instruction at PC into the given buffer */
497 unsigned cpu_dasm(char *buffer, unsigned pc);
498 /* Return a string describing the currently set flag (status) bits of the active CPU */
499 const char *cpu_flags(void);
500 
501 /***************************************************************************
502  * Get information for a specific CPU type
503  * cputype is a value from the CPU enum in driver.h
504  ***************************************************************************/
505 /* Return address shift factor */
506 /* TMS320C10 -1: word addressing mode, TMS34010 3: bit addressing mode */
507 int cputype_address_shift(int cputype);
508 /* Return number of address bits */
509 unsigned cputype_address_bits(int cputype);
510 /* Return address mask */
511 unsigned cputype_address_mask(int cputype);
512 /* Return endianess of the emulated CPU (CPU_IS_LE or CPU_IS_BE) */
513 unsigned cputype_endianess(int cputype);
514 /* Return opcode align unit (1 byte, 2 word, 4 dword) */
515 unsigned cputype_align_unit(int cputype);
516 /* Return maximum instruction length */
517 unsigned cputype_max_inst_len(int cputype);
518 
519 /* Return name of the CPU */
520 const char *cputype_name(int cputype);
521 /* Return family name of the CPU */
522 const char *cputype_core_family(int cputype);
523 /* Return core version number of the CPU */
524 const char *cputype_core_version(int cputype);
525 /* Return core filename of the CPU */
526 const char *cputype_core_file(int cputype);
527 /* Return credits for the CPU core */
528 const char *cputype_core_credits(int cputype);
529 
530 /***************************************************************************
531  * Get (or set) information for a numbered CPU of the running machine
532  * cpunum is a value between 0 and cpu_gettotalcpu() - 1
533  ***************************************************************************/
534 /* Return number of address bits */
535 unsigned cpunum_address_bits(int cputype);
536 /* Return address mask */
537 unsigned cpunum_address_mask(int cputype);
538 /* Return endianess of the emulated CPU (CPU_LSB_FIRST or CPU_MSB_FIRST) */
539 unsigned cpunum_endianess(int cputype);
540 /* Return opcode align unit (1 byte, 2 word, 4 dword) */
541 unsigned cpunum_align_unit(int cputype);
542 /* Return maximum instruction length */
543 unsigned cpunum_max_inst_len(int cputype);
544 
545 /* Get a register value for the specified CPU number of the running machine */
546 unsigned cpunum_get_reg(int cpunum, int regnum);
547 /* Set a register value for the specified CPU number of the running machine */
548 void cpunum_set_reg(int cpunum, int regnum, unsigned val);
549 
550 unsigned cpunum_dasm(int cpunum,char *buffer,unsigned pc);
551 /* Return a string describing the currently set flag (status) bits of the CPU */
552 const char *cpunum_flags(int cpunum);
553 /* Return a name for the specified cpu number */
554 const char *cpunum_name(int cpunum);
555 /* Return a family name for the specified cpu number */
556 const char *cpunum_core_family(int cpunum);
557 /* Return a version for the specified cpu number */
558 const char *cpunum_core_version(int cpunum);
559 /* Return a the source filename for the specified cpu number */
560 const char *cpunum_core_file(int cpunum);
561 /* Return a the credits for the specified cpu number */
562 const char *cpunum_core_credits(int cpunum);
563 
564 /* daisy-chain link */
565 typedef struct {
566 	void (*reset)(int);             /* reset callback     */
567 	int  (*interrupt_entry)(int);   /* entry callback     */
568 	void (*interrupt_reti)(int);    /* reti callback      */
569 	int irq_param;                  /* callback paramater */
570 }	Z80_DaisyChain;
571 
572 #define Z80_MAXDAISY	4		/* maximum of daisy chan device */
573 
574 #define Z80_INT_REQ     0x01    /* interrupt request mask       */
575 #define Z80_INT_IEO     0x02    /* interrupt disable mask(IEO)  */
576 
577 #define Z80_VECTOR(device,state) (((device)<<8)|(state))
578 
579 #endif	/* CPUINTRF_H */
580