public MachineCPU(int cpu_type, int cpu_clock, MemoryReadAddress[] memory_read, MemoryWriteAddress[] memory_write, IOReadPort[] port_read, IOWritePort[] port_write, vblank_interrupt_callback vblank_interrupt, int vblank_interrupts_per_frame, vblank_interrupt_callback interrupt = null, int ips = 0) { this.cpu_type = cpu_type; this.cpu_clock = cpu_clock; this.memory_read = memory_read; this.memory_write = memory_write; this.port_read = port_read; this.port_write = port_write; this.vblank_interrupt = vblank_interrupt; this.vblank_interrupts_per_frame = vblank_interrupts_per_frame; this.timed_interrupt = interrupt; this.timed_interrupts_per_second = ips; }
static void cpu_generate_interrupt(int cpunum, vblank_interrupt_callback func, int num) { int oldactive = activecpu; /* don't trigger interrupts on suspended CPUs */ if (!cpu_getstatus(cpunum)) return; /* swap to the CPU's context */ activecpu = cpunum; memorycontextswap(activecpu); if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context); /* cause the interrupt, calling the function if it exists */ if (func != null) num = func(); /* wrapper for the new interrupt system */ if (num != INT_TYPE_NONE(cpunum)) { //LOG((errorlog,"CPU#%d interrupt type $%04x: ", cpunum, num)); /* is it the NMI type interrupt of that CPU? */ if (num == INT_TYPE_NMI(cpunum)) { // LOG((errorlog,"NMI\n")); cpu_manualnmicallback(cpunum | (PULSE_LINE << 3)); } else { int irq_line; switch (CPU_TYPE(cpunum)) { case CPU_Z80: irq_line = 0; break;//LOG((errorlog,"Z80 IRQ\n")); break; case CPU_8080: switch (num) { case cpu_i8085.I8080_INTR: irq_line = 0; //LOG((errorlog,"I8080 INTR\n")); break; default: irq_line = 0; //LOG((errorlog,"I8080 unknown\n")); break; } break; //case CPU_8085A: // switch (num) // { // case I8085_INTR: irq_line = 0; break; // case I8085_RST55: irq_line = 1; break; // case I8085_RST65: irq_line = 2; break; // case I8085_RST75: irq_line = 3; break; // default: irq_line = 0; break; // } // break; case CPU_M6502: irq_line = 0; break; case CPU_M65C02: irq_line = 0; break; case CPU_M65SC02: irq_line = 0; break; case CPU_M65CE02: irq_line = 0; break; case CPU_M6509: irq_line = 0; break; case CPU_M6510: irq_line = 0; break; case CPU_N2A03: irq_line = 0; break; #if (HAS_H6280) case CPU_H6280: switch (num) { case H6280_INT_IRQ1: irq_line = 0; LOG((errorlog,"H6280 INT 1\n")); break; case H6280_INT_IRQ2: irq_line = 1; LOG((errorlog,"H6280 INT 2\n")); break; case H6280_INT_TIMER: irq_line = 2; LOG((errorlog,"H6280 TIMER INT\n")); break; default: irq_line = 0; LOG((errorlog,"H6280 unknown\n")); } break; #endif case CPU_I86: irq_line = 0; break; case CPU_V20: irq_line = 0; break; case CPU_V30: irq_line = 0; break; case CPU_V33: irq_line = 0; break; case CPU_I8035: irq_line = 0; break; case CPU_I8039: irq_line = 0; break; case CPU_I8048: irq_line = 0; break; case CPU_N7751: irq_line = 0; break; case CPU_M6800: irq_line = 0; break;//LOG((errorlog,"M6800 IRQ\n")); break; case CPU_M6801: irq_line = 0; break; case CPU_M6802: irq_line = 0; break; case CPU_M6803: irq_line = 0; break; case CPU_M6808: irq_line = 0; break; case CPU_HD63701: irq_line = 0; break; case CPU_M6805: irq_line = 0; break; case CPU_M68705: irq_line = 0; break; case CPU_HD63705: irq_line = 0; break; case CPU_HD6309: switch (num) { case cpu_m6809.HD6309_INT_IRQ: irq_line = 0; break; case cpu_m6809.HD6309_INT_FIRQ: irq_line = 1; break; default: irq_line = 0; break; } break; case CPU_M6809: switch (num) { case cpu_m6809.M6809_INT_IRQ: irq_line = 0; break;//LOG((errorlog,"M6809 IRQ\n")); break; case cpu_m6809.M6809_INT_FIRQ: irq_line = 1; break;//LOG((errorlog,"M6809 FIRQ\n")); break; default: irq_line = 0; break;//LOG((errorlog,"M6809 unknown\n")); } break; case CPU_KONAMI: switch (num) { case cpu_konami.KONAMI_INT_IRQ: irq_line = 0; break; case cpu_konami.KONAMI_INT_FIRQ: irq_line = 1; break; default: irq_line = 0; break; } break; case CPU_M68000: switch (num) { case cpu_m68000.MC68000_IRQ_1: irq_line = 1; break; case cpu_m68000.MC68000_IRQ_2: irq_line = 2; break; case cpu_m68000.MC68000_IRQ_3: irq_line = 3; break; case cpu_m68000.MC68000_IRQ_4: irq_line = 4; break; case cpu_m68000.MC68000_IRQ_5: irq_line = 5; break; case cpu_m68000.MC68000_IRQ_6: irq_line = 6; break; case cpu_m68000.MC68000_IRQ_7: irq_line = 7; break; default: irq_line = 0; break; } /* until now only auto vector interrupts supported */ num = cpu_m68000.MC68000_INT_ACK_AUTOVECTOR; break; //case CPU_M68010: // switch (num) // { // case MC68010_IRQ_1: irq_line = 1; LOG((errorlog,"M68010 IRQ1\n")); break; // case MC68010_IRQ_2: irq_line = 2; LOG((errorlog,"M68010 IRQ2\n")); break; // case MC68010_IRQ_3: irq_line = 3; LOG((errorlog,"M68010 IRQ3\n")); break; // case MC68010_IRQ_4: irq_line = 4; LOG((errorlog,"M68010 IRQ4\n")); break; // case MC68010_IRQ_5: irq_line = 5; LOG((errorlog,"M68010 IRQ5\n")); break; // case MC68010_IRQ_6: irq_line = 6; LOG((errorlog,"M68010 IRQ6\n")); break; // case MC68010_IRQ_7: irq_line = 7; LOG((errorlog,"M68010 IRQ7\n")); break; // default: irq_line = 0; LOG((errorlog,"M68010 unknown\n")); // } // /* until now only auto vector interrupts supported */ // num = MC68000_INT_ACK_AUTOVECTOR; // break; //case CPU_M68020: // switch (num) // { // case MC68020_IRQ_1: irq_line = 1; LOG((errorlog,"M68020 IRQ1\n")); break; // case MC68020_IRQ_2: irq_line = 2; LOG((errorlog,"M68020 IRQ2\n")); break; // case MC68020_IRQ_3: irq_line = 3; LOG((errorlog,"M68020 IRQ3\n")); break; // case MC68020_IRQ_4: irq_line = 4; LOG((errorlog,"M68020 IRQ4\n")); break; // case MC68020_IRQ_5: irq_line = 5; LOG((errorlog,"M68020 IRQ5\n")); break; // case MC68020_IRQ_6: irq_line = 6; LOG((errorlog,"M68020 IRQ6\n")); break; // case MC68020_IRQ_7: irq_line = 7; LOG((errorlog,"M68020 IRQ7\n")); break; // default: irq_line = 0; LOG((errorlog,"M68020 unknown\n")); // } // /* until now only auto vector interrupts supported */ // num = MC68000_INT_ACK_AUTOVECTOR; // break; #if (HAS_M68EC020) case CPU_M68EC020: switch (num) { case MC68EC020_IRQ_1: irq_line = 1; LOG((errorlog,"M68EC020 IRQ1\n")); break; case MC68EC020_IRQ_2: irq_line = 2; LOG((errorlog,"M68EC020 IRQ2\n")); break; case MC68EC020_IRQ_3: irq_line = 3; LOG((errorlog,"M68EC020 IRQ3\n")); break; case MC68EC020_IRQ_4: irq_line = 4; LOG((errorlog,"M68EC020 IRQ4\n")); break; case MC68EC020_IRQ_5: irq_line = 5; LOG((errorlog,"M68EC020 IRQ5\n")); break; case MC68EC020_IRQ_6: irq_line = 6; LOG((errorlog,"M68EC020 IRQ6\n")); break; case MC68EC020_IRQ_7: irq_line = 7; LOG((errorlog,"M68EC020 IRQ7\n")); break; default: irq_line = 0; LOG((errorlog,"M68EC020 unknown\n")); } /* until now only auto vector interrupts supported */ num = MC68000_INT_ACK_AUTOVECTOR; break; #endif #if HAS_T11 case CPU_T11: switch (num) { case T11_IRQ0: irq_line = 0; LOG((errorlog,"T11 IRQ0\n")); break; case T11_IRQ1: irq_line = 1; LOG((errorlog,"T11 IRQ1\n")); break; case T11_IRQ2: irq_line = 2; LOG((errorlog,"T11 IRQ2\n")); break; case T11_IRQ3: irq_line = 3; LOG((errorlog,"T11 IRQ3\n")); break; default: irq_line = 0; LOG((errorlog,"T11 unknown\n")); } break; #endif #if HAS_S2650 case CPU_S2650: irq_line = 0; LOG((errorlog,"S2650 IRQ\n")); break; #endif #if HAS_TMS34010 case CPU_TMS34010: switch (num) { case TMS34010_INT1: irq_line = 0; LOG((errorlog,"TMS34010 INT1\n")); break; case TMS34010_INT2: irq_line = 1; LOG((errorlog,"TMS34010 INT2\n")); break; default: irq_line = 0; LOG((errorlog,"TMS34010 unknown\n")); } break; #endif /*#if HAS_TMS9900 case CPU_TMS9900: irq_line = 0; LOG((errorlog,"TMS9900 IRQ\n")); break; #endif*/ #if (HAS_TMS9900) || (HAS_TMS9940) || (HAS_TMS9980) || (HAS_TMS9985) || (HAS_TMS9989) || (HAS_TMS9995) || (HAS_TMS99105A) || (HAS_TMS99110A) #if (HAS_TMS9900) case CPU_TMS9900: #endif #if (HAS_TMS9940) case CPU_TMS9940: #endif #if (HAS_TMS9980) case CPU_TMS9980: #endif #if (HAS_TMS9985) case CPU_TMS9985: #endif #if (HAS_TMS9989) case CPU_TMS9989: #endif #if (HAS_TMS9995) case CPU_TMS9995: #endif #if (HAS_TMS99105A) case CPU_TMS99105A: #endif #if (HAS_TMS99110A) case CPU_TMS99110A: #endif LOG((errorlog,"Please use the new interrupt scheme for your new developments !\n")); irq_line = 0; break; #endif #if HAS_Z8000 case CPU_Z8000: switch (num) { case Z8000_NVI: irq_line = 0; LOG((errorlog,"Z8000 NVI\n")); break; case Z8000_VI: irq_line = 1; LOG((errorlog,"Z8000 VI\n")); break; default: irq_line = 0; LOG((errorlog,"Z8000 unknown\n")); } break; #endif #if HAS_TMS320C10 case CPU_TMS320C10: switch (num) { case TMS320C10_ACTIVE_INT: irq_line = 0; LOG((errorlog,"TMS32010 INT\n")); break; case TMS320C10_ACTIVE_BIO: irq_line = 1; LOG((errorlog,"TMS32010 BIO\n")); break; default: irq_line = 0; LOG((errorlog,"TMS32010 unknown\n")); } break; #endif #if HAS_ADSP2100 case CPU_ADSP2100: switch (num) { case ADSP2100_IRQ0: irq_line = 0; LOG((errorlog,"ADSP2100 IRQ0\n")); break; case ADSP2100_IRQ1: irq_line = 1; LOG((errorlog,"ADSP2100 IRQ1\n")); break; case ADSP2100_IRQ2: irq_line = 2; LOG((errorlog,"ADSP2100 IRQ1\n")); break; case ADSP2100_IRQ3: irq_line = 3; LOG((errorlog,"ADSP2100 IRQ1\n")); break; default: irq_line = 0; LOG((errorlog,"ADSP2100 unknown\n")); } break; #endif default: irq_line = 0; /* else it should be an IRQ type; assume line 0 and store vector */ //LOG((errorlog,"unknown IRQ\n")); break; } cpu_irq_line_vector_w(cpunum, irq_line, num); cpu_manualirqcallback(irq_line | (cpunum << 3) | (HOLD_LINE << 6)); } } /* update the CPU's context */ if (cpu[activecpu].save_context) GETCONTEXT(activecpu, ref cpu[activecpu].context); activecpu = oldactive; if (activecpu >= 0) memorycontextswap(activecpu); /* trigger already generated by cpu_manualirqcallback or cpu_manualnmicallback */ }