summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--chip8.c41
-rw-r--r--chip8.h19
-rw-r--r--main.c31
4 files changed, 87 insertions, 6 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fd54795..bda00bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ find_package(SDL2 REQUIRED)
add_executable(
chip8
- main.c)
+ main.c chip8.c chip8.h)
target_compile_options(chip8 PRIVATE -Wall)
diff --git a/chip8.c b/chip8.c
new file mode 100644
index 0000000..3c41117
--- /dev/null
+++ b/chip8.c
@@ -0,0 +1,41 @@
+#include "chip8.h"
+
+uint8_t key[KEY_SIZE]; // hex key input
+uint32_t video[WIDTH*HEIGHT]; // video memory TODO: video should be 8 bit not 32
+uint8_t V[16]; // registers - 0x0 to 0xF
+uint16_t I; // special I register, stores addresses
+uint16_t PC; // program counter
+uint8_t SP; // stack pointer
+uint16_t stack[STACK_SIZE]; // stack, for address storage when using subroutines, maximum of 16 levels of nested subroutines
+uint8_t memory[MEMORY_SIZE]; // 4KB of program memory
+
+int
+load_rom(char *rom)
+{
+ int ret = 1;
+ printf("loading rom %s..\n", rom);
+ FILE *romfile;
+ romfile = fopen(rom, "rb");
+ if (romfile == NULL)
+ {
+ fprintf(stderr, "cannot read rom %s: %s\n", rom, strerror(errno));
+ ret = 0;
+ }
+
+ /* read a maximum of MAX_ROM_SIZE bytes into memory starting after the reserved memory */
+ fread(&memory[0x200], 1, MAX_ROM_SIZE, romfile);
+
+ fclose(romfile);
+ return ret;
+}
+
+void
+chip8_init()
+{
+ /* clear everything */
+ memset(key, 0, 15);
+ memset(video, 0, (WIDTH*HEIGHT) * sizeof(uint32_t));
+ memset(V, 0, 16);
+ memset(stack, 0, (STACK_SIZE) * sizeof(uint16_t));
+ memset(memory, 0, MEMORY_SIZE);
+}
diff --git a/chip8.h b/chip8.h
new file mode 100644
index 0000000..7301c45
--- /dev/null
+++ b/chip8.h
@@ -0,0 +1,19 @@
+#ifndef CHIP8_H
+#define CHIP8_H
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#define WIDTH 64
+#define HEIGHT 32
+#define KEY_SIZE 15
+#define MEMORY_SIZE 4096
+#define STACK_SIZE 16
+#define MAX_ROM_SIZE 0x1000 - 0x200 // memory size - reseved memory
+
+int load_rom();
+void chip8_init();
+
+#endif
diff --git a/main.c b/main.c
index 056e5b1..a3b9539 100644
--- a/main.c
+++ b/main.c
@@ -1,8 +1,8 @@
#include <stdio.h>
+#include <stdlib.h>
#include <SDL2/SDL.h>
-#define WIDTH 64
-#define HEIGHT 32
+#include "chip8.h"
/* references
* https://austinmorlan.com/posts/chip8_emulator/
@@ -21,6 +21,15 @@ void init_video();
void update_video();
void toggle_pixel(int x, int y);
void quit();
+void usage(char *);
+
+extern uint32_t video[WIDTH*HEIGHT];
+
+void
+usage(char *program)
+{
+ printf("usage: %s [romfile]\n", program);
+}
void
quit()
@@ -41,8 +50,6 @@ init_video()
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
}
-uint32_t video[WIDTH*HEIGHT];
-
void
update_video()
{
@@ -79,6 +86,20 @@ toggle_pixel(int x, int y)
int main(int argc, char *argv[])
{
+ if (argc < 2)
+ {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!load_rom(argv[1]))
+ {
+ fprintf(stderr, "cannot start interpreter\n");
+ exit(EXIT_FAILURE);
+ }
+
+ chip8_init();
+
init_video();
const int fps = 60;
@@ -101,5 +122,5 @@ int main(int argc, char *argv[])
}
quit();
- return 0;
+ return EXIT_SUCCESS;
}