void IntZ80(Z80 *R,word Vector) { /* If HALTed, take CPU off HALT instruction */ if(R->IFF&IFF_HALT) { R->PC.W++;R->IFF&=~IFF_HALT; } if((R->IFF&IFF_1)||(Vector==INT_NMI)) { /* Save PC on stack */ M_PUSH(PC); /* Automatically reset IRequest if needed */ if(R->IAutoReset&&(Vector==R->IRequest)) R->IRequest=INT_NONE; /* If it is NMI... */ if(Vector==INT_NMI) { /* Clear IFF1 */ R->IFF&=~(IFF_1|IFF_EI); /* Jump to hardwired NMI vector */ R->PC.W=0x0066; JumpZ80(0x0066); /* Done */ return; } /* Further interrupts off */ R->IFF&=~(IFF_1|IFF_2|IFF_EI); /* If in IM2 mode... */ if(R->IFF&IFF_IM2) { /* Make up the vector address */ Vector=(Vector&0xFF)|((word)(R->I)<<8); /* Read the vector */ R->PC.B.l=RdZ80(Vector++); R->PC.B.h=RdZ80(Vector); JumpZ80(R->PC.W); /* Done */ return; } /* If in IM1 mode, just jump to hardwired IRQ vector */ if(R->IFF&IFF_IM1) { R->PC.W=0x0038;JumpZ80(0x0038);return; } /* If in IM0 mode... */ /* Jump to a vector */ switch(Vector) { case INT_RST00: R->PC.W=0x0000;JumpZ80(0x0000);break; case INT_RST08: R->PC.W=0x0008;JumpZ80(0x0008);break; case INT_RST10: R->PC.W=0x0010;JumpZ80(0x0010);break; case INT_RST18: R->PC.W=0x0018;JumpZ80(0x0018);break; case INT_RST20: R->PC.W=0x0020;JumpZ80(0x0020);break; case INT_RST28: R->PC.W=0x0028;JumpZ80(0x0028);break; case INT_RST30: R->PC.W=0x0030;JumpZ80(0x0030);break; case INT_RST38: R->PC.W=0x0038;JumpZ80(0x0038);break; } } }
void Int6502(M6502 *R,byte Type) { register pair J; if((Type==INT_NMI)||((Type==INT_IRQ)&&!(R->P&I_FLAG))) { R->ICount-=7; M_PUSH(R->PC.B.h); M_PUSH(R->PC.B.l); M_PUSH(R->P&~B_FLAG); R->P&=~D_FLAG; if(Type==INT_NMI) J.W=0xFFFA; else { R->P|=I_FLAG;J.W=0xFFFE; } R->PC.B.l=Rd6502(J.W++); R->PC.B.h=Rd6502(J.W); } }
void IntZ80(Z80 *R,word Vector) { if((R->IFF&0x01)||(Vector==INT_NMI)) { /* Experimental V Shouldn't disable all interrupts? */ R->IFF=(R->IFF&0x9E)|((R->IFF&0x01)<<6); if(R->IFF&0x80) { R->PC.W++;R->IFF&=0x7F; } M_PUSH(PC); if(Vector==INT_NMI) R->PC.W=INT_NMI; else if(R->IFF&0x04) { Vector=(Vector&0xFF)|((word)(R->I)<<8); R->PC.B.l=RdZ80(Vector++); R->PC.B.h=RdZ80(Vector); } else if(R->IFF&0x02) R->PC.W=INT_IRQ; else R->PC.W=Vector; } mz80_cache_ip(R); }
void IntZ80(Z80 *R,word Vector) { if((R->IFF&0x01)||(Vector==INT_NMI)) { /* Experimental V Shouldn't disable all interrupts? */ R->IFF=(R->IFF&0x9E)|((R->IFF&0x01)<<6); if(R->IFF&0x80) { R->PC.W++;R->IFF&=0x7F; } M_PUSH(PC); /* Automatically reset IRequest if needed */ if(R->IAutoReset&&(Vector==R->IRequest)) R->IRequest=INT_NONE; if(Vector==INT_NMI) R->PC.W=0x0066; else if(R->IFF&0x04) { Vector=(Vector&0xFF)|((word)(R->I)<<8); R->PC.B.l=RdZ80(Vector++); R->PC.B.h=RdZ80(Vector); } else if(R->IFF&0x02) R->PC.W=0x0038; else switch(Vector) { case INT_RST00: R->PC.W=0x0000;break; case INT_RST08: R->PC.W=0x0008;break; case INT_RST10: R->PC.W=0x0010;break; case INT_RST18: R->PC.W=0x0018;break; case INT_RST20: R->PC.W=0x0020;break; case INT_RST28: R->PC.W=0x0028;break; case INT_RST30: R->PC.W=0x0030;break; case INT_RST38: R->PC.W=0x0038;break; } } }
word Z80(reg Regs) { register byte I; register pair J; R=Regs;CPURunning=1; #ifdef INTERRUPTS ICount=IPeriod; IFlag=0; #endif for(;;) { #ifdef DEBUG if(R.PC.W==Trap) Trace=1; /*** Turn tracing on if trapped ***/ if(Trace) Debug(&R); /*** Call single-step debugger ***/ #endif switch(M_RDMEM(R.PC.W++)) { #include "Codes.h" case PFX_CB: CodesCB();break; case PFX_ED: CodesED();break; case PFX_FD: CodesFD();break; case PFX_DD: CodesDD();break; case HALT: #ifdef INTERRUPTS if(R.IFF&0x01) { R.PC.W--;R.IFF|=0x80; } #else printf("CPU HALTed and stuck at PC=%hX\n",--R.PC.W); CPURunning=0; #endif break; default: if(TrapBadOps) printf ( "Unrecognized instruction: %X at PC=%hX\n", M_RDMEM(R.PC.W-1),R.PC.W-1 ); } #ifndef INTERRUPTS if(!CPURunning) break; #else if(!ICount--) { if(!CPURunning) break; ICount=IPeriod; if(IntSync||IFlag) { IFlag=0;J.W=Interrupt(); if(((J.W!=0xFFFF)&&(R.IFF&0x01))||(J.W==0x0066)) { /* Experimental V Shouldn't disable all interrupts? */ R.IFF=(R.IFF&0xBE)|((R.IFF&0x01)<<6); if(R.IFF&0x80) { R.PC.W++;R.IFF&=0x7F; } M_PUSH(PC); if(J.W==0x0066) R.PC.W=0x0066; else if(R.IFF&0x04) { J.W&=0xFE;J.B.h=R.I; R.PC.B.l=M_RDMEM(J.W++); R.PC.B.h=M_RDMEM(J.W); } else if(R.IFF&0x02) R.PC.W=0x0038; else R.PC.W=J.W; } } } #endif } return(R.PC.W); }