В предыдущей статье мы рассмотрели общее устройство CHIP-8. Сегодня перейдем к описанию ассемблерных команд и их опкодов.
В этой статье список инструкций условно разбит на три колонки:
опкод
команда на ассемблере
описание
И используются следующие обозначения:
nnn
- 12 битный адрес
kk
- 8 битная константа
x
- 4 битный номер регистра
y
- 4 битный номер регистра
1..9, A..F
- шестнадцатеричные цифры
Инструкции CHIP-8
00E0
CLS
Очистить экран
00EE
RET
Возвратиться из подпрограммы
0nnn
SYS nnn
Перейти на машинный код RCA 1802 по адресу nnn. Эта инструкция была только в самой первой реализации CHIP-8. В более поздних реализациях и эмуляторах не используется.
1nnn
JP nnn
Перейти по адресу nnn
2nnn
CALL nnn
Вызов подпрограммы по адресу nnn
3xkk
SE Vx, kk
Пропустить следующую инструкцию, если регистр Vx = kk
4xkk
SNE Vx, kk
Пропустить следующую инструкцию, если регистр Vx != kk
5xy0
SE Vx, Vy
Пропустить следующую инструкцию, если Vx = Vy
6xkk
LD Vx, kk
Загрузить в регистр Vx число kk, т.е. Vx = kk
7xkk
ADD Vx, kk
Установить Vx = Vx + kk
8xy0
LD Vx, Vy
Установить Vx = Vy
8xy1
OR Vx, Vy
Выполнить операцию дизъюнкция (логическое “ИЛИ”) над значениями регистров Vx и Vy, результат сохранить в Vx. Т.е. Vx = Vx | Vy
8xy2
AND Vx, Vy
Выполнить операцию конъюнкция (логическое “И”) над значениями регистров Vx и Vy, результат сохранить в Vx. Т.е. Vx = Vx & Vy
8xy3
XOR Vx, Vy
Выполнить операцию “исключающее ИЛИ” над значениями регистров Vx и Vy, результат сохранить в Vx. Т.е. Vx = Vx ^ Vy
8xy4
ADD Vx, Vy
Значения Vx и Vy суммируются. Если результат больше, чем 8 бит (т.е.> 255) VF устанавливается в 1, иначе 0. Только младшие 8 бит результата сохраняются в Vx. Т.е. Vx = Vx + Vy
8xy5
SUB Vx, Vy
Если Vx >= Vy, то VF устанавливается в 1, иначе 0. Затем Vy вычитается из Vx, а результат сохраняется в Vx. Т.е. Vx = Vx - Vy
8xy6
SHR Vx {, Vy}
Операция сдвига вправо на 1 бит. Сдвигается регистр Vx. Т.е. Vx = Vx » 1. До операции сдвига выполняется следующее: если младший бит (самый правый) регистра Vx равен 1, то VF = 1, иначе VF = 0
8xy7
SUBN Vx, Vy
Если Vy >= Vx, то VF устанавливается в 1, иначе 0. Тогда Vx вычитается из Vy, и результат сохраняется в Vx. Т.е. Vx = Vy - Vx
8xyE
SHL Vx {, Vy}
Операция сдвига влево на 1 бит. Сдвигается регистр Vx. Т.е. Vx = Vx « 1. До операции сдвига выполняется следующее: если младший бит (самый правый) регистра Vx равен 1, то VF = 1, иначе VF = 0
9xy0
SNE Vx, Vy
Пропустить следующую инструкцию, если Vx != Vy
Annn
LD I, nnn
Значение регистра I устанавливается в nnn
Bnnn
JP V0, nnn
Перейти по адресу nnn + значение в регистре V0.
Cxkk
RND Vx, kk
Устанавливается Vx = (случайное число от 0 до 255) & kk
Dxyn
DRW Vx, Vy, n
Нарисовать на экране спрайт. Эта инструкция считывает n байт по адресу содержащемуся в регистре I и рисует их на экране в виде спрайта c координатой Vx, Vy. Спрайты рисуются на экран по методу операции XOR, то есть если в том месте где мы рисуем спрайт уже есть нарисованные пиксели - они стираются, если их нет - рисуются. Если хоть один пиксель был стерт, то VF устанавливается в 1, иначе в 0.
Ex9E
SKP Vx
Пропустить следующую команду если клавиша, номер которой хранится в регистре Vx, нажата
ExA1
SKNP Vx
Пропустить следующую команду если клавиша, номер которой хранится в регистре Vx, не нажата
Fx07
LD Vx, DT
Скопировать значение таймера задержки в регистр Vx
Fx0A
LD Vx, K
Ждать нажатия любой клавиши. Как только клавиша будет нажата записать ее номер в регистр Vx и перейти к выполнению следующей инструкции.
Fx15
LD DT, Vx
Установить значение таймера задержки равным значению регистра Vx
Fx18
LD ST, Vx
Установить значение звукового таймера равным значению регистра Vx
Fx1E
ADD I, Vx
Сложить значения регистров I и Vx, результат сохранить в I. Т.е. I = I + Vx
Fx29
LD F, Vx
Используется для вывода на экран символов встроенного шрифта размером 4x5 пикселей. Команда загружает в регистр I адрес спрайта, значение которого находится в Vx. Например, нам надо вывести на экран цифру 5. Для этого загружаем в Vx число 5. Потом команда LD F, Vx загрузит адрес спрайта, содержащего цифру 5, в регистр I
Fx33
LD B, Vx
Сохранить значение регистра Vx в двоично-десятичном (BCD) представлении по адресам I, I+1 и I+2
Fx55
LD [I], Vx
Сохранить значения регистров от V0 до Vx в памяти, начиная с адреса находящегося в I
Fx65
LD Vx, [I]
Загрузить значения регистров от V0 до Vx из памяти, начиная с адреса находящегося в I
Инструкции Super CHIP
Super CHIP может использовать все вышеназванные инструкции (за исключением 0nnn), а так же добавляет следующие:
00Cn
SCD n
Прокрутить изображение на экране на n строк вниз
00FB
SCR
Прокрутить изображение на экране на 4 пикселя вправо в режиме 128x64, либо на 2 пикселя в режиме 64x32
00FC
SCL
Прокрутить изображение на экране на 4 пикселя влево в режиме 128x64, либо на 2 пикселя в режиме 64x32
00FD
EXIT
Завершить программу
00FE
LOW
Выключить расширенный режим экрана. Переход на разрешение 64x32
00FF
HIGH
Включить расширенный режим экрана. Переход на разрешение 128x64
Dxy0
DRW Vx, Vy, 0
Работает подобно инструкции Dxyn, только в расширенном режиме экрана рисует спрайты размером 16x16 пикселей, в обычном режиме 8x16
Fx30
LD HF, Vx
Работает подобно команде Fx29, только загружает спрайты размером 8x10 пикселей
Fx75
LD R, Vx
Сохранить регистры V0 - Vx в пользовательских флагах [RPL](http://en.wikipedia.org/wiki/RPL_(programming_language))
Fx85
LD Vx, R
Загрузить регистры V0 - Vx из пользовательских флагов RPL
На самом деле как в расширенном режиме, так и в обычном, физический размер экрана одинаков. Но при разрешении экрана 64x32 каждый пиксель рисуется в два раза больше, чем при 128x64. Поэтому операции скроллинга экрана (00FB, 00FC) в расширенном режиме сдвигают 4 пикселя, а в обычном 2. То же относится и к инструкции 00Cn.
Super CHIP добавляет в память еще один шрифт. Он тоже состоит из шестнадцатеричных символов от 0 до F, размер каждого 8x10 пикселей. Если программа находится в расширенном режиме, то она должна выводить этот крупный шрифт. В обычном режиме программа выводит обычный шрифт, размером 4x5.
Сегодняшняя статья получилась довольно громоздкой и, возможно, непонятной для тех кто не знаком с ассемблером. Но не волнуйтесь если вы во всём этом не разобрались, немного позже все станет понятнее. В дальнейшем мы будем использовать информацию с этой страницы как справочник. Что бы лучше понять эмулируемую платформу в следующей статье мы напишем несколько программ для CHIP-8 и затем начнем писать наш эмулятор.