Added basic GUI, debugger and register view
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4af0ce6
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "nuklear"]
+	path = nuklear
+	url = git@github.com:Immediate-Mode-UI/Nuklear.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c672846..e0b1243 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,8 @@
 
 option(GEN_INSTRUCTIONS_HEADER ON)
 
+include_directories(nuklear)
+
 if (${GEN_INSTRUCTIONS_HEADER})
 	add_custom_command(
 		OUTPUT instructions.h
@@ -12,5 +14,5 @@
 		WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 endif()
 
-add_executable(6502 main.c cpu.c cpu.h dbg.c dbg.h instructions.h)
-target_link_libraries(6502 readline)
\ No newline at end of file
+add_executable(6502 main.c cpu.c cpu.h dbg.c dbg.h instructions.h gui.h gui.c)
+target_link_libraries(6502 readline SDL2 GL GLU GLEW m)
diff --git a/cpu.c b/cpu.c
index 5a7c391..cd2b253 100644
--- a/cpu.c
+++ b/cpu.c
@@ -13,6 +13,13 @@
 #define warn(m, ...) \
 	printf("\033[33m" m "\033[0m\n", ##__VA_ARGS__);
 
+void reset(cpu_t *cpu)
+{
+	cpu->regs[SP] = 0xFD; // stack at is 0x100 + SP
+	cpu->pc = 0; // arbitrary program counter start
+	cpu->running = true;
+}
+
 cpu_t new_cpu()
 {
 	cpu_t cpu = { 0 };
diff --git a/cpu.h b/cpu.h
index 888972c..afaae30 100644
--- a/cpu.h
+++ b/cpu.h
@@ -138,6 +138,7 @@
 void step(cpu_t *cpu);
 void free_cpu(cpu_t *cpu);
 void die(const char *message);
+void reset(cpu_t *cpu);
 // IMPORTANT: all disassembly functions mess with the PC
 void disas(cpu_t *cpu);
 void disas_num(cpu_t *cpu, uint16_t num);
diff --git a/gui.c b/gui.c
new file mode 100644
index 0000000..7fe5d69
--- /dev/null
+++ b/gui.c
@@ -0,0 +1,144 @@
+#include "gui.h"
+
+#include <GL/glew.h>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_opengl.h>
+
+#define NK_INCLUDE_FIXED_TYPES
+#define NK_INCLUDE_STANDARD_IO
+#define NK_INCLUDE_STANDARD_VARARGS
+#define NK_INCLUDE_DEFAULT_ALLOCATOR
+#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+#define NK_INCLUDE_FONT_BAKING
+#define NK_INCLUDE_DEFAULT_FONT
+#define NK_IMPLEMENTATION
+#define NK_SDL_GL3_IMPLEMENTATION
+#include "nuklear/nuklear.h"
+#include "nuklear/demo/sdl_opengl3/nuklear_sdl_gl3.h"
+
+#define WINDOW_WIDTH 720
+#define WINDOW_HEIGHT 640
+#define MAX_VERTEX_MEMORY 512 * 1024
+#define MAX_ELEMENT_MEMORY 128 * 1024
+
+void gui(cpu_t *cpu)
+{
+	SDL_Window *win;
+	SDL_GLContext glContext;
+	int win_width, win_height;
+	bool running = true;
+	bool cpu_running = false;
+
+	struct nk_context *ctx;
+	struct nk_colorf bg;
+
+	SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
+	SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS);
+	SDL_GL_SetAttribute (SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
+	SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
+	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+	win = SDL_CreateWindow("6502",
+		SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+		WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI);
+	glContext = SDL_GL_CreateContext(win);
+	SDL_GetWindowSize(win, &win_width, &win_height);
+
+	/* OpenGL setup */
+	glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
+	glewExperimental = 1;
+	if (glewInit() != GLEW_OK) {
+		fprintf(stderr, "Failed to setup GLEW\n");
+		exit(1);
+	}
+
+	ctx = nk_sdl_init(win);
+
+	struct nk_font_atlas *atlas;
+	nk_sdl_font_stash_begin(&atlas);
+	struct nk_font *font = nk_font_atlas_add_default(atlas, 16, NULL);
+	nk_sdl_font_stash_end();
+	//nk_style_load_all_cursors(ctx, atlas->cursors);
+	nk_style_set_font(ctx, &font->handle);
+
+	bg.r = 0.29f, bg.g = 0.28f, bg.b = 0.50f, bg.a = 1.0f;
+
+	while (running)
+	{
+		SDL_Event evt;
+		nk_input_begin(ctx);
+		while (SDL_PollEvent(&evt))
+		{
+			if (evt.type == SDL_QUIT) goto cleanup;
+			nk_sdl_handle_event(&evt);
+		}
+		nk_input_end(ctx);
+
+		if (cpu_running && cpu->running)
+			step(cpu);
+
+		if (!cpu->running)
+			cpu_running = false;
+
+		if (nk_begin(ctx, "Registers", nk_rect(50, 300, 400, 90),
+			NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
+			NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
+		{
+			nk_layout_row_dynamic(ctx, 30, 4);
+			char regpc[12],
+				rega[12],
+				regx[12],
+				regy[12];
+			sprintf(regpc, "PC: $%x", cpu->pc);
+			sprintf(rega, "A: $%x", cpu->regs[A]);
+			sprintf(regx, "X: $%x", cpu->regs[X]);
+			sprintf(regy, "Y: $%x", cpu->regs[Y]);
+			cpu->pc = nk_propertyi(ctx, "PC", 0, cpu->pc, 0xFFFF, 1, 20.0f);
+			cpu->regs[A] = nk_propertyi(ctx, "A", 0, cpu->regs[A], 0xFF, 1, 20.0f);
+			cpu->regs[X] = nk_propertyi(ctx, "X", 0, cpu->regs[X], 0xFF, 1, 20.0f);
+			cpu->regs[Y] = nk_propertyi(ctx, "Y", 0, cpu->regs[Y], 0xFF, 1, 20.0f);
+		}
+		nk_end(ctx);
+
+		if (nk_begin(ctx, "Debugger", nk_rect(50, 50, 230, 150),
+			NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
+			NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
+		{
+			nk_layout_row_dynamic(ctx, 30, 2);
+			nk_label(ctx, cpu->running ? "CPU Running" : "CPU Halted", NK_TEXT_LEFT);
+			if (nk_button_label(ctx, "Reset"))
+			{
+				puts("cpu reset");
+				reset(cpu);
+			}
+
+			nk_layout_row_dynamic(ctx, 30, 2);
+			if (nk_button_label(ctx, "Step"))
+			{
+				printf("step pressed!\n");
+				step(cpu);
+			}
+
+			if (nk_button_label(ctx, cpu_running ? "Stop" : "Run"))
+			{
+				cpu_running = !cpu_running;
+				puts(cpu_running ? "cpu running" : "cpu stopped");
+			}
+		}
+		nk_end(ctx);
+
+		SDL_GetWindowSize(win, &win_width, &win_height);
+		glViewport(0, 0, win_width, win_height);
+		glClear(GL_COLOR_BUFFER_BIT);
+		glClearColor(bg.r, bg.g, bg.b, bg.a);
+		nk_sdl_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY);
+		SDL_GL_SwapWindow(win);
+	}
+
+cleanup:
+	nk_sdl_shutdown();
+	SDL_GL_DeleteContext(glContext);
+	SDL_DestroyWindow(win);
+	SDL_Quit();
+}
diff --git a/gui.h b/gui.h
new file mode 100644
index 0000000..730db11
--- /dev/null
+++ b/gui.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "cpu.h"
+
+void gui(cpu_t *cpu);
diff --git a/main.c b/main.c
index 888168c..b4b05e7 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,6 @@
 #include "cpu.h"
 #include "dbg.h"
+#include "gui.h"
 
 #include <bits/getopt_core.h>
 #include <ctype.h>
@@ -13,7 +14,8 @@
 		runflag = false,
 		helpflag = false,
 		debugflag = false,
-		should_read = false;
+		should_read = false,
+		guiflag = false;
 
 	int disasm_len = 0;
 
@@ -21,7 +23,7 @@
 
 	char c;
 
-	while ((c = getopt(argc, argv, "Ddrhi:n:")) != -1)
+	while ((c = getopt(argc, argv, "Ddrhgi:n:")) != -1)
 	{
 		switch (c)
 		{
@@ -37,6 +39,10 @@
 			debugflag = true;
 			should_read = true;
 			break;
+		case 'g':
+			guiflag = true;
+			should_read = true;
+			break;
 		case 'i':
 			input = fopen(optarg, "r");
 			break;
@@ -76,7 +82,11 @@
 		printf("%s -h  for help\n", argv[0]);
 	}
 
-	if (disflag)
+	if (guiflag)
+	{
+		gui(&cpu);
+	}
+	else if (disflag)
 	{
 		disas(&cpu);
 	}
diff --git a/nuklear b/nuklear
new file mode 160000
index 0000000..d9ddd18
--- /dev/null
+++ b/nuklear
@@ -0,0 +1 @@
+Subproject commit d9ddd1810f8e43911c06f4f86eab3053db757adc