Рассмотрим систему команд архитектуры 6502. В Денди используется именно эта модель, за исключением блока десятичной арифметики.
Процессор оперирует целыми восьмиразрядными числами. Содержит всего 6 программно-доступных регистров. Из них 5 – восьмиразрядных, и 1 – шестнадцатиразрядный программный счетчик.
A – регистр - аккумулятор. Как и большинство «простых» архитектур – 6502 является «аккумуляторной», то есть во всех, или почти во всех, операциях явно или неявно участвует аккумулятор.
PC – программный счетчик. Единственный 16-ти разрядный регистр – указатель выполняемой команды (классически).
S – регистр - указатель вершины стека (первой свободной ячейки). Стек находится в пространстве адресов 0100h – 01FFh и «растёт» от старшего к младшему.
P – регистр флагов.
P[0] - “C” – “Carry” – флаг переноса из старшего разряда (классически).
P[2] - “I” – “Interrupt” – флаг маскирования прерывания аппаратного прерывания на линии IRQ – варьируется командами SEI/CLI.
P[3] - “D” – “Decimal” – флаг режима десятичной арифметики. Так как в Денди этот режим отсутствует, то этот флаг не используется процессором, может использоваться программистом. Варьируется командами SED/CLD.
P[4] - “B” – “Break” – флаг программного прерывания (команда BRK).
P[5] - “1”
P[6] - “V” – “” – флаг переноса в знаковый разряд (из 6-ого в 7-ой - классически).
P[7] - “N” – “” – флаг знака результата операции – дублирует седьмой разряд (классически).
X, Y – регистры индексной адресации (или просто "общего назначения").
В общем итоге получается регистров для "юзания" всего навсего 3 (A,X,Y) - да и то, многие команды жестко привязаны именно к одному из них, очень часто неудобно бывает, что рождает лишние мнемоники и обращения в память.
Напомним, что система команд процессора оперирует или с перечисленными выше регистрами, или с адресным пространством памяти (64кб) – все устройства, управляемые процессором, должны отображаться своими регистрами на память.
И так – о способах адресации памяти.
ABS - прямая, в команде указывается полный 16-разрядный адрес операнда:
ABS, X (ABX)- индексированная по X, указывается базовый 16-разрядный адрес, к которому прибавляется смещение из регистра X;
ABS, Y (ABY) - индексированная по Y, указывается базовый 16-разрядный адрес, к которому прибавляется смещение из регистра Y.
АСС - аккумуляторная, подразумевает наличие операнда в регистре A процессора (что требуется указать в мнемонике).
IMM - непосредственная, 8-разрядный операнд расположен сразу за кодом команды (в мнемонической записи перед непосредственным операндом ставится символ «#»).
IMPL - неявная (указывается лишь мнемоника), операнды не указываются – жесткая логика работы инструкции.
IND - косвенная, задается адрес ячейки памяти, в которой хранится адрес операнда - бывает следующих видов:
IND, X (NDX) - индексно-косвенная, указывается 8-разрядный адрес в нулевой странице (в квадратных скобках), к которому прибавляется содержимое регистра X, после чего из ячейки памяти с вычисленным адресом и следующей за ней извлекается полный 16-разрядный адрес операнда (в мнемонике после адреса через запятую ставится и "X"). Другими словами - в области нулевой страницы создается таблица адресов, а при помощи переменной в регистре "X" можно по ним "бегать";
IND, Y (NDY) - косвенно-индексная, указывается 8-разрядный адрес в нулевой странице (в квадратных скобках), после чего из заданной ячейки памяти и следующей за ней считывается 16-разрядный базовый адрес, к которому прибавляется содержимое регистра Y, и из ячейки с вычисленным адресом извлекается операнд (в мнемонике после адреса через запятую ставится и "Y"). В данном случае переменная в регистре "Y" играет роль смещения относительно адреса базы, хранящегося в нулевой странице;
REL - относительная, в команде указывается 8-разрядное смещение относительно содержимого счетчика команд PC;
ZP - адресация нулевой страницы, в команде задается 8-разрядный адрес, определяющий ячейку памяти нулевой страницы, где хранится операнд;
ZP, X (ZPX) - индексированная по X адресация нулевой страницы, указывается 8-разрядный базовый адрес в нулевой странице, к которому прибавляется содержимое регистра X, и из ячейки памяти с вычисленным адресом извлекается операнд;
ZP, Y (ZPY) - индексированная по Y адресация нулевой страницы, в нулевой странице указывается 8-разрядный базовый адрес, к которому прибавляется содержимое регистра Y, и из ячейки памяти с вычисленным адресом извлекается операнд.
Ниже приведем саму систему команд (Всего 56 мнемоник инструкций).
Мнемоника
Краткое описание
Методы адресации
Запись на языке ассемблера
Код команды
Число байтов
Изменяемые флаги
ADC
Сложение с учетом флага переноса: А + d8 + С. Результат в аккумуляторе А и флаге переноса C
IMM
ADC #d8
69 d8
2
V, N, Z, С
ZP
ADC 08
65 a8
2
ZP, X
ADC а8, X
75 a8
2
ABS
ADC а16
6D a16l a16h
3
ABS, X
ADC а16, Х
7D a16l a16h
3
ABS, Y
ADC a16, Y
79 a16l a16h
3
IND, X
ADC (a8, X)
61 a8
2
IND, Y
ADC (a8), Y
71 a8
2
AND
Поразрядное логическое И аккумулятора и операнда
IMM
AND #d8
29 d8
2
N, Z
ZP
AND a8
25 a8
2
ZP, X
AND a8, X
35 a8
2
ABS
AND a16
2D a16l a16h
3
ABS, X
AND a16, X
3D a16l a16h
3
ABS, Y
AND a16, Y
39 a16l a16h
3
IND, X
AND (a8, X)
21 a8
2
IND, Y
AND (a8), Y
31 a8
2
ASL
Арифметический сдвиг операнда влево, без начального учета флага C (умножение на 2)
ACC
ASL A
0A
1
N, Z, C
ZP
ASL a8
06 a8
2
ZP, X
ASL a8, X
16 a8
2
ABS
ASL a16
0E a16l a16h
3
ABS, X
ASL a16, X
1E a16l a16h
3
BCC
Переход, если флаг C = 0
REL
BCC i8
90 18
2
BCS
Переход, если флаг C = 1
REL
BCS 18
B0 18
2
BEQ
Переход, если флаг Z = 1
REL
BEQ 18
F018
2
BIT
Установка флагов в соответствии с результатом выполнения поразрядного логического И над содержимым аккумулятора и операнда. Бит 6 результата копируется во флаг V, а бит 7 - во флаг N
ZP
BIT a8
24 a8
2
N, V, Z
ABS
BIT a16
2C a16l a16h
3
BMI
Переход, если флаг N = 1
REL
BMI 18
3018
2
BNE
Переход, если флаг Z = 0
REL
BNE 18
D0 18
2
BPL
Переход, если флаг N = 0
REL
BPL 18
1018
2
BRK
Программное прерывание
IMPL
BRK
00
1
I
BVC
Переход, если флаг V = 0
REL
BVC 18
5018
2
BVS
Переход, если флаг V = 1
REL
BVS 18
7018
2
CLC
Сброс флага C
IMPL
CLC
18
1
С
CLD
Сброс флага D
IMPL
CLD
D8
1
D
CLI
Сброс флага I (разрешение прерываний)
IMPL
CLI
58
1
I
CLV
Сброс флага V
IMPL
CLV
B8
1
V
CMP
Установка флагов в соответствии с результатом вычитания операнда из содержимого аккумулятора
IMM
CMP #d8
C9 d8
2
N, Z, C
ZP
CMP a8
C5 a8
2
ZP, X
CMP a8, X
D5 a8
2
ABS
CMP a16
CD a16l a16h
3
ABS, X
CMP a16, X
DD a16l a16h
3
ABS, Y
CMP a16, Y
D9 a16l a16h
3
IND, X
CMP (a8, X)
C1 a8
2
IND, Y
CMP (a8), Y
D1 a8
2
CPX
Установка флагов в соответствии с результатом вычитания операнда из содержимого регистра X
IMM
CPX #d8
E0 d8
2
N, Z, C
ZP
CPX a8
E4d8
2
ABS
CPX a16
EC a16l a16h
3
CPY
Установка флагов в соответствии с результатом вычитания операнда из содержимого аккумулятора
IMM
CPY #d8
C0 d8
2
N, Z, C
ZP
CPY a8
C4 a8
2
ABS
CPY a16
CC a16l a16h
3
DEC
Уменьшение операнда на 1
ZP
DEC a8
C6 a8
2
N, Z
ZP, X
DEC a8, X
D6 a8
2
ABS
DEC а16
CE a16l a16h
3
ABS, X
DEC a16, X
DE a16l a16h
DEX
Х = Х-1
IMPL
DEX
CA
1
N, Z
DEY
Y = Y-1
IMPL
DEY
88
1
N, Z
EOR
Поразрядное Исключающее ИЛИ содержимого аккумулятора и операнда
IMM
EOR #d8
49 d8
2
N, Z
ZP
EOR a8
45 a8
2
ZP, X
EOR a8, X
55 a8
2
ABS
EOR a16
4D a16l a16h
3
ABS, X
EOR a16, X
5D a16l a16h
3
ABS, Y
EOR a16, Y
59 a16l a16h
3
IND, X
EOR (a8, X)
41 a8
2
IND, Y
EOR (a8), Y
51 a8
2
INC
Увеличение операнда на 1
ZP
INC a8
E6 a8
2
N, Z
ZP, X
INC a8, X
F6 a8
2
ABS
INC a16
EE a16l a16h
3
ABS, X
INC a16, X
FE a16l a16h
3
INX
Х = X+1
IMPL
INX
E8
1
N, Z
INY
Y = Y+1
IMPL
INY
C8
1
N, Z
JMP
Переход по указанному адресу
ABS
JMP a16
4C a16l a16h
2
IND
JMP (a 16)
6C a16l a16h
2
JSR
Вызов подпрограммы с указанным адресом. В стеке сохраняется только адрес возврата
ABS
JSR a16
20 a16l a16h
3
LDA
Загрузка операнда в аккумулятор
IMM
LDA #d8
A9d8
2
N, Z
ZP
LDA a8
A5a8
2
ZP, X
LDA a8, X
B5a8
2
ABS
LDA a16
AD a16l a16h
3
ABS, X
LDA a16, X
BD a16l a16h
3
ABS, Y
LDA a16, Y
B9 a16l a16h
3
IND, X
LDA (a8, X)
A1 a8
2
IND, Y
LDA (a8), Y
B1 a8
2
LDX
Загрузка операнда в регистр X
IMM
LDX #d8
A2 d8
2
H, Z
ZP
LDX a8
A6a8
2
ZP, Y
LDX a8, Y
B6a8
2
ABS
LDX a16
AE a16l a16h
3
ABS, Y
LDX a16, Y
BE a16l a16h
3
LDY
Загрузка операнда в регистр Y
IMM
LDY #d8
A0 d8
2
N, Z
ZP
LDY a8
A4 a8
2
ZP, Y
LDY a8, Y
B4 a8
2
ABS
LDY a16
AC a16l a16h
3
ABS, Y
LDY a16, Y
BC a16l a16h
3
LSR
Логический сдвиг операнда вправо (деление на 2)
ACC
LSR A
4A
1
N, Z, C
ZP
LSR a8
46 a8
2
ZP, X
LSR a8, X
56 a8
2
ABS
LSR a16
4E a16l a16h
3
ABS, X
LSR a16, X
5E a16l a16h
3
NOP
Нет операции
IMPL
NOP
EA
1
ORA
Поразрядное логическое ИЛИ содержимого аккумулятора и операнда
IMM
ORA #d8
09 d8
2
N, Z
ZP
ORA a8
05 a8
2
ZP, X
ORA a8, X
15 a8
2
ABS
ORA a16
0D a16l a16h
3
ABS, X
ORA a16, X
1D a16l a16h
3
ABS, Y
ORA a16, Y
19 a16l a16h
3
IND, X
ORA (a8, X)
01 a8
2
IND, Y
ORA (a8), Y
11 a8
2
PHA
Помещение содержимого аккумулятора в стек
IMPL
PHA
48
1
PHP
Помещение регистра состояния в стек
IMPL
PHP
08
1
PLA
Помещение байта с вершины стека в аккумулятор
IMPL
PLA
68
1
PLP
Помещение байта с вершины стека в регистр состояния
IMPL
PLP
28
1
Все флаги
ROL
Циклический сдвиг операнда влево
АСС
ROL A
2A
1
N, Z, C
ZP
ROL a8
26 a8
2
ZP, X
ROL a8, X
36 a8
2
ABS
ROL a16
2E a16l a16h
3
ABS, X
ROL a16, X
3E a16l a16h
3
ROR
Циклический сдвиг операнда вправо
АСС
ROR A
6A
1
N, Z, C
ZP
ROR a8
66 a8
2
ZP, X
ROR a8, X
76 a8
2
ABS
ROR a16
6E a16l a16h
3
ABS, X
ROR a16, X
7E a16l a16h
3
RTI
Возврат из прерывания
IMPL
RTI
40
1
Все флаги
RTS
Возврат из подпрограммы
IMPL
RTS
60
1
SBC
Вычитание операнда из содержимого аккумулятора с учетом флага переноса
IMM
SBC #d8
E9 d8
2
N, V, Z, C
ZP
SBC a8
E5 a8
2
ZP, X
SBC a8, X
F5 a8
2
ABS
SBC a16
ED a16l a16h
3
ABS, X
SBC a16, X
FD a16l a16h
3
ABS, Y
SBC a16, Y
F9 a16l a16h
3
IND, X
SBC (a8, X)
E1 a8
2
IND, Y
SBC (a8), Y
F1 a8
2
SEC
Установка флага C
IMPL
SEC
38
1
С
SED
Установка флага D
IMPL
SED
F8
1
D
SEI
Установка флага I (запрещение прерываний)
IMPL
SEI
78
1
I
STA
Запись содержимого аккумулятора в память
ZP
STA a8
85 a8
2
ZP, X
STA a8, X
95 a8
2
ABS
STA a16
8D a16l a16h
3
ABS, X
STA a16, X
9D a16l a16h
3
ABS, Y
STA a16; Y
99 a16l a16h
3
IND, X
STA (a8, X)
81 a8
2
IND, Y
STA (a8)
91 a8
2
STX
Запись содержимого регистра X в память
ZP
STX a8
86 a8
2
ZP, Y
STX a8, Y
96 a8
2
ABS
STX a16
8E a16l a16h
3
STY
Запись содержимого регистра Y в память
ZP
STY a8
84 a8
2
ZP, X
STY a8, X
94 a8
2
ABS
STY a16
8C a16l a16h
3
TAX
Пересылка содержимого аккумулятора в регистр X
IMPL
TAX
AA
1
N, Z
TAY
Пересылка содержимого аккумулятора в регистр Y
IMPL
TAY
A8
1
N, Z
TSX
Пересылка содержимого указателя стека в регистр X
IMPL
TSX
BA
1
N, Z
TXA
Пересылка содержимого регистра X в аккумулятор
IMPL
TXA
8A
1
N, Z
TXS
Пересылка содержимого регистра X в указатель стека
IMPL
TXS
9A
1
TYA
Пересылка содержимого регистра Y в аккумулятор
IMPL
TYA
98
1
N, Z
Условные обозначения:
а16 - 16-разрядный адрес
a16h - старший байт 16-разрядного адреса
а16l - младший байт 16-разрядного адреса
а8 - 8-разрядный адрес в нулевой странице
d8 - непосредственный 8-разрядный операнд
i8 - 8-разрядное смещение в диапазоне от -128 до 127
Также приведем матрицу системы команд (красным цветом отмечены недокументированные инструкции – в базовой архитектуре 6502 они отсутствуют, но контроллером 6561, вероятно, поддерживаются).