about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManuel Palenzuela <manuelpalenzuelamerino@gmail.com>2021-07-20 00:27:37 +0100
committerManuel Palenzuela <manuelpalenzuelamerino@gmail.com>2021-07-20 00:27:37 +0100
commit3e4639ce6871f50aca13aa1fe66620b08471c9bd (patch)
tree1ff98c4e3ec18027bb8423cbf2138dc228a370be
parentMisc: Added stars.ch8 rom (diff)
downloadCHIP8-Emulator-3e4639ce6871f50aca13aa1fe66620b08471c9bd.tar.gz
CHIP8-Emulator-3e4639ce6871f50aca13aa1fe66620b08471c9bd.tar.bz2
CHIP8-Emulator-3e4639ce6871f50aca13aa1fe66620b08471c9bd.zip
Features: Added multiple instructions and added an infinite loop detector
Now we are able to detect when we are entering an infinite loop to stop
the program.
-rw-r--r--chip8_emulator.corebin0 -> 34790048 bytes
-rw-r--r--emulator.c90
-rw-r--r--emulator.h1
-rw-r--r--main.c2
4 files changed, 72 insertions, 21 deletions
diff --git a/chip8_emulator.core b/chip8_emulator.core
new file mode 100644
index 0000000..5911628
--- /dev/null
+++ b/chip8_emulator.core
Binary files differdiff --git a/emulator.c b/emulator.c
index 082cbfb..6016374 100644
--- a/emulator.c
+++ b/emulator.c
@@ -22,6 +22,8 @@ int emulator_initialise(Emulator* emulator)
         0xF0, 0x80, 0xF0, 0x80, 0x80  // F
     };
 
+    srand(time(NULL));
+
     //zero out the memory
     memset(emulator, 0, sizeof(Emulator));
 
@@ -66,6 +68,9 @@ int emulator_tick(Emulator* emulator)
 {
     uint16_t* pc = &emulator->pc;
     uint16_t instr = (emulator->memory[*pc] << 8) | emulator->memory[*pc + 1];
+
+    uint16_t instr_pc = *pc;
+
     *pc += 2;
 
     uint8_t first_nibble = (instr >> 12) & 0xf;
@@ -75,7 +80,7 @@ int emulator_tick(Emulator* emulator)
     uint8_t NN = (instr & 0x00FF); //second_byte
     uint16_t NNN = (instr & 0x0FFF); //last three nibbles
 
-    dbgprintf("instr: 0x%x\n", instr);
+    dbgprintf("instr: 0x%x [0x%x]\n", instr, instr_pc);
     dbgprintf("A: 0x%x\nX: 0x%x\nY: 0x%x\nN: 0x%x\nNN: 0x%x\nNNN: 0x%x\n", first_nibble, X, Y, N, NN, NNN);
 
     switch(first_nibble)
@@ -83,11 +88,9 @@ int emulator_tick(Emulator* emulator)
         case 0x0:
             switch(NNN)
             {
-                case 0x000:
-                    emulator_dump_registers(emulator);
-                    exit(1); //stop executing when program over
                 case 0x0E0: //00E0: Clear screen
                     dbgprintf("CLEAR SCREEN!\n");
+                    memset(emulator->display, 0, sizeof(emulator->display));
                     break;
             }
 
@@ -95,14 +98,31 @@ int emulator_tick(Emulator* emulator)
         case 0x1:
             dbgprintf("JUMP! (0x%x)\n", NNN);
             emulator->pc = NNN;
+
+            if(NNN == instr_pc) //infinite loop
+            {
+                printf("INFINITE LOOP DETECTED! EXITING...\n");
+                emulator_dump_registers(emulator);
+                getchar(); //block
+                exit(0); //stop executing when program over
+            }
+
             break;
         case 0x2:
+            printf("TODO: Instr: 0x%x\n", instr);
+            assert(0);
             break;
         case 0x3:
+            if(emulator->regs.V[X] == NN)
+                *pc += 2;
             break;
         case 0x4:
+        printf("TODO: Instr: 0x%x\n", instr);
+        assert(0);
             break;
         case 0x5:
+            if(emulator->regs.V[X] == emulator->regs.V[Y])
+                *pc += 2;
             break;
         case 0x6:
             dbgprintf("SET REGISTER VX! (0x%x)\n", NN);
@@ -113,14 +133,42 @@ int emulator_tick(Emulator* emulator)
             emulator->regs.V[X] += NN;
             break;
         case 0x8:
+            switch(N)
+            {
+                case 0x0:
+                emulator->regs.V[X] = emulator->regs.V[Y];
+                break;
+            case 0x1:
+            case 0x2:
+            case 0x3:
+                printf("TODO: Instr: 0x%x -- %d\n", instr, N);
+                assert(0);
+                    break;
+            case 0x4:
+                if(emulator->regs.V[X] + emulator->regs.V[Y] > 255)
+                    emulator->regs.VF = 1;
+                else
+                    emulator->regs.VF = 0;
+
+                emulator->regs.V[X] += emulator->regs.V[Y];
+                break;
+            case 0x5:
+            case 0x6:
+            case 0xE:
+                break;
+            }
+
             break;
         case 0xA:
             dbgprintf("SET INDEX REGISTER I! (0x%x)\n", NNN);
             emulator->regs.I = NNN;
             break;
         case 0xB:
+        printf("TODO: Instr: 0x%x\n", instr);
+        assert(0);
             break;
         case 0xC:
+            emulator->regs.V[X] = rand() & NN;
             break;
         case 0xD:
             dbgprintf("DRAW!\n");
@@ -177,21 +225,21 @@ void* emulator_timers_thread(Emulator* emulator)
 void emulator_dump_registers(Emulator* emulator)
 {
     printf("REGISTERS: \n");
-    printf("\tV0: 0x%x", emulator->regs.V0);
-    printf("\tV1: 0x%x", emulator->regs.V1);
-    printf("\tV2: 0x%x", emulator->regs.V2);
-    printf("\tV3: 0x%x", emulator->regs.V3);
-    printf("\tV4: 0x%x", emulator->regs.V4);
-    printf("\tV5: 0x%x", emulator->regs.V5);
-    printf("\tV6: 0x%x", emulator->regs.V6);
-    printf("\tV7: 0x%x", emulator->regs.V7);
-    printf("\tV8: 0x%x", emulator->regs.V8);
-    printf("\tV9: 0x%x", emulator->regs.V9);
-    printf("\tVA: 0x%x", emulator->regs.VA);
-    printf("\tVB: 0x%x", emulator->regs.VB);
-    printf("\tVC: 0x%x", emulator->regs.VC);
-    printf("\tVD: 0x%x", emulator->regs.VD);
-    printf("\tVE: 0x%x", emulator->regs.VE);
-    printf("\tVF: 0x%x", emulator->regs.VF);
-    printf("\tI: 0x%x", emulator->regs.I);
+    printf("\tV0: 0x%x - %d\n", emulator->regs.V0, emulator->regs.V0);
+    printf("\tV1: 0x%x - %d\n", emulator->regs.V1, emulator->regs.V1);
+    printf("\tV2: 0x%x - %d\n", emulator->regs.V2, emulator->regs.V2);
+    printf("\tV3: 0x%x - %d\n", emulator->regs.V3, emulator->regs.V3);
+    printf("\tV4: 0x%x - %d\n", emulator->regs.V4, emulator->regs.V4);
+    printf("\tV5: 0x%x - %d\n", emulator->regs.V5, emulator->regs.V5);
+    printf("\tV6: 0x%x - %d\n", emulator->regs.V6, emulator->regs.V6);
+    printf("\tV7: 0x%x - %d\n", emulator->regs.V7, emulator->regs.V7);
+    printf("\tV8: 0x%x - %d\n", emulator->regs.V8, emulator->regs.V8);
+    printf("\tV9: 0x%x - %d\n", emulator->regs.V9, emulator->regs.V9);
+    printf("\tVA: 0x%x - %d\n", emulator->regs.VA, emulator->regs.VA);
+    printf("\tVB: 0x%x - %d\n", emulator->regs.VB, emulator->regs.VB);
+    printf("\tVC: 0x%x - %d\n", emulator->regs.VC, emulator->regs.VC);
+    printf("\tVD: 0x%x - %d\n", emulator->regs.VD, emulator->regs.VD);
+    printf("\tVE: 0x%x - %d\n", emulator->regs.VE, emulator->regs.VE);
+    printf("\tVF: 0x%x - %d\n", emulator->regs.VF, emulator->regs.VF);
+    printf("\tI: 0x%x - %d\n", emulator->regs.I, emulator->regs.I);
 }
diff --git a/emulator.h b/emulator.h
index 7a9c5ef..7fac868 100644
--- a/emulator.h
+++ b/emulator.h
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <assert.h>
 #include <pthread.h>
 #include <sys/stat.h>
 
diff --git a/main.c b/main.c
index 5269978..9f5dd1b 100644
--- a/main.c
+++ b/main.c
@@ -35,6 +35,8 @@ int main(int argc, char** argv)
         {
             if(event.type == SDL_QUIT)
                 goto exit;
+            if(event.type == SDL_WINDOWEVENT)
+                SDL_RenderPresent(renderer);
         }
 
         emulator_tick(&emulator);