369 lines
8.1 KiB
C++
369 lines
8.1 KiB
C++
#include "Assembler.h"
|
|
#include <assert.h>
|
|
|
|
|
|
AsmInsData DecInsData[256] = {
|
|
{ASMIT_BRK, ASMIM_IMPLIED},
|
|
{ASMIT_ORA, ASMIM_INDIRECT_X},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_ORA, ASMIM_ZERO_PAGE},
|
|
{ASMIT_ASL, ASMIM_ZERO_PAGE},
|
|
{ASMIT_INV},
|
|
{ASMIT_PHP, ASMIM_IMPLIED},
|
|
{ASMIT_ORA, ASMIM_IMMEDIATE},
|
|
{ASMIT_ASL, ASMIM_IMPLIED},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_ORA, ASMIM_ABSOLUTE},
|
|
{ASMIT_ASL, ASMIM_ABSOLUTE},
|
|
{ASMIT_INV},
|
|
|
|
{ASMIT_BPL, ASMIM_RELATIVE },
|
|
{ASMIT_ORA, ASMIM_INDIRECT_Y},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_ORA, ASMIM_ZERO_PAGE_X},
|
|
{ASMIT_ASL, ASMIM_ZERO_PAGE_X},
|
|
{ASMIT_INV},
|
|
{ASMIT_CLC, ASMIM_IMPLIED},
|
|
{ASMIT_ORA, ASMIM_ABSOLUTE_Y},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_ORA, ASMIM_ABSOLUTE_X},
|
|
{ASMIT_ASL, ASMIM_ABSOLUTE_X},
|
|
{ASMIT_INV},
|
|
|
|
|
|
{ASMIT_JSR, ASMIM_ABSOLUTE},
|
|
{ASMIT_AND, ASMIM_INDIRECT_X},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_BIT, ASMIM_ZERO_PAGE},
|
|
{ASMIT_AND, ASMIM_ZERO_PAGE},
|
|
{ASMIT_ROL, ASMIM_ZERO_PAGE},
|
|
{ASMIT_INV},
|
|
{ASMIT_PLP, ASMIM_IMPLIED},
|
|
{ASMIT_AND, ASMIM_IMMEDIATE},
|
|
{ASMIT_ROL, ASMIM_IMPLIED},
|
|
{ASMIT_INV},
|
|
{ASMIT_BIT, ASMIM_ABSOLUTE},
|
|
{ASMIT_AND, ASMIM_ABSOLUTE},
|
|
{ASMIT_ROL, ASMIM_ABSOLUTE},
|
|
{ASMIT_INV},
|
|
|
|
{ASMIT_BMI, ASMIM_RELATIVE },
|
|
{ASMIT_AND, ASMIM_INDIRECT_Y},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_AND, ASMIM_ZERO_PAGE_X},
|
|
{ASMIT_ROL, ASMIM_ZERO_PAGE_X},
|
|
{ASMIT_INV},
|
|
{ASMIT_SEC, ASMIM_IMPLIED},
|
|
{ASMIT_AND, ASMIM_ABSOLUTE_Y},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_AND, ASMIM_ABSOLUTE_X},
|
|
{ASMIT_ROL, ASMIM_ABSOLUTE_X},
|
|
{ASMIT_INV},
|
|
|
|
|
|
{ASMIT_RTI, ASMIM_IMPLIED},
|
|
{ASMIT_EOR, ASMIM_INDIRECT_X},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_EOR, ASMIM_ZERO_PAGE},
|
|
{ASMIT_LSR, ASMIM_ZERO_PAGE},
|
|
{ASMIT_INV},
|
|
{ASMIT_PHA, ASMIM_IMPLIED},
|
|
{ASMIT_EOR, ASMIM_IMMEDIATE},
|
|
{ASMIT_LSR, ASMIM_IMPLIED},
|
|
{ASMIT_INV},
|
|
{ASMIT_JMP, ASMIM_ABSOLUTE},
|
|
{ASMIT_EOR, ASMIM_ABSOLUTE},
|
|
{ASMIT_LSR, ASMIM_ABSOLUTE},
|
|
{ASMIT_INV},
|
|
|
|
{ASMIT_BVC, ASMIM_RELATIVE },
|
|
{ASMIT_EOR, ASMIM_INDIRECT_Y},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_EOR, ASMIM_ZERO_PAGE_X},
|
|
{ASMIT_LSR, ASMIM_ZERO_PAGE_X},
|
|
{ASMIT_INV},
|
|
{ASMIT_CLI, ASMIM_IMPLIED},
|
|
{ASMIT_EOR, ASMIM_ABSOLUTE_Y},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_INV},
|
|
{ASMIT_EOR, ASMIM_ABSOLUTE_X},
|
|
{ASMIT_LSR, ASMIM_ABSOLUTE_X},
|
|
{ASMIT_INV},
|
|
|
|
|
|
{ ASMIT_RTS, ASMIM_IMPLIED },
|
|
{ ASMIT_ADC, ASMIM_INDIRECT_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_ADC, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_ROR, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_PLA, ASMIM_IMPLIED },
|
|
{ ASMIT_ADC, ASMIM_IMMEDIATE },
|
|
{ ASMIT_ROR, ASMIM_IMPLIED },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_JMP, ASMIM_INDIRECT },
|
|
{ ASMIT_ADC, ASMIM_ABSOLUTE },
|
|
{ ASMIT_ROR, ASMIM_ABSOLUTE },
|
|
{ ASMIT_INV },
|
|
|
|
{ ASMIT_BVS, ASMIM_RELATIVE },
|
|
{ ASMIT_ADC, ASMIM_INDIRECT_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_ADC, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_ROR, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_SEI, ASMIM_IMPLIED },
|
|
{ ASMIT_ADC, ASMIM_ABSOLUTE_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_ADC, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_ROR, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_INV },
|
|
|
|
|
|
{ ASMIT_INV },
|
|
{ ASMIT_STA, ASMIM_INDIRECT_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_STY, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_STA, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_STX, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_DEY, ASMIM_IMPLIED },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_TXA, ASMIM_IMPLIED },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_STY, ASMIM_ABSOLUTE },
|
|
{ ASMIT_STA, ASMIM_ABSOLUTE },
|
|
{ ASMIT_STX, ASMIM_ABSOLUTE },
|
|
{ ASMIT_INV },
|
|
|
|
{ ASMIT_BCC, ASMIM_RELATIVE },
|
|
{ ASMIT_STA, ASMIM_INDIRECT_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_STY, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_STA, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_STX, ASMIM_ZERO_PAGE_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_TYA, ASMIM_IMPLIED },
|
|
{ ASMIT_STA, ASMIM_ABSOLUTE_Y },
|
|
{ ASMIT_TXS },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_STA, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
|
|
|
|
{ ASMIT_LDY, ASMIM_IMMEDIATE },
|
|
{ ASMIT_LDA, ASMIM_INDIRECT_X },
|
|
{ ASMIT_LDX, ASMIM_IMMEDIATE },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_LDY, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_LDA, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_LDX, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_TAY, ASMIM_IMPLIED },
|
|
{ ASMIT_LDA, ASMIM_IMMEDIATE },
|
|
{ ASMIT_TAX, ASMIM_IMPLIED },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_LDY, ASMIM_ABSOLUTE },
|
|
{ ASMIT_LDA, ASMIM_ABSOLUTE },
|
|
{ ASMIT_LDX, ASMIM_ABSOLUTE },
|
|
{ ASMIT_INV },
|
|
|
|
{ ASMIT_BCS, ASMIM_RELATIVE },
|
|
{ ASMIT_LDA, ASMIM_INDIRECT_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_LDY, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_LDA, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_LDX, ASMIM_ZERO_PAGE_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CLV, ASMIM_IMPLIED },
|
|
{ ASMIT_LDA, ASMIM_ABSOLUTE_Y },
|
|
{ ASMIT_TSX, ASMIM_IMPLIED },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_LDY, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_LDA, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_LDX, ASMIM_ABSOLUTE_Y },
|
|
{ ASMIT_INV },
|
|
|
|
|
|
{ ASMIT_CPY, ASMIM_IMMEDIATE },
|
|
{ ASMIT_CMP, ASMIM_INDIRECT_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CPY, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_CMP, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_DEC, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INY, ASMIM_IMPLIED },
|
|
{ ASMIT_CMP, ASMIM_IMMEDIATE },
|
|
{ ASMIT_DEX, ASMIM_IMPLIED },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CPY, ASMIM_ABSOLUTE },
|
|
{ ASMIT_CMP, ASMIM_ABSOLUTE },
|
|
{ ASMIT_DEC, ASMIM_ABSOLUTE },
|
|
{ ASMIT_INV },
|
|
|
|
{ ASMIT_BNE, ASMIM_RELATIVE },
|
|
{ ASMIT_CMP, ASMIM_INDIRECT_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CMP, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_DEC, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CLD, ASMIM_IMPLIED },
|
|
{ ASMIT_CMP, ASMIM_ABSOLUTE_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CMP, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_DEC, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_INV },
|
|
|
|
{ ASMIT_CPX, ASMIM_IMMEDIATE },
|
|
{ ASMIT_SBC, ASMIM_INDIRECT_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CPX, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_SBC, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_INC, ASMIM_ZERO_PAGE },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INX, ASMIM_IMPLIED },
|
|
{ ASMIT_SBC, ASMIM_IMMEDIATE },
|
|
{ ASMIT_NOP, ASMIM_IMPLIED },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_CPX, ASMIM_ABSOLUTE },
|
|
{ ASMIT_SBC, ASMIM_ABSOLUTE },
|
|
{ ASMIT_INC, ASMIM_ABSOLUTE },
|
|
{ ASMIT_INV },
|
|
|
|
{ ASMIT_BEQ, ASMIM_RELATIVE },
|
|
{ ASMIT_SBC, ASMIM_INDIRECT_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_SBC, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_INC, ASMIM_ZERO_PAGE_X },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_SED, ASMIM_IMPLIED },
|
|
{ ASMIT_SBC, ASMIM_ABSOLUTE_Y },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_INV },
|
|
{ ASMIT_SBC, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_INC, ASMIM_ABSOLUTE_X },
|
|
{ ASMIT_INV },
|
|
};
|
|
|
|
short AsmInsOpcodes[NUM_ASM_INS_TYPES][NUM_ASM_INS_MODES];
|
|
|
|
const char* AsmInstructionNames[NUM_ASM_INS_TYPES] = {
|
|
"ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRK", "BVC", "BVS", "CLC",
|
|
"CLD", "CLI", "CLV", "CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "EOR", "INC", "INX", "INY", "JMP",
|
|
"JSR", "LDA", "LDX", "LDY", "LSR", "NOP", "ORA", "PHA", "PHP", "PLA", "PLP", "ROL", "ROR", "RTI",
|
|
"RTS", "SBC", "SEC", "SED", "SEI", "STA", "STX", "STY", "TAX", "TAY", "TSX", "TXA", "TXS", "TYA",
|
|
"INV", "BYT"
|
|
};
|
|
|
|
int AsmInsModeSize[NUM_ASM_INS_MODES] = {
|
|
1,
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
3,
|
|
3,
|
|
3,
|
|
3,
|
|
2,
|
|
2,
|
|
2,
|
|
};
|
|
|
|
void InitAssembler(void)
|
|
{
|
|
for (int i = 0; i < NUM_ASM_INS_TYPES; i++)
|
|
{
|
|
for (int j = 0; j < NUM_ASM_INS_MODES; j++)
|
|
{
|
|
AsmInsOpcodes[i][j] = -1;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 256; i++)
|
|
{
|
|
const AsmInsData& di(DecInsData[i]);
|
|
if (di.mType != ASMIT_INV)
|
|
{
|
|
assert(AsmInsOpcodes[di.mType][di.mMode] == -1);
|
|
AsmInsOpcodes[di.mType][di.mMode] = i;
|
|
}
|
|
}
|
|
|
|
AsmInsOpcodes[ASMIT_BYTE][ASMIM_ZERO_PAGE] = 0;
|
|
}
|
|
|
|
int AsmInsSize(AsmInsType type, AsmInsMode mode)
|
|
{
|
|
if (type < ASMIT_INV)
|
|
return AsmInsModeSize[mode];
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
static inline char toupper(char ch)
|
|
{
|
|
if (ch >= 'a' && ch <= 'z')
|
|
return ch - 'a' + 'A';
|
|
else
|
|
return ch;
|
|
}
|
|
AsmInsType FindAsmInstruction(const char* ins)
|
|
{
|
|
if (!ins[3])
|
|
{
|
|
for (int i = 0; i < NUM_ASM_INS_TYPES; i++)
|
|
{
|
|
if (AsmInstructionNames[i][0] == toupper(ins[0]) &&
|
|
AsmInstructionNames[i][1] == toupper(ins[1]) &&
|
|
AsmInstructionNames[i][2] == toupper(ins[2]))
|
|
return AsmInsType(i);
|
|
}
|
|
}
|
|
|
|
return ASMIT_INV;
|
|
}
|
|
|
|
bool HasAsmInstructionMode(AsmInsType type, AsmInsMode mode)
|
|
{
|
|
return AsmInsOpcodes[type][mode] != -1;
|
|
}
|
|
|