diff --git a/include/cpu.h b/include/cpu.h index fb8eb3b..386f883 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -31,4 +31,11 @@ typedef struct { } cpu_context; void cpu_init(); -bool cpu_step(); \ No newline at end of file +bool cpu_step(); + +typedef void (*IN_PROC)(cpu_context *); + +IN_PROC inst_get_processor(in_type type); + +#define CPU_FLAG_Z BIT(ctx->regs.f, 7) +#define CPU_FLAG_C BIT(ctx->regs.f, 4) \ No newline at end of file diff --git a/include/instructions.h b/include/instructions.h index 82b43c0..eb697fd 100644 --- a/include/instructions.h +++ b/include/instructions.h @@ -108,4 +108,6 @@ typedef struct { u8 param; } instruction; -instruction *instruction_by_opcode(u8 opcode); \ No newline at end of file +instruction *instruction_by_opcode(u8 opcode); + +char *inst_name(in_type t); \ No newline at end of file diff --git a/lib/cpu.c b/lib/cpu.c index ccbb900..a1b7ac9 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -10,16 +10,14 @@ void cpu_init() { static void fetch_instruction() { ctx.cur_opcode = bus_read(ctx.regs.pc++); ctx.cur_inst = instruction_by_opcode(ctx.cur_opcode); - if(ctx.cur_inst == NULL){ - printf("Unknown Instruction! %d\n", ctx.cur_opcode); - exit(-7); - } } static void fetch_data() { ctx.mem_dest = 0; ctx.dest_is_mem = false; + if(ctx.cur_inst == NULL) return; + switch(ctx.cur_inst->mode) { case AM_IMP: return; case AM_R: @@ -47,7 +45,13 @@ static void fetch_data() { } static void execute() { - printf("\tNot executing yet...\n"); + IN_PROC proc = inst_get_processor(ctx.cur_inst->type); + + if (!proc) { + NO_IMPL + } + + proc(&ctx); } bool cpu_step() { @@ -56,7 +60,11 @@ bool cpu_step() { u16 pc = ctx.regs.pc; fetch_instruction(); fetch_data(); - printf("Executing Instruction: %02X PC: %04X\n", ctx.cur_opcode, pc); + printf("%04X: %7s (%02X %02X %02X) A: %02X B: %02X C: %02X\n", pc, ctx.cur_inst != NULL ? inst_name(ctx.cur_inst->type) : "UNK", ctx.cur_opcode, bus_read(pc+1), bus_read(pc+2), ctx.regs.a, ctx.regs.b, ctx.regs.c); + if(ctx.cur_inst == NULL){ + printf("Unknown Instruction! %02X\n", ctx.cur_opcode); + exit(-7); + } execute(); } diff --git a/lib/cpu_proc.c b/lib/cpu_proc.c new file mode 100644 index 0000000..0ae89aa --- /dev/null +++ b/lib/cpu_proc.c @@ -0,0 +1,50 @@ +#include +#include + +//process CPU instructions... + +static void proc_none(cpu_context *ctx) { + printf("INVALID INSTRUCTION!\n"); + exit(-7); +} + +static void proc_nop(cpu_context *ctx) { + +} + +static void proc_ld(cpu_context *ctx) { + //TODO +} + +static bool check_condition(cpu_context *ctx) { + bool z = CPU_FLAG_Z; + bool c = CPU_FLAG_C; + + switch(ctx->cur_inst->cond) { + case CT_NONE: return true; + case CT_C: return c; + case CT_NC: return !c; + case CT_Z: return z; + case CT_NZ: return !z; + } + + return false; +} + +static void proc_jp(cpu_context *ctx) { + if (check_condition(ctx)) { + ctx->regs.pc = ctx->fetched_data; + emu_cycles(1); + } +} + +IN_PROC processors[] = { + [IN_NONE] = proc_none, + [IN_NOP] = proc_nop, + [IN_LD] = proc_ld, + [IN_JP] = proc_jp, +}; + +IN_PROC inst_get_processor(in_type type) { + return processors[type]; +} \ No newline at end of file diff --git a/lib/instructions.c b/lib/instructions.c index 27db91e..4bf8ec7 100644 --- a/lib/instructions.c +++ b/lib/instructions.c @@ -19,4 +19,59 @@ instruction *instruction_by_opcode(u8 opcode) { } return &instructions[opcode]; +} + +char *inst_lookup[] = { + "", + "NOP", + "LD", + "INC", + "DEC", + "RLCA", + "ADD", + "RRCA", + "STOP", + "RLA", + "JR", + "RRA", + "DAA", + "CPL", + "SCF", + "CCF", + "HALT", + "ADC", + "SUB", + "SBC", + "AND", + "XOR", + "OR", + "CP", + "POP", + "JP", + "PUSH", + "RET", + "CB", + "CALL", + "RETI", + "LDH", + "JPHL", + "DI", + "EI", + "RST", + "IN_ERR", + "IN_RLC", + "IN_RRC", + "IN_RL", + "IN_RR", + "IN_SLA", + "IN_SRA", + "IN_SWAP", + "IN_SRL", + "IN_BIT", + "IN_RES", + "IN_SET" +}; + +char *inst_name(in_type t) { + return inst_lookup[t]; } \ No newline at end of file