diff --git a/Makefile b/Makefile index 78dedea..d6677a2 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ build/screen.o: src/screen.c run: all @$(ECHO) "Runing the Chip8 compiler" - @$(OUT) + @$(OUT) $(rom) clean: @$(ECHO) "Cleaning files..." diff --git a/include/chip8.h b/include/chip8.h index fcad85b..347ca92 100644 --- a/include/chip8.h +++ b/include/chip8.h @@ -1,6 +1,8 @@ #ifndef __CHIP8_H #define __CHIP8_H +#include + #include "config.h" #include "keyboard.h" #include "mem.h" @@ -18,5 +20,7 @@ struct chip8 }; void chip8_init (struct chip8 *chip8); +void chip8_load (struct chip8 *chip8, const char *buf, size_t size); +void chip8_exec (struct chip8 *chip8, unsigned short opcode); #endif diff --git a/include/config.h b/include/config.h index e145a0f..2e47abe 100644 --- a/include/config.h +++ b/include/config.h @@ -5,6 +5,7 @@ #define EMULATOR_WINDOW_MULTIPLIER 10 #define CHIP8_MEMORY_SIZE 4096 +#define CHIP8_PROGRAM_LOAD_ADDRESS 0x200 #define CHIP8_DISPLAY_WIDTH 64 #define CHIP8_DISPLAY_HEIGHT 32 diff --git a/include/mem.h b/include/mem.h index 1475913..6e12bce 100644 --- a/include/mem.h +++ b/include/mem.h @@ -10,5 +10,6 @@ struct chip8_memory void chip8_memory_set (struct chip8_memory *mem, int index, unsigned char val); unsigned char chip8_memory_get (struct chip8_memory *mem, int index); +unsigned short chip8_memory_get_short (struct chip8_memory *mem, int index); #endif diff --git a/roms/horsey_jump.ch8 b/roms/horsey_jump.ch8 new file mode 100644 index 0000000..4dc09e7 Binary files /dev/null and b/roms/horsey_jump.ch8 differ diff --git a/src/chip8.c b/src/chip8.c index 102e932..622d092 100644 --- a/src/chip8.c +++ b/src/chip8.c @@ -1,4 +1,6 @@ #include "chip8.h" + +#include #include const char chip8_default_character_set[] = { @@ -26,3 +28,16 @@ chip8_init (struct chip8 *chip8) memcpy (&chip8->memory.memory, chip8_default_character_set, sizeof (chip8_default_character_set)); } + +void +chip8_load (struct chip8 *chip8, const char *buf, size_t size) +{ + assert (size + CHIP8_PROGRAM_LOAD_ADDRESS < CHIP8_MEMORY_SIZE); + memcpy (&chip8->memory.memory[CHIP8_PROGRAM_LOAD_ADDRESS], buf, size); + chip8->registers.PC = CHIP8_PROGRAM_LOAD_ADDRESS; +} + +void +chip8_exec (struct chip8 *chip8, unsigned short opcode) +{ +} diff --git a/src/main.c b/src/main.c index 01fd477..fd9efe2 100644 --- a/src/main.c +++ b/src/main.c @@ -8,12 +8,39 @@ const char keyboard_map[CHIP8_TOTAL_KEYS] SDLK_8, SDLK_9, SDLK_a, SDLK_b, SDLK_c, SDLK_d, SDLK_e, SDLK_f }; int -main (int argc, char **argv) +main (int argc, const char **argv) { + if (argc < 2) + { + fprintf (stderr, "you must provide a file to load.\n"); + return EXIT_FAILURE; + } + + const char *fname = argv[1]; + printf ("the file to load is: %s\n", fname); + + FILE *f = fopen (fname, "rb"); + if (!f) + { + fprintf (stderr, "failed to open the file.\n"); + return EXIT_FAILURE; + } + + fseek (f, 0, SEEK_END); + long size = ftell (f); + fseek (f, 0, SEEK_SET); + + char buf[size]; + int res = fread (buf, size, 1, f); + if (res != 1) + { + fprintf (stderr, "failed to read from file.\n"); + return EXIT_FAILURE; + } + struct chip8 chip8; chip8_init (&chip8); - chip8_screen_draw_sprite (&chip8.screen, 62, 10, - (const char *)&chip8.memory.memory[0x00], 5); + chip8_load (&chip8, buf, size); SDL_Init (SDL_INIT_EVERYTHING); SDL_Window *window = SDL_CreateWindow ( @@ -23,6 +50,8 @@ main (int argc, char **argv) SDL_Renderer *renderer = SDL_CreateRenderer (window, -1, SDL_TEXTUREACCESS_TARGET); + + chip8.registers.ST = 255; while (1) { SDL_Event event; @@ -85,9 +114,20 @@ main (int argc, char **argv) sleep (100); chip8.registers.DT -= 1; } + + if (chip8.registers.ST > 0) + { + /* TODO: Beep */ + chip8.registers.ST -= 1; + } + + unsigned short opcode + = chip8_memory_get_short (&chip8.memory, chip8.registers.PC); + chip8_exec (&chip8, opcode); + chip8.registers.PC += 2; } out: SDL_DestroyWindow (window); - return 0; + return EXIT_SUCCESS; } diff --git a/src/mem.c b/src/mem.c index 3d4a30d..f22e56b 100644 --- a/src/mem.c +++ b/src/mem.c @@ -21,3 +21,11 @@ chip8_memory_get (struct chip8_memory *mem, int index) chip8_is_mem_in_bounds (index); return mem->memory[index]; } + +unsigned short +chip8_memory_get_short (struct chip8_memory *mem, int index) +{ + unsigned char byte1 = chip8_memory_get (mem, index); + unsigned char byte2 = chip8_memory_get (mem, index + 1); + return byte1 << 8 | byte2; +}