Программирование эмулятора: как эмулятор понимает коды операций из адресов?

Мне трудно понять, как SNES понимает, что такое коды операций и что такое адреса/параметры. Я знаю, что каждый код операции кодируется уникальным шестнадцатеричным байтом. Являются ли они параметрами следующих байтов? Если да, то как он узнает, что нужно принимать один или два байта (для абсолютных или прямых адресов).

Если это так, означает ли это, что первый байт файла (после заголовка) является кодом операции?


person VJC1288    schedule 18.09.2013    source источник
comment
Взгляните на набор инструкций 6502, который должен прояснить ситуацию.   -  person    schedule 19.09.2013
comment
Эмулятор предназначен для конкретного микропроцессора. Этот микропроцессор имеет четко определенный машинный язык, который указывает, какие коды операций имеют ноль, один, два или более параметров и как они должны выглядеть. Все эти знания встроены в эмулятор.   -  person lurker    schedule 19.09.2013
comment
когда вы смотрите документацию по набору инструкций процессора, эта документация обычно включает как язык ассемблера (удобочитаемый текст), так и машинный код, биты и байты, которые понимает процессор. Для каждой инструкции и опции инструкции есть биты в машинном коде, связанные с этим. Все это вы можете увидеть в документации процессора. Все, что делает эмулятор, это считывает эти биты и байты и имеет переменные, которые притворяются регистрами, и массивы, которые притворяются памятью и т. д.   -  person old_timer    schedule 19.09.2013
comment
Когда вы прочитаете документацию по процессору, вы узнаете, как загружается процессор. В случае с 6502, например, таблица векторов находится в верхней части памяти. Что вы делаете с файлом, так это то, что вы помещаете данные из файла в свою смоделированную память (массив), а затем ваш смоделированный процессор загружается так же, как реальный процессор, который он эмулирует.   -  person old_timer    schedule 19.09.2013
comment
Добро пожаловать в архитектуру фон Неймана. Инструкции и данные находятся в памяти и являются адресуемыми. Что такое код операции, полностью определяется тем, указывает ли ПК процессора прямо на него (и, таким образом, вызывает его выполнение). Тот же самый байт данных в памяти позже может быть использован в качестве данных (хотя это довольно редко встречается в поддерживаемом коде). Действительно неприятный запутанный код будет делать это намеренно, потому что его очень сложно понять.   -  person Ira Baxter    schedule 24.11.2013


Ответы (2)


Процессор имеет регистр PC (счетчик программ), содержащий адрес следующей инструкции, которая должна быть выполнена. При сбросе ПК устанавливается на фиксированное значение, с которого начинается выполнение.

Первый байт каждой инструкции является байтом кода операции; его кодирование определяет, что будет делать инструкция и сколько байтов операнда потребуется. Процессор извлекает байт кода операции из адреса в ПК и увеличивает значение ПК. Проверяется код операции и извлекаются все необходимые байты операнда, всегда из памяти, на которую указывает ПК, которая увеличивается для каждого из них. Как только полная инструкция будет получена, ПК укажет на код операции для следующей инструкции.

Затем ЦП выполняет операции, определяемые байтом кода операции и его операндами, это называется выполнением инструкции. Выполнение может изменить ПК в случае перехода, например, но в конце выполнения ПК будет указывать на байт кода операции следующей инструкции для выполнения, и цикл, называемый циклом выборки-выполнения, продолжается.

Ошибки в программах довольно часто связаны с тем, что ПК меняется на значение, которое не является началом инструкции, написанной программистом/компилятором. ЦП не может знать об этом и продолжает работать независимо, выполняя содержимое памяти, которое никогда не предназначалось для выполнения, и выполняя по существу случайные операции.

Отличным ресурсом для понимания того, как все это устроено, является Элементы вычислительных систем. содержимое доступно на этом веб-сайте.

Надеюсь, это поможет.

person HBP    schedule 19.09.2013

Если это так, означает ли это, что первый байт файла (после заголовка) является кодом операции?

Процессор SNES основан на 65C816, который является своего рода эволюцией 6502. Для обратной совместимости 65C816 включает режим эмуляции, бинарно совместимый с 6502 (фактически 65C02). Также есть нативный режим, где у вас есть 16-битные регистры и все такое прочее.

Каждый режим имеет свою собственную таблицу векторов:

Основной режим:

$FFE4: COP (co-processor interrupt)
$FFE6: BRK
$FFE8: ABORT
$FFEA: NMI (vertical blank)
$FFEC: - (no RESET in native mode)
$FFEE: IRQ

Режим эмуляции:

$FFF4: COP
$FFF6: -
$FFF8: ABORT
$FFFA: NMI (vertical blank)
$FFFC: RESET
$FFFE: IRQ or BRK

Когда ЦП сбрасывается, он запускается в режиме эмуляции и ожидает найти вектор СБРОСА по логическому адресу $FFFC (какое физическое смещение в ПЗУ соответствует, зависит от режим отображения памяти).

Адрес, хранящийся в векторе RESET, должен указывать на первую часть кода, которую вы хотите выполнить после сброса/цикла питания. Обычно это начинается с отключения прерываний, переключения ЦП в собственный режим и продолжения инициализации остальной части системы (графического процессора, звукового процессора и т. д.):

sei    ; Disable interrupts
clc    ; Clear the carry flag 
xce    ; Swap the carry and emulation flag (i.e. clear the emulation flag)
...    ; Awesomeness follows..
person Michael    schedule 19.09.2013
comment
Что вы подразумеваете под логическим адресом? Я знаю, что у ПЗУ есть свои адреса, и они загружаются в память SNES. Один из них называется логическим адресом? - person VJC1288; 22.09.2013
comment
Я имею в виду, что когда вы обращаетесь к адресу ROM, такому как $FFFC, вы не обязательно получаете доступ к данным по физическому смещению $FFFC в файле ROM. Смещение внутри ПЗУ зависит от разметки ПЗУ. - person Michael; 22.09.2013