Add screen(), memory mapped frame buffer
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0b1243..fe0e4cd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,5 +14,5 @@
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
endif()
-add_executable(6502 main.c cpu.c cpu.h dbg.c dbg.h instructions.h gui.h gui.c)
+add_executable(6502 main.c cpu.c cpu.h dbg.c dbg.h instructions.h gui.h gui.c screen.h screen.c)
target_link_libraries(6502 readline SDL2 GL GLU GLEW m)
diff --git a/cpu.c b/cpu.c
index 40fb567..fbe72b2 100644
--- a/cpu.c
+++ b/cpu.c
@@ -16,7 +16,7 @@
void reset(cpu_t *cpu)
{
cpu->regs[SP] = 0xFD; // stack at is 0x100 + SP
- cpu->pc = 0; // arbitrary program counter start
+ cpu->pc = 0x600; // arbitrary program counter start
cpu->running = true;
}
@@ -24,7 +24,7 @@
{
cpu_t cpu = { 0 };
cpu.regs[SP] = 0xFD; // stack at is 0x100 + SP
- cpu.pc = 0; // arbitrary program counter start
+ cpu.pc = 0x600; // arbitrary program counter start
cpu.running = true;
cpu.mem = malloc(0xFFFF);
memset(cpu.mem, 0, 0xFFFF);
diff --git a/cpu.h b/cpu.h
index 4629b14..cee84c5 100644
--- a/cpu.h
+++ b/cpu.h
@@ -4,6 +4,9 @@
#include <stdbool.h>
#define REGISTERS R(A) R(X) R(Y) R(SP)
+#define CPU_FB_ADDR 0x200
+#define CPU_FB_W 32
+#define CPU_FB_H 32
enum // Registers
{
diff --git a/gui.c b/gui.c
index a03d948..cfaa097 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"
+#include "screen.h"
#define WINDOW_WIDTH 720
#define WINDOW_HEIGHT 640
@@ -45,8 +46,10 @@
.a = 255,
};
- uint16_t disas_start = 0,
- disas_end = 32;
+ uint16_t disas_start = 0x600,
+ disas_end = 0x600 + 32;
+
+ uint8_t screen_scale = 4;
SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS);
@@ -95,7 +98,7 @@
if (!cpu->running)
cpu_running = false;
- if (nk_begin(ctx, "Registers", nk_rect(50, 300, 400, 90),
+ if (nk_begin(ctx, "Registers", nk_rect(50, 300, 500, 90),
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
{
@@ -107,7 +110,19 @@
}
nk_end(ctx);
- if (nk_begin(ctx, "Disassembler", nk_rect(330, 50, 250, 200),
+ if (nk_begin(ctx, "Screen", nk_rect(50, 400, 150, 220),
+ NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
+ NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
+ {
+ 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);
+ }
+ nk_end(ctx);
+
+ if (nk_begin(ctx, "Disassembler", nk_rect(330, 50, 300, 200),
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
{
diff --git a/main.c b/main.c
index 9a03f95..07af040 100644
--- a/main.c
+++ b/main.c
@@ -60,9 +60,10 @@
{
printf("6502 emulator, disassembler and debugger\n"
"Usage:\n"
+ " -g use GUI\n"
" -d disassemble input\n"
" -r run input\n"
- " -D debug input (open debug prompt)\n"
+ " -D open CLI debug prompt (like gdb)\n"
" -i <input> set input file, defaults to standard input\n"
" -n <number> number of instructions to disassemble, 0 for all\n"
" -h, -? show this help page\n");
@@ -74,7 +75,7 @@
if (should_read)
{
cpu = new_cpu();
- fread(cpu.mem, 0xFFFF, 1, input);
+ fread(cpu.mem + 0x600, 0xFFFF - 0x600, 1, input);
}
else
{
diff --git a/screen.c b/screen.c
new file mode 100644
index 0000000..2eb17a2
--- /dev/null
+++ b/screen.c
@@ -0,0 +1,38 @@
+#include "screen.h"
+#include "cpu.h"
+
+struct nk_color byte_to_color(uint8_t b)
+{
+ struct nk_color c;
+ c.r = (b >> 6) * (255 / 0b11);
+ c.g = ((b >> 2) & 0b111) * (255 / 0b111);
+ c.b = (b & 0b11) * (255 / 0b11);
+ c.a = 255;
+ return c;
+}
+
+void screen(struct nk_context *ctx, uint8_t *mem, uint8_t size)
+{
+ struct nk_command_buffer *out = nk_window_get_canvas(ctx);
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state = nk_widget(&bounds, ctx);
+
+ if (!state)
+ return;
+
+ //nk_fill_rect(out, bounds, 0, nk_rgb(255, 0, 0));
+
+ //return;
+
+ for (int i = 0; i < CPU_FB_H; i++)
+ {
+ for (int j = 0; j < CPU_FB_W; j++)
+ {
+ 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]));
+ }
+ }
+}
diff --git a/screen.h b/screen.h
new file mode 100644
index 0000000..e504617
--- /dev/null
+++ b/screen.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <stdint.h>
+
+#undef NK_IMPLEMENTATION
+#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
+#include "nuklear/nuklear.h"
+
+// draw the CPU screen
+void screen(struct nk_context *ctx, uint8_t *mem, uint8_t size);
diff --git a/test.dat b/test.dat
index 310bd9e..a1ba7d1 100644
--- a/test.dat
+++ b/test.dat
Binary files differ