diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | chip8.c | 41 | ||||
-rw-r--r-- | chip8.h | 19 | ||||
-rw-r--r-- | main.c | 31 |
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) @@ -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); +} @@ -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 @@ -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; } |