Статус флаги ассемблера 6502 nes/famicom/dendy

9f867de6fa217e0ffffa4fb15e98d897

Для более глубокого понимания как происходит ветвление в программах написанных на ассемблере 6502 необходимо углубиться в флаги и понять какие команды влияют на тот или иной флаг. Это поможет избежать множество ошибок связанных с не очевидностью ветвления вашей программы.

Состояние статус флагов это один из шести архитектурных регистров процессора 6502:

  • Регистр аккумулятора A

  • Регистры X и Y

  • Статус регистр (статус флаги)

  • Указатель стека

  • Программный счетчик

С регистрами A, X, Y мы уже знакомы, мы их часто используем для операций с данными и записи в различные порты процессоров. Указатель стека — хранит в себе указатель на последнее/первое значение стека. Программный счетчик — всегда указывает на следующую команду которую нужно будет выбрать и выполнить, он 16 битный и после выполнения обновляется указатель на следующую команду. Более подробно рассмотрим в следующих статьях работу с этими регистрами.

Давайте рассмотрим более подробно флаги они в регистре расположены следующим образом NV**DIZC где:

  1. N — Negative — этот флаг будет содержать 7-й бит результата если команда имеет результат

  2. V — Overflow — флаг переполнения устанавливается если при сложение (ADC) или вычитание (SBC) результат знакового числа получился больше/меньше диапазона -127 — +127

  3. D — Decimal — флаг указывающий на работу с десятичными цифрами в денди не используется

  4. I — Interrupt disable — флаг указывающий на то что отключены все прерывания кроме NMI

  5. Z — Zero — флаг указывающий что результат команды равен 0, часто используется в программе и ветвление с помощью BEQ (переход если равно 0) и BNE (переход если не равен 0)

  6. C — Carry — флаг переноса устанавливается если результат больше 255 или меньше 0 с беззнаковыми числами, так же устанавливается если при сравнение CMP результат больше либо равно. Тоже часто используется BCC (если очищен) и BCS (если установлен)

  7. * — не используемые биты

Собственно нас интересуют больше флаги 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 с загрузкой для каждого перерисованного экрана своей карты коллизий.

Полезные ссылки

© Habrahabr.ru