summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordweller <dweller@cabin.digital>2025-03-26 20:12:14 +0200
committerdweller <dweller@cabin.digital>2025-03-26 20:12:14 +0200
commitf65558c3ae2ee4439d12344f79c09b6e82519f5d (patch)
tree2087a52e025bd2a59b72a893c69acdacbb5b8b4b
parent6f3a1b4fac4091168809b50a6b94142ba2a40a4f (diff)
add most of the instructions, needs testing
-rw-r--r--sources/bits.c3
-rw-r--r--sources/meta/exec.c237
2 files changed, 190 insertions, 50 deletions
diff --git a/sources/bits.c b/sources/bits.c
index a6b7887..ba52f4f 100644
--- a/sources/bits.c
+++ b/sources/bits.c
@@ -1,5 +1,7 @@
#define iota __COUNTER__
+#define lengthof(x) (sizeof(x) / sizeof((x)[0]))
+
#define bit(x) (1 << (x))
#define KB bit(10)
@@ -9,6 +11,7 @@
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long long u64;
+typedef u64 usize;
typedef u8 bool;
#define true 1
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)