Skip to content

Commit

Permalink
Dirty fix on bug in op_ldd and op_ldi
Browse files Browse the repository at this point in the history
Integrated debugger with the emulation flow (interrupts, hardware emulation, etc)
  • Loading branch information
Dhole committed Oct 5, 2014
1 parent f96c956 commit 66795c6
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 86 deletions.
91 changes: 59 additions & 32 deletions debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@

//#define MEM_SIZE 0x10000

typedef struct {
char name[16];
int arg_a, arg_b;
} command_t;

typedef enum {
DBG_IDLE,
DBG_CONT,
DBG_STEP
} dbg_state_t;

const char *PROMPT = "miniBoy> ";
const int ARG_LEN = 16;

static uint8_t break_points[MEM_SIZE];
static regs_t *regs;

typedef struct {
char name[16];
int arg_a, arg_b;
} command_t;
static dbg_state_t state;
static int rem_steps;

void com_help() {
printf("\n -= miniBoy debugger commands: =-\n\n"
Expand Down Expand Up @@ -72,23 +80,19 @@ void com_disas(int start, int end) {
}

void com_step(int a) {
int i;

if (a < 0) {
a = 1;
}
for (i = 0; i < a; i++) {
disas_op(regs->PC);
cpu_step();
}
rem_steps = a;
state = DBG_STEP;
}

void init_debug() {
void debug_init() {
int i;
for (i = 0; i < MEM_SIZE; i++) {
break_points[i] = 0;
}
regs = cpu_get_regs();
state = DBG_IDLE;
}

int parse_com(char *buf, command_t *com, int arg_len) {
Expand Down Expand Up @@ -126,23 +130,25 @@ int parse_com(char *buf, command_t *com, int arg_len) {
return 2;
}

debug_ret_t run_com(command_t *com) {
int run_com(command_t *com) {
char *name = com->name;

if (strncmp(name, "help", ARG_LEN) == 0 || name[0] == 'h') {
com_help();
} else if (strncmp(name, "step", ARG_LEN) == 0 || name[0] == 's') {
com_step(com->arg_a);
return 1;
} else if (strncmp(name, "run", ARG_LEN) == 0) {
printf("run!\n");
return -1;
} else if (strncmp(name, "regs", ARG_LEN) == 0 || name[0] == 'r') {
cpu_dump_reg();
} else if (strncmp(name, "break", ARG_LEN) == 0 || name[0] == 'b') {
com_break(com->arg_a);
} else if (strncmp(name, "clear", ARG_LEN) == 0) {
com_clear(com->arg_a);
} else if (strncmp(name, "continue", ARG_LEN) == 0 || name[0] == 'c') {
return DBG_CONTINUE;
state = DBG_CONT;
return 1;
} else if (strncmp(name, "memory", ARG_LEN) == 0 || name[0] == 'm') {
//printf("memory!\n");
mem_dump(com->arg_a, com->arg_b);
Expand All @@ -153,19 +159,41 @@ debug_ret_t run_com(command_t *com) {
//printf("memory!\n");
mem_dump_io_regs();
} else if (strncmp(name, "quit", ARG_LEN) == 0 || name[0] == 'q') {
return DBG_EXIT;
return -1;
} else {
printf("E) Unrecognized command: %s\n", name);
return DBG_NOTHING;
}
return DBG_NOTHING;
return 0;
}

debug_ret_t debug_run() {
int debug_run(int *debug_flag) {
char *line;
command_t com;
int res;

init_debug();
regs = cpu_get_regs();

switch(state) {
case DBG_IDLE:
break;
case DBG_STEP:
if (rem_steps > 0) {
disas_op(regs->PC);
rem_steps--;
return cpu_step();
} else {
state = DBG_IDLE;
}
break;
case DBG_CONT:
if (break_points[regs->PC]) {
state = DBG_IDLE;
break;
} else {
return cpu_step();
}
break;
}

while((line = linenoise(PROMPT)) != NULL) {
if (line[0] != '\0') {
Expand All @@ -177,16 +205,15 @@ debug_ret_t debug_run() {
}
}
free(line);
switch (run_com(&com)) {
case DBG_EXIT:
return DBG_EXIT;
break;
case DBG_CONTINUE:
return DBG_CONTINUE;
break;
default:
break;
}
res = run_com(&com);
if (res < 0) {
*debug_flag = 0;
return 0;
} else if (res == 0) {
continue;
} else {
return 0;
}
}
return DBG_EXIT;
return 0;
}
9 changes: 2 additions & 7 deletions debugger.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
typedef enum {
DBG_EXIT,
DBG_CONTINUE,
DBG_NOTHING
} debug_ret_t;

debug_ret_t debug_run();
int debug_run();
void debug_init();
57 changes: 34 additions & 23 deletions dmg.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
#define MAX_BIOS_SIZE 0x100
#define MAX_ROM_SIZE 0x400000

static uint8_t bios[256];
static uint8_t *rom;
//static uint8_t bios[256];
//static uint8_t *rom;

void dmg_load_bios(char *bios_path) {
int size;
FILE *fb;
uint8_t *bios;

fb = fopen(bios_path, "rb");
if (fb == NULL) {
printf("Can't open bios file %s", bios_path);
Expand All @@ -28,14 +30,18 @@ void dmg_load_bios(char *bios_path) {
exit(1);
}
fseek(fb, 0, SEEK_SET);
bios = malloc(size);
fread(bios, 1, size, fb);
mem_load(0, bios, size);
//mem_load(0, bios, size);
mem_set_bios(bios, size);
fclose(fb);
}

void dmg_load_rom(char *rom_path) {
int size;
FILE *fr;
uint8_t *rom;

fr = fopen(rom_path, "rb");
if (fr == NULL) {
printf("Can't open rom file %s", rom_path);
Expand All @@ -50,15 +56,20 @@ void dmg_load_rom(char *rom_path) {
fseek(fr, 0, SEEK_SET);
rom = malloc(size);
fread(rom, 1, size, fr);
mem_load(0x100, &rom[0x100], 0x4000 - 0x100);
//mem_load(0x100, &rom[0x100], 0x4000 - 0x100);
//printf("READ ROM: %02x %02x %02x %02x\n", rom[0], rom[1], rom[2], rom[3]);
mem_set_rom(rom, size);
mem_load_rom();
fclose(fr);
}

void dmg_unload_rom() {
free(rom);
mem_unset_rom();
}

void dmg_init() {
mem_enable_bios();
debug_init();
cpu_init();
//cpu_test();
//debug_run();
Expand All @@ -68,27 +79,27 @@ void dmg_reset() {

}

void dmg_run(uint32_t delta, int debug_flag) {
void dmg_run(uint32_t delta, int *debug_flag) {
int clk, cycles;
if (debug_flag) {
debug_run(delta);
} else {
//dmg_emulate_hardware(delta);
clk = 0;
screen_start_frame();
//dmg_emulate_hardware(delta);
clk = 0;
screen_start_frame();

while (clk < SCREEN_DUR_FRAME) {
// if timer overflow...
// if End of serial IO transfer...
// if High to low p10-p13...

cycles = cpu_step();
while (clk < SCREEN_DUR_FRAME) {
// if timer overflow...
// if End of serial IO transfer...
// if High to low p10-p13...

// If LCD on...!!!
screen_emulate(cycles);
clk += cycles;
if (*debug_flag) {
cycles = debug_run(debug_flag);
} else {
cycles = cpu_step();
}
screen_write_fb();

// If LCD on...!!!
screen_emulate(cycles);

clk += cycles;
}
screen_write_fb();
}
2 changes: 1 addition & 1 deletion dmg.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ void dmg_load_rom(char *rom_path);
void dmg_unload_rom();
void dmg_init();
void dmg_reset();
void dmg_run(uint32_t delta, int debug_flag);
void dmg_run(uint32_t delta, int *debug_flag);
50 changes: 37 additions & 13 deletions lr35902.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,42 @@ void op_ld_16(void *_a, void *_b) {
*a = *b;
}

// BUG!!!, HL+ happens before the exec_op() stores the result
// Dirty fix
void op_ldi(void *_a, void *_b) {
uint8_t *a = (uint8_t*)_a;
uint8_t *b = (uint8_t*)_b;
*a = *b;
(*regs.HL)++;
//uint8_t *b = (uint8_t*)_b;
//*a = *b;
//(*regs.HL)++;
if (a == regs.A) {
exec_op(0x7E);
regs.PC -= ops[0x7E].length;
} else {
exec_op(0x77);
regs.PC -= ops[0x77].length;
}

exec_op(0x23);
regs.PC -= ops[0x2B].length;
}

// BUG!!!, HL- happens before the exec_op() stores the result
// Dirty fix
void op_ldd(void *_a, void *_b) {
uint8_t *a = (uint8_t*)_a;
uint8_t *b = (uint8_t*)_b;
*a = *b;
(*regs.HL)--;
//uint8_t *b = (uint8_t*)_b;
//*a = *b;
//(*regs.HL)--;
if (a == regs.A) {
exec_op(0x7E);
regs.PC -= ops[0x7E].length;
} else {
exec_op(0x77);
regs.PC -= ops[0x77].length;
}

exec_op(0x2B);
regs.PC -= ops[0x2B].length;
}

void op_ldhl(void *_a, void *_b) {
Expand All @@ -187,20 +211,20 @@ void op_halt(void *_a, void *_b) {
void op_add_8(void *_a, void *_b) {
uint8_t *a = (uint8_t*)_a;
uint8_t *b = (uint8_t*)_b;

set_flag(H_FLAG, ((*a & 0x0F) > (0x0F - (*b & 0x0F))) ? 1 : 0);
set_flag(C_FLAG, (*a > (0xFF - *b)) ? 1 : 0);

*a += *b;

set_flag_Z(a);
set_flag(N_FLAG, 0);
}

void op_add_16(void *_a, void *_b) {
uint16_t *a = (uint16_t*)_a;
uint16_t *b = (uint16_t*)_b;

set_flag(H_FLAG, ((*a & 0x0FFF) > (0x0FFF - (*b & 0x0FFF))) ? 1 : 0);
set_flag(C_FLAG, ((*a & 0xFFFF) > (0xFFFF - (*b & 0xFFFF))) ? 1 : 0);

Expand Down Expand Up @@ -738,31 +762,31 @@ SET_OP(0x1E, "LD E,d8", op_ld_8, regs.E, imm_8, NONE, 2, 8, 0);
SET_OP(0x1F, "RRA", op_rra, NULL, NULL, NONE, 1, 4, 0);
SET_OP(0x20, "JR NZ,r8", op_jr, &C_NZ, imm_8, NONE, 2, 8, 12);
SET_OP(0x21, "LD HL,d16", op_ld_16, regs.HL, imm_16, NONE, 3, 12, 0);
SET_OP(0x22, "LD (HL+),A", op_ldi, regs.HL, regs.A, MEM_W_16, 1, 8, 0);
SET_OP(0x22, "LD (HL+),A", op_ldi, regs.HL, regs.A, NONE, 1, 8, 0);
SET_OP(0x23, "INC HL", op_inc_16, regs.HL, NULL, NONE, 1, 8, 0);
SET_OP(0x24, "INC H", op_inc_8, regs.H, NULL, NONE, 1, 4, 0);
SET_OP(0x25, "DEC H", op_dec_8, regs.H, NULL, NONE, 1, 4, 0);
SET_OP(0x26, "LD H,d8", op_ld_8, regs.H, imm_8, NONE, 2, 8, 0);
SET_OP(0x27, "DAA", op_daa, NULL, NULL, NONE, 1, 4, 0);
SET_OP(0x28, "JR Z,r8", op_jr, &C_Z, imm_8, NONE, 2, 8, 12);
SET_OP(0x29, "ADD HL,HL", op_add_16, regs.HL, regs.HL, NONE, 1, 8, 0);
SET_OP(0x2A, "LD A,(HL+)", op_ldi, regs.A, regs.HL, MEM_R_16, 1, 8, 0);
SET_OP(0x2A, "LD A,(HL+)", op_ldi, regs.A, regs.HL, NONE, 1, 8, 0);
SET_OP(0x2B, "DEC HL", op_dec_16, regs.HL, NULL, NONE, 1, 8, 0);
SET_OP(0x2C, "INC L", op_inc_8, regs.L, NULL, NONE, 1, 4, 0);
SET_OP(0x2D, "DEC L", op_dec_8, regs.L, NULL, NONE, 1, 4, 0);
SET_OP(0x2E, "LD L,d8", op_ld_8, regs.L, imm_8, NONE, 2, 8, 0);
SET_OP(0x2F, "CPL", op_cpl, NULL, NULL, NONE, 1, 4, 0);
SET_OP(0x30, "JR NC,r8", op_jr, &C_NC, imm_8, NONE, 2, 8, 12);
SET_OP(0x31, "LD SP,d16", op_ld_16, regs.SP, imm_16, NONE, 3, 12, 0);
SET_OP(0x32, "LD (HL-),A", op_ldd, regs.HL, regs.A, MEM_W_16, 1, 8, 0);
SET_OP(0x32, "LD (HL-),A", op_ldd, regs.HL, regs.A, NONE, 1, 8, 0);
SET_OP(0x33, "INC SP", op_inc_16, regs.SP, NULL, NONE, 1, 8, 0);
SET_OP(0x34, "INC (HL)", op_inc_8, regs.HL, NULL, MEM_W_16, 1, 12, 0);
SET_OP(0x35, "DEC (HL)", op_dec_8, regs.HL, NULL, MEM_W_16, 1, 12, 0);
SET_OP(0x36, "LD (HL),d8", op_ld_8, regs.HL, imm_8, MEM_W_16, 2, 12, 0);
SET_OP(0x37, "SCF", op_scf, NULL, NULL, NONE, 1, 4, 0);
SET_OP(0x38, "JR C,r8", op_jr, &C_C, imm_8, NONE, 2, 8, 12);
SET_OP(0x39, "ADD HL,SP", op_add_16, regs.HL, regs.SP, NONE, 1, 8, 0);
SET_OP(0x3A, "LD A,(HL-)", op_ldd, regs.A, regs.HL, MEM_R_16, 1, 8, 0);
SET_OP(0x3A, "LD A,(HL-)", op_ldd, regs.A, regs.HL, NONE, 1, 8, 0);
SET_OP(0x3B, "DEC SP", op_dec_16, regs.SP, NULL, NONE, 1, 8, 0);
SET_OP(0x3C, "INC A", op_inc_8, regs.A, NULL, NONE, 1, 4, 0);
SET_OP(0x3D, "DEC A", op_dec_8, regs.A, NULL, NONE, 1, 4, 0);
Expand Down
Loading

0 comments on commit 66795c6

Please sign in to comment.