summaryrefslogtreecommitdiff
path: root/main.c
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 /main.c
parent5bf658d3a940e536e232d8fcd6e2ae431e5afdd7 (diff)
build ''system''; decode metaprog; disasm
Diffstat (limited to 'main.c')
-rw-r--r--main.c343
1 files changed, 0 insertions, 343 deletions
diff --git a/main.c b/main.c
deleted file mode 100644
index c082914..0000000
--- a/main.c
+++ /dev/null
@@ -1,343 +0,0 @@
-#define _DEFAULT_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <time.h>
-
-#include <endian.h>
-
-#include "bits.c"
-#include "fnt.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;
-
-#include "instr.c"
-
-#define V mem.sys.v
-#define STACK mem.sys.stack
-#define DISPLAY mem.sys.disp
-#define FONT mem.sys.font
-#define RAM mem.ram
-
-
-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;
-}
-
-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]);
- }
- }
-}
-
-void _c8_loop(chip8* c8, bool disasm, u16 from, u16 len)
-{
- u16 to = 0;
- u16 pc = 0;
-
- assert(c8);
-
- if(disasm)
- {
- pc = c8->pc;
- c8->pc = from;
- to = from + len*2;
- }
-
- c8->running = true;
- while(c8->running)
- {
- int tmp;
- u16 word, instr, nnn;
- u8 o, x, y, n, kk;
-
- if(c8->pc >= sizeof(c8->mem))
- {
- printf("PC Overflow!\n");
- c8->running = false;
- break;
- }
-
- if(c8->pc & 0x0001)
- {
- printf("PC is not aligned!\n");
- c8->running = false;
- break;
- }
-
- word = *(u16*)(c8->RAM + c8->pc);
- instr = be16toh(word);
- o = (instr & 0xF000) >> 12;
- nnn = (instr & 0x0FFF);
- x = (instr & 0x0F00) >> 8;
- y = (instr & 0x00F0) >> 4;
- n = (instr & 0x000F);
- kk = (instr & 0x00FF);
-
- printf("%04X: ", c8->pc);
- switch(o)
- {
- case 1:
- printf(" %04X JP 0x%03X\n", instr, nnn);
- if(disasm) break;
- c8->pc = nnn - 2;
- break;
-
- case 2:
- printf(" %04X CALL 0x%03X\n", instr, nnn);
- if(disasm) break;
- c8->STACK[c8->sp++] = c8->pc; /* docs says ++sp then stack[sp] = pc ??? */
- c8->pc = nnn - 2;
- break;
-
- case 3:
- printf(" %04X SE V%x, 0x%02X\n", instr, x, kk);
- if(disasm) break;
- if(c8->V[x] == kk) c8->pc += 2;
- break;
-
- case 5:
- printf(" %04X SE V%x, V%x\n", instr, x, y);
- if(disasm) break;
- if(c8->V[x] == c8->V[y]) c8->pc += 2;
- break;
-
- case 6:
- printf(" %04X LD V%x, 0x%02X\n", instr, x, kk);
- if(disasm) break;
- c8->V[x] = kk;
- break;
-
- case 7:
- printf(" %04X ADD V%x, 0x%02X\n", instr, x, kk);
- if(disasm) break;
- tmp = (int)c8->V[x] + (int)kk;
- c8->V[0xf] = (tmp > 255);
- /* c8->V[x] = (u8)tmp; /* spec says Vf not set */
- break;
-
- case 8:
- {
- switch(n)
- {
- case 4:
- printf(" %04X ADD V%x, V%x\n", instr, x, y);
- if(disasm) break;
- tmp = (int)c8->V[x] + (int)c8->V[y];
- c8->V[0xf] = (tmp > 255);
- c8->V[x] = (u8)tmp;
- break;
-
- default:
- printf(" %04X Unknown instruction\n", instr);
- if(disasm) break;
- c8->running = false;
- break;
- }
- }
- break;
-
- case 0xA:
- printf(" %04X LD I, 0x%03X\n", instr, nnn);
- if(disasm) break;
- c8->i = nnn;
- break;
-
- case 0xC:
- printf(" %04X RND V%x, 0x%02X\n", instr, x, kk);
- if(disasm) break;
- c8->V[x] = (rand() % 256) & kk;
- break;
-
- case 0xD:
- printf(" %04X DRW V%x, V%x, %d\n", instr, x, y, n);
- if(disasm) break;
- /* TODO: implement */
- break;
-
- case 0xE:
- if(kk == 0x9E)
- {
- printf(" %04X SKP V%x\n", instr, x);
- if(disasm) break;
- if(c8->keys & bit(x)) c8->pc += 2;
- }
- else if(kk == 0xA1)
- {
- printf(" %04X SKNP V%x\n", instr, x);
- if(disasm) break;
- if(!(c8->keys & bit(x))) c8->pc += 2;
- }
- else
- {
- printf(" %04X Unknown instruction\n", instr);
- if(disasm) break;
- c8->running = false;
- }
- break;
-
- case 0xF:
- if(kk == 0x07)
- {
- printf(" %04X LD V%x, DT\n", instr, x);
- if(disasm) break;
- c8->V[x] = c8->dt;
- }
- else if(kk == 0x15)
- {
- printf(" %04X LD DT, V%x\n", instr, x);
- if(disasm) break;
- c8->dt= c8->V[x];
- }
- else
- {
- printf(" %04X Unknown instruction\n", instr);
- if(disasm) break;
- c8->running = false;
- }
- break;
-
- default:
- printf(" %04X Unknown instruction\n", instr);
- if(disasm) break;
- c8->running = false;
- break;
- }
-
- if(!disasm) c8_dump_state(c8, false);
-
- c8->pc += 2;
- c8->cycles++;
- if((c8->cycles % C8_CYCLES_PER_FRAME) == 0)
- {
- if(c8->dt) c8->dt--;
- if(c8->st) c8->st--;
- }
-
- if(disasm && (c8->pc >= to)) c8->running = false;
- }
-
- 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;
- chip8 c8 = {0};
-
- srand(time(NULL));
-
- c8_reset(&c8);
-
- if(argc > 1)
- {
- u64 sz, got = 0;
-
- f = fopen(argv[1], "r");
- if(!f) return 1;
-
- fseek(f, 0, SEEK_END);
- sz = (u64)ftell(f);
- rewind(f);
-
- if(sz >= (sizeof(c8.RAM) - 512)) return 2;
-
- got = fread(c8.RAM + C8_RESET_VECTOR, 1, sz, f);
- if(got != sz) return 3;
-
- fclose(f);
- }
- else
- {
- c8.RAM[C8_RESET_VECTOR + iota] = 0x60;
- c8.RAM[C8_RESET_VECTOR + iota] = 0x04;
-
- c8.RAM[C8_RESET_VECTOR + iota] = 0x61;
- c8.RAM[C8_RESET_VECTOR + iota] = 0x03;
-
- c8.RAM[C8_RESET_VECTOR + iota] = 0x72;
- c8.RAM[C8_RESET_VECTOR + iota] = 0x01;
-
- c8.RAM[C8_RESET_VECTOR + iota] = 0x80;
- c8.RAM[C8_RESET_VECTOR + iota] = 0x14;
-
- c8.RAM[C8_RESET_VECTOR + iota] = 0x30;
- c8.RAM[C8_RESET_VECTOR + iota] = 0x10;
-
- c8.RAM[C8_RESET_VECTOR + iota] = 0x12;
- c8.RAM[C8_RESET_VECTOR + iota] = 0x04;
- }
-
- printf("Disasm:\n");
- c8_disam(&c8, C8_RESET_VECTOR, 32);
-
- printf("\nExec:\n");
- c8_loop(&c8);
-
- return 0;
-}