nesemu/cpu/op.c

531 lines
12 KiB
C
Raw Normal View History

2023-10-05 17:05:06 -04:00
#include "../include/cpu/op.h"
// Reference: https://www.nesdev.org/wiki/CPU_unofficial_opcodes
#define IS_OP_CODE_MODE(op, op_code, addr_mode) \
case op_code: \
op_ ## op(ADDR_MODE_ ## addr_mode); \
break;
#define IS_OP_CODE(op, op_code) \
IS_OP_CODE_MODE(op, op_code, IMPLICIT)
#define IS_ALU_OP_CODE_(op, offset, addr_mode) \
IS_OP_CODE_MODE(op, OP_CODE_BASE_ ## op + offset, addr_mode)
#define IS_ALU_OP_CODE(op) \
IS_ALU_OP_CODE_(op, 0x01, INDEXED_INDIRECT) \
IS_ALU_OP_CODE_(op, 0x05, ZERO_PAGE) \
IS_ALU_OP_CODE_(op, 0x09, IMMEDIATE) \
IS_ALU_OP_CODE_(op, 0x0d, ABSOLUTE) \
IS_ALU_OP_CODE_(op, 0x11, INDIRECT_INDEXED) \
IS_ALU_OP_CODE_(op, 0x15, ZERO_PAGE_INDEXED_X) \
IS_ALU_OP_CODE_(op, 0x19, ABSOLUTE_INDEXED_Y) \
IS_ALU_OP_CODE_(op, 0x1d, ABSOLUTE_INDEXED_X)
#define IS_ALU_OP_CODE_NO_IMMEDIATE(op) \
IS_ALU_OP_CODE_(op, 0x01, INDEXED_INDIRECT) \
IS_ALU_OP_CODE_(op, 0x05, ZERO_PAGE) \
IS_ALU_OP_CODE_(op, 0x0d, ABSOLUTE) \
IS_ALU_OP_CODE_(op, 0x11, INDIRECT_INDEXED) \
IS_ALU_OP_CODE_(op, 0x15, ZERO_PAGE_INDEXED_X) \
IS_ALU_OP_CODE_(op, 0x19, ABSOLUTE_INDEXED_Y) \
IS_ALU_OP_CODE_(op, 0x1d, ABSOLUTE_INDEXED_X)
#define IS_RMW_OP_CODE_(op, line, offset, addr_mode) \
IS_OP_CODE_MODE(op, OP_CODE_BASE_ ## line + offset, addr_mode)
#define IS_RMW_OP_CODE(op, line) \
IS_RMW_OP_CODE_(op, line, 0x06, ZERO_PAGE) \
IS_RMW_OP_CODE_(op, line, 0x0a, IMPLICIT) \
IS_RMW_OP_CODE_(op, line, 0x0e, ABSOLUTE) \
IS_RMW_OP_CODE_(op, line, 0x16, ZERO_PAGE_INDEXED_X) \
IS_RMW_OP_CODE_(op, line, 0x1e, ABSOLUTE_INDEXED_X)
#define IS_UNOFFICIAL_OP_CODE_(op, line, offset, addr_mode) \
IS_OP_CODE_MODE(op, OP_CODE_BASE_ ## line + offset, addr_mode)
#define IS_UNOFFICIAL_OP_CODE(op, line) \
IS_UNOFFICIAL_OP_CODE_(op, line, 0x03, INDEXED_INDIRECT) \
IS_UNOFFICIAL_OP_CODE_(op, line, 0x07, ZERO_PAGE) \
IS_UNOFFICIAL_OP_CODE_(op, line, 0x0f, ABSOLUTE) \
IS_UNOFFICIAL_OP_CODE_(op, line, 0x13, INDIRECT_INDEXED) \
IS_UNOFFICIAL_OP_CODE_(op, line, 0x17, ZERO_PAGE_INDEXED_X) \
IS_UNOFFICIAL_OP_CODE_(op, line, 0x1b, ABSOLUTE_INDEXED_Y) \
IS_UNOFFICIAL_OP_CODE_(op, line, 0x1f, ABSOLUTE_INDEXED_X)
void op_ADC(addr_mode_t addr_mode) {
}
/* === CTRL === */
void op_BRK(addr_mode_t addr_mode) {
}
void op_BPL(addr_mode_t addr_mode) {
}
void op_BIT(addr_mode_t addr_mode) {
}
void op_BMI(addr_mode_t addr_mode) {
}
void op_BVC(addr_mode_t addr_mode) {
}
void op_BVS(addr_mode_t addr_mode) {
}
void op_BCC(addr_mode_t addr_mode) {
}
void op_BCS(addr_mode_t addr_mode) {
}
void op_BNE(addr_mode_t addr_mode) {
}
void op_BEQ(addr_mode_t addr_mode) {
}
void op_PHP(addr_mode_t addr_mode) {
}
void op_CLC(addr_mode_t addr_mode) {
}
void op_JSR(addr_mode_t addr_mode) {
}
void op_PLP(addr_mode_t addr_mode) {
}
void op_SEC(addr_mode_t addr_mode) {
}
void op_RTI(addr_mode_t addr_mode) {
}
void op_PHA(addr_mode_t addr_mode) {
}
void op_JMP(addr_mode_t addr_mode) {
}
void op_CLI(addr_mode_t addr_mode) {
}
void op_RTS(addr_mode_t addr_mode) {
}
void op_PLA(addr_mode_t addr_mode) {
}
void op_SEI(addr_mode_t addr_mode) {
}
void op_STY(addr_mode_t addr_mode) {
}
void op_DEY(addr_mode_t addr_mode) {
}
void op_TYA(addr_mode_t addr_mode) {
}
void op_LDY(addr_mode_t addr_mode) {
}
void op_TAY(addr_mode_t addr_mode) {
}
void op_CLV(addr_mode_t addr_mode) {
}
void op_CPY(addr_mode_t addr_mode) {
}
void op_INY(addr_mode_t addr_mode) {
}
void op_CLD(addr_mode_t addr_mode) {
}
void op_CPX(addr_mode_t addr_mode) {
}
void op_INX(addr_mode_t addr_mode) {
}
void op_SED(addr_mode_t addr_mode) {
}
/* === ALU === */
void op_ORA(addr_mode_t addr_mode) {
}
void op_AND(addr_mode_t addr_mode) {
}
void op_EOR(addr_mode_t addr_mode) {
}
void op_ADC(addr_mode_t addr_mode) {
}
void op_STA(addr_mode_t addr_mode) {
}
void op_LDA(addr_mode_t addr_mode) {
}
void op_CMP(addr_mode_t addr_mode) {
}
void op_SBC(addr_mode_t addr_mode) {
}
void op_NOP(addr_mode_t addr_mode) {
}
/* RMW */
void op_ASL(addr_mode_t addr_mode) {
}
void op_ROL(addr_mode_t addr_mode) {
}
void op_LSR(addr_mode_t addr_mode) {
}
void op_ROR(addr_mode_t addr_mode) {
}
void op_STX(addr_mode_t addr_mode) {
}
void op_TXA(addr_mode_t addr_mode) {
}
void op_TXS(addr_mode_t addr_mode) {
}
void op_SHX(addr_mode_t addr_mode) {
}
void op_LDX(addr_mode_t addr_mode) {
}
void op_TAX(addr_mode_t addr_mode) {
}
void op_TSX(addr_mode_t addr_mode) {
}
void op_DEC(addr_mode_t addr_mode) {
}
void op_DEX(addr_mode_t addr_mode) {
}
void op_INC(addr_mode_t addr_mode) {
}
// Unofficial
void op_STP(addr_mode_t addr_mode) {
}
void op_SHY(addr_mode_t addr_mode) {
}
void op_SLO(addr_mode_t addr_mode) {
}
void op_RLA(addr_mode_t addr_mode) {
}
void op_SRE(addr_mode_t addr_mode) {
}
void op_RRA(addr_mode_t addr_mode) {
}
void op_SAX(addr_mode_t addr_mode) {
}
void op_LAX(addr_mode_t addr_mode) {
}
void op_DCP(addr_mode_t addr_mode) {
}
void op_ISC(addr_mode_t addr_mode) {
}
void op_ANC(addr_mode_t addr_mode) {
}
void op_ALR(addr_mode_t addr_mode) {
}
void op_ARR(addr_mode_t addr_mode) {
}
void op_XAA(addr_mode_t addr_mode) {
}
void op_AXS(addr_mode_t addr_mode) {
}
void op_AHX(addr_mode_t addr_mode) {
}
void op_TAS(addr_mode_t addr_mode) {
}
void process_op_code(int op) {
switch (op) {
// CTRL
IS_OP_CODE(BRK, 0x00)
IS_OP_CODE(PHP, 0x08)
IS_OP_CODE(CLC, 0x18)
IS_OP_CODE(PLP, 0x28)
IS_OP_CODE(SEC, 0x38)
IS_OP_CODE(RTI, 0x40)
IS_OP_CODE(PHA, 0x48)
IS_OP_CODE(CLI, 0x58)
IS_OP_CODE(RTS, 0x60)
IS_OP_CODE(PLA, 0x68)
IS_OP_CODE(SEI, 0x78)
IS_OP_CODE(DEY, 0x88)
IS_OP_CODE(TYA, 0x98)
IS_OP_CODE(TAY, 0xa8)
IS_OP_CODE(CLV, 0xb8)
IS_OP_CODE(INY, 0xc8)
IS_OP_CODE(CLD, 0xd8)
IS_OP_CODE(INX, 0xe8)
IS_OP_CODE(SED, 0xf8)
IS_OP_CODE_MODE(JSR, 0x20, ABSOLUTE)
IS_OP_CODE_MODE(BIT, 0x24, ZERO_PAGE)
IS_OP_CODE_MODE(BIT, 0x2c, ABSOLUTE)
IS_OP_CODE_MODE(JMP, 0x4c, ABSOLUTE)
IS_OP_CODE_MODE(JMP, 0x6c, ABSOLUTE_JUMP)
IS_OP_CODE_MODE(STY, 0x84, ZERO_PAGE)
IS_OP_CODE_MODE(STY, 0x8c, ABSOLUTE)
IS_OP_CODE_MODE(STY, 0x94, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(SHY, 0x9c, ABSOLUTE_INDEXED_X)
IS_OP_CODE_MODE(LDY, 0xa0, IMMEDIATE)
IS_OP_CODE_MODE(LDY, 0xa4, ZERO_PAGE)
IS_OP_CODE_MODE(LDY, 0xac, ABSOLUTE)
IS_OP_CODE_MODE(LDY, 0xb4, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(LDY, 0xbc, ABSOLUTE_INDEXED_X)
IS_OP_CODE_MODE(CPY, 0xc0, IMMEDIATE)
IS_OP_CODE_MODE(CPY, 0xc4, ZERO_PAGE)
IS_OP_CODE_MODE(CPY, 0xcc, ABSOLUTE)
IS_OP_CODE_MODE(CPX, 0xe0, IMMEDIATE)
IS_OP_CODE_MODE(CPX, 0xe4, ZERO_PAGE)
IS_OP_CODE_MODE(CPX, 0xec, ABSOLUTE)
IS_OP_CODE_MODE(BPL, 0x10, RELATIVE)
IS_OP_CODE_MODE(BMI, 0x30, RELATIVE)
IS_OP_CODE_MODE(BVC, 0x50, RELATIVE)
IS_OP_CODE_MODE(BVS, 0x70, RELATIVE)
IS_OP_CODE_MODE(BCC, 0x90, RELATIVE)
IS_OP_CODE_MODE(BCS, 0xb0, RELATIVE)
IS_OP_CODE_MODE(BNE, 0xd0, RELATIVE)
IS_OP_CODE_MODE(BEQ, 0xf0, RELATIVE)
IS_OP_CODE_MODE(NOP, 0x04, ZERO_PAGE)
IS_OP_CODE_MODE(NOP, 0x0c, ABSOLUTE)
IS_OP_CODE_MODE(NOP, 0x14, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x1c, ABSOLUTE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x34, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x3c, ABSOLUTE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x44, ZERO_PAGE)
IS_OP_CODE_MODE(NOP, 0x54, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x5c, ABSOLUTE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x64, ZERO_PAGE)
IS_OP_CODE_MODE(NOP, 0x74, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x7c, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0x80, IMMEDIATE)
IS_OP_CODE_MODE(NOP, 0xd4, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0xdc, ABSOLUTE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0xf4, ZERO_PAGE_INDEXED_X)
IS_OP_CODE_MODE(NOP, 0xfc, ABSOLUTE_INDEXED_X)
// ALU
IS_ALU_OP_CODE(ORA)
IS_ALU_OP_CODE(AND)
IS_ALU_OP_CODE(EOR)
IS_ALU_OP_CODE(ADC)
IS_ALU_OP_CODE_NO_IMMEDIATE(STA)
IS_ALU_OP_CODE(LDA)
IS_ALU_OP_CODE(CMP)
IS_ALU_OP_CODE(SBC)
// RMW
IS_RMW_OP_CODE(ASL, ORA)
IS_RMW_OP_CODE(ROL, AND)
IS_RMW_OP_CODE(LSR, EOR)
IS_RMW_OP_CODE(ROR, ADC)
IS_OP_CODE(STP, 0x02)
IS_OP_CODE(STP, 0x12)
IS_OP_CODE(NOP, 0x1a)
IS_OP_CODE(STP, 0x22)
IS_OP_CODE(STP, 0x32)
IS_OP_CODE(NOP, 0x3a)
IS_OP_CODE(STP, 0x42)
IS_OP_CODE(STP, 0x52)
IS_OP_CODE(NOP, 0x5a)
IS_OP_CODE(STP, 0x62)
IS_OP_CODE(STP, 0x72)
IS_OP_CODE(NOP, 0x7a)
IS_OP_CODE_MODE(NOP, 0x82, IMMEDIATE)
IS_OP_CODE_MODE(STX, 0x86, ZERO_PAGE)
IS_OP_CODE(TXA, 0x8a)
IS_OP_CODE_MODE(STX, 0x8e, ABSOLUTE)
IS_OP_CODE(STP, 0x92)
IS_OP_CODE_MODE(STX, 0x96, ZERO_PAGE_INDEXED_Y)
IS_OP_CODE(TSX, 0x9a)
IS_OP_CODE_MODE(SHX, 0x9e, ABSOLUTE_INDEXED_Y)
IS_OP_CODE_MODE(LDX, 0xa2, IMMEDIATE)
IS_OP_CODE_MODE(LDX, 0xa6, ZERO_PAGE)
IS_OP_CODE(TAX, 0xaa)
IS_OP_CODE_MODE(LDX, 0xae, ABSOLUTE)
IS_OP_CODE(STP, 0xb2)
IS_OP_CODE_MODE(LDX, 0xb6, ZERO_PAGE_INDEXED_Y)
IS_OP_CODE(TSX, 0xba)
IS_OP_CODE_MODE(LDX, 0xbe, ABSOLUTE_INDEXED_Y)
IS_OP_CODE_MODE(NOP, 0xc2, IMMEDIATE)
IS_OP_CODE_MODE(DEC, 0xc6, ZERO_PAGE)
IS_OP_CODE(DEX, 0xca)
IS_OP_CODE_MODE(DEC, 0xce, ABSOLUTE)
IS_OP_CODE(STP, 0xd2)
IS_OP_CODE_MODE(DEC, 0xd6, ZERO_PAGE_INDEXED_Y)
IS_OP_CODE(NOP, 0xda)
IS_OP_CODE_MODE(DEC, 0xde, ABSOLUTE_INDEXED_Y)
IS_OP_CODE_MODE(NOP, 0xe2, IMMEDIATE)
IS_OP_CODE_MODE(INC, 0xe6, ZERO_PAGE)
IS_OP_CODE(NOP, 0xea) // The official NOP
IS_OP_CODE_MODE(INC, 0xee, ABSOLUTE)
IS_OP_CODE(STP, 0xf2)
IS_OP_CODE_MODE(INC, 0xf6, ZERO_PAGE_INDEXED_Y)
IS_OP_CODE(NOP, 0xfa)
IS_OP_CODE_MODE(INC, 0xfe, ABSOLUTE_INDEXED_X)
// Unofficial
IS_UNOFFICIAL_OP_CODE(SLO, ORA)
IS_UNOFFICIAL_OP_CODE(RLA, AND)
IS_UNOFFICIAL_OP_CODE(SRE, EOR)
IS_UNOFFICIAL_OP_CODE(RRA, ADC)
IS_UNOFFICIAL_OP_CODE(DCP, CMP)
IS_UNOFFICIAL_OP_CODE(ISC, SBC)
IS_OP_CODE_MODE(ANC, 0x0b, IMMEDIATE)
IS_OP_CODE_MODE(ANC, 0x2b, IMMEDIATE)
IS_OP_CODE_MODE(ALR, 0x4b, IMMEDIATE)
IS_OP_CODE_MODE(ARR, 0x6b, IMMEDIATE)
IS_OP_CODE_MODE(AXS, 0xcb, IMMEDIATE)
IS_OP_CODE_MODE(SBC, 0xeb, IMMEDIATE)
IS_OP_CODE_MODE(SAX, 0x83, INDEXED_INDIRECT)
IS_OP_CODE_MODE(SAX, 0x87, ZERO_PAGE)
IS_OP_CODE_MODE(XAA, 0x8b, IMMEDIATE)
IS_OP_CODE_MODE(SAX, 0x8f, ABSOLUTE)
IS_OP_CODE_MODE(AHX, 0x93, INDIRECT_INDEXED)
IS_OP_CODE_MODE(SAX, 0x97, ZERO_PAGE_INDEXED_Y)
IS_OP_CODE_MODE(TAS, 0x9b, ABSOLUTE_INDEXED_Y)
IS_OP_CODE_MODE(AHX, 0x9f, ABSOLUTE_INDEXED_Y)
IS_OP_CODE_MODE(LAX, 0xa3, INDEXED_INDIRECT)
IS_OP_CODE_MODE(LAX, 0xa7, ZERO_PAGE)
IS_OP_CODE_MODE(LAX, 0xab, IMMEDIATE)
IS_OP_CODE_MODE(LAX, 0xaf, ABSOLUTE)
IS_OP_CODE_MODE(LAX, 0xb3, INDIRECT_INDEXED)
IS_OP_CODE_MODE(LAX, 0xb7, ZERO_PAGE_INDEXED_Y)
IS_OP_CODE_MODE(LAX, 0xbb, ABSOLUTE_INDEXED_Y)
IS_OP_CODE_MODE(LAX, 0xbf, ABSOLUTE_INDEXED_Y)
}
}