Browse Source

Simplify single-step stages

master
Nathaniel Walizer 11 months ago
parent
commit
7a61d1a214
2 changed files with 57 additions and 42 deletions
  1. +55
    -41
      e6502.c
  2. +2
    -1
      e6502.h

+ 55
- 41
e6502.c View File

@@ -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


+ 2
- 1
e6502.h View File

@@ -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,


Loading…
Cancel
Save