Курс программирования на ассемблере для C64(Ghouls/Mechanix). Урок 1

Теперь мы изучим 4 новые команды:

  • ADC  ;ADD WITH CARRY
  • SBC   ;SUBTRACT WITH CARRY
  • CLC   ;CLEAR CARRY
  • SEC   ;SET CARRY

«ADC #$XX» — команда складывает значение в Аккумуляторе с числом XX и сохраняет результат обратно в Аккумулятор.  Прежде чем сделать сложение, нужно сбросить флаг переноса (флаг «C»), например:

Аккумулятор теперь содержит значение $18, потому что $15+$03=$18. Если мы теперь посмотрим на следующий пример:

Аккумулятор будет содержать значение $02. Кроме того, флаг переноса будет установлен, т.е. C — флаг равен 1.  Причиной этого является то, что в результате сложения сумма превышает 255 ($FF). Суммирование:

Конечно, результат дает $05, но посмотрите на результат здесь:

В результате получаем $06. Когда C-флаг установлен к результату автоматически добавляется 1. Таким образом,  всегда надо сбрасывать флаг C до сложения.

Постарайтесь понять следующие программы:

ЗДЕСЬ, мы знаем только что адрес $2001 с самого начала содержит $00. Если теперь мы предположим, что $2000 содержит $01, тогда результат сложения будет равен $FF и С флаг будет равен 0. Затем берется значение по адресу $2001 и складывается с $00, после чего результат сохраняется в $2001 (результат-$00).

Если предположим $2000 содержит значение $02, тогда первое сложение дало бы значение $00 ($02+$FE=$00), и С флаг будет установлен. Это приведет к тому, что сложение:

даст в результате $01, потому что  флаг переноса установлен (если он установлен, автоматически добавляется 1 к результату сложения).  АДРЕС $2000 имеет значение $00 и  значение по адресу $2001 равно $01. Итак: $00 и $01 в LOW/HIGH-BYTE формате дает значение $0100 (256) и он подходит очень хорошо, принимая $02+$FE=$0100.  Все это может быть трудно понять, но попробовать в любом случае надо. «SEC» & «SBC» работает так же, как «CLC» & «ADC» просто с противоположным эффектом. Вы не должны забывать включать C-флаг с «SEC» перед выполнением вычитания.

Попробуйте догадаться, что делает следующая программа:

BCC означает «BRANCH ON CARRY CLEAR» переход если C-флаг равен нулю.  BCS означает «BRANCH ON CARRY SET» переход, если C-флаг установлен (единица). В нашей программе значение C-флага равно нулю, потому что $FE+$01= $FF. Переход по BCC ZERO и цвет бордюра черный. Если мы вместо LDA #$FE написали бы  LDA #$FF, то был бы установлен C-флаг, потому что $FF+$01=$00 и компьютер выполнил бы BCS ONE вместо BCC ZERO. Бордюр в этом случае был бы белым.

Упражнение 5

Что произойдет в программе, если  вместо ADC #$01  поставить ADC #$XX, Где XX  — число больше, чем $01?

Скрытый текст

Мы знаем, пока 5 форм адресации, а именно:

  • LDA #$XX    ;DIREKT
  • LDA  $XX    ;ZERO PAGE
  • LDA $XXXX   ;ABSOLUT
  • LDA $XXXX,X ;ABSOLUT,X
  • LDA $XXXX,Y ;ABSOLUT,Y

Есть, конечно, соответствующий набор STA, помимо того, что не существует команды: STA #$XX. Однако, есть еще несколько LDA, а именно:

  • LDA $XX,X  ;ZERO PAGE,X

Эта команда работает точно также как LDA $XXXX,X, разница в том, что LDA $XX, X занимает на один байт меньше (почему?). Также существует и

  • LDA $XX,Y

Но не спрашивайте меня, почему. Есть даже 2 таких LDA:

  • LDA ($XX),Y ;INDIREKT,Y
  • LDA ($XX,X) ;INDIREKT,X

Обратите внимание на разницу между ними! Существует большая разница в том, как они работают!

LDA ($XX, X) трудно понять,  труднее объяснить и даже используется не часто.

LDA ($XX), Y — немного легче.

Пример:

Сначала сохраняется $00 и $A0, соответственно, по адресам $02 и  $03,  регистр Y равен нулю. Таким образом, задается адреса в  $02 и  $03. Там сейчас $00 и $A0. Затем берется значение по адресу $A000 и сохраняется в $0400. Затем Y увеличивается на единицу.  Цифры находятся в LOW/HIGH-BYTE формате $A000 — $00 и $A0. Младший байт $00 является более важным, чем старший байт $A0. Другими словами в нулевой странице задается адрес, который ваш компьютер использует для чтения.

Упражнение 6

Что делает следующая программа?

Скрытый текст

Регистр X имеет 5 методов адресации:

  • LDX #$XX    ;DIREKT
  • LDX $XX     ;ZERO PAGE
  • LDX $XX,Y   ;ZERO PAGE,Y
  • LDX $XXXX   ;ABSOLUT
  • LDX $XXXX,Y ;ABSOLUT,Y

Регистр Y соответственно тоже:

  • LDY #$XX    ;DIREKT
  • LDY $XX     ;ZERO PAGE
  • LDY $YY,X   ;ZERO PAGE,X
  • LDY $XXXX   ;ABSOLUT
  • LDY $XXXX,X ;ABSOLUTE,X

 

Но STX только 3:

  • STX $XX     ;ZERO PAGE
  • STX $XX,Y   ;ZERO PAGE,Y
  • STX $XXXX   ;ABSOLUT

Так что нет ничего подобного этому: STX $XXXX,Y. То же самое относится и к регистру Y.

Теперь зная о различных формах адресации мы можем сделать очень полезную программу, а именно процедуру перемещения данных:

Попробуйте проанализировать программу. Как вы уже догадались, копируется содержимое адресов  $6000-$6800 вниз в адреса $2000-$2800. $6800 — $6000 = $0800, т.е. так же, как 8 * 256. 256 байт называется блоком. Мы копируем 8 блоков. Командой CPX #$XX определяет, количество перемещаемых блоков. Каждый раз, когда X увеличивается на единицу, мы переместили 256 байт (1 блок).  Содержимое ячеек памяти $02 и $03 является адресом в LOW/HIGH-BYTE формате  для процедуры извлечения данных. Ячейки памяти$04 и $05 содержат адрес в LOW/HIGH-BYTE формате для процедуры сохранения данных.  Для перемещения экрана понадобится только 4 блока для перемещения, и по адресам $04 и $05 должны быть значения $00 и  $04, что эквивалентно адресу экранной памяти в LOW/HIGH-BYTE формате  ($0400). Если вы захотите сделать демо  более чем с одной картинкой, вам понадобится процедура перемещения, похожая на эту.

Добавить комментарий