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_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_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_mov_a0(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* A0 * Move byte at (seg:offset) to AL * MOV AL,moffs8* */ MEM_BYTE_READ(c, i->disp, c->reg8[al]); return 0; }
int32_t instr_test_84(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3) { /* 84 /r * AND r8 with r/m8; set SF, ZF, PF according to result * TEST r/m8,r8 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC_AND_SET_FLAGS(8, c, *c->reg8[i->modrm.opc], m8) }else
int32_t instr_cmp_38(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* 38 /r * Compare r8 with r/m8 * CMP 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], -) // MEM_BYTE_WRITE(c, i->modrm.ea, dst); }
int32_t instr_group_3_f6_idiv(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* F6 /7 * Signed divide AX (where AH must contain sign-extension of AL) by r/m byte. (Results: AL=Quotient,AH=Remainder) * IDIV r/m8 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC(16, 8, c, *c->reg16[ax], m8, *c->reg8[al], *c->reg8[ah]) }
int32_t instr_mov_8a(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* 8A /r * Move r/m8 to r8 * MOV r8,r/m8 */ if( i->modrm.mod != 3 ) { MEM_BYTE_READ(c, i->modrm.ea, c->reg8[i->modrm.opc]); //TRACK_INIT_REG16(c->instr, i->modrm.opc); } else { *c->reg8[i->modrm.opc] = *c->reg8[i->modrm.rm]; } 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_3_f6_imul(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->modrm.mod != 3 ) { /* F6 /5 * AX<- AL * r/m byte * IMUL r/m8 */ uint8_t m8; MEM_BYTE_READ(c, i->modrm.ea, &m8); INSTR_CALC(8, 16, c, *c->reg8[al], m8) *c->reg16[ax] = operation_result; uint8_t high; WORD_UPPER_TO_BYTE(high,operation_result); INSTR_SET_FLAGS(c,high); } else { /* F6 /5 * AX<- AL * r/m byte * IMUL r/m8 */ INSTR_CALC(8, 16, c, *c->reg8[al], *c->reg8[i->modrm.rm]) *c->reg16[ax] = operation_result; uint8_t high; WORD_UPPER_TO_BYTE(high,operation_result); INSTR_SET_FLAGS(c,high); } return 0; }
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; }
int32_t instr_lods_ac(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* AC * Load byte at address DS:(E)SI into AL * LODS m8 */ /* AC * Load byte at address DS:(E)SI into AL * LODSB */ if ( i->prefixes & PREFIX_ADSIZE ) { // MEM_BYTE_READ(c, c->reg16[si], c->reg8[al]); UNIMPLEMENTED(c, SST); } else { MEM_BYTE_READ(c, c->reg[esi], c->reg8[al]); if ( CPU_FLAG_ISSET(c,f_df) ) { /* decrement */ c->reg[esi] -= 1; } else { /* increment */ c->reg[esi] += 1; } //TRACK_INIT_REG8(c->instr, al); } return 0; }