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