diff --git a/src/cpu-supp.c b/src/cpu-supp.c index c70dd676..5e968e3d 100644 --- a/src/cpu-supp.c +++ b/src/cpu-supp.c @@ -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); } diff --git a/src/meta/debug.h b/src/meta/debug.h index 663c4881..1a9d78a5 100644 --- a/src/meta/debug.h +++ b/src/meta/debug.h @@ -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 diff --git a/src/meta/opcodes.c b/src/meta/opcodes.c index 2055510d..a9cc2e9a 100644 --- a/src/meta/opcodes.c +++ b/src/meta/opcodes.c @@ -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, +}; diff --git a/src/test/testvm.c b/src/test/testvm.c index c1525245..f16ea4fe 100644 --- a/src/test/testvm.c +++ b/src/test/testvm.c @@ -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; diff --git a/src/x86/cpu.S b/src/x86/cpu.S index e94b0a88..b26833ba 100644 --- a/src/x86/cpu.S +++ b/src/x86/cpu.S @@ -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. */