From bf544a28fb0b462f7dfe05f323bee1ee31878bc7 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Fri, 27 Sep 2019 22:21:39 -0400 Subject: fix drawing --- chip8.c | 399 +++++++++++++++++++++++++++++++--------------------------------- chip8.h | 2 + ui.c | 26 ++++- 3 files changed, 214 insertions(+), 213 deletions(-) diff --git a/chip8.c b/chip8.c index b27d067..504c49c 100644 --- a/chip8.c +++ b/chip8.c @@ -21,7 +21,6 @@ static void load_rom(); static void init_vm(); -static void vm_thread(void* v); chip8_vm vm; @@ -47,220 +46,206 @@ void load_rom() { fclose(f); } -void vm_thread(void* v) { - memset(&vm.screen, 0, sizeof(vm.screen)); - while (1) { - // read 2 bytes and convert to big-endian - u16 in = htons(vm.rom[vm.PC + 0x1]<<8 | vm.rom[vm.PC]); +void vm_step() { + // read 2 bytes and convert to big-endian + u16 in = htons(vm.rom[vm.PC + 0x1]<<8 | vm.rom[vm.PC]); - // in>>12&0xF 0xFFFf - // ^ - // in>>8&0xF 0xFFFf - // ^ - // in>>4&0xF 0xFFFf - // ^ - // in&0xF 0xFFFf - // ^ - // in&0xFFF 0xFFFf - // ^^^ - // in&0xFF 0xFFFf - // ^^ - // in&0xFF 0xFFFf - // ^^ + // in>>12&0xF 0xFFFF + // ^ + // in>>8&0xF 0xFFFF + // ^ + // in>>4&0xF 0xFFFF + // ^ + // in&0xF 0xFFFF + // ^ + // in&0xFFF 0xFFFF + // ^^^ + // in&0xFF 0xFFFF + // ^^ + // in&0xFF 0xFFFF + // ^^ - switch ((in>>12&0xF)) { - case 0x0: - switch (in&0xFF) { - case 0xE0: // CLS - memset(&vm.screen, 0, sizeof(vm.screen)); - break; - case 0xEE: // RET - vm.PC = vm.stack[vm.SP--]; - break; - } - break; - case 0x1: // JP addr - vm.PC = (in&0xFFF) - 0x2; - break; - case 0x2: // CALL addr - vm.stack[++vm.SP] = vm.PC; - vm.PC = (in&0xFFF) - 0x2; - break; - case 0x3: // SE Vx, byte - if (vm.Vx[in>>8&0xF] == (in&0xFF)) { - vm.PC += 0x2; - } - break; - case 0x4: // SNE Vx, byte - if (vm.Vx[in>>8&0xF] != (in&0xFF)) { - vm.PC += 0x2; - } - break; - case 0x5: // SE Vx, Vy - if (vm.Vx[in>>8&0xF] == vm.Vx[in>>4&0xF]) { - vm.PC += 0x2; - } - break; - case 0x6: // LD Vx, byte - vm.Vx[in>>8&0xF] = in&0xFF; - break; - case 0x7: // ADD Vx, byte - vm.Vx[in>>8&0xF] += in&0xFF; - break; - case 0x8: - switch(in&0xF) { - case 0x0: // LD Vx, Vy - vm.Vx[in>>8&0xF] = vm.Vx[in>>4&0xF]; - break; - case 0x1: // OR Vx, Vy - vm.Vx[in>>8&0xF] |= vm.Vx[in>>4&0xF]; - break; - case 0x2: // AND Vx, Vy - vm.Vx[in>>8&0xF] &= vm.Vx[in>>4&0xF]; - break; - case 0x3: // XOR Vx, Vy - vm.Vx[in>>8&0xF] ^= vm.Vx[in>>4&0xF]; - break; - case 0x4: // ADD Vx, Vy - if ((vm.Vx[in>>8&0xF] + vm.Vx[in>>4&0xF]) > 0xFF) { - vm.Vx[0xF] = 1; - } else { - vm.Vx[0xF] = 0; - } - vm.Vx[in>>8&0xF] = (vm.Vx[in>>8&0xF] + vm.Vx[in>>4&0xF])&0xFF; - break; - case 0x5: // SUB Vx, Vy - if (vm.Vx[in>>8&0xF] > vm.Vx[in>>4&0xF]) { - vm.Vx[0xF] = 1; - } else { - vm.Vx[0xF] = 0; - } - vm.Vx[in>>8&0xF] -= vm.Vx[in>>4&0xF]; - break; - case 0x6: // SHR Vx {, Vy} - vm.Vx[0xF] = (vm.Vx[in>>8&0xF] & 1); - // TODO: toggle for Vx /= 2 - vm.Vx[in>>8&0xF] = vm.Vx[in>>8&0xF]>>1; - break; - case 0x7: // SUBN Vx, Vy - if (vm.Vx[in>>8&0xF] < vm.Vx[in>>4&0xF]) { - vm.Vx[0xF] = 1; - } else { - vm.Vx[0xF] = 0; - } - vm.Vx[in>>8&0xF] = vm.Vx[in>>4&0xF] - vm.Vx[in>>8&0xF]; - break; - case 0xE: // SHL Vx {, Vy} - vm.Vx[0xF] = ((vm.Vx[in>>8&0xF]>>7) & 1); - // TODO: toggle for Vx *= 2; - vm.Vx[in>>8&0xF] = vm.Vx[in>>8&0xF]<<1; - break; - } - break; - case 0x9: // SNE Vx, Vy - if (vm.Vx[(in>>8&0xF)] != vm.Vx[(in>>4&0xF)]) { - vm.PC += 0x2; - } - break; - case 0xA: // LD I, addr - vm.I = in&0xFFF; - break; - case 0xB: // JP V0, addr - vm.PC = ((in&0xFFF) + vm.Vx[0x0]) - 0x2; - break; - case 0xC: // RND Vx, byte - vm.Vx[in>>8&0xF] = (rand() % 255) & in&0xFF; - break; - case 0xD: // DRW Vx, Vy, nibble - vm.Vx[0xF] = 0; - for (int i = 0; i < (in&0xF); i++) { - for (int s = 0; s < 8; s++) { - u8 pix = (vm.rom[vm.I + i] & (0x80 >> s)) != 0; - - if (pix) { - u8 y = (i + vm.Vx[in>>4&0xF])&0x1F; - u8 x = ((vm.Vx[in>>8&0xF] + 7) - s)&0x3F; + switch ((in>>12&0xF)) { + case 0x0: + switch (in&0xFF) { + case 0xE0: // CLS + memset(&vm.screen, 0, sizeof(vm.screen)); + break; + case 0xEE: // RET + vm.PC = vm.stack[vm.SP--]; + break; + } + break; + case 0x1: // JP addr + vm.PC = (in&0xFFF) - 0x2; + break; + case 0x2: // CALL addr + vm.stack[++vm.SP] = vm.PC; + vm.PC = (in&0xFFF) - 0x2; + break; + case 0x3: // SE Vx, byte + if (vm.Vx[in>>8&0xF] == (in&0xFF)) { + vm.PC += 0x2; + } + break; + case 0x4: // SNE Vx, byte + if (vm.Vx[in>>8&0xF] != (in&0xFF)) { + vm.PC += 0x2; + } + break; + case 0x5: // SE Vx, Vy + if (vm.Vx[in>>8&0xF] == vm.Vx[in>>4&0xF]) { + vm.PC += 0x2; + } + break; + case 0x6: // LD Vx, byte + vm.Vx[in>>8&0xF] = in&0xFF; + break; + case 0x7: // ADD Vx, byte + vm.Vx[in>>8&0xF] += in&0xFF; + break; + case 0x8: + switch(in&0xF) { + case 0x0: // LD Vx, Vy + vm.Vx[in>>8&0xF] = vm.Vx[in>>4&0xF]; + break; + case 0x1: // OR Vx, Vy + vm.Vx[in>>8&0xF] |= vm.Vx[in>>4&0xF]; + break; + case 0x2: // AND Vx, Vy + vm.Vx[in>>8&0xF] &= vm.Vx[in>>4&0xF]; + break; + case 0x3: // XOR Vx, Vy + vm.Vx[in>>8&0xF] ^= vm.Vx[in>>4&0xF]; + break; + case 0x4: // ADD Vx, Vy + if ((vm.Vx[in>>8&0xF] + vm.Vx[in>>4&0xF]) > 0xFF) { + vm.Vx[0xF] = 1; + } else { + vm.Vx[0xF] = 0; + } + vm.Vx[in>>8&0xF] = (vm.Vx[in>>8&0xF] + vm.Vx[in>>4&0xF])&0xFF; + break; + case 0x5: // SUB Vx, Vy + if (vm.Vx[in>>8&0xF] > vm.Vx[in>>4&0xF]) { + vm.Vx[0xF] = 1; + } else { + vm.Vx[0xF] = 0; + } + vm.Vx[in>>8&0xF] -= vm.Vx[in>>4&0xF]; + break; + case 0x6: // SHR Vx {, Vy} + vm.Vx[0xF] = (vm.Vx[in>>8&0xF] & 1); + // TODO: toggle for Vx /= 2 + vm.Vx[in>>8&0xF] = vm.Vx[in>>8&0xF]>>1; + break; + case 0x7: // SUBN Vx, Vy + if (vm.Vx[in>>8&0xF] < vm.Vx[in>>4&0xF]) { + vm.Vx[0xF] = 1; + } else { + vm.Vx[0xF] = 0; + } + vm.Vx[in>>8&0xF] = vm.Vx[in>>4&0xF] - vm.Vx[in>>8&0xF]; + break; + case 0xE: // SHL Vx {, Vy} + vm.Vx[0xF] = ((vm.Vx[in>>8&0xF]>>7) & 1); + // TODO: toggle for Vx *= 2; + vm.Vx[in>>8&0xF] = vm.Vx[in>>8&0xF]<<1; + break; + } + break; + case 0x9: // SNE Vx, Vy + if (vm.Vx[(in>>8&0xF)] != vm.Vx[(in>>4&0xF)]) { + vm.PC += 0x2; + } + break; + case 0xA: // LD I, addr + vm.I = in&0xFFF; + break; + case 0xB: // JP V0, addr + vm.PC = ((in&0xFFF) + vm.Vx[0x0]) - 0x2; + break; + case 0xC: // RND Vx, byte + vm.Vx[in>>8&0xF] = (rand() % 255) & in&0xFF; + break; + case 0xD: // DRW Vx, Vy, nibble + vm.Vx[0xF] = 0; + for (int i = 0; i < (in&0xF); i++) { + for (int s = 0; s < 8; s++) { + int pix = (vm.rom[vm.I + i] & (0x80 >> s)) != 0; - //while (x > 0x3F) { x -= 0x3F; } - //while (y > 0x1F) { y -= 0x1F; } - - u8 byte = y * 64 + x; - u8 bit = 1 << (byte * 0x07); + if (pix) { + int y = (vm.Vx[in>>4&0xF] + i)&0x1F; + int x = (vm.Vx[in>>8&0xF] + s)&0x3F; - if (vm.screen[byte>>3] & bit) { - vm.Vx[0xF] = 1; - } + //while (x > 0x3F) { x -= 0x3F; } + //while (y > 0x1F) { y -= 0x1F; } + + int byte = y * 64 + x; + int bit = 1 << (byte & 0x07); - vm.screen[byte>>3] ^= bit; + if (vm.screen[byte>>3] & bit) { + vm.Vx[0xF] = 1; } + + vm.screen[byte>>3] ^= bit; } } - break; - case 0xE: switch (in&0xFF) { - case 0x9E: // SKP Vx - if (vm.keyboard[vm.Vx[in>>8&0xF]]) { - vm.PC += 0x2; - } - break; - case 0xA1: // SKNP Vx - if (!vm.keyboard[vm.Vx[in>>8&0xF]]) { - vm.PC += 0x2; - } - break; - } - break; - case 0xF: - switch (in&0xFF) { - case 0x07: // LD Vx, DT - vm.Vx[in>>8&0xF] = vm.DT; - break; - case 0x0A: // LD Vx, K - //vm.Vx[in>>8&0xF] = 0xA;//ui_get_key(true); - break; - case 0x15: // LD DT, Vx - vm.DT = vm.Vx[in>>8&0xF]; - break; - case 0x18: // LD ST, Vx - vm.ST = vm.Vx[in>>8&0xF]; - break; - case 0x1E: // ADD I, Vx - vm.I += vm.Vx[in>>8&0xF]; - break; - case 0x29: // LD F, Vx - // characters - break; - case 0x33: // LD B, Vx - vm.rom[vm.I] = (vm.Vx[in>>8&0xF] / 100); - vm.rom[vm.I+0x1] = ((vm.Vx[in>>8&0xF] % 100)/10); - vm.rom[vm.I+0x2] = (vm.Vx[in>>8&0xF] % 10); - break; - case 0x55: // LD [I], Vx - for (int i = 0; i <= (in>>8&0xF); i++) { - vm.rom[(vm.I) + i] = vm.Vx[i]; - } - break; - case 0x65: // LD Vx, [I] - for (int i = 0; i <= (in>>8&0xF); i++) { - vm.Vx[i] = vm.rom[(vm.I) + i]; - } - break; - } - break; - } - - while (vm.DT > 0) { - vm.DT--; - usleep(1000000/60); - } - - // TODO: play sound - while(vm.ST > 0) { - vm.ST--; - usleep(1000000/60); - } - - vm.PC += 0x2; + } + break; + case 0xE: switch (in&0xFF) { + case 0x9E: // SKP Vx + if (vm.keyboard[vm.Vx[in>>8&0xF]]) { + vm.PC += 0x2; + } + break; + case 0xA1: // SKNP Vx + if (!vm.keyboard[vm.Vx[in>>8&0xF]]) { + vm.PC += 0x2; + } + break; + } + break; + case 0xF: + switch (in&0xFF) { + case 0x07: // LD Vx, DT + vm.Vx[in>>8&0xF] = vm.DT; + break; + case 0x0A: // LD Vx, K + //vm.Vx[in>>8&0xF] = 0xA;//ui_get_key(true); + break; + case 0x15: // LD DT, Vx + vm.DT = vm.Vx[in>>8&0xF]; + break; + case 0x18: // LD ST, Vx + vm.ST = vm.Vx[in>>8&0xF]; + break; + case 0x1E: // ADD I, Vx + vm.I += vm.Vx[in>>8&0xF]; + break; + case 0x29: // LD F, Vx + // characters + break; + case 0x33: // LD B, Vx + vm.rom[vm.I] = (vm.Vx[in>>8&0xF] / 100); + vm.rom[vm.I+0x1] = ((vm.Vx[in>>8&0xF] % 100)/10); + vm.rom[vm.I+0x2] = (vm.Vx[in>>8&0xF] % 10); + break; + case 0x55: // LD [I], Vx + for (int i = 0; i <= (in>>8&0xF); i++) { + vm.rom[(vm.I) + i] = vm.Vx[i]; + } + break; + case 0x65: // LD Vx, [I] + for (int i = 0; i <= (in>>8&0xF); i++) { + vm.Vx[i] = vm.rom[(vm.I) + i]; + } + break; + } + break; } + + vm.PC += 0x2; } int main(void) { @@ -271,7 +256,7 @@ int main(void) { #ifdef _WIN32 HANDLE vm = CreateThread(NULL, 0, vm_thread, NULL, 0, NULL); #else - pthread_t vm; pthread_create(&vm, NULL, (void*)vm_thread, (void*)0); + //pthread_t vm; pthread_create(&vm, NULL, (void*)vm_thread, (void*)0); #endif init_curses(); diff --git a/chip8.h b/chip8.h index e7a1196..400d9cd 100644 --- a/chip8.h +++ b/chip8.h @@ -2,6 +2,8 @@ #include "util.h" +void vm_step(); + typedef struct { u8* rom; diff --git a/ui.c b/ui.c index 620cf8d..b7c6924 100644 --- a/ui.c +++ b/ui.c @@ -17,11 +17,14 @@ void init_curses() { } void draw() { - for (int i = 0; i < (0x3F * 0x1F); i++) { - if (vm.screen[i]) { - - // TODO: fix this lmao - mvaddstr(i / 0x1F, (i % 0x3F) * 2, "[]"); + erase(); + for (int x = 0; x < 0x3F; x++) { + for (int y = 0; y < 0x1F; y++) { + int byte = y * 64 + x; + int bit = byte & 0x07; + if ((vm.screen[byte>>3] & (1 << bit)) != 0) { + mvaddstr(y, x * 2, "[]"); + } } } @@ -78,11 +81,22 @@ void curses_thread(void* v) { u8 c; while(1) { draw(); + vm_step(); + + if (vm.DT > 0) { + vm.DT--; + usleep(1000000/60); + } + + if (vm.ST > 0) { + vm.ST--; + usleep(1000000/60); + } + c = getch(); //if ((c = ui_get_key(false)) <= 0xF) { // vm.keyboard[c] = 1; //} - usleep(10); } } -- cgit v1.2.3-101-g0448