#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);
}
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);
}
// Goes to next instruction.
// Note: we do not implement the Super Chip 48 instruction set
- ctx->PC++;
+ ctx->PC+=2;
}