jump and nop instructions.
This commit is contained in:
parent
cd588671c4
commit
ba56bd2491
@ -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)
|
@ -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);
|
20
lib/cpu.c
20
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();
|
||||
}
|
||||
|
||||
|
50
lib/cpu_proc.c
Normal file
50
lib/cpu_proc.c
Normal 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];
|
||||
}
|
@ -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];
|
||||
}
|
Loading…
Reference in New Issue
Block a user