Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
  }
}
Ejemplo n.º 3
0
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);
}