#include "stdafx.h"
#include "..\..\Common\Application.h"
#include "Mov.h"

bool CMov::Disasm(BYTE*& ptr)
{
	if(Mov_RM_Seg(ptr)) return true;
	else if(Mov_Seg_RM(ptr)) return true;
	else if(Mov_Reg_Imm(ptr)) return true;
	else return false;
}

void CMov::Mov_RM_S(BYTE oo,BYTE mmm,BYTE sss)
{
	USHORT* pSrc = 0;
	USHORT* pDest = 0;
	switch(mmm)
	{
	case 0: // 000
		pDest = (USHORT*)&theApp.Real_Register.AX;
		break;
	case 1: // 001
		pDest = (USHORT*)&theApp.Real_Register.CX;
		break;
	case 2: // 010
		pDest = (USHORT*)&theApp.Real_Register.DX;
		break;
	case 3: // 011
		pDest = (USHORT*)&theApp.Real_Register.BX;
		break;
	case 4: // 100
		pDest = (USHORT*)&theApp.Real_Register.SP;
		break;
	case 5: // 101
		pDest = (USHORT*)&theApp.Real_Register.BP;
		break;
	case 6: // 110
		pDest = (USHORT*)&theApp.Real_Register.SI;
		break;
	case 7: // 111
		pDest = (USHORT*)&theApp.Real_Register.DI;
		break;
	}
	switch(sss)
	{
	case 0: // 000
		pSrc = (USHORT*)&theApp.Real_Register.ES;
		break;
	case 1: // 001
		pSrc = (USHORT*)&theApp.Real_Register.CS;
		break;
	case 2: // 010
		pSrc = (USHORT*)&theApp.Real_Register.SS;
		break;
	case 3: // 011
		pSrc = (USHORT*)&theApp.Real_Register.DS;
		break;
	}
	*pDest = *pSrc;
}

void CMov::Mov_S_RM(BYTE oo,BYTE mmm,BYTE sss)
{
	USHORT* pSrc = 0;
	USHORT* pDest = 0;
	switch(mmm)
	{
	case 0: // 000
		pSrc = (USHORT*)&theApp.Real_Register.AX;
		break;
	case 1: // 001
		pSrc = (USHORT*)&theApp.Real_Register.CX;
		break;
	case 2: // 010
		pSrc = (USHORT*)&theApp.Real_Register.DX;
		break;
	case 3: // 011
		pSrc = (USHORT*)&theApp.Real_Register.BX;
		break;
	case 4: // 100
		pSrc = (USHORT*)&theApp.Real_Register.SP;
		break;
	case 5: // 101
		pSrc = (USHORT*)&theApp.Real_Register.BP;
		break;
	case 6: // 110
		pSrc = (USHORT*)&theApp.Real_Register.SI;
		break;
	case 7: // 111
		pSrc = (USHORT*)&theApp.Real_Register.DI;
		break;
	}
	switch(sss)
	{
	case 0: // 000
		pDest = (USHORT*)&theApp.Real_Register.ES;
		break;
	case 1: // 001
		pDest = (USHORT*)&theApp.Real_Register.CS;
		break;
	case 2: // 010
		pDest = (USHORT*)&theApp.Real_Register.SS;
		break;
	case 3: // 011
		pDest = (USHORT*)&theApp.Real_Register.DS;
		break;
	}
	*pDest = *pSrc;
}

USHORT* CMov::Mov_R_I(BYTE w,BYTE rrr)
{
	USHORT* Result = 0;
	switch(rrr)
	{
	case 0: // 000
		Result = (USHORT*)&theApp.Real_Register.AX;
		break;
	case 1: // 001
		Result = (USHORT*)&theApp.Real_Register.CX;
		break;
	case 2: // 010
		Result = (USHORT*)&theApp.Real_Register.DX;
		break;
	case 3: // 011
		Result = (USHORT*)&theApp.Real_Register.BX;
		break;
	case 4: // 100
		Result = (USHORT*)&theApp.Real_Register.SP;
		break;
	case 5: // 101
		Result = (USHORT*)&theApp.Real_Register.BP;
		break;
	case 6: // 110
		Result = (USHORT*)&theApp.Real_Register.SI;
		break;
	case 7: // 111
		Result = (USHORT*)&theApp.Real_Register.DI;
		break;
	}
	return Result;
}

bool CMov::Mov_RM_Seg(BYTE*& ptr)
{
	if(*ptr == MOV_RM_SEG)
	{
		ptr++;
		BYTE mmm = GetBit(*ptr,0,3);
		BYTE sss = GetBit(*ptr,3,3);
		BYTE oo = GetBit(*ptr,6,2);
		Mov_RM_S(oo,mmm,sss);
		ptr++;
		return true;
	}
	return false;
}

bool CMov::Mov_Seg_RM(BYTE*& ptr)
{
	if(*ptr == MOV_SEG_RM)
	{
		ptr++;
		BYTE mmm = GetBit(*ptr,0,3);
		BYTE sss = GetBit(*ptr,3,3);
		BYTE oo = GetBit(*ptr,6,2);
		Mov_S_RM(oo,mmm,sss);
		ptr++;
		return true;
	}
	return false;
}

bool CMov::Mov_Reg_Imm(BYTE*& ptr)
{
	BYTE header = GetBit(*ptr,4,4);
	if(header == MOV_REG_IMM)
	{
		BYTE rrr = GetBit(*ptr,0,3);
		BYTE w = GetBit(*ptr,3,1);
		USHORT* pDest = Mov_R_I(w,rrr);
		ptr++;
		memcpy(pDest,ptr,sizeof(USHORT));
		ptr += 2;
		return true;
	}
	return false;
}