jump and nop instructions.

This commit is contained in:
Samuel Walker 2025-01-30 17:03:56 -07:00
parent cd588671c4
commit ba56bd2491
Signed by: piwalker
GPG Key ID: BE1F84BF85111255
5 changed files with 130 additions and 8 deletions

View File

@ -31,4 +31,11 @@ typedef struct {
} cpu_context;
void cpu_init();
bool cpu_step();
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)

View File

@ -108,4 +108,6 @@ typedef struct {
u8 param;
} instruction;
instruction *instruction_by_opcode(u8 opcode);
instruction *instruction_by_opcode(u8 opcode);
char *inst_name(in_type t);

View File

@ -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();
}

50
lib/cpu_proc.c Normal file
View File

@ -0,0 +1,50 @@
#include <cpu.h>
#include <emu.h>
//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];
}

View File

@ -19,4 +19,59 @@ instruction *instruction_by_opcode(u8 opcode) {
}
return &instructions[opcode];
}
char *inst_lookup[] = {
"<NONE>",
"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];
}