Предлагаемый процесс обучения — КиберПедия 

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...

Предлагаемый процесс обучения

2023-02-03 18
Предлагаемый процесс обучения 0.00 из 5.00 0 оценок
Заказать работу

Вступление

Добро пожаловать в Retro Game Dev C64 Edition Volume 2. (Создание Ретро Игр на C64 . Часть 2 )

 

Об этой книге

Эта книга предназначена для тех, кто хочет развить свои навыки создания игр для Commodore 64 и изучить некоторые из более продвинутых функций, которые предлагает оборудование.

Отклик на первый том был потрясающим, и я благодарю всех вас за то, что вы приняли концепцию простого, но эффективного подхода к изучению сложного предмета. Участие в форуме и потрясающие моды, созданные на основе мини-игр космических шутеров и платформеров, намного превзошли ожидания.

Идея первого тома заключалась в том, чтобы предоставить структуру абстрактного кода библиотеки, чтобы детали кода сборки не мешали представленным концепциям разработки игр. Хотя это сработало, некоторые из наиболее частых запросов на второй том заключались в том, чтобы полностью объяснить весь ассемблерный код 6502, а также макросы библиотеки и подпрограммы. Эта книга направлена ​​на оба аспекта.

Он начинается с обширного руководства, охватывающего язык ассемблера 6502, графический чип VIC-II, звуковой чип SID и концепции компоновки памяти. Затем шаг за шагом создается игра Beach Bar. Это более крупная и многофункциональная игра, чем мини-игры из предыдущего тома, и включает в себя такие продвинутые концепции, как растровые прерывания и мультиплексирование спрайтов. Каркас кода библиотеки по-прежнему абстрагирован для ясности кода игры, но полные объяснения каждого макроса и подпрограммы включены в справочный раздел.

CBM prg Studio используется для разработки и предназначена только для Microsoft Windows. Примеры встроенного кода (prg) работают на эмуляторе (различные платформы), C64 Mini или реальном Commodore 64/128.

 

Предполагаемое знание

Информация в этой книге второго тома основана на первом томе и не предназначена для замены. Поэтому есть некоторые фундаментальные концепции, которые здесь не рассматриваются. Предполагается, что читатель не полный новичок, начальный пользователь. И знаком с этим:

• Двоичное (%), десятичное и шестнадцатеричное ($) число системы.

• Установка и настройка CBM prg Studio (удобное IDE для разработки).

• Установка и настройка эмулятора VICE Commodore (полностью бесплатен).

 

Предлагаемый процесс обучения

Чтобы получить максимальную отдачу от этой книги, я предлагаю следующие шаги:

• Загрузите ресурсы с www.retrogamedev.com.

• Запустите некоторые из предварительно созданных prg (программных файлов Commodore) в эмуляторе, на C64 Mini или на реальном Commodore 64/128.

• Следуйте книге, пробуя эксперименты, обращая внимание на предупреждения.

• Изучите предоставленную базу кода, используя в качестве справочника главу о макросах и подпрограммах библиотеки.

Веселитесь!

 

ЧАСТЬ I: ОБОРУДОВАНИЕ

Архитектура

Commodore 64 использует микропроцессор 6510, который является вариантом 6502 с дополнительными 6-ю доступными пинами ввода-вывода (P0-P5). Они используются для управления набором данных и для переключения банков карты памяти компьютера, позволяя использовать все 64 КБ ОЗУ (см. Главу 4).

Помимо этих дополнительных контактов, 6510 полностью совместим с набором команд машинного кода с процессором 6502 и форматом адресации. Поэтому информация о языке ассемблера для 6510, содержащаяся в этой главе, применима ко всему аппаратному обеспечению на базе 6502.

 

 

Шина (Bus) - это набор электрических сигналов, сгруппированных вместе для передачи связанных данных от одной части компьютера к другой. Двоичное представление числа помещается на шину путем установки каждого отдельного вывода числа 1 (5 вольт) или 0 (0 вольт).

 

 

16-разрядная адресная шина состоит из контактов A0-A15 и используется для определения местоположения 1 из 65 536 (64 КБ) отдельных ячеек памяти.

8-битная шина данных состоит из контактов D0-D7 и используется для передачи байта за раз между 6510 и памятью или вводом-выводом (I/O) с использованием ячейки памяти, указанной на адресной шине.

Шина управления (Control Bus) содержит чтение/запись (R/W) пин, который определяет направление шины данных, и вывод 0in (CLKIN), который принимает прямоугольный сигнал от 0 до 5 вольт со скоростью 1022727 циклов в секунду (NTSC) или 985248 циклов в секунду. второй (PAL) для синхронизации 6510 и операций с памятью или вводом-выводом.

6510 содержит ячейки памяти, называемые регистрами, встроенные в микропроцессор, которые действуют как временная рабочая область.

 

 


A = аккумулятор (8 бит)
X = индексный регистр X (8 бит)
Y = индексный регистр Y (8 бит)
PC = Программный счетчик (16 бит)
S = указатель стека (9-битный, 9-й бит зафиксирован на 1)
P = регистр состояния процессора (8 бит, 1 бит не используется):
           N = отрицательный (1 = отрицательный)
           V = переполнение (1 = переполнение)
           B = команда прерывания (1 = прерывание, вызванное прерыванием)
           D = десятичный режим (1 = десятичный режим)
           I = IRQ отключено (1 = IRQ отключено)
           Z = ноль (1 = нулевой результат)
           C = переносить (1 = переносить)

 

Аккумулятор (A) - это 8-битный регистр, используемый для выполнения арифметических и логических операций.

Индексы X и Y - это 8-битные регистры, используемые для индексации в памяти или в качестве переменных общего назначения.

Регистр программного счетчика (PC) - это 16-разрядный указатель на следующую команду машинного кода, которую нужно выполнить.

Регистр указателя стека (S) - это 8-битный указатель на область стека памяти между $ 0100 и $ 01FF (9-й бит предполагается равным 1).

Регистр состояния процессора (P) - это 8-битный регистр, используемый для отслеживания результатов операций с использованием 7 отдельных битовых флагов (1 бит не используется).

 

Обзор сборки

6510 работает путем последовательной обработки 8-битных команд машинного кода, также известных как коды операций или опкоды.

Данные, которые используются в операции, называются операндом. Например: 1 + 2. «+» - это операция (код операции), а «1» и «2» - операнды.

Режим адресации - это особый метод, используемый для определения местоположения операнда. Например, прямая выборка значения из области памяти или использование значения из области памяти в качестве индекса поиска в другую область памяти (см. раздел «Режимы адресации»).

В зависимости от конкретного кода операции и режима адресации дополнительные 1 или 2 байта данных могут следовать за 8-битным кодом операции в памяти, чтобы представить 8 или 16-битный операнд. Таким образом, полная инструкция машинного кода может иметь длину 1, 2 или 3 байта.

Обратите внимание, что несколько операндов в одной инструкции не поддерживаются на 6510. Приведенный выше пример может быть реализован как 2 отдельные инструкции. Сначала загрузите «1» в регистр, затем добавьте к нему «2».

 

Обратите внимание, что для 3-байтовых инструкций операнд составляет 2 байта (или 16 бит), но, как это ни парадоксально, младший байт предшествует старшему байту в памяти.

Например, шестнадцатеричный адрес $ 9023 будет помещен в память как $ 23 в качестве младшего байта, за которым следует $ 90 в качестве старшего байта. Это связано с тем, что 6510 имеет архитектуру с обратным порядком байтов из соображений производительности. Аппаратное обеспечение с прямым порядком байтов хранит 9023 доллара как 90 долларов, за которыми следуют 23 доллара в памяти.

6510 считывает коды операций и операнды в двоичном формате. По мере их последовательной обработки программный счетчик (PC) увеличивается каждый раз, чтобы указать на следующий байт данных, которые необходимо прочитать.

По мере увеличения размеров программ людям становится сложно писать и отлаживать большие потоки двоичных данных. Решение состояло в том, чтобы создать язык, который представляет коды операций в виде трехбуквенной мнемоники (слово, которое в некоторой степени читается человеком), и возможность представления операнда как двоичного, десятичного или шестнадцатеричного.

Этот «язык ассемблера» используется для написания кода в более удобочитаемой форме, и программа, называемая ассемблером, затем преобразует исходный код на языке ассемблера в его двоичный эквивалентный машинный код для запуска на микропроцессоре.

Ассемблер 6510 имеет 56 различных мнемоник, многие из которых работают с несколькими режимами адресации (см. Следующий раздел), в результате чего общее количество официальных кодов операций составляет 151. Поскольку каждый код операции имеет длину байта, есть место для максимум 256 кодов операции, что означает 105 неофициальных кодов операции (256–151). Иногда они становятся доступными в зависимости от ассемблера.

Вот мнемоника ассемблерного кода LDA с его шестнадцатеричным и двоичным представлениями машинного кода и режимами адресации для иллюстрации:


Здесь мы видим 8 машинных кодов операций для мнемоники языка ассемблера "lda". Ассемблер решает, какой код операции использовать, в зависимости от используемого режима адресации, который определяется форматом операнда в инструкции.

ВАЖНО! Формат мнемоники + операнда выбирает актуальную версию кода операции.

 

Откройте chapter1.cbmprj в CBM prg Studio.

 

Каждый раздел в главе 1 имеет свой собственный файл сборки, содержащийся в одном проекте, чтобы продемонстрировать затронутые темы.

Чтобы создать и запустить эти отдельные файлы в CBM prg Studio, вы должны переключиться на соответствующий файл и использовать Build-> Program-> And Run (или F5).

Build-> Project-> And Run (или Ctrl + F5) используется вместо этого, когда мы хотим собрать все файлы в проекте в одну программу. Это используется в следующих главах.

ВНИМАНИЕ! Есть 2 разных метода создания файлов.

 

Переключитесь на файл Assembly Overview.asm.

Прежде чем мы перейдем к кодированию на языке ассемблера, есть небольшая программа, которую нужно вставить в первую очередь.

Когда программа Commodore 64 загружается с помощью BASIC через команду «LOAD« * », 8,1», а затем запускается с помощью BASIC командой «RUN» (обратите внимание, что этот процесс автоматизирован при запуске через CBM prg Studio). Процессор 6510 сначала смотрит на адрес памяти $ 0801 для запуска программы BASIC.

Чтобы выполнить программу с машинным кодом из BASIC, необходимо ввести команду «SYS», а затем указать место в памяти программы в десятичном формате (например, SYS 2061).

Поэтому, чтобы автоматизировать процесс выполнения команды «SYS», мы вставляем короткую программу BASIC в ячейку памяти $ 0801, чтобы при загрузке программы она автоматически запускала нашу программу машинного кода.

 

Assembly Overview.asm

#region BASIC Loader

*=$0801 ; 10 SYS2061 ($080D)
          
byte $0B         ; Next BASIC line low byte($080B)
           byte $08          ; Next BASIC line high byte
          
byte $0A         ; Line number low byte (10)
          
byte $00          ; Line number high byte
          
byte $9E          ; SYS BASIC token
          
byte $32          ; ASCII 2
          
byte $30          ; ASCII 0
          
byte $36          ; ASCII 6
          
byte $31          ; ASCII 1
           byte $00          ; End of line
          
byte $00          ; Next BASIC line low byte(0=end)
          
byte $00          ; Next BASIC line high byte

; Our code starts at $080D (2061 decimal)
; after the 12 bytes for the BASIC loader

#endregion

 

CBM prg Studio предоставляет возможность вставить этот код с помощью Tools-> Generate SYS () Call.

#region и #endregion - это команды CBM prg Studio, которые позволяют сворачивать разделы кода в редакторе (аналогично Microsoft Visual Studio) и игнорируются ассемблером.

Чтобы продемонстрировать разницу между машинным кодом и языком ассемблера, в Assembly Overview.asm есть 2 версии простой программы. Первая программа размещает каждый байт в двоичном формате в памяти, начиная с адреса $ 080D (12 байтов после $ 0801 для загрузчика BASIC).

 

Assembly Overview.asm

           byte %10101001          ; $A9 = lda(immediate mode)
           byte %00000010          ; $02 = red
           byte %10001101          ; $8D = sta(absolute mode)
          
byte %00100000          ; $20 = EXTCOL low byte
           byte %11010000          ; $D0 = EXTCOL high byte
          
byte %01100000          ; $60 = rts(ret. to BASIC)

 

Существует 2-байтовая инструкция, состоящая из 1 байта для кода операции lda и 1 байта для цвета (красный = 2).

Затем есть 3-байтовая инструкция, состоящая из 1 байта для кода операции «sta» и 2 байтов для 16-битного адреса памяти $ D020 (помните, что младший байт, за которым следует старший байт для младшего байта).

Последний байт программы - это код операции «rts» (возврат из подпрограммы), который возвращается в BASIC после выполнения программы.

Вся программа составляет 6 байт (без загрузчика BASIC). Он загружает значение «2» для красного цвета в регистр аккумулятора (A), затем копирует это значение из аккумулятора в адрес памяти $ D020, по которому графический чип VIC-II ищет цвет границы.

По мере роста размера программы преобразование кодов операций, значений и адресов памяти в двоичные файлы становится трудоемким и подверженным ошибкам. Здесь помогает ассемблер.

Следующая программа делает то же самое, используя мнемонику ассемблера и шестнадцатеричные числа. Помните, что он компилируется в то же двоичное представление, что и предыдущая программа, поскольку 6510 может запускать только двоичный машинный код.

 

Assembly Overview.asm

           LDA #$02       ; load A (# = immediate mode)
           STA $D020      ; store A to $D020 memory
           RTS                    ; return to BASIC

 

Чтобы деактивировать предыдущий код, добавьте символ «;» перед каждой строкой кода (это называется закомментированием). Чтобы сделать этот новый код активным, удалите символы «;» перед каждой строкой кода. Новый код можно затем собрать и запустить с помощью Build-> Program-> And Run (или F5).

Попробуйте комментировать машинный код и комментировать код сборки ассемблера.

Для отладки программы сборки в CBM prg Studio, которая имеет загрузчик для BASIC в начале, байты загрузчика BASIC необходимо игнорировать. Это можно сделать двумя способами. Либо закомментируйте байты загрузчика для BASIC. (После этого вы можете отладить правильно, но программа больше не будет работать в эмуляторе VICE, поэтому не забудьте снять знаки комментариев позже).

Или пропустите байты загрузчика BASIC в отладчике следующим образом:

• Выберите Debugger-> Debug Program (или F8), чтобы скомпилировать программу в машинный код и открыть инструмент отладчика. (Debugger-> Debug Project (или Ctrl + F8) можно использовать для последующих глав, где несколько файлов собираются вместе).

• Выберите Registers->Set и измените значение программного счетчика с $ 0801 на $ 080D.

Установив программный счетчик на $ 080D, мы можем теперь пройти по программе и увидеть изменение значений регистра и памяти.

• Выберите Debug-> Step Program, чтобы увидеть изменение значения регистра (аккумулятора) AC на 02.

• Выберите Memory-> View…, чтобы открыть окно памяти и установить адрес $ D020.

• Снова выберите Debug-> Step Program, и значение памяти в $ D020 изменится на 02.

• Закройте отладчик и выберите Build-> Program-> And Run (или F5) для запуска в эмуляторе VICE.

Попробуйте изменить значение $ 02 для другого цвета границы.

 

Режимы адресации

Существует 13 различных способов, которыми 6510 может получить доступ к любым требуемым данным операнда для инструкции, известных как режимы адресации.

Каждая пара ассемблерной мнемоники / режима адресации имеет свой собственный отдельный код операции, хотя вам не нужно запоминать каждый код операции, поскольку ассемблер обрабатывает это на основе формата операнда.

Ниже приведен один пример каждого режима адресации с использованием единственной мнемоники сборки в каждом случае. Все доступные комбинации см. В справочной главе 6502.

1. Режим немедленной или непосредственной адресации ( i mmediate) используется, когда вам нужно жестко запрограммированное значение в качестве операнда для инструкции. Значение кодируется внутри самой инструкции, и, следовательно, инструкции не требуется адрес памяти в качестве операнда.

Например, «LDA # 2» - это 2-байтовая инструкция, 1 байт для кода операции «$ A9» (версия lda для непосредственного режима) и 1 байт для значения «2».

 

 

В CBM prg Studio символ «#» сообщает ассемблеру, что следующее число должно использоваться в немедленном режиме и, следовательно, не относится к адресу памяти. Номер может быть представлен в двоичном виде (с использованием префикса «%»), десятичном (без префикса) или шестнадцатеричном (с использованием префикса «$») виде.

Чтобы было ясно, "#" и префикс номера - разные вещи и не связаны между собой. Значек «#» определяет значение или адрес памяти, а префикс определяет основание числа.

ВНИМАНИЕ! "#" означает значение, иначе это адрес памяти.

2. Режим абсолютной адресации ( a bsolute) используется для доступа к 1 байту данных с использованием 2-байтового (16-битного) адреса памяти. Использование 16-битного адреса памяти позволяет ссылаться на все 65 536 (64 КБ) ячеек памяти в Commodore 64, поскольку 16-битное число может хранить значения от 0-> 65535.

Например, «LDA $ 1234» - это 3-байтовая инструкция, 1 байт для кода операции «$ AD» (версия LDA в абсолютном режиме), 1 байт для байта младшего адреса «$ 34» и 1 байт для байта старшего адреса «$ 12». Помните, что поскольку 6510 является с обратным порядком байтов, байты адреса памяти сохраняются в младшем, а затем в старшем байтах.

 

 

3. Режим адресации нулевой страницы ( zero page) используется для доступа к 1 байту данных с использованием 1 байтового (8-битного) адреса памяти. Поскольку один байт может хранить только значения от 0-> 255, этот режим используется исключительно с первыми 256 байтами памяти, известной как нулевая страница. Инструкции, ссылающиеся на нулевую страницу, выполняются быстрее и используют меньше памяти, чем их аналоги с абсолютной адресацией.

 

 

4. Режим подразумеваемой адресации ( i mplied) используется для инструкций, не требующих операнда. Обычно они работают со встроенными регистрами 6510. Например, «INX» - это 1-байтовая инструкция, состоящая только из кода операции.

 

 

5. Косвенный режим абсолютной адресации (indirect absolute) используется только для специального случая инструкции «JMP». Обычный JMP использует режим абсолютной адресации и имеет 2-байтовый (16-битный) адрес памяти для перехода к выполнению кода.

Эта косвенная абсолютная версия извлекает 1 байт из памяти по указанному 16-битному адресу, а также байт сразу после этого в памяти. Он использует значение первого байта в качестве младшего адреса, а значение второго байта - в качестве старшего адреса (с прямым порядком байтов), а затем перескакивает для выполнение кода в эту ячейку памяти. Так что эффективно, это переход через справочную таблицу.

 

 

6. Абсолютно индексированный режим X-адресации ( a bsolute i ndexed, X) используется для доступа к 1 байту данных с использованием 2-байтового (16-битного) адреса памяти, аналогичного режиму абсолютной адресации, за исключением того, что перед выборкой данных значение, содержащееся в регистре X, добавляется в 16-битный адрес памяти.

Например, «LDA $ 1234, X», где значение в X равно 3, эквивалентно инструкции режима абсолютной адресации «lda $ 1237».

Это полезно для циклов кода и может использоваться таким же образом, как «цикл for» в языке более высокого уровня.

 

 

7. Абсолютное индексирование, режим адресации Y (absolute indexed, Y) такой же, как и предыдущий режим адресации, за исключением того, что значение в регистре Y используется для смещения адреса памяти.

 

 

8. Индексированная нулевая страница, режим X-адресации (zero page indexed, X) используется для доступа к 1 байту данных с использованием 1-байтового (8-битного) адреса памяти и представляет собой нечто среднее между режимом адресации нулевой страницы и режимом абсолютной индексированной адресации. Значение в регистре X добавляется к 8-битному адресу памяти перед выборкой данных, но исходный адрес памяти ограничен нулевой страницей. Следовательно, он имеет преимущества нулевой оптимизации страницы.

 


9. Индексирование нулевой страницы, режим адресации Y (zero page indexed, Y) такой же, как и предыдущий режим адресации, за исключением того, что значение в регистре Y используется для смещения адреса памяти. Он также ограничен инструкциями «LDX» и «STX».


 

10. Индексированный режим косвенной адресации (indexed indirect) используется для доступа к 1 байту данных с использованием 2-байтового (16-битного) адреса памяти. Требуется 1 байтовый (8-битный) адрес памяти (следовательно, на нулевой странице), но перед выборкой данных значение, содержащееся в регистре X, добавляется к 8-битному адресу памяти. Затем данные в этом адресе памяти, а также байт сразу после этого в памяти используются в качестве окончательного 16-битного адреса памяти.

Например, «LDA ($ 12, X)», где значение в X равно 5, даст адрес «$ 17». Если «$ 17» и «$ 18» содержат «$ 51» и «$ A0», то последний 1 байт данных будет извлечен из адреса памяти «$ A051».

 

 

ВНИМАНИЕ! Индексированные косвенные и косвенные индексации немного отличаются.


11. Режим косвенной индексированной адресации ( i ndirect i ndexed) аналогичен предыдущему режиму адресации, за исключением того, что регистр Y используется для смещения адреса памяти, а смещение применяется после того, как выбраны 2 байта для 16-битного адреса памяти, а не раньше.

Например, «LDA ($ 12), Y», где значение в Y равно 5, сначала построит 16-битный адрес памяти из значений, содержащихся в «$ 12» и «$ 13». Если они содержат данные «$ 22» и «$ 91», то последний 1 байт данных будет извлечен из адреса памяти «$ 9122» + 5 = «$ 9127».

 

 

12. Режим относительной адресации (relative) используется для инструкций ветвления 6510 для перехода выполнения кода к заданному смещению от текущего местоположения счетчика программ на заданное значение смещения. Значение смещения - это число со знаком от -128 до +127 (верхний бит указывает положительное или отрицательное значение). Следовательно, эти инструкции ветвления могут перескакивать только на ограниченное количество байтов, и CBM prg Studio выдаст ошибку сборки, если смещение выходит за пределы допустимого диапазона.


 

13. Режим адресации аккумулятора (accumulator) аналогичен режиму подразумеваемой адресации, за исключением того, что инструкция работает только с регистром аккумулятора (A).

Например. «ASL» - это 1-байтовая инструкция, которая работает с аккумулятором.


 

Переключитесь на файл Addressing Modes.asm.

Прежде чем мы будем отлаживать и проходить код для этого раздела, важно представить 3 ключевые концепции, которые здесь используются в первую очередь.

Это константы, переменные и метки.

Константы - это способ назвать значение или адрес памяти, который можно использовать во всем коде. Они объявляются с помощью директивы «=». В качестве первого прохода ассемблер просматривает весь код и заменяет все вхождения имени константы связанным с ней значением. Следовательно, сами константы в программу не входят и не используют память.

По соглашению, в этой книге первая буква каждой константы пишется с заглавной буквы, а для констант, указывающих на аппаратные регистры, все слово делается с заглавной буквы. Значения могут быть указаны в двоичном (префикс %), десятичном (без префикса) или шестнадцатеричном (префикс $) виде.

 

Addressing Modes.asm

#region Constants

Black                 = $00
White               = $01
Red                   = $02
Cyan                 = $03
Purple              = $04
Green              = $05
Blue                  = $06
Yellow              = $07
Orange            = $08
Brown              = $09
LightRed         = $0A
DarkGray        = $0B
MediumGray = $0C
LightGreen    = $0D
LightBlue        = $0E
LightGray        = $0F

BGCOL0           = $D021 ; VIC-II Background Color

#endregion

 

Переменные используются как способ присвоения имен и резервирования ячеек памяти для использования в программе. Они зарезервированы с помощью директивы "byte" и имеют начальное значение по умолчанию. Следует проявлять осторожность, чтобы не объявлять переменную непосредственно в пути исполняемого кода, поскольку значения в них будут интерпретироваться как инструкции, вызывающие непредусмотренное поведение программы. Этот код объявляет их после инструкции «RTS» и, следовательно, никогда не будет достигнут путем выполнения кода.

 

Addressing Modes.asm

#region Variables

myVariable byte 0,0 ; 2 bytes reserved

#endregion

 

ВНИМАНИЕ! Не объявляйте переменные в пути выполнения кода.

В то время как инструкции по сборке вводятся с отступом в 1 табуляцию, метки - это имена, которые вставляются в код слева. Они служат для идентификации конкретной области памяти, которая может использоваться в качестве операнда для другой инструкции (обычно инструкции перехода). По сути, это константы, которые определяются ассемблером на его первом проходе. Преимущество использования меток вместо жестко запрограммированных адресов памяти состоит в том, что если код изменяется и, следовательно, изменяется место в памяти метки, ассемблер автоматически выполняет переназначение. Теперь мы можем отлаживать и выполнять код для этого раздела.

 

Addressing Modes.asm

#region Main
          
           LDA #White              ; 1. Immediate
           STA BGCOL0             ; 2. Absolute
           STA $FB                      ; 3. Zero Page
           TAY                              ; 4. Implied
           JMP (lut1)                      ; 5. Indirect Absolute
jumpToHere1                         ; label
           LDA lut2,x                       ; 6. Absolute Indexed, X
           STA myVariable,y        ; 7. Absolute Indexed, Y
jumpToHere2                               ; label
           LDA $FB,x                       ; 8. Zero Page Indexed, X
           STX $FA,y                       ; 9. Zero Page Indexed, Y
           LDA ($FC,x)                    ; 10. Indexed Indirect
          
LDA ($FC),y                    ; 11. Indirect Indexed
           BEQ jumpToHere2      ; 12. Relative
           ASL                                    ; 13. Accumulator
           RTS                                    ; return to BASIC

#endregion

 

Этот код является надуманным, поскольку его цель - продемонстрировать функциональность адресации памяти каждой инструкции, поэтому его результаты не особенно полезны.

• Выберите Debugger-> Debug Program (или F8), чтобы скомпилировать программу в машинный код и открыть инструмент отладчика.

• Выберите Registers->Set и измените значение программного счетчика (Program Counter) с 0801 на 080D.


• Выберите Debug-> Step Program, и значение регистра AC (аккумулятора) изменится на 01. Команда режима немедленной адресации «LDA» непосредственно загрузила значение $ 01 в аккумулятор. Обратите внимание, что константа «White» была заменена на $ 01 и это 2-байтовая инструкция. LDA # $ 01 - это ассемблерный код, который собирается в код инструкции (или машинный код) A9 01.

• Выберите Memory-> View…, чтобы открыть окно памяти и установить адрес $ D021.

• Выберите Debug-> Step Program, и значение памяти в $ D021 изменится на 01. Команда режима абсолютной адресации «STA» скопировала значение $ 01 из аккумулятора в 16-битный адрес памяти $ D021. Это 3-байтовая инструкция (AD 21 D0).

 


• Измените адрес в окне средства просмотра памяти на $ FB.

• Выберите Debug-> Step Program, и значение памяти в $ FB изменится на 01. Команда режима адресации нулевой страницы «STA» скопировала значение $ 01 из аккумулятора в 8-битный адрес памяти $ FB. Это 2-байтовая инструкция (85 FB).


 

• Выберите Debug-> Step Program, и значение регистра YR изменится на 01. Команда подразумеваемого режима адресации «TAY» скопировала значение $ 01 из аккумулятора в регистр Y. Это 1-байтовая инструкция (A8).



• Выберите Debug-> Step Program, и выполнение перейдет к следующей строке кода. Команда режима косвенной абсолютной адресации «JMP» считывает байт данных по 16-битному адресу памяти $ 082D (который был предоставлен ассемблером для метки «lut1»). Затем он взял этот байт и следующий за ним и выполнение кода перескочило на 16-битный адрес памяти $ 0818. Это 3-байтовая инструкция (6C 2D 08).

Чтобы сохранить младший и старший байтовый адрес памяти метки «jumpToHere1», директива CBM prg Studio «<» используется для получения младшего байта ($ 18) и «>» для получения старшего байта ($ 08).

Хотя в этом случае выполнение кода переходит к следующей строке кода и, следовательно, является избыточным, его использование происходит из-за того, что адрес перехода теперь хранится в таблице поиска, поэтому данные управляются. Эту метку перехода можно изменить так, чтобы она указывала на другую ячейку памяти, без необходимости изменять какой-либо код, который ее использует.

 

Addressing Modes.asm

#region Lookup Tables

; Variables for the look up tables
lut1
           byte <jumpToHere1 ; low byte of address
           byte >jumpToHere1 ; high byte of address

lut2
           byte Green
           byte Purple
           byte Cyan

#endregion

 

• Выберите Debug-> Step Program, и значение регистра AC (аккумулятора) изменится на 05. Инструкция «LDA» режима адресации с абсолютным индексом "x" скопировала значение $ 05 (зеленый - green) из 16-битного адреса памяти $ 082F (который был предоставлен ассемблером для метки lut2). Это 3-байтовая инструкция (BD 2F 08).

В этом примере значение регистра X равно 00, поэтому смещение не применялось. Если бы значение регистра X было 01, были бы получены данные с адреса $ 0830, который равен $ 04 (фиолетовый - purple).


 

• Измените адрес в окне средства просмотра памяти (Memory Viewer) на $ 082A.

• Выберите Debug-> Step Program, и значение памяти в $ 082B изменится на 05. Инструкция sta в режиме абсолютной индексации y-адресации скопировала значение $ 05 из аккумулятора по адресу $ 082A (который был предоставлен ассемблером для метки myVariable) + 1 (значение в регистре Y), поэтому $ 082B. Это 3-байтовая инструкция (99 2A 08).

Обратите внимание на то, как байтовые значения для таблиц поиска находятся в средстве просмотра памяти, поскольку они были определены сразу после 2 байтов для «myVariable» в памяти.


 

• Измените адрес в окне средства просмотра памяти на $ FB.

• Выберите Debug-> Step Program, и значение регистра AC (аккумулятора) изменится на 01. Инструкция «LDA» с индексированной нулевой страницей, режим адресации x скопировала значение $ 01 из 8-битного адреса памяти $ FB в аккумулятор. Это 2-байтовая инструкция (B5 FB).

В этом примере значение регистра X равно 00, поэтому смещение не применялось. Если бы значение регистра X было 01, данные из адреса $ FC были бы извлечены и так далее.


 

• Измените адрес в окне средства просмотра памяти на $ FA.

• Выберите Debug-> Step Program, и значение памяти в $ FB изменится с 01 на 00. Инструкция «STX» с индексированной нулевой страницей, режим адресации y скопировала значение $ 00 из регистра x в 8-битный адрес памяти $ FB. Это 2-байтовая инструкция (96 FA).

В этом примере значение регистра Y равно 01, поэтому было применено смещение 1, изменяющее ячейку памяти $ FB вместо $ FA.


 

• Измените адрес в окне средства просмотра памяти на $ FC.

• Выберите Memory->Set… и установите для адреса $ FC значение $ 2E.

 


• Выберите Memory->Set… и установите для адреса $ FD значение $ 08.

 


Это демонстрирует, как устанавливать значения памяти непосредственно во время отладки. Мы используем эти значения в этом случае для тестирования режимов адресации памяти. В реальной программе эти значения необходимо предварительно установить в память.

16-битная ячейка памяти $ 082E теперь установлена в память (с прямым порядком байтов) для использования в следующем примере режима адресации. Это зеленый цвет (05) в lut2.

• Выберите Debug-> Step Program, и значение регистра AC (аккумулятора) изменится на 05. Инструкция «LDA» режима индексированной косвенной адресации взяла значение $ 2E из адреса $ FC и значение $ 08 из адреса $ FD, а затем скопировала значение из этого адреса $ 082E в аккумулятор. Это 2-байтовая инструкция (A1 FC).

В этом примере значение регистра X равно 00, поэтому смещение не применялось. Если бы значение регистра X было 01, адрес поиска был бы прочитан из $ FD и $ FE.

 

 

• Выберите Debug-> Step Program, и значение регистра (аккумулятора) AC изменится на 04. Команда режима косвенной индексированной адресации «LDA» взяла значение $ 2E из адреса $ FC и значение $ 08 из адреса $ FD, затем добавила 01 из регистра Y и скопировал значение с этого адреса $ 082F в аккумулятор. Это 2-байтовая инструкция (B1 FC).

В этом примере значение регистра Y равно 01, поэтому к адресу поиска было применено смещение 1.


 

• Выберите Debug-> Step Program, и выполнение перейдет к следующей строке кода. Команда режима относительной адресации «BEQ» проверяла флаг нуля процессора (подробнее об этом в следующем разделе) и, поскольку он не установлен в 1, она не перескакивала на метку «jumpToHere2». Это 2-байтовая инструкция (F0 F6).

F6 представляет собой -4 байта, что является количеством байтов, которое ветвь перешла бы, если бы флаг нуля процессора был установлен в 1.


 

• Выберите Debug-> Step Program, и значение регистра AC (аккумулятора) изменится на 08. Команда режима адресации аккумулятора «ASL» сдвинула биты в позиции аккумулятора 1 влево, что удвоило значение 4 до 8. Это 1 байтовая инструкция (0A).

 


Следующая инструкция в памяти - это «RTS», которая возвращает нас к BASIC и подводит нас к концу этой примерной программы режимов адресации.

• Закройте отладчик и выберите Build-> Program-> And Run (или F5) для запуска в эмуляторе VICE.

Попробуйте изменить цвета таблицы lut2.

 

Обмен данными

6510 не может копировать данные напрямую из одной области памяти в другую. Он должен проходить через один из регистров микропроцессора (A, X или Y).

Следовательно, чтобы скопировать один байт из одной ячейки памяти в другую, мы могли бы использовать «LDA» для копирования из ячейки памяти в аккумулятор, а затем «STA» для копирования из аккумулятора в другую ячейку памяти. Значение в ячейке памяти, и<


Поделиться с друзьями:

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...

Типы сооружений для обработки осадков: Септиками называются сооружения, в которых одновременно происходят осветление сточной жидкости...

Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.188 с.