CPU_TRACING bugfix and more readable

- GetImm mode was not reporting correct arg
    - Converts it to a format easier to compare against similar CPU trace output from AppleWin
    - Sanity-check arg counts
This commit is contained in:
Aaron Culliney 2014-11-17 20:46:29 -08:00
parent 9b9ca39344
commit 9bbe906f43
5 changed files with 324 additions and 33 deletions

View File

@ -710,9 +710,6 @@ GLUE_C_WRITE(cpu65_trace_arg2)
GLUE_C_WRITE(cpu65_trace_epilogue)
{
char fmt[64];
char buf[64];
int8_t arg1 = opargs[1];
int8_t arg2 = opargs[2];
@ -722,50 +719,38 @@ GLUE_C_WRITE(cpu65_trace_epilogue)
assert(nargs > 0);
assert(nargs <= 3);
if (nargs != opcodes_65c02_numargs[cpu65_opcode]+1) {
assert(false && "OOPS, most likely some cpu.S routine is not properly setting the arg value");
}
#warning FIXME TODO ... need to refactor this and the debugger routines to use the same codepaths ...
switch (opcodes_65c02[cpu65_opcode].mode) {
case addr_implied:
case addr_accumulator: /* no arg */
sprintf(buf, "%04X:%02X %s %s", current_pc, cpu65_opcode, opcodes_65c02[cpu65_opcode].mnemonic, disasm_templates[opcodes_65c02[cpu65_opcode].mode]);
case addr_accumulator:
fprintf(cpu_trace_fp, "%04X:%02X ", current_pc, cpu65_opcode);
break;
case addr_immediate:
case addr_zeropage:
case addr_zeropage_x:
case addr_zeropage_y:
case addr_indirect:
case addr_indirect_x:
case addr_indirect_y: /* byte arg */
sprintf(fmt, "%04X:%02X%02X %s %s", current_pc, cpu65_opcode, (uint8_t)arg1, opcodes_65c02[cpu65_opcode].mnemonic, disasm_templates[opcodes_65c02[cpu65_opcode].mode]);
sprintf(buf, fmt, (uint8_t)arg1);
case addr_indirect_y:
case addr_relative:
fprintf(cpu_trace_fp, "%04X:%02X%02X ", current_pc, cpu65_opcode, (uint8_t)arg1);
break;
case addr_absolute:
case addr_absolute_x:
case addr_absolute_y:
case addr_j_indirect:
case addr_j_indirect_x: /* word arg */
sprintf(fmt, "%04X:%02X%02X%02X %s %s", current_pc, cpu65_opcode, (uint8_t)arg2, (uint8_t)arg1, opcodes_65c02[cpu65_opcode].mnemonic, disasm_templates[opcodes_65c02[cpu65_opcode].mode]);
sprintf(buf, fmt, (uint8_t)arg1, (uint8_t)arg2);
case addr_j_indirect_x:
fprintf(cpu_trace_fp, "%04X:%02X%02X%02X", current_pc, cpu65_opcode, (uint8_t)arg2, (uint8_t)arg1);
break;
case addr_relative: /* offset */
sprintf(fmt, "%04X:%02X%02X %s %s", current_pc, cpu65_opcode, (uint8_t)arg1, opcodes_65c02[cpu65_opcode].mnemonic, disasm_templates[opcodes_65c02[cpu65_opcode].mode]);
if (arg1 < 0) {
sprintf(buf, fmt, current_pc + arg1 + 2, '-', (uint8_t)(-arg1));
} else {
sprintf(buf, fmt, current_pc + arg1 + 2, '+', (uint8_t)arg1);
}
break;
default: /* shouldn't happen */
sprintf(buf, "invalid opcode mode");
default:
fprintf(cpu_trace_fp, "invalid opcode mode");
break;
}
char regs_buf[64];
sprintf(regs_buf, "EA:%04X SP:%02X X:%02X Y:%02X A:%02X", cpu65_ea, cpu65_sp, cpu65_x, cpu65_y, cpu65_a);
fprintf(cpu_trace_fp, " SP:%02X X:%02X Y:%02X A:%02X", cpu65_sp, cpu65_x, cpu65_y, cpu65_a);
#define FLAGS_BUFSZ 9
char flags_buf[FLAGS_BUFSZ];
@ -796,7 +781,44 @@ GLUE_C_WRITE(cpu65_trace_epilogue)
}
flags_buf[8] = '\0';
fprintf(cpu_trace_fp, "%s %s %s\n", buf, regs_buf, flags_buf);
fprintf(cpu_trace_fp, " %s EA:%04X", flags_buf, cpu65_ea);
char fmt[64];
sprintf(fmt, " %s %s", opcodes_65c02[cpu65_opcode].mnemonic, disasm_templates[opcodes_65c02[cpu65_opcode].mode]);
switch (opcodes_65c02[cpu65_opcode].mode) {
case addr_implied:
case addr_accumulator:
fprintf(cpu_trace_fp, "%s", fmt);
break;
case addr_immediate:
case addr_zeropage:
case addr_zeropage_x:
case addr_zeropage_y:
case addr_indirect:
case addr_indirect_x:
case addr_indirect_y:
fprintf(cpu_trace_fp, fmt, (uint8_t)arg1);
break;
case addr_absolute:
case addr_absolute_x:
case addr_absolute_y:
case addr_j_indirect:
case addr_j_indirect_x:
fprintf(cpu_trace_fp, fmt, (uint8_t)arg1, (uint8_t)arg2);
break;
case addr_relative:
if (arg1 < 0) {
fprintf(cpu_trace_fp, fmt, current_pc + arg1 + 2, '-', (uint8_t)(-arg1));
} else {
fprintf(cpu_trace_fp, fmt, current_pc + arg1 + 2, '+', (uint8_t)arg1);
}
break;
default:
break;
}
fprintf(cpu_trace_fp, "%s", "\n");
fflush(cpu_trace_fp);
}

View File

@ -96,5 +96,6 @@ extern const struct opcode_struct opcodes_6502[256];
extern const struct opcode_struct opcodes_65c02[256];
extern const struct opcode_struct opcodes_undoc[256];
extern const char* const disasm_templates[15];
extern const uint8_t opcodes_65c02_numargs[256];
#endif

View File

@ -814,3 +814,263 @@ const struct opcode_struct opcodes_undoc[256] =
{ "INC", addr_absolute_x },
{ "isb", addr_absolute_x },
};
const uint8_t opcodes_65c02_numargs[256] =
{
0, // 0x00
1,
0,
0,
1,
1,
1,
0,
0, // 0x08
1,
0,
0,
2,
2,
2,
0,
1, // 0x10
1,
1,
0,
1,
1,
1,
0,
0, // 0x18
2,
0,
0,
2,
2,
2,
0,
2, // 0x20
1,
0,
0,
1,
1,
1,
0,
0, // 0x28
1,
0,
0,
2,
2,
2,
0,
1, // 0x30
1,
1,
0,
1,
1,
1,
0,
0, // 0x38
2,
0,
0,
2,
2,
2,
0,
0, // 0x40
1,
0,
0,
0,
1,
1,
0,
0, // 0x48
1,
0,
0,
2,
2,
2,
0,
1, // 0x50
1,
1,
0,
0,
1,
1,
0,
0, // 0x58
2,
0,
0,
0,
2,
2,
0,
0, // 0x60
1,
0,
0,
1,
1,
1,
0,
0, // 0x68
1,
0,
0,
2,
2,
2,
0,
1, // 0x70
1,
1,
0,
1,
1,
1,
0,
0, // 0x78
2,
0,
0,
2,
2,
2,
0,
1, // 0x80
1,
0,
0,
1,
1,
1,
0,
0, // 0x88
1,
0,
0,
2,
2,
2,
0,
1, // 0x90
1,
1,
0,
1,
1,
1,
0,
0, // 0x98
2,
0,
0,
2,
2,
2,
0,
1, // 0xA0
1,
1,
0,
1,
1,
1,
0,
0, // 0xA8
1,
0,
0,
2,
2,
2,
0,
1, // 0xB0
1,
1,
0,
1,
1,
1,
0,
0, // 0xB8
2,
0,
0,
2,
2,
2,
0,
1, // 0xC0
1,
0,
0,
1,
1,
1,
0,
0, // 0xC8
1,
0,
0,
2,
2,
2,
0,
1, // 0xD0
1,
1,
0,
0,
1,
1,
0,
0, // 0xD8
2,
0,
0,
0,
2,
2,
0,
1, // 0xE0
1,
0,
0,
1,
1,
1,
0,
0, // 0xE8
1,
0,
0,
2,
2,
2,
0,
1, // 0xF0
1,
1,
0,
0,
1,
1,
0,
0, // 0xF8
2,
0,
0,
0,
2,
2,
0,
};

View File

@ -99,10 +99,10 @@ TEST test_boot_disk_bytes() {
PASS();
}
// This test is fairly abusive ... it creates an ~88MB file in $HOME
// This test is fairly abusive ... it creates an ~90MB file in $HOME
// ... but if it's correct, you're fairly assured the cpu/vm is working =)
#define EXPECTED_CPU_TRACE_FILE_SIZE 86057401
#define EXPECTED_CPU_TRACE_SHA "B6154D9DCC39EFD2AA69BEBF981E3024427F5240"
#define EXPECTED_CPU_TRACE_FILE_SIZE 89130253
#define EXPECTED_CPU_TRACE_SHA "2A86C5298CACBB1A894E91D41AA3061542286104"
TEST test_boot_disk_cputrace() {
char *homedir = getenv("HOME");
char *output = NULL;

View File

@ -193,8 +193,16 @@
/* Immediate Addressing - the operand is contained in the second byte of the
instruction. */
#define GetImm movLQ PC_Reg_X, EffectiveAddr_X; \
#define _GetImm movLQ PC_Reg_X, EffectiveAddr_X; \
incw PC_Reg;
#if CPU_TRACING
#define GetImm _GetImm \
SNX_PROLOGUE(cpu65_vmem_r); \
callLQ *SNX(cpu65_vmem_r,EffectiveAddr_X,SZ_PTR); \
TRACE_ARG;
#else
#define GetImm _GetImm
#endif
/* Absolute Addressing - the second byte of the instruction is the low
order address, and the third byte is the high order byte. */