1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-12-21 23:29:16 +00:00

Add the execute function for the 6502

This executes a single opcode. Note this also makes a change to the
get_address_resolver function such that accepts an opcode, not the
address mode itself.
This commit is contained in:
Peter Evans 2017-12-05 19:01:43 -06:00
parent eaaf63a069
commit 5ada987c83
2 changed files with 51 additions and 2 deletions

View File

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

View File

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