#include "stdafx.h"
#include "resource.h"
#include "X51.h"
#include "WinState.h"

// Версия программы для Windows NT
#ifndef UNICODE
	#define UNICODE
#endif
#ifndef _UNICODE
	#define _UNICODE
#endif

/* Версия программы для Windows 98
#ifdef UNICODE
	#undef UNICODE
#endif
#ifdef _UNICODE
	#undef _UNICODE
#endif
*/

#ifdef UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif

//Прототипы
BOOL CreateWndDlg (HINSTANCE hInst, INT nCmdShow);
BOOL CALLBACK WndDlgProc (HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK WndEditProc (HWND hWndEdit, UINT message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK WndEditProc2 (HWND hWndEdit, UINT message, WPARAM wParam, LPARAM lParam);
VOID MessageLoop ();
BOOL InitCommCtrl ();
VOID ShowOperands(const HWND hWndDlg,const unsigned int i);
VOID UpdatePSW(const HWND hWndDlg);
VOID UpdateBANK(const HWND hWndDlg);
VOID UpdateBeat(const HWND hWndDlg, const unsigned int i);
VOID UpdateMemory(const HWND hListMemory, const unsigned int ID_MEM);
VOID UpdateCOP(const HWND hWndDlg);
VOID UpdateRegs(const HWND hWndDlg);
VOID UpdateMnemonic(const HWND hWndDlg);
VOID EditSetFocus(const HWND hEdit);
VOID EditKillFocus(const HWND hEdit, const unsigned int uiLenInput);
VOID EditFunc(const HWND hEdit, const int iEvent, unsigned int& uiValue, const unsigned int uiLenInput);
VOID EditFunc(const HWND hEdit, const int iEvent, unsigned char& ucValue, const unsigned int uiLenInput);
VOID IntToEditHex(const HWND hEdit, const unsigned int uiValue, const unsigned int uiLenInput);
VOID ByteToEditBin(const HWND hEdit, const unsigned char ucValue);
unsigned int EditHexToInt(const HWND hEdit);

//Defines
#define ID_ACALL	0 
#define ID_LCALL	1
#define ID_MOV		2
#define ID_RR		3 
#define ID_SETB		4
#define ID_SUBB		5
#define ID_XCH		6
#define ID_XRL		7

#define ID_BIT		0 
#define ID_CODE		1
#define ID_DATA		2
#define ID_IDATA	3 
#define ID_RAM		4
#define ID_REG		5
#define ID_SFR		6
#define ID_STACK	7
#define ID_XDATA	8

//Глобальные переменные
static HINSTANCE g_hInst = 0;
static HWND g_hWndDlg = 0;
static WNDPROC wpOldEditProc;
static X51 x51;
static WinState winState;
static int g_spinDelta = 0;


int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	g_hInst = hInstance;

	//Создание главного окна - Диалог из ресурсов
	HWND g_hWndDlg = CreateDialog (hInstance, MAKEINTRESOURCE (IDD_DIALOGMAIN), 0, WndDlgProc);

	//Использование общих элементов управления
	InitCommCtrl ();

	//Цикл Сообщений
	MessageLoop ();
	return 0;
}

BOOL CALLBACK WndDlgProc (HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
			{
				//Заполение списка команд
				HWND hCommand = GetDlgItem(hWndDlg, IDC_COMBO_COMMAND);
				SendMessage (hCommand, CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("acall")));
				SendMessage (hCommand, CB_INSERTSTRING, 1, reinterpret_cast<LPARAM>(_T("lcall")));
				SendMessage (hCommand, CB_INSERTSTRING, 2, reinterpret_cast<LPARAM>(_T("mov")));
				SendMessage (hCommand, CB_INSERTSTRING, 3, reinterpret_cast<LPARAM>(_T("rr")));
				SendMessage (hCommand, CB_INSERTSTRING, 4, reinterpret_cast<LPARAM>(_T("setb")));
				SendMessage (hCommand, CB_INSERTSTRING, 5, reinterpret_cast<LPARAM>(_T("subb")));
				SendMessage (hCommand, CB_INSERTSTRING, 6, reinterpret_cast<LPARAM>(_T("xch")));
				SendMessage (hCommand, CB_INSERTSTRING, 7, reinterpret_cast<LPARAM>(_T("xrl")));

				//Заполение списков Память1 и Память2
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Code")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Data")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Xdata")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Bit")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Idata")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Stack")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("SFR")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Reg")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Ram")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Ram")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Reg")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Code")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Data")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Xdata")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Bit")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Idata")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("Stack")));
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("SFR")));
				winState.idComboMem1 = 1;
				winState.idComboMem2 = 2;
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_SETCURSEL, winState.idComboMem1, 0);
				SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_SETCURSEL, winState.idComboMem2, 0);
				UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), winState.idComboMem1);
				UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), winState.idComboMem2);

				//Установка начальных значений в Edit's
				SetWindowText(GetDlgItem(hWndDlg,IDC_EDIT_COP),_T("0x00"));
				SetWindowText(GetDlgItem(hWndDlg,IDC_EDIT_COP2),_T("0x00"));
				UpdateRegs(hWndDlg);
				SendMessage (GetDlgItem(hWndDlg, IDC_SPIN), UDM_SETBUDDY, reinterpret_cast<WPARAM>(GetDlgItem(hWndDlg, IDC_EDIT_PC)), 0);
				SendMessage (GetDlgItem(hWndDlg, IDC_SPIN), UDM_SETBASE, 16, 0);
				SendMessage (GetDlgItem(hWndDlg, IDC_SPIN), UDM_SETRANGE32, 0, 0xffff);
				
				//Сабклассирование (установка новых оконных процедур)
				wpOldEditProc = (WNDPROC)SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_COP), GWL_WNDPROC, (LONG)WndEditProc); 
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_COP2), GWL_WNDPROC, (LONG)WndEditProc); 
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_A), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_B), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R0), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R1), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R2), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R3), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R4), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R5), GWL_WNDPROC, (LONG)WndEditProc); 
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R6), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R7), GWL_WNDPROC, (LONG)WndEditProc); 
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_SP), GWL_WNDPROC, (LONG)WndEditProc);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_DPTR), GWL_WNDPROC, (LONG)WndEditProc2);
				SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_PC), GWL_WNDPROC, (LONG)WndEditProc2);
				
				return TRUE;
			}
	
		case WM_COMMAND:
		{
			INT wmId = LOWORD (wParam);
			INT wmEvent = HIWORD (wParam);
			switch (wmId)
			{
			case (IDC_CHECK_PSW0):
				{
					if (wmEvent == BN_CLICKED)
					{
						x51.PSW[0] = ~x51.PSW[0];
						UpdatePSW(hWndDlg);
					}
					break;					
				}
			case (IDC_CHECK_PSW2):
				{
					if (wmEvent == BN_CLICKED)
					{
						x51.PSW[2] = ~x51.PSW[2];
						UpdatePSW(hWndDlg);
					}
					break;
				}
			case (IDC_CHECK_PSW3):
				{
					if (wmEvent == BN_CLICKED)
					{
						x51.PSW[3] = ~x51.PSW[3];
						UpdatePSW(hWndDlg);
						UpdateBANK(hWndDlg);
					}
					break;
				}
			case (IDC_CHECK_PSW4):
				{
					if (wmEvent == BN_CLICKED)
					{
						x51.PSW[4] = ~x51.PSW[4]; 
						UpdatePSW(hWndDlg);
						UpdateBANK(hWndDlg);
					}
					break;
				}
			case (IDC_CHECK_PSW5):
				{
					if (wmEvent == BN_CLICKED)
					{
						x51.PSW[5] = ~x51.PSW[5];
						UpdatePSW(hWndDlg);
					}
					break;
				}
			case (IDC_CHECK_PSW6):
				{
					if (wmEvent == BN_CLICKED)
					{
						x51.PSW[6] = ~x51.PSW[6];
						UpdatePSW(hWndDlg);
					}			
					break;
				}
			case (IDC_CHECK_PSW7):
				{
					if (wmEvent == BN_CLICKED)
					{
						x51.PSW[7] = ~x51.PSW[7]; 
					}
					UpdatePSW(hWndDlg);
					break;
				}
			
			case (IDC_COMBO_COMMAND):
				{
					if (wmEvent == CBN_SELCHANGE)
					{
						winState.idComboCommand = SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_COMMAND), CB_GETCURSEL, 0, 0);
						winState.idComboOpd1 = 0;
						winState.idComboOpd2 = 0;
						winState.idComboOpd3 = 0;
						switch (winState.idComboCommand)
						{
						case ID_ACALL:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("ad11")));
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								ShowOperands (hWndDlg, 1);
								UpdateBeat(hWndDlg, 5); 
								break;
							}
						case ID_LCALL:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("ad16")));
								winState.countByte = 3;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), TRUE);
								ShowOperands (hWndDlg, 1);
								UpdateBeat(hWndDlg, 6);
								break;
							}
						case ID_MOV:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("A")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("@R0")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 1, reinterpret_cast<LPARAM>(_T("@R1")));
								winState.countByte = 1;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), FALSE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								ShowOperands (hWndDlg, 2);
								UpdateBeat(hWndDlg, 3);
								break;
							}
						case ID_RR:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("A")));
								winState.countByte = 1;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), FALSE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								ShowOperands (hWndDlg, 1);
								UpdateBeat(hWndDlg, 2);
								break;
							}
						case ID_SETB:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("bit")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 1, reinterpret_cast<LPARAM>(_T("C")));
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								ShowOperands (hWndDlg, 1);
								UpdateBeat(hWndDlg, 6);
								break;
							}
						case ID_SUBB:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("A")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("#d")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 1, reinterpret_cast<LPARAM>(_T("@R0")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 2, reinterpret_cast<LPARAM>(_T("@R1")));
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								ShowOperands (hWndDlg, 2);
								UpdateBeat(hWndDlg, 3);
								break;
							}
						case ID_XCH:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("A")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("#ad")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 1, reinterpret_cast<LPARAM>(_T("R0")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 2, reinterpret_cast<LPARAM>(_T("R1")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 3, reinterpret_cast<LPARAM>(_T("R2")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 4, reinterpret_cast<LPARAM>(_T("R3")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 5, reinterpret_cast<LPARAM>(_T("R4")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 6, reinterpret_cast<LPARAM>(_T("R5")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 7, reinterpret_cast<LPARAM>(_T("R6")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 8, reinterpret_cast<LPARAM>(_T("R7")));
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								ShowOperands (hWndDlg, 2);
								UpdateBeat(hWndDlg, 4);
								break;
							}
						case ID_XRL:
							{
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_RESETCONTENT, 0, 0);
								SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_RESETCONTENT, 0, 0);
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("ad")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(_T("A")));
								SendMessage (GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_INSERTSTRING, 1, reinterpret_cast<LPARAM>(_T("#d")));
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								ShowOperands (hWndDlg, 2);
								UpdateBeat(hWndDlg, 4);
								break;
							}
						}
						EnableWindow(GetDlgItem(hWndDlg, IDC_BUTTON_ADD), TRUE);
						UpdateCOP(hWndDlg);
					}					
					break;
				}
			case (IDC_COMBO_OPD1):
				{
					if (wmEvent == CBN_SELCHANGE)
					{
						winState.idComboOpd1 = SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD1), CB_GETCURSEL, 0, 0);
						switch (winState.idComboCommand)
						{
						case ID_SETB:
							//C
							if (winState.idComboOpd1)
							{
								winState.countByte = 1;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), FALSE);
								UpdateBeat(hWndDlg, 2);
							}
							//bit
							else
							{	
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								UpdateBeat(hWndDlg, 6);
							}
							break;
						}
						UpdateCOP(hWndDlg);
					}					
					break;
				}
			case (IDC_COMBO_OPD2):
				{
					if (wmEvent == CBN_SELCHANGE)
					{
						winState.idComboOpd2 = SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_OPD2), CB_GETCURSEL, 0, 0);
						switch (winState.idComboCommand)
						{
						case ID_SUBB:
							//@R0 и @R1
							if (winState.idComboOpd2)
							{
								winState.countByte = 1;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), FALSE);
								UpdateBeat(hWndDlg, 4);
							}
							//#d
							else
							{	
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
								UpdateBeat(hWndDlg, 3);
							}
							break;

						case ID_XCH:
							//R0 - R7
							if (winState.idComboOpd2)
							{
								winState.countByte = 1;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), FALSE);
							}
							//#d
							else
							{	
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP), TRUE);
							}
							break;

						case ID_XRL:
							//#d
							if (winState.idComboOpd2)
							{
								winState.countByte = 3;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), TRUE);
								UpdateBeat(hWndDlg, 6);
							}
							//A
							else
							{	
								winState.countByte = 2;
								EnableWindow(GetDlgItem(hWndDlg, IDC_EDIT_COP2), FALSE);
								UpdateBeat(hWndDlg, 4);
							}
							break;
						}
						UpdateCOP(hWndDlg);
					}	
					break;
				}
			case (IDC_COMBO_MEM1):
				{
					winState.idComboMem1 = SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_MEM1), CB_GETCURSEL, 0, 0);
					if (wmEvent == CBN_SELCHANGE)
					{
						UpdateMemory(GetDlgItem(hWndDlg,IDC_LIST_MEM1), winState.idComboMem1);
						break;
					}
				}
			case (IDC_COMBO_MEM2):
				{
					winState.idComboMem2 = SendMessage(GetDlgItem(hWndDlg, IDC_COMBO_MEM2), CB_GETCURSEL, 0, 0);
					if (wmEvent == CBN_SELCHANGE)
					{
						UpdateMemory(GetDlgItem(hWndDlg,IDC_LIST_MEM2), winState.idComboMem2);
						break;
					}
				}

			case (IDC_EDIT_COP):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, winState.byte1, 2);
					break;
				}
			case (IDC_EDIT_COP2):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, winState.byte2, 2);
					break;
				}
			case (IDC_EDIT_R0):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(0), 2);
					break;
				}
			case (IDC_EDIT_R1):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(1), 2);
					break;
				}
			case (IDC_EDIT_R2):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(2), 2);
					break;
				}
			case (IDC_EDIT_R3):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(3), 2);
					break;
				}
			case (IDC_EDIT_R4):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(4), 2);
					break;
				}
			case (IDC_EDIT_R5):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(5), 2);
					break;
				}
			case (IDC_EDIT_R6):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(6), 2);
					break;
				}
			case (IDC_EDIT_R7):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.R(7), 2);
					break;
				}
			case (IDC_EDIT_A):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.A, 2);
					break;
				}
			case (IDC_EDIT_B):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.B, 2);
					break;
				}
			case (IDC_EDIT_SP):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.SP, 2);
					break;
				}
			case (IDC_EDIT_PC):
				{
					switch (wmEvent)
					{
					case EN_CHANGE:
						x51.PC = EditHexToInt(GetDlgItem(hWndDlg, wmId));
						SendMessage(GetDlgItem(hWndDlg,IDC_SPIN), UDM_SETPOS32, 0, x51.PC - g_spinDelta);
						g_spinDelta = 0;
						break;

					case EN_SETFOCUS:
						EditSetFocus(GetDlgItem(hWndDlg, wmId));
						break;	

					case EN_KILLFOCUS:
						EditKillFocus(GetDlgItem(hWndDlg, wmId), 4);
						break;
					}
					break;
				}
			case (IDC_EDIT_DPTR):
				{
					EditFunc(GetDlgItem(hWndDlg, wmId), wmEvent, x51.DPTR, 4);
					break;
				}

			case (IDC_BUTTON_ADD):
				{
					x51.Code[x51.PC++] = winState.IR;
					if (winState.countByte > 1)
						x51.Code[x51.PC++] = winState.byte1;
					if (winState.countByte > 2)
						x51.Code[x51.PC++] = winState.byte2;

					if (winState.idComboMem1 == ID_CODE)
						UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), ID_CODE);
					if (winState.idComboMem2 == ID_CODE)
						UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), ID_CODE);

					IntToEditHex(GetDlgItem(hWndDlg, IDC_EDIT_PC), x51.PC++, 2);
					break;
				}
			case IDM_COMMANDS:
				{
					if (!x51.IR)
						x51.IR = x51.Code[x51.PC];
					if (x51.IR)
					{
						x51.PC++;
						do
						{
							do 
							{
								x51(); 
							} while (x51.step);
						} while (x51.IR);
						SetWindowText (GetDlgItem(hWndDlg, IDC_STATIC_STEP), _T("1"));
						UpdateRegs(hWndDlg);
						if (winState.idComboMem1 != ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), winState.idComboMem1);
						if (winState.idComboMem2 != ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), winState.idComboMem2);
					}
					UpdateMnemonic(hWndDlg);
					break;
				}
			case IDC_BUTTON_COMMAND:
			case IDM_COMMAND:
				{
					if (!x51.IR)
						x51.IR = x51.Code[x51.PC++];
					if (x51.IR)
					{
						do 
						{
							x51(); 
						} while (x51.step);
						SetWindowText (GetDlgItem(hWndDlg, IDC_STATIC_STEP), _T("1"));
						UpdateRegs(hWndDlg);
						if (winState.idComboMem1 != ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), winState.idComboMem1);
						if (winState.idComboMem2 != ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), winState.idComboMem2);
					}
					else
						IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_PC), x51.PC, 2);
					UpdateMnemonic(hWndDlg);
					break;
				}
			case IDC_BUTTON_STEP:
			case IDM_MICROCOMMAND:
				{
					if (!x51.IR)
						x51.IR = x51.Code[x51.PC++];
					if (x51.IR)
					{
						x51(); 
						TCHAR szBuf[5];
						_itot_s (x51.step + 1, szBuf, 5, 10);
						SetWindowText (GetDlgItem(hWndDlg, IDC_STATIC_STEP), szBuf);
						UpdateRegs(hWndDlg);
						if (winState.idComboMem1 != ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), winState.idComboMem1);
						if (winState.idComboMem2 != ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), winState.idComboMem2);
					}
					else
						IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_PC), x51.PC, 2);
					UpdateMnemonic(hWndDlg);
					break;
				}
			case IDC_BUTTON_RESET:
			case IDM_RESET:
				{
					x51.Reset();
					SetWindowText (GetDlgItem(hWndDlg, IDC_STATIC_STEP), _T("1"));
					UpdateRegs(hWndDlg);
					UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), winState.idComboMem1);
					UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), winState.idComboMem2);
					UpdateMnemonic(hWndDlg);
					break;
				}
			case IDM_EXIT:
				{
					DestroyWindow (hWndDlg);
					break;
				}
			case IDM_CODE_LOAD:
				{ 
					TCHAR szFileName[256];
					ZeroMemory(szFileName, 256);
					OPENFILENAME ofn = {0};
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.hwndOwner = hWndDlg;
					ofn.lpstrFilter = _T("Текстовые файлы (*.txt)\0*.txt\0\0");
					ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
					ofn.lpstrTitle = _T("Code: Загрузка");
					ofn.lpstrFile = szFileName;
					ofn.nMaxFile = 256;
					if (GetOpenFileName(&ofn))
					{
						std::ifstream ifsm(ofn.lpstrFile);
						std::string sBuf;
						unsigned int j = 0;
						while (!ifsm.eof())
						{
							ifsm >> sBuf;
							unsigned int uiBuf = 0;
							for (unsigned int i = 0; i < sBuf.length(); i++)
							{
								uiBuf = (uiBuf << 4) + (sBuf[i] & 0x0f);
								if (sBuf[i] > 0x40)
									uiBuf += 9;
							}
							if (j < 65536)
								x51.Code[j++] = uiBuf;
							else
							{
								MessageBox(hWndDlg, _T("\nЗагружено только 64 Кбайт (размер Data 64 Кбайт)\t\n"), _T("Предупреждение"), MB_OK | MB_ICONWARNING);
								break;
							}	
						}
						if (winState.idComboMem1 == ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), ID_CODE);
						if (winState.idComboMem2 == ID_CODE)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), ID_CODE);
					}
					break;
				}
				case IDM_CODE_SAVE:
				{ 
					TCHAR szFileName[256];
					ZeroMemory(szFileName, 256);
					OPENFILENAME ofn = {0};
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.hwndOwner = hWndDlg;
					ofn.lpstrFilter = _T("Текстовые файлы (*.txt)\0*.txt\0\0");
					ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
					ofn.lpstrTitle = _T("Code: Сохранение");
					ofn.lpstrFile = szFileName;
					ofn.nMaxFile = 256;
					if (GetSaveFileName(&ofn))
					{
						std::ofstream ofsm(ofn.lpstrFile);
						ofsm << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(x51.Code[0]) << ' ';
						for (unsigned int i = 1; i < 65536; i++)
						{
							ofsm << std::setw(2) << static_cast<int>(x51.Code[i]);
							if ((i % 10) == 9)
								ofsm << std::endl;
							else
								ofsm << ' ';
						}
					}
					break;
				}
			case IDM_DATE_LOAD:
				{ 
					TCHAR szFileName[256];
					ZeroMemory(szFileName, 256);
					OPENFILENAME ofn = {0};
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.hwndOwner = hWndDlg;
					ofn.lpstrFilter = _T("Текстовые файлы (*.txt)\0*.txt\0\0");
					ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
					ofn.lpstrTitle = _T("Data: Загрузка");
					ofn.lpstrFile = szFileName;
					ofn.nMaxFile = 256;
					if (GetOpenFileName(&ofn))
					{
						std::ifstream ifsm(ofn.lpstrFile);
						std::string sBuf;
						unsigned int j = 0;
						while (!ifsm.eof())
						{
							ifsm >> sBuf;
							unsigned int uiBuf = 0;
							for (unsigned int i = 0; i < sBuf.length(); i++)
							{
								uiBuf = (uiBuf << 4) + (sBuf[i] & 0x0f);
								if (sBuf[i] > 0x40)
									uiBuf += 9;
							}
							if (j < 256)
								x51.Data[j++] = uiBuf;
							else
							{
								MessageBox(hWndDlg, _T("\nЗагружено только 256 байт (размер Data 256 байт)\t\n"), _T("Предупреждение"), MB_OK | MB_ICONWARNING);
								break;
							}
						}
						if (winState.idComboMem1 == ID_DATA)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), ID_DATA);
						if (winState.idComboMem2 == ID_DATA)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), ID_DATA);
						UpdateRegs(hWndDlg);
					}
					break;
				}
			case IDM_DATE_SAVE:
				{ 
					TCHAR szFileName[256];
					ZeroMemory(szFileName, 256);
					OPENFILENAME ofn = {0};
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.hwndOwner = hWndDlg;
					ofn.lpstrFilter = _T("Текстовые файлы (*.txt)\0*.txt\0\0");
					ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
					ofn.lpstrTitle = _T("Data: Сохранение");
					ofn.lpstrFile = szFileName;
					ofn.nMaxFile = 256;
					if (GetSaveFileName(&ofn))
					{
						std::ofstream ofsm(ofn.lpstrFile);
						ofsm << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(x51.Data[0]) << ' ';
						for (unsigned int i = 1; i < 256; i++)
						{
							ofsm << std::setw(2) << static_cast<int>(x51.Data[i]);
							if ((i % 10) == 9)
								ofsm << std::endl;
							else
								ofsm << ' ';
						}
					}
					break;
				}
			case IDM_XDATA_LOAD:
				{ 
					TCHAR szFileName[256];
					ZeroMemory(szFileName, 256);
					OPENFILENAME ofn = {0};
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.hwndOwner = hWndDlg;
					ofn.lpstrFilter = _T("Текстовые файлы (*.txt)\0*.txt\0\0");
					ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
					ofn.lpstrFile = szFileName;
					ofn.lpstrTitle = _T("Xdata: Загрузка");
					ofn.nMaxFile = 256;
					if (GetOpenFileName(&ofn))
					{
						std::ifstream ifsm(ofn.lpstrFile);
						std::string sBuf;
						unsigned int j = 0;
						while (!ifsm.eof())
						{
							ifsm >> sBuf;
							unsigned int uiBuf = 0;
							for (unsigned int i = 0; i < sBuf.length(); i++)
							{
								uiBuf = (uiBuf << 4) + (sBuf[i] & 0x0f);
								if (sBuf[i] > 0x40)
									uiBuf += 9;
							}
							if (j < 65536)
								x51.Xdata[j++] = uiBuf;
							else
							{
								MessageBox(hWndDlg, _T("\nЗагружено только 64 Кбайт (размер Data 64 Кбайт)\t\n"), _T("Предупреждение"), MB_OK | MB_ICONWARNING);
								break;
							}
						}
						if (winState.idComboMem1 == ID_XDATA)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM1), ID_XDATA);
						if (winState.idComboMem2 == ID_XDATA)
							UpdateMemory(GetDlgItem(hWndDlg, IDC_LIST_MEM2), ID_XDATA);
					}
					break;
				}
			case IDM_XDATA_SAVE:
				{ 
					TCHAR szFileName[256];
					ZeroMemory(szFileName, 256);
					OPENFILENAME ofn = {0};
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.hwndOwner = hWndDlg;
					ofn.lpstrFilter = _T("Текстовые файлы (*.txt)\0*.txt\0\0");
					ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
					ofn.lpstrTitle = _T("Xdata: Сохранение");
					ofn.lpstrFile = szFileName;
					ofn.nMaxFile = 256;
					if (GetSaveFileName(&ofn))
					{
						std::ofstream ofsm(ofn.lpstrFile);
						ofsm << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(x51.Xdata[0]) << ' ';
						for (unsigned int i = 1; i < 65536; i++)
						{
							ofsm << std::setw(2) << static_cast<int>(x51.Xdata[i]);
							if ((i % 10) == 9)
								ofsm << std::endl;
							else
								ofsm << ' ';
						}
					}
					break;
				}
			}
			return 0;
		}

 		case WM_NOTIFY:
 		{
			NMHDR *pnmHdr = reinterpret_cast<NMHDR*>(lParam);
 			if ((pnmHdr->idFrom == IDC_SPIN) && (pnmHdr->code == UDN_DELTAPOS)) 
 			{
				NMUPDOWN *pnmUpDown = reinterpret_cast<NMUPDOWN*>(pnmHdr);
 				TCHAR szBuf[10];
 				g_spinDelta = pnmUpDown->iDelta;
				int iBuf = pnmUpDown->iPos + pnmUpDown->iDelta;
				if (iBuf < 0) iBuf = 0;
				if (iBuf > 0xffff) iBuf = 0xffff;
 				_itot_s(iBuf, szBuf, 10, 16);
				SetWindowText(GetDlgItem(hWndDlg, IDC_EDIT_PC), szBuf);
				return 1;
			}
			return 0;
		}	

		case WM_CLOSE:
		{
			DestroyWindow (hWndDlg);
			return 0;
		}		
		
		case WM_DESTROY:
		{		
			//Сабклассирование (восстановление старых оконных процедур)
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_COP), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_COP2), GWL_WNDPROC, (LONG)wpOldEditProc); 
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_A), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_B), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R0), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R1), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R2), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R3), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R4), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R5), GWL_WNDPROC, (LONG)wpOldEditProc); 
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R6), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_R7), GWL_WNDPROC, (LONG)wpOldEditProc); 
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_SP), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_DPTR), GWL_WNDPROC, (LONG)wpOldEditProc);
			SetWindowLong(GetDlgItem(hWndDlg, IDC_EDIT_PC), GWL_WNDPROC, (LONG)wpOldEditProc);
			
			PostQuitMessage(0);
			return 0;
		}
		default:
			return 0;
	}
}

BOOL CALLBACK WndEditProc (HWND hWndEdit, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_GETDLGCODE:
		{
			return DLGC_WANTALLKEYS;
		}
	case WM_CHAR:
		{		
			TCHAR szBuf[10];
			if (wParam == 8)
				break;
			if (GetWindowText(hWndEdit, szBuf, 10) > 1) 
				return 0;
			if (((wParam >= 48) && (wParam <= 57)) || ((wParam >= 65) && (wParam <= 70)) || ((wParam >= 92) && (wParam <= 102)))
				break;
			return 0;
		}
	}		 
	return CallWindowProc(wpOldEditProc, hWndEdit, message, wParam, lParam); 
}

BOOL CALLBACK WndEditProc2 (HWND hWndEdit, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_GETDLGCODE:
		{
			return DLGC_WANTALLKEYS;
		}
	case WM_CHAR:
		{		
			TCHAR szBuf[10];
			if (wParam == 8)
				break;
			if (GetWindowText(hWndEdit, szBuf, 10) > 3) 
				return 0;
			if (((wParam >= 48) && (wParam <= 57)) || ((wParam >= 65) && (wParam <= 70)) || ((wParam >= 92) && (wParam <= 102)))
				break;
			return 0;
		}
	}		 
	return CallWindowProc(wpOldEditProc, hWndEdit, message, wParam, lParam); 
}

VOID MessageLoop  ()
{
	MSG msg;
	while (GetMessage(&msg, NULL,0, 0))
	{
		if (!IsWindow(g_hWndDlg) || !IsDialogMessage(g_hWndDlg, &msg))
		{		
			TranslateMessage (&msg);
			DispatchMessage (&msg);
		}
	}
}


BOOL InitCommCtrl ()
{
	INITCOMMONCONTROLSEX Init = {0};
	Init.dwSize = sizeof(Init);
	Init.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx (&Init);
	return TRUE;
}


VOID ShowOperands (const HWND hWndDlg,const unsigned int i)
{
	HWND
		hComboOpd1 = GetDlgItem(hWndDlg, IDC_COMBO_OPD1),
		hComboOpd2 = GetDlgItem(hWndDlg, IDC_COMBO_OPD2),
		hComboOpd3 = GetDlgItem(hWndDlg, IDC_COMBO_OPD3),
		hStaticOpd1 = GetDlgItem(hWndDlg, IDC_STATIC_OPD1),
		hStaticOpd2 = GetDlgItem(hWndDlg, IDC_STATIC_OPD2),
		hStaticOpd3 = GetDlgItem(hWndDlg, IDC_STATIC_OPD3);
	
	if (i)
	{
		ShowWindow(hStaticOpd1, TRUE);
		ShowWindow(hComboOpd1, TRUE);
		SendMessage(hComboOpd1, CB_SETCURSEL, 0, 0);
	}
	else
	{
		ShowWindow(hStaticOpd1, FALSE);
		ShowWindow(hComboOpd1, FALSE);
	}
	if (i > 1)
	{
		ShowWindow(hStaticOpd2, TRUE);
		ShowWindow(hComboOpd2, TRUE);
		SendMessage(hComboOpd2, CB_SETCURSEL, 0, 0);
	}
	else
	{
		ShowWindow(hStaticOpd2, FALSE);
		ShowWindow(hComboOpd2, FALSE);
	}
	if (i > 2)
	{
		ShowWindow(hStaticOpd3, TRUE);
		ShowWindow(hComboOpd3, TRUE);
		SendMessage(hComboOpd3, CB_SETCURSEL, 0, 0);
	}
	else
	{
		ShowWindow(hStaticOpd3, FALSE);
		ShowWindow(hComboOpd3, FALSE);
	}
}


VOID UpdatePSW(const HWND hWndDlg)
{
	TCHAR szBuf[10];
	int iBuf = x51.PSW.to_ulong();
	_itot_s (iBuf, szBuf, 10, 16);
	SetWindowText(GetDlgItem(hWndDlg, IDC_EDIT_PSW), szBuf);
}


VOID UpdateBANK(const HWND hWndDlg)
{
	int iBuf = 2 * x51.PSW[4] + x51.PSW[3];
	TCHAR szBuf[10];
	_stprintf_s (szBuf, 10, _T("Банк: %d"), iBuf);
	SetWindowText(GetDlgItem(hWndDlg, IDC_STATIC_BANK), szBuf);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R0), x51.R(0), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R1), x51.R(1), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R2), x51.R(2), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R3), x51.R(3), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R4), x51.R(4), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R5), x51.R(5), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R6), x51.R(6), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R7), x51.R(7), 2);
}


VOID UpdateBeat(const HWND hWndDlg, const unsigned int i)
{
	TCHAR szBuf[10];
	_stprintf_s (szBuf, 10, _T("Тактов: %d"),i);
	SetWindowText(GetDlgItem(hWndDlg, IDC_STATIC_STEPS), szBuf);
}


VOID UpdateMemory(const HWND hListMemory, const unsigned int ID_MEM)
{
	int n;
	unsigned char *mem;
	switch (ID_MEM)
	{
	case ID_BIT:
		{		
			n = 16;
			mem = x51.Bit;
			break;
		}
	case ID_CODE:
		{
			n = 8192;
			mem = x51.Code;
			break;
		}
	case ID_DATA:
	case ID_IDATA:
		{	
			n = 128;
			mem = x51.Data;
			break;
		}	
	case ID_RAM:
		{	
			n = 256;
			mem = x51.Ram;
			break;
		}
	case ID_REG:
		{	
			n = 32;
			mem = x51.Reg;
			break;
		}
	case ID_SFR:
		{	
			n = 128;
			mem = x51.SFR;
			break;
		}
	case ID_STACK:
		{	
			n = 16;
			mem = x51.Stack;
			break;
		}
	case ID_XDATA:
		{	
			n = 8192;
			mem = x51.Xdata;
			break;
		}
	}

	SendMessage (hListMemory, LB_RESETCONTENT, 0, 0);
	std::wostringstream *sstrm = new std::wostringstream();	
	int i = 0;
	for (; i < n;)
	{
		if (!(i % 10))
		{
			delete sstrm;
			sstrm = new std::wostringstream();
			new std::wostringstream();
			*sstrm << std::setfill(_T('0')) << std::hex;
			*sstrm <<  _T("0x") << std::setw(4)<< i << _T(':');
		}
		*sstrm << _T(' ') << std::setw(2) << mem[i];
		i++;
		if (!(i % 10))
			SendMessage(hListMemory, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(sstrm->str().c_str()));
	}
	if (i % 10)
		SendMessage(hListMemory, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(sstrm->str().c_str()));
	delete sstrm;
}


VOID UpdateCOP(const HWND hWndDlg)
{
	switch (winState.idComboCommand)
	{		
	case ID_ACALL:
		winState.IR = x51.copAcall;
		break;

	case ID_LCALL:
		winState.IR = x51.copLcall;
		break;

	case ID_MOV:
		winState.IR = x51.copMov_A_aR + winState.idComboOpd2;
		break;
		
	case ID_RR:
		winState.IR = x51.copRr;
		break;
		
	case ID_SETB:
		if (winState.idComboOpd1)
		{
			winState.IR = x51.copSetb_C;
		}
		else
		{
			winState.IR = x51.copSetb_bit;
		}
		break;
		
	case ID_SUBB:
		if (winState.idComboOpd2)
		{
			winState.IR = x51.copSubb_A_aR + (winState.idComboOpd2 - 1);
		}
		else
		{
			winState.IR = x51.copSubb_A_d;
		}
		break;
		
	case ID_XCH:
		if (winState.idComboOpd2)
		{
			winState.IR = x51.copXch_R + (winState.idComboOpd2 - 1);
		}
		else
		{
			winState.IR = x51.copXch_ad;
		}
		break;
		
	case ID_XRL:
		if (winState.idComboOpd2)
		{
			winState.IR = x51.copXrl_ad_d;
		}
		else
		{
			winState.IR = x51.copXrl_ad_A;
		}
		break;				
	}
	ByteToEditBin(GetDlgItem(hWndDlg,IDC_STATIC_COP), winState.IR);
}


VOID UpdateRegs(const HWND hWndDlg)
{
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_PC), x51.PC, 4);
	ByteToEditBin(GetDlgItem(hWndDlg,IDC_EDIT_IR), x51.IR);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_WRK), x51.WRK, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_WRK1), x51.WRK1, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_WRK2), x51.WRK2, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_RA), x51.RA, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_RB), x51.RB, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_A), x51.A, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_B), x51.B, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_SP), x51.SP, 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_DPTR), x51.DPTR, 4);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R0), x51.R(0), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R1), x51.R(1), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R2), x51.R(2), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R3), x51.R(3), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R4), x51.R(4), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R5), x51.R(5), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R6), x51.R(6), 2);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_R7), x51.R(7), 2);
	SendMessage(GetDlgItem(hWndDlg, IDC_CHECK_PSW0), BM_SETCHECK, x51.PSW[0], 0);
	SendMessage(GetDlgItem(hWndDlg, IDC_CHECK_PSW2), BM_SETCHECK, x51.PSW[2], 0);
	SendMessage(GetDlgItem(hWndDlg, IDC_CHECK_PSW3), BM_SETCHECK, x51.PSW[3], 0);
	SendMessage(GetDlgItem(hWndDlg, IDC_CHECK_PSW4), BM_SETCHECK, x51.PSW[4], 0);
	SendMessage(GetDlgItem(hWndDlg, IDC_CHECK_PSW5), BM_SETCHECK, x51.PSW[5], 0);
	SendMessage(GetDlgItem(hWndDlg, IDC_CHECK_PSW6), BM_SETCHECK, x51.PSW[6], 0);
	SendMessage(GetDlgItem(hWndDlg, IDC_CHECK_PSW7), BM_SETCHECK, x51.PSW[7], 0);
	IntToEditHex(GetDlgItem(hWndDlg,IDC_EDIT_PSW), x51.PSW.to_ulong(), 2);
}


VOID UpdateMnemonic(const HWND hWndDlg)
{
	TCHAR szBuf[20] = _T("NOP");
	switch (x51.Rom[x51.IR])
	{
	case x51.copMov_A_aR:
		{
			if (x51.IR & 1)
				_tcscpy_s (szBuf, 20, _T("MOV A, @R1"));
			else
				_tcscpy_s (szBuf, 20, _T("MOV A, @R0"));
			break;
		}
	case x51.copAcall:
		{
			_tcscpy_s (szBuf, 20, _T("ACALL a11"));
			break;
		}
	case x51.copLcall:
		{
			_tcscpy_s (szBuf, 20, _T("LCALL a16"));
			break;
		}
	case x51.copSubb_A_aR:
		{
			if (x51.IR & 1)
				_tcscpy_s (szBuf, 20, _T("SUBB A, @R1"));
			else
				_tcscpy_s (szBuf, 20, _T("SUBB A, @R0"));
			break;
		}
	case x51.copSubb_A_d:
		{
			_tcscpy_s (szBuf, 20, _T("SUBB A, #d"));
			break;
		}
	case x51.copXch_ad:
		{
			_tcscpy_s (szBuf, 20, _T("XCH A, ad"));
			break;
		}
	case x51.copXch_R:
		{
			_tcscpy_s (szBuf, 20, _T("XCH A, R"));
			int iBuf = x51.IR & 7;
			TCHAR szBuf2[4]; 
			_itot_s (iBuf,szBuf2,4,10);
			_tcscat_s(szBuf, 20, szBuf2);
			break;
		}
	case x51.copSetb_bit:
		{
			_tcscpy_s (szBuf, 20, _T("SETB bit"));
			break;
		}
	case x51.copSetb_C:
		{
			_tcscpy_s (szBuf, 20, _T("SETB C"));
			break;
		}
	case x51.copRr:
		{
			_tcscpy_s (szBuf, 20, _T("RR A"));
			break;
		}
	case x51.copXrl_ad_A:
		{
			_tcscpy_s (szBuf, 20, _T("XRL ad, A"));
			break;
		}
	case x51.copXrl_ad_d:
		{
			_tcscpy_s (szBuf, 20, _T("XRL ad, #d"));
			break;
		}
	}
	SetDlgItemText (hWndDlg, IDC_STATIC_MNEMONIC, szBuf);
}


VOID EditSetFocus(const HWND hEdit)
{
	TCHAR szBuf[8],
		  szBuf2[8];
	SendMessage(hEdit, EM_GETLINE, 0, (LPARAM)szBuf2);	
	unsigned int j = 0, i = 2;
	while (szBuf2[i] == _T('0')) i++;
	for (; i < _tcslen(szBuf2); i++, j++)
	{
		szBuf[j] = szBuf2[i];
	}
	szBuf[j] = 0;
	SetWindowText (hEdit, szBuf);
}


VOID EditKillFocus(const HWND hEdit, const unsigned int uiLenInput)
{
	TCHAR szBuf[8] = _T("0x"),
		  szBuf2[8];
	GetWindowText (hEdit, szBuf2, 8);
	unsigned int i = 0;
	for (; i < uiLenInput - _tcslen(szBuf2); i++)
	{
		szBuf[i + 2] = _T('0');
	}
	szBuf[i + 2] = 0;
	_tcscat_s (szBuf, 8, szBuf2);
	SetWindowText (hEdit, szBuf);
}


VOID EditFunc(const HWND hEdit, const int iEvent, unsigned int& uiValue, const unsigned int uiLenInput)
{
	switch (iEvent)
	{
	case EN_CHANGE:
		uiValue = EditHexToInt(hEdit);
		break;
		
	case EN_SETFOCUS:
		EditSetFocus(hEdit);
		break;	

	case EN_KILLFOCUS:
		EditKillFocus(hEdit, uiLenInput);
		break;
	}
}


VOID EditFunc(const HWND hEdit, const int iEvent, unsigned char& ucValue, const unsigned int uiLenInput)
{
	switch (iEvent)
	{
	case EN_CHANGE:
		ucValue = EditHexToInt(hEdit);
		break;

	case EN_SETFOCUS:
		EditSetFocus(hEdit);
		break;	

	case EN_KILLFOCUS:
		EditKillFocus(hEdit, uiLenInput);
		break;
	}
}


VOID IntToEditHex(const HWND hEdit, const unsigned int uiValue, const unsigned int uiLenInput)
{
	TCHAR szBuf[8] = _T("0x"),
		szBuf2[8];
	_itot_s (uiValue, szBuf2, 8, 16);
	unsigned int i = 0;
	for (; i < uiLenInput - _tcslen(szBuf2); i++)
	{
		szBuf[i + 2] = _T('0');
	}
	szBuf[i + 2] = 0;
	_tcscat_s (szBuf, 8, szBuf2);
	SetWindowText (hEdit, szBuf);
}


VOID ByteToEditBin(const HWND hEdit, const unsigned char ucValue)
{
	TCHAR
		szBuf[9],
		szMask[9] = _T("00000000");
	_itot_s (ucValue, szBuf, 9, 2);	
	for (unsigned int i = 1; i <= _tcslen(szBuf); i++)
	{
		szMask[8 - i] =  szBuf[_tcslen(szBuf) - i];
	}
	SetWindowText (hEdit, szMask);
}


unsigned int EditHexToInt (const HWND hEdit)
{
	TCHAR szBuf[10];
	SendMessage(hEdit, EM_GETLINE, 0, (LPARAM)szBuf);
	unsigned int 
		uiBuf = 0,
		i;
	if (_totupper(szBuf[1]) == _T('X'))
		i = 2;
	else
		i = 0;
	for (; i < _tcslen(szBuf); i++)
	{
		uiBuf = (uiBuf << 4) + (szBuf[i] & 0x0f);
		if (szBuf[i] > 0x40)
			uiBuf += 9;
	}
	return uiBuf;
}
Соседние файлы в папке MyProject3