diff options
author | dweller <dweller@cabin.digital> | 2025-03-26 20:12:14 +0200 |
---|---|---|
committer | dweller <dweller@cabin.digital> | 2025-03-26 20:12:14 +0200 |
commit | f65558c3ae2ee4439d12344f79c09b6e82519f5d (patch) | |
tree | 2087a52e025bd2a59b72a893c69acdacbb5b8b4b | |
parent | 6f3a1b4fac4091168809b50a6b94142ba2a40a4f (diff) |
add most of the instructions, needs testing
-rw-r--r-- | sources/bits.c | 3 | ||||
-rw-r--r-- | sources/meta/exec.c | 237 |
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) |