Для более глубокого понимания как происходит ветвление в программах написанных на ассемблере 6502 необходимо углубиться в флаги и понять какие команды влияют на тот или иной флаг. Это поможет избежать множество ошибок связанных с не очевидностью ветвления вашей программы.
Состояние статус флагов это один из шести архитектурных регистров процессора 6502:
Регистр аккумулятора A
Регистры X и Y
Статус регистр (статус флаги)
Указатель стека
Программный счетчик
С регистрами A, X, Y мы уже знакомы, мы их часто используем для операций с данными и записи в различные порты процессоров. Указатель стека - хранит в себе указатель на последнее/первое значение стека. Программный счетчик - всегда указывает на следующую команду которую нужно будет выбрать и выполнить, он 16 битный и после выполнения обновляется указатель на следующую команду. Более подробно рассмотрим в следующих статьях работу с этими регистрами.
Давайте рассмотрим более подробно флаги они в регистре расположены следующим образом NV**DIZC где:
N - Negative - этот флаг будет содержать 7-й бит результата если команда имеет результат
V - Overflow - флаг переполнения устанавливается если при сложение (ADC) или вычитание (SBC) результат знакового числа получился больше/меньше диапазона -127 -- +127
D - Decimal - флаг указывающий на работу с десятичными цифрами в денди не используется
I - Interrupt disable - флаг указывающий на то что отключены все прерывания кроме NMI
Z - Zero - флаг указывающий что результат команды равен 0, часто используется в программе и ветвление с помощью BEQ (переход если равно 0) и BNE (переход если не равен 0)
C - Carry - флаг переноса устанавливается если результат больше 255 или меньше 0 с беззнаковыми числами, так же устанавливается если при сравнение CMP результат больше либо равно. Тоже часто используется BCC (если очищен) и BCS (если установлен)
* - не используемые биты
Собственно нас интересуют больше флаги C, Z так как они часто используются при разработке игр на денди, по этому более подробнее поговорим о них, остальные же флаги для сокращения объема статьи, пока рассматривать подробно не будем.
Флаг Z - zerro
Влияют следующие команды на этот флаг: LDA, LDX, LDY, AND, INX, INY, INC, DEX, DEY, DEC, CMP, EOR, ORA и многие другие, важно просто понимание что если результат выполнения 0 то флаг Z установлен к примеру
LDA #$00 ; установлен
LDA #$01 ; не установлен
LDX #$00 ; установлен так же и LDY
DEX ; как только X станет 0 будет установлен, так же с DEC, DEY
AND #%0000 ; если результат 0 то будет установлен, так же EOR, ORA
LDA #$07
CMP #$07 ; если при сравнение с памятью значение равно то флаг будет установлен
Таким образом при установке данного флага будет выполняться переход с помощью BEQ если установлен и BNE если не установлен либо результат не равен 0.
Флаг C - carry
Команды которые влияют на данный флаг:
ADC - если после сложения больше 255
SBC - если меньше 0
CMP - если сравниваемое значение больше либо равно значению в аккумуляторе, альтернативное использование данного флага
ASL, LSR, ROL, ROR - содержит бит который был сдвинут.
На самом деле, перед ADC и SBC, я часто сбрасываю флаг переноса командой CLC для того что бы указатель переноса был 0 в таком случае ADC установит флаг переноса при достижения результат больше 255.
При программирование игры меня больше интересует использование этого флага для условий "больше либо равно" и соответственно "меньше", это такая альтернатива использования данного флага
LDA #$01
CMP #$02 ; флаг C установлен
BCS greatOrEq ; больше либо равно
BCC less ; значение в cmp меньше аккумулятора
В качестве заключения
Когда я начал изучать ассемблер 6502, я сделал большую ошибку не вникнув в работу флагов, по этому было довольно сложно понять почему после AND часто используют BEQ или же BNE переход.
Немного о планах
В ближайшем будущем я планирую написать статью о массивах байтов и как правильно их использовать и для чего надо в zeropage грузить и старший и младший байт указателя. Не так давно я разобрался как сделать коллизии фона, основанных на bitmap с загрузкой для каждого перерисованного экрана своей карты коллизий.
Полезные ссылки
https://youtu.be/DiMMnTW7NzM - видео/ааудио презентация статьи
Программирование assembler 6502 nes/famicom/dendy векторы прерывания, процедуры и их вызов
https://habr.com/ru/post/719636/ - вывод спрайтов и анимация
https://www.nesdev.org/wiki/Status_flags - статус флаги на nesdev
serge-sb
"Состояние статус флагов это один из шести архитектурных регистров". Мозг сломан. Это как?
himysay Автор
Так что это один из 6-ти регистров процессора 6502