From a4b39966aed8d41ad4ddc6700683c4779e8d1cb2 Mon Sep 17 00:00:00 2001 From: vin Date: Sun, 30 Jun 2024 19:10:29 -0400 Subject: [PATCH] start refactoring opcode defs into an array --- cpu.c | 18 +----- cpu.h | 62 ++++++++++++++++++ opcodes.h | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+), 16 deletions(-) create mode 100644 cpu.h create mode 100644 opcodes.h diff --git a/cpu.c b/cpu.c index 0bbbc75..edfe172 100644 --- a/cpu.c +++ b/cpu.c @@ -4,6 +4,8 @@ #include #include +#include "cpu.h" +#include "opcodes.h" #include "rom.h" #define MAX(a, b) ((a > b) ? a : b) @@ -52,22 +54,6 @@ struct registers regs = {0}; struct Rom rom = {0}; -enum addressing_mode { - AM_ACC, - AM_IMPLICIT, - AM_IMM, - AM_ZP, - AM_ZP_X, - AM_ZP_Y, - AM_REL, - AM_ABS, - AM_ABS_X, - AM_ABS_Y, - AM_IND, - AM_IND_X, - AM_IND_Y, -}; - /* 64K address space, 16bit words */ uint8_t memory[0x16000]; diff --git a/cpu.h b/cpu.h new file mode 100644 index 0000000..139ad83 --- /dev/null +++ b/cpu.h @@ -0,0 +1,62 @@ +#include + +void ADC(uint16_t arg); +void AND(uint16_t arg); +void ASL_acc(uint16_t arg); +void ASL(uint16_t arg); +void BCC(uint16_t arg); +void BCS(uint16_t arg); +void BEQ(uint16_t arg); +void BIT(uint16_t arg); +void BMI(uint16_t arg); +void BNE(uint16_t arg); +void BPL(uint16_t arg); +void BRK(uint16_t arg); +void BVC(uint16_t arg); +void BVS(uint16_t arg); +void CLC(uint16_t arg); +void CLD(uint16_t arg); +void CLI(uint16_t arg); +void CLV(uint16_t arg); +void CMP(uint16_t arg); +void CPX(uint16_t arg); +void CPY(uint16_t arg); +void DEC(uint16_t arg); +void DEX(uint16_t arg); +void DEY(uint16_t arg); +void EOR(uint16_t arg); +void INC(uint16_t arg); +void INX(uint16_t arg); +void INY(uint16_t arg); +void JMP(uint16_t arg); +void JSR(uint16_t arg); +void LDA(uint16_t arg); +void LDX(uint16_t arg); +void LDY(uint16_t arg); +void LSR_acc(uint16_t arg); +void LSR(uint16_t arg); +void NOP(uint16_t arg); +void ORA(uint16_t arg); +void PHA(uint16_t arg); +void PHP(uint16_t arg); +void PLA(uint16_t arg); +void PLP(uint16_t arg); +void ROL_acc(uint16_t arg); +void ROL(uint16_t arg); +void ROR_acc(uint16_t arg); +void ROR(uint16_t arg); +void RTI(uint16_t arg); +void RTS(uint16_t arg); +void SBC(uint16_t arg); +void SEC(uint16_t arg); +void SED(uint16_t arg); +void SEI(uint16_t arg); +void STA(uint16_t arg); +void STX(uint16_t arg); +void STY(uint16_t arg); +void TAX(uint16_t arg); +void TAY(uint16_t arg); +void TSX(uint16_t arg); +void TXA(uint16_t arg); +void TXS(uint16_t arg); +void TYA(uint16_t arg); diff --git a/opcodes.h b/opcodes.h new file mode 100644 index 0000000..defc427 --- /dev/null +++ b/opcodes.h @@ -0,0 +1,184 @@ +#include + +#include "cpu.h" + +enum addressing_mode { + AM_NONE, + AM_ACC, + AM_IMM, + AM_REL, + AM_ZP, + AM_ZP_X, + AM_ZP_Y, + AM_ABS, + AM_ABS_X, + AM_ABS_Y, + AM_IND, + AM_IND_X, + AM_IND_Y, +}; + +/* index of below array is the code of the instruction */ +struct opcode { + const char name[4]; + /* I know 16bit seems wasteful, but some ops use 16bit memory as arg */ + void (*instr)(uint16_t arg); + uint8_t bytes; + uint8_t cycles; + enum addressing_mode mode; +}; + +struct opcode opcodes[0x100] = { + /* official opcodes */ + [0x69] = { "ADC", ADC, 2, 2, AM_IMM }, + [0x65] = { "ADC", ADC, 2, 3, AM_ZP }, + [0x75] = { "ADC", ADC, 2, 4, AM_ZP_X }, + [0x6D] = { "ADC", ADC, 3, 4, AM_ABS }, + [0x7D] = { "ADC", ADC, 3, 4, AM_ABS_X }, + [0x79] = { "ADC", ADC, 3, 4, AM_ABS_Y }, + [0x61] = { "ADC", ADC, 2, 6, AM_IND_X }, + [0x71] = { "ADC", ADC, 2, 5, AM_IND_Y }, + [0x29] = { "AND", AND, 2, 2, AM_IMM }, + [0x25] = { "AND", AND, 2, 3, AM_ZP }, + [0x35] = { "AND", AND, 2, 4, AM_ZP_X }, + [0x2D] = { "AND", AND, 3, 4, AM_ABS }, + [0x3D] = { "AND", AND, 3, 4, AM_ABS_X }, + [0x39] = { "AND", AND, 3, 4, AM_ABS_Y }, + [0x21] = { "AND", AND, 2, 6, AM_IND_X }, + [0x31] = { "AND", AND, 2, 5, AM_IND_Y }, + [0x0A] = { "ASL", ASL_acc, 1, 2, AM_ACC }, + [0x06] = { "ASL", ASL, 2, 5, AM_ZP }, + [0x16] = { "ASL", ASL, 2, 6, AM_ZP_X }, + [0x0E] = { "ASL", ASL, 3, 6, AM_ABS }, + [0x1E] = { "ASL", ASL, 3, 7, AM_ABS_X }, + [0x90] = { "BCC", BCC, 2, 2, AM_REL }, + [0xB0] = { "BCS", BCS, 2, 2, AM_REL }, + [0xF0] = { "BEQ", BEQ, 2, 2, AM_REL }, + [0x24] = { "BIT", BIT, 2, 3, AM_ZP }, + [0x2C] = { "BIT", BIT, 3, 4, AM_ABS }, + [0x30] = { "BMI", BMI, 2, 2, AM_REL }, + [0xD0] = { "BNE", BNE, 2, 2, AM_REL }, + [0x10] = { "BPL", BPL, 2, 2, AM_REL }, + [0x00] = { "BRK", BRK, 1, 7, AM_NONE }, + [0x50] = { "BVC", BVC, 2, 2, AM_REL }, + [0x70] = { "BVS", BVS, 2, 2, AM_REL }, + [0x18] = { "CLC", CLC, 1, 2, AM_NONE }, + [0xD8] = { "CLD", CLD, 1, 2, AM_NONE }, + [0x58] = { "CLI", CLI, 1, 2, AM_NONE }, + [0xB8] = { "CLV", CLV, 1, 2, AM_NONE }, + [0xC9] = { "CMP", CMP, 2, 2, AM_IMM }, + [0xC5] = { "CMP", CMP, 2, 3, AM_ZP }, + [0xD5] = { "CMP", CMP, 2, 4, AM_ZP_X }, + [0xCD] = { "CMP", CMP, 3, 4, AM_ABS }, + [0xDD] = { "CMP", CMP, 3, 4, AM_ABS_X }, + [0xD9] = { "CMP", CMP, 3, 4, AM_ABS_Y }, + [0xC1] = { "CMP", CMP, 2, 6, AM_IND_X }, + [0xD1] = { "CMP", CMP, 2, 5, AM_IND_Y }, + [0xE0] = { "CPX", CPX, 2, 2, AM_IMM }, + [0xE4] = { "CPX", CPX, 2, 3, AM_ZP }, + [0xEC] = { "CPX", CPX, 3, 4, AM_ABS }, + [0xC0] = { "CPY", CPY, 2, 2, AM_IMM }, + [0xC4] = { "CPY", CPY, 2, 3, AM_ZP }, + [0xCC] = { "CPY", CPY, 3, 4, AM_ABS }, + [0xC6] = { "DEC", DEC, 2, 5, AM_ZP }, + [0xD6] = { "DEC", DEC, 2, 6, AM_ZP_X }, + [0xCE] = { "DEC", DEC, 3, 6, AM_ABS }, + [0xDE] = { "DEC", DEC, 3, 7, AM_ABS_X }, + [0xCA] = { "DEX", DEX, 1, 2, AM_NONE }, + [0x88] = { "DEY", DEY, 1, 2, AM_NONE }, + [0x49] = { "EOR", EOR, 2, 2, AM_IMM }, + [0x45] = { "EOR", EOR, 2, 3, AM_ZP }, + [0x55] = { "EOR", EOR, 2, 4, AM_ZP_X }, + [0x4D] = { "EOR", EOR, 3, 4, AM_ABS }, + [0x5D] = { "EOR", EOR, 3, 4, AM_ABS_X }, + [0x59] = { "EOR", EOR, 3, 4, AM_ABS_Y }, + [0x41] = { "EOR", EOR, 2, 6, AM_IND_X }, + [0x51] = { "EOR", EOR, 2, 5, AM_IND_Y }, + [0xE6] = { "INC", INC, 2, 5, AM_ZP }, + [0xF6] = { "INC", INC, 2, 6, AM_ZP_X }, + [0xEE] = { "INC", INC, 3, 6, AM_ABS }, + [0xFE] = { "INC", INC, 3, 7, AM_ABS_X }, + [0xE8] = { "INX", INX, 1, 2, AM_NONE }, + [0xC8] = { "INY", INY, 1, 2, AM_NONE }, + [0x4C] = { "JMP", JMP, 3, 3, AM_ABS }, + [0x6C] = { "JMP", JMP, 3, 5, AM_IND }, + [0x20] = { "JSR", JSR, 3, 6, AM_ABS }, + [0xA9] = { "LDA", LDA, 2, 2, AM_IMM }, + [0xA5] = { "LDA", LDA, 2, 3, AM_ZP }, + [0xB5] = { "LDA", LDA, 2, 4, AM_ZP_X }, + [0xAD] = { "LDA", LDA, 3, 4, AM_ABS }, + [0xBD] = { "LDA", LDA, 3, 4, AM_ABS_X }, + [0xB9] = { "LDA", LDA, 3, 4, AM_ABS_Y }, + [0xA1] = { "LDA", LDA, 2, 6, AM_IND_X }, + [0xB1] = { "LDA", LDA, 2, 5, AM_IND_Y }, + [0xA2] = { "LDX", LDX, 2, 2, AM_IMM }, + [0xA6] = { "LDX", LDX, 2, 3, AM_ZP }, + [0xB6] = { "LDX", LDX, 2, 4, AM_ZP_Y }, + [0xAE] = { "LDX", LDX, 3, 4, AM_ABS }, + [0xBE] = { "LDX", LDX, 3, 4, AM_ABS_Y }, + [0xA0] = { "LDY", LDY, 2, 2, AM_IMM }, + [0xA4] = { "LDY", LDY, 2, 3, AM_ZP }, + [0xB4] = { "LDY", LDY, 2, 4, AM_ZP_X }, + [0xAC] = { "LDY", LDY, 3, 4, AM_ABS }, + [0xBC] = { "LDY", LDY, 3, 4, AM_ABS_X }, + [0x4A] = { "LSR", LSR_acc, 1, 2, AM_ACC }, + [0x46] = { "LSR", LSR, 2, 5, AM_ZP }, + [0x56] = { "LSR", LSR, 2, 6, AM_ZP_X }, + [0x4E] = { "LSR", LSR, 3, 6, AM_ABS }, + [0x5E] = { "LSR", LSR, 3, 7, AM_ABS_X }, + [0xEA] = { "NOP", NOP, 1, 2, AM_NONE }, + [0x09] = { "ORA", ORA, 2, 2, AM_IMM }, + [0x05] = { "ORA", ORA, 2, 3, AM_ZP }, + [0x15] = { "ORA", ORA, 2, 4, AM_ZP_X }, + [0x0D] = { "ORA", ORA, 3, 4, AM_ABS }, + [0x1D] = { "ORA", ORA, 3, 4, AM_ABS_X }, + [0x19] = { "ORA", ORA, 3, 4, AM_ABS_Y }, + [0x01] = { "ORA", ORA, 2, 6, AM_IND_X }, + [0x11] = { "ORA", ORA, 2, 5, AM_IND_Y }, + [0x48] = { "PHA", PHA, 1, 3, AM_NONE }, + [0x08] = { "PHP", PHP, 1, 3, AM_NONE }, + [0x68] = { "PLA", PLA, 1, 4, AM_NONE }, + [0x28] = { "PLP", PLP, 1, 4, AM_NONE }, + [0x2A] = { "ROL", ROL_acc, 1, 2, AM_ACC }, + [0x26] = { "ROL", ROL, 2, 5, AM_ZP }, + [0x36] = { "ROL", ROL, 2, 6, AM_ZP_X }, + [0x2E] = { "ROL", ROL, 3, 6, AM_ABS }, + [0x3E] = { "ROL", ROL, 3, 7, AM_ABS_X }, + [0x6A] = { "ROR", ROR_acc, 1, 2, AM_ACC }, + [0x66] = { "ROR", ROR, 2, 5, AM_ZP }, + [0x76] = { "ROR", ROR, 2, 6, AM_ZP_X }, + [0x6E] = { "ROR", ROR, 3, 6, AM_ABS }, + [0x7E] = { "ROR", ROR, 3, 7, AM_ABS_X }, + [0x40] = { "RTI", RTI, 1, 6, AM_NONE }, + [0x60] = { "RTS", RTS, 1, 6, AM_NONE }, + [0xE9] = { "SBC", SBC, 2, 2, AM_IMM }, + [0xE5] = { "SBC", SBC, 2, 3, AM_ZP }, + [0xF5] = { "SBC", SBC, 2, 4, AM_ZP_X }, + [0xED] = { "SBC", SBC, 3, 4, AM_ABS }, + [0xFD] = { "SBC", SBC, 3, 4, AM_ABS_X }, + [0xF9] = { "SBC", SBC, 3, 4, AM_ABS_Y }, + [0xE1] = { "SBC", SBC, 2, 6, AM_IND_X }, + [0xF1] = { "SBC", SBC, 2, 5, AM_IND_Y }, + [0x38] = { "SEC", SEC, 1, 2, AM_NONE }, + [0xF8] = { "SED", SED, 1, 2, AM_NONE }, + [0x78] = { "SEI", SEI, 1, 2, AM_NONE }, + [0x85] = { "STA", STA, 2, 3, AM_ZP }, + [0x95] = { "STA", STA, 2, 4, AM_ZP_X }, + [0x8D] = { "STA", STA, 3, 4, AM_ABS }, + [0x9D] = { "STA", STA, 3, 5, AM_ABS_X }, + [0x99] = { "STA", STA, 3, 5, AM_ABS_Y }, + [0x81] = { "STA", STA, 2, 6, AM_IND_X }, + [0x91] = { "STA", STA, 2, 6, AM_IND_Y }, + [0x86] = { "STX", STX, 2, 3, AM_ZP }, + [0x96] = { "STX", STX, 2, 4, AM_ZP_Y }, + [0x8E] = { "STX", STX, 3, 4, AM_ABS }, + [0x84] = { "STY", STY, 2, 3, AM_ZP }, + [0x94] = { "STY", STY, 2, 4, AM_ZP_X }, + [0x8C] = { "STY", STY, 3, 4, AM_ABS }, + [0xAA] = { "TAX", TAX, 1, 2, AM_NONE }, + [0xA8] = { "TAY", TAY, 1, 2, AM_NONE }, + [0xBA] = { "TSX", TSX, 1, 2, AM_NONE }, + [0x8A] = { "TXA", TXA, 1, 2, AM_NONE }, + [0x9A] = { "TXS", TXS, 1, 2, AM_NONE }, + [0x98] = { "TYA", TYA, 1, 2, AM_NONE }, +};