From 23802b176f45cd589ccd1452c35351770828ac94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kujawa?= Date: Tue, 17 Jan 2017 14:29:20 +0100 Subject: [PATCH] Instruction set definition is now private to 65c02isa.c, has API. Minor refactoring while here, splitting stuff. --- src/65c02isa.c | 285 ++++++++++++++++++++++++++++++++++++++++++ src/65c02isa.h | 9 ++ src/Makefile | 2 +- src/instruction.c | 113 +++++++++++++++++ src/instruction.h | 42 +++++++ src/rk65c02.c | 105 +--------------- src/rk65c02.h | 312 +--------------------------------------------- 7 files changed, 457 insertions(+), 411 deletions(-) create mode 100644 src/65c02isa.c create mode 100644 src/65c02isa.h create mode 100644 src/instruction.c create mode 100644 src/instruction.h diff --git a/src/65c02isa.c b/src/65c02isa.c new file mode 100644 index 0000000..e8346e0 --- /dev/null +++ b/src/65c02isa.c @@ -0,0 +1,285 @@ +#include "bus.h" +#include "instruction.h" + +#include "65c02isa.h" + +#define OP_BRK 0x00 +#define OP_TSB_ZP 0x04 +#define OP_JSR 0x20 +#define OP_LDY_IMM 0xA0 +#define OP_STP 0xDB +#define OP_INX 0xE8 +#define OP_NOP 0xEA + +#define OP_UNIMPL 0xFF + +static const struct instrdef instrs[] = { + { OP_BRK, "brk", IMPLIED, 1 }, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_NOP, "nop", IMMEDIATE, 2}, /* inv */ + { OP_NOP, "nop", IMPLIED, 1}, /* inv */ + { OP_TSB_ZP, "tsb", ZP, 2}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_JSR, "jsr", ABSOLUTE, 3}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_LDY_IMM, "ldy", IMMEDIATE, 2}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_STP, "stp", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_INX, "inx", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_NOP, "nop", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpl", IMPLIED, 1}, + { OP_UNIMPL, "unimpllast", IMPLIED, 1} +}; + +instrdef_t +instrdef_get(uint8_t opcode) +{ + instrdef_t id; + + id = instrs[opcode]; + + return id; +} + diff --git a/src/65c02isa.h b/src/65c02isa.h new file mode 100644 index 0000000..20db0f3 --- /dev/null +++ b/src/65c02isa.h @@ -0,0 +1,9 @@ +#ifndef _65C02ISA_H_ +#define _65C02ISA_H_ + +#include + +instrdef_t instrdef_get(uint8_t); + +#endif /* _65C02ISA_H_ */ + diff --git a/src/Makefile b/src/Makefile index c778a24..24a0b53 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=rk65c02.o bus.o +OBJS=rk65c02.o bus.o instruction.o 65c02isa.o LIB_SO=librk65c02.so LIB_STATIC=librk65c02.a LDFLAGS=-shared diff --git a/src/instruction.c b/src/instruction.c new file mode 100644 index 0000000..420cce2 --- /dev/null +++ b/src/instruction.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include + +#include +#include + +#include "bus.h" +#include "65c02isa.h" +#include "instruction.h" + +instruction_t +instruction_fetch(bus_t *b, uint16_t addr) +{ + instruction_t i; + uint8_t op; + + op = bus_read_1(b, addr); + i.def = instrdef_get(op); + + assert(i.def.opcode != OP_UNIMPL); + + /* handle operands */ + switch (i.def.mode) { + case IMMEDIATE: + case ZP: + case ZPX: + case ZPY: + case IZP: + case IZPX: + case IZPY: + case RELATIVE: + i.op1 = bus_read_1(b, addr+1); + break; + case ABSOLUTE: + case ABSOLUTEX: + case ABSOLUTEY: + case IABSOLUTE: + case IABSOLUTEX: + i.op1 = bus_read_1(b, addr+1); + i.op2 = bus_read_1(b, addr+2); + break; + case IMPLIED: + default: + break; + } + + return i; +} + +void +instruction_print(instruction_t *i) +{ + switch (i->def.mode) { + case IMPLIED: + printf("%s", i->def.mnemonic); + break; + case IMMEDIATE: + printf("%s #%X", i->def.mnemonic, i->op1); + break; + case ZP: + printf("%s %X", i->def.mnemonic, i->op1); + break; + case ZPX: + printf("%s %X,X", i->def.mnemonic, i->op1); + break; + case ZPY: + printf("%s %X,Y", i->def.mnemonic, i->op1); + break; + case IZP: + printf("%s (%X)", i->def.mnemonic, i->op1); + break; + case IZPX: + printf("%s (%X,X)", i->def.mnemonic, i->op1); + break; + case IZPY: + printf("%s (%X),Y", i->def.mnemonic, i->op1); + break; + case ABSOLUTE: + printf("%s %02X%02X", i->def.mnemonic, i->op2, i->op1); + break; + case ABSOLUTEX: + printf("%s %02X%02X,X", i->def.mnemonic, i->op2, i->op1); + break; + case ABSOLUTEY: + printf("%s %02X%02X,Y", i->def.mnemonic, i->op2, i->op1); + break; + case IABSOLUTE: + printf("%s (%02X%02X)", i->def.mnemonic, i->op2, i->op1); + break; + case IABSOLUTEX: + printf("%s (%02X%02X,X)", i->def.mnemonic, i->op2, i->op1); + break; + case RELATIVE: + printf("%s %02X%02X", i->def.mnemonic, i->op2, i->op1); + break; + } +} + +void +disassemble(bus_t *b, uint16_t addr) +{ + instruction_t i; + + i = instruction_fetch(b, addr); + + printf("%X:\t", addr); + instruction_print(&i); + printf("\t\t// %X", i.def.opcode); + printf("\n"); +} + diff --git a/src/instruction.h b/src/instruction.h new file mode 100644 index 0000000..819f106 --- /dev/null +++ b/src/instruction.h @@ -0,0 +1,42 @@ +#ifndef _INSTRUCTION_H_ +#define _INSTRUCTION_H_ + +typedef enum { + IMPLIED, + IMMEDIATE, + ZP, + ZPX, + ZPY, + IZP, + IZPX, + IZPY, + RELATIVE, + ABSOLUTE, + ABSOLUTEX, + ABSOLUTEY, + IABSOLUTE, + IABSOLUTEX +} addressing_t; + +struct instrdef { + uint8_t opcode; + const char *mnemonic; + addressing_t mode; + uint8_t size; +}; + +typedef struct instrdef instrdef_t; + +struct instruction { + instrdef_t def; + uint8_t op1; + uint8_t op2; +}; + +typedef struct instruction instruction_t; + +instruction_t instruction_fetch(bus_t *, uint16_t); +void instruction_print(instruction_t *); +void disassemble(bus_t *, uint16_t); + +#endif /* _INSTRUCTION_H_ */ diff --git a/src/rk65c02.c b/src/rk65c02.c index 582eccc..d3658b6 100644 --- a/src/rk65c02.c +++ b/src/rk65c02.c @@ -6,111 +6,12 @@ #include #include -#include "rk65c02.h" #include "bus.h" +#include "instruction.h" +#include "rk65c02.h" static bool run = false; -instruction_t -instruction_fetch(bus_t *b, uint16_t addr) -{ - instruction_t i; - - i.opcode = bus_read_1(b, addr); - i.def = instrs[i.opcode]; - - assert(i.def.opcode != OP_UNIMPL); - - /* handle operands */ - switch (i.def.mode) { - case IMMEDIATE: - case ZP: - case ZPX: - case ZPY: - case IZP: - case IZPX: - case IZPY: - case RELATIVE: - i.op1 = bus_read_1(b, addr+1); - break; - case ABSOLUTE: - case ABSOLUTEX: - case ABSOLUTEY: - case IABSOLUTE: - case IABSOLUTEX: - i.op1 = bus_read_1(b, addr+1); - i.op2 = bus_read_1(b, addr+2); - break; - case IMPLIED: - default: - break; - } - - return i; -} - -void -instruction_print(instruction_t *i) -{ - switch (i->def.mode) { - case IMPLIED: - printf("%s", i->def.mnemonic); - break; - case IMMEDIATE: - printf("%s #%X", i->def.mnemonic, i->op1); - break; - case ZP: - printf("%s %X", i->def.mnemonic, i->op1); - break; - case ZPX: - printf("%s %X,X", i->def.mnemonic, i->op1); - break; - case ZPY: - printf("%s %X,Y", i->def.mnemonic, i->op1); - break; - case IZP: - printf("%s (%X)", i->def.mnemonic, i->op1); - break; - case IZPX: - printf("%s (%X,X)", i->def.mnemonic, i->op1); - break; - case IZPY: - printf("%s (%X),Y", i->def.mnemonic, i->op1); - break; - case ABSOLUTE: - printf("%s %02X%02X", i->def.mnemonic, i->op2, i->op1); - break; - case ABSOLUTEX: - printf("%s %02X%02X,X", i->def.mnemonic, i->op2, i->op1); - break; - case ABSOLUTEY: - printf("%s %02X%02X,Y", i->def.mnemonic, i->op2, i->op1); - break; - case IABSOLUTE: - printf("%s (%02X%02X)", i->def.mnemonic, i->op2, i->op1); - break; - case IABSOLUTEX: - printf("%s (%02X%02X,X)", i->def.mnemonic, i->op2, i->op1); - break; - case RELATIVE: - printf("%s %02X%02X", i->def.mnemonic, i->op2, i->op1); - break; - } -} - -void -disassemble(bus_t *b, uint16_t addr) -{ - instruction_t i; - - i = instruction_fetch(b, addr); - - printf("%X:\t", addr); - instruction_print(&i); - printf("\t\t// %X", i.opcode); - printf("\n"); -} - void rk6502_start(bus_t *b, uint16_t addr) { reg_state_t r; @@ -125,7 +26,7 @@ rk6502_start(bus_t *b, uint16_t addr) { //execute(i, r); - if (i.opcode == OP_STP) + if (i.def.opcode == 0xDB) // STP run = false; r.PC += i.def.size; diff --git a/src/rk65c02.h b/src/rk65c02.h index 803d59f..70815e0 100644 --- a/src/rk65c02.h +++ b/src/rk65c02.h @@ -1,22 +1,8 @@ #ifndef _RK6502_H_ #define _RK6502_H_ -typedef enum { - IMPLIED, - IMMEDIATE, - ZP, - ZPX, - ZPY, - IZP, - IZPX, - IZPY, - RELATIVE, - ABSOLUTE, - ABSOLUTEX, - ABSOLUTEY, - IABSOLUTE, - IABSOLUTEX -} addressing_t; +#include "bus.h" +#include "instruction.h" typedef enum { STOPPED, @@ -36,302 +22,12 @@ struct reg_state { typedef struct reg_state reg_state_t; -struct instrdef { - uint8_t opcode; - const char *mnemonic; - addressing_t mode; - uint8_t size; -}; - -typedef struct instrdef instrdef_t; - -struct instruction { - uint8_t opcode; - instrdef_t def; - uint8_t op1; - uint8_t op2; -}; - -typedef struct instruction instruction_t; - struct rk65c02emu { emu_state_t state; bus_t bus; reg_state_t regs; -} +}; typedef struct rk65c02emu rk65c02emu_t; -#define OP_BRK 0x00 -#define OP_TSB_ZP 0x04 -#define OP_JSR 0x20 -#define OP_LDY_IMM 0xA0 -#define OP_STP 0xDB -#define OP_INX 0xE8 -#define OP_NOP 0xEA - -#define OP_UNIMPL 0xFF - -const struct instrdef instrs[] = { - { OP_BRK, "brk", IMPLIED, 1 }, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_NOP, "nop", IMMEDIATE, 2}, /* inv */ - { OP_NOP, "nop", IMPLIED, 1}, /* inv */ - { OP_TSB_ZP, "tsb", ZP, 2}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_JSR, "jsr", ABSOLUTE, 3}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_LDY_IMM, "ldy", IMMEDIATE, 2}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_STP, "stp", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_INX, "inx", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_NOP, "nop", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpl", IMPLIED, 1}, - { OP_UNIMPL, "unimpllast", IMPLIED, 1} -}; - - -#endif /* _RK6502_H_ */ - +#endif