]> git.ayabusa.dev Git - chipy-8.git/commitdiff
Added most of the instructions, but it'll need further testing.
authorayabusa <lebgpub@gmail.com>
Fri, 9 Jan 2026 18:00:39 +0000 (19:00 +0100)
committerayabusa <lebgpub@gmail.com>
Fri, 9 Jan 2026 18:00:39 +0000 (19:00 +0100)
src/font.h
src/main.c
src/processor.c
src/processor.h

index 015a2d215a4d49ad7be624d58f3695d7159f3832..7c47f2d2df6c8dd8675c44289cb61aac50cee323 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef FONT_H
 #define FONT_H
 
+#include <stdint.h>
+
 const uint8_t font[80] = {
 0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
 0x20, 0x60, 0x20, 0x20, 0x70, // 1
index d265ec5c592c56d7e194a5e41b7cc6cac3a7cf18..36eff794253be41c8a53bf42433bc49c2cea8744 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
+#include <time.h>
 #include "font.h"
 #include "processor.h"
 
@@ -36,12 +37,13 @@ int main(int argc, char * argv[]){
        }
        printf("Welcome to the Chipy 8 emulator!\n");
 
-       ch8_ctx context = {NULL, {0}, 0, 0, 0, 0x200, 0, {0}}; 
+       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;
+       srand( time( NULL ) );
        while (running){
                ;
        }
index b625a763caf517dc5876e0fe6c0071950f99e174..3a76ab5941179e1f56940123c39a52839ac02f30 100644 (file)
 #include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include "processor.h"
 
+void ins_CLS(ch8_ctx * ctx){
+    //TODO
+}
+
+void ins_DRW(ch8_ctx * ctx, uint8_t x, uint8_t y, uint8_t n){
+    //TODO
+}
+
+void ins_JP(ch8_ctx * ctx, uint16_t nnn){
+    ctx->PC = nnn;
+}
+
+void ins_CALL(ch8_ctx * ctx, uint16_t nnn){
+    ctx->SP++;
+    ctx->STACK[ctx->SP] = ctx->PC;
+    ctx->PC = nnn;
+}
+
+void ins_RET(ch8_ctx * ctx){
+    ctx->PC = ctx->STACK[ctx->SP];
+    ctx->SP--;
+}
+
+void ins_SE_IM(ch8_ctx * ctx, uint8_t x, uint8_t kk){
+    if(ctx->REGS[x] == kk)
+        ctx->PC+=2;
+}
+
+void ins_SNE_IM(ch8_ctx * ctx, uint8_t x, uint8_t kk){
+    if(ctx->REGS[x] != kk)
+        ctx->PC+=2;
+}
+
+void ins_SE(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    if(ctx->REGS[x] == ctx->REGS[y])
+        ctx->PC+=2;
+}
+
+void ins_LD_IM(ch8_ctx * ctx, uint8_t x, uint8_t kk){
+    ctx->REGS[x] = kk;
+}
+
+void ins_ADD_IM(ch8_ctx * ctx, uint8_t x, uint8_t kk){
+    ctx->REGS[x]+=kk;
+}
+
+void ins_LD(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    ctx->REGS[x] = ctx->REGS[y];
+}
+
+void ins_OR(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    ctx->REGS[x] |= ctx->REGS[y];
+}
+
+void ins_AND(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    ctx->REGS[x] &= ctx->REGS[y];
+}
+
+void ins_XOR(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    ctx->REGS[x] ^= ctx->REGS[y];
+}
+
+void ins_ADD(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    ctx->REGS[x] += ctx->REGS[y];
+    uint16_t overflow = ctx->REGS[x] + ctx->REGS[y];
+    ctx->REGS[0xF] = overflow>255;
+}
+
+void ins_SUB(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    ctx->REGS[0xF] = ctx->REGS[x] > ctx->REGS[y];
+    ctx->REGS[x] -= ctx->REGS[y];
+}
+
+void ins_SUBN(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    ctx->REGS[0xF] = ctx->REGS[y] > ctx->REGS[x];
+    ctx->REGS[x] = ctx->REGS[y] - ctx->REGS[x];
+}
+
+void ins_SHR(ch8_ctx * ctx, uint8_t x){
+    ctx->REGS[0xF] = x & 1;
+    ctx->REGS[x] = ctx->REGS[x]>>1;
+}
+
+void ins_SHL(ch8_ctx * ctx, uint8_t x){
+    ctx->REGS[0xF] = x & 0x80;
+    ctx->REGS[x] = ctx->REGS[x]<<1;
+}
+
+void ins_SNE(ch8_ctx * ctx, uint8_t x, uint8_t y){
+    if(ctx->REGS[x] != ctx->REGS[y])
+        ctx->PC += 2;
+}
+
+void ins_LD_I_nnn(ch8_ctx * ctx, uint16_t nnn){
+    ctx->I=nnn;
+}
+
+void ins_JP_V0(ch8_ctx * ctx, uint16_t nnn){
+    ctx->PC = ctx->REGS[0] + nnn;
+}
+
+void ins_RND(ch8_ctx * ctx, uint8_t x, uint8_t kk){
+    ctx->REGS[x] = rand() & kk;
+}
+
+void ins_SKP(ch8_ctx * ctx, uint8_t x){
+    //TODO
+}
+
+void ins_SKNP(ch8_ctx * ctx, uint8_t x){
+    //TODO
+}
+
+void ins_LDK(ch8_ctx * ctx, uint8_t x){
+    //TODO
+}
+
+void ins_LD_V_DT(ch8_ctx * ctx, uint8_t x){
+    ctx->REGS[x] = ctx->DT;
+}
+
+void ins_LD_DT_V(ch8_ctx * ctx, uint8_t x){
+    ctx->DT = ctx->REGS[x];
+}
+
+void ins_LD_ST(ch8_ctx * ctx, uint8_t x){
+    ctx->ST = ctx->REGS[x];
+}
+
+void ins_ADD_I(ch8_ctx * ctx, uint8_t x){
+    ctx->I += ctx->REGS[x];
+}
+
+void ins_LD_F(ch8_ctx * ctx, uint8_t x){
+    ctx->I = ctx->REGS[x] * 5;
+}
+
+void ins_LD_B(ch8_ctx * ctx, uint8_t x){
+    uint8_t nb = ctx->REGS[x];
+    ctx->RAM[ctx->I + 2] = nb%10;
+    nb/=10;
+    ctx->RAM[ctx->I + 1] = nb%10;
+    nb/=10;
+    ctx->RAM[ctx->I] = nb;
+}
+
+void ins_LD_I_V(ch8_ctx * ctx, uint8_t x){
+    for(uint8_t i; i<=x; i++)
+        ctx->RAM[ctx->I + i] = ctx->REGS[i];
+}
+
+void ins_LD_V_I(ch8_ctx * ctx, uint8_t x){
+    for(uint8_t i; i<=x; i++)
+        ctx->REGS[i] = ctx->RAM[ctx->I + i];
+}
+
 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++;
+               ctx->PC+=2;
                return;
        }if(b1==0 && b2 == 0xEE){
                ins_RET(ctx);
                return;
        }
+       // Instruction: (3 is the instruction prefix, so n1 here)
+       // 3nnn: address
+       // 3xkk: x is the Vx reg, and kk an immediate value
+       // 3xy0: y is another Vy reg.
+
        // First nimble (4 bits)
        uint8_t n1 = (b1&0xF0)>>4;
+       // Last nimble
+       uint8_t n4 = b2&0xF;
+       uint8_t x = (b1&0xF);
+       uint8_t y = (b2&0xF0)>>4;
+       uint16_t kk = b2;
+       uint16_t nnn = b2 + (x<<8);
+
+       // << Switch de la mort qui tue >>
        switch (n1){
                //case 0:
                        //Sys instr, deprecated
                        //break;
                case 1:
-                       ins_JP(ctx);
+                       ins_JP(ctx, nnn);
                        return;
                case 2:
-                       ins_CALL(ctx);
+                       ins_CALL(ctx, nnn);
                        return;
                case 3:
-                       ins_SE(ctx);
+                       ins_SE_IM(ctx, x, kk);
                        break;
                case 4:
-                       ins_SNE(ctx);
+                       ins_SNE_IM(ctx, x, kk);
                        break;
                case 5:
-                       ins_SEV(ctx);
+                       ins_SE(ctx, x, y);
                        break;
                case 6:
-                       ins_LD(ctx);
+                       ins_LD_IM(ctx, x, kk);
                        break;
                case 7:
-                       ins_ADD(ctx);
+                       ins_ADD_IM(ctx, x, kk);
                        break;
                case 8:
-                       // Last nimble
-                       uint8_t n4=b2&0xF;
                        switch (n4){
                                case 0:
-                                       ins_LDV(ctx);
+                                       ins_LD(ctx, x, y);
                                        break;
                                case 1:
-                                       ins_OR(ctx);
+                                       ins_OR(ctx, x, y);
                                        break;
                                case 2:
-                                       ins_ANDV(ctx);
+                                       ins_AND(ctx, x, y);
                                        break;
                                case 3:
-                                       ins_XOR(ctx);
+                                       ins_XOR(ctx, x, y);
                                        break;
                                case 4:
-                                       ins_ADDV(ctx);
+                                       ins_ADD(ctx, x, y);
                                        break;
                                case 5:
-                                       ins_SUB(ctx);
+                                       ins_SUB(ctx, x, y);
                                        break;
                                case 6:
-                                       ins_SHR(ctx);
+                                       ins_SHR(ctx, x);
                                        break;
                                case 7:
-                                       ins_SUBN(ctx);
+                                       ins_SUBN(ctx, x, y);
                                        break;
                                case 0xE:
-                                       ins_SHL(ctx);
+                                       ins_SHL(ctx, x);
                                        break;
                                default:
                                        printf("Unknown 8xxx instruction b1: %X   b2: %X\n", b1, b2);
@@ -77,56 +245,56 @@ void execute_instruction(ch8_ctx * ctx){
                        }
                        break;
                case 9:
-                       ins_SNEV(ctx);
+                       ins_SNE(ctx, x, y);
                        break;
                case 0xA:
-                       ins_LDI(ctx);
+                       ins_LD_I_nnn(ctx, nnn);
                        break;
                case 0xB:
-                       ins_JPV(ctx);
+                       ins_JP_V0(ctx, nnn);
                        break;
                case 0xC:
-                       ins_RND(ctx);
+                       ins_RND(ctx, x, kk);
                        break;
                case 0xD:
-                       ins_DRW(ctx);
+                       ins_DRW(ctx, x, y, n4);
                        break;
                case 0xE:
                        if(b2==0x9E)
-                               ins_SKP(ctx);
+                               ins_SKP(ctx, x);
                        else if(b2==0xA1)
-                               ins_SKNP(ctx);
+                               ins_SKNP(ctx, x);
                        else
                                printf("Unknown Exxx instruction b1: %X   b2: %X\n", b1, b2);
                        break;
                default: // 0xF
                        switch (b2){
                                case 7:
-                                       ins_LDVDT(ctx);
+                                       ins_LD_V_DT(ctx, x);
                                        break;
                                case 0xA:
-                                       ins_LDK(ctx);
+                                       ins_LDK(ctx, x);
                                        break;
                                case 0x15:
-                                       ins_LDDTV(ctx);
+                                       ins_LD_DT_V(ctx, x);
                                        break;
                                case 0x18:
-                                       ins_LDST(ctx);
+                                       ins_LD_ST(ctx, x);
                                        break;
                                case 0x1E:
-                                       ins_ADDI(ctx);
+                                       ins_ADD_I(ctx, x);
                                        break;
                                case 0x29:
-                                       ins_LDF(ctx);
+                                       ins_LD_F(ctx, x);
                                        break;
                                case 0x33:
-                                       ins_LDB(ctx);
+                                       ins_LD_B(ctx, x);
                                        break;
                                case 0x55:
-                                       ins_LD_Rng_IV(ctx);
+                                       ins_LD_I_V(ctx, x);
                                        break;
                                case 0x65:
-                                       ins_LD_Rng_VI(ctx);
+                                       ins_LD_V_I(ctx, x);
                                        break;
                                default:
                                        printf("Unknown Fxxx instruction b1: %X   b2: %X\n", b1, b2);
@@ -135,5 +303,5 @@ void execute_instruction(ch8_ctx * ctx){
        }
        // Goes to next instruction.
        // Note: we do not implement the Super Chip 48 instruction set
-       ctx->PC++;
+       ctx->PC+=2;
 }
index d366a58d05539da5c3e7b61564b115922dbeefe8..9243eca2ca677624f8f5259db10b0d7bdfd13c43 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef PROCESSOR_H
 #define PROCESSOR_H
 
+#include "stdint.h"
+
 typedef struct{
 // The ram which store the ROM, DATA and some interpreter stuff
 uint8_t * RAM;