summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2019-09-28 21:00:02 -0400
committerAndrew Opalach <andrew@akon.city> 2019-09-28 21:00:02 -0400
commit398ee4538c2ae4a818f2de7a61aeaa7e8e5f7f13 (patch)
tree93f39f32e28d9615cd540636a63d8ae2f812b6b7
parentd20068025b93350b7a1f6443542103c1a3569afe (diff)
downloadchip8-398ee4538c2ae4a818f2de7a61aeaa7e8e5f7f13.tar.gz
chip8-398ee4538c2ae4a818f2de7a61aeaa7e8e5f7f13.tar.bz2
chip8-398ee4538c2ae4a818f2de7a61aeaa7e8e5f7f13.zip
windows support and start fonts
-rw-r--r--chip8.c60
-rw-r--r--ui.c103
-rw-r--r--ui_sdl.c15
-rw-r--r--util.h1
4 files changed, 57 insertions, 122 deletions
diff --git a/chip8.c b/chip8.c
index 90c6823..6b7040d 100644
--- a/chip8.c
+++ b/chip8.c
@@ -2,6 +2,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h>
#include <math.h>
#include <time.h>
@@ -15,30 +16,55 @@
#include "util.h"
#include "chip8.h"
-#define ROM_FILE "roms/tetris.ch8"
-
chip8_vm vm;
+static u8 font[] = {
+ 0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
+ 0x20, 0x60, 0x20, 0x20, 0x70, // 1
+ 0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
+ 0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
+ 0x90, 0x90, 0xF0, 0x10, 0x10, // 4
+ 0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
+ 0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
+ 0xF0, 0x10, 0x20, 0x40, 0x40, // 7
+ 0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
+ 0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
+ 0xF0, 0x90, 0xF0, 0x90, 0x90, // A
+ 0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
+ 0xF0, 0x80, 0x80, 0x80, 0xF0, // C
+ 0xE0, 0x80, 0x80, 0x80, 0xE0, // D
+ 0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
+ 0xF0, 0x80, 0xF0, 0x80, 0x80 // F
+};
+
void init_vm() {
vm.PC = 0x200; // start of chip8 programs
}
-void load_rom() {
+void load_rom(char *file_path) {
memset(&vm, 0, sizeof(chip8_vm));
- FILE* f = fopen(ROM_FILE, "r");
+ int fd = open(file_path, O_RDONLY);
+ FILE* f = fdopen(fd, "r");
fseek(f, 0, SEEK_END);
- long fsize = ftell(f);
- fseek(f, 0, SEEK_SET);
+ off_t fsize = ftell(f);
+ rewind(f);
vm.rom = (u8*)malloc(0xFFF);
memset(vm.rom, 0, 0xFFF);
- if (fread(&vm.rom[0x200], 1, fsize, f) != fsize) {
+
+#ifdef _WIN32
+ size_t res = read(fd, &vm.rom[0x200], fsize);
+#else
+ size_t res = fread(&vm.rom[0x200], 1, fsize, f);
+#endif
+
+ if (res != fsize) {
printf("err: failed to read rom fully\n");
exit(1);
}
- fclose(f);
+ fclose(f); close(fd);
}
void vm_step() {
@@ -165,16 +191,16 @@ void vm_step() {
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;
+ for (u32 i = 0; i < (in&0xF); i++) {
+ for (u32 s = 0; s < 8; s++) {
+ u8 pix = (vm.rom[vm.I + i] & (0x80 >> s)) != 0;
if (pix) {
- int y = (vm.Vx[in>>4&0xF] + i)&0x1F;
- int x = (vm.Vx[in>>8&0xF] + s)&0x3F;
+ u8 y = (vm.Vx[in>>4&0xF] + i)&0x1F;
+ u8 x = (vm.Vx[in>>8&0xF] + s)&0x3F;
- int byte = y * 64 + x;
- int bit = 1 << (byte & 0x07);
+ u32 byte = y * 64 + x;
+ u32 bit = 1 << (byte & 0x07);
if (vm.screen[byte>>3] & bit) {
vm.Vx[0xF] = 1;
@@ -224,12 +250,12 @@ void vm_step() {
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++) {
+ for (u8 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++) {
+ for (u8 i = 0; i <= (in>>8&0xF); i++) {
vm.Vx[i] = vm.rom[(vm.I) + i];
}
break;
diff --git a/ui.c b/ui.c
deleted file mode 100644
index b7c6924..0000000
--- a/ui.c
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <ncurses.h>
-#include <string.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "chip8.h"
-#include "util.h"
-
-void init_curses() {
- initscr();
- curs_set(0);
- noecho();
- nodelay(stdscr, 1);
- clear();
-}
-
-void draw() {
- 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, "[]");
- }
- }
- }
-
- char buf[25];
- for (int i = 0; i < 7; i++) {
- sprintf(buf, "V%x: 0x%x", i, vm.Vx[i]);
- mvaddstr(35, 9 * i, buf);
- }
- for (int i = 7; i < 15; i++) {
- sprintf(buf, "V%x: 0x%x", i, vm.Vx[i]);
- mvaddstr(36, 9 * (i - 8), buf);
- }
-
- sprintf(buf, "Vf: 0x%x", vm.Vx[15]);
- mvaddstr(37, 0, buf);
- sprintf(buf, "SP: 0x%x", vm.SP);
- mvaddstr(37, 9, buf);
- sprintf(buf, "DT: 0x%x", vm.DT);
- mvaddstr(37, 18, buf);
- sprintf(buf, "ST: 0x%x", vm.ST);
- mvaddstr(37, 27, buf);
- sprintf(buf, "PC: 0x%x", vm.PC);
- mvaddstr(37, 36, buf);
- sprintf(buf, "I: 0x%x", vm.I);
- mvaddstr(37, 46, buf);
-}
-
-u8 ui_get_key(bool block) {
- do {
- char c = getch();
- switch (c) {
- case '1': return 0x0;
- case '2': return 0x1;
- case '3': return 0x2;
- case '4': return 0x3;
- case 'q': return 0x4;
- case 'w': return 0x5;
- case 'e': return 0x6;
- case 'r': return 0x7;
- case 'a': return 0x8;
- case 's': return 0x9;
- case 'd': return 0xA;
- case 'f': return 0xB;
- case 'z': return 0xC;
- case 'x': return 0xD;
- case 'c': return 0xE;
- case 'v': return 0xF;
- }
- } while (block);
- return 0x10;
-}
-
-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;
- //}
- }
-}
-
-
diff --git a/ui_sdl.c b/ui_sdl.c
index 5d14fd3..ccadcbf 100644
--- a/ui_sdl.c
+++ b/ui_sdl.c
@@ -1,7 +1,12 @@
#define SDL_MAIN_HANDLED
#include <time.h>
+
+#ifdef _WIN32
+#include <SDL.h>
+#else
#include <SDL2/SDL.h>
+#endif
#include "chip8.h"
@@ -38,10 +43,16 @@ void draw() {
}
int main(int argc, char* argv[]) {
+ if (argc != 2) {
+ printf("%s [rom file]\n", argv[0]);
+ return 1;
+ }
+
srand(time(NULL));
- setup();
- load_rom();
+
+ load_rom(argv[1]);
init_vm();
+ setup();
int last_500hz = SDL_GetTicks();
int last_60hz = SDL_GetTicks();
diff --git a/util.h b/util.h
index 24bc5f1..405ebde 100644
--- a/util.h
+++ b/util.h
@@ -2,5 +2,6 @@
#define u8 uint8_t
#define u16 uint16_t
+#define u32 uint32_t
#define s8 int8_t
#define s16 int16_t