Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
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
Пример #11
0
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);
	}
Пример #12
0
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])
	}
Пример #13
0
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;
}
Пример #14
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);
	}
Пример #15
0
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);
	}
Пример #16
0
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;
}
Пример #17
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;
}
Пример #18
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;
}