ZX-Ревю 1991 №7-8 1990 г.

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


СЕКРЕТЫ ПЗУ

(Продолжение).

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

Специально оговорим, что под словом "принтер" здесь понимается ZX-принтер -периферийное печатающее устройство, разработанное К. Синклером для компьютеров ZX-Spectrum. Его характерными особенностями является то, что он поддерживается командами интерпретатора БЕЙСИКа LLIST, LPRINT, COPY. За ним закреплен постоянный канал - "P". Он печатает в строку 32 символа, конструкция которых полностью совпадает с конструкцией символов на экране (8x8 пикселей).

Скорее всего Вы применяете для работы с компьютером точечно-матричный принтер, для которого в ПЗУ никакой поддержки нет. В этом случае Вы обеспечиваете физическую подстыковку с помощью специального интерфейса (последовательного RS232 или параллельного "Центроникс"), а программное управление - с помощью специальной небольшой программы - драйвера, которая зависит от того, какой интерфейс Вы подключаете.

Неплохо обо всем этом написано в разработке НТК "ПЛЮС" - "Интерфейсы "Спектрума".

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

Системные переменные.

TVDATA - 23566,23567.

Переменная содержит те параметры, которые сопровождают операторы INK, PAPER,FLASH,BRIGHT,INVERSE,OVER,AT и TAB. Если параметр один (для INK и пр.) - он содержится в младшем байте - по адресу 23566. Если же параметров два (AT и TAB) -первый содержится в младшем байте, а второй - в старшем.

DF-SZ - 23659.

Здесь хранится количество строк нижней части экрана.

S-POSN - 23688,23669.

Здесь хранятся номер колонки позиции печати и номер строки печати (при печати в главную часть экрана).

DF-CC - 23684,23685.

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

Область черно-белой графики занимает 6144 байта и располагается в адресах 16384 -22527.

Область цветовых атрибутов занимает 768 байтов и размещается в адресах 22528 -23295.

S-POSN-L -23690,23691.

То же, что и S-POSN, но для нижнего окна экрана.

DF-CCL-23666,23687.

То же, что и DF-CC, но для нижнего окна экрана.

ECHO-E - 23682,23683. Здесь хранятся номер колонки позиции печати и номер строки печати (при печати в нижнюю часть экрана в операциях INPUT).

P-POSN - 23679.

Здесь хранится номер позиции печати на принтере.

PR-CC - 23680.

Здесь хранится младший байт адреса текущего печатаемого символа в буфере принтера. Старший байт хранить не надо, поскольку он и так известен, т.к. весь буфер принтера имеет всего 256 байтов. Напомним, что он располагается в адресах 23296 - 23551.

MEMBOT - 23696 - 23727.

Это область памяти калькулятора. В тридцати байтах могут разместиться 6 ячеек памяти от M0 до M5 (по 5 байтов на каждое число или строковую переменную). Обычно калькулятор работает храня данные на своем стеке, но это не всегда удобно и иногда эти ячейки используются.

UDG - 23675,23676.

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

CHARS -23606,23607.

В этих ячейках хранится двухбайтное число, указывающее на 256 байтов ниже, чем адрес с которого начинается размещение образов символов в ПЗУ компьютера.

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

ATTR-P - 23693.

Содержит информацию о постоянных атрибутах экрана.

Биты 0, 1, 2 - INK.

Биты 3, 4, 5 - PAPER.

Бит 6 - BRIGHT.

Бит 7 - FLASH.

ATTR-T - 23695.

То же, что и ATTR-P, но для временных атрибутов.

MASK-P - 23694.

Эта системная переменная нужна для реализации режимов INK 8, PAPER 8, BRIGHT и FLASH 8 на постоянной основе.

Биты 0, 1, 2 - включены, если установлено INK 8. Биты 3, 4, 5 - включены, если установлено PAPER 8. Бит 6 включен в режиме BRIGHT 8. Бит 7 включен в режиме FLASH 8.

MASK-T - 23696.

То же, что и MASK-P, но для временных атрибутов.

Для тех, кто не все знает о "Спектруме" дадим некоторые пояснения:

"Временными" атрибутами называются те, которые действуют на один оператор печати. Они вводятся в команде PRINT через точку с запятой. А далее будут действовать

постоянные атрибуты. Например: 10 INK 5: PAPER 1 20 PRINT INK 7; PAPER 2; "ZX"

Здесь в строке 10 операторами INK и PAPER вводятся постоянные цветовые атрибуты. Они действуют на всю программу или до тех пор, пока не будут изменены другими такими же операторами.

В строке же 20 действующий оператор - PRINT, а INK и PAPER только устанавливают временные атрибуты, которые действуют только на эту строку.

Теперь несколько слов об INK 9 и PAPER 9. В принципе все знают, что "Спектрум" оперирует с 8-ю основными цветами, пронумерованными от 0 до 7. Тем не менее команды INK 8, PAPER 8 и даже FLASH 8 и BRIGHT 8, а также INK 9 и PAPER 9 могут иметь место.

INK 8, PAPER 8, BRIGHT 8, FLASH 8 устанавливают текущие атрибуты "прозрачными". Это означает, что при печати на экране атрибуты в знакоместе устанавливаются такими, какими они были в этом знакоместе до печати, очень удобно, если Вы не знаете, какими они были, но хотите их не изменять.

INK 9, PAPER 9 - устанавливают атрибуты "контрастными". Так, INK 9 установит цвет символов таким образом, чтобы он наилучшим образом контрастировал с текущим цветом PAPER.

Флаговые переменные.

Состояние битов расписывается справа налево, т.е. бит 0 - младший, а бит 7 -старший.

FLAGS - 23611.

Бит 0 - включен, если перед печатью не требуется ведущий пробел. Бит 1 - включен, если ZX-принтер подключен.

PFLAG - 23697.

Карта битов этой флаговой переменной характеризует установку атрибутов OVER, INVERSE, INK 9, PAPER 9. Включенное состояние этих битов означает: Бит 0 - режим OVER 1 (временный) Бит 1 - режим OVER 1 (постоянный) Бит 2 - INVERSE 1 (временный) Бит 3 - INVERSE 1 (постоянный) Бит 4 - INK 9 (временный) Бит 5 - INK 9 (постоянный) Бит 6 - PAPER 9 (временный) Бит 7 - PAPER 9 (постоянный).

TV-FLAG

Бит 0 - включен, если печать выполняется в нижнюю часть экрана (канал "K"). Бит 3 - включен, если идет редактирование программной строки. Бит 4 - включен при автоматическом листинге.

Бит 5 - включен, если при нажатии клавиши должна очиститься нижняя часть экрана. FLAGS-2

Бит 1 - выключен, если буфер принтера пуст.

Основными блоками этого раздела являются:

09F4 - 0A10 - PRINTOUT - выполняет функции диспетчера.

0A11 - 0A22 - таблица управляющих символов (кодов).

0A23 - 0A3C - CURSOR LEFT - управляет перемещением курсора влево.

0A3D - 0A4E - CURSOR RIGHT - управляет перемещением курсора вправо.

0A4F - 0A5Е - CARRIAGE RETURN - обработка кода "возврат каретки" (ENTER).

0A5F - 0A68 - PRINT COMMA - Обработка кода CHR$ 6.

0A69 - 0A6C - PRINT QUESTION MARK - печать вопросительного знака.

0A6D - 0AD8 - CONTROL CHARACTERS WITH OPERANDS - обрабатывает те управляющие коды, которые требуют наличия после себя определенного операнда.

0A09 - 0ADB - PRINTABLE CHARACTER CODES - выполняет печать печатаемых символов.

0ADC - 0B02 - POSITION STORE - запоминание координат знакоместа в системных переменных.

0B03 - 0B23 - POSITION FETCH -ввод координат позиции печати из соответствующих системных переменных.

0B24 - 0B7E - PRINT ANY CHARACTERS - печать символов, токенов, символов блочной графики и символов графики пользователя.

0B7F - 0BDA - PRINT ALL CHARACTERS - печать шаблонов символов

0BDB - 0C09 - SET ATTRIBUTE BYTE - обработка атрибутов.

0C0A - 0C3A - MESSAGE PRINTING -печать токенов ключевых слов и системных сообщений.

0C3B - 0C40 - PO-SAVE - вспомогательная подпрограмма.

0C41 - 0C55 - TABLE SEARCH - подпрограмма поиска в таблицах.

0C56 - 0D4C - TEST FOR SCROLL - проверяет необходимость "прокрутки" экрана.

0D4D - 0DCA - TEMPORARY COLOUR ITEMS - обработка временных установок атрибутов.

0D6B - 0DFD - CLS COMMAND - выполняет очистку экрана.

0DFE - 0E43 - SCROLLING - выполняет "прокрутку" экрана.

0E44 - 0E87 - CLEAR LINES - выполняет очистку заданного количества строк.

0E88 - 0E9A - CL-ATTR - определяет адрес байта в файле атрибутов экрана по координатам знакоместа.

0E9B - 0EAB - CL-ADDR - определяет адрес байта в экранном файле по координатам знакоместа.

0EAC - 0EDF - COPY COMMAND - обрабатывает команду COPY.

0EDF - 0EF3 - COPY-BUFF - передает данные из буфера на принтер.

0EDF - 0EF3 - CLEAR PRINTER BUFFER - выполняет очистку буфера принтера.

0EF4 - 0F2B - COPY LINE - копирует строку пикселей (в поддержку COPY COMMAND).

Теперь рассмотрим процедуры, входящие в эти подпрограммы подробно.

09F4 - 0A10 - PRINT-OUT.

При входе в данную процедуру в регистре A должен содержаться код печатного символа, управляющий код или код токена ключевого слова.

Процедура вызывает PO-FETCH для ввода координат позиции печати, а затем определяет что же за символ ей предстоит напечатать.

Если это печатный символ - переход на PO-ABLE (0AD9).

Если управляющий код от 00 до 05 - переход для печати вопросительного знака на PO-QUEST(0A69).

То же, если управляющий код от 18 до 1F.

Для прочих управляющих кодов (от 6 до 17) выполняется следующая операция:

Код символа прибавляется к базовому адресу таблицы управляющих кодов (0A11-0A22). Базовым служит адрес 0A0B. В этой таблице содержатся "смещения" адреса, с которого начинается процедура обработки данного кода относительно положения этого кода в таблице и результат отправляется на стек. Далее выполняется переход на процедуру PO-FETCH, заготовленный на стеке адрес процедуры обработки данного управляющего кода обеспечивает переход к ней после возврата по RET из PO_FETCH.

(Примечание: все управляющие коды Вы можете просмотреть в "Справочнике по программированию в машинных кодах Z-80" - т. 3 нашего трехтомника.)

0A11 - 0A23 - таблица управляющих кодов.

Здесь расположены "смещения" адресов для процедур обработки управляющих кодов, начиная с CHR$ 6 и кончая CHR$ 23 (TAB). Ячейки 0A19 и 0A1A - не используются.

Подпрограмма "CURSOR LEFT".

0A23 - 0A38 - PO-BACK-1.

При входе в эту процедуру в регистре B содержится текущий номер строки, а в регистре C - номер колонки.

Проверяется не достигнут ли левый край. Если нет, то переход на выходную процедуру PO-BACK-3.

Если да, то проверяется подключен ли принтер по первому биту FLAGS, в этом случае переход на PO-BACK-2.

Если край достигнут, переход на новую строку, проверка на то не последняя ли это строка и переход на PO-BACK-3.

0A36 - 0A39 - PO-BACK-2.

Регистр C устанавливается на крайнюю левую колонку.

0A3A - 0A3C - PO-BACK-3.

Переход на CL-SET (0DD9) для печати и последующего возврата через PO-STORE (0ADC).

Подпрограмма "CURSOR RIGHT".

0A3D - 0A4E - PO-RIGHT.

Процедура вызывает системную переменную P-FLAG, сохраняет ее на стеке, включает в ней первый бит (аналогично команде БЕЙСИКа) OVER 1; и вызовом процедуры PO-CHAR (0B65) печатает в той же позиции пробел (CHR$ 32) и восстанавливает со стека P-FLAG перед возвратом.

Процедура имеет ошибку. Дело в том, что возврат надо было бы делать через PO-STORE, чтобы запомнить в системных переменных координаты позиции печати.

Подпрограмма "CARRIAGE RETURN".

0A4F-0A5E- PO-ENTER.

Если печать идет на принтер (проверяется по FLAGS), в буфер принтера выдается символ CHR$ 13 переходом на COPY-BUFF (0ECD).

Если на экран - проверка на необходимость скроллинга вызовом PO-SCR (0C55) и переход на новую строку.

Выход выполняется переходом на CL-SET (0DD9).

Подпрограмма "PRINT COMMA".

0A5F - 0A68 - PO-COMMA.

Процедура выполняет ввод текущих координат позиции печати вызовом PO-FETCH (0B03), чего в принципе делать и не обязательно, поскольку это было уже сделано в PRINTOUT (09F1).

Позиция печати в регистре A проходит сравнение по AND 10H, в результате чего устанавливается либо нулевая, либо шестнадцатая колонка печати.

Выход выполняется переходом на PO-FILL (0AC3).

Подпрограмма "PRINT A QUESTION MARK".

0A69 - 0A6C - PO-QUEST.

При попытке распечатать непечатный символ должен выдаваться знак "?". Его код (3F) вводится в аккумулятор, а для печати выполняется переход на PO-ABLE (0AD9).

Подпрограмма "CONTROL CHARACTERS WITH OPERANDS".

Некоторые управляющие коды требуют после себя наличия операндов. Так, после кодов INK или PAPER должен идти байт, указывающий на то, какой цвет устанавливается. А такой код как AT требует даже два операнда для указания координат позиции печати.

0A6D - 0A74 - PO-TV-2.

Эта процедура обрабатывает второй операнд для операций AT и TAB и делает следующие операции:

Загружает в DE 0A87 - это адрес процедуры PO-CONT. Это нужно чтобы после PO-CHANGE обеспечить выход через PO-CONT.

Операнд направляется из аккумулятора в старший байт системной переменной TV-DATA и выполняется переход на PO-CHANGE (0A80).

0A75 - 0A79 - PO-2-OPER.

Сюда мы попадаем, если идет обработка управляющих кодов AT и TAB, т.е. тех, после которых идут два операнда.

Загружается в DE 0A6D - адрес процедуры PO-TV-2. Это нужно чтобы после PO-CHANGE сделать второй проход, поскольку операндов два. Далее переход на PO-TV-1.

0A7A - 0A7C - PO-1-OPER.

Это точка входа для управляющих кодов, после которых идет один операнд. Здесь только устанавливается в DE адрес 0A87 для обеспечения выхода через PO-CONT.

0A7D - 0A7Е - PO-TV-1.

Операнд направляется из аккумулятора в младший байт системной переменной TV-

DATA.

0A80 - 0A86 - PO-CHANGE.

Установленный выше адрес перегружается из DE в HL для обеспечения перехода на PO-CONT, если один операнд или на PO-TV-2, если есть еще и второй.

0AB7 - 0AAВ - PO-CONT.

Продолжает работу, когда операнды приняты и введены в TVDATA.

В качестве выходного адреса устанавливается 09F4 (PRINT-OUT). Это делается тем же способом, в DE вводится 09F4 и вызывается PO-CHANGE для переброски его в HL.

Если обрабатывается управляющий код от 16 до 21 (от INK до OVER), то переход на CO-TEMP-5 (2211), где изменяются цветовые системные переменные, а если код равен 23 (TAB) - переход на PO-TAB (0AC2).

Далее идет обработка кода 22 (AT). Изменяются координаты позиции печати (они хранились в BC). Если координаты выходят за допустимые пределы - переход на PO-AT-ERR (0AAC). Проверяется работа с принтером. Если печать идет на принтер - переход на PO-AT-SET (0ABF) иначе продолжение работы.

0AAC-0ABE - PO-AT-ERR.

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

В первом случае сразу выполняется переход на REPORT-B (1E9F) для печати сообщения Integer out of range.

Во втором случае проверяется не идет ли печать в нижнее окно экрана (по биту 0 переменной TV-FLAG). Если да, то переход на PO-SCR (0C55). Если печать идет в основную часть экрана, то проверяется сравнением с DF-SZ есть ли место для печати. Если его нет, то переход на REPORT-5 (0C86) для сообщения out of screen.

0ABF - 0AC1 - PO-AT-SET.

Выполняется возврат путем перехода на 0DD9 (CL-SET).

0AC2 PO-TAB.

Начинается обработка управляющего кода 22 (TAB).

0AC3 - 0ACF - PO-FILL.

Вызовом PO-FETCH (0B03) вводятся текущие координаты позиции печати. Вычисляется новая позиция печати. В регистре D устанавливается необходимое число пробелов.

0AD0-0AD8- PO-SPACE.

В цикле вызывается процедура PO-SAVE для печати пробелов. Цикл заканчивается, когда содержимое D становится равным нулю, далее - возврат.

Подпрограмма PRINTABLE CHARACTER CODES.

0AD9 - 0ADB - PO-ABLE.

Это только точка входа. Дальнейшая работа отсюда передается на PO-ANY (0B24) посредством ее вызова CALL. После возврата из нее работу продолжает PO-STORE.

Подпрограмма "POSITION STORE".

0ADC - 0AEF - PO-STORE.

Если печать идет на принтер (проверяется по FLAGS) - переход на PO-ST-PR (0AFC).

По системной переменной TV-FLAG проверяется в какую часть экрана идет печать - в главную или в нижние две строки. В последнем случае переход на PO-ST-E (0AF0).

Далее выполняется запоминание позиции печати в системных переменных S-POSN и DF-CC и возврат.

0AF0 - 0AFB - PO-ST-E.

Запоминает координаты позиции печати в системных переменных S-POSN-L, ECHO-E, DF-CCL и выполняет возврат.

0AFC - 0B02 - PO-ST-PR.

Если печать идет на принтер, координаты позиции печати запоминаются в переменных P-POSN и PR-CC. Далее возврат.

Подпрограмма "POSITION FETCH".

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

0B03 - 0B1C - PO-FETCH.

Если печать на принтере, переход на PO-F-PR (определяется по FLAGS), в противном случае выясняется в какую часть экрана идет печать (определяется по TV-FLAG).

Если печать производится в главный экран, то координаты позиции печати берутся из S-POSN и DF-CC, а если в "системном окне", т.е. в нижних двух строках экрана - из переменных S-POSNL и DF-CCL.

Далее - возврат.

0B1D - 0B23 - PO-F-PR.

Для печати на принтере координаты позиции печати снимаются из системных переменных P-POSN и PR-CCL. Далее возврат.

Подпрограмма "PRINT ANY CHARACTERS".

0B24 - 0B37 - PO-ANY.

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

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

Если это одиночный символ - переход на PO-CHAR (0B65).

Если это токен ключевого слова или символ графики пользователя - переход на PO-T&UDG (0B52).

Если это символ блочной графики, вызывается через CALL процедура PO-GR-1, выполняющая его конструирование. Поскольку PO-GR-1 "портит" координаты позиции печати, содержавшиеся в HL, то FO-FETCH вызывается еще раз.

Для самой же печати графического символа выполняется переход на PR-ALL (0B7F).

0B38 - 0B3D - PO-GR-1.

Графические символы конструируются с использованием ячеек памяти калькулятора M0 и M1, для чего сначала в регистре HL устанавливается адрес системной переменной MEMBOT, определяющей начало памяти калькулятора. Далее вызывается процедура PO-GR-2. Поскольку сама PO-GR-2 стоит сразу за PO-GR-1, то фактически по ней происходит два прохода.

0B3E - 0B4B - PO-GR-2.

На входе в эту процедуру регистр B содержит код символа блочной графики (от 128 до 143), он был установлен в PO-ANY.

Конструкция шаблонов символов блочной графики в "Спектруме" сделана очень интересно. В принципе она заложена уже в самом номере символа (а точнее - в его четырех младших битах). Если представить символ блочной графики как выполненный из четырех блоков, каждый из которых имеет размер 4x4 пикселя, то получится следующее:

1

0

3

2

Здесь цифрами показаны номера младших битов кода символа, отвечающие за цвет своего участка. Возьмем для примера символ с кодом 134. Разложим его на биты: 134 - 1000 0110.

Тогда четыре младших бита дают рисунок:

1

0

0

1

Закрасим единицы черным цветом и получим рисунок:

н

Этим декодированием и занимается процедура PO-GR-2, но только для первой строки символа (из восьми).

0B4C - 0B51 - PO-GR-3.

Здесь организовывается цикл (4 прохода), в результате которого определяются уже 4 верхние строки символа.

Поскольку, как мы уже говорили, процедура PO-GR-2, а вслед за ней и PO-GR-3 фактически проходятся дважды, то на втором проходе конструируются нижние четыре строки шаблона символа.

Заканчивается возвратом.

0B52 - 0B5E - PO-T&UDG.

Здесь мы можем рассмотреть как конструируются изображения токенов ключевых слов и шаблоны символов графики пользователя (UDG).

Сначала выполняется селекция. Если речь идет о печати токенов, то этим будет заниматься PO-T (0B5F), а для символов UDG вводится адрес, начиная с которого в памяти компьютера расположены их шаблоны. Адрес расположен в системной переменной UDG.

Для выполнения их печати выполняется безусловный переход на PO-CHAR-2.

0B5F - 0B64 - PO-T.

Отсюда для печати токенов вызывается PO-TOKENS (0C10), а по окончании печати безусловным переходом через PO-FETCH (0B03) выполняется возврат в вызывающую программу.

0B65-0B69-PO-CHAR.

Сюда передается управление из PO-ANY, если печатается обычный символ. На стеке сохраняются координаты позиции печати, а затем в BC устанавливается базовый адрес таблицы символов. Он берется из системной переменной CHARS.

0B6A - 0B75 - PO-CHAR-2.

Выключается нулевой бит FLAGS, что означает: "перед печатью дать пробел", а затем проверяется не "пробел" ли должен печататься. Если нет, то переход на PO-CHAR-3, а если да, то ведущий пробел не нужен и бит 0 FLAGS принудительно включается.

0B76 - 0B7E - PO-CHAR-3.

В регистре HL код печатаемого символа умножается на 8, а затем суммированием с базовым адресом таблицы символов определяется адрес, начиная с которого в ПЗУ расположены восемь битов, определяющих его конструкцию.

Подпрограмма "PRINT ALL CHARACTERS".

Эта подпрограмма служит для печати графических шаблонов символов размером 8x8. При входе сюда в регистровой паре DE содержится базовый адрес таблицы символов, в HL -адрес в дисплейном файле, в который помещается графическое изображение символа; пара BC содержит номер строки и столбца позиции печати. B-строка, C - столбец.

Процедура проверяет не достигнут ли конец строки. В зависимости от результата реализуется один из двух переходов на PR-ALL-1.

Далее проверяется куда идет печать. Если на принтер - вызывается процедура для копирования буфера принтера COPY-BUFF (0ECD), после чего прямым проходом мы идем к PR-ALL-1.

0B93 - 0BA3 - PR-ALL-1.

Если начинается новая строка, то вызовом PO-SCR (0C56) проверяется не надо ли делать "прокрутку" экрана.

Далее проверяется необходимость режима печати OVER по системной переменной P-FLAG. Если он включен, в регистре B выставляется FF, а если нет - 00 перед переходом на PR-ALL-2.

0BA4 - 0BB5 - PR-ALL-2.

Здесь проверяется необходимость режима печати INVERSE по системной переменной P-FLAG. Если он включен, в регистре C выставляется FF, а если нет - 00.

Подготавливая печать в аккумуляторе выставляется число 8 по числу строк в символе. Далее проверяется куда идет печать. Если на экран - переход на PR-ALL-3, а если на принтер - принудительно включается первый бит системной переменной FLAGS-2, что означает "буфер принтера не пустой".

0BB6 - PR-ALL-3.

Здесь только обмен содержимым между регистровыми парами DE и HL -вспомогательная операция.

0BB7 - 0BC0 - PR-ALL-4.

Из ПЗУ или ОЗУ принимается первая строчка шаблона символа (из восьми) и

обрабатывается в соответствии с установками OVER и INVERSE (определено в BC).

Если печать идет на принтер - переход на PO-ALL-6, а если на экран - на PR-ALL-5.

0BC1 - 0BD2 - PR-ALL-5.

Организует цикл по восьми строкам символа. Возвращается в PR-ALL-4 для печати второй и последующих строк (до восьмой).

После того, как весь символ напечатан, начинается обработка цветовых атрибутов, для этой цели вызывается PO-ATTR (0BDB).

Далее возврат.

0BD3 - 0BDA - PO-ALL-6.

Если печать выполняется на экран, то каждая следующая строка шаблона символа имеет адрес в дисплейном файле на 256 больше, чем предыдущая (это связано с особенностью формата экранного файла "Спектрума".) Просмотреть эту особенность и понять ее нетрудно простым экспериментом

FOR i=16384 TO 22527: POKE i,255: NEXT i

Кстати, этот эксперимент поможет Вам увидеть, что в области памяти экрана существуют три области, каждая по 2048 байтов.

Отслеживается такой шаг на 256 байтов командой INC D в процедуре PR-ALL-4. Когда же печать ведется на принтере, то этого делать не надо. Здесь приращение только на 32, что и выполняется увеличением содержимого регистра E на 20H за каждый проход.

Таким образом, эта процедура представляет собой путь обхода ненужной команды INC D, стоящей на выходе PR-ALL-4, если печать ведется на принтере.

Подпрограмма "SET ATTRIBUTE BYTE"

Рассмотрев печать графического изображения символа, перейдем к тому, как устанавливаются в оперативной памяти значения цветовых атрибутов экрана. В работе этих процедур активно используются системные переменные ATTR-T, MASK-T и P-FLAG.

0BDB - 0BF9 - PO-ATTR.

Сначала старший байт адреса позиции печати в дисплейной памяти делится на 8 для определения координаты знакоместа, а затем выполняется операция AND 03 для определения трети экрана, в которой выполняется печать. Вычисляется адрес, соответствующий заданному знакоместу в файле атрибутов и принимаются во внимание ATTR-T, MASK-T, P-FLAG.

Если бит 6 P-FLAG включен, то обрабатывается команда PAPER 9.

0BFA - 0C07 - PO-ATTR-1.

Обрабатывается ситуация INK 9, если бит 4 P-FLAG включен.

0C08 - 0C09 - PO-ATTR-2.

Это выходная процедура. В нужный адрес файла атрибутов заносится байт атрибутов знакоместа и выполняется возврат.

Подпрограмма "MESSAGE PRINTING".

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

0C0A-0C0F - PO-MSG.

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

0C10 - 0C13 - PO-TOKENS.

Процедура работает при печати токенов. Здесь в регистровую пару DE вводится базовый адрес таблицы токенов - 0095.

0C14 - 0C21 - PO-TABLE.

Вызовом PO-SEARCH по номеру сообщения (токена) отыскивается адрес его размещения в таблице.

Переходом на PO-EACH выполняется печать тех сообщений и токенов, которые не требуют ведущего пробела, для прочих выполняется вызов PO-SAVE для печати пробела.

0C22-0C34- PO-EACH.

Отсюда рекуррентно начинает печататься сообщение или токен символ за символом. Очередной печатаемый символ выставляется в аккумуляторе из DE. Если появляется символ, у которого включен 7-ой бит (символ больше 128), то это означает, что данный символ в сообщении или в токене последний. Его выключают, чтобы символ мог быть напечатан вызовом PO-SAVE (0C3B).

Тем не менее символ вновь восстанавливают из DE и вновь проверяют седьмой бит. Если он выключен, то символ не последний и идет переход к началу PO-EACH для печати очередного символа. В противном случае рассматривается вопрос о необходимости ведущего пробела.

Если печатается сообщение, в регистре D помещается 0, а если токен, то его номер в таблице токенов.

Проверяется код печатаемого символа. Если он равен 43 (символ $), то переход на PO-TRSP.

Если он знак препинания, цифра и т.п., т.е. меньше чем 41 (код буквы "а"), то выполняется возврат в вызывающую процедуру, в противном случае - проход на PO-TRSP.

0C35-0C3A- PO-TRSP.

Процедура выполняет подготовку печати ведущего пробела. Проверяется что печатается. Если это текстовое сообщение или токен RND, INKEY$ или PI, то ведущий пробел не нужен и выполняется возврат, иначе в аккумулятор загружается код "пробела".

Подпрограмма "PO-SAVE".

0C3B-0C40 - PO-SAVE.

Процедура исполняет печать символов рекуррентно. Она вызывает PRINT-A-1 (0010), которая вызывает PRINT-OUT и т.д. вплоть до самой PO-SAVE. Эта рекурсия прерывается только в PO-EACH или в PO-TRSP когда проходит последний символ (с включенным седьмым битом).

Подпрограмма "TABLE SEARCH".

При входе в нее в регистровой паре DE содержится базовый адрес таблицы, в которой размещены сообщения, а в аккумуляторе номер сообщения в таблице.

0С41 -0С43- PO-SEARCH.

Выполняет подготовительные операции для поиска.

0С44 - 0С55 - PO-STEP.

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

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

Подпрограмма "TEST FOR SCROLL".

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

- при обработке символа CHR$ 13 ("возврат каретки");

- при печати с указанием AT в нижней строке экрана (INPUT-строке);

- когда текущая строка печати заполнена и необходим переход к следующей строке.

При входе в эту подпрограмму в регистре B содержится номер текущей строки

печати.

0C56-0C85-PO-SCR.

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

В начале своей работы процедура выставляет на стеке адрес 0D09, поэтому при завершении работы по команде RET автоматически будет стартовать CL-SET, расположенная по этому адресу.

Если речь идет о печати в системное окно оператором INPUT AT (проверяется по нулевому биту TV-FLAG), то выполняется переход на PO-SCR-4.

Номер строки сравнивается с DF-SZ. Если он больше, то выход с переходом через адрес на стеке в CL-SET, а если меньше, то переход на REPORT-5 для печати сообщения.

При их равенстве встает вопрос о необходимости скроллинга.

Если компьютер находится в режиме автоматического скроллинга (проверяется по 4-му биту TV-FLAG) переход на PO-SCR-2.

Уменьшается на единицу счетчик строки и если достигнут ноль, переход на PO-SCR-3. В противном случае вызовом CHAN-ОРЕN (1601) открывается канал "K" и принудительно включается бит 4 в TV-FLAG. Напомним, что канал "K" осуществляет связь с клавиатурой. Возвратом выполняется переход в CL-SET.

0C86 - 0C87 - REPORT-5.

Вызывается процедура обработки ошибок ERROR-1 с кодом перехвата 04, что вызывает печать сообщения об ошибке "Out of screen".

0C88 - 0CD1 - PO-SCR-2.

Уменьшается на единицу содержимое системной переменной SCR-CT. Если достигнут нуль, то надо давать на экране запрос "scroll?". В противном случае работа продолжается переходом на PO-SCR-3.

Для печати сообщения открывается канал "K" вызовов CHAN-ОРЕN (1601) и вызывается процедура печати сообщений PO-MSG (0C0A).

Включается бит 5 TV-FLAG. Это является сигналом для очистки нижней части экрана после нажатия клавиши.

Включается бит 3 FLAGS (означает: "курсор - L").

Включается бит 5 FLAGS (означает: "Клавиша не нажата").

Вызывается процедура WAIT-KEY (15D4), ожидавшая нажатия клавиши.

После того, как клавиша нажата, она анализируется. В четырех случаях, когда Вы отказываетесь от скроллинга нажатием "N", "n", "BREAK" и "STOP", вызывается REPORT-D (0D00) для остановки и печати сообщения "BREAK-CONT repeats".

Нажатие любой другой клавиши означает продолжение скроллинга экрана.

Перед выходом на PO-SCR-3 открывается канал "S" вызовом CHAN-OPEN (1601). Напоминаем, что канал "S" осуществляет связь с экраном.

0CD2 - 0CEF - PO-SCR-3.

Теперь можно делать "скроллинг". Это выполняется вызовом CL-SC-ALL (0DFE).

Для отыскания адреса в экранной памяти, соответствующего текущему номеру строки, вызывается CL-ADDR (0E9B).

0CF0 - 0CF7 - PO-SCR-3A.

Управляет цветовыми атрибутами нижних двух строк экрана при скроллинге.

0CF6 - 0CFF - здесь хранится текст сообщения "scroll?". Как и положено, последний байт, содержащий знак вопроса инвертирован.

0D00 - 0D1B - REPORT-D.

Вызывается процедура обработки ошибок ERROR-1 с кодом перехвата 0С, что вызывает печать сообщения "BREAK - CONT repeats".

0D02 - 0D1B - PO-SCR-4.

Сюда мы попадаем, если печать должна быть выполнена в нижней части экрана (в окне системных сообщений). При попытке использовать более двух строк переход на REPORT-5. Если скроллинг не нужен - возврат. В противном случае подготавливается возможность скроллинга. Вызывается TEMPS (0D4D) для того, чтобы работать с временными цветовыми атрибутами.

0D1C - 0D2C - PO-SCR-4A.

Определяется необходимость скроллинга только нижних двух строк или всего экрана. В первом случае - переход на PO-SCR-4B, во втором случае - прямой проход туда же. Разница в содержимом регистра B, где установлено количество строк, подлежащих скроллингу. В аккумуляторе же содержится количество шагов скроллинга.

0D2D - 0D4С - PO-SCR-4B.

Шаг за шагом вызывается CL-SCROLL (0E00) до тех пор, пока содержимое аккумулятора не уменьшится до нуля.

По окончании цикла выполняются финишные операции по установке значений системных переменных, вызов процедуры CL-SET (0DD9) и возврат.

Подпрограмма "TEMPORARY COLOR ITEMS".

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

0D40 - 0D57 - TEMPS.

Здесь устанавливаются ATTR-T и MASK-T для нижней части экрана.

0D58 - 0D65 - TEMPS-1.

Здесь устанавливаются ATTR-T и MASK-T для главной части экрана.

0D65 - 0D6A - TEMPS-2.

Здесь устанавливается P-FLAG.

Подпрограмма "CLS COMMAND".

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

0D6B - 0D6D - CLS.

Здесь только вызов CL-ALL (0DAF) для очистки дисплейного файла.

0D6E - 0D86 - CLS-LOWER.

Вызовом TEMPS (004D) устанавливаются цветовые атрибуты. В регистр B вводится из

DF-SZ количество строк в нижней части экрана. Для их очистки вызывается процедура CL-LINE (0E44). Решается вопрос об атрибутах этих строк. В принципе они берутся из ATTR-T, но для двух самых нижних строк они выставляются равными цвету бордюра из системной переменной BORDER.

Организуется внешний цикл по установке атрибутов в строках. Счетчик цикла - в регистре B.

0D87 - 0D88 - CLS-1.

Это вершина внутреннего цикла по установке атрибутов в позициях строки. Счетчик цикла - в регистре C.

0D89 - 0D8D - CLS-2.

Тело внутреннего цикла.

0D8E - 0D93 - CLS-3.

Завершение внешнего цикла и принудительная установка в DF-SZ числа 2, поскольку в нормальных условиях для окна системных сообщений отводятся две строки.

0D94 - 0D9F - CL-CHAN.

Выполняются финишные вспомогательные операции, а именно:

- открывается канал "K" и далее: 0BA0 - 0DAE - CL-CHAN-A.

- устанавливается в качестве выходного адреса 09F4 (PRINT-OUT) и в качестве входного - 10A8 (KEY-INPUT).

0DAF - 0DD8 - CL-ALL.

Открывает канал "S", устанавливает в качестве временных постоянные атрибуты экрана и выполняет очистку 24-х строк (вызовом CL-LINE (0E44) с установленным в регистре B числом строк, подлежащих очистке.) Продолжает работу в CL-SET.

0DD9 - 0DED - CL-SET.

При входе в эту процедуру в паре BC хранятся номер строки экрана и номер позиции печати. Если печать идет на принтер, то только в регистре C содержится координата позиции печати.

Если печать идет на принтер, управление передается на CL-SET-2 а если в главную часть экрана - на CL-SET-1.

0DEE - 0DF3 - CL-SET-1.

Вызовом CL-ADDR (0E9B) формирует в HL адрес, соответствующий началу строки, номер которой содержится в B.

0DF4 - 0DFD - CL-SET-2.

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

Выход оформляется безусловным переходом на PO-STORE (0ADC) для запоминания координат позиции печати.

Подпрограмма "SCROLLING".

Количество строк, подлежащих скроллингу содержится в регистре B.

0DFE - 0DFF - CL-SC-ALL.

Это точка входа в процедуру после запроса "scroll?". Здесь в регистр B засылается 017H, что означает "скроллировать весь экран".

0E00 - 0E04 - CL-SCROLL.

Это главная точка входа. Вызовом CL-ADDR (0E9B) определяется адрес в дисплейном файле, соответствующий строке.

0E05 - 0E0C - CL-SCR-1.

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

В этой процедуре выполняется переход на CL-SCR-3, если скроллингу подлежат более чем 8 строк, т.е. предполагается такой переход. Если нет, то прямой проход на CL-SCR-2.

0E0D - 0E18 - CL-SCR-2.

Процедура обеспечивает переход из трети в треть посредством переброски информации в оперативной памяти командой LDIR.

0E19 - 0E43 - CL-SCR-3.

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

Подпрограмма "CLEAR LINES".

Эта подпрограмма выполняет очистку n нижних строк экрана, где n - это содержимое регистра B.

0E44 - 0E49 - CL-LINE.

Вызовом CL-ADDR (0E9B) в паре HL формируется адрес, соответствующий номеру строки.

0E4A - 0E4C - CL-LINE-1.

Подготовка к очистке пиксельных строк.

0E4D - 0E7F - CL-LINE-2.

Очищаются строки в следующем порядке: первая пиксельная строка первого символа; первая пиксельная строка всех символов ряда, переход на следующий ряд; если происходит переход между третями экрана - переход на CL-LINE-2; очистка первой строки второго и последующего рядов; переход на CL-LINE-1 для очистки в том же порядке второй пиксельной строки и последующих до восьми; очистка области атрибутов.

Атрибуты в главной части экрана берутся из ATTR-P, а для нижних двух строк устанавливаются по цвету бордюра - из BORDER.

0E80 - 0E87 - CL-LINE-3.

Завершает установку атрибутов и выполняет возврат.

Подпрограмма "CL-ATTR".

0E88 - 0E9A - CL-ATTR.

Эта процедура выполняет две функции:

- по заданному адресу графики в дисплейном файле отыскивает и возвращает в регистровой паре DE соответствующий ему адрес в файле атрибутов;

- по заданному номеру строки, содержащемуся в регистре в, возвращает в BC количество символов, которое имеется от начала этой строки до конца экрана.

Подпрограмма "CL-ADDR".

0E9B - 0EAB - CL-ADDR.

Процедура возвращает в паре HL адрес в дисплейном файле по заданному в регистре B номеру строки.

Подпрограмма "COPY COMMAND".

Суть команды COPY состоит в копировании графики экрана на ZX-PRINTER.

0EAC - 0EB1 - COPY.

Копирование производится построчно (176 строк). В этой процедуре настраиваются регистры перед входом в цикл.

0EB2 - 0EC8 - COPY-1.

Организуется цикл для 176 строк и в цикле вызывается COPY-LINE (0EF4) для копирования строк.

0EC9 - 0ECC - COPY-2.

Окончание цикла и переход на финишную процедуру COPY-END.

Подпрограмма "COPY-BUFF".

Подпрограмма вызывается в тех случаях, когда необходимо переслать содержимое буфера принтера на ZX-принтер.

0ECD - 0ED2 - COPY-BUFF.

Подготовка работы.

0ED3 - 0ED9 - COPY-3.

Организуется цикл, который в раз обращается к COPY-LINE (0ED3) для копирования информации из буфера на принтер.

0EDA - 0EDE - COPY-END.

Выключается двигатель принтера.

Подпрограмма "CLEAR PRINTER BUFFER".

0EDF - 0EE6 - CLEAR-PRB.

Подготовка к очистке буфера принтера.

0EE7 - 0EF4 - PRB-BYTES.

Последовательная байт за байтом очистка буфера. Выход переходом на CL-SET и далее PO-STORE.

Подпрограмма "COPY-LINE".

0EF4 - 0EFC - COPY-LINE.

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

Из аккумулятора на порт FB выдается 00 для включения мотора. Если до конца печати осталось две строчки, на порт FB выдается 02 -сигнал замедлить мотор.

0EFD - 0F0B - COPY-L-1.

Вызовом BREAK-KEY (1F54) проверяется нажатие клавиши BREAK и если она не нажата - продолжение работы переходом на COPY-L-2.

Если нажата, выдается 04 на порт FB (остановить мотор), очищается буфер принтера вызовом CLEAR-PRB (0EDF) и работа прерывается вызовом ERROR-1 (0008) с кодом перехвата 0C (BREAK - CONT repeats).

0F0C - 0F13 - COPY-L-2.

Проверка опросом порта FB на наличие принтера. Если принтер не подключен, немедленный возврат.

0F14 - 0F17 - COPY-L-3.

Начало внешнего цикла. Здесь в регистр E засылается очередной байт из буфера принтера и устанавливается параметр цикла в регистре B - 8 по числу графических строчек в печатной строке

0F18 - 0F1D - COPY-L-4.

Начало внутреннего цикла. Здесь печатаемые байты раскладываются на биты. В результате этой раскладки очередной печатаемый бит выставляется старшим битом в аккумуляторе.

0F1E - 0F2B - COPY-L-5.

В цикле выполняется печать. Печать выполняется побитно выдачей содержимого аккумулятора на порт FD. При этом младшие биты управляют мотором, а самой печатью (есть точка/ нет точки) управляет бит 7.

(Продолжение следует).




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Презентация - Perspective Commander 1.0: файловая оболочка.
Вступление - Не кто не думал, не гадал наверно, что я (SLIP) таки стану настоящим журналистом. А все началось с того, что ваш покорный слуга взял интервью у Льва Дурова...
BBS - График работы BBS'oк.
Party - Funtop: Репортаж Сергея Новикова - День первый: Compo.
Описание - описание программы 'CONVER-Commander V 4.23 pro' (часть первая).

В этот день...   21 ноября