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); } }
word ExecZ80(Z80 *R) { register byte I; register pair J; 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; } /* We are done */ return(R->PC.W); }
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); }
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); }