Add SDL renderer, demo webm
diff --git a/README.md b/README.md
index 2d235ba..eb391f0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,10 @@
 # 6502 Toolchain
 
-![Screenshot](screenshot.png)
+<center>
+	**Click for demonstration:**
+
+	[![Screenshot](screenshot.png)](colors.webm)
+</center>
 
 This project aims to create a portable toolchain for developing,
 testing and debugging programs for the 6502 processor. An assembler
diff --git a/colors.dat b/colors.dat
new file mode 100644
index 0000000..fc0ee0a
--- /dev/null
+++ b/colors.dat
Binary files differ
diff --git a/colors.webm b/colors.webm
new file mode 100644
index 0000000..e32b42f
--- /dev/null
+++ b/colors.webm
Binary files differ
diff --git a/cpu.c b/cpu.c
index fbe72b2..cfcd89d 100644
--- a/cpu.c
+++ b/cpu.c
@@ -1,5 +1,7 @@
 #include "cpu.h"
 #include "instructions.h"
+#define SCREEN_ONLY_SDL
+#include "screen.h"
 
 #include <endian.h>
 #include <stdio.h>
@@ -13,6 +15,10 @@
 #define warn(m, ...) \
 	printf("\033[33m" m "\033[0m\n", ##__VA_ARGS__);
 
+
+sdl_screen_t *g_scr = NULL;
+
+
 void reset(cpu_t *cpu)
 {
 	cpu->regs[SP] = 0xFD; // stack at is 0x100 + SP
@@ -89,36 +95,36 @@
 }
 
 // rotate right
-uint8_t ror(uint8_t a, uint8_t n)
+inline uint8_t ror(uint8_t a, uint8_t n)
 {
 	return (a >> n) | (a << (8 - n));
 }
 
 // rotate left
-uint8_t rol(uint8_t a, uint8_t n)
+inline uint8_t rol(uint8_t a, uint8_t n)
 {
 	return (a << n) | (a >> (8 - n));
 }
 
-void stat_nz(cpu_t *cpu, int8_t v)
+inline void stat_nz(cpu_t *cpu, int8_t v)
 {
 	cpu->status.negative = v < 0;
 	cpu->status.zero = v == 0;
 }
 
 // Used to check for overflow, is c unique?
-bool last_unique(bool a, bool b, bool c)
+inline bool last_unique(bool a, bool b, bool c)
 {
 	return a == b && a != c;
 }
 
-void stat_cv(cpu_t *cpu, uint8_t a, uint8_t b, uint8_t c)
+inline void stat_cv(cpu_t *cpu, uint8_t a, uint8_t b, uint8_t c)
 {
 	cpu->status.overflow = last_unique(a >> 7, b >> 7, c >> 7);
 	cpu->status.carry = c < a || c < b;
 }
 
-void cmp(cpu_t *cpu, uint8_t reg, uint8_t mem)
+inline void cmp(cpu_t *cpu, uint8_t reg, uint8_t mem)
 {
 	cpu->status.negative = 0;
 	cpu->status.zero = 0;
@@ -405,19 +411,19 @@
 	#undef REGS
 }
 
-uint16_t fetch_le(cpu_t *cpu)
+inline uint16_t fetch_le(cpu_t *cpu)
 {
 	uint8_t a = cpu->mem[cpu->pc++];
 	uint8_t b = cpu->mem[cpu->pc++];
 	return le_to_native(a, b);
 }
 
-arg_t arg_imm(uint16_t a)
+inline arg_t arg_imm(uint16_t a)
 {
 	return (arg_t){ a, a };
 }
 
-arg_t arg_ptr(cpu_t *c, uint flags, uint16_t p)
+inline arg_t arg_ptr(cpu_t *c, uint flags, uint16_t p)
 {
 	if (flags & FETCH_NO_INDIRECTION)
 		return arg_imm(p);
@@ -425,7 +431,7 @@
 	return (arg_t){ c->mem[p], p };
 }
 
-arg_t arg(uint16_t v, uint16_t a)
+inline arg_t arg(uint16_t v, uint16_t a)
 {
 	return (arg_t){ v, a };
 }
@@ -470,15 +476,25 @@
 		}
 
 		case AM_AX:
+			if (f & FETCH_NO_INDIRECTION)
+				return arg_ptr(cpu, f, fetch_le(cpu));
+
 			return arg_ptr(cpu, f, fetch_le(cpu) + cpu->regs[X]);
 
 		case AM_AY:
+			if (f & FETCH_NO_INDIRECTION)
+				return arg_ptr(cpu, f, fetch_le(cpu));
+		
 			return arg_ptr(cpu, f, fetch_le(cpu) + cpu->regs[Y]);
 
 		case AM_ZPX:
+			if (f & FETCH_NO_INDIRECTION)
+				return arg_ptr(cpu, f, cpu->mem[cpu->pc++]);
 			return arg_ptr(cpu, f, cpu->mem[cpu->pc++] + cpu->regs[X]);
 
 		case AM_ZPY:
+			if (f & FETCH_NO_INDIRECTION)
+				return arg_ptr(cpu, f, cpu->mem[cpu->pc++]);
 			return arg_ptr(cpu, f, cpu->mem[cpu->pc++] + cpu->regs[Y]);
 
 		case AM_ZIX:
@@ -510,8 +526,10 @@
 	}
 }
 
-void step(cpu_t *cpu)
+inline void step(cpu_t *cpu)
 {
+	static int steps;
+	steps++;
 	switch (cpu->mem[cpu->pc++])
 	{
 #define INST(mn, am, op) \
@@ -526,6 +544,14 @@
 		default:
 			die("Undefined opcode");
 	}
+
+	if (steps % 100 == 0)
+		printf("%d\n", steps);
+
+	if (g_scr)
+	{
+		sdl_screen(g_scr, cpu->mem + CPU_FB_ADDR);
+	}
 }
 
 int dump_inst(cpu_t *cpu, char *buf, const char *mn, uint16_t addr, uint8_t am)
diff --git a/gui.c b/gui.c
index cfaa097..201fdae 100644
--- a/gui.c
+++ b/gui.c
@@ -15,6 +15,7 @@
 #define NK_SDL_GL3_IMPLEMENTATION
 #include "nuklear/nuklear.h"
 #include "nuklear/demo/sdl_opengl3/nuklear_sdl_gl3.h"
+#undef SCREEN_ONLY_SDL
 #include "screen.h"
 
 #define WINDOW_WIDTH 720
@@ -116,7 +117,7 @@
 		{
 			nk_layout_row_dynamic(ctx, 24, 1);
 			screen_scale = nk_propertyi(ctx, "Scale", 1, screen_scale, 8, 1, 1);
-			
+
 			nk_layout_row_static(ctx, screen_scale * 32, screen_scale * 32, 1);
 			screen(ctx, cpu->mem + CPU_FB_ADDR, screen_scale);
 		}
diff --git a/main.c b/main.c
index 07af040..84e9779 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,7 @@
 #include "cpu.h"
 #include "dbg.h"
 #include "gui.h"
+#include "screen.h"
 
 #include <bits/getopt_core.h>
 #include <ctype.h>
@@ -8,6 +9,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+extern sdl_screen_t *g_scr;
+
 int main(int argc, char **argv)
 {
 	bool disflag = false,
@@ -15,7 +18,8 @@
 		helpflag = false,
 		debugflag = false,
 		should_read = false,
-		guiflag = false;
+		guiflag = false,
+		scrflag = false;
 
 	int disasm_len = 0;
 
@@ -23,7 +27,7 @@
 
 	char c;
 
-	while ((c = getopt(argc, argv, "Ddrhgi:n:")) != -1)
+	while ((c = getopt(argc, argv, "Dsdrhgi:n:")) != -1)
 	{
 		switch (c)
 		{
@@ -49,6 +53,9 @@
 		case 'n':
 			disasm_len = atoi(optarg);
 			break;
+		case 's':
+			scrflag = true;
+			break;
 		case 'h':
 		case '?':
 			helpflag = 1;
@@ -83,6 +90,12 @@
 		printf("%s -h  for help\n", argv[0]);
 	}
 
+	if (scrflag)
+	{
+		sdl_screen_t scr = new_sdl_screen(8);
+		g_scr = &scr;
+	}
+
 	if (guiflag)
 	{
 		gui(&cpu);
diff --git a/screen.c b/screen.c
index 2eb17a2..fedc151 100644
--- a/screen.c
+++ b/screen.c
@@ -1,10 +1,12 @@
 #include "screen.h"
 #include "cpu.h"
 
+#include <SDL2/SDL.h>
+
 struct nk_color byte_to_color(uint8_t b)
 {
 	struct nk_color c;
-	c.r = (b >> 6) * (255 / 0b11);
+	c.r = (b >> 5) * (255 / 0b111);
 	c.g = ((b >> 2) & 0b111) * (255 / 0b111);
 	c.b = (b & 0b11) * (255 / 0b11);
 	c.a = 255;
@@ -32,7 +34,59 @@
 			nk_fill_rect(out,
 				nk_rect(bounds.x + i * size, bounds.y + j * size,
 					size, size), 0.0f,
-				byte_to_color(mem[i * CPU_FB_H + j]));
+				byte_to_color(mem[i + CPU_FB_H * j]));
 		}
 	}
 }
+
+sdl_screen_t new_sdl_screen(uint8_t size)
+{
+	sdl_screen_t scr;
+	scr.win = SDL_CreateWindow("6502",
+		SDL_WINDOWPOS_CENTERED,
+		SDL_WINDOWPOS_CENTERED,
+		size * 32,
+		size * 32,
+		0);
+	scr.size = size;
+	scr.r = SDL_CreateRenderer(scr.win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+
+	return scr;
+}
+
+void sdl_screen(sdl_screen_t *scr, uint8_t *mem)
+{
+	SDL_RenderClear(scr->r);
+
+	SDL_Event e;
+
+	while (SDL_PollEvent(&e))
+	{
+		switch (e.type)
+		{
+			case SDL_QUIT:
+				exit(0);
+		}
+	}
+
+	for (int i = 0; i < CPU_FB_H; i++)
+	{
+		for (int j = 0; j < CPU_FB_W; j++)
+		{
+			SDL_Rect r =
+			{
+				i * scr->size,
+				j * scr->size,
+				scr->size,
+				scr->size,
+			};
+
+			struct nk_color c = byte_to_color(mem[i + CPU_FB_H * j]);
+
+			SDL_SetRenderDrawColor(scr->r, c.r, c.g, c.b, c.a);
+			SDL_RenderFillRect(scr->r, &r);
+		}
+	}
+
+	SDL_RenderPresent(scr->r);	
+}
diff --git a/screen.h b/screen.h
index e504617..4128005 100644
--- a/screen.h
+++ b/screen.h
@@ -2,6 +2,8 @@
 
 #include <stdint.h>
 
+#ifndef SCREEN_ONLY_SDL
+
 #undef NK_IMPLEMENTATION
 #define NK_INCLUDE_FIXED_TYPES
 #define NK_INCLUDE_STANDARD_IO
@@ -12,5 +14,20 @@
 #define NK_INCLUDE_DEFAULT_FONT
 #include "nuklear/nuklear.h"
 
-// draw the CPU screen
 void screen(struct nk_context *ctx, uint8_t *mem, uint8_t size);
+
+#endif
+
+#include <SDL2/SDL.h>
+
+
+typedef struct
+{
+	SDL_Window *win;
+	SDL_Renderer *r;
+	uint8_t size;
+} sdl_screen_t;
+
+// draw the CPU screen
+sdl_screen_t new_sdl_screen(uint8_t size);
+void sdl_screen(sdl_screen_t *scr, uint8_t *mem);
diff --git a/screenshot.png b/screenshot.png
index 026a05f..be57434 100644
--- a/screenshot.png
+++ b/screenshot.png
Binary files differ
diff --git a/test.dat b/test.dat
index a1ba7d1..b004f7a 100644
--- a/test.dat
+++ b/test.dat
Binary files differ