From f65558c3ae2ee4439d12344f79c09b6e82519f5d Mon Sep 17 00:00:00 2001
From: dweller <dweller@cabin.digital>
Date: Wed, 26 Mar 2025 20:12:14 +0200
Subject: add most of the instructions, needs testing

---
 sources/meta/exec.c | 237 +++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 187 insertions(+), 50 deletions(-)

(limited to 'sources/meta')

diff --git a/sources/meta/exec.c b/sources/meta/exec.c
index 69e9a8a..d9a6052 100644
--- a/sources/meta/exec.c
+++ b/sources/meta/exec.c
@@ -1,3 +1,4 @@
+/* FIXME: add a one time init and deinit to generate macro */
 #define BEGIN           \
 do{                     \
     chip8* c8 = usrdat; \
@@ -5,75 +6,211 @@ do{                     \
 
 #define END }while(0)
 
-#define X_C8_ILL                                                        \
-BEGIN                                                                   \
-                                                                        \
-    c8->running = false;                                                \
+#define X_C8_ILL \
+BEGIN \
+    c8->running = false; \
     report(ERR, "Illegal instruction (%04X) @ %04X\n", instr, offset);  \
 END
 
-#define X_C8_CLS       X_C8_ILL
-#define X_C8_RET       X_C8_ILL
-#define X_C8_SYS       X_C8_ILL
+#define X_C8_CLS \
+BEGIN \
+    int i, lines = lengthof(c8->DISPLAY); \
+    for(i = 0; i < lines; i++) c8->DISPLAY[i] = 0; \
+END
+
+#define X_C8_RET \
+BEGIN \
+    c8->pc = c8->STACK[--c8->sp]; \
+END
+
+/* NOTE: NOP for now */
+#define X_C8_SYS \
+BEGIN \
+END
 
-#define X_C8_JP       \
-BEGIN                 \
+#define X_C8_JP \
+BEGIN \
     c8->pc = nnn - 2; \
 END
 
-#define X_C8_CALL      X_C8_ILL
-#define X_C8_LDI       X_C8_ILL
-#define X_C8_JPV       X_C8_ILL
+#define X_C8_CALL \
+BEGIN \
+    c8->STACK[c8->sp++] = c8->pc; \
+    c8->pc = nnn; \
+END
+
+#define X_C8_LDI \
+BEGIN \
+    c8->i = nnn; \
+END
 
-#define X_C8_SEB                    \
-BEGIN                               \
+#define X_C8_JPV \
+BEGIN \
+    c8->pc = nnn + c8->V[0] - 2; \
+END
+
+#define X_C8_SEB \
+BEGIN \
     if(c8->V[x] == kk) c8->pc += 2; \
 END
 
-#define X_C8_SNEB      X_C8_ILL
+#define X_C8_SNEB \
+BEGIN \
+    if(c8->V[x] != kk) c8->pc += 2; \
+END
 
-#define X_C8_LD    \
-BEGIN              \
+#define X_C8_LD \
+BEGIN \
     c8->V[x] = kk; \
 END
 
-#define X_C8_ADDB                      \
-BEGIN                                  \
+#define X_C8_ADDB \
+BEGIN \
     int tmp = (int)c8->V[x] + (int)kk; \
-    c8->V[x] = tmp & 0xFF;             \
-END
-
-#define X_C8_RND       X_C8_ILL
-#define X_C8_SKP       X_C8_ILL
-#define X_C8_SKNP      X_C8_ILL
-#define X_C8_MVDT      X_C8_ILL
-#define X_C8_LDK       X_C8_ILL
-#define X_C8_LDDT      X_C8_ILL
-#define X_C8_LDST      X_C8_ILL
-#define X_C8_ADDI      X_C8_ILL
-#define X_C8_HEX       X_C8_ILL
-#define X_C8_BCD       X_C8_ILL
-#define X_C8_SAVE      X_C8_ILL
-#define X_C8_RESTORE   X_C8_ILL
-#define X_C8_SE        X_C8_ILL
-#define X_C8_MOVE      X_C8_ILL
-#define X_C8_OR        X_C8_ILL
-#define X_C8_AND       X_C8_ILL
-#define X_C8_XOR       X_C8_ILL
-
-#define X_C8_ADD                             \
-BEGIN                                        \
+    c8->V[x] = tmp & 0xFF; \
+END
+
+#define X_C8_RND \
+BEGIN \
+    c8->V[x] = (rand() % 255) & kk; \
+END
+
+#define X_C8_SKP \
+BEGIN \
+    if(c8->keys & c8->V[x]) c8->pc += 2; \
+END
+
+#define X_C8_SKNP \
+BEGIN \
+    if(!(c8->keys & c8->V[x])) c8->pc += 2; \
+END
+
+#define X_C8_MVDT \
+BEGIN \
+    c8->V[x] = c8->dt; \
+END
+
+/* TODO: implement */
+#define X_C8_LDK \
+BEGIN \
+    if(!c8->keys) c8->pc -= 2; \
+END
+
+#define X_C8_LDDT \
+BEGIN \
+    c8->dt = c8->V[x]; \
+END
+
+#define X_C8_LDST \
+BEGIN \
+    c8->st = c8->V[x]; \
+END
+
+#define X_C8_ADDI \
+BEGIN \
+    c8->i += c8->V[x]; \
+END
+
+#define X_C8_HEX \
+BEGIN \
+    usize m = (usize)(c8->RAM); \
+    usize f = (usize)(c8->FONT); \
+    c8->i = (f - m) + c8->V[x] * 5; \
+END
+
+#define X_C8_BCD \
+BEGIN \
+    c8->RAM[c8->i] = c8->V[x] / 100; \
+    c8->RAM[c8->i + 1] = c8->V[x] % 100 / 10; \
+    c8->RAM[c8->i + 2] = c8->V[x] % 10; \
+END
+
+#define X_C8_SAVE \
+BEGIN \
+    u8 i; \
+    for(i = 0; i < x; i++) c8->RAM[c8->i + i] = c8->V[i]; \
+END
+
+#define X_C8_RESTORE \
+BEGIN \
+    u8 i; \
+    for(i = 0; i < x; i++) c8->V[i] = c8->RAM[c8->i + i]; \
+END
+
+#define X_C8_SE \
+BEGIN \
+    if(c8->V[x] == c8->V[y]) c8->pc += 2; \
+END
+
+#define X_C8_MOVE \
+BEGIN \
+    c8->V[x] = c8->V[y]; \
+END
+
+#define X_C8_OR \
+BEGIN \
+    c8->V[x] |= c8->V[y]; \
+END
+
+#define X_C8_AND \
+BEGIN \
+    c8->V[x] &= c8->V[y]; \
+END
+
+#define X_C8_XOR \
+BEGIN \
+    c8->V[x] ^= c8->V[y]; \
+END
+
+#define X_C8_ADD \
+BEGIN \
     int tmp = (int)c8->V[x] + (int)c8->V[y]; \
-    c8->V[0xf] = (tmp > 255);                \
-    c8->V[x] = tmp & 0xFF;                   \
+    c8->V[0xf] = tmp > 255; \
+    c8->V[x]   = tmp; \
+END
+
+#define X_C8_SUB \
+BEGIN \
+    int tmp = (int)c8->V[x] - (int)c8->V[y]; \
+    c8->V[0xf] = tmp > 0; \
+    c8->V[x]   = tmp; \
+END
+
+#define X_C8_SHR \
+BEGIN \
+    c8->V[0xf] = (c8->V[y] & 0x1) ? 1 : 0; \
+    c8->V[x]   = c8->V[y] >> 1; \
+END
+
+#define X_C8_SUBN \
+BEGIN \
+    int tmp = (int)c8->V[y] - (int)c8->V[x]; \
+    c8->V[0xf] = tmp > 0; \
+    c8->V[x]   = tmp; \
+END
+
+#define X_C8_SHL \
+BEGIN \
+    c8->V[0xf] = (c8->V[y] & 0x80) ? 1 : 0; \
+    c8->V[x]   = c8->V[y] << 1; \
 END
 
-#define X_C8_SUB       X_C8_ILL
-#define X_C8_SHR       X_C8_ILL
-#define X_C8_SUBN      X_C8_ILL
-#define X_C8_SHL       X_C8_ILL
-#define X_C8_SNE       X_C8_ILL
-#define X_C8_DRW       X_C8_ILL
+#define X_C8_SNE \
+BEGIN \
+    if(c8->V[x] != c8->V[y]) c8->pc += 2; \
+END
+
+
+/* TODO: actually implement */
+#define X_C8_DRW \
+BEGIN \
+    u8 l; \
+    u8 cx = c8->V[x]; \
+    u8 cy = c8->V[y]; \
+    \
+    for(l = 0; l < n; l++) \
+        c8->DISPLAY[cy + l * cx] ^= c8->RAM[c8->i + l]; \
+END
 
 c8_decode_generate(exec)
 
-- 
cgit v1.2.3