Index: elec/CrO2/software/Makefile
===================================================================
--- elec/CrO2/software/Makefile	(revision 192e29968ecf06910106597b9e82d2572120ed48)
+++ elec/CrO2/software/Makefile	(revision c2a98541792794d00ddb4a1245f2dc0fcddd096c)
@@ -14,6 +14,6 @@
 
 CC		= g++
-CPPFLAGS	= $(USBFLAGS) -O -Wall -I/usr/include/IUP/ -I/local/include -g -std=c++0x -mthreads
-LIBS	= $(USBLIBS) -L/usr/lib/ -mwindows -liup -lcomctl32 -lole32 -mthreads
+CPPFLAGS = $(USBFLAGS) -Os -Wall -I/usr/include/IUP/ -I/local/include -std=c++0x -mthreads
+LIBS = $(USBLIBS) -Os -L/usr/lib/ -mwindows -liup -liupcontrols -liupcd -lcd -lfreetype -lz -lcomctl32 -lole32 -mthreads
 
 PROJECT = CrO2
Index: elec/CrO2/software/gui.cpp
===================================================================
--- elec/CrO2/software/gui.cpp	(revision 192e29968ecf06910106597b9e82d2572120ed48)
+++ elec/CrO2/software/gui.cpp	(revision c2a98541792794d00ddb4a1245f2dc0fcddd096c)
@@ -11,4 +11,8 @@
 
 #include <stdint.h>
+#include <string.h>
+#include <sstream>
+#include <iostream>
+
 #include <iupcontrols.h>
 
@@ -50,5 +54,5 @@
 
 	IupOpen(argc, argv);
-//	IupControlsOpen();
+	IupControlsOpen();
 
 	Ihandle* menu_open = IupItem("Open", NULL);
@@ -71,4 +75,7 @@
 	Ihandle* motoron = IupProgressBar();
 	IupSetAttribute(motoron, "RASTERSIZE", "16x16");
+
+	Ihandle* playToggle = IupToggle("play", NULL);
+	Callback<Gui, int, int>::create(playToggle, "ACTION", this, &Gui::setPlaying);
 
 	// EXPLORE
@@ -79,10 +86,25 @@
 	IupSetAttribute(platformlist, "VALUE", "1");
 
-	Ihandle* blocklist = IupTree();
+	blocklist = IupTree();
 	IupSetAttribute(blocklist, "EXPAND", "VERTICAL");
-
-	Ihandle* playToggle = IupToggle("play", NULL);
-	Callback<Gui, int>::create(playToggle, "ACTION", this, &Gui::setPlaying);
-
+	IupSetAttribute(blocklist, "ADDEXPANDED", "NO");
+	IupSetAttribute(blocklist, "ADDROOT", "NO");
+	IupSetAttribute(blocklist, "IMAGELEAF", "IMGBLANK");
+	IupSetAttribute(blocklist, "RASTERSIZE", "140x200");
+	Callback<Gui, int, int, int>::create(blocklist, "SELECTION_CB", this, &Gui::selectBlock);
+
+	Ihandle* hexEd = IupMatrix(NULL);
+
+	// Setup title cells
+	IupSetAttribute(hexEd, "NUMLIN", "16");
+	IupSetAttribute(hexEd, "NUMCOL", "17");
+	IupSetAttribute(hexEd, "WIDTHDEF", "12");
+	IupSetAttribute(hexEd, "WIDTH17", "48");
+	IupSetAttribute(hexEd, "USETITLESIZE", "YES");
+	IupSetAttribute(hexEd, "FONT", "Courier, Bold 12");
+	IupSetAttribute(hexEd, "EXPAND", "YES");
+	Callback<Gui, const char*, int, int>::create(hexEd, "VALUE_CB", this, &Gui::matVal);
+	
+	// WINDOW LAYOUT
 	Ihandle* tabs = IupTabs(
 		IupVbox(
@@ -108,5 +130,5 @@
 				blocklist,
 				IupVbox(
-//					IupMatrix(NULL),
+					hexEd,
 					IupLabel("Checksum:"),
 					NULL
@@ -129,13 +151,16 @@
 	startPolling(motoron);
 
+	// TODO the IUP main loop is blocking - it may be wise to move it out of
+	// the constructor...
 	IupMainLoop();
-
+}
+
+
+Gui::~Gui()
+{
+	delete file;
+
+	IupControlsClose();
 	IupClose();
-}
-
-
-Gui::~Gui()
-{
-	delete file;
 }
 
@@ -149,4 +174,34 @@
 		// Load file
 		file = new K5(name);
+
+		// Fill in EXPLORE tab
+		int count = file->getBlockCount();
+		int lastfile = -1;
+
+		for (int i = 0; i < count; ++i)
+		{
+			const K5::Block& blk = file->getBlock(i);
+			switch(blk.type)
+			{
+				case 0:
+					//start block
+					char name[12];
+					memcpy(name, blk.data, 11);
+					name[11] = 0;
+					
+					IupSetAttributeId(blocklist, "INSERTBRANCH", lastfile, name);
+					lastfile = i;
+					break;
+				case 0xFF:
+					// end block
+					IupSetAttributeId(blocklist, "ADDLEAF", i-1, "EOF");
+					IupSetAttributeId(blocklist, "IMAGE", i, "IMGLEAF");
+					break;
+				default:
+					// regular block
+					IupSetAttributeId(blocklist, "ADDLEAF", i-1, "DATA");
+					break;
+			}
+		}
 	}
 	return IUP_DEFAULT;
@@ -156,4 +211,42 @@
 {
 	return IUP_CLOSE;
+}
+
+int Gui::selectBlock(int id, int what)
+{
+	if (what)
+	{
+		IupSetAttribute(hexEd, "REDRAW", "ALL");
+	}
+
+	return IUP_DEFAULT;
+}
+
+const char* Gui::matVal(int x, int y)
+{
+	if (x == 0)
+	{
+		switch(y)
+		{
+			case 0:
+				return "0x";
+			case 17:
+				return "ASCII";
+			default:
+			{
+				std::ostringstream name;
+				name << std::hex;
+				name << (y-1);
+				return name.str().c_str();
+			}
+		}
+	}
+
+	if (y == 0)
+	{
+		return "C";
+	}
+
+	return "V";
 }
 
Index: elec/CrO2/software/gui.h
===================================================================
--- elec/CrO2/software/gui.h	(revision 192e29968ecf06910106597b9e82d2572120ed48)
+++ elec/CrO2/software/gui.h	(revision c2a98541792794d00ddb4a1245f2dc0fcddd096c)
@@ -20,6 +20,13 @@
 		int menu_exit();
 
+		K5* file;
+
+		// Control
 		int setPlaying(int state);
 
-		K5* file;
+		// Explore
+		int selectBlock(int id, int what);
+		const char* matVal(int x, int y);
+		Ihandle* blocklist;
+		Ihandle* hexEd;
 };
Index: elec/CrO2/software/iupplusplus.h
===================================================================
--- elec/CrO2/software/iupplusplus.h	(revision 192e29968ecf06910106597b9e82d2572120ed48)
+++ elec/CrO2/software/iupplusplus.h	(revision c2a98541792794d00ddb4a1245f2dc0fcddd096c)
@@ -7,7 +7,7 @@
 #include <iup.h>
 
-template<class Handler, typename... Args> class Callback
+template<class Handler, typename ret = int, typename... Args> class Callback
 {
-	typedef int(Handler::*T)(Args... args);
+	typedef ret(Handler::*T)(Args... args);
 
 	public:
@@ -27,5 +27,5 @@
 		}
 
-		static int call(Ihandle* that, Args... args)
+		static ret call(Ihandle* that, Args... args)
 		{
 			Callback* call = (Callback*)IupGetAttribute(that, "LCALLBACK");
