summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordweller <dweller@cabin.digital>2025-03-26 17:31:51 +0200
committerdweller <dweller@cabin.digital>2025-03-26 17:31:51 +0200
commit76d89eb9973671726dc7fffaf22b06a7a77be550 (patch)
treec0c3c6fb20d905b8f9b3bde2c1546d481b66e280
parent5bf658d3a940e536e232d8fcd6e2ae431e5afdd7 (diff)
build ''system''; decode metaprog; disasm
-rw-r--r--.gitignore1
-rwxr-xr-xbuild/x1114
-rwxr-xr-xclean2
-rw-r--r--instr.c149
-rw-r--r--sources/bits.c (renamed from bits.c)0
-rw-r--r--sources/fnt.c (renamed from fnt.c)0
-rw-r--r--sources/instr.c102
-rw-r--r--sources/main.c (renamed from main.c)23
-rw-r--r--sources/meta/disasm.c41
-rw-r--r--sources/meta/undef.c36
10 files changed, 211 insertions, 157 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d4f588e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+artifacts/
diff --git a/build/x11 b/build/x11
new file mode 100755
index 0000000..a383438
--- /dev/null
+++ b/build/x11
@@ -0,0 +1,14 @@
+#!/bin/sh -e
+
+bench()
+{
+ if [ x = "x$(which time)" ]; then
+ $@
+ echo "time not installed"
+ else
+ time $@
+ fi
+}
+
+>&2 bench cc -std=c89 -Wall -Wextra sources/main.c -static -o artifacts/xip-8
+>&2 echo "------------------------------------------------\n"
diff --git a/clean b/clean
new file mode 100755
index 0000000..1dd2ea1
--- /dev/null
+++ b/clean
@@ -0,0 +1,2 @@
+#!/bin/sh -e
+rm -rf artifacts/*
diff --git a/instr.c b/instr.c
deleted file mode 100644
index bef859d..0000000
--- a/instr.c
+++ /dev/null
@@ -1,149 +0,0 @@
-typedef enum
-{
- C8_ILL,
-/* Onnn = 0,1,2,A,B */
-/* 00E0 - CLS */ C8_CLS,
-/* 00EE - RET */ C8_RET,
-/* 0nnn - SYS addr */ C8_SYS,
-/* 1nnn - JP addr */ C8_JP,
-/* 2nnn - CALL addr */ C8_CALL,
-/* Annn - LD I, addr */ C8_LDI,
-/* Bnnn - JP V0, addr */ C8_JPV,
-/* Oxkk = 3,4,6,7,C,E,F */
-/* 3xkk - SE Vx, byte */ C8_SEB,
-/* 4xkk - SNE Vx, byte */ C8_SNEB,
-/* 6xkk - LD Vx, byte */ C8_LD,
-/* 7xkk - ADD Vx, byte */ C8_ADDB,
-/* Cxkk - RND Vx, byte */ C8_RND,
-/* Ex9E - SKP Vx */ C8_SKP,
-/* ExA1 - SKNP Vx */ C8_SKNP,
-/* Fx07 - LD Vx, DT */ C8_MVDT,
-/* Fx0A - LD Vx, K */ C8_LDK,
-/* Fx15 - LD DT, Vx */ C8_LDDT,
-/* Fx18 - LD ST, Vx */ C8_LDST,
-/* Fx1E - ADD I, Vx */ C8_ADDI,
-/* Fx29 - LD F, Vx */ C8_HEX,
-/* Fx33 - LD B, Vx */ C8_BCD,
-/* Fx55 - LD [I], Vx */ C8_SAVE,
-/* Fx65 - LD Vx, [I] */ C8_RESTORE,
-/* Oxyn = 5,8,9,D */
-/* 5xy0 - SE Vx, Vy */ C8_SE,
-/* 8xy0 - LD Vx, Vy */ C8_MOVE,
-/* 8xy1 - OR Vx, Vy */ C8_OR,
-/* 8xy2 - AND Vx, Vy */ C8_AND,
-/* 8xy3 - XOR Vx, Vy */ C8_XOR,
-/* 8xy4 - ADD Vx, Vy */ C8_ADD,
-/* 8xy5 - SUB Vx, Vy */ C8_SUB,
-/* 8xy6 - SHR Vx {, Vy} */ C8_SHR,
-/* 8xy7 - SUBN Vx, Vy */ C8_SUBN,
-/* 8xyE - SHL Vx {, Vy} */ C8_SHL,
-/* 9xy0 - SNE Vx, Vy */ C8_SNE,
-/* Dxyn - DRW Vx, Vy, nibble */ C8_DRW,
- C8_OP_CNT
-
-} chip8_op;
-
-typedef void (*instr_func)(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 n, u8 kk);
-
-
-const char* chip8_disasm_fmts[C8_OP_CNT] =
-{
- "ILL unknown",
- "CLS",
- "RET",
- "SYS %03X",
- "JP %03X",
- "CALL %03X",
- "LD I, %03X",
- "JP V0, %03X",
- "SE V%-2x, %-2d",
- "SNE V%-2x, %-2d",
- "LD V%-2x, %-2d",
- "ADD V%-2x, %-2d",
- "RND V%-2x, %-2d",
- "SKP V%-2x",
- "SKNP V%-2x",
- "LD V%-2x, DT",
- "LD V%-2x, K",
- "LD DT, V%-2x",
- "LD ST, V%-2x",
- "ADD I, V%-2x",
- "LD F, V%-2x",
- "LD B, V%-2x",
- "LD [I], V%-2x",
- "LD V%-2x, [I]",
- "SE V%-2x, V%-2x",
- "LD V%-2x, V%-2x",
- "OR V%-2x, V%-2x",
- "AND V%-2x, V%-2x",
- "XOR V%-2x, V%-2x",
- "ADD V%-2x, V%-2x",
- "SUB V%-2x, V%-2x",
- "SHR V%-2x, V%-2x",
- "SUBN V%-2x, V%-2x",
- "SHL V%-2x, V%-2x",
- "SNE V%-2x, V%-2x",
- "DRW V%-2x, V%-2x, %-1d"
-};
-
-void c8_decode(u8* code, u16 offset, instr_func func, chip8* c8);
-void c8_disasm(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 n, u8 kk);
-void c8_do(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 n, u8 kk);
-
-void c8_decode(u8* code, u16 offset, instr_func func, chip8* c8)
-{
- chip8_op op = C8_ILL;
- u16 word, instr, nnn;
- u8 o, x, y, n, kk;
-
- word = *(u16*)(code + offset);
- instr = be16toh(word);
- o = (instr & 0xF000) >> 12;
- nnn = (instr & 0x0FFF);
- x = (instr & 0x0F00) >> 8;
- y = (instr & 0x00F0) >> 4;
- n = (instr & 0x000F);
- kk = (instr & 0x00FF);
-
- if(o == 0 && nnn == 0x0E0) op = C8_CLS;
- else if(o == 0 && nnn == 0x0EE) op = C8_RET;
- else if(o == 0) op = C8_SYS;
- else if(o == 1) op = C8_JP;
- else if(o == 2) op = C8_CALL;
- else if(o == 0xA) op = C8_LDI;
- else if(o == 0xB) op = C8_JPV;
- else if(o == 3) op = C8_SEB;
- else if(o == 4) op = C8_SNEB;
- else if(o == 6) op = C8_LD;
- else if(o == 7) op = C8_ADDB;
- else if(o == 0xC) op = C8_RND;
- else if(o == 0xE && kk == 0x9E) op = C8_SKP;
- else if(o == 0xE && kk == 0xA1) op = C8_SKNP;
- else if(o == 0xF && kk == 0x07) op = C8_MVDT;
- else if(o == 0xF && kk == 0x0A) op = C8_LDK;
- else if(o == 0xF && kk == 0x15) op = C8_LDDT;
- else if(o == 0xF && kk == 0x18) op = C8_LDST;
- else if(o == 0xF && kk == 0x1E) op = C8_ADDI;
- else if(o == 0xF && kk == 0x29) op = C8_HEX;
- else if(o == 0xF && kk == 0x33) op = C8_BCD;
- else if(o == 0xF && kk == 0x55) op = C8_SAVE;
- else if(o == 0xF && kk == 0x65) op = C8_RESTORE;
- else if(o == 5 && n == 0) op = C8_SE;
- else if(o == 8 && n == 0) op = C8_MOVE;
- else if(o == 8 && n == 1) op = C8_OR;
- else if(o == 8 && n == 2) op = C8_AND;
- else if(o == 8 && n == 3) op = C8_XOR;
- else if(o == 8 && n == 4) op = C8_ADD;
- else if(o == 8 && n == 5) op = C8_SUB;
- else if(o == 8 && n == 6) op = C8_SHR;
- else if(o == 8 && n == 7) op = C8_SUBN;
- else if(o == 8 && n == 0xE) op = C8_SHL;
- else if(o == 9 && n == 0) op = C8_SNE;
- else if(o == 0xD) op = C8_DRW;
-
- func(c8, op, nnn, x, y, n, kk);
-}
-
-void c8_disasm(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 kk, u8 n);
-void c8_do(chip8* c8, chip8_op op, u16 nnn, u8 x, u8 y, u8 kk, u8 n);
-
diff --git a/bits.c b/sources/bits.c
index a6b7887..a6b7887 100644
--- a/bits.c
+++ b/sources/bits.c
diff --git a/fnt.c b/sources/fnt.c
index ca45865..ca45865 100644
--- a/fnt.c
+++ b/sources/fnt.c
diff --git a/sources/instr.c b/sources/instr.c
new file mode 100644
index 0000000..8c0b132
--- /dev/null
+++ b/sources/instr.c
@@ -0,0 +1,102 @@
+typedef enum
+{
+ C8_ILL,
+/* Onnn = 0,1,2,A,B */
+/* 00E0 - CLS */ C8_CLS,
+/* 00EE - RET */ C8_RET,
+/* 0nnn - SYS addr */ C8_SYS,
+/* 1nnn - JP addr */ C8_JP,
+/* 2nnn - CALL addr */ C8_CALL,
+/* Annn - LD I, addr */ C8_LDI,
+/* Bnnn - JP V0, addr */ C8_JPV,
+/* Oxkk = 3,4,6,7,C,E,F */
+/* 3xkk - SE Vx, byte */ C8_SEB,
+/* 4xkk - SNE Vx, byte */ C8_SNEB,
+/* 6xkk - LD Vx, byte */ C8_LD,
+/* 7xkk - ADD Vx, byte */ C8_ADDB,
+/* Cxkk - RND Vx, byte */ C8_RND,
+/* Ex9E - SKP Vx */ C8_SKP,
+/* ExA1 - SKNP Vx */ C8_SKNP,
+/* Fx07 - LD Vx, DT */ C8_MVDT,
+/* Fx0A - LD Vx, K */ C8_LDK,
+/* Fx15 - LD DT, Vx */ C8_LDDT,
+/* Fx18 - LD ST, Vx */ C8_LDST,
+/* Fx1E - ADD I, Vx */ C8_ADDI,
+/* Fx29 - LD F, Vx */ C8_HEX,
+/* Fx33 - LD B, Vx */ C8_BCD,
+/* Fx55 - LD [I], Vx */ C8_SAVE,
+/* Fx65 - LD Vx, [I] */ C8_RESTORE,
+/* Oxyn = 5,8,9,D */
+/* 5xy0 - SE Vx, Vy */ C8_SE,
+/* 8xy0 - LD Vx, Vy */ C8_MOVE,
+/* 8xy1 - OR Vx, Vy */ C8_OR,
+/* 8xy2 - AND Vx, Vy */ C8_AND,
+/* 8xy3 - XOR Vx, Vy */ C8_XOR,
+/* 8xy4 - ADD Vx, Vy */ C8_ADD,
+/* 8xy5 - SUB Vx, Vy */ C8_SUB,
+/* 8xy6 - SHR Vx {, Vy} */ C8_SHR,
+/* 8xy7 - SUBN Vx, Vy */ C8_SUBN,
+/* 8xyE - SHL Vx {, Vy} */ C8_SHL,
+/* 9xy0 - SNE Vx, Vy */ C8_SNE,
+/* Dxyn - DRW Vx, Vy, nibble */ C8_DRW,
+ C8_OP_CNT
+
+} chip8_op;
+
+
+#define c8_decode_generate(name) \
+void c8_##name(u8* code, u16 offset, void* usrdat) \
+{ \
+ u16 word, instr, nnn; \
+ u8 o, x, y, n, kk; \
+ \
+ (void)usrdat; \
+ \
+ word = *(u16*)(code + offset); \
+ instr = be16toh(word); \
+ o = (instr & 0xF000) >> 12; \
+ nnn = (instr & 0x0FFF); \
+ x = (instr & 0x0F00) >> 8; \
+ y = (instr & 0x00F0) >> 4; \
+ n = (instr & 0x000F); \
+ kk = (instr & 0x00FF); \
+ \
+ if(o == 0 && nnn == 0x0E0) X_C8_CLS; \
+ else if(o == 0 && nnn == 0x0EE) X_C8_RET; \
+ else if(o == 0) X_C8_SYS; \
+ else if(o == 1) X_C8_JP; \
+ else if(o == 2) X_C8_CALL; \
+ else if(o == 0xA) X_C8_LDI; \
+ else if(o == 0xB) X_C8_JPV; \
+ else if(o == 3) X_C8_SEB; \
+ else if(o == 4) X_C8_SNEB; \
+ else if(o == 6) X_C8_LD; \
+ else if(o == 7) X_C8_ADDB; \
+ else if(o == 0xC) X_C8_RND; \
+ else if(o == 0xE && kk == 0x9E) X_C8_SKP; \
+ else if(o == 0xE && kk == 0xA1) X_C8_SKNP; \
+ else if(o == 0xF && kk == 0x07) X_C8_MVDT; \
+ else if(o == 0xF && kk == 0x0A) X_C8_LDK; \
+ else if(o == 0xF && kk == 0x15) X_C8_LDDT; \
+ else if(o == 0xF && kk == 0x18) X_C8_LDST; \
+ else if(o == 0xF && kk == 0x1E) X_C8_ADDI; \
+ else if(o == 0xF && kk == 0x29) X_C8_HEX; \
+ else if(o == 0xF && kk == 0x33) X_C8_BCD; \
+ else if(o == 0xF && kk == 0x55) X_C8_SAVE; \
+ else if(o == 0xF && kk == 0x65) X_C8_RESTORE; \
+ else if(o == 5 && n == 0) X_C8_SE; \
+ else if(o == 8 && n == 0) X_C8_MOVE; \
+ else if(o == 8 && n == 1) X_C8_OR; \
+ else if(o == 8 && n == 2) X_C8_AND; \
+ else if(o == 8 && n == 3) X_C8_XOR; \
+ else if(o == 8 && n == 4) X_C8_ADD; \
+ else if(o == 8 && n == 5) X_C8_SUB; \
+ else if(o == 8 && n == 6) X_C8_SHR; \
+ else if(o == 8 && n == 7) X_C8_SUBN; \
+ else if(o == 8 && n == 0xE) X_C8_SHL; \
+ else if(o == 9 && n == 0) X_C8_SNE; \
+ else if(o == 0xD) X_C8_DRW; \
+ else X_C8_ILL; \
+}
+
+#include "meta/disasm.c"
diff --git a/main.c b/sources/main.c
index c082914..56630df 100644
--- a/main.c
+++ b/sources/main.c
@@ -281,13 +281,11 @@ void _c8_loop(chip8* c8, bool disasm, u16 from, u16 len)
if(disasm) c8->pc = pc;
}
-void c8_disam(chip8* c8, u16 from, u16 len) { _c8_loop(c8, true, from, len); }
-void c8_loop(chip8* c8) { _c8_loop(c8, false, 0, 0); }
-
int main(int argc, char** argv)
{
- FILE* f = NULL;
+ u64 sz = 0;
+ FILE* f = NULL;
chip8 c8 = {0};
srand(time(NULL));
@@ -296,7 +294,7 @@ int main(int argc, char** argv)
if(argc > 1)
{
- u64 sz, got = 0;
+ u64 got = 0;
f = fopen(argv[1], "r");
if(!f) return 1;
@@ -331,13 +329,22 @@ int main(int argc, char** argv)
c8.RAM[C8_RESET_VECTOR + iota] = 0x12;
c8.RAM[C8_RESET_VECTOR + iota] = 0x04;
+
+ sz = iota;
}
printf("Disasm:\n");
- c8_disam(&c8, C8_RESET_VECTOR, 32);
+ {
+ u64 i;
+ char buf[512] = {0};
- printf("\nExec:\n");
- c8_loop(&c8);
+ for(i = 0; i < sz; i += 2)
+ {
+ u16 pc = C8_RESET_VECTOR + i;
+ c8_disasm(c8.RAM, pc, buf);
+ printf("%04X: %s\n", pc, buf);
+ }
+ }
return 0;
}
diff --git a/sources/meta/disasm.c b/sources/meta/disasm.c
new file mode 100644
index 0000000..2a33aed
--- /dev/null
+++ b/sources/meta/disasm.c
@@ -0,0 +1,41 @@
+#define X_C8_ILL sprintf(usrdat, "ILL unknown")
+#define X_C8_CLS sprintf(usrdat, "CLS")
+#define X_C8_RET sprintf(usrdat, "RET")
+#define X_C8_SYS sprintf(usrdat, "SYS 0x%03X", nnn)
+#define X_C8_JP sprintf(usrdat, "JP 0x%03X", nnn)
+#define X_C8_CALL sprintf(usrdat, "CALL 0x%03X", nnn)
+#define X_C8_LDI sprintf(usrdat, "LD I, 0x%03X", nnn)
+#define X_C8_JPV sprintf(usrdat, "JP V0, 0x%03X", nnn)
+#define X_C8_SEB sprintf(usrdat, "SE V%x, %d", x, kk)
+#define X_C8_SNEB sprintf(usrdat, "SNE V%x, %d", x, kk)
+#define X_C8_LD sprintf(usrdat, "LD V%x, %d", x, kk)
+#define X_C8_ADDB sprintf(usrdat, "ADD V%x, %d", x, kk)
+#define X_C8_RND sprintf(usrdat, "RND V%x, %d", x, kk)
+#define X_C8_SKP sprintf(usrdat, "SKP V%x", x)
+#define X_C8_SKNP sprintf(usrdat, "SKNP V%x", x)
+#define X_C8_MVDT sprintf(usrdat, "LD V%x, DT", x)
+#define X_C8_LDK sprintf(usrdat, "LD V%x, K", x)
+#define X_C8_LDDT sprintf(usrdat, "LD DT, V%x", x)
+#define X_C8_LDST sprintf(usrdat, "LD ST, V%x", x)
+#define X_C8_ADDI sprintf(usrdat, "ADD I, V%x", x)
+#define X_C8_HEX sprintf(usrdat, "LD F, V%x", x)
+#define X_C8_BCD sprintf(usrdat, "LD B, V%x", x)
+#define X_C8_SAVE sprintf(usrdat, "LD [I], V%x", x)
+#define X_C8_RESTORE sprintf(usrdat, "LD V%x, [I]", x)
+#define X_C8_SE sprintf(usrdat, "SE V%x, V%x", x, y)
+#define X_C8_MOVE sprintf(usrdat, "LD V%x, V%x", x, y)
+#define X_C8_OR sprintf(usrdat, "OR V%x, V%x", x, y)
+#define X_C8_AND sprintf(usrdat, "AND V%x, V%x", x, y)
+#define X_C8_XOR sprintf(usrdat, "XOR V%x, V%x", x, y)
+#define X_C8_ADD sprintf(usrdat, "ADD V%x, V%x", x, y)
+#define X_C8_SUB sprintf(usrdat, "SUB V%x, V%x", x, y)
+#define X_C8_SHR sprintf(usrdat, "SHR V%x, V%x", x, y)
+#define X_C8_SUBN sprintf(usrdat, "SUBN V%x, V%x", x, y)
+#define X_C8_SHL sprintf(usrdat, "SHL V%x, V%x", x, y)
+#define X_C8_SNE sprintf(usrdat, "SNE V%x, V%x", x, y)
+#define X_C8_DRW sprintf(usrdat, "DRW V%x, V%x, %d", x, y, n)
+
+c8_decode_generate(disasm)
+
+#include "undef.c"
+
diff --git a/sources/meta/undef.c b/sources/meta/undef.c
new file mode 100644
index 0000000..1863e9b
--- /dev/null
+++ b/sources/meta/undef.c
@@ -0,0 +1,36 @@
+#undef X_C8_ILL
+#undef X_C8_CLS
+#undef X_C8_RET
+#undef X_C8_SYS
+#undef X_C8_JP
+#undef X_C8_CALL
+#undef X_C8_LDI
+#undef X_C8_JPV
+#undef X_C8_SEB
+#undef X_C8_SNEB
+#undef X_C8_LD
+#undef X_C8_ADDB
+#undef X_C8_RND
+#undef X_C8_SKP
+#undef X_C8_SKNP
+#undef X_C8_MVDT
+#undef X_C8_LDK
+#undef X_C8_LDDT
+#undef X_C8_LDST
+#undef X_C8_ADDI
+#undef X_C8_HEX
+#undef X_C8_BCD
+#undef X_C8_SAVE
+#undef X_C8_RESTORE
+#undef X_C8_SE
+#undef X_C8_MOVE
+#undef X_C8_OR
+#undef X_C8_AND
+#undef X_C8_XOR
+#undef X_C8_ADD
+#undef X_C8_SUB
+#undef X_C8_SHR
+#undef X_C8_SUBN
+#undef X_C8_SHL
+#undef X_C8_SNE
+#undef X_C8_DRW