From 7a61d1a214059a920e2d53fcae47513f1e2a7936 Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Sun, 29 Dec 2024 18:47:05 -0800 Subject: [PATCH] Simplify single-step stages --- e6502.c | 96 +++++++++++++++++++++++++++++++++------------------------ e6502.h | 3 +- 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/e6502.c b/e6502.c index 3ce93b2..28e49bb 100644 --- a/e6502.c +++ b/e6502.c @@ -926,17 +926,62 @@ static void e6502_nmi(e6502_Core* core) { core->registers.PC = e6502_r16(core, e6502_NMI_Vec); } +int e6502_step(e6502_Core* core) { + core->cycle = 0; + +#ifdef E6502_DEBUG + int last_pc = core->registers.PC; +#endif + + uint8_t opcode = e6502_r8(core, core->registers.PC); + const e6502_Instruction* instr = + &e6502_instructions[opcode]; + if (!instr->operator) { +#ifdef E6502_DEBUG + fprintf(stdout, "$%04x: $%02x\n", last_pc, opcode); +#endif + core->cycle = -1; + + } else { + core->registers.PC++; + e6502_Address adr = instr->address(core); +#ifdef E6502_DEBUG + uint16_t size = core->registers.PC - last_pc; + uint16_t val = 0; + if (size > 1) { + if (size == 2) val = e6502_r8(core, last_pc + 1); + else val = e6502_r16(core, last_pc + 1); + } + e6502_dump_regs(core, stdout); + fprintf(stdout, "$%04x: ", last_pc); + e6502_fprintf_instr(stdout, opcode, (uint8_t*)&val); + fputc('\n', stdout); +#endif + instr->operator(core, adr); + core->cycle += instr->cycles; + + if ( (core->pins & e6502_Pin_NMI) && + !(core->pins & e6502_NMI_Serviced)) { + core->pins |= e6502_NMI_Serviced; + e6502_nmi(core); + } else if ( (core->pins & e6502_Pin_IRQ) && + !(core->registers.P & e6502_Status_I)) { + e6502_irq(core); + } + } + + return core->cycle; +} int e6502_run(e6502_Core* core, int remaining, int* run, int instructions) { int status = 0; - int i_count = 0; - uint64_t start = (instructions ? i_count : core->cycle); - uint64_t end = start + remaining; + int count = 0; int last_pc = -1; - while ((instructions ? i_count : core->cycle) < end) { + (void)last_pc; + while (count < remaining) { #ifdef E6502_HCF if (core->registers.PC == last_pc) { // Trapped. @@ -945,51 +990,20 @@ int e6502_run(e6502_Core* core, } #endif last_pc = core->registers.PC; - (void)last_pc; - uint8_t opcode = e6502_r8(core, core->registers.PC); - const e6502_Instruction* instr = - &e6502_instructions[opcode]; - if (!instr->operator) { -#ifdef E6502_DEBUG - fprintf(stdout, "$%04x: $%02x\n", last_pc, opcode); -#endif - status = -1; + int cpu_cycles = e6502_step(core); + if (cpu_cycles <= 0) { + status = cpu_cycles; break; - } else { - core->registers.PC++; - e6502_Address adr = instr->address(core); -#ifdef E6502_DEBUG - uint16_t size = core->registers.PC - last_pc; - uint16_t val = 0; - if (size > 1) { - if (size == 2) val = e6502_r8(core, last_pc + 1); - else val = e6502_r16(core, last_pc + 1); - } - e6502_dump_regs(core, stdout); - fprintf(stdout, "$%04x: ", last_pc); - e6502_fprintf_instr(stdout, opcode, (uint8_t*)&val); - fputc('\n', stdout); -#endif - instr->operator(core, adr); - core->cycle += instr->cycles; - i_count++; - - if ( (core->pins & e6502_Pin_NMI) && - !(core->pins & e6502_NMI_Serviced)) { - core->pins |= e6502_NMI_Serviced; - e6502_nmi(core); - } else if ( (core->pins & e6502_Pin_IRQ) && - !(core->registers.P & e6502_Status_I)) { - e6502_irq(core); - } } + count += (instructions ? 1 : cpu_cycles); } if (run) { - *run = (instructions ? i_count : core->cycle) - start; + *run = count; } return status; } + #ifdef E6502_POLL_MEM void e6502_init(e6502_Core* core) { /* nuthin' */ } #else diff --git a/e6502.h b/e6502.h index ab865b7..98dc001 100644 --- a/e6502.h +++ b/e6502.h @@ -45,7 +45,7 @@ typedef struct { e6502_Write* bus_write; void* bus_context; #endif - uint64_t cycle; + int cycle; } e6502_Core; #define e6502_Memory_Stack (0x0100U) @@ -120,6 +120,7 @@ void e6502_init(e6502_Core*); void e6502_init(e6502_Core*, e6502_Read, e6502_Write, void*); #endif +int e6502_step(e6502_Core* core); int e6502_run(e6502_Core* core, int remaining, int* run,