1
0
mirror of https://github.com/rkujawa/rk65c02.git synced 2024-12-04 19:50:19 +00:00

More refactoring and improvements to logging!

This commit is contained in:
Radosław Kujawa 2018-03-23 13:37:07 +01:00
parent 0c77eeb505
commit 5fddf2c5dc
9 changed files with 102 additions and 74 deletions

View File

@ -33,6 +33,9 @@ bus_device_add(bus_t *b, device_t *d, uint16_t addr)
dm->addr = addr; dm->addr = addr;
LL_APPEND((b->dm_head), dm); LL_APPEND((b->dm_head), dm);
rk65c02_log(LOG_INFO, "Bus mapping added: %x device %s size %x.",
addr, d->name, d->size);
} }
void void
@ -71,7 +74,7 @@ bus_access_device(bus_t *t, uint16_t addr, device_t **d, uint16_t *off)
} }
if (*d == NULL) { if (*d == NULL) {
rk6502_log(LOG_WARN, "Hitting unmapped bus space @ %x!", addr); rk65c02_log(LOG_WARN, "Hitting unmapped bus space @ %x!", addr);
return; return;
} }
@ -93,7 +96,7 @@ bus_read_1(bus_t *t, uint16_t addr)
val = d->read_1(d, off); val = d->read_1(d, off);
if (t->access_debug) if (t->access_debug)
rk6502_log(LOG_DEBUG, "bus READ @ %x (off %x) value %x\n", rk65c02_log(LOG_DEBUG, "bus READ @ %x (off %x) value %x\n",
addr, off, val); addr, off, val);
return val; return val;
@ -108,7 +111,7 @@ bus_write_1(bus_t *t, uint16_t addr, uint8_t val)
bus_access_device(t, addr, &d, &off); bus_access_device(t, addr, &d, &off);
if (t->access_debug) if (t->access_debug)
rk6502_log(LOG_DEBUG, "bus WRITE @ %x (off %x) value %x\n", rk65c02_log(LOG_DEBUG, "bus WRITE @ %x (off %x) value %x\n",
addr, off, val); addr, off, val);
d->write_1(d, off, val); d->write_1(d, off, val);
@ -163,7 +166,7 @@ bus_load_file(bus_t *t, uint16_t addr, const char *filename)
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd == -1) { if (fd == -1) {
rk6502_log(LOG_ERROR, "Problem while trying to open file: %s", rk65c02_log(LOG_ERROR, "Problem while trying to open file: %s",
strerror(errno)); strerror(errno));
return false; return false;
} }

View File

@ -18,6 +18,8 @@ debug_trace_print_all(rk65c02emu_t *e)
{ {
trace_t *tr; trace_t *tr;
instruction_t i; instruction_t i;
char *instrstr;
char *regsstr;
if (e->trace_head == NULL) if (e->trace_head == NULL)
return; return;
@ -26,11 +28,14 @@ debug_trace_print_all(rk65c02emu_t *e)
i.opcode = tr->opcode; i.opcode = tr->opcode;
i.op1 = tr->op1; i.op1 = tr->op1;
i.op2 = tr->op2; i.op2 = tr->op2;
instrstr = instruction_string_get(&i);
regsstr = rk65c02_regs_string_get(tr->regs);
rk6502_log(LOG_TRACE, " %X:\t", tr->address); rk65c02_log(LOG_TRACE, "%X: %s\t%s", tr->address, instrstr,
instruction_print(&i); regsstr);
printf("\t");
rk65c02_dump_regs(tr->regs); free(instrstr);
free(regsstr);
} }
} }

View File

@ -2,6 +2,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <errno.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -55,59 +56,83 @@ instruction_fetch(bus_t *b, uint16_t addr)
void void
instruction_print(instruction_t *i) instruction_print(instruction_t *i)
{ {
char *str;
str = instruction_string_get(i);
printf("%s", str);
free(str);
}
char *
instruction_string_get(instruction_t *i)
{
#define INSTR_STR_LEN 16
instrdef_t id; instrdef_t id;
char *str;
str = malloc(INSTR_STR_LEN);
if (str == NULL) {
rk65c02_log(LOG_CRIT, "Error allocating memory for buffer: %s.",
strerror(errno));
return NULL;
}
memset(str, 0, INSTR_STR_LEN);
id = instruction_decode(i->opcode); id = instruction_decode(i->opcode);
switch (id.mode) { switch (id.mode) {
case IMPLIED: case IMPLIED:
printf("%s", id.mnemonic); snprintf(str, INSTR_STR_LEN, "%s", id.mnemonic);
break; break;
case ACCUMULATOR: case ACCUMULATOR:
printf("%s A", id.mnemonic); snprintf(str, INSTR_STR_LEN, "%s A", id.mnemonic);
break; break;
case IMMEDIATE: case IMMEDIATE:
printf("%s #%#02x", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s #%#02x", id.mnemonic, i->op1);
break; break;
case ZP: case ZP:
printf("%s %#02x", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s %#02x", id.mnemonic, i->op1);
break; break;
case ZPX: case ZPX:
printf("%s %#02x,X", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s %#02x,X", id.mnemonic, i->op1);
break; break;
case ZPY: case ZPY:
printf("%s %#02x,Y", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s %#02x,Y", id.mnemonic, i->op1);
break; break;
case IZP: case IZP:
printf("%s (%#02x)", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s (%#02x)", id.mnemonic, i->op1);
break; break;
case IZPX: case IZPX:
printf("%s (%#02x,X)", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s (%#02x,X)", id.mnemonic, i->op1);
break; break;
case IZPY: case IZPY:
printf("%s (%#02x),Y", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s (%#02x),Y", id.mnemonic, i->op1);
break; break;
case ZPR: case ZPR:
printf("%s %#02x,%#02x", id.mnemonic, i->op1, i->op2); snprintf(str, INSTR_STR_LEN, "%s %#02x,%#02x", id.mnemonic, i->op1, i->op2);
break; break;
case ABSOLUTE: case ABSOLUTE:
printf("%s %#02x%02x", id.mnemonic, i->op2, i->op1); snprintf(str, INSTR_STR_LEN, "%s %#02x%02x", id.mnemonic, i->op2, i->op1);
break; break;
case ABSOLUTEX: case ABSOLUTEX:
printf("%s %#02x%02x,X", id.mnemonic, i->op2, i->op1); snprintf(str, INSTR_STR_LEN, "%s %#02x%02x,X", id.mnemonic, i->op2, i->op1);
break; break;
case ABSOLUTEY: case ABSOLUTEY:
printf("%s %#02x%02x,Y", id.mnemonic, i->op2, i->op1); snprintf(str, INSTR_STR_LEN, "%s %#02x%02x,Y", id.mnemonic, i->op2, i->op1);
break; break;
case IABSOLUTE: case IABSOLUTE:
printf("%s (%#02x%02x)", id.mnemonic, i->op2, i->op1); snprintf(str, INSTR_STR_LEN, "%s (%#02x%02x)", id.mnemonic, i->op2, i->op1);
break; break;
case IABSOLUTEX: case IABSOLUTEX:
printf("%s (%#02x%02x,X)", id.mnemonic, i->op2, i->op1); snprintf(str, INSTR_STR_LEN, "%s (%#02x%02x,X)", id.mnemonic, i->op2, i->op1);
break; break;
case RELATIVE: case RELATIVE:
printf("%s %#02x", id.mnemonic, i->op1); snprintf(str, INSTR_STR_LEN, "%s %#02x", id.mnemonic, i->op1);
break; break;
} }
return str;
} }
assembler_t assembler_t
@ -173,7 +198,7 @@ assemble_single_buf(uint8_t **buf, uint8_t *bsize, const char *mnemonic, address
} }
if (!found) { if (!found) {
rk6502_log(LOG_ERROR, rk65c02_log(LOG_ERROR,
"Couldn't find opcode for mnemonic %s mode %x.", "Couldn't find opcode for mnemonic %s mode %x.",
mnemonic, mode); mnemonic, mode);
return false; return false;
@ -182,7 +207,7 @@ assemble_single_buf(uint8_t **buf, uint8_t *bsize, const char *mnemonic, address
*bsize = id.size; *bsize = id.size;
*buf = malloc(id.size); *buf = malloc(id.size);
if(*buf == NULL) { if(*buf == NULL) {
rk6502_log(LOG_ERROR, "Error allocating assembly buffer."); rk65c02_log(LOG_ERROR, "Error allocating assembly buffer.");
return false; return false;
} }
@ -304,7 +329,7 @@ instruction_data_write_1(rk65c02emu_t *e, instrdef_t *id, instruction_t *i, uint
* PC which is handled within emulation of a given opcode. * PC which is handled within emulation of a given opcode.
*/ */
default: default:
rk6502_log(LOG_ERROR, rk65c02_log(LOG_ERROR,
"unhandled addressing mode for opcode %x\n", i->opcode); "unhandled addressing mode for opcode %x\n", i->opcode);
break; break;
} }
@ -371,7 +396,7 @@ instruction_data_read_1(rk65c02emu_t *e, instrdef_t *id, instruction_t *i)
* PC which is handled within emulation of a given opcode. * PC which is handled within emulation of a given opcode.
*/ */
default: default:
rk6502_log(LOG_ERROR, rk65c02_log(LOG_ERROR,
"unhandled addressing mode for opcode %x\n", i->opcode); "unhandled addressing mode for opcode %x\n", i->opcode);
break; break;
} }

View File

@ -51,6 +51,7 @@ typedef struct assembler assembler_t;
instruction_t instruction_fetch(bus_t *, uint16_t); instruction_t instruction_fetch(bus_t *, uint16_t);
instrdef_t instruction_decode(uint8_t); instrdef_t instruction_decode(uint8_t);
void instruction_print(instruction_t *); void instruction_print(instruction_t *);
char * instruction_string_get(instruction_t *);
void disassemble(bus_t *, uint16_t); void disassemble(bus_t *, uint16_t);
uint8_t instruction_data_read_1(rk65c02emu_t *, instrdef_t *, instruction_t *); uint8_t instruction_data_read_1(rk65c02emu_t *, instrdef_t *, instruction_t *);
void instruction_data_write_1(rk65c02emu_t *, instrdef_t *, instruction_t *, uint8_t); void instruction_data_write_1(rk65c02emu_t *, instrdef_t *, instruction_t *, uint8_t);

View File

@ -16,12 +16,12 @@ static const char *level_str[] = {
static uint8_t level = LOG_INFO; static uint8_t level = LOG_INFO;
void rk6502_loglevel_set(uint8_t l) void rk65c02_loglevel_set(uint8_t l)
{ {
level = l; level = l;
} }
void rk6502_log(uint8_t l, const char* fmt, ...) void rk65c02_log(uint8_t l, const char* fmt, ...)
{ {
va_list args; va_list args;
struct timeval t; struct timeval t;

View File

@ -10,6 +10,6 @@
current level, but not when creating new log current level, but not when creating new log
messages. */ messages. */
void rk6502_loglevel_set(uint8_t); void rk65c02_loglevel_set(uint8_t);
void rk6502_log(uint8_t, const char *, ...); void rk65c02_log(uint8_t, const char *, ...);

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <errno.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -35,7 +36,7 @@ rk65c02_init(bus_t *b)
e.trace_head = NULL; e.trace_head = NULL;
e.runtime_disassembly = false; e.runtime_disassembly = false;
rk6502_log(LOG_DEBUG, "Initialized new emulator."); rk65c02_log(LOG_DEBUG, "Initialized new emulator.");
return e; return e;
} }
@ -119,7 +120,7 @@ rk65c02_exec(rk65c02emu_t *e)
if (!instruction_modify_pc(&id)) if (!instruction_modify_pc(&id))
program_counter_increment(e, &id); program_counter_increment(e, &id);
} else { } else {
rk6502_log(LOG_ERROR, "unimplemented opcode %X @ %X\n", rk65c02_log(LOG_ERROR, "unimplemented opcode %X @ %X\n",
i.opcode, e->regs.PC); i.opcode, e->regs.PC);
e->state = STOPPED; e->state = STOPPED;
e->stopreason = EMUERROR; e->stopreason = EMUERROR;
@ -188,50 +189,42 @@ rk65c02_dump_stack(rk65c02emu_t *e, uint8_t n)
void void
rk65c02_dump_regs(reg_state_t regs) rk65c02_dump_regs(reg_state_t regs)
{ {
printf("A: %X X: %X Y: %X PC: %X SP: %X P: ", char *str;
regs.A, regs.X, regs.Y, regs.PC, regs.SP);
if (regs.P & P_NEGATIVE) str = rk65c02_regs_string_get(regs);
printf("N");
else
printf("-");
if (regs.P & P_SIGN_OVERFLOW) printf ("%s", str);
printf("V");
else
printf("-");
if (regs.P & P_UNDEFINED) free(str);
printf("1"); }
else
printf("-");
if (regs.P & P_BREAK) char *
printf("B"); rk65c02_regs_string_get(reg_state_t regs)
else {
printf("-"); #define REGS_STR_LEN 50
char *str;
if (regs.P & P_DECIMAL) /* XXX: string allocation to a separate utility function? */
printf("D"); str = malloc(REGS_STR_LEN);
else if (str == NULL) {
printf("-"); rk65c02_log(LOG_CRIT, "Error allocating memory for buffer: %s.",
strerror(errno));
return NULL;
}
memset(str, 0, REGS_STR_LEN);
if (regs.P & P_IRQ_DISABLE) snprintf(str, REGS_STR_LEN, "A: %X X: %X Y: %X PC: %X SP: %X P: %c%c%c%c%c%c%c%c",
printf("I"); regs.A, regs.X, regs.Y, regs.PC, regs.SP,
else (regs.P & P_NEGATIVE) ? 'N' : '-',
printf("-"); (regs.P & P_SIGN_OVERFLOW) ? 'V' : '-',
(regs.P & P_UNDEFINED) ? '1' : '-',
(regs.P & P_BREAK) ? 'B' : '-',
(regs.P & P_DECIMAL) ? 'D' : '-',
(regs.P & P_IRQ_DISABLE) ? 'I' : '-',
(regs.P & P_ZERO) ? 'Z' : '-',
(regs.P & P_CARRY) ? 'C' : '-');
if (regs.P & P_ZERO) return str;
printf("Z");
else
printf("-");
if (regs.P & P_CARRY)
printf("C");
else
printf("-");
printf("\n");
} }
/* /*
int int
@ -252,7 +245,7 @@ main(void)
bus_write_1(&b, 8, 0x0); bus_write_1(&b, 8, 0x0);
bus_write_1(&b, 9, OP_STP); bus_write_1(&b, 9, OP_STP);
rk6502_start(&b, 0); rk65c02_start(&b, 0);
bus_finish(&b); bus_finish(&b);
} }

View File

@ -79,7 +79,8 @@ typedef struct rk65c02emu rk65c02emu_t;
rk65c02emu_t rk65c02_init(bus_t *); rk65c02emu_t rk65c02_init(bus_t *);
void rk65c02_start(rk65c02emu_t *); void rk65c02_start(rk65c02emu_t *);
void rk65c02_step(rk65c02emu_t *, uint16_t); void rk65c02_step(rk65c02emu_t *, uint16_t);
void rk65c02_dump_regs(reg_state_t regs); char *rk65c02_regs_string_get(reg_state_t);
void rk65c02_dump_regs(reg_state_t);
void rk65c02_dump_stack(rk65c02emu_t *, uint8_t); void rk65c02_dump_stack(rk65c02emu_t *, uint8_t);
void rk65c02_irq(rk65c02emu_t *e); void rk65c02_irq(rk65c02emu_t *e);

View File

@ -55,7 +55,7 @@ ATF_TC_BODY(trace, tc)
trace_t *tr; trace_t *tr;
int i; int i;
rk6502_loglevel_set(LOG_TRACE); rk65c02_loglevel_set(LOG_TRACE);
b = bus_init_with_default_devs(); b = bus_init_with_default_devs();
a = assemble_init(&b, ROM_LOAD_ADDR); a = assemble_init(&b, ROM_LOAD_ADDR);