В свободное время я начинаю писать очень простой эмулятор C ++ для процессора 6502. Раньше я записывал много ассемблерного кода для этого процессора, поэтому все коды операций, режимы адресации и другие вещи не имеют большого значения.
6502 имеет 56 различных инструкций плюс 13 режимов адресации, что дает в общей сложности 151 различный код операции. Для меня скорость не является проблемой, поэтому вместо написания огромного оператора switch-case и повторения одного и того же кода снова и снова (разные коды операций могут ссылаться на одну и ту же инструкцию с использованием другого режима адресации) я хотел бы отделить фактический код инструкции от код режима адресации: я нашел это решение очень изящным, так как для этого нужно было бы написать только 13 функций режима адресации и 56 функций команд без повторения.
здесь функции режима адресации:
// Addressing modes
uint16_t Addr_ACC(); // ACCUMULATOR
uint16_t Addr_IMM(); // IMMEDIATE
uint16_t Addr_ABS(); // ABSOLUTE
uint16_t Addr_ZER(); // ZERO PAGE
uint16_t Addr_ZEX(); // INDEXED-X ZERO PAGE
uint16_t Addr_ZEY(); // INDEXED-Y ZERO PAGE
uint16_t Addr_ABX(); // INDEXED-X ABSOLUTE
uint16_t Addr_ABY(); // INDEXED-Y ABSOLUTE
uint16_t Addr_IMP(); // IMPLIED
uint16_t Addr_REL(); // RELATIVE
uint16_t Addr_INX(); // INDEXED-X INDIRECT
uint16_t Addr_INY(); // INDEXED-Y INDIRECT
uint16_t Addr_ABI(); // ABSOLUTE INDIRECT
все они возвращают фактический адрес памяти (16 бит), используемый инструкцией для чтения / записи операнда / результата
прототип функции инструкции:
void Op_ADC(uint16_t addr);
void Op_AND(uint16_t addr);
void Op_ASL(uint16_t addr);
...
он принимает 16-битный адрес, выполняет свои собственные операции, обновляет флаги состояния и / или регистры и фиксирует результаты (если есть) по тому же адресу памяти.
Учитывая эту структуру кода, мне было трудно использовать режим адресации ACCUMULATOR, который является единственным, который возвращает фактическое значение внутреннего регистра A вместо адреса памяти. Я мог бы вернуть значение A, используя возвращаемый тип uin16_t, и добавить логический флаг для такого режима адресации, но я считаю это крайне уродливым решением.
Функции команд должны быть полностью независимыми от режима адресации.