int32_t instr_group_5_ff_inc(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { if ( i->prefixes & PREFIX_OPSIZE ) { /* FF /0 * Increment r/m word by 1 * INC r/m16 */ uint16_t dst; MEM_WORD_READ(c, i->modrm.ea, &dst); INSTR_CALC_AND_SET_FLAGS(16, c, dst) MEM_WORD_WRITE(c, i->modrm.ea, dst); } else { /* FF /0 * Increment r/m doubleword by 1 * INC r/m32 */ uint32_t dst; MEM_DWORD_READ(c, i->modrm.ea, &dst); INSTR_CALC_AND_SET_FLAGS(32, c, dst) MEM_DWORD_WRITE(c, i->modrm.ea, dst); } } else { if ( i->prefixes & PREFIX_OPSIZE ) { /* FF /0 * Increment r/m word by 1 * INC r/m16 */ INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm]) } else { /* FF /0 * Increment r/m doubleword by 1 * INC r/m32 */ INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm]) } } return 0; }
//dzzie 5.19.11 - http://pdos.csail.mit.edu/6.828/2004/readings/i386/MOVS.htm int32_t instr_movs_a5(struct emu_cpu *c, struct emu_cpu_instruction *i) { if (i->prefixes & PREFIX_ADSIZE ) { UNIMPLEMENTED(c, SST); return 0; } uint8_t incSize = 0; if ( i->prefixes & PREFIX_OPSIZE ) //16bit { uint16_t tmp; MEM_WORD_READ(c, c->reg[esi], &tmp); MEM_WORD_WRITE(c, c->reg[edi], tmp); incSize = 2; } else{ //32bit uint32_t tmp2; MEM_DWORD_READ(c, c->reg[esi], &tmp2); MEM_DWORD_WRITE(c, c->reg[edi], tmp2); incSize = 4; } if (i->prefixes & PREFIX_F3) /* rep prefix - Copy ECX bytes from DS:[ESI] to ES:[EDI] */ { c->repeat_current_instr = false; if (c->reg[ecx] > 0 ){ c->reg[ecx]--; c->repeat_current_instr = true; }else{ return 0; //rep operation complete..do not adjust registers any more } } if ( !CPU_FLAG_ISSET(c,f_df) ){ /* increment */ c->reg[edi] += incSize; c->reg[esi] += incSize; } else{ /* decrement */ c->reg[edi] -= incSize; c->reg[esi] -= incSize; } return 0; }
int32_t instr_mov_89(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* 89 /r * Move r16 to r/m16 * MOV r/m16,r16 */ /* 89 /r * Move r32 to r/m32 * MOV r/m32,r32 */ if( i->prefixes & PREFIX_OPSIZE ) { if( i->modrm.mod != 3 ) { MEM_WORD_WRITE(c, i->modrm.ea, *c->reg16[i->modrm.opc]); } else { *c->reg16[i->modrm.rm] = *c->reg16[i->modrm.opc]; } } else { if( i->modrm.mod != 3 ) { MEM_DWORD_WRITE(c, i->modrm.ea, c->reg[i->modrm.opc]); } else { c->reg[i->modrm.rm] = c->reg[i->modrm.opc]; //TRACK_NEED_REG32(c->instr, i->modrm.opc); //TRACK_INIT_REG32(c->instr, i->modrm.rm); } } return 0; }
int32_t instr_mov_c7(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* C7 /0 * Move imm16 to r/m16 * MOV r/m16,imm16 */ /* C7 /0 * Move imm32 to r/m32 * MOV r/m32,imm32 */ if( i->prefixes & PREFIX_OPSIZE ) { if( i->modrm.mod != 3 ) { MEM_WORD_WRITE(c, i->modrm.ea, *i->imm16); } else { #if BYTE_ORDER == BIG_ENDIAN bcopy(i->imm16, c->reg16[i->modrm.rm], 2); #else *c->reg16[i->modrm.rm] = *i->imm16; #endif } } else { if( i->modrm.mod != 3 ) { MEM_DWORD_WRITE(c, i->modrm.ea, i->imm); } else { c->reg[i->modrm.rm] = i->imm; } } return 0; }
int32_t instr_mov_a3(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->prefixes & PREFIX_OPSIZE ) { /* A3 * Move AX to (seg:offset) * MOV moffs16*,AX */ MEM_WORD_WRITE(c, i->imm, *c->reg16[ax]); } else { /* A3 * Move EAX to (seg:offset) * MOV moffs32*,EAX */ MEM_DWORD_WRITE(c, i->imm, c->reg[eax]); } return 0; }
int32_t instr_group_2_d3_shr(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { if ( i->prefixes & PREFIX_OPSIZE ) { /* D3 /5 * Unsigned divide r/m16 by 2, CL times * SHR r/m16,CL */ uint16_t m16; MEM_WORD_READ(c, i->modrm.ea, &m16); INSTR_CALC_AND_SET_FLAGS(16, c, m16, *c->reg8[cl]); MEM_WORD_WRITE(c, i->modrm.ea, m16); } else { /* D3 /5 * Unsigned divide r/m32 by 2, CL times * SHR r/m32,CL */ uint32_t m32; MEM_DWORD_READ(c, i->modrm.ea, &m32); INSTR_CALC_AND_SET_FLAGS(32, c, m32, *c->reg8[cl]); MEM_DWORD_WRITE(c, i->modrm.ea, m32); } } else { if ( i->prefixes & PREFIX_OPSIZE ) { /* D3 /5 * Unsigned divide r/m16 by 2, CL times * SHR r/m16,CL */ INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm], *c->reg8[cl]); } else { /* D3 /5 * Unsigned divide r/m32 by 2, CL times * SHR r/m32,CL */ INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm], *c->reg8[cl]); } } return 0; }
int32_t instr_group_3_f7_not(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { if ( i->prefixes & PREFIX_OPSIZE ) { /* F7 /2 * Reverse each bit of r/m16 * NOT r/m16 */ uint16_t m16; MEM_WORD_READ(c, i->modrm.ea, &m16); INSTR_CALC_AND_SET_FLAGS(16, c, m16) MEM_WORD_WRITE(c, i->modrm.ea, m16); } else { /* F7 /2 * Reverse each bit of r/m32 * NOT r/m32 */ uint32_t m32; MEM_DWORD_READ(c, i->modrm.ea, &m32); INSTR_CALC_AND_SET_FLAGS(32, c, m32) MEM_DWORD_WRITE(c, i->modrm.ea, m32); } } else { if ( i->prefixes & PREFIX_OPSIZE ) { /* F7 /2 * Reverse each bit of r/m16 * NOT r/m16 */ INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm]) } else { /* F7 /2 * Reverse each bit of r/m32 * NOT r/m32 */ INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm]) } } return 0; }
int32_t instr_group_2_d3_rcl(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { if ( i->prefixes & PREFIX_OPSIZE ) { /* D3 /2 * Rotate 17 bits (CF,r/m16) left CL times * RCL r/m16,CL */ uint16_t m16; MEM_WORD_READ(c, i->modrm.ea, &m16); INSTR_CALC_AND_SET_FLAGS(16, c, m16, *c->reg8[cl]); MEM_WORD_WRITE(c, i->modrm.ea, m16); } else { /* D3 /2 * Rotate 33 bits (CF,r/m32) left CL times * RCL r/m32,CL */ uint32_t m32; MEM_DWORD_READ(c, i->modrm.ea, &m32); INSTR_CALC_AND_SET_FLAGS(32, c, m32, *c->reg8[cl]); MEM_DWORD_WRITE(c, i->modrm.ea, m32); } } else { if ( i->prefixes & PREFIX_OPSIZE ) { /* D3 /2 * Rotate 17 bits (CF,r/m16) left CL times * RCL r/m16,CL */ INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm], *c->reg8[cl]); } else { /* D3 /2 * Rotate 33 bits (CF,r/m32) left CL times * RCL r/m32,CL */ INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm], *c->reg8[cl]); } } return 0; }
int32_t instr_group_2_d1_sal(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { if ( i->prefixes & PREFIX_OPSIZE ) { /* D1 /4 * Multiply r/m16 by 2, once * SAL r/m16,1 */ uint16_t m16; MEM_WORD_READ(c, i->modrm.ea, &m16); INSTR_CALC_AND_SET_FLAGS(16, c, m16, 1); MEM_WORD_WRITE(c, i->modrm.ea, m16); } else { /* D1 /4 * Multiply r/m32 by 2, once * SAL r/m32,1 */ uint32_t m32; MEM_DWORD_READ(c, i->modrm.ea, &m32); INSTR_CALC_AND_SET_FLAGS(32, c, m32, 1); MEM_DWORD_WRITE(c, i->modrm.ea, m32); } } else { if ( i->prefixes & PREFIX_OPSIZE ) { /* D1 /4 * Multiply r/m16 by 2, once * SAL r/m16,1 */ INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm], 1); } else { /* D1 /4 * Multiply r/m32 by 2, once * SAL r/m32,1 */ INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm], 1); } } return 0; }
int32_t instr_group_2_c1_sar(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { if ( i->prefixes & PREFIX_OPSIZE ) { /* C1 /7 ib * Signed divide* r/m16 by 2, imm8 times * SAR r/m16,imm8 */ uint16_t m16; MEM_WORD_READ(c, i->modrm.ea, &m16); INSTR_CALC_AND_SET_FLAGS(16, c, m16, *i->imm8); MEM_WORD_WRITE(c, i->modrm.ea, m16); } else { /* C1 /7 ib * Signed divide* r/m32 by 2, imm8 times * SAR r/m32,imm8 */ uint32_t m32; MEM_DWORD_READ(c, i->modrm.ea, &m32); INSTR_CALC_AND_SET_FLAGS(32, c, m32, *i->imm8); MEM_DWORD_WRITE(c, i->modrm.ea, m32); } } else { if ( i->prefixes & PREFIX_OPSIZE ) { /* C1 /7 ib * Signed divide* r/m16 by 2, imm8 times * SAR r/m16,imm8 */ INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm], *i->imm8); } else { /* C1 /7 ib * Signed divide* r/m32 by 2, imm8 times * SAR r/m32,imm8 */ INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm], *i->imm8); } } return 0; }
int32_t instr_group_2_d1_rcr(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { if ( i->prefixes & PREFIX_OPSIZE ) { /* D1 /3 * Rotate 17 bits (CF,r/m16) right once * RCR r/m16,1 */ uint16_t m16; MEM_WORD_READ(c, i->modrm.ea, &m16); INSTR_CALC_AND_SET_FLAGS(16, c, m16, 1); MEM_WORD_WRITE(c, i->modrm.ea, m16); } else { /* D1 /3 * Rotate 33 bits (CF,r/m32) right once * RCR r/m32,1 */ uint32_t m32; MEM_DWORD_READ(c, i->modrm.ea, &m32); INSTR_CALC_AND_SET_FLAGS(32, c, m32, 1); MEM_DWORD_WRITE(c, i->modrm.ea, m32); } } else { if ( i->prefixes & PREFIX_OPSIZE ) { /* D1 /3 * Rotate 17 bits (CF,r/m16) right once * RCR r/m16,1 */ INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm], 1); } else { /* D1 /3 * Rotate 33 bits (CF,r/m32) right once * RCR r/m32,1 */ INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm], 1); } } return 0; }