diff options
author | dweller <dweller@cabin.digital> | 2025-03-26 17:31:51 +0200 |
---|---|---|
committer | dweller <dweller@cabin.digital> | 2025-03-26 17:31:51 +0200 |
commit | 76d89eb9973671726dc7fffaf22b06a7a77be550 (patch) | |
tree | c0c3c6fb20d905b8f9b3bde2c1546d481b66e280 /main.c | |
parent | 5bf658d3a940e536e232d8fcd6e2ae431e5afdd7 (diff) |
build ''system''; decode metaprog; disasm
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 343 |
1 files changed, 0 insertions, 343 deletions
@@ -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; -} |