]> git.ayabusa.dev Git - chipy-8.git/commitdiff
added rom loading, reg and mem structure, and did the instruction decoder
authorayabusa <lebgpub@gmail.com>
Wed, 24 Dec 2025 17:40:09 +0000 (18:40 +0100)
committerayabusa <lebgpub@gmail.com>
Wed, 24 Dec 2025 17:40:09 +0000 (18:40 +0100)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
game.ch8 [new file with mode: 0644]
src/font.h [new file with mode: 0644]
src/main.c [new file with mode: 0644]
src/processor.c [new file with mode: 0644]
src/processor.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..28c2520
--- /dev/null
@@ -0,0 +1,2 @@
+build/*
+*.swp
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..f3947a6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,16 @@
+flags = -g -Wall -Wextra -fsanitize=address
+src = src/*.c
+inc = src/
+out = build/chipy8
+rom = game.ch8
+
+all: clean comp run
+
+clean:
+       rm -f $(out)
+
+comp:
+       $(CC) $(src) -I $(inc) -o $(out) $(flags)
+
+run:
+       ./$(out) $(rom)
diff --git a/game.ch8 b/game.ch8
new file mode 100644 (file)
index 0000000..d5a865f
Binary files /dev/null and b/game.ch8 differ
diff --git a/src/font.h b/src/font.h
new file mode 100644 (file)
index 0000000..015a2d2
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef FONT_H
+#define FONT_H
+
+const uint8_t font[80] = {
+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, 0x90, 0x90, 0x90, 0xE0, // D
+0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
+0xF0, 0x80, 0xF0, 0x80, 0x80  // F
+};
+
+#endif
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..d265ec5
--- /dev/null
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "font.h"
+#include "processor.h"
+
+int init(ch8_ctx * context, char * rom_name){
+       FILE * rom_file = fopen(rom_name, "r");
+       if (rom_file == NULL){
+               printf("Could not open the file <%s>\n", rom_name);
+               fclose(rom_file);
+               return 1;
+       }
+       context->RAM = calloc(0x1000, 1);
+       if (context->RAM == NULL){
+               printf("Could not allocate enough space (4KB)\n");
+               fclose(rom_file);
+               return 1;
+       }
+       // The font is located at address 0, so that program can access it
+       memcpy(context->RAM, font, 80);
+
+       // Next we load the rom at address 0x200
+       fread((context->RAM + 0x200), 1, 0xDFF, rom_file);
+
+       fclose(rom_file);
+       return 0;
+}
+
+
+int main(int argc, char * argv[]){
+       if (argc!=2){
+               printf("Usage: ./chipy8 <path of the rom>\n");
+               return 1;
+       }
+       printf("Welcome to the Chipy 8 emulator!\n");
+
+       ch8_ctx context = {NULL, {0}, 0, 0, 0, 0x200, 0, {0}}; 
+       if(init(&context, argv[1])){ // If error in init
+               free(context.RAM);
+               return 1;
+       }       
+       int running = 1;
+       while (running){
+               ;
+       }
+       free(context.RAM);
+       return 0;
+}
diff --git a/src/processor.c b/src/processor.c
new file mode 100644 (file)
index 0000000..b625a76
--- /dev/null
@@ -0,0 +1,139 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "processor.h"
+
+void execute_instruction(ch8_ctx * ctx){
+       // The two instruction bytes
+       uint8_t b1=*(ctx->RAM + ctx->PC), b2=*(ctx->RAM + ctx->PC + 1);
+       if(b1==0 && b2 == 0xE0){
+               ins_CLS(ctx);
+               ctx->PC++;
+               return;
+       }if(b1==0 && b2 == 0xEE){
+               ins_RET(ctx);
+               return;
+       }
+       // First nimble (4 bits)
+       uint8_t n1 = (b1&0xF0)>>4;
+       switch (n1){
+               //case 0:
+                       //Sys instr, deprecated
+                       //break;
+               case 1:
+                       ins_JP(ctx);
+                       return;
+               case 2:
+                       ins_CALL(ctx);
+                       return;
+               case 3:
+                       ins_SE(ctx);
+                       break;
+               case 4:
+                       ins_SNE(ctx);
+                       break;
+               case 5:
+                       ins_SEV(ctx);
+                       break;
+               case 6:
+                       ins_LD(ctx);
+                       break;
+               case 7:
+                       ins_ADD(ctx);
+                       break;
+               case 8:
+                       // Last nimble
+                       uint8_t n4=b2&0xF;
+                       switch (n4){
+                               case 0:
+                                       ins_LDV(ctx);
+                                       break;
+                               case 1:
+                                       ins_OR(ctx);
+                                       break;
+                               case 2:
+                                       ins_ANDV(ctx);
+                                       break;
+                               case 3:
+                                       ins_XOR(ctx);
+                                       break;
+                               case 4:
+                                       ins_ADDV(ctx);
+                                       break;
+                               case 5:
+                                       ins_SUB(ctx);
+                                       break;
+                               case 6:
+                                       ins_SHR(ctx);
+                                       break;
+                               case 7:
+                                       ins_SUBN(ctx);
+                                       break;
+                               case 0xE:
+                                       ins_SHL(ctx);
+                                       break;
+                               default:
+                                       printf("Unknown 8xxx instruction b1: %X   b2: %X\n", b1, b2);
+                                       break;
+                       }
+                       break;
+               case 9:
+                       ins_SNEV(ctx);
+                       break;
+               case 0xA:
+                       ins_LDI(ctx);
+                       break;
+               case 0xB:
+                       ins_JPV(ctx);
+                       break;
+               case 0xC:
+                       ins_RND(ctx);
+                       break;
+               case 0xD:
+                       ins_DRW(ctx);
+                       break;
+               case 0xE:
+                       if(b2==0x9E)
+                               ins_SKP(ctx);
+                       else if(b2==0xA1)
+                               ins_SKNP(ctx);
+                       else
+                               printf("Unknown Exxx instruction b1: %X   b2: %X\n", b1, b2);
+                       break;
+               default: // 0xF
+                       switch (b2){
+                               case 7:
+                                       ins_LDVDT(ctx);
+                                       break;
+                               case 0xA:
+                                       ins_LDK(ctx);
+                                       break;
+                               case 0x15:
+                                       ins_LDDTV(ctx);
+                                       break;
+                               case 0x18:
+                                       ins_LDST(ctx);
+                                       break;
+                               case 0x1E:
+                                       ins_ADDI(ctx);
+                                       break;
+                               case 0x29:
+                                       ins_LDF(ctx);
+                                       break;
+                               case 0x33:
+                                       ins_LDB(ctx);
+                                       break;
+                               case 0x55:
+                                       ins_LD_Rng_IV(ctx);
+                                       break;
+                               case 0x65:
+                                       ins_LD_Rng_VI(ctx);
+                                       break;
+                               default:
+                                       printf("Unknown Fxxx instruction b1: %X   b2: %X\n", b1, b2);
+                       }
+                       break;
+       }
+       // Goes to next instruction.
+       // Note: we do not implement the Super Chip 48 instruction set
+       ctx->PC++;
+}
diff --git a/src/processor.h b/src/processor.h
new file mode 100644 (file)
index 0000000..d366a58
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef PROCESSOR_H
+#define PROCESSOR_H
+
+typedef struct{
+// The ram which store the ROM, DATA and some interpreter stuff
+uint8_t * RAM;
+
+// general purpose registers
+uint8_t REGS[16];
+
+// address special reg
+uint16_t I;
+
+// Delay and sound timers
+uint8_t DT;
+uint8_t ST;
+
+// Program counter, not accessible directly by the game
+uint16_t PC;
+
+// Stack and stack pointer
+uint8_t SP;
+uint16_t STACK[16];
+} ch8_ctx;
+
+#endif