Перевод Тихоновой Н. А.
40 ЛУЧШИХ ПРОЦЕДУР
Данная книга является сокращенным переводом книги "40 Best Machine Code Routines For The ZX Spectrum With Explanatory Text", J.Hardman & A. Hewson, содержащей в себе набор программ в машинных кодах с весьма подробными разъяснениями принципов их работы.
Значительным сокращениям подверглись те разделы оригинала, в которых рассматриваются вопросы компьютерной терминологии и система команд Z80 - советуем обратиться к трехтомнику по программированию в машинных кодах, выпущенному "Инфоркомом".
При подготовке данного пособия были также исключены описания программ, которые не представляют, на наш взгляд, особого интереса.
РАЗДЕЛ А 1. ВВЕДЕНИЕ
Цель этой книги - обеспечить как начинающего, так и опытного пользователя компьютера ZX SPECTRUM полезными, интересными и развлекательными программами в машинных кодах. Книга имеет 2 раздела.
Раздел A описывает те особенности SPECTRUMa, которые важны при программировании в машинных кодах, некоторые процедуры системного ПЗУ, а также структуру машинного языка.
Раздел B представляет сами программы. Они представлены в стандартном формате, который детально описан в начале раздела. Программы полностью закончены, т.е. они могут быть загружены и использованы индивидуально, без обращений к другим программам.
Предлагаемые программы могут быть загружены с помощью простого загрузчика машинных кодов (MC-LOADER - маш. ЗАГРУЗЧИК), описанного в начале раздела В.
Общие сведения о Бейсике и машинных кодах
Микропроцессор Z80A, на базе которого сделан ZX SPECTRUM, не понимает непосредственно слова БЕЙСИКа. Такие, как PRINT, IF, TAB, и т. д. Вместо этого он выполняет приказы специального языка - своего внутреннего машинного кода. Процедуры ПЗУ, которые придают SPECTRUMy его индивидуальность, написаны на этом специальном языке и состоят из большого количества стандартных подпрограмм для ввода-вывода листинга, интерпретирования и выполнения команд BASICa и др.
Например, стандартные подпрограммы говорят процессору Z80A ("ЧТО ДЕЛАТЬ, ЕСЛИ..."). Если, например, команда BASICa - слово PRINT, то что делать, если следующий элемент имя переменной; или что делать, если следующий элемент - запятая и т. д.
Машинный код состоит из последовательности положительных целых чисел (от 0 до 255), которые диктуют действия для Z80A. Хотя машина использует двоичную форму представления чисел, нет необходимости для человека изучать команды в такой форме. Мы будем использовать десятичную форму, которая обрабатывается МС - ЗАГРУЗЧИКОМ из Раздела В.
Однако даже однообразную строку десятичных чисел трудно интерпретировать и поэтому десятичные числа обычно преобразовываются в специальный язык (ассемблер), который представляет собой определенные аббревиатуры. Язык ассемблера называется так потому, что специальная программа, называемая АССЕМБЛЕРОМ, используется для обработки ("сбора или ассемблирования") команд в машинных кодах при написании (формировании) программы.
Требуется только одно число, чтобы точно определить простую команду Z80A. Например, команда СКОПИРОВАТЬ содержимое регистра C в регистр D - это десятичное число 81 (термин "регистр" более детально описан в главе 3, а пока достаточно если Вы будете воспринимать C и D, как переменные BASICа). Для таких команд есть точное соответствие между десятичным числом и командой. 81, например, записывается на языке АССЕМБЛЕРа, как LD D^ ("LD", кстати, сокращение слова "load" загрузить). Многие команды ассемблера состоят из подобных простых аббревиатур по этой причине они часто называются мнемониками. Более сложные команды требуют 2, 3 или 4 числа. Но, все равно, для представления их используется одна команда ассемблера. Табл. 1.1. показывает список нескольких чисел, их мнемоник и краткое объяснение действия Z80A.
Таблица 1.1. Некоторые примеры машинных команд Z80A
Ссылка |
Десятичное число |
Мнемоника |
Комментарий |
(а) |
81 |
LD D,C |
Загрузить в D содержимое C |
(b) |
14 27 |
LD C,27 |
Поместить число 27 в C. |
(с) |
14 13 |
LD C,13 |
Поместить число 13 в C. |
(d) |
33 27 52 |
LD HL,13339 |
Поместить 13339 в пару регистров HL. Обратите внимание: 27+256*52= 13339; 27 поместить в L; 52 поместить в H. |
(е) |
221 33 27 52 |
LD IX,13339 |
Поместить 13339 в пару регистров IX. |
Строка (а) таблицы - пример LD D^ рассматривался выше, строки (b) и (с) показывают, как положительное число может быть загружено в регистр (используются два числа: первое определяет действие, которое должно быть выполнено, а второе определяет число, которое должно быть загружено). Строка (d) показывает, как большое целое число может быть загружено в два регистра (H и L) вместе. Здесь второе и третье числа определяют, какие числа должны быть загружены. Последний пример в строке (e) иллюстрирует четырехбайтовый код для загрузки большого целого числа в пару регистров IX. Обратите внимание, что три из четырех чисел такие же, как в строке (d). А дополнительное первое число определяет пару регистров IX вместо HL.
Структура машинного языка объясняется более подробно в главе 3, а полный список мнемоник ассемблера Z80A можно найти в литературе по микропроцессорной технике и программированию.
Итак, наиболее насущный вопрос:
ЗАЧЕМ ИСПОЛЬЗУЮТ МАШИННЫЙ КОД?
На некоторых компьютерах это делается потому, что задачи, которые пользователь желает выполнить, слишком медленно выполняются. В этом отношении ZX SPECTRUM не исключение. Рассмотрим, например, проблему сохранения полного отображения экрана в RAM (ОЗУ) или копирования его обратно на экран с целью создания эффекта мультипликации.
Файл изображения и цветовые атрибуты занимают 6912 байт. Следующая программа BASICa сохранит отображение экрана, но это займет много времени - около 70 секунд:
5 CLEAR 58623
10 FOR I=0 ТО 6911
20 POKE 58624+^РЕЕК (16384+I)
30 NEXT I
Причина такой медленной работы в том, что SPECTRUM тратит больше всего времени на декодирование команд BASICа перед их выполнением. Некоторое количество времени также тратится на преобразование чисел в двухбайтную форму (которую понимает Z80A) из десятичных чисел в пятибайтной форме (с которыми оперирует BASIC), а также на выполнение пятибайтовой арифметики.
Так, в нашем примере по переброске экрана должны быть выполнены следующие
шаги:
1. Прибавить i к 16384.
2. Преобразовать результат в форму двух байтов.
3. Восстановить содержимое адреса PEEK.
4. Прибавить i к 58624.
5. Преобразовать результат в форму 2-х байтов.
6. Сохранить полученное (РЕЕК) значение по заданному адресу (POKE).
7. Прибавить 1 к значению I и сохранить результат.
8. Вычесть i из 6911. Если результат положительный, то идти на пункт 1.
Во время прохождения цикла, SPECTRUM должен декодировать каждую команду снова, так как в данном случае память не используется для сохранения последовательности предыдущих действий. Легко увидеть, что компьютер тратит более 99 процентов времени на подготовку к выполнению задачи, а не на выполнение самой задачи. Аналогичная программа в машинных кодах для сохранения экрана выполняется практически мгновенно. Пример такой программы дан в Разделе В.