Операционная система Спектрума 1993 г.

Глава 2 - как вызывать подпрограммы.


ГЛАВА 2

КАК ВЫЗЫВАТЬ ПОДПРОГРАММЫ

16К ПЗУ

Перед использованием процедур ПЗУ всегда очень важно сохра-
нять "Н"' и "L'" регистры и восстанавливать их перед возвратом в
БЕЙСИК, при котором "IY" регистр должен содержать адрес систем-
ной переменной "ERR NR" 23610(5C3Ah).

П Сообщения: RST 16 (10h)

Строчное значение, код которого содержится в регистре "А", бу-
дет напечатан в любом открытом в настоящий момент потоке. Это
может быть использовано для вывода управляющих кодов (т.е. TAB,
INK, OVER и т.д.; детали см. в Справочнике СПЕКТРУМа).

D Открытие и закрытие потоков (для RST 16 (10h)):
CALL 5633 (1601h)

CALL 5633 (1601h) при вызове устанавливает вывод для RST 16
(10h) в поток, указанный в регистре "А". Обычно при:

А=2 - печать идет на основной экран,

А=3 - на принтер, а если

А=1 или А=0 - на нижний экран.

Другие потоки при использовании INTERFACE 1, могут быть
распределены для вывода на накопитель или другие элементы. Д ета-
ли распределения потоков при решении конкретных задач (например
контроля интерфейса для других нужд, кемпстона или интерфейса
принтера CENTRONICS) даны ниже в этой главе в разделе «РАС-
ШИРЕНИЕ СИМВОЛОВ ДЛЯ ВЫВОДАр:::!:!;;;;;:;

□ Контроль нажатия "BREAK": CALL 8020 (1F54f^

Эта подпрограмма тестирует ввод "CAPS SHIFT" и "SPACE": При
необходимости протестировать только "SPACE" см. далее:;раздел
«ВВОД СИМВОЛА С КЛАВИАТУРЫ», там всё Сложено r деталях.
Сейчас же можно использовать:

LD A,7Fh

IN A(OFEh)
RRA

JP NC.PRESSED

□ Установка позиции печати прй;:йёпользовании
RST 16 (10h): CALL 3545 (DD9h)

Координаты позиции печати:перед этим вызовом помещаются в
"ВС". При этом необходимо, чт^^:рёгйетр "В"содержал номер стро-
ки экрана в форме:

В = 24 - N (N - номер строки)

(т.е. если 6=24^ то это верхняя строка экрана; если В=1 - нижняя
строка). К сожалеШюизгзаош10шности^дрц:ущенной при написании
ПЗУ, вы не сможете ;йСНбльзовать 23-Й; й 24-ю строки основного
экрана, поэтому нужно'йёпшдо нижний экран, устанавливая
выходной поток для RST 16 (ШШ[равным 1 и используя две верхние
строки нижнего экрана.

Регистр С - номер; колонки с учетом:

С = 33 - N (N - номер колонки)

(т.е. если С=33,;^о э^;йёбая ксшонка; если С=2 - правая). Какой
бы поток вы не использовали, вызов 5633 (1601h) автоматически дает
сообщение о системных переменных для позиции печати. Некоторая
сгсторф^ость. необходима при работе с последней строкой основного
экрана,:тщкак; при печати в последнюю позицию нижней строки
будет выдаваться;предупреждающее сообщение "SCROLL?", а это в
свою очередь приведетквдзвращению в БЕЙСИК, если в ответ будет
введено "N" или ^РЖЩ'^Кроме этого, любая попытка печати в
поток 1 приведет к "SCROLL" нижнего экрана, при заполненном
месте для печати, определяемом системной переменной "DFSZ
(23659)". Это может привести к непредсказуемым результатам. Оче-
видно, что при печати на принтер невозможно установить номер
строки, т.к. регистр "В" не используется.

□ Стирание всего экрана: CALL 3435 (D6Bh)

Этот вызов очищает весь экран, применяя атрибуты, хранящиеся
в системной переменной "ATTRP" - для основного экрана и
"BORDCR" для нижнего экрана (23693 и 23624, соответственно; см.
СПРАВОЧНИК СПЕКТРУМа).

□ Стирание нижнего экрана: CALL 3438 (D6Eh)

Этот вызов очищает нижний экран и сбрасывает атрибуты. При-
мечание: и 3435 и 3438 устанавливают "DFSZ" в 2 и могут тем самым
изменить текущий поток, используемый RST 16, поэтому он должен
быть соответственно изменен. При этом текущая позиция печати
устанавливается в верхнее левое положение для обоих экранов

□ SCROLL всего экрана: CALL 3582 (DFEh)

Этим вызовом производится "SCROLL" на одну строку вверх с
сохранением позиции печати. Если вы продолжаете печатать в той
же строке, то по окончании произойдет как на печатной машинке
(печать, начинающаяся в конце страницы переходит вверх после
каждого перевода каретки).

□ Рисование на экране: CALL 8933 (22Е5И)

Точка X, Y указанная в регистре "В" (Y 0-175) и в регистре "С" (X
0-255) будет размещена на экране. Требующийся цвет задается за-
грузкой системных переменных атрибутов "INK" и "PAPER", или
используются текущие атрибуты. Командой

"SET 0,(IY+87)"

может быть установлен "OVER1", отключен же командой

"RES 0,(IY+87)".

Стирается точка командой "SET 2,(IY+87)". Примечание: при
этом вызове точки печатаются и на нижний экран, но, если этого не
нужно, то требуемый поток определяется вами с помощью команды
вызова 5633 (1601h).

□ Вывод числа в поток.

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

LD DE rADRES

LD HL,SPARE

LD (HL)fD

INC HL

LD (HL)r E

; адрес, где размещено число
WORD

Теперь можно использовать подпрограмму ПЗУ 6696 Г(1!А28И),
при этом в "HL" необходимо помещать адрес "SPARE WORD'!^ выво-
димого в коде "ASCI" в текущий поток. При этом:

Вывод будет корректным, если число целШ:и.,меньше
Пятизначные числа необходимо выводить с пробёлюм;;йрзд
во избежание их слияния в строке, для четырехзначных этого делать
ненужно.

10 ООО.

числом

Те, кто читал об этих вызовах в ЪРЙСТЩМ;POCKET BOOK",

но не использовал их практически, назовут меня:ЩШ)том. В этой
книге автор пишет, что регистр "Е" управляет способам представле-
ния числа, но применив эту процедурны поймете, что я описываю
не тот случай, потому что у меня pёшc^jp!i::E,, игнорируется. Это
довольно двояко: 1) Для обхода первой части; ПЗУ У касающейся "Е"
можно написать свою маленькую программу:

PUSH

DE

LD

D,(HL)

INC

HL

LD

E. (HL)

PUSH

HL !::...

EX

DE; НШ •

LD

E,20h

JP

lA30h

Примечание: последней в эт6м;таксте должна быть "JP", лишь
после этого вызывается: ироцедура, которую вы написали. В против-
ном случае стек будет испорчен, т.к. на его вершине размещен адрес
возврата (командой; "PUSHntliiijSi;юрманда "POP" использует именно
эти значения. Теперь вй^йй- чтб регистр "Е" уже загружен и автор
"SPECTRUM POCKET;ШОК" не ярав, т.к. это двойной старт проце-
дуры вследствие двойной загрузки; Теперь можно изменить загрузку
"LD Шв:этои процедуре, но загружаемое число должно быть либо 48
(DEC), впервыми печатаются нули, либо 25 (DEC),
когда при пёч^та; игнорируется незначимая часть числа. «Минуточ-
ку!», скажете вы, «тшёрь я могу видеть, почему изменился порядок
байта!». Совершенно верш, если вы поменяете порядок загрузки
"DE" или просто загрузите"HL" числом, которое не нужно перевора-
чивать этой программкой^то это будет стоящая подпрограмма, кото-
рую можно использовать для выведения в поток символов. 2) Есть
еще одна часть процедуры ПЗУ (начинающаяся с точки lAlBh),
которая не будет детализирована. Она просто берет число из пары
"ВС" и выводит его без нулей слева или пробелов и, как мне кажется,
во многих случаях будет весьма полезна.

Я думаю читатель найдет возможным применять эти процедуры
для вывода чисел любых размеров, однако может оказаться проще
использовать процедуры, которые берут значения из стека кальку-
лятора (см. Главу 8).

□ Ввод символа с клавиатуры.

Команда RST 56 (38Ю используется компьютером для сканиро-
вания клавиатуры и присваивания новых значений системной пере-
менной "FRAMES". Вызывается она маскируемым прерыванием. Ес-
ли требуется лишь подтверждение нажатия, то можно использовать
пятый бит "FLAGS" 23611 (5C3Bh); если бит активен, нажатие про-
исходило с момента последнего обнуления этого бита, но бит должен
сбрасываться специально.

Код последней нажатой клавиши можно найти по адресу 23560
(5C08h) "LASTK" (см. Главу 4), этого обычно достаточно для ввода с
клавиатуры, но есть некоторые неудобства.

Во-первых, смена значений производится 0 раз в секунду, поэто-
му нельзя использовать команду "RES 5" сразу после просмотра бита,
т.к. очевидно, что даже если клавиша была нажата, клавиатура не
успеет быть опрошена при прерывании.

Во-вторых, если прерывания отключены, клавиатура никогда не
изменит своего значения. Поэтому следующие строки положат в "А"
код ключа "NO KEY", или 0, если ничего не было нажато.

LD

HL,23611

;системная переменная
:"FLAGS"

RES

5,(HL)

LD

A, FFh

LD

(23552),A

;23552 часть системной

;переменой"К$ТАТЕ"

PUSH

HL

RST

56

POP

HL

XOR

A *t

BIT

5,(HL)

JP

Z,N0 KEY

LD

A,(23560)

;"LAST К" системная

;переменная, где всегда код
;последнейвведенной клавиши

В вышеуказанной программе "LD HL,23611" можно опустить и
вместо этого может быть проверена (IY+1), ведь "IY" содержит адрес
"ERR NR" (23610) (5C3Ah) и ПЗУ использует его для адресации
системной переменной. Вот почему, если вы используете в вашей
программе "IY", то вы должны уяснить, отключены ли прерывания
или направлены на ваши собственные процедуры и нужно возвратить
"IY" к корректному адресу перед использоМЩШ;ПЗУ или возвраще-
нием к режиму нормальных прерываний.

Нельзя определить, было ли нажато сразу несколько:клавиш
одновременно потому, что "SPECTRUM" игнорирует комбинацию
ключей, не имеющую смысла. Для преодоления этого можно напи-
сать свою программу сканирования клавиатуры:. Для началайнужно
просто определить факт нажатия. Что-то подобной делает следующая
программка:

X0R А

IN A,(FEh)

LD D,31

AND D

XOR D

JR Zf NO ; клаврй; ; :

Клавиатура может быть сканирована и болёё Шдробно, для этого
в "А" загружается значение линии^ которая должна быть сканирована
перед командой "IN A, (FEh)". Втлавё;23.справочника "SPECTRUM"
описано подробно, каким образом у стройка;: клавиатура, кратко - в
приложении "D". Первая строка в каждом случае - это нулевой бит,
вторая - бит четыре. Для определения бита опрошенной строки ниже
дано шестнадцатиричное значение, загружаемое в регистр "А":

CAPS SHIFT ;;
A

V

FEh
FDh

Q

T

FBh

" ■ : 1

5

F7h

0

6

EFh

p

Y

DFh

;;;;;;;;; ENTER

H

BFh

В

7 Fh

Так, например,• -йтрбы ;проверить, была ли нажата "ENTER",
нужно написать следующее:

LD A,OBFh

IN Ar(OFEh)

AND 1

JR Z/ENTER PRESSED

Чтобы узнать, была ли нажата более чем одна клавиша на одной
и той же строке, можно использовать логические операторы "AND",
"OR" и т.п., или программу тестирования битов (см. CALL 5598
(15DEh)) при вводе обычных символов.

□ Ожидание ввода: CALL 5598 (15DEh)

Это очень полезная программа, позволяющая делать ввод с лю-
бого потока и имеющая адрес ввода. Командой 5633, описанной вы-
ше, поток открывается для ввода. При работе эта подпрограмма в
свою очередь вызывает процедуру ввода текущего канала. При воз-
врате из нее проверяется флаг переноса и, если он установлен, осу-
ществляется возврат в основную программу. Если флаг при возврате
не был установлен, то проверяется нуль-флаг и процесс повторяется
заново, если он активизирован. Обычно при текущем вводе
"SPECTRUM" использует программу ввода с клавиатуры, но если в
"CURHL" установлен адрес канала, указывающего на адрес вашей
подпрограммы, то ввод будет осуществляется из нее (см. главу 5).
При использовании потока 1 (клавиатура и нижний экран), проце-
дура будет ждать, и по нажатии клавиши положит в "А" ее код. Это
продемонстрировано в программе "DEBASE" (см. приложение G).
Однако есть сложности: при каждом вызове этой процедуры проверя-
ется "TVFLAG 23612 (5C3Ch) IY+2" и если бит 3 активен, то входной
буфер копируется в редактируемую часть экрана. Это может быть
преодолено использованием процедуры «ВВОД КЛАВИШИ» 4264
(10А8Ю, а не через программу ожидания ввода. Это применено в
"DEBASE" (см. приложение G с метки "INPUT"). Эти строки анало-
гичны программе «ОЖИДАНИЕ ВВОДА», но всегда контролируется
сброс флага "MODE CHANGE". Программа «ОЖИДАНИЕ ВВОДА»
используется с метки "INPUTF" и если введена она, или ее часть, то
суть проблемы может быть продемонстрирована нажатием "CAPS
SHIFT" и "SIMBOL SHIFT" для выхода в "EXTENDED MODE" (рас-
ширенный режим). При этом последний веденный с клавиатуры сим-
вол появится в нижней части экрана.

При использовании этой процедуры должны быть включены и
прерывания, и вызываемая в цикле процедура нормальных прерыва-
ний 56 (38h), иначе ввод не произойдет.

О Копирование экрана на принтер: CALL 3756
(OEACh)

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

□ Печать графики на принтере: CALL 3789 (OECDh)

Эта процедура похожа на копирование: экрана тем, что она ис-
пользует буфер принтера и выводит его содержимое на бумагу. При
этом используется процедура "RST 16м, работающая^буфером, как
с одной строкой экрана высотой 8 пиксель. Если вы разместите в одну
линию буфера ваш рисунок и затем сделаете вызов по этому;адресу,
то буфер распечатается принтером. Примечание: буфер выводится
построчно линиями пиксель (по 32 байт), а цё; побуквенно,;;как на
экран. По завершении вывода буфер обнуляется;;;;:

□ Очистка буфера принтера: CALL 3807 (EDFh)

Этот вызов обнуляет буфер принтера^ .....

□ Использование "ВЕЕР" CALL 949 (3B5h>

Для этой программы необходимо поместить в: пару регистров
"DE" - время звучания, "HL" - частоту.

Здесь: 0 - высокий звук, FFFFh - низкий.

Чем выше тон, тем короче звук:,
должна быть учтена. Необходимые значения рассчитываются следу-
ющим образом:

HL = 437500 / частота - 30.125 (частота® Гц)

DE = время * частота (время в сек;)

30.125 вычитается

и эта линеиная зависимость

процедура 120.5 периодов

:штому, что сама:
генерирует ноту, потом очищает регистры и т.д. Нота «до» первой
октавы примерно 261 Гц, следовательно, в "HL" должно быть число
1646 (DEC), а в "DE" для одной секунды 261 (DEC). Помните, пре-
рывание осуществляется 50 раз в секунду и если вы запишите вашу
программу в нижнюю часть 16К ОЗУ, звук будет промодулирован
сигналами прерываний.

□ Печать сообщений: CALL 3082 (COAh)

Для этого вызова пара "DE": должна содержать начальный адрес
таблицысообщений, в которой бит 7 должен быть в 1, а регистр "А" -
содержать смещение начала сообщения в таблице, седьмой бит по-
следнего байта сообщения; должен быть активизирован. Первое сооб-
щение имеет смещение: 9.; ; Если вы хотите напечатать сообщение "I
AM" вы можете написать строку вроде: 'MESSAGE DEFB 80h : DEFM
"I AM": DEFB" "+80h Программа теперь прибавляет 80h, корректно
выводя последний пробел и зная, что достигнут конец, произведет
возврат к вызывающей программе. Таким образом целиком програм-
ма выглядит примерно так:

LD Аг0 ;для печати первого

CALL PRIMES ;списка сообщения
• • •

;здесь идет остальная часть программы

PRIMES LD DErMESSAGE

CALL 3082

RET

MESSAGE DEFD 80
DEFM "ENTRY"
DEFB " "+80
DEFM "ENTRY 2"
DEFB " "+80h

Этим способом в текущем потоке, в текущей позиции будет на-
печатано сообщение "ENTRY", но., чтобы было напечатано
"ENTRY2" регистр «А» должен содержать 1. Выведено будет только
то, что между апострофов, сами апострофы не печатаются. Эта про-
грамма использует ПЗУ для расширения символов и генерации сооб-
щения об ошибках при вызове из программы 2898 (B52h). Программа
"DEBASE" в приложении G широко используют эту процедуру.

□ Расширение символов для вывода: CALL 2898
(B52h)

Как только "SPECTRUM" находит код символа (нечто с активи-
зированным битом 7), он должен решить, что с ним делать, т.к. им
может быть или определенный пользователем рисунок, ч^сть рисун-
ка или слово из словаря БЕЙСИКа. Обычно за этим следят автома-
тически, когда используют RST 16 (10h) посредством этой процеду-
ры. Если вы заменили адрес вывода в поток (например, выводите в
интерфейс принтера), регистр «А» будет содержать код символа не-
зависимо от того, когда использовалась ваша процедура, и если вы
хотите его расширить, вам придется сделать это самостоятельно. Но,
если вы оставите его таким как есть, на принтере можно получить
несколько необычные результаты. Эта программа может быть ис-
пользована для расширения ключевых слов, но вам придется самому
работать с графикой и делать так, чтобы графические коды не засы-
лались в программу, иначе у вашего компьютера «крыша поедет».
Примечание: при расширении процедура сама повторяет вызовы ад-
реса, указанного используемым потоком, и осуществляет возврат
после выдачи всех букв. Это означает, что вам предпочтительнее
перейти к процедуре изменив код в регистре «А», тогда при последнем
возврате код выведен не будет. Это показано в следующей типовой
программе вывода на интерфейс принтера:

INIT LD HLr ( 23631);'"CHANS" (адрес канала

; данных )

LD ВС,15 густановкШп&тока 3 (принтер)

ADD HLrВС ;в HL ячёйка^^гр находится

; адресг вызываёШй;;;;:::..
; при выводе в; этот^поток;
LD ВСr START ; START = адрес вашей
LD (HL)rC ;программы ввода/вывода
INC HL
LD (HL),В

RET ;сейчас третий поток уст&й;ЩШЙ:: tia

;вывод вашей программы
START LD BrA ; сохранnHtiiiASC11 код. в «В»
CP 165

JP NCrB52h ;программа расШЙрНия в ПЗУ
CP 13

JR Zr CRLF ; возвр;!г;;;каретки после

;перевод^-Строки

CP 32

RET С ;всег что меньше 32

чатается

CP 128

JR Сr PRINT ^должен обычный СИМВОЛ г

остальное; здесь - графика,
;можно делать;:с ней что хотите
PRINT ;сюда прирт ваша программа

вывода/печати
RET ^йозврат за следующим

;сймв;О;110мг если его нетг
;то возврат к вызывающей программе

Это стандартная;программа вывода, но управляющие коды при-
нтера ею выведены не буд^т;: ;Чтобы преодолеть это, необходимо
сначала однократно; заносить первую часть программы, т.к. в ней
предварительно определяется, к^да распределен вывод потока 3.
Единственная ситуация, когда необходимо инициализировать ее еще
раз, й6;;нйеле. исполнения команды "NEW" или изменения вывода
другой чайёью; программы.

□ Расширение блока графики: CALL 2878 (B3Eh)

Если вы хотите применить блок графики из программы, то это
может сделать процедура:С точки 2878 (B3Eh). Для нее в пару "HL"
нужно поместить базовый адрес резервных восьми байтов, в которых
вы хотите изобразить сконструированный рисунок, а в регистр «В» -
адрес блока графики. Затем делаются два вызова, второй непосредст-
венно после первого, т.к. каждый вызов создает лишь четыре байта
изображения блока 8*8 пикселей. Здесь первый байт вашего 8-ми
байтного блока будет вершиной, a "HL" укажет точку, следующую за
последним байтом графики. "AF", "HL" и "ВС" изменяются этой про-
граммой, никакие другие не используются.

□ Рисование окружностей: CALL 9005 (232Dh)

Процедура рисования окружностей требует, чтобы параметры
окружности были размещены на стеке калькулятора, поэтому пред-
варительно необходимо загрузить стек. Программа, размещенная в
11560 (2D28h) выполнит эту задачу, если мы положим нужный нам
код из регистра «А» на стек (подробности использования калькулято-
ра в главе 8). После этого необходимо знать, что программа сбрасы-
вает регистр "IY", идентифицируя "ERR NR" и портит содержимое
большей части других регистров, поэтому нужно сохранять его зна-
чение перед использованием этой программы. На стеке калькулято-
ра вами в указанном порядке устанавливаются следующие парамет-
ры: X, Y, Z, где X и Y - координаты центра, a Z - радиус. Программа
рисования окружностей задает системные переменные COORDS и,
если менять их не нужно, следует запомнить их перед рисованием
окружности, разместив затем заново. Таким образом, программа
рисования окружности выглядит примерно так:

LD HL,(23677) ;COORDS

PUSH HL ;запоминаем координаты

LD А,Х ;где Х=0-255

CALL 2D28h

LD A,Y ;Y=0-175

CALL 2D28h

LD A,Z ;г=РАДИУС (убедитесь, что на

;экране есть достаточное окно, в
;противном случае вы получите
;сообщение об ошибке
CALL 2D28h

CALL 232Dh ; рисуем окружность

POP HL

LD (23677),HL ; заново размещаем COORDS

Если нужно нарисовать окружность вокруг текущих координат
"COORDS", необходимо разместить их на стеке калькулятора, пред-
варительно запомнив на машинном стеке, чтобы при желании иметь
их в неизменном виде.

П Рисование линии: CALL 9146 (23ВАИ)

Процедура рисования линии лежит в ЩЗУ: с 9399 (24B7h). Как и
программа рисования окружностей берет Шачшйя со стека кальку-
лятора, однако в ней проще обойти место, где этот стек используется.
Процедура стартует из "COORDS" и, если вам нужно начата в каком-
то другом месте, то необходимо загрузить в "COORDS" эту ст;а)равую
точку, предварительно ее запомнив для использования в дальней-
шем. В противном случае она укажет на конец вашей линии. На
входе регистр "DE" содержит знаки параметров; "DRAW", содержа-
щихся в "ВС": -1 (FFh) для отрицательных, +1 (0положитель-
ных. Регистры "С" и "Е" содержат "X", а "В" и "D" - -Машинные
коды, эквивалентные команде "DRAW 0,175" БЕЙСИКа выглядят
примерно так:

LD ВС,AFOOh ; 175 г О
LD DE г 0101h ; +
CALL 24BAh

или, для DRAW -255,0

LD ВСrOOFFh ;0r255 ''""-f
LD DE r OlFFh i+ШШ-:,.

Отметьте, что эти команды; рису ют из теку щи "COORDS" и, если
они не были изменены, то после окончания:йроцедуры они укажут
последнюю нарисованную точку и не учитывая этого не стоит рисо-
вать что-нибудь вновь.

□ Поиск адресаШшля ("PIXEL"): CALL 8874 (22AAh)

Эта процедура может быть использована для нахождения адреса
байта, содержащего пиксель, при этом регистры "ВС" должны содер-
жать координаты X hJ :("В" Y 0-175, "С" X 0-255). После возврата в
паре "HL" будет содержаться адрес, а в "А" - позиция бита.

□ Стирание части экрана: CALL 3652 (E44h)

Эта программа очистит строки нижней части всего экрана. Число
их указано;в; регистре «В» (т.е. если «В» содержит 1, то сотрется только
нижняя Строкам если 10 - 10 нижних строк). Низ экрана - это всегда
24-я строка, а нё-последняя строка основного экрана.

□ "SCROLL" части Экрана: CALL 3584 (EOOh)

Для того, чтобы произвести "SCROLL" части экрана, в регистре
«В» необходимо предварительно разместить число, на единицу мень-
шее количества строк, для которых выполняется "SCROLL". Затем
осуществляется вызов. Нижняя строка после каждого использования
программы будет стерта, а две последние строки подняты. Линии
вновь считаются с нижней части экрана.

□ Ввод в текущий поток: CALL 5606 (15E6h)

Эта программа берет адрес текущего потока из системной пере-
менной "CURHL", ищет вход подпрограммы ввода в области инфор-
мации о каналах и вызывает требуемую процедуру.

□ Очистка стека калькулятора и рабочей области
памяти: CALL 5823 (16BFh)

Эта программа может быть использована для освобождения стека
калькулятора и определения его размеров. Она использует "HL" и по
завершении размещает там содержимое "STKEND".

□ "SAVE", "LOAD" и "VERIFY"

Эти программы очень просты и непритязательны, если в одной
упряжке используются "SAVE" и "LOAD", известна точная длина
данных и не волнует возврат в БЕЙСИК вследствие ошибки или
нажатия "BREAK". Но если длина не известна и используется еще
что-либо, то все усложняется. Обычно при загрузке "SPECTRUM"
полагает, что заголовок, говорящий компьютеру как работать, будет
получен перед основным блоком, и лишь затем последует сам блок.
Но гораздо проще делать "SAVE" и "LOAD" без заголовка. Это воз-
можно только тогда, когда точно известны все параметры загружае-
мого блока. Длина заголовка 19 байт (а не 17, как написано в боль-
шинстве книг), но только 17 должны быть активны, так как "SAVE"
и "LOAD" первый и последний байты определяют сами.

Байт 1 - для заголовка всегда 00.

Последний - "PARITY BYTE", генерируется процедурой и он нас
не волнует.

Байт 2 - содержит число, характеризующее запись;

если 0 - то это БЕЙСИК-программа,

1 - числовой массив,

2 - массив символов,

3 - блок кодов.

Байты 3—12 - имя.

Байты 13 и 14 - длина основного блока; (для БЕЙСИК-программы
это соответственно переменные "ELINE - PROG").

Байты 15 и 16 - начальный адрес загрузки блока кодов или номер
строки автономного старта для БЕЙСИК-программы.

Байт 16, для массива - имя в следующей фщме:

биты 0-4 - имя (от А=1, до Z=26)

бит 5 - сброшен, если массив числовой;

бит 6 - активен, если массив строковый;

бит 7 - активен всегда.

Байты 17 и 18 - длина БЕЙСИК-программы

Байт 19 - активизируется в ходе работы программ "SAVE" и
"LOAD". j|Pi;;i;;::::.....

Для "SAVE" на; ленте нужно либо создать заголовок (см. выше) и
сразу же за ним; набор;данных, либо может быть записан только
набор, если известны его параметры. В программу "SAVE" есть не-
сколько входов, у каждого свои;достоинства и недостатки.

1. Наиболее простой. Для Heroi в^'ГХ" помещается точка старта
заголовка (байт 2 см. выше);:в "HL" - точка старта записы-
ваемого основного:блока, после всего этого - CALL 2416
(0970Ю. Этим будет сохранен как заголовок, так и сам блок,

i но: 'i;i;;:ii;;;:;:i:"

а) Загорится "START ТАРЕ THEN PRESS ANY KEY", и все будет
;; ;; хорощо, если вы нажмёте все, кроме "BREAK" на клавиату-
ре:;-Иначе будет возврат в БЕЙСИК.

б) Клавиша "BREAK:-периодически опрашивается во время про-

цедуры "8АУЕ":и;происходит возврат в БЕЙСИК, если она
нажата.

в) Заголовок сохраняется в форме, гарантирующей, что сохра-

ненная информация будет загружена БЕЙСИКОМ. Это
иногда более полезно, чем кажется на первый взгляд.

2. Эта точка входа аналогична предыдущей, за исключением
того, что она не ждет и не опрашивает "BREAK". Она управ-
ляется через подпрограмму вызывающей процедуры, пото-
му что нормальная ее работа зависит от правильной загруз-
ки машинного стека. Как и выше, сначала
устанавливаются "HL" и "IX", затем вызывается следующая
подпрограмма:

SAVE PUSH HL
JP 2436(0984h)

Возвращение после вызова будет к точке, следующей после
"SAVE". Это удобно для записи на ленту нескольких блоков подряд,
без нажатия каждый раз на клавишу по сообщению "...THEN PRESS
ANY KEY...".

Для того, чтобы исключить влияние "BREAK", должен быть сде-
лан нормальный старт, но заголовок и данные записаны отдельно, как
блоки. Программа "SA_BYTES" с точки 1218 (04С2Ю делает любые
записи. Для нее нужно в регистр «А» поместить: 00 - для заголовка, а
FFh - для блока данных. Поначалу она загружает машинный стек
программой "SAVE/LOAD RETURN", которая разрешает прерыва-
ния и проверяет "BREAK". По нажатии этой клавиши вызывается
программа обработки ошибок из RST 8 и происходит возврат в БЕЙ-
СИК. В противном случае возврат осуществляется к точке
"RETURN", по адресу, положенному на стек вызывающей програм-
мой. По прохождении программы "SAVE/LOAD RETURN", на стеке
останется адрес вашей вызывающей программы, а управление к ней
будет передано при выходе из процедуры "SAVE". Если в процессе нее
нажималась "BREAK", то флаг переноса сбрасывается. В противном
случае флаг останется, но прерывания при этом будут отключены и
для использования их необходимо восстанавливать.

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

Чтобы записать этим методом блок кодов, необходимо, чтобы
"IX" пара содержала точку старта, a "IY" - его длину. При этом в «А»
положен 00 для заголовка, либо FFh для блока данных. Прямой вызов
осуществляется по адресу 1222 (04C6h).

Если вы хотите сохранить стандартный заголовок, пара "DE"
должна содержать 17 (llh). Так можно записать блок данных и без
заголовка, но загрузить его обратно будет возможным лишь когда
известна его длина.

Если не волнует возврат в БЕЙСИК, можно использовать коды с
точки 1218 (04С2Ю, здесь, при нажатии "BREAK" вы вернетесь в
БЕЙСИК и придется вновь включать запись;::: ;

□ Выполнение "LOAD" и "VERIFY".

Данные с ленты могут быть загружены в память вашего компью-
тера в двух видах: с заголовком или без. Если;есть заголовок, то он
может быть использован для:

а) задания всех параметров блока данных, <й^ующегО:За заго-

ловком;

б) для задания тех деталей, которые не известны (как в БЕЙСИ-

Ке), или известны не до конца;;;;;;

в) чтобы гарантировать правильность вводимьгх;данных.

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

Из обычного заголовка можно скЬнструвдовать;несколько типов
разных заголовков следующим путем: как основной блок данных
записывается ваш собственный заголовок, который устанавливает
детали в настоящем основном блоке^

Часто это полезно тем, что предотвращается потеря блока при
неизвестности его длины или местоположения на ленте. Это предот-
вращает введение блока кодов непосвященным пользователем, кото-
рому придется умудриться написать свою программу, проверяющую,
что вы такое сделали^ и; лишь после этого ввести блок.

Процедура, которая ;даёт такие специальные заголовки, дана в
программе "DEBASE" приложения "G".

При загрузке блока данных с нормальным заголовком, сначала
резервируются 34 байта в ОЗУ. В первых 17 байтах должен быть
создан макетный заголовок. Он определяет параметры, требуемые
для соответствия загружаемому; последнему блоку. Все не прошед-
шее проверки на нмичи^ги шотвётствие частей заголовка повторно
тестируется уже относительно реального заголовка. Предполагая,
что допустимы изменения, детали для загрузки будут взяты из ма-
кетного заголовка. Если изменения недопустимы, то командой RST
8 генёрй^ется:сообщение БЕЙСИКа об ошибке. Вторые 17 байт
заполняются заголовком с ленты для сравнения, и при наличии соот-
ветствия эта облаете освобождается для использования.

Макетный заголовок делается также, как и записываемый на
ленту. Как и раньше первый и последний из 19 байтов генерируются
автоматически и не включены в 17-байтовую спецификацию. Пер-
вый байт должен быть аналогичен первому байту заголовка загружа-
емых данных (это типы данных, для успешной загрузки необходимо
их соответствие). Пои входе в подпрограмму "LOAD BYTES" он со-
держится в "А". Эта загрузка должна выполнятся только прямым
вызовом. При несоответствии типа, будет ожидаться начало следу-
ющего блока информации до тех пор, пока типы не станут равны: 0 -
для БЕЙСИКа, 1 - для числового массива и т.д.

Следующие 10 байт - имя. Если оно безразлично, то первый байт
из десяти должен быть FFh, при этом всегда считается, что
соответствие есть.

Еще 2 байта - длина. Если это 0000, то длина будет взята из
заголовка на ленте. В противном случае - эти байты здесь и
на ленте должны быть равны.

Байты 1 и 16 содержат стартовые адреса для загрузки. Для БЕЙ-
СИКа байт 15 игнорируется, а байт 16 задает специфика-
цию набора в той же форме, что и при выполнении команды
"SAVE". ДляБЕЙСИК-программыбайт 1 -0, а байт 16-80h.
Последующая часть безразлична. Перед использованием
контрольной части заголовка, в системной переменной
"TADDR" в младшем байте должно быть 01 для команды
"LOAD", или 2 для выполнения "VERIFY".

В паре "HL" должен хранится адрес, по которому разместится
основной блок, или 0, если будет использоваться информа-
ция заголовка с ленты. Для существующего БЕЙСИК набо-
ра здесь начало данных, идущих вслед за байтами имени и
длины в области переменных БЕЙСИК -программы.

"IX" адресует первый байт макетного заголовка, и, наконец, вы-
зов программы ПЗУ с точки 1889 (76 lh), выполнит команды
"LOAD" и "VERIFY" заголовка и данных с ленты.

Выполнение команд "LOAD" и "VERIFY" без заголовка возмож-
но, если все основные параметры блока известны. Делается это очень
просто. Сначала в «А» кладется FFh. Это сигнализирует о том, что
будет вводится собственно программа. Затем в "DE" полная длина
блока, после чего в "IX" помещается адрес начала "LOAD" или
"VERIFY". Это сопровождается установкой флага переноса, если вы-
полняется "LOAD", или его сбросом при "VERIFY". И наконец, CALL
1366 (556h).

В начале работы этой процедуры как и при "SAVE" загружается
машинный стек и происходит возврат по ошибке, при нажатии
"BREAK". "BREAK" можно исключить вызовом следующей короткой
подпрограммы:

LOAD INC D ;сброс флага в О

EX AF,А,' F'
DEC D

DI ;отключаются прерывания

LD Ar OFh

OUT (FEh),A lyCTaHOBKaiiii'iiBQRDER11 и

; порт a "EAR" i liii ii;::
JP 562h ;перейти к главно^;;;::.

; LOAD программе

Команда "OUT" устанавливает "BORDER:' в белый цветке по-
мощью трех младших битов по адресу (FEh)У;Можно установить и
другой цвет, но пятый бит остается 1, т.к. он определяет nop:T::rEAR",
сигнализируя, что с ленты идет загрузка.

Ошибка загрузки диагностируется по сбросу флага: переноса при
возвращении к вызывающей программе, Так как попытка сделать
"BREAK" приводит к возврату, то он может!произойти, если проце-
дура проверки "BREAK" вызывается пйсле проверки ошибок. При-
мечание: прерывания после возврата из загрузки будут отключены.
Эта процедура может быть также использована для ввода заголовка
вместо основного блока данных, для этого ;п£ред вызовом в «А» поме-
щается 0. Это полезно при создании вами брйшнальных заголовков,
читаемых только эашей программой (см. "DEBASE" приложения G).




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Прикол - Единый Стандарт На Совкового Сисопа.
Freeda - Снова стихи! Снова они!
Coding - Раздeл для начинаюших кодeров.
How To Contribute To Subliminal Extacy
Анкета - Заполнять анкету можно как на листке бумаги, так и в текстовом файле на дискете.

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