Пример #1
0
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FCMOV_ST0_STj(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareFPU(i);
  BX_CPU_THIS_PTR FPU_update_last_instruction(i);

  if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm()))
  {
     FPU_stack_underflow(0);
     BX_NEXT_INSTR(i);
  }

  floatx80 sti_reg = BX_READ_FPU_REG(i->rm());

  bx_bool condition = 0;
  switch(i->nnn() & 3)
  {
     case 0: condition = get_CF(); break;
     case 1: condition = get_ZF(); break;
     case 2: condition = get_CF() || get_ZF(); break;
     case 3: condition = get_PF(); break;
     default:
        BX_PANIC(("FCMOV_ST0_STj: default case"));
  }
  if (i->b1() & 1)
     condition = !condition;

  if (condition)
     BX_WRITE_FPU_REG(sti_reg, 0);

  BX_NEXT_INSTR(i);
}
Пример #2
0
Файл: bcd.cpp Проект: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::DAS(bxInstruction_c *i)
{
  /* The algorithm for DAS is fashioned after the pseudo code in the
   * Pentium Processor Family Developer's Manual, volume 3.  It seems
   * to have changed from earlier processor's manuals.  I'm not sure
   * if this is a correction in the algorithm printed, or Intel has
   * changed the handling of instruction. Validated against Intel
   * Pentium family hardware.
   */

  Bit8u tmpAL = AL;
  int tmpCF = 0, tmpAF = 0;

  /* DAS effect the following flags: A,C,S,Z,P */

  if (((tmpAL & 0x0F) > 0x09) || get_AF())
  {
    tmpCF = (AL < 0x06) || get_CF();
    AL = AL - 0x06;
    tmpAF = 1;
  }

  if ((tmpAL > 0x99) || get_CF())
  {
    AL = AL - 0x60;
    tmpCF = 1;
  }

  SET_FLAGS_OSZAPC_LOGIC_8(AL);
  set_CF(tmpCF);
  set_AF(tmpAF);

  BX_NEXT_INSTR(i);
}
Пример #3
0
Файл: bcd.cpp Проект: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::DAA(bxInstruction_c *i)
{
  Bit8u tmpAL = AL;
  int   tmpCF = 0, tmpAF = 0;

  /* Validated against Intel Pentium family hardware. */

  // DAA affects the following flags: S,Z,A,P,C

  if (((tmpAL & 0x0F) > 0x09) || get_AF())
  {
    tmpCF = ((AL > 0xF9) || get_CF());
    AL = AL + 0x06;
    tmpAF = 1;
  }

  if ((tmpAL > 0x99) || get_CF())
  {
    AL = AL + 0x60;
    tmpCF = 1;
  }

  SET_FLAGS_OSZAPC_LOGIC_8(AL);
  set_CF(tmpCF);
  set_AF(tmpAF);

  BX_NEXT_INSTR(i);
}
Пример #4
0
  void
bx_cpu_c::JCC_Jd(BxInstruction_t *i)
{
  Boolean condition = 0;

  switch (i->b1 & 0x0f) {
    case 0x00: /* JO */ condition = get_OF(); break;
    case 0x01: /* JNO */ condition = !get_OF(); break;
    case 0x02: /* JB */ condition = get_CF(); break;
    case 0x03: /* JNB */ condition = !get_CF(); break;
    case 0x04: /* JZ */ condition = get_ZF(); break;
    case 0x05: /* JNZ */ condition = !get_ZF(); break;
    case 0x06: /* JBE */ condition = get_CF() || get_ZF(); break;
    case 0x07: /* JNBE */ condition = !get_CF() && !get_ZF(); break;
    case 0x08: /* JS */ condition = get_SF(); break;
    case 0x09: /* JNS */ condition = !get_SF(); break;
    case 0x0A: /* JP */ condition = get_PF(); break;
    case 0x0B: /* JNP */ condition = !get_PF(); break;
    case 0x0C: /* JL */ condition = get_SF() != get_OF(); break;
    case 0x0D: /* JNL */ condition = get_SF() == get_OF(); break;
    case 0x0E: /* JLE */ condition = get_ZF() || (get_SF() != get_OF());
      break;
    case 0x0F: /* JNLE */ condition = (get_SF() == get_OF()) &&
                            !get_ZF();
      break;
    }

  if (condition) {
    Bit32u new_EIP;

    new_EIP = EIP + (Bit32s) i->Id;
#if BX_CPU_LEVEL >= 2
    if (protected_mode()) {
      if ( new_EIP > bx_cpu. sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
        BX_PANIC(("jo_routine: offset outside of CS limits"));
        exception(BX_GP_EXCEPTION, 0, 0);
        }
      }
#endif
    EIP = new_EIP;
    BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
    revalidate_prefetch_q();
    }
#if BX_INSTRUMENTATION
  else {
    BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
    }
#endif
}
Пример #5
0
void BX_CPU_C::CMOV_GdEd(bxInstruction_c *i)
{
#if (BX_CPU_LEVEL >= 6) || (BX_CPU_LEVEL_HACKED >= 6)
  // Note: CMOV accesses a memory source operand (read), regardless
  //       of whether condition is true or not.  Thus, exceptions may
  //       occur even if the MOV does not take place.

  bx_bool condition = 0;
  Bit32u op2_32;

  switch (i->b1()) {
    // CMOV opcodes:
    case 0x140: condition = get_OF(); break;
    case 0x141: condition = !get_OF(); break;
    case 0x142: condition = get_CF(); break;
    case 0x143: condition = !get_CF(); break;
    case 0x144: condition = get_ZF(); break;
    case 0x145: condition = !get_ZF(); break;
    case 0x146: condition = get_CF() || get_ZF(); break;
    case 0x147: condition = !get_CF() && !get_ZF(); break;
    case 0x148: condition = get_SF(); break;
    case 0x149: condition = !get_SF(); break;
    case 0x14A: condition = get_PF(); break;
    case 0x14B: condition = !get_PF(); break;
    case 0x14C: condition = getB_SF() != getB_OF(); break;
    case 0x14D: condition = getB_SF() == getB_OF(); break;
    case 0x14E: condition = get_ZF() || (getB_SF() != getB_OF()); break;
    case 0x14F: condition = !get_ZF() && (getB_SF() == getB_OF()); break;
    default:
      BX_PANIC(("CMOV_GdEd: default case"));
  }

  if (i->modC0()) {
    op2_32 = BX_READ_32BIT_REG(i->rm());
  }
  else {
    /* pointer, segment address pair */
    read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
  }

  if (condition) {
    BX_WRITE_32BIT_REGZ(i->nnn(), op2_32);
  }
  BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
#else
  BX_INFO(("CMOV_GdEd: -enable-cpu-level=6 required"));
  UndefinedOpcode(i);
#endif
}
Пример #6
0
  void
bx_cpu_c::ADC_EbIb(BxInstruction_t *i)
{
  Bit8u op2, op1, sum;
  Boolean temp_CF;

  temp_CF = get_CF();

  op2 = i->Ib;

  /* op1 is a register or memory reference */
  if (i->mod == 0xc0) {
    op1 = BX_READ_8BIT_REG(i->rm);
    }
  else {
    /* pointer, segment address pair */
    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
    }

  sum = op1 + op2 + temp_CF;

  /* now write sum back to destination */
  if (i->mod == 0xc0) {
    BX_WRITE_8BIT_REG(i->rm, sum);
    }
  else {
    write_RMW_virtual_byte(sum);
    }

  SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
                           temp_CF);
}
Пример #7
0
  void
bx_cpu_c::SBB_EbIb(BxInstruction_t *i)
{
  Bit8u op2_8, op1_8, diff_8;
  Boolean temp_CF;

  temp_CF = get_CF();

  op2_8 = i->Ib;

  /* op1_8 is a register or memory reference */
  if (i->mod == 0xc0) {
    op1_8 = BX_READ_8BIT_REG(i->rm);
    }
  else {
    /* pointer, segment address pair */
    read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
    }

  diff_8 = op1_8 - (op2_8 + temp_CF);

  /* now write diff back to destination */
  if (i->mod == 0xc0) {
    BX_WRITE_8BIT_REG(i->rm, diff_8);
    }
  else {
    write_RMW_virtual_byte(diff_8);
    }

  SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
                           temp_CF);
}
Пример #8
0
  void
bx_cpu_c::SBB_GbEb(BxInstruction_t *i)
{
  Bit8u op1_8, op2_8, diff_8;
  Boolean temp_CF;

  temp_CF = get_CF();


  /* op1 is a register, i->rm_addr is an index of a register */
  op1_8 = BX_READ_8BIT_REG(i->nnn);

  /* op2 is a register or memory reference */
  if (i->mod == 0xc0) {
    op2_8 = BX_READ_8BIT_REG(i->rm);
    }
  else {
    /* pointer, segment address pair */
    read_virtual_byte(i->seg, i->rm_addr, &op2_8);
    }

  diff_8 = op1_8 - (op2_8 + temp_CF);

  /* now write diff back to destination, which is a register */
  BX_WRITE_8BIT_REG(i->nnn, diff_8);

  SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
                           temp_CF);
}
Пример #9
0
  void
bx_cpu_c::ADC_GbEb(BxInstruction_t *i)
{
  Bit8u op1, op2, sum;
  Boolean temp_CF;

  temp_CF = get_CF();


  /* op1 is a register, i->rm_addr is an index of a register */
  op1 = BX_READ_8BIT_REG(i->nnn);

  /* op2 is a register or memory reference */
  if (i->mod == 0xc0) {
    op2 = BX_READ_8BIT_REG(i->rm);
    }
  else {
    /* pointer, segment address pair */
    read_virtual_byte(i->seg, i->rm_addr, &op2);
    }

  sum = op1 + op2 + temp_CF;

  SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
                           temp_CF);

  /* now write sum back to destination, which is a register */
  BX_WRITE_8BIT_REG(i->nnn, sum);
}
Пример #10
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNBE_GwEwR(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 6
  if (! (get_CF() || get_ZF()))
    BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
#else
  BX_INFO(("CMOVNBE_GwEw: --enable-cpu-level=6 required"));
  UndefinedOpcode(i);
#endif
}
Пример #11
0
Bitu FillFlags(void) {
//	if (lflags.type==t_UNKNOWN) return reg_flags;
	Bitu new_word=(reg_flags & ~FLAG_MASK);
	if (get_CF()) new_word|=FLAG_CF;
	if (get_PF()) new_word|=FLAG_PF;
	if (get_AF()) new_word|=FLAG_AF;
	if (get_ZF()) new_word|=FLAG_ZF;
	if (get_SF()) new_word|=FLAG_SF;
	if (get_OF()) new_word|=FLAG_OF;
	reg_flags=new_word;
	lflags.type=t_UNKNOWN;
	return reg_flags;
}
Пример #12
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNBE_GwEwM(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 6
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  Bit16u op2_16 = read_virtual_word(i->seg(), RMAddr(i));

  if (! (get_CF() || get_ZF()))
    BX_WRITE_16BIT_REG(i->nnn(), op2_16);
#else
  BX_INFO(("CMOVNBE_GwEw: --enable-cpu-level=6 required"));
  UndefinedOpcode(i);
#endif
}
Пример #13
0
void BX_CPU_C::SETNB_Eb(bxInstruction_c *i)
{
  Bit8u result_8;

  if (get_CF()==0)
    result_8 = 1;
  else
    result_8 = 0;

  /* now write result back to destination */
  if (i->modC0()) {
    BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
  }
  else {
    write_virtual_byte(i->seg(), RMAddr(i), &result_8);
  }
}
Пример #14
0
  void
bx_cpu_c::SBB_ALIb(BxInstruction_t *i)
{
  Bit8u op1_8, op2_8, diff_8;
  Boolean temp_CF;

  temp_CF = get_CF();


  op1_8 = AL;

  op2_8 = i->Ib;

  diff_8 = op1_8 - (op2_8 + temp_CF);

  /* now write diff back to destination, which is a register */
  AL = diff_8;

  SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
                           temp_CF);
}
Пример #15
0
  void
bx_cpu_c::ADC_ALIb(BxInstruction_t *i)
{
  Bit8u op1, op2, sum;
  Boolean temp_CF;

  temp_CF = get_CF();


  op1 = AL;

  op2 = i->Ib;

  sum = op1 + op2 + temp_CF;

  /* now write sum back to destination, which is a register */
  AL = sum;

  SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
                           temp_CF);
}
Пример #16
0
  void
bx_cpu_c::SETB_Eb(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
  BX_PANIC(("SETB: not available on < 386"));
#else
  Bit8u result_8;


  if (get_CF())
    result_8 = 1;
  else
    result_8 = 0;

  /* now write result back to destination */
  if (i->mod == 0xc0) {
    BX_WRITE_8BIT_REG(i->rm, result_8);
    }
  else {
    write_virtual_byte(i->seg, i->rm_addr, &result_8);
    }
#endif
}