diff --git a/src/mos6502.addr.c b/src/mos6502.addr.c index dd63c09..ba8bae7 100644 --- a/src/mos6502.addr.c +++ b/src/mos6502.addr.c @@ -12,6 +12,11 @@ #include "mos6502.h" #include "mos6502.enums.h" +/* + * This is a table of all the possible opcodes the 6502 understands, + * mapped to the correct address mode. (Well -- I _hope_ it's the + * correct address mode!) + */ static int addr_modes[] = { // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F IMP, IDX, NOA, NOA, NOA, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, NOA, ABS, ABS, NOA, // 0x @@ -39,9 +44,9 @@ static int addr_modes[] = { * cpu) that an instruction will use. */ mos6502_address_resolver -mos6502_get_address_resolver(int addr_mode) +mos6502_get_address_resolver(vm_8bit opcode) { - switch (addr_mode) { + switch (mos6502_addr_mode(opcode)) { case ACC: return mos6502_resolve_acc; case ABS: return mos6502_resolve_abs; case ABX: return mos6502_resolve_abx; diff --git a/src/mos6502.c b/src/mos6502.c index 649b622..c8fcc57 100644 --- a/src/mos6502.c +++ b/src/mos6502.c @@ -309,3 +309,47 @@ mos6502_get_instruction_handler(vm_8bit opcode) { return instruction_handlers[mos6502_instruction(opcode)]; } + +/* + * This code does the execution step that the 6502 processor would take, + * from soup to nuts. + */ +void +mos6502_execute(mos6502 *cpu, vm_8bit opcode) +{ + vm_8bit operand; + int cycles; + mos6502_address_resolver resolver; + mos6502_instruction_handler handler; + + // First, we need to know how to resolve our effective address and + // how to execute anything. + resolver = mos6502_get_address_resolver(opcode); + handler = mos6502_get_instruction_handler(opcode); + + // The operand is the effective operand, the value that the + // instruction handler cares about (if it cares about any such + // value). For example, the operand could be the literal value that + // you pass into an instruction via immediate mode. As a + // side-effect, resolver will set the last_addr field in cpu to the + // effective address where the operand can be found in memory, or + // zero if that does not apply (such as in immediate mode). + operand = resolver(cpu); + + // Here's where the magic happens. Whatever the instruction does, it + // happens in the handler function. + handler(cpu, operand); + + // This will be the number of cycles we should spend on the + // instruction. Of course, we can execute instructions pretty + // quickly in a modern architecture, but a lot of code was written + // with the idea that certain instructions -- in certain address + // modes -- were more expensive than others, and you want those + // programs to feel faster or slower in relation to that. + cycles = mos6502_cycles(cpu, opcode); + + // FIXME: actually emulate the cycles + + // Ok -- we're done! This wasn't so hard, was it? + return; +}