diff --git a/src/drivers/win/debugger.cpp b/src/drivers/win/debugger.cpp
index e942b3928..ec9aaa1f4 100644
--- a/src/drivers/win/debugger.cpp
+++ b/src/drivers/win/debugger.cpp
@@ -114,9 +114,9 @@ struct DBGCOLORMENU {
 
 bool ChangeColor(HWND hwnd, DBGCOLORMENU* item)
 {
-	if (ChangeColor(hwnd, (COLORMENU*)item))
+	if (ChangeColor(hwnd, (CHOOSECOLORINFO*)item))
 	{
-		item->fmt->crTextColor = RGB(*item->menu.r, *item->menu.g, *item->menu.b);
+		item->fmt->crTextColor = RGB(*item->menu.info.r, *item->menu.info.g, *item->menu.info.b);
 		return true;
 	}
 	return false;
@@ -149,28 +149,51 @@ void UpdateOtherDebuggingDialogs()
 	PPUViewDoBlit();		//PPU Viewer
 }
 
-#define DISASM_DEFAULT_WIDTH (debuggerIDAFont ? 540 : 470)
-
+// owomomo: these values should alwasy sync with default debugger window size changes.
+/*
+  The default width of disasm view.
+  ***NOTE: Currently disasm text is NOT scaled with the screen dpi, so DO NOT use 
+  Muldiv(DISASM_DEFAULT_WIDTH, GetDeviceCaps(hdc, LOGPIXELSY), 96) to convert this
+  value!
+*/
+#define DISASM_DEFAULT_WIDTH (debuggerIDAFont ? 540 : 470) 
+
+/*
+  The left and right margin of the disasm view in the debugger window, it can be
+  caclulated by the size of the debugger and the disasm view. 
+  Here's an fake code example of how to get this value:
+  
+  RECT wndRect, disasmRect;
+  GetWindowRect(hDebug, &wndRect);
+  GetWindowRect(GetDlgItem(hDebug, IDC_DEBUGGER_DISASSEMBLY), &disasmRect);
+  (disasmRect.left - wndRect.left) + (wndRect.right - disasmRect.right);
+
+  The reason why I directly write it here is to deal with the situation when debugger
+  width is narrow that some of the left panel is not shown in the window,
+  (wndRect.right - disasmRect.right) can't get the right value.
+*/
+#define DISASM_MARGIN 378
+
+/*
+  When the window size is smaller than these values, the window itself can be shrinked
+  more, but the panel will keep their minimum size. 
+*/
 #define DEBUGGER_MIN_HEIGHT_LEFT 120 // Minimum height for the left part
 #define DEBUGGER_MIN_HEIGHT_RIGHT 590 // Minimun height for the right part.
+#define DEBUGGER_MIN_WIDTH 380 // Minimum width for debugger
 
-#define DEBUGGER_MIN_WIDTH 360 // Minimum width for debugger
 #define DEBUGGER_DEFAULT_HEIGHT 594 // default height for debugger
-// owomomo: default width of the debugger is depend on the default width of disasm view, so it's not defined here.
-
+/*
+  The default width of the debugger is depend on the default width of disasm view,
+  Since the margin varies from screen dpi but disasm view is not, they cant' use
+  so it's not defined here.
+*/
+// #define DEBUGGER_DEFAULT_WIDTH (DISASM_MARGIN + DISASM_DEFAULT_WIDTH)
 void RestoreSize(HWND hwndDlg)
 {
 	HDC hdc = GetDC(hwndDlg);
-	RECT wndRect, disasmRect;
-	GetWindowRect(hwndDlg, &wndRect);
-	GetWindowRect(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), &disasmRect);
-
-	int default_width = (disasmRect.left - wndRect.left) + DISASM_DEFAULT_WIDTH + (wndRect.right - disasmRect.right);
-	int default_height = MulDiv(DEBUGGER_DEFAULT_HEIGHT, GetDeviceCaps(hdc, LOGPIXELSY), 96);
-
+	SetWindowPos(hwndDlg,HWND_TOP, DbgPosX, DbgPosY, MulDiv(DISASM_MARGIN, GetDeviceCaps(hdc, LOGPIXELSY), 96) + DISASM_DEFAULT_WIDTH, MulDiv(DEBUGGER_DEFAULT_HEIGHT, GetDeviceCaps(hdc, LOGPIXELSY), 96), SWP_SHOWWINDOW);
 	ReleaseDC(hwndDlg, hdc);
-	
-	SetWindowPos(hwndDlg,HWND_TOP,DbgPosX,DbgPosY,default_width,default_height,SWP_SHOWWINDOW);
 }
 
 unsigned int NewBreakWindows(HWND hwndDlg, unsigned int num, bool enable)
@@ -483,6 +506,7 @@ void HighlightSyntax(HWND hWnd, int lines)
 		wordbreak = SendDlgItemMessage(hWnd, IDC_DEBUGGER_DISASSEMBLY, EM_FINDWORDBREAK, (WPARAM)WB_RIGHT, (LPARAM)newline.chrg.cpMin + 21);
 		for (int ch = newline.chrg.cpMin; ; ch++)
 		{
+
 			if (debug_wstr[ch] == L'=' || debug_wstr[ch] == L'@' || debug_wstr[ch] == L'\n' || debug_wstr[ch] == L'-' || debug_wstr[ch] == L';')
 			{
 				opbreak = ch;
@@ -592,7 +616,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
 	//figure out how many lines we can draw
 	RECT rect;
 	GetClientRect(GetDlgItem(hWnd, id), &rect);
-	int lines = (rect.bottom-rect.top) / debugSystem->disasmFontHeight;
+	int lines = (rect.bottom-rect.top) / debugSystem->disasmLineHeight;
 
 	debug_wstr[0] = 0;
 	PCLine = -1;
@@ -983,6 +1007,21 @@ void UpdateBreakpointsCaption()
 	SetDlgItemText(hDebug, IDC_DEBUGGER_BREAKPOINTS, str);
 }
 
+int GetDebuggerLineHeight(HWND hwnd)
+{
+	FINDTEXT _newline = newline;
+	_newline.chrg.cpMin = 0;
+	_newline.chrg.cpMax = -1;
+	_newline.chrg.cpMin = SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_FINDTEXT, FR_DOWN, (LPARAM)&_newline) + 1;
+	_newline.chrg.cpMax = SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_FINDTEXT, FR_DOWN, (LPARAM)&_newline) + 1;
+
+	POINT line1, line2;
+	SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_POSFROMCHAR, (WPARAM)&line1, _newline.chrg.cpMin);
+	SendDlgItemMessage(hwnd, IDC_DEBUGGER_DISASSEMBLY, EM_POSFROMCHAR, (WPARAM)&line2, _newline.chrg.cpMax);
+
+	return line2.y - line1.y;
+}
+
 void UpdateDebugger(bool jump_to_pc)
 {
 	//don't do anything if the debugger is not visible
@@ -1003,7 +1042,7 @@ void UpdateDebugger(bool jump_to_pc)
 		// ensure that PC pointer will be visible even after the window was resized
 		RECT rect;
 		GetClientRect(GetDlgItem(hDebug, IDC_DEBUGGER_DISASSEMBLY), &rect);
-		unsigned int lines = (rect.bottom-rect.top) / debugSystem->disasmFontHeight;
+		unsigned int lines = (rect.bottom-rect.top) / debugSystem->disasmLineHeight;
 		if (PC_pointerOffset >= lines)
 			PC_pointerOffset = 0;
 
@@ -1799,7 +1838,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
 	{
 		case WM_LBUTTONDBLCLK:
 		{
-			int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmFontHeight, false);
+			int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmLineHeight, false);
 			if (offset != EOF)
 			{
 				// bring "Add Breakpoint" dialog
@@ -1813,7 +1852,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
 		}
 		case WM_LBUTTONUP:
 		{
-			Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmFontHeight, true);
+			Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmLineHeight, true);
 			break;
 		}
 		case WM_RBUTTONDOWN:
@@ -1838,7 +1877,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
 			CallWindowProc(IDC_DEBUGGER_DISASSEMBLY_oldWndProc, hwndDlg, WM_LBUTTONDOWN, wParam, lParam);
 			CallWindowProc(IDC_DEBUGGER_DISASSEMBLY_oldWndProc, hwndDlg, WM_LBUTTONUP, wParam, lParam);
 			// try bringing Symbolic Debug Naming dialog
-			int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmFontHeight, false);
+			int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->disasmLineHeight, false);
 			if (offset != EOF)
 			{
 				if (DoSymbolicDebugNaming(offset, hDebug))
@@ -1875,7 +1914,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
 			if(mouse_y < 0 || mouse_x < 0)
 				break;
 
-			tmp = mouse_y / debugSystem->disasmFontHeight;
+			tmp = mouse_y / debugSystem->disasmLineHeight;
 			if (tmp < (int)disassembly_addresses.size())
 			{
 				i = disassembly_addresses[tmp];
@@ -1986,7 +2025,6 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 			SetScrollInfo(GetDlgItem(hwndDlg,IDC_DEBUGGER_DISASSEMBLY_VSCR),SB_CTL,&si,TRUE);
 
 			//setup font
-			SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_DISASSEMBLY,WM_SETFONT,(WPARAM)debugSystem->hDisasmFont,FALSE);
 			SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_DISASSEMBLY_LEFT_PANEL,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
 			//SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_A,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
 			//SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_VAL_X,WM_SETFONT,(WPARAM)debugSystem->hFixedFont,FALSE);
@@ -2037,6 +2075,25 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 			// prevent the font of the edit control from screwing up when it contains MBC or characters not contained the current font.
 			SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, EM_SETLANGOPTIONS, 0, SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONT);
 
+			/* owomomo: calculate the actural line height of the disassembly view.
+			the font height is not always equals to the line height in rich edit control.
+			As most developers uses latin letters, the font height and line height are 
+			same in their Windows, but there are many languages aren't.
+			This is probably why this bug is not mentioned and fixed for a long time.
+			*/
+			SetDlgItemText(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, "\r\n\r\n\r\n");
+
+			SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hIDAFont, FALSE);
+			debugSystem->IDAFontLineHeight = GetDebuggerLineHeight(hwndDlg);
+
+			SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hFixedFont, FALSE);
+			debugSystem->fixedFontLineHeight = GetDebuggerLineHeight(hwndDlg);
+
+			debugSystem->hDisasmFont = debuggerIDAFont ? debugSystem->hIDAFont : debugSystem->hFixedFont;
+			debugSystem->disasmLineHeight = debuggerIDAFont ? debugSystem->IDAFontLineHeight : debugSystem->fixedFontLineHeight;
+			if (debuggerIDAFont)
+				SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hDisasmFont, FALSE);
+
 			// subclass editfield
 			IDC_DEBUGGER_DISASSEMBLY_oldWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), GWLP_WNDPROC, (LONG_PTR)IDC_DEBUGGER_DISASSEMBLY_WndProc);
 
@@ -2100,8 +2157,6 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 			}
 			break;
 		}
-
-
 		case WM_CLOSE:
 		case WM_QUIT:
 			//exitdebug:
@@ -2140,7 +2195,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 						case DEBUGIDAFONT:
 							debuggerIDAFont ^= 1;
 							debugSystem->hDisasmFont = debuggerIDAFont ? debugSystem->hIDAFont : debugSystem->hFixedFont;
-							debugSystem->disasmFontHeight = debuggerIDAFont ? IDAFontSize : debugSystem->fixedFontHeight;
+							debugSystem->disasmLineHeight = debuggerIDAFont ? debugSystem->IDAFontLineHeight : debugSystem->fixedFontLineHeight;
 							SendDlgItemMessage(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, WM_SETFONT, (WPARAM)debugSystem->hDisasmFont, FALSE);
 							UpdateDebugger(false);
 							break;
@@ -2171,7 +2226,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 								RestoreDefaultDebugColor();
 								RECT rect;
 								GetClientRect(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), &rect);
-								UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmFontHeight);
+								UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmLineHeight);
 								HMENU hcolorpopupmenu = GetSubMenu(GetMenu(hwndDlg), 1);
 								for (int i = 0; i < sizeof(dbgcolormenu) / sizeof(DBGCOLORMENU); ++i)
 									ModifyColorMenu(hwndDlg, hcolorpopupmenu, &dbgcolormenu[i].menu, i, ID_COLOR_DEBUGGER + i);
@@ -2197,7 +2252,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 							{
 								RECT rect;
 								GetClientRect(GetDlgItem(hwndDlg, IDC_DEBUGGER_DISASSEMBLY), &rect);
-								UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmFontHeight);
+								UpdateDisassembleView(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, (rect.bottom - rect.top) / debugSystem->disasmLineHeight);
 								ModifyColorMenu(hwndDlg, GetSubMenu(GetMenu(hwndDlg), 1), &dbgcolormenu[index].menu, index, wParam);
 							}
 						}
@@ -2344,11 +2399,11 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 				}
 				SetScrollInfo((HWND)lParam,SB_CTL,&si,TRUE);
 
-				Disassemble(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, si.nPos);
+				Disassemble(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, si.nPos);
 				// "Address Bookmark Add" follows the address
 				char str[16];
 				sprintf(str,"%04X", si.nPos);
-				SetDlgItemText(hDebug, IDC_DEBUGGER_BOOKMARK, str);
+				SetDlgItemText(hwndDlg, IDC_DEBUGGER_BOOKMARK, str);
 				break;
 			}
 			case WM_KEYDOWN:
@@ -2365,18 +2420,18 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 				{
 					setString = true;
 					RECT rectDisassembly;
-					GetClientRect(GetDlgItem(hDebug,IDC_DEBUGGER_DISASSEMBLY),&rectDisassembly);
+					GetClientRect(GetDlgItem(hwndDlg,IDC_DEBUGGER_DISASSEMBLY),&rectDisassembly);
 					int height = rectDisassembly.bottom-rectDisassembly.top;
 					mouse_y -= 10;
 					if(mouse_y > height)
 						setString = false;
-					mouse_y /= debugSystem->disasmFontHeight;
+					mouse_y /= debugSystem->disasmLineHeight;
 				}
 
 				if (setString)
-					SetDlgItemText(hDebug, IDC_DEBUGGER_ADDR_LINE, "Leftclick = Inline Assembler. Midclick = Game Genie. Rightclick = Hexeditor.");
+					SetDlgItemText(hwndDlg, IDC_DEBUGGER_ADDR_LINE, "Leftclick = Inline Assembler. Midclick = Game Genie. Rightclick = Hexeditor.");
 				else
-					SetDlgItemText(hDebug, IDC_DEBUGGER_ADDR_LINE, "");
+					SetDlgItemText(hwndDlg, IDC_DEBUGGER_ADDR_LINE, "");
 				break;
 			}
 			case WM_LBUTTONDOWN:
@@ -2391,7 +2446,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 				if (FCEUI_EmulationPaused() && (mouse_x > 6) && (mouse_x < 30) && (mouse_y > 10))
 				{
 // ################################## End of SP CODE ###########################
-					int tmp = (mouse_y - 10) / debugSystem->disasmFontHeight;
+					int tmp = (mouse_y - 10) / debugSystem->disasmLineHeight;
 					if (tmp < (int)disassembly_addresses.size())
 					{
 						int i = disassembly_addresses[tmp];
@@ -2413,7 +2468,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 				//mbg merge 7/18/06 changed pausing check
 				if (FCEUI_EmulationPaused() && (mouse_x > 6) && (mouse_x < 30) && (mouse_y > 10))
 				{
-					int tmp = (mouse_y - 10) / debugSystem->disasmFontHeight;
+					int tmp = (mouse_y - 10) / debugSystem->disasmLineHeight;
 					if (tmp < (int)disassembly_addresses.size())
 					{
 						int i = disassembly_addresses[tmp];
@@ -2434,7 +2489,7 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 				//mbg merge 7/18/06 changed pausing check
 				if (FCEUI_EmulationPaused() && (mouse_x > 6) && (mouse_x < 30) && (mouse_y > 10))
 				{
-					int tmp = (mouse_y - 10) / debugSystem->disasmFontHeight;
+					int tmp = (mouse_y - 10) / debugSystem->disasmLineHeight;
 					if (tmp < (int)disassembly_addresses.size())
 					{
 						int i = disassembly_addresses[tmp];
@@ -2567,10 +2622,10 @@ INT_PTR CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
 								{
 									sprintf(str,"%04X", tmp);
 									SetDlgItemText(hwndDlg,IDC_DEBUGGER_VAL_PCSEEK,str);
-									Disassemble(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, tmp);
+									Disassemble(hwndDlg, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, tmp);
 									// "Address Bookmark Add" follows the address
 									sprintf(str,"%04X", si.nPos);
-									SetDlgItemText(hDebug, IDC_DEBUGGER_BOOKMARK, str);
+									SetDlgItemText(hwndDlg, IDC_DEBUGGER_BOOKMARK, str);
 								}
 								break;
 							}
@@ -2839,7 +2894,6 @@ void DebugSystem::init()
 	SelectObject(hdc,old);
 	DeleteDC(hdc);
 	hDisasmFont = debuggerIDAFont ? hIDAFont : hFixedFont;
-	disasmFontHeight = debuggerIDAFont ? IDAFontSize : fixedFontHeight;
 
 	InitDbgCharFormat();
 
diff --git a/src/drivers/win/debugger.h b/src/drivers/win/debugger.h
index 2063229e2..68abf8ab7 100644
--- a/src/drivers/win/debugger.h
+++ b/src/drivers/win/debugger.h
@@ -57,11 +57,14 @@ extern class DebugSystem {
 	HFONT hFixedFont;
 	int fixedFontWidth;
 	int fixedFontHeight;
+	int fixedFontLineHeight;
 
 	HFONT hIDAFont;
+	int IDAFontLineHeight;
 
 	HFONT hDisasmFont;
-	int disasmFontHeight;
+
+	int disasmLineHeight;
 
 	HFONT hHexeditorFont;
 	int HexeditorFontWidth;
@@ -138,7 +141,7 @@ _OP(DbgRts,    187,  80,  93)      /* Imayou */
 #define SPCLR(pf, name, suf) pf SBCLR(name, suf)
 #define CSCLR(pf, name, suf, op, val) SPCLR(pf, name, suf) op val
 #define CNRGB(pf, name, op, r, g, b, sep) CSCLR(pf, name, R, op, r) sep CSCLR(pf, name, G, op, g) sep CSCLR(pf, name, B, op, b)
-#define PPRGB(name) NULL, CNRGB(&, name, , , , , _COMMA)
+#define PPRGB(name) CNRGB(&, name, , , , , _COMMA), NULL
 #define MKRGB(name) (RGB(SBCLR(name, R), SBCLR(name, G), SBCLR(name, B)))
 #define DEFRGB(name, r, g, b) CNRGB( , name, =, r, g, b, _COMMA)
 #define DCLRGB(name, r, g, b) CNRGB( , name, , , , , _COMMA)
diff --git a/src/drivers/win/memview.cpp b/src/drivers/win/memview.cpp
index 66367835b..50d48b103 100644
--- a/src/drivers/win/memview.cpp
+++ b/src/drivers/win/memview.cpp
@@ -2396,7 +2396,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
 		case ID_COLOR_HEXEDITOR + 9:
 		{
 			int index = wParam - ID_COLOR_HEXEDITOR;
-			if (ChangeColor(hwnd, &hexcolormenu[index]))
+			if (ChangeColor(hwnd, (CHOOSECOLORINFO*)&hexcolormenu[index]))
 			{
 				UpdateColorTable();
 				ModifyColorMenu(hwnd, GetHexColorMenu(hwnd), &hexcolormenu[index], index, wParam);
@@ -2426,7 +2426,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
 		case ID_COLOR_CDLOGGER + 9:
 		{
 			int index = wParam - ID_COLOR_CDLOGGER;
-			if (ChangeColor(hwnd, &cdlcolormenu[index]))
+			if (ChangeColor(hwnd, (CHOOSECOLORINFO*)&cdlcolormenu[index]))
 			{
 				UpdateColorTable();
 				ModifyColorMenu(hwnd, GetCdlColorMenu(hwnd), &cdlcolormenu[index], index, wParam);
@@ -2438,7 +2438,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
 		{
 			RestoreDefaultCdlColor();
 			UpdateColorTable();
-			for (int i = 0; i < sizeof(hexcolormenu) / sizeof(COLORMENU); ++i)
+			for (int i = 0; i < sizeof(cdlcolormenu) / sizeof(COLORMENU); ++i)
 				ModifyColorMenu(hwnd, GetCdlColorMenu(hwnd), &cdlcolormenu[i], i, ID_COLOR_CDLOGGER + i);
 		}
 		break;
@@ -3241,7 +3241,7 @@ void SwitchEditingText(int editingText) {
 	}
 }
 
-bool ChangeColor(HWND hwnd, COLORMENU* item)
+bool ChangeColor(HWND hwnd, CHOOSECOLORINFO* item)
 {
 	int backup = RGB(*item->r, *item->g, *item->b);
 	CHOOSECOLOR choose;
@@ -3249,8 +3249,10 @@ bool ChangeColor(HWND hwnd, COLORMENU* item)
 	choose.lStructSize = sizeof(CHOOSECOLOR);
 	choose.hwndOwner = hwnd;
 	choose.rgbResult = backup;
+	choose.lCustData = (LPARAM)item;
 	choose.lpCustColors = custom_color;
-	choose.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ANYCOLOR;
+	choose.lpfnHook = (LPCCHOOKPROC)ChooseColorHookProc;
+	choose.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ANYCOLOR | CC_ENABLEHOOK;
 	if (ChooseColor(&choose) && choose.rgbResult != backup)
 	{
 		*item->r = GetRValue(choose.rgbResult);
@@ -3270,26 +3272,16 @@ BOOL OpColorMenu(HWND hwnd, HMENU menu, COLORMENU* item, int pos, int id, BOOL (
 	memset(&info, 0, sizeof(MENUITEMINFO));
 	info.cbSize = sizeof(MENUITEMINFO);
 
-	if (item->text)
+	CHOOSECOLORINFO *color_info = (CHOOSECOLORINFO*)item;
+	if (color_info->name)
 	{
-		HDC hdc = GetDC(hwnd);
-		HDC memdc = CreateCompatibleDC(hdc);
-		
-		int width = GetSystemMetrics(SM_CXMENUCHECK);
-		int height = GetSystemMetrics(SM_CYMENUCHECK);
-
-		if (!item->bitmap)
-			item->bitmap = CreateCompatibleBitmap(hdc, width, height);
-		SelectObject(memdc, item->bitmap);
-		HBRUSH brush = CreateSolidBrush(RGB(*item->r, *item->g, *item->b));
-		RECT rect = { 1, 1, width - 1, height - 1};
-		FillRect(memdc, &rect, brush);
-		DeleteObject(brush);
-		DeleteDC(memdc);
-		ReleaseDC(hwnd, hdc);
+
+		if (item->bitmap)
+			DeleteObject(item->bitmap);
+		item->bitmap = CreateColorBitmap(hwnd, GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK), RGB(*color_info->r, *color_info->g, *color_info->b));
 
 		char menu_str[64];
-		sprintf(menu_str, "%s\t#%02X%02X%02X", item->text, *item->r, *item->g, *item->b);
+		sprintf(menu_str, "%s\t#%02X%02X%02X", color_info->name, *color_info->r, *color_info->g, *color_info->b);
 
 		info.dwTypeData = menu_str;
 		info.cch = strlen(menu_str);
@@ -3306,4 +3298,68 @@ BOOL OpColorMenu(HWND hwnd, HMENU menu, COLORMENU* item, int pos, int id, BOOL (
 	}
 
 	return opMenu(menu, pos, TRUE, &info);
+}
+
+UINT CALLBACK ChooseColorHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
+{
+	static HICON icon;
+
+	switch (uiMsg)
+	{
+		case WM_INITDIALOG:
+		{
+			CHOOSECOLORINFO* item = (CHOOSECOLORINFO*)((CHOOSECOLOR*)lParam)->lCustData;
+
+			char title[128];
+			strcpy(title, "Choose color for ");
+			strcat(title, item->name);
+			SetWindowText(hdlg, title);
+
+			icon = CreateChooseColorIcon(hdlg, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), RGB(*item->r, *item->g, *item->b));
+			SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)icon);
+			break;
+		}
+		case WM_CLOSE:
+		case WM_QUIT:
+			DestroyIcon(icon);
+	}
+
+	return FALSE;
+}
+
+HBITMAP CreateColorBitmap(HWND hwnd, int width, int height, COLORREF color)
+{
+
+	HDC hdc = GetDC(hwnd);
+	HDC memdc = CreateCompatibleDC(hdc);
+
+	HBITMAP bitmap = CreateCompatibleBitmap(hdc, width, height);
+	HGDIOBJ oldObj = SelectObject(memdc, bitmap);
+	HBRUSH brush = CreateSolidBrush(color);
+	RECT rect = { 1, 1, width - 1, height - 1 };
+	FillRect(memdc, &rect, brush);
+
+	SelectObject(memdc, oldObj);
+	DeleteObject(brush);
+	DeleteDC(memdc);
+	ReleaseDC(hwnd, hdc);
+
+	return bitmap;
+}
+
+HICON CreateChooseColorIcon(HWND hwnd, int width, int height, COLORREF color)
+{
+
+	HBITMAP bitmap = CreateColorBitmap(hwnd, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), color);
+
+	ICONINFO info;
+	memset(&info, 0, sizeof(ICONINFO));
+	info.hbmColor = bitmap;
+	info.hbmMask = bitmap;
+	info.fIcon = true;
+	HICON icon = CreateIconIndirect(&info);
+
+	DeleteObject(bitmap);
+
+	return icon;
 }
\ No newline at end of file
diff --git a/src/drivers/win/memview.h b/src/drivers/win/memview.h
index d943744fb..e83e274aa 100644
--- a/src/drivers/win/memview.h
+++ b/src/drivers/win/memview.h
@@ -21,15 +21,24 @@ extern int EditingMode;
 
 extern char* EditString[4];
 
+struct CHOOSECOLORINFO
+{
+	char* name;
+	int *r, *g, *b;
+};
+
 struct COLORMENU {
-	char* text;
+	CHOOSECOLORINFO info;
 	HBITMAP bitmap;
-	int *r, *g, *b;
 };
-bool ChangeColor(HWND hwnd, COLORMENU* item);
+bool ChangeColor(HWND hwnd, CHOOSECOLORINFO* item);
 BOOL OpColorMenu(HWND hwnd, HMENU menu, COLORMENU* item, int pos, int id, BOOL (WINAPI *opMenu)(HMENU hmenu, UINT item, BOOL byPos, LPCMENUITEMINFO info));
 #define InsertColorMenu(hwnd, menu, item, pos, id) OpColorMenu(hwnd, menu, item, pos, id, InsertMenuItem)
 #define ModifyColorMenu(hwnd, menu, item, pos, id) OpColorMenu(hwnd, menu, item, pos, id, SetMenuItemInfo)
 #define GetHexColorMenu(hwnd) (GetSubMenu(GetSubMenu(GetMenu(hwnd), HIGHLIGHTING_SUBMENU_POS), HEXEDITOR_COLOR_SUBMENU_POS))
 #define GetCdlColorMenu(hwnd) (GetSubMenu(GetSubMenu(GetMenu(hwnd), HIGHLIGHTING_SUBMENU_POS), CDLOGGER_COLOR_SUBMENU_POS))
+
+UINT CALLBACK ChooseColorHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
+HBITMAP CreateColorBitmap(HWND hwnd, int width, int height, COLORREF color);
+HICON CreateChooseColorIcon(HWND hwnd, int width, int height, COLORREF color);
 #endif
\ No newline at end of file
diff --git a/src/drivers/win/memwatch.cpp b/src/drivers/win/memwatch.cpp
index 48948ab22..6765ab7ae 100644
--- a/src/drivers/win/memwatch.cpp
+++ b/src/drivers/win/memwatch.cpp
@@ -790,7 +790,7 @@ static INT_PTR CALLBACK MemWatchCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
 			xPositions[i] = r.left;
 
 			// experimental: limit the text length and input to hex values
-			SendDlgItemMessage(hwndDlg, MW_ADDR[i], EM_SETLIMITTEXT, 4, 0);
+			SendDlgItemMessage(hwndDlg, MW_ADDR[i], EM_SETLIMITTEXT, 6, 0);
 			DefaultEditCtrlProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, MW_ADDR[i]), GWLP_WNDPROC, (LONG_PTR)FilterEditCtrlProc);
 		}
 
@@ -1085,8 +1085,8 @@ void RamChange()
 			{
 				case 0: whichADDR = 0; break;	//Addr 1
 				case 1: whichADDR = 1; break;	//Addr 2
-				case 2: whichADDR = 11; break;	//Addr 12
-				case 3: whichADDR = 12; break;	//Addr 13
+				case 2: whichADDR = 12; break;	//Addr 13
+				case 3: whichADDR = 13; break;	//Addr 14
 			}
 			GetDlgItemText(hwndMemWatch, MW_ADDR[whichADDR], editboxnow[x], 6);	//Get Address value of edit00
 			SetDlgItemText(hwndMemWatch, MW_RMADDR[x], editboxnow[x]); //Put Address value
@@ -1129,11 +1129,11 @@ void RamChange()
 
 			}
 			sprintf(editchangem[x], "%d", editcount[x]);	//Convert counter to text
-			SetDlgItemText(hwndMemWatch, EDIT00_RESULTS+x, editchangem[x]);	//Display text in results box
+			SetDlgItemText(hwndMemWatch, MW_RESULT[x], editchangem[x]);	//Display text in results box
 		}
 		else
 		{
-			SetDlgItemText(hwndMemWatch, MEMW_EDIT00RMADDRESS+x, "");
+			SetDlgItemText(hwndMemWatch, MW_RMADDR[x], "");
 		}
 	} //End of for loop	
 }
diff --git a/src/drivers/win/palette.cpp b/src/drivers/win/palette.cpp
index 7ca57ebf1..76283e93e 100644
--- a/src/drivers/win/palette.cpp
+++ b/src/drivers/win/palette.cpp
@@ -3,6 +3,11 @@
 #include "main.h"
 #include "window.h"
 #include "gui.h"
+#include "../../palette.h"
+#include "memview.h"
+
+#define ToGrey(r, g, b) ((int)((float)(r) * 0.299F + (float)(g) * 0.587F + (float)(b) * 0.114F))
+#define GetPaletteIndex(x, y) ((x) > palpv->pvRect.left && (x) < palpv->pvRect.right && (y) > palpv->pvRect.top && (y) < palpv->pvRect.bottom ? floor((float)((x) - palpv->pvRect.left) / palpv->cell_width) + (int)floor((float)((y) - palpv->pvRect.top) / palpv->cell_height) * 16 : -1)
 
 int cpalette_count = 0;
 u8 cpalette[64*8*3] = {0};
@@ -12,7 +17,19 @@ extern int palsharpness;
 extern int palcontrast;
 extern int palbrightness;
 extern bool paldeemphswap;
+bool palcolorindex = false;
 HWND hWndPal = NULL;
+extern pal palette[512], rp2c04001[512], rp2c04002[512], rp2c04003[512], rp2c05004[512], palette_game[64*8], palette_ntsc[64*8], palette_user[64*8], palette_unvarying[23];
+
+struct PALPV {
+	int mouse_index;
+	float cell_height, cell_width;
+	char buf[4];
+	RECT pvRect;
+	SIZE pvSize;
+	HBITMAP pvBitmap;
+	HFONT font;
+} *palpv;
 
 bool SetPalette(const char* nameo)
 {
@@ -38,9 +55,9 @@ bool SetPalette(const char* nameo)
 *
 * @return Flag that indicates failure (0) or success (1)
 **/
-int LoadPaletteFile()
+int LoadPaletteFile(HWND hwnd)
 {
-	const char filter[]="All usable files (*.pal)\0*.pal\0All Files (*.*)\0*.*\0\0";
+	const char filter[]="Palette file (*.pal)\0*.pal\0All Files (*.*)\0*.*\0\0";
 
 	bool success = false;
 	char nameo[2048];
@@ -61,20 +78,131 @@ int LoadPaletteFile()
 	if(GetOpenFileName(&ofn))
 	{
 		success = SetPalette(nameo);
+		if (!success)
+			MessageBox(hwnd, "Error loading palette file.", "Load palette file", MB_OK | MB_ICONERROR);
 	}
 
 	return success;
 }
 
+/**
+* Prompts the user for a palette file and saves that file.
+* @return Flag that indicates failure (0) or success (1)
+**/
+int SavePaletteFile(HWND hwnd)
+{
+	const char filter[] = "Palette file (*.pal)\0*.pal\0All Files (*.*)\0*.*\0\0";
+
+	bool success = false;
+	char nameo[2048];
+
+	// Display save file dialog
+	OPENFILENAME ofn;
+	memset(&ofn, 0, sizeof(ofn));
+	ofn.lStructSize = sizeof(ofn);
+	ofn.hInstance = fceu_hInstance;
+	ofn.lpstrTitle = FCEU_NAME" Save Palette File...";
+	ofn.lpstrFilter = filter;
+	ofn.lpstrDefExt = "pal";
+	nameo[0] = 0;
+	ofn.lpstrFile = nameo;
+	ofn.nMaxFile = 256;
+	ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+	ofn.lpstrInitialDir = 0;
+
+	if (GetSaveFileName(&ofn))
+	{
+		FILE* pal_file = fopen(nameo, "wb");
+		if (pal_file)
+		{
+			fwrite(palo, 64 * 3, 1, pal_file);
+			fclose(pal_file);
+			success = true;
+		}
+		else
+			MessageBox(hwnd, "Error saving palette file.", "Save palette file", MB_OK | MB_ICONERROR);
+	}
+
+	return success;
+}
+
+/**
+* Notify the dialog to redraw the palette preview area
+**/
+void InvalidatePalettePreviewRect(HWND hwnd)
+{
+	InvalidateRect(hwnd, &palpv->pvRect, FALSE);
+	UpdateWindow(hwnd);
+}
+
+void UpdatePalettePreviewCaption(HWND hwnd, int x, int y)
+{
+	int mouse_index = GetPaletteIndex(x, y);
+
+	if (palpv->mouse_index != mouse_index)
+	{
+		if (mouse_index != -1)
+		{
+			char str[64];
+			if (force_grayscale)
+				sprintf(str, "Greyscale $%02X: #%02X (Actural: #%02X%02X%02X)", mouse_index, ToGrey(palo[mouse_index].r, palo[mouse_index].g, palo[mouse_index].b), palo[mouse_index].r, palo[mouse_index].g, palo[mouse_index].b);
+			else
+				sprintf(str, "Color $%02X: #%02X%02X%02X", mouse_index, palo[mouse_index].r, palo[mouse_index].g, palo[mouse_index].b);
+			SetDlgItemText(hwnd, IDC_PALETTE_PREVIEW_GROUPBOX, str);
+		}
+		else
+			SetDlgItemText(hwnd, IDC_PALETTE_PREVIEW_GROUPBOX, "Preview");
+		palpv->mouse_index = mouse_index;
+	}
+}
+
+void UpdatePalettePreviewCaption(HWND hwnd)
+{
+	POINT p;
+	GetCursorPos(&p);
+	ScreenToClient(hwnd, &p);
+
+	palpv->mouse_index = -1;
+	UpdatePalettePreviewCaption(hwnd, p.x, p.y);
+
+}
+
+void UpdateCurrentPaletteName(HWND hwnd)
+{
+	if (!palo)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "None");
+	else if (palo == (pal*)&palette)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "NES Default");
+	else if (palo == (pal*)&rp2c04001)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RP2C04-01");
+	else if (palo == (pal*)&rp2c04002)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RP2C04-02");
+	else if (palo == (pal*)&rp2c04003)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RP2C04-03");
+	else if (palo == (pal*)&rp2c05004)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "RC2C05-04");
+	else if (palo == (pal*)&palette_game)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Game specific");
+	else if (palo == (pal*)&palette_ntsc)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "NTSC");
+	else if (palo == (pal*)&palette_user)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Custom");
+	else if (palo == (pal*)&palette_unvarying)
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Internal");
+	else
+		SetDlgItemText(hwnd, IDC_PALETTE_CURRENT, "Unknown");
+}
+
 /**
 * Callback function for the palette configuration dialog.
 **/
 INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-	char text[40];
+
 	switch(uMsg)
 	{
 		case WM_INITDIALOG:
+		{
 
 			if(ntsccol_enable)
 				CheckDlgButton(hwndDlg, CHECK_PALETTE_ENABLED, BST_CHECKED);
@@ -88,6 +216,9 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
 			if (eoptions & EO_CPALETTE)
 				CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED);
 
+			if (palcolorindex)
+				CheckDlgButton(hwndDlg, CHECK_PALETTE_COLOR_INDEX, BST_CHECKED);
+
 			SendDlgItemMessage(hwndDlg, CTL_TINT_TRACKBAR,       TBM_SETRANGE, 1, MAKELONG(0, 128));
 			SendDlgItemMessage(hwndDlg, CTL_HUE_TRACKBAR,        TBM_SETRANGE, 1, MAKELONG(0, 128));
 			SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR,   TBM_SETRANGE, 1, MAKELONG(0, 100));
@@ -96,6 +227,7 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
 			SendDlgItemMessage(hwndDlg, CTL_PALCONTRAST_TRACKBAR,TBM_SETRANGE, 1, MAKELONG(0, 200));
 			SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR,  TBM_SETRANGE, 1, MAKELONG(0, 100));
 
+			char text[40];
 			FCEUI_GetNTSCTH(&ntsctint, &ntschue);
 			sprintf(text, "Notch: %d%%", palnotch);
 			SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE,   WM_SETTEXT, 0, (LPARAM) text);
@@ -123,9 +255,35 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
 			EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TRACKBAR), ntsccol_enable);
 			EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TRACKBAR), ntsccol_enable);
 
-			break;
-
+			palpv = (PALPV*)malloc(sizeof(PALPV));
+			
+			HWND hpalpv = GetDlgItem(hwndDlg, IDC_PALETTE_PREVIEW);
+			GetClientRect(hpalpv, &palpv->pvRect);
+			palpv->pvSize = *((SIZE*)&palpv->pvRect + 1);
+			ClientToScreen(hpalpv, (POINT*)&palpv->pvRect);
+			ClientToScreen(hpalpv, ((POINT*)&palpv->pvRect) + 1);
+			ScreenToClient(hwndDlg, (POINT*)&palpv->pvRect);
+			ScreenToClient(hwndDlg, ((POINT*)&palpv->pvRect) + 1);
+
+			LOGFONT logFont;
+			GetObject((HANDLE)SendMessage(hwndDlg, WM_GETFONT, NULL, NULL), sizeof(logFont), &logFont);
+			palpv->font = (HFONT)CreateFontIndirect(&logFont);
+
+			palpv->cell_width = (float)palpv->pvSize.cx / 16;
+			palpv->cell_height = (float)palpv->pvSize.cy / 4;
+
+			HDC hdc = GetDC(hwndDlg);
+			HDC memdc = CreateCompatibleDC(hdc);
+			palpv->pvBitmap = CreateCompatibleBitmap(hdc, palpv->pvSize.cx, palpv->pvSize.cy);
+			DeleteDC(memdc);
+			ReleaseDC(hwndDlg, hdc);
+
+			UpdateCurrentPaletteName(hwndDlg);
+			UpdatePalettePreviewCaption(hwndDlg);
+		}
+		break;
 		case WM_HSCROLL:
+		{
 			ntsctint      = SendDlgItemMessage(hwndDlg, CTL_TINT_TRACKBAR,       TBM_GETPOS, 0, (LPARAM)(LPSTR)0);
 			ntschue       = SendDlgItemMessage(hwndDlg, CTL_HUE_TRACKBAR,        TBM_GETPOS, 0, (LPARAM)(LPSTR)0);
 			palnotch      = SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR,   TBM_GETPOS, 0, (LPARAM)(LPSTR)0);
@@ -135,6 +293,7 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
 			palbrightness = SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR,  TBM_GETPOS, 0, (LPARAM)(LPSTR)0);
 			FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue);
 
+			char text[40];
 			sprintf(text, "Notch: %d%%", palnotch);
 			SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE,   WM_SETTEXT, 0, (LPARAM) text);
 			sprintf(text, "Saturation: %d%%", palsaturation);
@@ -145,92 +304,244 @@ INT_PTR CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
 			SendDlgItemMessage(hwndDlg, STATIC_CONTRASTVALUE,WM_SETTEXT, 0, (LPARAM) text);
 			sprintf(text, "Brightness: %d%%", palbrightness);
 			SendDlgItemMessage(hwndDlg, STATIC_BRIGHTVALUE,  WM_SETTEXT, 0, (LPARAM) text);
-			break;
 
-		case WM_CLOSE:
-		case WM_QUIT:
-			goto gornk;
+			if (~eoptions & EO_CPALETTE)
+			{
+				UpdatePalettePreviewCaption(hwndDlg);
+				InvalidatePalettePreviewRect(hwndDlg);
+			}
+		}
+		break;
+		case WM_PAINT:
+		{
+			if (!palo)
+				break;
+
+			PAINTSTRUCT paint;
+			HDC hdc = BeginPaint(hwndDlg, &paint);
+			HDC memdc = CreateCompatibleDC(hdc);
+
+			HGDIOBJ oldObj = SelectObject(memdc, palpv->pvBitmap);
+			HFONT oldFont = SelectFont(memdc, palpv->font);
+
+			RECT rect;
+			float left, top = -palpv->cell_height, right, bottom = 0.0F;
+			for (int i = 0; i < 64; ++i)
+			{
+				if (i % 16 == 0)
+				{
+					left = 0.0F;
+					right = palpv->cell_width;
+					top += palpv->cell_height;
+					bottom += palpv->cell_height;
+				}
+				else
+				{
+					left += palpv->cell_width;
+					right += palpv->cell_width;
+				}
 
-		case WM_COMMAND:
-			if(!(wParam>>16))
+				rect.left = round(left);
+				rect.right = round(right);
+				rect.top = round(top);
+				rect.bottom = round(bottom);
+
+				int grey = ToGrey(palo[i].r, palo[i].g, palo[i].b);
+				COLORREF color = force_grayscale ? RGB(grey, grey, grey) : RGB(palo[i].r, palo[i].g, palo[i].b);
+				HBRUSH brush = CreateSolidBrush(color);
+				FillRect(memdc, &rect, brush);
+				DeleteObject(brush);
+
+				if (palcolorindex)
+				{
+					SetTextColor(memdc, grey > 127 ? RGB(0, 0, 0) : RGB(255, 255, 255));
+					SetBkColor(memdc, color);
+
+					sprintf(palpv->buf, "%X", i);
+					SIZE str_size;
+					GetTextExtentPoint(memdc, palpv->buf, strlen(palpv->buf), &str_size);
+					ExtTextOut(memdc, rect.left + (rect.right - rect.left - str_size.cx) / 2, rect.top + (rect.bottom - rect.top - str_size.cy) / 2, NULL, NULL, palpv->buf, strlen(palpv->buf), NULL);
+				}
+			}
+
+			BitBlt(hdc, palpv->pvRect.left, palpv->pvRect.top,  palpv->pvSize.cx, palpv->pvSize.cy, memdc, 0, 0, SRCCOPY);
+
+			EndPaint(hwndDlg, &paint);
+
+			SelectFont(memdc, oldFont);
+			SelectObject(memdc, oldObj);
+			DeleteDC(memdc);
+
+			break;
+		}
+		case WM_MOUSEMOVE:
+			if (palo)
+				UpdatePalettePreviewCaption(hwndDlg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+			break;
+
+		case WM_LBUTTONDOWN:
+			if (palo && palpv->mouse_index != -1)
 			{
-				switch(wParam&0xFFFF)
+				CHOOSECOLORINFO info;
+				char str[16];
+				sprintf(str, "$%02X", palpv->mouse_index);
+				info.name = str;
+
+				int r = palo[palpv->mouse_index].r;
+				int g = palo[palpv->mouse_index].g;
+				int b = palo[palpv->mouse_index].b;
+
+				info.r = &r;
+				info.g = &g;
+				info.b = &b;
+
+				if (ChangeColor(hwndDlg, &info))
 				{
-					case CHECK_PALETTE_ENABLED:
-						ntsccol_enable ^= 1;
-						FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); // it recalculates everything, use it for PAL block too!
-						EnableWindow(GetDlgItem(hwndDlg, 65463), ntsccol_enable);
-						EnableWindow(GetDlgItem(hwndDlg, 64395), ntsccol_enable);
-						EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TRACKBAR), ntsccol_enable);
-						EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TRACKBAR), ntsccol_enable);
-
-						break;
-
-					case CHECK_PALETTE_GRAYSCALE:
-						force_grayscale ^= 1;
-						FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue);
-						break;
-
-					case CHECK_DEEMPH_SWAP:
-						paldeemphswap ^= 1;
-						FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue);
-						break;
-
-					case CHECK_PALETTE_CUSTOM:
+					if (palo[palpv->mouse_index].r != r || palo[palpv->mouse_index].g != g || palo[palpv->mouse_index].b != b)
 					{
 						if (eoptions & EO_CPALETTE)
 						{
-							//disable user palette
-							FCEUI_SetUserPalette(0,0);
-							eoptions &= ~EO_CPALETTE;
-						} else
+							palo[palpv->mouse_index].r = r;
+							palo[palpv->mouse_index].g = g;
+							palo[palpv->mouse_index].b = b;
+							FCEU_ResetPalette();
+						}
+						else
 						{
-							//switch to user palette (even if it isn't loaded yet!?)
-							FCEUI_SetUserPalette(cpalette,64); //just have to guess the size I guess
+							memcpy(cpalette, palo, 64 * 3);
+							pal* tmp_palo = (pal*)&cpalette;
+							tmp_palo[palpv->mouse_index].r = r;
+							tmp_palo[palpv->mouse_index].g = g;
+							tmp_palo[palpv->mouse_index].b = b;
+							FCEUI_SetUserPalette(cpalette, 64);
 							eoptions |= EO_CPALETTE;
+							UpdateCurrentPaletteName(hwndDlg);
+							CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED);
 						}
-						break;
-					}
 
-					case BTN_PALETTE_LOAD:
-						if(LoadPaletteFile())
-							CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED);
-						break;
-
-					case BTN_PALETTE_RESET:
-						palnotch      = 100;
-						palsaturation = 100;
-						palsharpness  = 0;
-						palcontrast   = 100;
-						palbrightness = 50;
-
-						sprintf(text, "Notch: %d%%", palnotch);
-						SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE, WM_SETTEXT, 0, (LPARAM) text);
-						sprintf(text, "Saturation: %d%%", palsaturation);
-						SendDlgItemMessage(hwndDlg, STATIC_SATVALUE, WM_SETTEXT, 0, (LPARAM) text);
-						sprintf(text, "Sharpness: %d%%", palsharpness);
-						SendDlgItemMessage(hwndDlg, STATIC_SHARPVALUE, WM_SETTEXT, 0, (LPARAM) text);
-						sprintf(text, "Contrast: %d%%", palcontrast);
-						SendDlgItemMessage(hwndDlg, STATIC_CONTRASTVALUE,WM_SETTEXT, 0, (LPARAM) text);
-						sprintf(text, "Brightness: %d%%", palbrightness);
-						SendDlgItemMessage(hwndDlg, STATIC_BRIGHTVALUE,  WM_SETTEXT, 0, (LPARAM) text);
-
-						SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR,   TBM_SETPOS, 1, palnotch);
-						SendDlgItemMessage(hwndDlg, CTL_PALSAT_TRACKBAR,     TBM_SETPOS, 1, palsaturation);
-						SendDlgItemMessage(hwndDlg, CTL_PALSHARP_TRACKBAR,   TBM_SETPOS, 1, palsharpness);
-						SendDlgItemMessage(hwndDlg, CTL_PALCONTRAST_TRACKBAR,TBM_SETPOS, 1, palcontrast);
-						SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR,  TBM_SETPOS, 1, palbrightness);
-
-						FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue);
-						break;
-
-					case BUTTON_CLOSE:
-gornk:
-						DestroyWindow(hwndDlg);
-						hWndPal = 0; // Yay for user race conditions.
-						break;
+						UpdatePalettePreviewCaption(hwndDlg);
+						InvalidatePalettePreviewRect(hwndDlg);
+					}
 				}
 			}
+			break;
+
+		case WM_CLOSE:
+		case WM_QUIT:
+			goto gornk;
+
+		case WM_COMMAND:
+			switch (HIWORD(wParam))
+			{
+				case BN_CLICKED:
+					switch (LOWORD(wParam))
+					{
+						case CHECK_PALETTE_ENABLED:
+							ntsccol_enable ^= 1;
+							FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue); // it recalculates everything, use it for PAL block too!
+							EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TEXT), ntsccol_enable);
+							EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TEXT), ntsccol_enable);
+							EnableWindow(GetDlgItem(hwndDlg, CTL_HUE_TRACKBAR), ntsccol_enable);
+							EnableWindow(GetDlgItem(hwndDlg, CTL_TINT_TRACKBAR), ntsccol_enable);
+							UpdateCurrentPaletteName(hwndDlg);
+							UpdatePalettePreviewCaption(hwndDlg);
+							InvalidatePalettePreviewRect(hwndDlg);
+							break;
+
+						case CHECK_PALETTE_GRAYSCALE:
+							force_grayscale ^= 1;
+							FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue);
+							UpdatePalettePreviewCaption(hwndDlg);
+							InvalidatePalettePreviewRect(hwndDlg);
+							break;
+
+						case CHECK_DEEMPH_SWAP:
+							paldeemphswap ^= 1;
+							FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue);
+							UpdatePalettePreviewCaption(hwndDlg);
+							InvalidatePalettePreviewRect(hwndDlg);
+							break;
+
+						case CHECK_PALETTE_CUSTOM:
+							if (eoptions & EO_CPALETTE)
+							{
+								//disable user palette
+								FCEUI_SetUserPalette(0, 0);
+								eoptions &= ~EO_CPALETTE;
+							}
+							else
+							{
+								//switch to user palette (even if it isn't loaded yet!?)
+								FCEUI_SetUserPalette(cpalette, 64); //just have to guess the size I guess
+								eoptions |= EO_CPALETTE;
+							}
+							UpdateCurrentPaletteName(hwndDlg);
+							UpdatePalettePreviewCaption(hwndDlg);
+							InvalidatePalettePreviewRect(hwndDlg);
+							break;
+
+						case CHECK_PALETTE_COLOR_INDEX:
+							palcolorindex ^= 1;
+							InvalidatePalettePreviewRect(hwndDlg);
+							break;
+
+						case BTN_PALETTE_LOAD:
+							if (LoadPaletteFile(hwndDlg))
+							{
+								CheckDlgButton(hwndDlg, CHECK_PALETTE_CUSTOM, BST_CHECKED);
+								UpdateCurrentPaletteName(hwndDlg);
+								UpdatePalettePreviewCaption(hwndDlg);
+								InvalidatePalettePreviewRect(hwndDlg);
+							}
+							break;
+
+						case BTN_PALETTE_SAVE:
+							SavePaletteFile(hwndDlg);
+							break;
+
+						case BTN_PALETTE_RESET:
+						{
+							palnotch      = 100;
+							palsaturation = 100;
+							palsharpness  = 0;
+							palcontrast   = 100;
+							palbrightness = 50;
+
+							char text[40];
+							sprintf(text, "Notch: %d%%", palnotch);
+							SendDlgItemMessage(hwndDlg, STATIC_NOTCHVALUE, WM_SETTEXT, 0, (LPARAM)text);
+							sprintf(text, "Saturation: %d%%", palsaturation);
+							SendDlgItemMessage(hwndDlg, STATIC_SATVALUE, WM_SETTEXT, 0, (LPARAM)text);
+							sprintf(text, "Sharpness: %d%%", palsharpness);
+							SendDlgItemMessage(hwndDlg, STATIC_SHARPVALUE, WM_SETTEXT, 0, (LPARAM)text);
+							sprintf(text, "Contrast: %d%%", palcontrast);
+							SendDlgItemMessage(hwndDlg, STATIC_CONTRASTVALUE, WM_SETTEXT, 0, (LPARAM)text);
+							sprintf(text, "Brightness: %d%%", palbrightness);
+							SendDlgItemMessage(hwndDlg, STATIC_BRIGHTVALUE, WM_SETTEXT, 0, (LPARAM)text);
+
+							SendDlgItemMessage(hwndDlg, CTL_PALNOTCH_TRACKBAR, TBM_SETPOS, 1, palnotch);
+							SendDlgItemMessage(hwndDlg, CTL_PALSAT_TRACKBAR, TBM_SETPOS, 1, palsaturation);
+							SendDlgItemMessage(hwndDlg, CTL_PALSHARP_TRACKBAR, TBM_SETPOS, 1, palsharpness);
+							SendDlgItemMessage(hwndDlg, CTL_PALCONTRAST_TRACKBAR, TBM_SETPOS, 1, palcontrast);
+							SendDlgItemMessage(hwndDlg, CTL_PALBRIGHT_TRACKBAR, TBM_SETPOS, 1, palbrightness);
+
+							FCEUI_SetNTSCTH(ntsccol_enable, ntsctint, ntschue);
+
+							UpdatePalettePreviewCaption(hwndDlg);
+							InvalidatePalettePreviewRect(hwndDlg);
+
+							break;
+						}
+						case BUTTON_CLOSE:
+							gornk:
+								DestroyWindow(hwndDlg);
+								hWndPal = 0; // Yay for user race conditions.
+								DeleteFont(palpv->font);
+								DeleteObject(palpv->pvBitmap);
+								free(palpv);
+								return 0;
+					}
+			}
 	}
 
 	return 0;
@@ -246,4 +557,3 @@ void ConfigPalette()
 	else
 		SetFocus(hWndPal);
 }
-
diff --git a/src/drivers/win/ramwatch.cpp b/src/drivers/win/ramwatch.cpp
index 60a73af1e..94c550c2c 100644
--- a/src/drivers/win/ramwatch.cpp
+++ b/src/drivers/win/ramwatch.cpp
@@ -1295,7 +1295,7 @@ INT_PTR CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
 
 										// draw the separator
 										// draw it with a different color when hilighted for eyes easy
-										SelectObject(hdc, state ? SeparatorCache::sepPenSel : SeparatorCache::sepPen);
+										HGDIOBJ oldObj = SelectObject(hdc, state ? SeparatorCache::sepPenSel : SeparatorCache::sepPen);
 										MoveToEx(hdc, rect.left + sepCache.sepOffX, rect.top + SeparatorCache::sepOffY, NULL);
 										LineTo(hdc, rect.right, rect.top + SeparatorCache::sepOffY);
 
@@ -1309,6 +1309,7 @@ INT_PTR CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
 											SelectObject(hdc, SeparatorCache::sepFon);
 											DrawText(hdc, comment, strlen(comment), &rect, DT_LEFT);
 										}
+										SelectObject(hdc, oldObj);
 									}
 									break;
 
@@ -1684,8 +1685,9 @@ SeparatorCache::SeparatorCache(HWND hwnd, char* text) {
 		SIZE size;
 
 		HDC hdc = GetDC(hwnd);
-		SelectFont(hdc, sepFon);
+		HGDIOBJ oldObj = SelectFont(hdc, sepFon);
 		GetTextExtentPoint(hdc, text, strlen(text), &size);
+		SelectObject(hdc, oldObj);
 		ReleaseDC(hwnd, hdc);
 
 		sepOffX = size.cx + 8;
diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc
index e052bd118..e4b238885 100644
--- a/src/drivers/win/res.rc
+++ b/src/drivers/win/res.rc
@@ -375,36 +375,42 @@ BEGIN
     EDITTEXT        IDC_NETMOO_PASS,60,182,67,12,ES_PASSWORD
 END
 
-PALCONFIG DIALOGEX 16, 81, 228, 217
+PALCONFIG DIALOGEX 16, 81, 228, 280
 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 CAPTION "Palette Configuration"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-    GROUPBOX        "NES Palette",302,10,8,102,81,WS_GROUP
-    DEFPUSHBUTTON   "&Load Palette...",BTN_PALETTE_LOAD,18,39,58,14
-    CONTROL         "Enabled",CHECK_PALETTE_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,122,22,87,12
-    CTEXT           "Tint",65463,123,34,85,8,WS_DISABLED
-    CONTROL         "Tint",CTL_TINT_TRACKBAR,"msctls_trackbar32",WS_DISABLED | WS_TABSTOP,121,44,91,11
-    GROUPBOX        "NTSC Color Emulation",101,115,8,103,81,WS_GROUP
-    CTEXT           "Hue",64395,124,59,85,8,WS_DISABLED
-    CONTROL         "Hue",CTL_HUE_TRACKBAR,"msctls_trackbar32",WS_DISABLED | WS_TABSTOP,121,69,91,11
-    CONTROL         "Force Grayscale",CHECK_PALETTE_GRAYSCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,57,85,12
-    CONTROL         "Use Custom Palette",CHECK_PALETTE_CUSTOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,22,85,12
-    GROUPBOX        "PAL Simulation",IDC_STATIC,10,89,208,66
-    LTEXT           "Saturation:",STATIC_SATVALUE,83,100,58,8
-    CONTROL         "",CTL_PALSAT_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,78,110,70,15
-    PUSHBUTTON      "Reset",BTN_PALETTE_RESET,161,132,50,14
-    LTEXT           "Notch:",STATIC_NOTCHVALUE,16,100,46,8
-    CONTROL         "",CTL_PALNOTCH_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,11,110,68,15
-    LTEXT           "Sharpness:",STATIC_SHARPVALUE,151,99,60,8
-    CONTROL         "",CTL_PALSHARP_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,146,109,71,15
-    LTEXT           "NTSC Color Emulation overrides Internal default Palette.\nIndividual Game Palette overrides Internal+NTSC Palettes.\nCustom Palette overrides all of the above.\nPAL Simulation overrides other choices when PAL filter is selected in Video Configuration.",IDC_STATIC,10,159,208,43
-    LTEXT           "Contrast: ",STATIC_CONTRASTVALUE,16,126,55,8
-    CONTROL         "",CTL_PALCONTRAST_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,11,134,67,15
-    LTEXT           "Brightness: ",STATIC_BRIGHTVALUE,83,125,61,8
-    CONTROL         "",CTL_PALBRIGHT_TRACKBAR,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,78,133,70,15
-    CONTROL         "De-emphasis bit swap",CHECK_DEEMPH_SWAP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,73,83,10
-    DEFPUSHBUTTON   "Close",BUTTON_CLOSE,162,195,56,14
+	GROUPBOX        "NES Palette", 302, 10, 8, 102, 81, WS_GROUP
+	CONTROL         "Use Custom Palette", CHECK_PALETTE_CUSTOM, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 22, 85, 12
+	DEFPUSHBUTTON   "&Load Palette...", BTN_PALETTE_LOAD, 18, 39, 58, 14
+	CONTROL         "Force Grayscale", CHECK_PALETTE_GRAYSCALE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 57, 85, 12
+	CONTROL         "De-emphasis bit swap", CHECK_DEEMPH_SWAP, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 73, 83, 10
+	GROUPBOX        "NTSC Color Emulation", 101, 115, 8, 103, 81, WS_GROUP
+	CONTROL         "Enabled", CHECK_PALETTE_ENABLED, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 122, 22, 87, 12
+	CTEXT           "Tint", CTL_TINT_TEXT, 123, 34, 85, 8, WS_DISABLED
+	CONTROL         "Tint", CTL_TINT_TRACKBAR, "msctls_trackbar32", WS_DISABLED | WS_TABSTOP, 121, 44, 91, 11
+	CTEXT           "Hue", CTL_HUE_TEXT, 124, 59, 85, 8, WS_DISABLED
+	CONTROL         "Hue", CTL_HUE_TRACKBAR, "msctls_trackbar32", WS_DISABLED | WS_TABSTOP, 121, 69, 91, 11
+	GROUPBOX        "PAL Emulation", IDC_STATIC, 10, 90, 208, 66, WS_DISABLED
+	LTEXT           "Notch:", STATIC_NOTCHVALUE, 16, 100, 46, 8, WS_DISABLED
+	CONTROL         "", CTL_PALNOTCH_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 11, 110, 68, 15
+	LTEXT           "Saturation:", STATIC_SATVALUE, 83, 100, 58, 8, WS_DISABLED
+	CONTROL         "", CTL_PALSAT_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 78, 110, 70, 15
+	LTEXT           "Sharpness:", STATIC_SHARPVALUE, 161, 99, 50, 8, WS_DISABLED
+	CONTROL         "", CTL_PALSHARP_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 156, 109, 61, 15
+	LTEXT           "Contrast: ", STATIC_CONTRASTVALUE, 16, 126, 55, 8, WS_DISABLED
+	CONTROL         "", CTL_PALCONTRAST_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 11, 134, 67, 15
+	LTEXT           "Brightness: ", STATIC_BRIGHTVALUE, 83, 125, 61, 8, WS_DISABLED
+	CONTROL         "", CTL_PALBRIGHT_TRACKBAR, "msctls_trackbar32", TBS_NOTICKS | WS_DISABLED | WS_TABSTOP, 78, 133, 70, 15
+	PUSHBUTTON      "Reset", BTN_PALETTE_RESET, 161, 132, 50, 14, WS_DISABLED
+	GROUPBOX        "Preview", IDC_PALETTE_PREVIEW_GROUPBOX, 10, 157, 208, 68
+	CONTROL         "Color index", CHECK_PALETTE_COLOR_INDEX, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 16, 166, 49, 10
+	LTEXT           "Current palette:", IDC_STATIC, 70, 167, 53, 8
+	LTEXT           "None", IDC_PALETTE_CURRENT, 127, 167, 46, 8
+	PUSHBUTTON      "Save...", BTN_PALETTE_SAVE, 177, 163, 38, 14
+	LTEXT           "", IDC_PALETTE_PREVIEW, 15, 178, 198, 43, NOT WS_VISIBLE
+	LTEXT           "NTSC Color Emulation overrides Internal default Palette.\nIndividual Game Palette overrides Internal+NTSC Palettes.\nCustom Palette overrides all of the above.\nPAL Emulation overrides other choices when PAL filter is selected", IDC_STATIC, 10, 227, 217, 33
+	DEFPUSHBUTTON   "Close", BUTTON_CLOSE, 162, 261, 56, 14
 END
 
 POWERPADDIALOG DIALOGEX 30, 123, 131, 119
@@ -1863,13 +1869,13 @@ BEGIN
         BOTTOMMARGIN, 201
     END
 
-    "PALCONFIG", DIALOG
-    BEGIN
-        LEFTMARGIN, 10
-        RIGHTMARGIN, 218
-        TOPMARGIN, 8
-        BOTTOMMARGIN, 209
-    END
+	"PALCONFIG", DIALOG
+		BEGIN
+		LEFTMARGIN, 10
+		RIGHTMARGIN, 218
+		TOPMARGIN, 8
+		BOTTOMMARGIN, 275
+	END
 
     "POWERPADDIALOG", DIALOG
     BEGIN
diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h
index ea863c968..7d6150df8 100644
--- a/src/drivers/win/resource.h
+++ b/src/drivers/win/resource.h
@@ -512,6 +512,7 @@
 #define IDC_CHEAT_AUTOLOADSAVE          1013
 #define IDC_CHECK_SHORTCUT              1013
 #define IDC_CHECK_SYMBOLIC_ARRAY        1013
+#define CHECK_PALETTE_COLOR_INDEX       1013
 #define IDC_RESTORE_BUTTON              1014
 #define MW_VAL04                        1014
 #define MW_NAME05                       1015
@@ -609,11 +610,15 @@
 #define IDC_DEBUGGER_TEXT_A             1049
 #define IDC_SUBMAPPER_TEXT              1050
 #define MW_VAL16                        1050
+#define IDC_PALETTE_PREVIEW             1050
 #define IDC_PRGROM_TEXT                 1051
 #define MW_NAME17                       1051
+#define IDC_PALETTE_PREVIEW_GROUPBOX    1051
 #define MW_ADDR17                       1052
+#define IDC_PALETTE_CURRENT             1052
 #define IDC_CHRROM_TEXT                 1053
 #define MW_VAL17                        1053
+#define BTN_PALETTE_SAVE                1053
 #define MW_NAME18                       1054
 #define MW_ADDR18                       1055
 #define IDC_PRGRAM_TEXT                 1055
@@ -1207,9 +1212,11 @@
 #define CHEAT_CONTEXT_POSSI_ADDCHEAT    40601
 #define CHEAT_CONTEXT_POSSI_ADDTORAMWATCH 40603
 #define IDC_DEBUGGER_BOOKMARKS          45535
+#define CTL_HUE_TEXT                    64395
 #define MW_VALUELABEL2                  65423
 #define MW_VALUELABEL1                  65426
 #define IDC_STATIC_SLASHTEXT            65442
+#define CTL_TINT_TEXT                   65463
 #define IDC_DEBUGGER_TEXT_SPR           65530
 #define IDC_DEBUGGER_TEXT_PPU           65531
 #define IDC_BOOKMARK_NAME_TEXT          65532
@@ -1226,7 +1233,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        313
 #define _APS_NEXT_COMMAND_VALUE         40012
-#define _APS_NEXT_CONTROL_VALUE         1050
+#define _APS_NEXT_CONTROL_VALUE         1054
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp
index b36e74bcc..2230af040 100644
--- a/src/drivers/win/window.cpp
+++ b/src/drivers/win/window.cpp
@@ -1119,6 +1119,17 @@ bool ALoad(const char *nameo, char* innerFilename, bool silent)
 		{
 			DoDebug(0);
 		}
+
+		extern HWND hWndPal;
+		if (hWndPal)
+		{
+			extern void InvalidatePalettePreviewRect(HWND);
+			InvalidatePalettePreviewRect(hWndPal);
+			extern void UpdatePalettePreviewCaption(HWND);
+			UpdatePalettePreviewCaption(hWndPal);
+			extern void UpdateCurrentPaletteName(HWND);
+			UpdateCurrentPaletteName(hWndPal);
+		}
 	}
 	else
 	{
@@ -3377,6 +3388,8 @@ bool inline (*GetIsLetterLegal(UINT id))(char letter)
 		case MW_ADDR12: case MW_ADDR13: case MW_ADDR14: case MW_ADDR15:
 		case MW_ADDR16: case MW_ADDR17: case MW_ADDR18: case MW_ADDR19:
 		case MW_ADDR20: case MW_ADDR21: case MW_ADDR22: case MW_ADDR23:
+			return IsLetterLegalMemoryWatch;
+
 		case IDC_EDIT_COMPAREADDRESS:
 			return IsLetterLegalHex;
 
@@ -3473,6 +3486,12 @@ inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter))
 		"you must add a $ prefix to prevent ambiguous.\n"
 		"eg. 10 is a decimal number,\n"
 		"$10 means a hexademical number that is 16 in decimal.";
+	if (IsLetterLegal == IsLetterLegalMemoryWatch)
+		return
+		L"You can only type characters for hexadecimal number(0 - 9, A - F).\n"
+		"To display the value in hex, use a prefix of \"x\" (such as x00FD).\n"
+		"Use the prefix \"!\" to display a 2 byte value.\n"
+		"Use a prefix of \"X\" to watch a 2 byte value in hex.";
 
 	return L"Your input contains invalid characters.";
 }
@@ -3530,3 +3549,8 @@ inline bool IsLetterLegalUnsignedDecHexMixed(char letter)
 {
 	return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$';
 }
+
+inline bool IsLetterLegalMemoryWatch(char letter)
+{
+	return IsLetterLegalHex(letter) || letter == 'X' || letter == 'x' || letter == '!';
+}
\ No newline at end of file
diff --git a/src/drivers/win/window.h b/src/drivers/win/window.h
index 0127ad978..790d32aa0 100644
--- a/src/drivers/win/window.h
+++ b/src/drivers/win/window.h
@@ -141,6 +141,7 @@ inline bool IsLetterLegalSize(char letter);
 inline bool IsLetterLegalFloat(char letter);
 inline bool IsLetterLegalDecHexMixed(char letter);
 inline bool IsLetterLegalUnsignedDecHexMixed(char letter);
+inline bool IsLetterLegalMemoryWatch(char letter);
 
 extern WNDPROC DefaultEditCtrlProc;
 extern LRESULT APIENTRY FilterEditCtrlProc(HWND hDlg, UINT msg, WPARAM wP, LPARAM lP);