Я занимаюсь рефакторингом эмулятора NMOS6502 на несколько классов. Мне было интересно, существует ли «объектно-ориентированный» способ определения таблицы переходов функций. По сути, я определил отдельные классы инструкций для классификации групп связанных операций процессора, таких как «CStackInstHandler» или «CArithmeticInstHandler», которые будут иметь ссылку на объект процессора. Каждый класс инструкций является производным от абстрактного класса инструкций. Каждый производный класс инструкций имеет набор функций, которые будут использовать общедоступный интерфейс объекта процессора для изменения состояния процессора, например:
uint8_t opcode = _memory->readMem(_cpu->getProgramCounter());
AInstructionHandler* _handler = _cpu->getInstHandler(opcode);
_handler->setCpu(&cpu);
_handler->setMemory(&memory);
_handler->execute(opcode);
Проблема в том, что во время выполнения обработчик инструкций, а также соответствующая функция-член, определенная для этого обработчика, должны быть определены с использованием кода операции.
Итак, у нас есть - код операции считывается из памяти, таблица используется процессором для сопоставления кода операции с типом обработчика инструкции, а затем тот же самый код операции используется обработчиком инструкции для выбора правильной функции. Каждая инструкция переопределяет функцию «выполнить», например:
void CBranchInstHandler::execute() {
switch(_opcode) {
case 0x90:
this->BCC();
break;
case 0xb0:
this->BCS();
break;
case 0xf0:
this->BEQ();
break;
case 0x30:
this->BMI();
break;
case 0xd0:
this->BNE();
break;
case 0x10:
this->BPL();
break;
default:
break;
}
}
void CBranchInstHandler::BCC() {
uint16_t address = this->getAddress();
if(!_cpu->isCarry()) {
uint16_t pc = _cpu->getPC();
pc += address;
_cpu->setPC(pc);
}
}
/*more instruction specific functions...*/
Я получаю два поиска, один из которых является избыточным. Один для выбора обработчика, а другой для выбора функции обработчика. Я чувствую, что это неправильный способ выполнения этой задачи, но я не уверен в альтернативе, которая не просто переходит в группы функций, не являющихся членами.
Мне интересно, есть ли у кого-нибудь понимание этой проблемы. В основном это сводится к желанию реорганизовать класс на более мелкие кусочки (класс процессора с функциями-членами инструкций, реорганизованными в класс процессора и классы инструкций), но все компоненты настолько взаимосвязаны, что мне приходится повторяться. Вводится резервирование.
Необъектно-ориентированное решение состояло бы в том, чтобы эти инструкции были функциями, не являющимися членами, которые принимают ссылку на процессор. Затем будет определена таблица переходов функций, инструкции будут искать и индексировать по коду операции и выполнять.
Это действительно не кажется практичным с объектами. Я мог бы сделать все инструкции статическими или что-то в этом роде, но это, похоже, упускает суть.
Любое понимание или информация о даже косвенно связанных проблемах были бы очень полезны.
Спасибо.
_cpu->execute(opcode)
. - person Michael   schedule 01.06.2015execute
? Классы, которые не обрабатывают данный код операции, знают, что они его не обрабатывают и просто ничего не будут делать. - person Tommy   schedule 02.06.2015