word RunZ80(Z80 *R) { register byte I; register pair J; for(;;) { #ifdef DEBUG /* Turn tracing on when reached trap address */ if(R->PC.W==R->Trap) R->Trace=1; /* Call single-step debugger, exit if requested */ if(R->Trace) if(!DebugZ80(R)) return(R->PC.W); #endif I=RdZ80(R->PC.W++); R->ICount-=Cycles[I]; switch(I) { #include "Codes.h" case PFX_CB: CodesCB(R);break; case PFX_ED: CodesED(R);break; case PFX_FD: CodesFD(R);break; case PFX_DD: CodesDD(R);break; } /* If cycle counter expired... */ if(R->ICount<=0) { /* If we have come after EI, get address from IRequest */ /* Otherwise, get it from the loop handler */ if(R->IFF&IFF_EI) { R->IFF=(R->IFF&~IFF_EI)|IFF_1; /* Done with AfterEI state */ R->ICount+=R->IBackup-1; /* Restore the ICount */ /* Call periodic handler or set pending IRQ */ if(R->ICount>0) J.W=R->IRequest; else { J.W=LoopZ80(R); /* Call periodic handler */ R->ICount+=R->IPeriod; /* Reset the cycle counter */ if(J.W==INT_NONE) J.W=R->IRequest; /* Pending IRQ */ } } else { J.W=LoopZ80(R); /* Call periodic handler */ R->ICount+=R->IPeriod; /* Reset the cycle counter */ if(J.W==INT_NONE) J.W=R->IRequest; /* Pending IRQ */ } if(J.W==INT_QUIT) return(R->PC.W); /* Exit if INT_QUIT */ if(J.W!=INT_NONE) IntZ80(R,J.W); /* Int-pt if needed */ } } /* Execution stopped */ return(R->PC.W); }
word RunZ80(Z80 *R) { register byte I; register pair J; R->ICount += R->IPeriod; while ((R->ICount > 0) || (R->IFF&0x20)) { J.W = R->IRequest; R->IRequest = INT_NONE; /* If we have come after EI, get address from IRequest */ /* Otherwise, get it from the loop handler */ if(R->IFF&0x20) { R->ICount+=R->IBackup-1; /* Restore the ICount */ R->IFF&=0xDF; /* Done with AfterEI state */ } if(J.W==INT_QUIT) return(R->PC.W); /* Exit if INT_QUIT */ if(J.W!=INT_NONE) IntZ80(R,J.W); /* Int-pt if needed */ I=OpZ80(R); R->ICount-=z80_Cycles[I]; switch(I) { #include "mz80opc1.h" case PFX_CB: CodesCB(R);break; case PFX_ED: CodesED(R);break; case PFX_FD: CodesFD(R);break; case PFX_DD: CodesDD(R);break; } } /* Execution stopped */ return(R->PC.W); }
int ExecZ80(register Z80 *R,register int RunCycles) { register byte I; register pair J; for(R->ICount=RunCycles;;) { while(R->ICount>0) { #ifdef DEBUG /* Turn tracing on when reached trap address */ if(R->PC.W==R->Trap) R->Trace=1; /* Call single-step debugger, exit if requested */ if(R->Trace) if(!DebugZ80(R)) return(R->ICount); #endif /* Read opcode and count cycles */ I=OpZ80(R->PC.W++); /* Count cycles */ R->ICount-=Cycles[I]; /* Interpret opcode */ switch(I) { #include "Codes.h" case PFX_CB: CodesCB(R);break; case PFX_ED: CodesED(R);break; case PFX_FD: CodesFD(R);break; case PFX_DD: CodesDD(R);break; } /* Unless we have come here after EI, exit */ if(!(R->IFF&IFF_EI)) { /* Interrupt CPU if needed */ if((R->IRequest!=INT_NONE)&&(R->IRequest!=INT_QUIT)) IntZ80(R,R->IRequest); } else { /* Done with AfterEI state */ R->IFF=(R->IFF&~IFF_EI)|IFF_1; /* Restore the ICount */ R->ICount+=R->IBackup-1; } } return(R->ICount); } }
void Z80_irq(void) { Z80_regs.IFF |= IFF_1; IntZ80(&Z80_regs, INT_IRQ); }
void Z80_nmi(void) { IntZ80(&Z80_regs, INT_NMI); }
word RunZ80(Z80 *R) { register byte I; register pair J; for(;;) { #ifdef DEBUG /* Turn tracing on when reached trap address */ if(R->PC.W==R->Trap) R->Trace=1; /* Call single-step debugger, exit if requested */ if(R->Trace) if(!DebugZ80(R)) return(R->PC.W); #endif I=OpZ80(R->PC.W++); R->ICount-=Cycles[I]; switch(I) { #include "Codes.h" case PFX_CB: CodesCB(R);break; case PFX_ED: CodesED(R);break; case PFX_FD: CodesFD(R);break; case PFX_DD: CodesDD(R);break; } /* Nascom Single Step ; activate nmi push af ld a,8 out (0),a pop af ; execute one step of program retn after out skip pop,retn and one user program opcode before forcing NMI */ byte skip; if (R->Trap) { if (skip++==3) { skip=0; R->Trap=0; IntZ80(R,INT_NMI); } } /* If cycle counter expired... */ if(R->ICount<=0) { /* If we have come after EI, get address from IRequest */ /* Otherwise, get it from the loop handler */ if(R->IFF&IFF_EI) { R->IFF=(R->IFF&~IFF_EI)|IFF_1; /* Done with AfterEI state */ R->ICount+=R->IBackup-1; /* Restore the ICount */ /* Call periodic handler or set pending IRQ */ if(R->ICount>0) J.W=R->IRequest; else { J.W=LoopZ80(R); /* Call periodic handler */ R->ICount+=R->IPeriod; /* Reset the cycle counter */ if(J.W==INT_NONE) J.W=R->IRequest; /* Pending IRQ */ } } else { J.W=LoopZ80(R); /* Call periodic handler */ R->ICount+=R->IPeriod; /* Reset the cycle counter */ if(J.W==INT_NONE) J.W=R->IRequest; /* Pending IRQ */ } if(J.W==INT_QUIT) return(R->PC.W); /* Exit if INT_QUIT */ if(J.W!=INT_NONE) IntZ80(R,J.W); /* Int-pt if needed */ } } /* Execution stopped */ return(R->PC.W); }