예제 #1
0
INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	CMemView* wnd = (CMemView*)GetWindowLongPtr(hDlg, DWLP_USER);
	if((wnd == NULL) && (uMsg != WM_INITDIALOG))
		return 0;

	switch(uMsg)
	{
	case WM_INITDIALOG:
		{
			HWND cur;

			wnd = (CMemView*)lParam;
			SetWindowLongPtr(hDlg, DWLP_USER, (LONG)wnd);
			SetWindowLongPtr(GetDlgItem(hDlg, IDC_MEMVIEWBOX), DWLP_USER, (LONG)wnd);

			wnd->font = CreateFont(16, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, DEFAULT_CHARSET, 
				OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, GetFontQuality(), FIXED_PITCH, "Courier New");

			cur = GetDlgItem(hDlg, IDC_CPU);
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"ARM9");
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"ARM7");
			SendMessage(cur, CB_SETCURSEL, 0, 0);

			cur = GetDlgItem(hDlg, IDC_VIEWMODE);
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Bytes");
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Halfwords");
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Words");
			SendMessage(cur, CB_SETCURSEL, 0, 0);

			cur = GetDlgItem(hDlg, IDC_ADDRESS);
			SendMessage(cur, EM_SETLIMITTEXT, 8, 0);
			SetWindowText(cur, "02000000");

			wnd->Refresh();
		}
		return 1;

	case WM_CLOSE:
		CloseToolWindow(wnd);
		return 1;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDCANCEL:
			CloseToolWindow(wnd);
			return 1;

		case IDC_CPU:
			if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_CLOSEUP))
			{
				wnd->cpu = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);

				wnd->sel = FALSE;
				wnd->selAddress = 0x00000000;
				wnd->selPart = 0;
				wnd->selNewVal = 0x00000000;

				wnd->SetTitle((wnd->cpu == ARMCPU_ARM9) ? "ARM9 memory":"ARM7 memory");

				wnd->Refresh();
			}
			return 1;

		case IDC_VIEWMODE:
			if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_CLOSEUP))
			{
				wnd->viewMode = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);

				wnd->sel = FALSE;
				wnd->selAddress = 0x00000000;
				wnd->selPart = 0;
				wnd->selNewVal = 0x00000000;

				wnd->Refresh();
			}
			return 1;

		case IDC_GO:
			{
				char addrstr[9];
				int len;
				int i;
				int shift;
				BOOL error = FALSE;
				u32 address = 0x00000000;

				len = GetWindowText(GetDlgItem(hDlg, IDC_ADDRESS), addrstr, 9);

				for(i = 0; i < len; i++)
				{
					char ch = addrstr[i];

					if((ch >= '0') && (ch <= '9'))
						continue;

					if((ch >= 'A') && (ch <= 'F'))
						continue;

					if((ch >= 'a') && (ch <= 'f'))
						continue;

					if(ch == '\0')
						break;

					error = TRUE;
					break;
				}

				if(error)
				{
					MessageBox(hDlg, "Error:\nInvalid address specified.\nThe address must be an hexadecimal value.", "DeSmuME", (MB_OK | MB_ICONERROR));
					SetWindowText(GetDlgItem(hDlg, IDC_ADDRESS), "");
					return 1;
				}

				for(i = (len-1), shift = 0; i >= 0; i--, shift += 4)
				{
					char ch = addrstr[i];

					if((ch >= '0') && (ch <= '9'))
						address |= ((ch - '0') << shift);
					else if((ch >= 'A') && (ch <= 'F'))
						address |= ((ch - 'A' + 0xA) << shift);
					else if((ch >= 'a') && (ch <= 'f'))
						address |= ((ch - 'a' + 0xA) << shift);
				}

				wnd->address = min((u32)0xFFFFFF00, (address & 0xFFFFFFF0));

				wnd->sel = FALSE;
				wnd->selAddress = 0x00000000;
				wnd->selPart = 0;
				wnd->selNewVal = 0x00000000;

				SetScrollPos(GetDlgItem(hDlg, IDC_MEMVIEWBOX), SB_VERT, ((wnd->address >> 4) & 0x000FFFFF), TRUE);
				wnd->Refresh();
			}
			return 1;

		case IDC_TEXTDUMP:
			{
				char fileName[256] = "";
				OPENFILENAME ofn;

				ZeroMemory(&ofn, sizeof(ofn));
				ofn.lStructSize = sizeof(ofn);
				ofn.hwndOwner = hDlg;
				ofn.lpstrFilter = "Text file (*.txt)\0*.txt\0Any file (*.*)\0*.*\0\0";
				ofn.nFilterIndex = 1;
				ofn.lpstrFile = fileName;
				ofn.nMaxFile = 256;
				ofn.lpstrDefExt = "txt";
				ofn.Flags = OFN_NOCHANGEDIR | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;

				if(GetSaveFileName(&ofn))
				{
					FILE *f;
					u8 memory[0x100];
					int line;

					MMU_DumpMemBlock(wnd->cpu, wnd->address, 0x100, memory);

					f = fopen(fileName, "a");

					for(line = 0; line < 16; line++)
					{
						int i;
						
						fprintf(f, "%08X\t\t", (wnd->address + (line << 4)));

						switch(wnd->viewMode)
						{
						case 0:
							{
								for(i = 0; i < 16; i++)
								{
									fprintf(f, "%02X ", T1ReadByte(memory, ((line << 4) + i)));
								}
								fprintf(f, "\t");
							}
							break;

						case 1:
							{
								for(i = 0; i < 16; i += 2)
								{
									fprintf(f, "%04X ", T1ReadWord(memory, ((line << 4) + i)));
								}
								fprintf(f, "\t\t");
							}
							break;

						case 2:
							{
								for(i = 0; i < 16; i += 4)
								{
									fprintf(f, "%08X ", T1ReadLong(memory, ((line << 4) + i)));
								}
								fprintf(f, "\t\t\t");
							}
							break;
						}

						for(i = 0; i < 16; i++)
						{
							u8 val = T1ReadByte(memory, ((line << 4) + i));
									
							if((val >= 32) && (val <= 127))
								fprintf(f, "%c", (char)val);
							else
								fprintf(f, ".");
						}
						fprintf(f, "\n");
					}

					fclose(f);
				}
			}
			return 1;

		case IDC_RAWDUMP:
			{
				char fileName[256] = "";
				OPENFILENAME ofn;

				ZeroMemory(&ofn, sizeof(ofn));
				ofn.lStructSize = sizeof(ofn);
				ofn.hwndOwner = hDlg;
				ofn.lpstrFilter = "Binary file (*.bin)\0*.bin\0Any file (*.*)\0*.*\0\0";
				ofn.nFilterIndex = 1;
				ofn.lpstrFile = fileName;
				ofn.nMaxFile = 256;
				ofn.lpstrDefExt = "bin";
				ofn.Flags = OFN_NOCHANGEDIR | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;

				if(GetSaveFileName(&ofn))
				{
					FILE *f;
					u8 memory[0x100];

					MMU_DumpMemBlock(wnd->cpu, wnd->address, 0x100, memory);

					f = fopen(fileName, "ab");

					fwrite(memory, 0x100, 1, f);

					fclose(f);
				}
			}
			return 1;
		}
		return 0;
	}

	return 0;
}
예제 #2
0
파일: memView.cpp 프로젝트: Annovae/desmume
INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	CMemView* wnd = (CMemView*)GetWindowLongPtr(hDlg, DWLP_USER);
	if((wnd == NULL) && (uMsg != WM_INITDIALOG))
		return 0;

	switch(uMsg)
	{
	case WM_INITDIALOG:
		{
			wnd = (CMemView*)lParam;
			SetWindowLongPtr(hDlg, DWLP_USER, (LONG)wnd);
			SetWindowLongPtr(GetDlgItem(hDlg, IDC_MEMVIEWBOX), DWLP_USER, (LONG)wnd);

			wnd->font = CreateFont(16, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, DEFAULT_CHARSET, 
				OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, GetFontQuality(), FIXED_PITCH, "Courier New");

			s_memoryRegions[MEMVIEW_ARM9].hardwareAddress = arm9InitAddress;
			s_memoryRegions[MEMVIEW_ARM7].hardwareAddress = arm7InitAddress;
			if (wnd->address == 0xFFFFFFFF)
				wnd->address = s_memoryRegions.front().hardwareAddress;
			MemViewRegion& region = s_memoryRegions[wnd->region];

			HWND cur = GetDlgItem(hDlg, IDC_REGION); 
			u32 sel = 0;
			for(MemoryList::iterator iter = s_memoryRegions.begin(); iter != s_memoryRegions.end(); ++iter)
			{
				u32 id = SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)iter->name);
				if (iter->region == wnd->region)
					sel = id;
			}
			SendMessage(cur, CB_SETCURSEL, sel, 0);

			cur = GetDlgItem(hDlg, IDC_VIEWMODE);
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Bytes");
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Halfwords");
			SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Words");
			SendMessage(cur, CB_SETCURSEL, 0, 0);
			
			gAddress = GetDlgItem(hDlg, IDC_ADDRESS);
			SendMessage(gAddress, EM_SETLIMITTEXT, 8, 0);
			char addressText[9];
			wsprintf(addressText, "%08X", wnd->address);
			SetWindowText(gAddress, addressText);
			//SendMessage(gAddress, CB_LIMITTEXT, 8, 0);
			oldEditAddrProc = SetWindowLongPtr(gAddress, GWLP_WNDPROC, (LONG_PTR)EditAddrProc);

			for (u16 i = 0; i < MAX_ADDRESS_SAVE; i++)
			{
				char hex[16] = {0};
				char buf[16] = {0};
				memset(&hex[0], 0, sizeof(hex));
				sprintf(buf, "addr%03d", i);

				u16 len = GetPrivateProfileString("Tools.MemoryViewer", buf, 0, &hex[0], 9, IniName);
				if (!len) break;
				
				ComboBox_AddString(gAddress, hex);
			}

			gAddrText = GetDlgItem(hDlg, IDC_CURRENT_ADDR);
			char buf[10] = {0};
			sprintf(buf, "%08Xh", wnd->address);
			SetWindowText(gAddrText, buf);

			CheckDlgButton(hDlg, IDC_FULL_CHARS, MF_CHECKED);

			wnd->sel = TRUE;
			wnd->selAddress = wnd->address + (wnd->address & 0x0000000F);
			wnd->selPart = 0;
			wnd->selNewVal = 0x00000000;
			wnd->Refresh();
			wnd->SetFocus();
		}
		return 1;

	case WM_DESTROY:
		{
			u16 num = ComboBox_GetCount(gAddress);
			for (u16 i = 0; i < num; i++)
			{
				char hex[16] = {0};
				char buf[16] = {0};
				memset(&hex[0], 0, sizeof(hex));

				sprintf(buf, "addr%03d", i);
				ComboBox_GetLBText(gAddress, i, (LPCTSTR)&hex[0]);
				WritePrivateProfileString("Tools.MemoryViewer", buf, hex, IniName);
			}
		}
		return 1;

	case WM_CLOSE:
		CloseToolWindow(wnd);
		return 1;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
			case IDCANCEL:
			CloseToolWindow(wnd);
			return 1;

		case IDC_REGION:
			if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_CLOSEUP))
			{
				wnd->region = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);

				MemViewRegion& region = s_memoryRegions[wnd->region];
				wnd->address = region.hardwareAddress;
				SetScrollRange(GetDlgItem(hDlg, IDC_MEMVIEWBOX), SB_VERT, 0x00000000, (region.size - 1) >> 4, TRUE);
				SetScrollPos(GetDlgItem(hDlg, IDC_MEMVIEWBOX), SB_VERT, 0x00000000, TRUE);

				wnd->sel = TRUE;
				wnd->selAddress = wnd->address;
				wnd->selPart = 0;
				wnd->selNewVal = 0x00000000;

				wnd->SetTitle(region.longname);

				wnd->SetFocus();
				wnd->Refresh();
			}
			return 1;

		case IDC_VIEWMODE:
			if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_CLOSEUP))
			{
				wnd->viewMode = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);

				wnd->sel = TRUE;
				//wnd->selAddress = 0x00000000;
				wnd->selPart = 0;
				wnd->selNewVal = 0x00000000;

				wnd->SetFocus();
				wnd->Refresh();
			}
			return 1;

		case IDC_GO:
			{
				char addrstr[9];
				int len;
				int i;
				int shift;
				BOOL error = FALSE;
				u32 address = 0x00000000;

				len = GetWindowText(gAddress, addrstr, 9);

				for(i = 0; i < len; i++)
				{
					char ch = addrstr[i];

					if((ch >= '0') && (ch <= '9'))
						continue;

					if((ch >= 'A') && (ch <= 'F'))
						continue;

					if((ch >= 'a') && (ch <= 'f'))
						continue;

					if(ch == '\0')
						break;

					error = TRUE;
					break;
				}

				if(error)
				{
					MessageBox(hDlg, "Error:\nInvalid address specified.\nThe address must be an hexadecimal value.", "DeSmuME", (MB_OK | MB_ICONERROR));
					SetWindowText(gAddress, "");
					return 1;
				}

				for(i = (len-1), shift = 0; i >= 0; i--, shift += 4)
				{
					char ch = addrstr[i];

					if((ch >= '0') && (ch <= '9'))
						address |= ((ch - '0') << shift);
					else if((ch >= 'A') && (ch <= 'F'))
						address |= ((ch - 'A' + 0xA) << shift);
					else if((ch >= 'a') && (ch <= 'f'))
						address |= ((ch - 'a' + 0xA) << shift);
				}

				MemViewRegion& region = s_memoryRegions[wnd->region];
				if (wnd->region == MEMVIEW_ARM9 || wnd->region == MEMVIEW_ARM7)
				{
					region.hardwareAddress = address & 0xFF000000;
				}
				HWAddressType addrMin = (region.hardwareAddress) & 0xFFFFFF00;
				HWAddressType addrMax = max((u32)addrMin, (region.hardwareAddress + region.size - 0x100 - 1) & 0xFFFFFF00);

				wnd->address = max((u32)addrMin, min((u32)addrMax, (address & 0xFFFFFFF0)));

				wnd->sel = TRUE;
				wnd->selAddress = wnd->address + (address & 0x0000000F);
				wnd->selPart = 0;
				wnd->selNewVal = 0x00000000;

				// ====================== add address in list
				if (ComboBox_GetCount(gAddress) == MAX_ADDRESS_SAVE)
					ComboBox_DeleteString(gAddress, ComboBox_GetCount(gAddress) - 1);

				// remove duplicate address
				u16 num = ComboBox_GetCount(gAddress);
				for (u16 i = 0; i < num; i++)
				{
					char hex[16] = {0};
					ComboBox_GetLBText(gAddress, i, (LPCTSTR)&hex[0]);
					if (strcmp(addrstr, hex) == 0)
						ComboBox_DeleteString(gAddress, i);
				}
				// add to list
				ComboBox_InsertString(gAddress, 0, addrstr);
				ComboBox_SetText(gAddress, addrstr);


				SetScrollPos(GetDlgItem(hDlg, IDC_MEMVIEWBOX), SB_VERT, (((wnd->address - region.hardwareAddress) >> 4) & 0x000FFFFF), TRUE);
				wnd->Refresh();
				wnd->SetFocus();
			}
			return 1;

		case IDC_TEXTDUMP:
			{
				char fileName[256] = "";
				OPENFILENAME ofn;

				ZeroMemory(&ofn, sizeof(ofn));
				ofn.lStructSize = sizeof(ofn);
				ofn.hwndOwner = hDlg;
				ofn.lpstrFilter = "Text file (*.txt)\0*.txt\0Any file (*.*)\0*.*\0\0";
				ofn.nFilterIndex = 1;
				ofn.lpstrFile = fileName;
				ofn.nMaxFile = 256;
				ofn.lpstrDefExt = "txt";
				ofn.Flags = OFN_NOCHANGEDIR | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;

				if(GetSaveFileName(&ofn))
				{
					FILE *f;
					u8 memory[0x100];
					int line;

					memRead(memory, (MemRegionType)wnd->region, wnd->address, 0x100);

					f = fopen(fileName, "a");

					for(line = 0; line < 16; line++)
					{
						int i;
						
						fprintf(f, "%08X\t\t", (wnd->address + (line << 4)));

						switch(wnd->viewMode)
						{
						case 0:
							{
								for(i = 0; i < 16; i++)
								{
									fprintf(f, "%02X ", T1ReadByte(memory, ((line << 4) + i)));
								}
								fprintf(f, "\t");
							}
							break;

						case 1:
							{
								for(i = 0; i < 16; i += 2)
								{
									fprintf(f, "%04X ", T1ReadWord(memory, ((line << 4) + i)));
								}
								fprintf(f, "\t\t");
							}
							break;

						case 2:
							{
								for(i = 0; i < 16; i += 4)
								{
									fprintf(f, "%08X ", T1ReadLong(memory, ((line << 4) + i)));
								}
								fprintf(f, "\t\t\t");
							}
							break;
						}

						for(i = 0; i < 16; i++)
						{
							u8 val = T1ReadByte(memory, ((line << 4) + i));
									
							if((val >= 32) && (val <= 127))
								fprintf(f, "%c", (char)val);
							else
								fprintf(f, ".");
						}
						fprintf(f, "\n");
					}

					fclose(f);
				}
			}
			return 1;

		case IDC_DUMPALL:
		case IDC_RAWDUMP:
			{
				char fileName[256] = "";
				OPENFILENAME ofn;

				ZeroMemory(&ofn, sizeof(ofn));
				ofn.lStructSize = sizeof(ofn);
				ofn.hwndOwner = hDlg;
				ofn.lpstrFilter = "Binary file (*.bin)\0*.bin\0Any file (*.*)\0*.*\0\0";
				ofn.nFilterIndex = 1;
				ofn.lpstrFile = fileName;
				ofn.nMaxFile = 256;
				ofn.lpstrDefExt = "bin";
				ofn.Flags = OFN_NOCHANGEDIR | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;

				if(GetSaveFileName(&ofn))
				{

					if(LOWORD(wParam) == IDC_RAWDUMP)
					{
						EMUFILE_FILE f(fileName,"ab");
						u8 memory[0x100];
						memRead(memory, (MemRegionType)wnd->region, wnd->address, 0x100);
						f.fwrite(memory, 0x100);
					}
					else
					{
						EMUFILE_FILE f(fileName,"wb");
						switch(wnd->region)
						{
						case MEMVIEW_ARM9:
						case MEMVIEW_ARM7:
							DEBUG_dumpMemory(&f);
							break;
						default:
							{
								const size_t blocksize = 0x100;
								byte* memory = new byte[blocksize];
								if (memory != NULL)
								{
									MemViewRegion& region = s_memoryRegions[wnd->region];
									for (HWAddressType address = region.hardwareAddress;
										address < region.hardwareAddress + region.size; address += blocksize)
									{
										size_t size = blocksize;
										if (address + size > region.hardwareAddress + region.size)
										{
											size = region.size - (address - region.hardwareAddress);
										}
										memRead(memory, (MemRegionType)wnd->region, address, size);
										f.fwrite(memory, size);
									}
									delete [] memory;
								}
							}	break;
						}
					}
				}
			}
			return 1;

		case IDC_BIG_ENDIAN:
			wnd->Refresh();
			wnd->SetFocus();
			return 1;

		case IDC_FULL_CHARS:
			wnd->Refresh();
			wnd->SetFocus();
			return 1;
		}
		return 0;
	}
예제 #3
0
LRESULT CALLBACK MemView_ViewBoxProc(HWND hCtl, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	CMemView* wnd = (CMemView*)GetWindowLongPtr(hCtl, DWLP_USER);

	switch(uMsg)
	{
	case WM_NCCREATE:
		SetScrollRange(hCtl, SB_VERT, 0x00000000, 0x000FFFF0, TRUE);
		SetScrollPos(hCtl, SB_VERT, 0x00000000, TRUE);
		return 1;

	case WM_NCDESTROY:
		return 1;
	
	case WM_ERASEBKGND:
		return 1;

	case WM_PAINT:
		MemView_ViewBoxPaint(wnd, hCtl, wParam, lParam);
		return 1;

	case WM_LBUTTONDOWN:
		{
			HDC hdc;
			HFONT font;
			SIZE fontsize;
			int x, y;

			wnd->sel = FALSE;
			wnd->selAddress = 0x00000000;
			wnd->selPart = 0;
			wnd->selNewVal = 0x00000000;

			hdc = GetDC(hCtl);
			font = (HFONT)SelectObject(hdc, wnd->font);
			GetTextExtentPoint32(hdc, " ", 1, &fontsize);
			
			x = LOWORD(lParam);
			y = HIWORD(lParam);

			if((x >= ((fontsize.cx * 8) + 5)) && (y >= (fontsize.cy + 3)))
			{
				int line, col;

				x -= ((fontsize.cx * 8) + 5);
				y -= (fontsize.cy + 3);
				
				line = (y / fontsize.cy);

				switch(wnd->viewMode)
				{
				case 0:
					{
						if((x < (fontsize.cx * 2)) || (x >= (fontsize.cx * (2 + ((2+1) * 16)))))
							break;

						col = ((x - (fontsize.cx * 2)) / (fontsize.cx * (2+1)));

						wnd->sel = TRUE;
						
					}
					break;

				case 1:
					{
						if((x < (fontsize.cx * 6)) || (x >= (fontsize.cx * (6 + ((4+1) * 8)))))
							break;

						col = ((x - (fontsize.cx * 6)) / (fontsize.cx * (4+1)) * 2);

						wnd->sel = TRUE;
						
					}
					break;

				case 2:
					{
						if((x < (fontsize.cx * 8)) || (x >= (fontsize.cx * (8 + ((8+1) * 4)))))
							break;

						col = ((x - (fontsize.cx * 8)) / (fontsize.cx * (8+1)) * 4);

						wnd->sel = TRUE;
						
					}
					break;
				}
				
				wnd->selAddress = (wnd->address + (line << 4) + col);
				wnd->selPart = 0;
				wnd->selNewVal = 0x00000000;
			}

			SelectObject(hdc, font);
			ReleaseDC(hCtl, hdc);

			SetFocus(hCtl);				/* Required to receive keyboard messages */
			wnd->Refresh();
		}
		return 1;

	case WM_CHAR:
		{
			char ch = (char)wParam;

			if(((ch >= '0') && (ch <= '9')) || ((ch >= 'A') && (ch <= 'F')) || ((ch >= 'a') && (ch <= 'f')))
			{
				u8 maxSelPart[3] = {2, 4, 8};

				wnd->selNewVal <<= 4;
				wnd->selPart++;

				if((ch >= '0') && (ch <= '9'))
					wnd->selNewVal |= (ch - '0');
				else if((ch >= 'A') && (ch <= 'F'))
					wnd->selNewVal |= (ch - 'A' + 0xA);
				else if((ch >= 'a') && (ch <= 'f'))
					wnd->selNewVal |= (ch - 'a' + 0xA);

				if(wnd->selPart >= maxSelPart[wnd->viewMode])
				{
					switch(wnd->viewMode)
					{
					case 0: MMU_write8(wnd->cpu, wnd->selAddress, (u8)wnd->selNewVal); wnd->selAddress++; break;
					case 1: MMU_write16(wnd->cpu, wnd->selAddress, (u16)wnd->selNewVal); wnd->selAddress += 2; break;
					case 2: MMU_write32(wnd->cpu, wnd->selAddress, wnd->selNewVal); wnd->selAddress += 4; break;
					}
					wnd->selPart = 0;
					wnd->selNewVal = 0x00000000;

					if(wnd->selAddress == 0x00000000)
					{
						wnd->sel = FALSE;
					}
					else if(wnd->selAddress >= (wnd->address + 0x100))
					{
						wnd->address = min((u32)0xFFFFFF00, (wnd->address + 0x10));
						SetScrollPos(hCtl, SB_VERT, ((wnd->address >> 4) & 0x000FFFFF), TRUE);
					}
				}
			}

			wnd->Refresh();
		}