Пакет документации о рестартах iS-DOS 1969 г.

Рестарты - WIND.SYS (#61...#6F).



"Оконная система IS-DOS"

 

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

 

Создание окон.

 

Работа любого оконного интерфейса начинается, естественно, с процедуры открытия окна. Окно в системе IS-DOS имеет следующую структуру (см. рис 1):

 

 

Рис. 1: Структура окна в IS-DOS

 

Область окна определяется значениями XS (X-size) и YS (Y-size), и измеряется в знакоместах 8*8 пикселей, область рамки имеет ширину в 8 пикселей (1 знакоместо 8*8) по всему периметру окна, следовательно, размеры рабочей области окна равны XS-2 и YS-2. Размер и расположение в окне поля печати, а также ширина левого и правого полей определяются prnt pos. и print size и измеряются в знакоместах 6*8. Верхний и нижний край поля печати ограничивается только областью рамки.

Область тени представляет собой окантовку нижней и правой сторон окна толщиной в 1 знакоместо 8*8 и с отступом в 1 знакоместо от левой и верхней границ области окна.

 

#61 (97) $wt

 

В системе IS-DOS для открытия окна используется рестарт wt (#61). Он осуществляет формирование на экране окна с параметрами, заданными в специальной таблице, называемой "вектором окна". Адрес вектора окна на момент вызова рестарта должен находиться в регистровой паре IX, при этом содержимое регистра A определяет внешний вид окна следующим образом:

7-й бит, установленный в 1 делает открываемое окно "прозрачным", т. е. окно открывается только изменением атрибутов, а пиксели внутри него не сбрасываются.

Остальные биты определяют вид рамки окна:

000000 - одинарная рамка

000010 - двойная рамка

Все остальные значения приводят к открытию окна без рамки.

Таким образом, формат задания внешнего вида окна можно представить в виде таблицы:

 

окно

одинарная рамка

двойная рамка

без рамки

прозрачное

A=#80

A=#82

A=#81

A=#83..#FF

непрозрачное

A=#00

A=#02

A=#01

A=#03..#7F

 

Итак, процедура открытия окна в системе IS-DOS выглядит следующим образом:

 

LD IX,WIND     ;загрузка в IX адреса вектора окна

LD C,#61         ;загрузка в C кода рестарта wt

LD A,n          ;загрузка в A значения, определяющего вид окна

RST #10        ;вызов рестарта

 

Структура вектора окна:

 

WIND   DEFB #00     ;X-координата верхнего левого угла окна в знакоместах 8*8 пикселей

DEFB #00      ;Y-координата верхнего левого угла окна в знакоместах 8*8 пикселей

;значения координат отсчитываются от левого верхнего угла экрана

DEFB #0F      ;высота окна в знакоместах 8*8

DEFB #0F      ширина окна в знакоместах 8*8

DEFB %00000111    ;цвета окна

;цвета кодируются стандартным образом:

;бит 7 - flash

;бит 6 - bright

;биты 5...3 - paper

;биты 2...0 - ink

DEFB %00000001      ;цвета тени окна

;Примечательно, что в цветах тени окна можно задавать как цвет paper, так и ;цвет ink, что позволяет сделать видимой часть информации, на которую падает ;тень от окна и обеспечивает максимальную естественность восприятия. Если ;байт цветов тени равен #FF, то тень не выводится.

DEFB #01                  ;X-координата для процедуры печати текста в окне

DEFB #12                  ;ширина поля печати в окне

 

Последние два параметра выражаются в знакоместах размером 6*8, а не 8*8 как остальные, это сделано потому, что такую систему отчёта используют все рестарты печати в iS-DOS. Значение X-координаты печати абсолютное и отсчитывается не от левой границы окна, а от левой границы экрана. Перевод координат окна в координаты печати и обратно можно осуществить по формулам:

 

n=N*8/6                                                                                     (1)

 

N=n*6/8,                                                                                    (2)

 

где    n - значение в знакоместах 6*8,

N - значение в знакоместах 8*8.

 

Y-координата печати не задается, так как большинство рестартов печати самостоятельно отсчитывает ее от верхней строки окна.

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

Рассмотрим простейший пример. Задача - создать в точке с координатами X=5 и Y=3 окно размером 28*16 знакомест с двойной рамкой, синей бумагой, белыми чернилами и с черно-синей тенью, поле печати текста определить с отступом в 1 знакоместо от левой и в 5 знакомест от правой границы окна.

Для создания этой несложной программы кроме рестарта открытия окна wt(#61) нам понадобятся еще три подпрограммы - очистки экрана, ожидания нажатия клавиши и возврата в IS-DOS.

 

Итак, рассмотрим листинг 1:

Листинг 1 Пример создания окна

 

;Исходные данные:

 

;    X-coord (X) = 5

; Y-coord (Y) = 3

; X-size (XS) = 20

; Y-size (YS) = 16

; W.Colors(WC) = %00001111

; S.Colors(SC) = %00000001

; L.Margin(LM) = 1

; R.Margin(RM) = 5

 

ORG #5D64

 

;основная программа

 

START        CALL CLS          ;вызов процедуры очистки экрана

LD IX,WIND      ;адрес вектора окна

LD C,#61          ;код рестарта wt

LD A,2              ;код двойной рамки

RST #10              ;вызов рестарта

CALL WAIT         ;вызов процедуры ожидания клавиши

JP EXIT            ;переход на процедуру возврата в IS-DOS

 

;вектор окна

 

WIND       DEFB 5

DEFB 3

DEFB 16

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

;Данные для print position (печать с отступом в 1 знакоместо 6*8 от левой ;границы окна) получены путем расчета по формуле (3):

 

PP=X*8/6+LM,                                                                           (3)

 

;где   PP - print pos. в знакоместах 6*8

;        X - X-коорд. окна в знакоместах 8*8

;        LM - левое поле в знакоместах 6*8

 

;Данные для print size получены путем расчета по формуле (4):

 

;                                                          PS=XS*8/6-LM-RM,                                                                      (4)

 

;где PS - print size в знакоместах 6*8

;      XS - размер окна в знакоместах 8*8

;      LM - левое поле в знакоместах 6*8

;      RM - правое поле в знакоместах 6*8

 

дополнительные процедуры

 

CLS       LD C,#73         ;рестарт cls

RST #10            ;для очистки экрана

RET

 

WAIT      LD C,#07         ;рестарт ttyin

RST #10            ;для ожидания

RET                  ;нажатия клавиши

 

EXIT       XOR A            ;стандартный выход

LD A,#F4        ;в IS-DOS

RET

 

#62 (98) $box

 

Следующий рестарт box(#62) позволяет нарисовать или стереть в области рамки окна любую возможную рамку, или любую из ее сторон в любом сочетании. Поскольку ширина области рамки в окне IS-DOS равна 8 пикселям, всего возможно 8 различных одинарных рамок. Вызывая рестарт box несколько раз можно рисовать двойные, тройные и даже счетверенные рамки, а также рамки различной толщины - всего 256 комбинаций.

В качестве входных параметров рестарт box(#62) использует вектор окна, адрес которого задается в регистре IX, а также значения отступа от края окна по Y и по X в пикселях, задаваемые в регистрах D и E соответственно, и содержимое регистра A, определяющее, что именно требуется нарисовать или стереть.

Содержимое регистра A определяется следующим образом:

бит 7=0 - рисовать, 1 - стирать

биты 6...4 - не используются

остальные биты показывают, с какими из сторон рамки производится операция:

бит 3=0 - левая сторона рамки

бит 2=0 - правая сторона рамки

бит 1=0 - верхняя сторона рамки

бит 0=0 - нижняя сторона рамки

Для битов 3...0 возможны любые сочетания.

Общая форма процедуры рисования/стирания рамки выглядит так:

 

LD IX,WIND      ;адрес вектора окна

LD C,#62          ;код рестарта box

LD D,N1           ;отступ по Y

LD E,N2            ;отступ по X

LD A,n              ;что делать

RST #10              ;вызов рестарта

 

Для задания значений отступа рамки предпочтительнее использовать числа от 0 до 7, причем при загрузке в регистры D и E значения 0 рамка будет выведена по наружному краю окна, а при загрузке значения 7 - по внутреннему краю области рамки. Значение 8 даст тот же эффект, что и 0, 9 -тот же, что и 1 и т.д.

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

 

Листинг 2 Пример рисования рамки окна

 

ORG #5D64

 

;открытие окна

 

START      CALL CLS          ;очистка экрана

LD IX,WIND

LD C,#61

LD A,1              ;окно без рамки

RST #10

CALL WAIT

 

;рисование наружной рамки двойной толщины производится в два приема

 

LD IX,WIND    ;адрес вектора окна

LD C,#62        ;код рестарта box

LD D,0           ;отступ по Y

LD E,0            ;отступ по X

LD A,%00000000

 

;все биты равны 0 - рисовать всю рамку

 

RST #10

LD IX,WIND

LD C,#62

LD D,1

LD E,1

LD A,%00000000

RST #10

CALL WAIT

 

;рисование внутренней рамки

 

LD IX,WIND

LD C,#62

LD D,3

LD E,3

LD A,%00000000

RST #10

CALL WAIT

 

;стирание боковых сторон

 

LD IX,WIND

LD C,#62

LD D,2

LD E,1

LD A,%10000011

 

;7-й бит установлен - команда стирания установленные 0-й и 1-й биты обозначают не затрагиваемые в этой операции верхнюю и нижнюю стороны рамки

 

RST #10

CALL WAIT

JR EXIT

 

;вектор окна

 

WIND       DEFB 5

DEFB 3

DEFB 16

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

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

 

Поясним на примере:

 

Пусть необходимо создать внутри окна (см. Листинг 1) рамку с отступом в 2 знакоместа от верхней границы окна, в 4 - от нижней и в 3 от левой и правой сторон.

Для этого создадим фиктивный вектор окна WIND1, а для расчета его параметров воспользуемся следующими формулами:

 

Y1=Y+UM,                                                                               (5)

 

где    Y1 - Y-координата рамки,

Y - Y-координата окна,

UM - отступ сверху

 

X1=X+LM,                                                                             (6)

 

где    X1 - X-координата рамки,

X - X-координата окна,

LM - отступ слева

 

YS1=YS-UM-DM,                                                                   (7)

 

где    YS1 - размер рамки по Y,

YS - размер окна по Y,

UM - отступ сверху,

DM - отступ снизу

 

XS1=XS-LM-RM,                                                                      (8)

 

где    XS1 - размер рамки по X,

XS - размер окна по X,

LM - отступ слева,

RM - отступ справа

 

Все величины измеряются в знакоместах 8*8. Значения цветов выберем такие же, как и в основном окне, но без тени (S.Colors=#FF), значения Print pos. и Print size могут быть любыми.

Итак,


 

Листинг 3 Пример рисования внутренних рамок при помощи box(#62)

;Исходные данные:

;        Up Margin (UM) = 2

;        Down Margin (DM) = 4

;        Left Margin (LM) = 3

;        Right Margin (RM) = 3

 

ORG #5D64

 

;открытие окна

 

START        CALL CLS            ;очистка экрана

LD IX,WIND

LD C,#61

LD A,2

RST #10

CALL WAIT

 

;рисовать второе окно не требуется, достаточно просто поместить адрес его вектора в регистр IX для передачи параметров рестарту box

 

;рисование рамки внутри окна

 

LD IX,WIND1       ;вектор рамки

LD C,#62

LD D,0

LD E,0

LD A,%00000000

RST #10

CALL WAIT

JR EXIT

 

;вектор окна

 

WIND       DEFB 5

DEFB 3

DEFB 16

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

;вектор окна для рамки

 

WIND1      DEFB 8

DEFB 5

DEFB 10

DEFB 14

DEFB %00001111

DEFB #FF

DEFB #00

DEFB #00

 

Подобным же образом выполняются вертикальные и горизонтальные линии - они представляются как стороны воображаемой рамки и задаются фиктивным вектором окна. Подбирая содержимое регистров D и E нетрудно добиться позиционирования рамки или линии с точностью до 1 пикселя.

 

#63 (99) $awt, #64 (100) $awtc

 

Еще несколько служебных рестартов могут пригодиться при работе с окнами в IS-DOS. Два из них позволяют подсветить требуемым цветом выбранную строку окна. Различаются они только тем, что рестарт awt(#63) действует на все окно, включая и область рамки, а действие рестарта awtc(#64) распространяется только на рабочую область окна.

Входными параметрами для этих рестартов служат следующие значения:

IX - адрес вектора окна

A - номер строки (начиная с 1-й)

B - цвета в стандартном формате

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

Пример работы awt и awtc:

 

Листинг 10 Пример использования awt(#63) и awtc(#64)

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

CALL WAIT

 

;печать строк текста из буфера в окне через подфункцию 3 рестарта $prstr

 

LD IX,WIND      ;вектор окна

LD C,#68          ;код рестарта

LD E,3              ;код подфункции

LD HL,TEXT      ;адрес начала текста

LD A,%11000010

 

;печать с центровкой и отступ сверху - 2 строки

 

LD B,1              ;номер строки в тексте

RST #10            ;вызов рестарта

LD IX,WIND      ;вектор окна

LD C,#68          ;код рестарта

LD E,3            ; код подфункции

LD A,%11000101

LD B,2              ;печать следующей

RST #10            ;строки в окне

 

;подсветка строки вместе с рамкой

 

LD IX,WIND

LD A,2            ;2-я строка

LD B,%00110001

LD C,#63

RST #10

 

;подсветка строки в рабочей области окна

 

LD IX,WIND

LD A,5            ;5-я строка

LD B,%00110001

LD C,#64

RST #10

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 1

DEFB 1

DEFB 8

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 3

DEFB 38

 

;текстовый буфер

 

TEXT      DEFM "подсветка строки с рамкой"

DEFB #0D

DEFM "подсветка строки без рамки"

DEFB #0D

DEFB #03

 

#65 (101) $lwt

 

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

Входные параметры:   C - код рестарта (#65)

IX - адрес вектора окна

HL - адрес текстового буфера

A - величина отступа по Y от верхней границы окна

B - количество печатаемых строк

Формат текстового буфера для lwt является стандартным для большинства рестартов печати в IS-DOS: символы располагаются последовательно, начиная от стартового адреса в сторону увеличения адресов, строки отделяются друг от друга символом с кодом #0D, маркер окончания текста - символ с кодом #03.

При работе lwt маркер #03 не обязателен, т. к. печатаемый текст ограничивается заданным количеством строк. Однако, если маркер #03 встретится в тексте до того, как будет напечатано требуемое количество строк, печать прекращается. Символы перевода строки тоже не обязательны, так как при достижении правого края окна печать продолжается с начала следующей строки, причем счетчик строк учитывает это, так что независимо от наличия символов #0D в окне будет распечатано заданное количество строк. Остальная часть текста обрезается.

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

При работе рестарта lwt сохраняется неизменным содержимое регистра IX и регистровой пары HL.

 

Рассмотрим пример:

Листинг 4 Пример использования lwt(#65)

 

ORG #5D64

 

;открытие окон

 

CALL CLS

LD IX,WIND1

LD C,#61

LD A,2

RST #10

LD IX,WIND2

LD C,#61

LD A,0

RST #10

CALL WAIT

 

;печать строк текста из буфера в окне 1

 

LD IX,WIND1       ;адрес вектора окна

LD HL,TEXT1      ;адрес текста

LD C,#65             ;код рестарта

LD A,1

LD B,4

RST #10

CALL WAIT

JP EXIT


 

;векторы окон

 

WIND1      DEFB 5

DEFB 2

DEFB 8

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 


WIND2      DEFB 5

DEFB 12

DEFB 8

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

;текстовые буферы

 

TEXT1      DEFM "Рестарт lwt(65)"

DEFB 13

DEFM "позволяет печатать"

DEFB 13

DEFM "в окне текст из"

DEFB 13

DEFM "текстового буфера."

DEFB 13

 

TEXT2      DEFM "В регистре B задано"

DEFB 13

DEFM "количество строк,"

DEFB 13

DEFM "которое требуется"

DEFB 13

DEFM "напечатать"

DEFB 13

 

#66 (102) $adrwt

 

Предназначен для распечатки в окне текста, расположенного непосредственно после вектора окна.

Входные параметры:   C - код рестарта (#66)

IX - адрес вектора окна

Рестарт adrwt очень удобен для печати окон с текстом, жестко привязанным к конкретному окну. Главное его достоинство - всего один входной параметр (не считая самого кода рестарта в регистре C).

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

При работе рестарта adrwt содержимое регистра IX сохраняется.

Пример:

 

Листинг 5 Печать при помощи $adrwt(#66)

 

ORG #5D64

 

;открытие окон

 

CALL CLS

LD IX,WIND1

LD C,#61

LD A,2

RST #10

LD IX,WIND2

LD C,#61

LD A,0

RST #10

CALL WAIT

 

;печать строк текста в окне 1

 

LD IX,WIND1       ;адрес вектора окна

LD C,#66             ;код рестарта

RST #10

CALL WAIT

 

;печать строк текста в окне 2

 

LD IX,WIND2

LD C,#66

RST #10

CALL WAIT

JP EXIT

 

;векторы окон

 

WIND1 DEFB 5

DEFB 3

DEFB 7

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

;текст окна 1

 

DEFM "Рестарт adrwt(66)"

DEFB #0D

DEFM "позволяет печатать"

DEFB #0D

DEFM "текст, следующий"

DEFB #0D

DEFM "за вектором окна."

DEFB #03

 

WIND2 DEFB 5

DEFB 12

DEFB 7

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

;текст окна 2

 

DEFM "Строки разделяются"

DEFB #0D

DEFM "символом с кодом #0D"

DEFB #0D

DEFM "конец текста - "

DEFB #0D

DEFM "символ с кодом #03"

DEFB #03


 

#67 (103) $lenwt

 

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

Основное преимущество рестарта lenwt - возможность печати одного текста в нескольких окнах и наоборот - возможность печати разных текстов в одном окне.

Входные параметры:   C - код рестарта

IX - адрес вектора окна

HL - адрес текста

При работе рестарта lenwt содержимое регистра IX и регистровой пары HL сохраняется.

Пример:

 

Листинг 6 Печать при помощи $lenwt(#67)

 

ORG #5D64

 

;открытие окон

 

CALL CLS

LD IX,WIND1

LD C,#61

LD A,2

RST #10

LD IX,WIND2

LD C,#61

LD A,0

RST #10

CALL WAIT

 

;печать строк текста из буфера в окне 1

 

LD IX,WIND1       ;адрес вектора окна

LD HL,TEXT        ;адрес текста

LD C,#67             ;код рестарта

RST #10

CALL WAIT

 

;печать строк текста из буфера в окне 2

 

LD IX,WIND2

LD HL,TEXT

LD C,#67

RST #10

CALL WAIT

JP EXIT

 

;векторы окон

 

WIND1   DEFB 5

DEFB 3

DEFB 7

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

WIND2   DEFB 5

DEFB 12

DEFB 7

DEFB 20

DEFB %00001111

DEFB %00000001

DEFB 8

DEFB 20

 

;текстовый буфер

 

TEXT   DEFM "Рестарт lenwt(67)"

DEFB #0D

DEFM "позволяет печатать"

DEFB #0D

DEFM "текст, находящийся"

DEFB #0D

DEFM "в любом месте"

DEFB #0D

DEFM "программы"

DEFB #03

 

 

#68 (104) $prstr

 

Рестарт prstr(#68) - самый мощный и универсальный из всех рестартов, предназначенных для печати строк текста в окне. Основным его достоинством является возможность автоматического выравнивания строки по левому и правому краю, а также центровки строки. Рестарт имеет 4 подфункции, позволяющие задать печатаемую строку различными способами. Код подфункции помещается в регистре E:

E=0 - распечатка строки по логическому имени, определенному в специальном массиве-анализаторе

E=1 - распечатка строки заданной длины, содержащейся по указанному адресу

E=2 - служебная подфункция, которая ни чего не печатает, но позволяет вы числить параметры для предыдущей подфункции, зная адрес начала текстового буфера и номер строки

E=3 - распечатка строки по номеру ее в тексте - фактически представляет собой комбинацию подфункций 2 и 1

Диспетчер подфункций имеет "защиту от дурака" - если Вы задали в регистре E номер, больший, чем 3, он будет автоматически приравнен к нулю.

Теперь рассмотрим более подробно работу с подфункциями рестарта prstr(#68).

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

00 - выравнивание по левому краю

01 - выравнивание по левому краю

10 - выравнивание по правому краю

11 - центровка строки

При работе рестарта содержимое регистра A не сохраняется.

Формат текстового буфера для prstr стандартный - символы располагаются последовательно, начиная со стартового адреса, строки отделяются друг от друга символом #0D, маркер конца текста - #03.

Для вывода символов на экран prstr использует рестарт ttyout(#0A) из уровня DOS.SYS. При формировании текстового буфера, задании отступа и числа печатаемых символов необходимо самостоятельно следить за тем, чтобы текст не вышел за пределы окна. При ширине строки, большей, чем ширина поля печати окна выравнивание автоматически осуществляется по левому краю, независимо от состояния двух старших битов регистра А.

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

Допустим, Вам необходимо распечатать в окне текст, содержащий часто повторяющиеся строки. Вместо того, чтобы многократно вызывать prstr, каждый раз задавая все параметры и строго следя за тем, какую из строк печатать следующей, или, что еще хуже, забивать текстовый буфер одинаковыми строками, Вы можете просто составить массив, в котором будет установлена последовательность печати строк путем ссылок на их порядковые номера в буфере. Оперативно переключая разные массивы, Вы сможете легко перекомпоновывать Ваши тексты, менять местами строки, вставлять другие и т. п. При помощи подфункции 0 легко также организовать печать текстовых сообщений по коду из таблицы (по типу сообщений об ошибках в Spectrum BASIC)

Входные параметры:   С - код рестарта (#68)

E - код подфункции (0)

IX - адрес вектора окна

HL - адрес массива-анализатора

A - режим центровки и отступ по Y (см. выше)

B - логическое имя строки - любой код, кроме #FF

На выходе при нормальном завершении работы регистр HL содержит число, на единицу меньшее, чем адрес первого символа строки, следующей за напечатанной, сохраняется неизменным содержимое регистра IX, содержимое регистров A, B, C, E - теряется. Рестарт prstr также модифицирует системную переменную xypos (см. вектор символьного устройства вывода).

Возможные ошибки:

1. Если логическое имя строки не найдено в массиве-анализаторе, то рестарт возвращается в вызывающую программу с установленным флагом C и кодом ошибки 140 (нет имени в массиве) в регистре A.

2. Если текст не содержит строки с порядковым номером, указанным в массиве, рестарт возвращается с установленным флагом C и кодом ошибки 141 (нет строки в тексте) в регистре A.

Массив-анализатор имеет следующую структуру: первые два байта - адрес текстового буфера, далее - двухбайтовые записи, в которых первый байт - логическое имя строки, а второй - ее порядковый номер в буфере. Завершается массив обязательно кодом #FF.

Рассмотрим пример. Изобразим на экране рамку из звездочек в двух разных вариантах для двух окон (см. рисунок):

Для рисования двух этих рамок при помощи подфункции 0 рестарта prstr необходимы только 4 вида строк:

 

1. "*************************"

2. "*                            *"

3. "*            *               *"

4. "*     *            *        *"

 


Составим программу, выполняющую эту задачу:

 

Листинг 7 Печать при помощи подфункции 0 рестарта $prstr

 

ORG #5D60

 

;открытие окон

 

CALL CLS           ;очистка экрана

LD IX,WIND1     ;открыть окно 1

LD C,#61

LD A,2

RST #10

LD IX,WIND2     ;открыть окно 2

LD C,#61

LD A,0

RST #10

 

;печать первой рамки

 

LD IX,WIND1       ;адрес вектора окна

LD HL,TABL1      ;адрес массива

CALL PRINT      ;вызов процедуры печати текста

 

;печать второй рамки

 

LD IX,WIND2

LD HL,TABL2

CALL PRINT

 

CALL WAIT       ;ожидание клавиши

JP EXIT            ;выход в IS-DOS

 

;процедура печати

 

PRINT    LD B,#09       ;число строк, которые необходимо распечатать, одновременно - логическое имя первой строки

;режим выравнивания - по центру, отступ - 1 строка

LD A,%11000001

M1           PUSH HL    ;сохранить на стеке адрес массива

PUSH AF   ;сохранить на стеке режим выравнивания и текущую величину отступа по Y

LD C,#68      ;код рестарта

LD E,#00      ;код подфункции

RST #10       ;вызов рестарта

POP AF     ;снять со стека текущую величину отступа

INC A           ;увеличить ее на 1 для печати следующей строки

POP HL     ;восстановить в HL адрес массива

DJNZ M1      ;повторить, пока значение B не уменьшится до 0

 

;значение B служит одновременно счетчиком в цикле печати и логическим именем очередной печатаемой строки

RET             ;возврат в основную программу

 

;векторы окон

 

WIND1   DEFB 0

DEFB 0

DEFB 11

DEFB 30

DEFB %00001111

DEFB #FF

DEFB 3

DEFB 38

 

WIND2   DEFB 0

DEFB 12

DEFB 11

DEFB 30

DEFB %00001111

DEFB #FF

DEFB 3

DEFB 38

 

;текстовый буфер

 

TEXT      DEFM "*************************"

DEFB #0D

DEFM "* *"

DEFB #0D

DEFM "* * *"

DEFB #0D

DEFM "* * * *"

DEFB #0D

DEFB #03

 

;массивы-анализаторы

 

TABL1    DEFW TEXT

DEFB #09

DEFB 1

DEFB #08

DEFB 3

DEFB #07

DEFB 3

DEFB #06

DEFB 1

DEFB #05

DEFB 2

DEFB #04

DEFB 2

DEFB #03

DEFB 2

DEFB #02

DEFB 2

DEFB #01

DEFB 1

DEFB #FF

 

TABL2      DEFW TEXT

DEFB #09

DEFB 1

DEFB #08

DEFB 4

DEFB #07

DEFB 4

DEFB #06

DEFB 4

DEFB #05

DEFB 1

DEFB #04

DEFB 3

DEFB #03

DEFB 3

DEFB #02

DEFB 3

DEFB #01

DEFB 1

DEFB #FF

 

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

После вычисления координат подфункция 1 вызывает тот же рестарт $ttyout(#0A) в цикле до тех пор, пока не будет напечатано требуемое количество символов.

Входные параметры:   C - код рестарта (#68)

E - код подфункции (#01)

IX - адрес вектора окна

HL - адрес начала строки

B - длина строки

A - режим выравнивания и отступ по Y

Длина печатаемой строки определяется исключительно значением регистра B. Символ перевода строки #0D в этом случае заменяется пробелом, остальные символы с кодами меньше #20 применять не рекомендуется во избежание появления "мусора" на экране.

Пример использования подфункции 1:

 

Листинг 8 Пример печати при помощи $prstr(#68) подфункция 1

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

CALL WAIT

 

;печать строки текста из буфера в окне через подфункцию 1

 

LD IX,WIND      ;вектор окна

LD C,#68          ;код рестарта

LD E,1              ;код подфункции

LD HL,TEXT1    ;адрес строки

LD A,%11000010

 

;два старших бита - режим выравнивания (в данном случае - центровка) шесть младших - отступ сверху (2 строки)

 

LD B,30        ;кол-во символов в строке

RST #10         ;вызов рестарта

CALL WAIT

 

;печать следующей строки

 

LD IX,WIND    ;вектор окна

LD C,#68        ;код рестарта

LD E,1           ;код подфункции

LD HL,TEXT2  ;адрес начала строки

LD A,%11000100

 

;печать без выравнивания и отступ сверху - 4 строки

 

LD B,36          ;кол-во символов в строке

RST #10            ;вызов рестарта

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 1

DEFB 1

DEFB 8

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 3

DEFB 38

 

;текстовый буфер

 

TEXT1    DEFM "Рестарт prstr(68)"

DEFM "подфункция 1"

TEXT2    DEFM "печать строки в окне"

DEFM "с выравниванием"

 

Подфункция 2 позволяет вычислить входные параметры для подфункции 1 (адрес и длину строки) по ее порядковому номеру в текстовом буфере.

Входные параметры:   C - код рестарта (#68)

E - код подфункции (#02)

HL - адрес начала текста

B - порядковый номер строки

 

Выходные параметры: HL - адрес строки

B - длина строки

 

Содержимое регистров C и E не сохраняется. Формат текста - стандартный. Если значение порядкового номера превышает число строк в тексте, рестарт возвращается с установленным флагом C и кодом ошибки 141 (нет строки в тексте) в регистре A.

Пример использования подфункции 2:

 

Листинг 9 Пример использования $prstr(#68) подфункция 2

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

CALL WAIT

 

;пример использования подфункции 2 для определения параметров для подфункции 1 по известному номеру строки в тексте

 

LD C,#68        ;код рестарта

LD E,2            ;код подфункции 2

LD HL,TEXT    ;адрес начала текста

LD B,1            ;номер строки

RST #10

 

;на выходе в HL' - адрес строки, а в B - длина

 

EXX

LD C,#68

LD E,1              ;код подфункции 1

LD A,%11000001

RST #10

LD C,#68

LD E,2              ;определение

LD HL,TEXT      ;параметров следующей

LD B,2              ;строки

RST #10

EXX

LD C,#68

LD E,1              ;печать

LD A,%11000011

RST #10

LD C,#68

LD E,2

LD HL,TEXT

LD B,3

RST #10

EXX

LD C,#68

LD E,1

LD A,%11000101

RST #10

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 1

DEFB 1

DEFB 8

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 3

DEFB 38

 

;текстовый буфер

 

TEXT      DEFM "Рестарт prstr(68) "

DEFM "подфункция 2"

DEFB #0D

DEFM "определяет параметры для"

DEFB #0D

DEFM "подфункции 1"

DEFB #0D

DEFB #03

 

Подфункция 3 - комбинация подфункций 2 и 1. В качестве входных параметров используются адрес начала текста и порядковый номер строки в нем.

Сначала подфункция 3 при помощи подфункции 2 вычисляет значения адреса и длины строки, после чего управление передается подфункции 1.

Входные параметры:   C - код рестарта (#68)

E - код подфункции (#03)

IX - адрес вектора окна

HL - адрес начала текста

B - номер строки

A - режим выравнивания и отступ по Y

Как и в подфункции 2, отсутствие в тексте строки с указанным порядковым номером приводит к возврату в вызывающую программу с установленным флагом C и кодом ошибки 141 (нет строки в тексте) в регистре A.

Пример использования подфункции 3:

 

Листинг 10 Пример использования $prstr(#68) подфункция 3

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

CALL WAIT

 

;печать строк текста из буфера в окне через подфункцию 3

 

LD IX,WIND      ;вектор окна

LD C,#68          ;код рестарта

LD E,3              ;код подфункции

LD HL,TEXT      ;адрес начала текста

LD A,%11000010

 

;печать с центровкой и отступ сверху - 2 строки

 

LD B,1              ;номер строки в тексте

RST #10            ;вызов рестарта

CALL WAIT

LD IX,WIND      ;вектор окна

LD C,#68          ;код рестарта

LD E,3              ;код подфункции

LD A,%11000101

LD B,2              ;печать следующей

RST #10            ;строки в окне

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 1

DEFB 1

DEFB 8

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 3

DEFB 38

 

;текстовый буфер

 

TEXT      DEFM "Рестарт prstr(68)"

DEFM "подфункция 3"

DEFB #0D

DEFM "печать строки по номеру"

DEFB #0D

DEFB #03

 

#69 (105) EMPTY

 

Не используется.

 

#6A (106) $panel

 

Работа с панелью. Код подфункции передаётся в регистре A (см. ПРИЛОЖЕНИЕ 15).

 

#6B (107) $wtpos

 

Рестарт wtpos вычисляет абсолютные логические координаты печати по значениям Y-coord и Print pos. из вектора окна, на который указывает содержимое регистра IX, с учетом смещения по Y, задаваемого в регистре H и по X, задаваемого в регистре L, и помещает их в системную переменную XYPOS, находящуюся в векторе символьного устройства вывода. Эта системная переменная активно используется рестартом ttyout(#0A), на основе которого созданы многие из рестартов печати уровня WIND.SYS.

Следует упомянуть о том, что для задания координат печати можно пользоваться также и рестартом prapd(#0C) из уровня DOS.SYS, который помещает в системную переменную XYPOS значения регистров H (Y‑coord в строках) и L (X‑coord в знакоместах 6*8).

Пример с использованием prapd:

 

Листинг 13 Установка координат для $lnstr(#6D)

 

ORG #5D64

CALL CLS           ;очистка экрана

LD H,5              ;Y-coord

LD L,2              ;X-coord

LD C,#0C        ;код рестарта #0С из уровня DOS.SYS

RST #10

LD HL,TEXT    ;адрес текста

LD C,#6D       ;код рестарта lnstr

LD B,37          ;кол-во символов

RST #10            ;печать строки

CALL WAIT

JP EXIT

 

;текстовый буфер

 

TEXT      DEFM "Печать строки"

DEFM "с координатами"

DEFM "X=2, Y=5"

 

То же с использованием $wtpos:

Листинг 14 Установка координат wtpos для $lnstr(#6D)

 

ORG #5D64

 

;исходные данные:

;      Y-coord окна =3

;      X-coord окна =0

;      Print pos=1

 

;требуемые координаты печати:

;      X=2

;      Y=5

 

;следовательно:

;      H=2 (смещение по Y)

;      L=1 (смещение по X)

 

CALL CLS         ;очистка экрана

LD IX,WIND    ;вектор окна

LD A,2            ;открытие окна

LD C,#61

RST #10

LD H,2            ;Y-смещение

LD L,1            ;X-смещение

LD C,#6B        ;код рестарта wtpos

RST #10

LD HL,TEXT    ;адрес текста

LD C,#6D       ;код рестарта lnstr

LD B,37          ;кол-во символов

RST #10            ;печать строки

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 0

DEFB 3

DEFB 7

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 1

DEFB 40

 

;текстовый буфер

 

TEXT      DEFM "Печать строки"

DEFM "с координатами"

DEFM "X=2, Y=5"

 

 

#6C (108) $str

 

Рестарт str(#6C) - печать в текущей позиции экрана строки, ограниченной кодом #0D. Адрес строки задается в регистровой паре HL. Этот рестарт удобен для печати строк на экране за пределами окон, не требует задания координат, а использует текущую позицию печати, хранящуюся в системной переменной XYPOS.

Рестарт str - это всего лишь циклическое обращение к уже упоминавшемуся выше рестарту $ttyout(#0A) из уровня DOS.SYS, осуществляемое до тех пор, пока не встретится код перевода строки #0D. Для определения координат печати используется системная переменная XYPOS, располагающаяся в векторе символьного устройства вывода. Доступ к этой переменной можно получить, используя рестарты $wtpos(#6B) и $prapd(#0C), о чем несколько позже.

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

Входные параметры:   C - код рестарта (#6C)

HL - адрес строки

XYPOS - системная переменная - текущая позиция печати.

Пример:

 

Листинг 11 Пример использования $str(#6C)

 

ORG #5D64

CALL CLS           ;очистка экрана

LD HL,TEXT1    ;адрес текста

LD C,#6C          ;код рестарта

RST #10              ;печать строки

CALL WAIT

LD HL,TEXT2    ;печать второй

LD C,#6C          ;строки

RST #10

CALL WAIT

LD HL,TEXT3    ;печать третей

LD C,#6C          ;строки

RST #10

CALL WAIT

JP EXIT

 

;текстовый буфер

 

TEXT1    DEFM "Рестарт str (#6C)"

DEFB #0D

TEXT2    DEFM " позволяет печатать"

DEFB #0D

TEXT3    DEFM "в абсолютных"

DEFM " координатах"

DEFB #0D

 

#6D (109) $lnstr

 

Рестарт lnstr(#6D) - так же, как и предыдущий, обращается в цикле к $ttyout(#0A), но распечатывает только заданное количество символов. Координаты печати также хранятся в системной переменной XYPOS.

Входные параметры:   C - код рестарта (#6D)

HL - адрес текста строки

B - количество символов

XYPOS - системная переменная - текущая позиция печати.

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

Для задания координат через системную переменную XYPOS пользуйтесь рестартами $prapd(#0C) из уровня DOS.SYS и $wtpos(#6B).

Пример:

 

Листинг 12 Пример работы $lnstr(#6D)

 

ORG #5D64

CALL CLS           ;очистка экрана

LD HL,TEXT      ;адрес текста

LD C,#6D          ;код рестарта

LD B,81

RST #10              ;печать строки

CALL WAIT

JP EXIT

 

;текстовый буфер

 

TEXT      DEFM "Рестарт str (#6C)"

DEFM "позволяет печатать"

DEFM " в абсолютных"

DEFM "координатах"

 

#6E (110) $smbgt

 

Строковый мобильный редактор. Сам печатает содержимое буфера.

Вход:     HL - адрес буфера,

A - ширина окна (X),

В (биты 0..4) - высота окна (Y), Старшие биты регистра B:

бит 7: курсор позиционируется на первый пробел с конца(0)/начала(1),

бит 6: на конец(0)/начало(1) буфера,

бит 5: режим "overtype"/"ME"(очистка буфера по нажатии).

D - M^CSR, E - K^CSR. (см. ПРИЛОЖЕНИЕ 2)

Выход: с обработкой ошибок:  Флаг C: ошибка ввода/вывода (нет драйвера например ).

Иначе (NC)флаг Z: Выход по клавише <Enter>, А = длина строки без <ВК>,

флаг NZ: Выход по одной из 5 специальных клавиш: CS/9, CS/SS, SS/A, SS/Space, SS/Enter (коды от #0E до #12), A = код клавиши.

 

#6F (111) EMPTY

 

Не используется.




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Вот вам ответ! - если не впадлу.
Сцена - дайджест ZX Spectrum новостей 2000 года с сайта SCENERGY.NM.RU
У нас в гостях - О группе - Virtual Vision group.
Рубрика X - Новелла к "Черному ворону" (окончание).
Жизнь баклана - неужели вы еще в состоянии сидеть за компом и читать уже второй PSY? Неужели вы еще не свихнулись от ужаса, коим напичкана наша газета?

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