/* 
   Pcm: a PC eMulator
   Copyright (C) 1992 Electronetics, Inc.  All rights reserved.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * routines to interpret jmp, call/ret instructions
 */
#include "sim.h"

unsigned char *i_70(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (OVERFLOW) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_71(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (!OVERFLOW) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_72(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (CARRY) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_73(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (!CARRY) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_74(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (ZERO) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_75(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (!ZERO) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_76(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (CARRY || ZERO) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_77(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (!(CARRY || ZERO)) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_78(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (SIGN) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_79(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (!SIGN) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_7a(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (PARITY) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_7b(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (!PARITY) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_7c(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (SIGN != OVERFLOW) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_7d(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (SIGN == OVERFLOW) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_7e(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (ZERO || SIGN != OVERFLOW) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_7f(pc)
unsigned char *pc; {
  short offset;
  compute_flags();
  offset = *(char *)pc++;
  if (!ZERO && SIGN == OVERFLOW) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_9a(pc)
unsigned char *pc; {
  unsigned short opr, offset;
  *(SSPTR+--SP) = CSH;
  *(SSPTR+--SP) = CSL;
  opr = *pc++;
  opr |= ((unsigned int)*pc++) << 8;
  CSL = *pc++;
  CSH = *pc++;
  offset = pc - CSPTR;
  *(SSPTR+--SP) = offset >> 8;
  *(SSPTR+--SP) = offset;
  CSPTR = pc_mem + ((unsigned int)CS << 4);
  return pc = CSPTR + opr;
}

unsigned char *i_c2(pc)
unsigned char *pc; {
  unsigned short offset;
  LOADW2(offset,(SSPTR+SP++));
  SP += *pc++;
  SPH += *pc++;
  return CSPTR + offset;
}

unsigned char *i_c3(pc)
unsigned char *pc; {
  unsigned short offset;
  LOADW2(offset,(SSPTR+SP++));
  return CSPTR + offset;
}

unsigned char *i_ca(pc)
unsigned char *pc; {
  unsigned short offset, opr;
  LOADW2(opr,pc++);
  offset = *(SSPTR+SP++);
  offset |= ((unsigned int)*(SSPTR+SP++) << 8);
  CSL = *(SSPTR+SP++);
  CSH = *(SSPTR+SP++);
  CSPTR = pc_mem + ((unsigned int)CS << 4);
  SP += opr;
  return CSPTR + offset;
}

unsigned char *i_cb(pc)
unsigned char *pc; {
  unsigned short offset, opr;
  offset = *(SSPTR+SP++);
  offset |= ((unsigned int)*(SSPTR+SP++) << 8);
  CSL = *(SSPTR+SP++);
  CSH = *(SSPTR+SP++);
  CSPTR = pc_mem + ((unsigned int)CS << 4);
  return CSPTR + offset;
}

unsigned char *i_e0(pc)
unsigned char *pc; {
  short offset;
  offset = *(char *)pc++;
  compute_flags();
  if (--CX && !ZERO) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_e1(pc)
unsigned char *pc; {
  short offset;
  offset = *(char *)pc++;
  compute_flags();
  if (--CX && ZERO) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_e2(pc)
unsigned char *pc; {
  short offset;
  offset = *(char *)pc++;
  if (--CX) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_e3(pc)
unsigned char *pc; {
  short offset;
  offset = *(char *)pc++;
  if (CX == 0) {
    return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
  }
  return pc;
}

unsigned char *i_e8(pc)
unsigned char *pc; {
  unsigned short offset;
  offset = (unsigned short)(pc - CSPTR) + 2;
  *(SSPTR+--SP) = offset >> 8;
  *(SSPTR+--SP) = offset;
  LOADW2(offset,pc++);
  return CSPTR + (unsigned short)((pc - CSPTR) + offset);
}

unsigned char *i_e9(pc)
unsigned char *pc; {
  unsigned short offset;
  LOADW2(offset,pc++);
  return CSPTR + (unsigned short)((pc - CSPTR) + offset);
}

unsigned char *i_ea(pc)
unsigned char *pc; {
  short offset, seg;
  LOADW2(offset, pc++);
  CSL = *pc++;
  CSH = *pc++;
  CSPTR = pc_mem + ((unsigned int)CS << 4);
  return CSPTR + offset;
}

unsigned char *i_eb(pc)
unsigned char *pc; {
  short offset;
  offset = *(char *)pc++;
  return CSPTR + (unsigned short)((short)(pc - CSPTR) + offset);
}
