/* 
   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.
 */

/*
 * Instructions that manipulate the stack
 */
#include "sim.h"

unsigned char *i_06(pc) /* push es */
unsigned char *pc; {
  *(SSPTR+--SP) = ESH;
  *(SSPTR+--SP) = ESL;
  return pc;
}

unsigned char *i_07(pc) /* pop es */
unsigned char *pc; {
  ESL = *(SSPTR+SP++);
  ESH = *(SSPTR+SP++);
  SETES;
  return pc;
}

unsigned char *i_0e(pc) /* push cs */
unsigned char *pc; {
  *(SSPTR+--SP) = CSH;
  *(SSPTR+--SP) = CSL;
  return pc;
}

unsigned char *i_16(pc) /* push ss */
unsigned char *pc; {
  *(SSPTR+--SP) = SSH;
  *(SSPTR+--SP) = SSL;
  return pc;
}

unsigned char *i_17(pc) /* pop ss */
unsigned char *pc; {
  SSL = *(SSPTR+SP++);
  SSH = *(SSPTR+SP++);
  SETSS;
  return pc;
}


unsigned char *i_1e(pc) /* push ds */
unsigned char *pc; {
  *(SSPTR+--SP) = DSH;
  *(SSPTR+--SP) = DSL;
  return pc;
}

unsigned char *i_1f(pc) /* pop ds */
unsigned char *pc; {
  DSL = *(SSPTR+SP++);
  DSH = *(SSPTR+SP++);
  SETDS;
  return pc;
}

unsigned char *i_50(pc) /* push ax */
unsigned char *pc; {
  *(SSPTR+--SP) = AH;
  *(SSPTR+--SP) = AL;
  return pc;
}

unsigned char *i_51(pc) /* push cx */
unsigned char *pc; {
  *(SSPTR+--SP) = CH;
  *(SSPTR+--SP) = CL;
  return pc;
}

unsigned char *i_52(pc) /* push dx */
unsigned char *pc; {
  *(SSPTR+--SP) = DH;
  *(SSPTR+--SP) = DL;
  return pc;
}

unsigned char *i_53(pc) /* push bx */
unsigned char *pc; {
  *(SSPTR+--SP) = BH;
  *(SSPTR+--SP) = BL;
  return pc;
}

unsigned char *i_54(pc) /* push sp */
unsigned char *pc; {
/*
 * Do it 8086 style, push new sp
 */
  SP -= 2;
  *(SSPTR+(SP+1)) = SPH;
  *(SSPTR+SP) = SPL;
  return pc;
}

unsigned char *i_55(pc) /* push bp */
unsigned char *pc; {
  *(SSPTR+--SP) = BPH;
  *(SSPTR+--SP) = BPL;
  return pc;
}

unsigned char *i_56(pc) /* push si */
unsigned char *pc; {
  *(SSPTR+--SP) = SIH;
  *(SSPTR+--SP) = SIL;
  return pc;
}

unsigned char *i_57(pc) /* push di */
unsigned char *pc; {
  *(SSPTR+--SP) = DIH;
  *(SSPTR+--SP) = DIL;
  return pc;
}

unsigned char *i_58(pc) /* pop ax */
unsigned char *pc; {
  AL = *(SSPTR+SP++);
  AH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_59(pc) /* pop cx */
unsigned char *pc; {
  CL = *(SSPTR+SP++);
  CH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_5a(pc) /* pop dx */
unsigned char *pc; {
  DL = *(SSPTR+SP++);
  DH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_5b(pc) /* pop bx */
unsigned char *pc; {
  BL = *(SSPTR+SP++);
  BH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_5c(pc) /* pop sp */
unsigned char *pc; {
  unsigned short old_sp = SP;
  SPL = *(SSPTR+old_sp++);
  SPH = *(SSPTR+old_sp);
  return pc;
}

unsigned char *i_5d(pc) /* pop bp */
unsigned char *pc; {
  BPL = *(SSPTR+SP++);
  BPH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_5e(pc) /* pop si */
unsigned char *pc; {
  SIL = *(SSPTR+SP++);
  SIH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_5f(pc) /* pop di */
unsigned char *pc; {
  DIL = *(SSPTR+SP++);
  DIH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_8f(pc)
unsigned char *pc; {
  pc = word_operand(pc);
  *EAPTRL = *(SSPTR+SP++);
  *EAPTRH = *(SSPTR+SP++);
  return pc;
}

unsigned char *i_9c(pc) /* pushf */
unsigned char *pc; {
  compute_flags();
  putflags();
  *(SSPTR+--SP) = flagshort >> 8;
  *(SSPTR+--SP) = flagshort;
  return pc;
}

unsigned char *i_9d(pc) /* popf */
unsigned char *pc; {
  flagshort = *(SSPTR+SP++);
  flagshort |= ((unsigned int)*(SSPTR+SP++) << 8);
  getflags();
  return pc;
}


