summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordweller <dweller@cabin.digital>2025-03-26 20:37:01 +0200
committerdweller <dweller@cabin.digital>2025-03-26 20:37:01 +0200
commit750cd23d7afac165502defa1d259ace00ca0e414 (patch)
treeff28a5649a4ba2b19a93c924536634106b65816e
parent202712187e6ea7ce39dafad744c1e729e5279db6 (diff)
clean up chip-8 into its own file
-rw-r--r--sources/chip8.c (renamed from sources/instr.c)108
-rw-r--r--sources/fnt.c19
-rw-r--r--sources/main.c104
-rw-r--r--sources/meta/disasm.c3
-rw-r--r--sources/meta/exec.c34
-rw-r--r--sources/meta/undef.c3
6 files changed, 142 insertions, 129 deletions
diff --git a/sources/instr.c b/sources/chip8.c
index 72511f1..f5a28a8 100644
--- a/sources/instr.c
+++ b/sources/chip8.c
@@ -1,3 +1,64 @@
+#define C8_RESET_VECTOR 0x200
+#define C8_CYCLES_PER_FRAME 1000
+
+static const u8 fnt[] =
+{
+ 0xF0, 0x90, 0x90, 0x90, 0xF0, /* 0 */
+ 0x20, 0x60, 0x20, 0x20, 0x70, /* 1 */
+ 0xF0, 0x10, 0xF0, 0x80, 0xF0, /* 2 */
+ 0xF0, 0x10, 0xF0, 0x10, 0xF0, /* 3 */
+ 0x90, 0x90, 0xF0, 0x10, 0x10, /* 4 */
+ 0xF0, 0x80, 0xF0, 0x10, 0xF0, /* 5 */
+ 0xF0, 0x80, 0xF0, 0x90, 0xF0, /* 6 */
+ 0xF0, 0x10, 0x20, 0x40, 0x40, /* 7 */
+ 0xF0, 0x90, 0xF0, 0x90, 0xF0, /* 8 */
+ 0xF0, 0x90, 0xF0, 0x10, 0xF0, /* 9 */
+ 0xF0, 0x90, 0xF0, 0x90, 0x90, /* A */
+ 0xE0, 0x90, 0xE0, 0x90, 0xE0, /* B */
+ 0xF0, 0x80, 0x80, 0x80, 0xF0, /* C */
+ 0xE0, 0x90, 0x90, 0x90, 0xE0, /* D */
+ 0xF0, 0x80, 0xF0, 0x80, 0xF0, /* E */
+ 0xF0, 0x80, 0xF0, 0x80, 0x80 /* F */
+};
+
+
+typedef struct
+{
+ u16 pc;
+ u8 sp;
+
+ u16 i;
+ u16 keys;
+
+ u64 cycles;
+
+ /* timers: */
+ u8 dt; /* - delay */
+ u8 st; /* - sound */
+
+ bool running;
+
+ union
+ {
+ struct
+ {
+ u8 v[16];
+ u64 disp[32];
+ u8 font[sizeof(fnt)];
+ u16 stack[16];
+
+ } sys;
+ u8 ram[4*KB];
+ } mem;
+
+} chip8;
+
+#define V mem.sys.v
+#define STACK mem.sys.stack
+#define DISPLAY mem.sys.disp
+#define FONT mem.sys.font
+#define RAM mem.ram
+
typedef enum
{
C8_ILL,
@@ -44,6 +105,46 @@ typedef enum
} chip8_op;
+void c8_reset(chip8* c8)
+{
+ assert(c8);
+ assert(sizeof(c8->mem) > sizeof(fnt));
+ assert(sizeof(c8->mem) >= 4*KB);
+
+ memcpy(c8->FONT, fnt, sizeof(fnt));
+
+ c8->pc = C8_RESET_VECTOR;
+ c8->running = true;
+}
+
+void c8_dump_state(chip8* c8, bool stack)
+{
+ int i = 0;
+
+ for(i = 0; i < (int)sizeof(c8->V); i += 4)
+ {
+ printf(" V%x: %02X (%3d) ", i+0, c8->V[i+0], c8->V[i+0]);
+ printf("V%x: %02X (%3d) ", i+1, c8->V[i+1], c8->V[i+1]);
+ printf("V%x: %02X (%3d) ", i+2, c8->V[i+2], c8->V[i+2]);
+ printf("V%x: %02X (%3d)\n", i+3, c8->V[i+3], c8->V[i+3]);
+ }
+
+ printf(" I:%04X SP: %02X DT: %02X ST: %02X CYCLES: %llu\n",
+ c8->i, c8->sp, c8->dt, c8->st, c8->cycles);
+
+ if(stack)
+ {
+ printf("stack:\n");
+ for(i = 0; i < (int)sizeof(c8->STACK); i += 2)
+ {
+ printf(" %-2d: %04X ", i+0, c8->STACK[i+0]);
+ printf("%-2d: %04X\n", i+1, c8->STACK[i+1]);
+ }
+ }
+}
+
+
+
#define c8_decode_generate(name) \
void c8_##name(u8* code, u16 offset, void* usrdat) \
{ \
@@ -68,6 +169,8 @@ void c8_##name(u8* code, u16 offset, void* usrdat) \
(void)n; \
(void)kk; \
\
+ X_C8_PRELUDE; \
+ \
if(o == 0 && nnn == 0x0E0) X_C8_CLS; \
else if(o == 0 && nnn == 0x0EE) X_C8_RET; \
else if(o == 0) X_C8_SYS; \
@@ -104,7 +207,6 @@ void c8_##name(u8* code, u16 offset, void* usrdat) \
else if(o == 9 && n == 0) X_C8_SNE; \
else if(o == 0xD) X_C8_DRW; \
else X_C8_ILL; \
+ \
+ X_C8_EPILOGUE; \
}
-
-#include "meta/disasm.c"
-#include "meta/exec.c"
diff --git a/sources/fnt.c b/sources/fnt.c
deleted file mode 100644
index ca45865..0000000
--- a/sources/fnt.c
+++ /dev/null
@@ -1,19 +0,0 @@
-static const u8 fnt[] =
-{
- 0xF0, 0x90, 0x90, 0x90, 0xF0, /* 0 */
- 0x20, 0x60, 0x20, 0x20, 0x70, /* 1 */
- 0xF0, 0x10, 0xF0, 0x80, 0xF0, /* 2 */
- 0xF0, 0x10, 0xF0, 0x10, 0xF0, /* 3 */
- 0x90, 0x90, 0xF0, 0x10, 0x10, /* 4 */
- 0xF0, 0x80, 0xF0, 0x10, 0xF0, /* 5 */
- 0xF0, 0x80, 0xF0, 0x90, 0xF0, /* 6 */
- 0xF0, 0x10, 0x20, 0x40, 0x40, /* 7 */
- 0xF0, 0x90, 0xF0, 0x90, 0xF0, /* 8 */
- 0xF0, 0x90, 0xF0, 0x10, 0xF0, /* 9 */
- 0xF0, 0x90, 0xF0, 0x90, 0x90, /* A */
- 0xE0, 0x90, 0xE0, 0x90, 0xE0, /* B */
- 0xF0, 0x80, 0x80, 0x80, 0xF0, /* C */
- 0xE0, 0x90, 0x90, 0x90, 0xE0, /* D */
- 0xF0, 0x80, 0xF0, 0x80, 0xF0, /* E */
- 0xF0, 0x80, 0xF0, 0x80, 0x80 /* F */
-};
diff --git a/sources/main.c b/sources/main.c
index 8c4ac97..2036b73 100644
--- a/sources/main.c
+++ b/sources/main.c
@@ -9,89 +9,12 @@
#include <endian.h>
#include "bits.c"
-#include "fnt.c"
#include "log.c"
+#include "chip8.c"
+#include "meta/disasm.c"
+#include "meta/exec.c"
-#define C8_RESET_VECTOR 0x200
-#define C8_CYCLES_PER_FRAME 1000
-
-
-typedef struct
-{
- u16 pc;
- u8 sp;
-
- u16 i;
- u16 keys;
-
- u64 cycles;
-
- /* timers: */
- u8 dt; /* - delay */
- u8 st; /* - sound */
-
- bool running;
-
- union
- {
- struct
- {
- u8 v[16];
- u64 disp[32];
- u8 font[sizeof(fnt)];
- u16 stack[16];
-
- } sys;
- u8 ram[4*KB];
- } mem;
-
-} chip8;
-
-#define V mem.sys.v
-#define STACK mem.sys.stack
-#define DISPLAY mem.sys.disp
-#define FONT mem.sys.font
-#define RAM mem.ram
-
-#include "instr.c"
-
-void c8_reset(chip8* c8)
-{
- assert(c8);
- assert(sizeof(c8->mem) > sizeof(fnt));
- assert(sizeof(c8->mem) >= 4*KB);
-
- memcpy(c8->FONT, fnt, sizeof(fnt));
-
- c8->pc = C8_RESET_VECTOR;
- c8->running = true;
-}
-
-void c8_dump_state(chip8* c8, bool stack)
-{
- int i = 0;
-
- for(i = 0; i < (int)sizeof(c8->V); i += 4)
- {
- printf(" V%x: %02X (%-3d) ", i+0, c8->V[i+0], c8->V[i+0]);
- printf("V%x: %02X (%-3d) ", i+1, c8->V[i+1], c8->V[i+1]);
- printf("V%x: %02X (%-3d) ", i+2, c8->V[i+2], c8->V[i+2]);
- printf("V%x: %02X (%-3d)\n", i+3, c8->V[i+3], c8->V[i+3]);
- }
-
- printf(" I:%04X SP: %02X DT: %02X ST: %02X\n", c8->i, c8->sp, c8->dt, c8->st);
-
- if(stack)
- {
- printf("stack:\n");
- for(i = 0; i < (int)sizeof(c8->STACK); i += 2)
- {
- printf(" %-2d: %04X ", i+0, c8->STACK[i+0]);
- printf("%-2d: %04X\n", i+1, c8->STACK[i+1]);
- }
- }
-}
int main(int argc, char** argv)
{
@@ -162,32 +85,11 @@ int main(int argc, char** argv)
{
char buf[512] = {0};
- if(c8.pc >= sizeof(c8.mem))
- {
- report(ERR, "PC Overflow!\n");
- c8.running = false;
- }
-
- if(c8.pc & 0x0001)
- {
- report(ERR, "PC is not aligned!\n");
- c8.running = false;
- }
-
c8_disasm(c8.RAM, c8.pc, buf);
printf("%04X: %s\n", c8.pc, buf);
c8_exec(c8.RAM, c8.pc, &c8);
c8_dump_state(&c8, false);
-
- c8.cycles++;
- if((c8.cycles % C8_CYCLES_PER_FRAME) == 0)
- {
- if(c8.dt) c8.dt--;
- if(c8.st) c8.st--;
- }
-
- c8.pc += 2;
}
return 0;
diff --git a/sources/meta/disasm.c b/sources/meta/disasm.c
index 66c1478..82e715e 100644
--- a/sources/meta/disasm.c
+++ b/sources/meta/disasm.c
@@ -1,3 +1,6 @@
+#define X_C8_PRELUDE
+#define X_C8_EPILOGUE
+
#define X_C8_ILL sprintf(usrdat, "%04X ILL unknown", instr)
#define X_C8_CLS sprintf(usrdat, "%04X CLS", instr)
#define X_C8_RET sprintf(usrdat, "%04X RET", instr)
diff --git a/sources/meta/exec.c b/sources/meta/exec.c
index b913390..a39aef2 100644
--- a/sources/meta/exec.c
+++ b/sources/meta/exec.c
@@ -1,11 +1,33 @@
-/* FIXME: add a one time init and deinit to generate macro */
-#define BEGIN \
-do{ \
- chip8* c8 = usrdat; \
- assert(c8);
-
+#define BEGIN do{
#define END }while(0)
+#define X_C8_PRELUDE \
+ chip8* c8 = usrdat; \
+ assert(c8); \
+\
+ if(c8->pc >= sizeof(c8->mem)) \
+ { \
+ report(ERR, "CHIP-8: PC(%04X) Overflow!\n", c8->pc); \
+ c8->running = false; \
+ } \
+\
+ if(c8->pc & 0x0001) \
+ { \
+ report(ERR, "CHIP-8: PC(%04X) is not aligned!\n", c8->pc); \
+ c8->running = false; \
+ }
+
+#define X_C8_EPILOGUE \
+BEGIN \
+ c8->cycles++; \
+ if((c8->cycles % C8_CYCLES_PER_FRAME) == 0) \
+ { \
+ if(c8->dt) c8->dt--; \
+ if(c8->st) c8->st--; \
+ } \
+ c8->pc += 2; \
+END
+
#define X_C8_ILL \
BEGIN \
c8->running = false; \
diff --git a/sources/meta/undef.c b/sources/meta/undef.c
index 1863e9b..01ce25f 100644
--- a/sources/meta/undef.c
+++ b/sources/meta/undef.c
@@ -1,3 +1,6 @@
+#undef X_C8_PRELUDE
+#undef X_C8_EPILOGUE
+
#undef X_C8_ILL
#undef X_C8_CLS
#undef X_C8_RET