jump and nop instructions.
This commit is contained in:
parent
cd588671c4
commit
ba56bd2491
@ -32,3 +32,10 @@ typedef struct {
|
|||||||
|
|
||||||
void cpu_init();
|
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)
|
@ -109,3 +109,5 @@ typedef struct {
|
|||||||
} instruction;
|
} 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() {
|
static void fetch_instruction() {
|
||||||
ctx.cur_opcode = bus_read(ctx.regs.pc++);
|
ctx.cur_opcode = bus_read(ctx.regs.pc++);
|
||||||
ctx.cur_inst = instruction_by_opcode(ctx.cur_opcode);
|
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() {
|
static void fetch_data() {
|
||||||
ctx.mem_dest = 0;
|
ctx.mem_dest = 0;
|
||||||
ctx.dest_is_mem = false;
|
ctx.dest_is_mem = false;
|
||||||
|
|
||||||
|
if(ctx.cur_inst == NULL) return;
|
||||||
|
|
||||||
switch(ctx.cur_inst->mode) {
|
switch(ctx.cur_inst->mode) {
|
||||||
case AM_IMP: return;
|
case AM_IMP: return;
|
||||||
case AM_R:
|
case AM_R:
|
||||||
@ -47,7 +45,13 @@ static void fetch_data() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void execute() {
|
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() {
|
bool cpu_step() {
|
||||||
@ -56,7 +60,11 @@ bool cpu_step() {
|
|||||||
u16 pc = ctx.regs.pc;
|
u16 pc = ctx.regs.pc;
|
||||||
fetch_instruction();
|
fetch_instruction();
|
||||||
fetch_data();
|
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();
|
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];
|
||||||
|
}
|
@ -20,3 +20,58 @@ instruction *instruction_by_opcode(u8 opcode) {
|
|||||||
|
|
||||||
return &instructions[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