summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xMakefile38
-rw-r--r--chip8.c219
-rw-r--r--ui.c6
-rw-r--r--util.c14
-rw-r--r--util.h3
5 files changed, 145 insertions, 135 deletions
diff --git a/Makefile b/Makefile
index d1cb938..3f86ee2 100755
--- a/Makefile
+++ b/Makefile
@@ -1,19 +1,19 @@
-all: CC=gcc
-win: CC=x86_64-w64-mingw32-gcc
-
-CFLAGS = -O3 -Wall -std=c99 $(shell pkg-config --cflags ncursesw)
-
-all: BIN = chip8
-win: BIN = chip8.exe
-
-all: executable
-win: executable
-
-all: LDFLAGS = -lncursesw -ltinfow -lpthread
-win: LDFLAGS = ./win/pdcurses.a -lpthread
-
-executable: chip8.c ui.c util.c
- $(CC) $(CFLAGS) -o $(BIN) chip8.c ui.c util.c $(LDFLAGS)
-
-clean:
- $(RM) chip8
+all: CC=gcc
+win: CC=x86_64-w64-mingw32-gcc
+
+CFLAGS = -O3 -Wall -std=c99 $(shell pkg-config --cflags ncursesw)
+
+all: BIN = chip8
+win: BIN = chip8.exe
+
+all: executable
+win: executable
+
+all: LDFLAGS = -lncursesw -ltinfow -lpthread
+win: LDFLAGS = ./win/pdcurses.a -lpthread
+
+executable: chip8.c ui.c
+ $(CC) $(CFLAGS) -o $(BIN) chip8.c ui.c $(LDFLAGS)
+
+clean:
+ $(RM) chip8
diff --git a/chip8.c b/chip8.c
index b66d331..f5bed01 100644
--- a/chip8.c
+++ b/chip8.c
@@ -60,134 +60,146 @@ void push_top_of_stack(u16 val) {
void vm_thread(void* v) {
// read 2 bytes and convert to big-endian
- u16 instr = htons(vm.rom[(vm.PC) - 0x1FF]<<8 | vm.rom[(vm.PC) - 0x200]);
-
- char str[5];
- sprintf(str, "%x", instr);
+ u16 in = htons(vm.rom[(vm.PC) - 0x1FF]<<8 | vm.rom[(vm.PC) - 0x200]);
u8 buf[255];
- if (instr == 0xE0) {
+ if (in == 0xE0) {
memset(&vm.screen, 0, sizeof(vm.screen));
}
- switch (*str) {
- case '0':
- if (instr == 0x00E0) {
+ // 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:
+ if (in == 0x00E0) { // CLS
memset(&vm.screen, 0, sizeof(vm.screen));
- } else if (instr == 0x00EE) {
+ } else if (in == 0x00EE) { // RET
vm.PC = vm.stack[vm.SP--];
}
break;
- case '1':
- vm.PC = hex_str(str+1);
+ case 0x1: // JP addr
+ vm.PC = in&0xFFF;
break;
- case '2':
+ case 0x2: // CALL addr
vm.SP++;
push_top_of_stack(vm.PC);
- vm.PC = hex_str(str+1);
+ vm.PC = in&0xFFF;
break;
- case '3':
- if (vm.Vx[hex_char(str[1])] == hex_str(str+2)) {
+ case 0x3: // SE Vx, byte
+ if (vm.Vx[in>>8&0xF] == (in&0xFF)) {
vm.PC += 0x2;
}
break;
- case '4':
- if (vm.Vx[hex_char(str[1])] != hex_str(str+2)) {
+ case 0x4: // SNE Vx, byte
+ if (vm.Vx[in>>8&0xF] != (in&0xFF)) {
vm.PC += 0x2;
}
break;
- case '5':
- if (vm.Vx[hex_char(str[1])] == vm.Vx[hex_char(str[2])]) {
+ case 0x5: // SE Vx, Vy
+ if (vm.Vx[in>>8&0xF] == vm.Vx[in>>4&0xF]) {
vm.PC += 0x2;
}
break;
- case '6':
- vm.Vx[hex_char(str[1])] = hex_str(str+2);
+ case 0x6: // LD Vx, byte
+ vm.Vx[in>>8&0xF] = in&0xFF;
break;
- case '7':
- vm.Vx[hex_char(str[1])] += hex_str(str+2);
+ case 0x7: // ADD Vx, byte
+ vm.Vx[in>>8&0xF] += in&0xFF;
break;
- case '8':
- switch(str[3]) {
- case '0':
- vm.Vx[hex_char(str[1])] = vm.Vx[hex_char(str[2])];
+ case 0x8:
+ switch(in&0xF) {
+ case 0x0: // LD Vx, Vy
+ vm.Vx[in>>8&0xF] = vm.Vx[in>>4&0xF];
break;
- case '1':
- vm.Vx[hex_char(str[1])] |= vm.Vx[hex_char(str[2])];
+ case 0x1: // OR Vx, Vy
+ vm.Vx[in>>8&0xF] |= vm.Vx[in>>4&0xF];
break;
- case '2':
- vm.Vx[hex_char(str[1])] &= vm.Vx[hex_char(str[2])];
+ case 0x2: // AND Vx, Vy
+ vm.Vx[in>>8&0xF] &= vm.Vx[in>>4&0xF];
break;
- case '3':
- vm.Vx[hex_char(str[1])] ^= vm.Vx[hex_char(str[2])];
+ case 0x3: // XOR Vx, Vy
+ vm.Vx[in>>8&0xF] ^= vm.Vx[in>>4&0xF];
break;
- case '4':
- vm.Vx[hex_char(str[1])] += vm.Vx[hex_char(str[2])];
- if (vm.Vx[hex_char(str[1])] + vm.Vx[hex_char(str[2])] > 255) {
+ case 0x4: // ADD Vx, Vy
+ vm.Vx[in>>8&0xF] += vm.Vx[in>>4&0xF];
+ if (vm.Vx[in>>8&0xF] + vm.Vx[in>>4&0xF] > 255) {
vm.Vx[15] = 1;
- vm.Vx[hex_char(str[1])] &= 0x255;
+ vm.Vx[in>>8&0xF] &= 0xFF;
} else {
vm.Vx[15] = 0;
}
break;
- case '5':
- if (vm.Vx[hex_char(str[1])] > vm.Vx[hex_char(str[2])]) {
+ case 0x5: // SUB Vx, Vy
+ if (vm.Vx[in>>8&0xF] > vm.Vx[in>>4&0xF]) {
vm.Vx[15] = 1;
} else {
vm.Vx[15] = 0;
}
- vm.Vx[hex_char(str[1])] -= vm.Vx[hex_char(str[2])];
+ vm.Vx[in>>8&0xF] -= vm.Vx[in>>4&0xF];
break;
- case '6':
- if ((vm.Vx[hex_char(str[1])] & 1) == 1) {
+ case 0x6: // SHR Vx {, Vy}
+ if ((vm.Vx[in>>8&0xF] & 1) == 1) {
vm.Vx[15] = 1;
} else {
vm.Vx[15] = 0;
}
- vm.Vx[hex_char(str[1])] /= 2;
+ vm.Vx[in>>8&0xF] /= 2;
break;
- case '7':
- if (vm.Vx[hex_char(str[1])] < vm.Vx[hex_char(str[2])]) {
+ case 0x7: // SUBN Vx, Vy
+ if (vm.Vx[in>>8&0xF] < vm.Vx[in>>4&0xF]) {
vm.Vx[15] = 1;
} else {
vm.Vx[15] = 0;
}
- vm.Vx[hex_char(str[1])] = vm.Vx[hex_char(str[2])] - vm.Vx[hex_char(str[1])];
+ vm.Vx[in>>8&0xF] = vm.Vx[in>>4&0xF] - vm.Vx[in>>8&0xF];
break;
- case 'e':
- if ((vm.Vx[hex_char(str[1])] & 1) == 1) {
+ case 0xE: // SHL Vx {, Vy}
+ if ((vm.Vx[in>>8&0xF] & 1) == 1) {
vm.Vx[15] = 1;
} else {
vm.Vx[15] = 0;
}
- vm.Vx[hex_char(str[1])] *= 2;
+ vm.Vx[in>>8&0xF] *= 2;
break;
}
break;
- case '9':
- if (vm.Vx[hex_char(str[1])] != vm.Vx[hex_char(str[2])]) {
+ case 0x9: // SNE Vx, Vy
+ if (vm.Vx[(in>>8&0xF)] != vm.Vx[(in>>4&0xF)]) {
vm.PC += 0x2;
}
break;
- case 'a':
- vm.I = hex_str(str+1);
+ case 0xA: // LD I, addr
+ vm.I = in&0xFFF;
break;
- case 'b':
- vm.PC = hex_str(str+1) + vm.Vx[0];
+ case 0xB: // JP V0, addr
+ vm.PC = (in&0xFFF) + vm.Vx[0];
break;
- case 'c':
- vm.Vx[hex_char(str[1])] = (rand() % 255) & hex_str(str+2);
+ case 0xC: // RND Vx, byte
+ vm.Vx[in>>8&0xF] = (rand() % 255) & in&0xFF;
break;
- case 'd':
- memcpy(buf, &vm.rom[vm.I - 0x200], hex_char(str[3]));
- for (int i = 0; i < hex_char(str[3]); i++) {
+ case 0xD: // DRW Vx, Vy, nibble
+ memcpy(buf, &vm.rom[vm.I - 0x200], in&0xF);
+ for (int i = 0; i < (in&0xF); i++) {
for (int s = 0; s < 8; s++) {
u8 bit = (buf[i]>>s)&1;
if (bit) {
- u8 x = (vm.Vx[hex_char(str[1])] + 7) - s;
- u8 y = i + vm.Vx[hex_char(str[2])];
+ u8 x = (vm.Vx[in>>8&0xF] + 7) - s;
+ u8 y = i + vm.Vx[in>>4&0xF];
while (x > 63) { x -= 63; }
while (y > 31) { y -= 31; }
@@ -201,45 +213,56 @@ void vm_thread(void* v) {
}
}
break;
- case 'e':
- if (hex_str(str+2) == 0x9E) {
- if (vm.keyboard[vm.Vx[hex_char(str[1])]]) {
- vm.PC += 0x2;
- }
- } else if (hex_str(str+2) == 0xA1) {
- if (!vm.keyboard[vm.Vx[hex_char(str[1])]]) {
- vm.PC += 0x2;
- }
+ case 0xE:
+ switch (in&0xFF) {
+ case 0x9E:
+ if (vm.keyboard[vm.Vx[in>>8&0xF]]) {
+ vm.PC += 0x2;
+ }
+ break;
+ case 0xA1:
+ if (!vm.keyboard[vm.Vx[in>>8&0xF]]) {
+ vm.PC += 0x2;
+ }
+ break;
}
break;
- case 'f':
- if (hex_str(str+2) == 0x07) {
- vm.Vx[hex_char(str[1])] = vm.DT;
- } else if (hex_str(str+2) == 0x0A) {
- vm.Vx[hex_char(str[1])] = ui_get_key(true);
- } else if (hex_str(str+2) == 0x15) {
- vm.DT = vm.Vx[hex_char(str[1])];
- } else if (hex_str(str+2) == 0x18) {
- vm.ST = vm.Vx[hex_char(str[1])];
- } else if (hex_str(str+2) == 0x1E) {
- vm.I += vm.Vx[hex_char(str[1])];
- } else if (hex_str(str+2) == 0x29) {
- // characters
- } else if (hex_str(str+2) == 0x33) {
- u8 tmp = vm.Vx[hex_char(str[1])];
- vm.rom[vm.I - 0x200] = floor(tmp / 100);
- vm.rom[(vm.I - 0x200)+1] = floor((tmp % 100)/10);
- vm.rom[(vm.I - 0x200)+2] = floor(tmp % 10);
- } else if (hex_str(str+2) == 0x55) {
- for (int i = 0; i < hex_char(str[1]); i++) {
- vm.rom[(vm.I - 0x200) - i] = vm.Vx[i];
- }
- } else if (hex_str(str+2) == 0x65) {
- for (int i = 0; i < hex_char(str[1]); i++) {
- vm.Vx[i] = vm.rom[(vm.I - 0x200) - i];
- }
+ case 0xF:
+ switch (in&0xFF) {
+ case 0x07:
+ vm.Vx[in>>8&0xF] = vm.DT;
+ break;
+ case 0x0A:
+ vm.Vx[in>>8&0xF] = ui_get_key(true);
+ break;
+ case 0x15:
+ vm.DT = vm.Vx[in>>8&0xF];
+ break;
+ case 0x18:
+ vm.ST = vm.Vx[in>>8&0xF];
+ break;
+ case 0x1E:
+ vm.I += vm.Vx[in>>8&0xF];
+ break;
+ case 0x29:
+ // characters
+ break;
+ case 0x33:
+ vm.rom[vm.I - 0x200] = floor(vm.Vx[in>>8&0xF] / 100);
+ vm.rom[(vm.I - 0x200)+1] = floor((vm.Vx[in>>8&0xF] % 100)/10);
+ vm.rom[(vm.I - 0x200)+2] = floor(vm.Vx[in>>8&0xF] % 10);
+ break;
+ case 0x55:
+ for (int i = 0; i < (in>>8&0xF); i++) {
+ vm.rom[(vm.I - 0x200) - i] = vm.Vx[i];
+ }
+ break;
+ case 0x65:
+ for (int i = 0; i < (in>>8&0xF); i++) {
+ vm.Vx[i] = vm.rom[(vm.I - 0x200) - i];
+ }
+ break;
}
- break;
}
vm.PC += 0x2;
diff --git a/ui.c b/ui.c
index b8039ad..3fa1a1c 100644
--- a/ui.c
+++ b/ui.c
@@ -70,13 +70,17 @@ u8 ui_get_key(bool block) {
case 'v': return 0xF;
}
} while (block);
+ return 0x10;
}
void curses_thread(void* v) {
+ u8 c;
while(1) {
erase();
draw();
- vm.keyboard[ui_get_key(false)] = 1;
+ if ((c = ui_get_key(false)) <= 0xF) {
+ vm.keyboard[c] = 1;
+ }
usleep(100);
}
}
diff --git a/util.c b/util.c
deleted file mode 100644
index a8c2f94..0000000
--- a/util.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "util.h"
-
-u16 hex_str(char* str) {
- return (u16)strtol(str, NULL, 16);
-}
-
-u16 hex_char(char c) {
- char buf[2];
- sprintf(buf, "%c", c);
- return (u16)strtol(buf, NULL, 16);
-}
diff --git a/util.h b/util.h
index 17760b6..24bc5f1 100644
--- a/util.h
+++ b/util.h
@@ -4,6 +4,3 @@
#define u16 uint16_t
#define s8 int8_t
#define s16 int16_t
-
-u16 hex_char(char c);
-u16 hex_str(char* str);