int32_t instr_movsb(struct emu_cpu *c, struct emu_cpu_instruction *i) { if (i->prefixes & PREFIX_OPSIZE ) { UNIMPLEMENTED(c, SST); } if (i->prefixes & PREFIX_F3 || i->prefixes & PREFIX_F2) { /* Copy ECX bytes from DS:[ESI] to ES:[EDI] */ if (c->reg[ecx] > 0 ) { uint8_t tmp; c->reg[ecx]--; c->repeat_current_instr = true; MEM_BYTE_READ(c, c->reg[esi], &tmp); MEM_BYTE_WRITE(c, c->reg[edi], tmp); if ( !CPU_FLAG_ISSET(c,f_df) ) { /* increment */ c->reg[edi] += 1; c->reg[esi] += 1; } else { /* decrement */ c->reg[edi] -= 1; c->reg[esi] -= 1; } } else{ c->repeat_current_instr = false; } } else { /* a4 move ds:esi -> es->edi */ uint8_t tmp; MEM_BYTE_READ(c, c->reg[esi], &tmp); MEM_BYTE_WRITE(c, c->reg[edi], tmp); if ( !CPU_FLAG_ISSET(c,f_df) ) { /* increment */ c->reg[edi] += 1; c->reg[esi] += 1; } else { /* decrement */ c->reg[edi] -= 1; c->reg[esi] -= 1; } } return 0; }
int32_t instr_group_2_c0_shr(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* C0 /5 ib * Unsigned divide r/m8 by 2, imm8 times * SHR r/m8,imm8 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, m8, *i->imm8); MEM_BYTE_WRITE(c, i->modrm.ea, m8); } else { /* C0 /5 ib * Unsigned divide r/m8 by 2, imm8 times * SHR r/m8,imm8 */ INSTR_CALC_AND_SET_FLAGS(8, c, *c->reg8[i->modrm.rm], *i->imm8); } return 0; }
int32_t instr_group_3_f6_not(struct emu_cpu *c, struct emu_cpu_instruction *i) { if (i->modrm.mod != 3) { /* F6 /2 * Reverse each bit of r/m8 * NOT r/m8 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, m8) MEM_BYTE_WRITE(c, i->modrm.ea, m8); } else { /* F6 /2 * Reverse each bit of r/m8 * NOT r/m8 */ INSTR_CALC_AND_SET_FLAGS(8,c,*c->reg8[i->modrm.rm]); } return 0; }
int32_t instr_group_2_c0_rcl(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* C0 /2 ib * Rotate nine bits (CF,r/m8) left imm8 times * RCL r/m8,imm8 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, m8, *i->imm8); MEM_BYTE_WRITE(c, i->modrm.ea, m8); } else { /* C0 /2 ib * Rotate nine bits (CF,r/m8) left imm8 times * RCL r/m8,imm8 */ INSTR_CALC_AND_SET_FLAGS(8, c, *c->reg8[i->modrm.rm], *i->imm8); } return 0; }
int32_t instr_group_3_f6_neg(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* F6 /3 * Two's complement negate r/m8 * NEG r/m8 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, m8) MEM_BYTE_WRITE(c, i->modrm.ea, m8); } else { /* F6 /3 * Two's complement negate r/m8 * NEG r/m8 */ INSTR_CALC_AND_SET_FLAGS(8,c,*c->reg8[i->modrm.rm]); } return 0; }
int32_t instr_group_2_d2_sal(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* D2 /4 * Multiply r/m8 by 2, CL times * SAL r/m8,CL */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, m8, *c->reg8[cl]); MEM_BYTE_WRITE(c, i->modrm.ea, m8); } else { /* D2 /4 * Multiply r/m8 by 2, CL times * SAL r/m8,CL */ INSTR_CALC_AND_SET_FLAGS(8, c, *c->reg8[i->modrm.rm], *c->reg8[cl]); } return 0; }
int32_t instr_group_2_d0_sar(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* D0 /7 * Signed divide* r/m8 by 2, once * SAR r/m8,1 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, m8, 1); MEM_BYTE_WRITE(c, i->modrm.ea, m8); } else { /* D0 /7 * Signed divide* r/m8 by 2, once * SAR r/m8,1 */ INSTR_CALC_AND_SET_FLAGS(8, c, *c->reg8[i->modrm.rm], 1); } return 0; }
int32_t instr_group_2_d2_rcr(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* D2 /3 * Rotate nine bits (CF,r/m8) right CL times * RCR r/m8,CL */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, m8, *c->reg8[cl]); MEM_BYTE_WRITE(c, i->modrm.ea, m8); } else { /* D2 /3 * Rotate nine bits (CF,r/m8) right CL times * RCR r/m8,CL */ INSTR_CALC_AND_SET_FLAGS(8, c, *c->reg8[i->modrm.rm], *c->reg8[cl]); } return 0; }
int32_t instr_mov_a2(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* A2 * Move AL to (seg:offset) * MOV moffs8*,AL */ MEM_BYTE_WRITE(c, i->imm, *c->reg8[al]); return 0; }
int32_t instr_mov_88(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* 88 /r * Move r8 to r/m8 * MOV r/m8,r8 */ if( i->modrm.mod != 3 ) { MEM_BYTE_WRITE(c, i->modrm.ea, *c->reg8[i->modrm.opc]); } else { *c->reg8[i->modrm.rm] = *c->reg8[i->modrm.opc]; } return 0; }
int32_t instr_mov_c6(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* C6 /0 * Move imm8 to r/m8 * MOV r/m8,imm8 */ if( i->modrm.mod != 3 ) { MEM_BYTE_WRITE(c, i->modrm.ea, *i->imm8); } else { *c->reg8[i->modrm.rm] = *i->imm8; } return 0; }
int32_t instr_xor_30(struct emu_cpu *c, struct emu_cpu_instruction *i) { ////TRACK_INIT_ALL_FLAGS(c->instr); /* 30 /r * r/m8 XOR r8 * XOR r/m8,r8 */ if ( i->modrm.mod != 3 ) { uint8_t dst; MEM_BYTE_READ(c, i->modrm.ea, &dst); INSTR_CALC_AND_SET_FLAGS(8, c, dst, *c->reg8[i->modrm.opc], dst, ^) MEM_BYTE_WRITE(c, i->modrm.ea, dst); }
int32_t instr_sbb_18(struct emu_cpu *c, struct emu_cpu_instruction *i) { TRACK_INIT_ALL_FLAGS(c->instr); /* 18 /r * Subtract with borrow r8 from r/m8 * SBB r/m8,r8 */ if ( i->modrm.mod != 3 ) { uint8_t dst; MEM_BYTE_READ(c, i->modrm.ea, &dst); INSTR_CALC_AND_SET_FLAGS(8, c, dst, *c->reg8[i->modrm.opc], dst, -) MEM_BYTE_WRITE(c, i->modrm.ea, dst); }
int32_t instr_group_4_fe_inc(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* FE /0 * INC r/m8 * Increment r/m byte by 1 */ if ( i->modrm.mod != 3 ) { uint8_t dst; MEM_BYTE_READ(c, i->modrm.ea, &dst); INSTR_CALC_AND_SET_FLAGS(8, c, dst) MEM_BYTE_WRITE(c, i->modrm.ea, dst); } else { INSTR_CALC_AND_SET_FLAGS(8, c, *c->reg8[i->modrm.rm]) } return 0; }