ZX Format #01
31 октября 1995
  IS-DOS  

IS-DOS - программистам: Оконная система IS-DOS

Рубрика "IS-DOS - программистам". No 1

              Елисеев В. А.
        "Оконная система IS-DOS"
          (журнальный вариант)

(C) PENCRAFT 1995
(C) IskraSoft 1995

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

    Идея оконного интерфейса,  отсутство-
вавшего в традиционной операционной  сис-
теме ZX Spectrum, всегда привлекала к се-
бе  программистов,  мечтавших,  чтобы  их
произведения  выглядели  на    профессио-
нальном уровне. Одним из  шедевров  окон-
ной технологии по праву считается  знаме-
нитый "Оконный  интерфейс  Питера  Кука",
использовавшийся во многих играх, в  фир-
менных программах Art Studio, ASTRO и да-
же в  некоторых  творениях  отечественных
програмистов - DCU, FUT, STM, F Commander
и т.д.

    Разработчики системы  IS-DOS,  естес-
твено не остались в стороне и,  осознавая
важность  и  необходимость  реализации  в
профессиональной системе оконной техноло-
гии, выделили под нее целый уровень  сис-
темы, получивший название WIND.SYS.

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

   К сожалению, объем этой статьи не поз-
воляет подробно рассмотреть все  23  рес-
тарта,  составляющих  уровень   WIND.SYS,
поэтому речь сейчас пойдет только о 19 из
них, относящихся непосредственно к  рабо-
те с окнами  и  текстовой  информацией  в
них. Описанию строкового редактора и сис-
темы управления файловыми панелями  будет
посвящена  отдельная  статья  в   рубрике
"IS-DOS - программистам".

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

    Работа любого оконного интерфейса на-
чинается, естественно, с процедуры откры-
тия окна. Окно  в  системе  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
знакоместо от левой и верхней границ  об-
ласти окна.

                wt (#61)

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

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

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

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

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

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

╔═════════╦══════════╤═════════╤════════╗
║         ║ одинарная│ двойная │  без   ║
║  Окно   ║   рамка  │  рамка  │ рамки  ║
║         ║          │         │        ║
╟─────────╫──────────┼─────────┼────────╢
║         ║          │         │ A=#81  ║
║ прозрач-║  A=#80   │  A=#82  │ A=#83- ║
║   ное   ║          │         │  #FF   ║
║         ║          │         │        ║
╟─────────╫──────────┼─────────┼────────╢
║         ║          │         │ A=#01  ║
║ непроз- ║  A=#00   │  A=#02  │ 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-координаты
печати абсолютное и отсчитывается  не  от
левой границы окна, а  от  левой  границы
экрана. Перевод координат окна в кооорди-
наты печати и обратно  можно  осуществить
по формулам:

 (1)       n=N*8/6

 (2)       N=n*6/8,

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

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

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

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

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

    Действие этих подпрограмм основано на
других рестартах системы IS-DOS,  которые
будут описаны в следующих номерах журнала, а  по-
ка что просто запомните их:

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

    Итак, рассмотрим Листинг 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):

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

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

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

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

;где 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

;****************************************

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

┌───────────────────────────────────────┐
│                                       │
│                                       │
│    ╔═══════════════════╗              │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ╚═══════════════════╝▒             │
│      ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒             │
│                                       │
│                                       │
├───────────────────────────────────────┤
│ Рис. 2: результат  работы  программы  │
│                  Листинг 1            │
└───────────────────────────────────────┘
                                      ...
       
                box (#62)

    Следующий рестарт 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

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

CLS    LD   C,#73
       RST  #10
       RET

WAIT   LD   C,#07
       RST  #10
       RET

EXIT   XOR  A
       LD   A,#F4
       RET

;****************************************

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

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

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

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

 (5) Y1=Y+UM,

где Y1  - Y-координата рамки,
    Y   - Y-координата окна,
    UM  - отступ сверху

 (6) X1=X+LM,

где X1  - X-координата рамки,
    X   - X-координата окна,
    LM  - отступ слева

 (7) YS1=YS-UM-DM,

где YS1 - размер рамки по Y,
    YS  - размер окна по Y,
    UM  - отступ сверху,
    DM  - отступ снизу

 (8) XS1=XS-LM-RM,

где 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

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

CLS    LD   C,#73
       RST  #10
       RET

WAIT   LD   C,#07
       RST  #10
       RET

EXIT   XOR  A
       LD   A,#F4
       RET

;****************************************

    В результате  работы  программы  Лис-
тинг 3 на экране должна получиться карти-
на, изображенная на Рис. 3

┌───────────────────────────────────────┐
│                                       │
│                                       │
│    ╔═══════════════════╗              │
│    ║                   ║▒             │
│    ║   ┌───────────┐   ║▒             │
│    ║   │           │   ║▒             │
│    ║   │           │   ║▒             │
│    ║   │           │   ║▒             │
│    ║   │           │   ║▒             │
│    ║   │           │   ║▒             │
│    ║   │           │   ║▒             │
│    ║   │           │   ║▒             │
│    ║   │           │   ║▒             │
│    ║   └───────────┘   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ║                   ║▒             │
│    ╚═══════════════════╝▒             │
│      ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒             │
│                                       │
│                                       │
├───────────────────────────────────────┤
│ Рис. 3: результат  работы  программы  │
│                  Листинг 3            │
└───────────────────────────────────────┘

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

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

В следующем номере мы поговорим о  другой
не менее важной группе системных  рестар-
тов IS-DOS - рестартах печати символов  и
строк.



Другие статьи номера:

IS-DOS - Информация: новости в мире IS-DOS

IS-DOS - начинающим: IS-DOS - первое знакомство

IS-DOS - пользователям: Краткий путеводитель по системному диску IS-DOS

IS-DOS - Программистам: UniColor - cтандарт настройки цветов в программах IS-DOS

IS-DOS - программистам: Оконная система IS-DOS

IS-DOS - Программистам: Программа gmen.com

Железо - Доработки: блокиpовка поpта #1FFD на Scorpion ZS-256

Железо - Переферия: тормоз KAY'я

Железо - Производители: KAY

Железо - производители: Scorpion ZS 256

Игрушки - Новелла: Crystal Kingdom Dizzy

Игрушки - По полочкам: Быки и коровы

Игрушки - По полочкам: НЛО. Враг неизвестен

Игрушки - Что новенького: обзор новинок

Интервью - Старые знакомые: Рассказ Славы Медноногова о своей деятельности как программиста

Информация - От авторов

Конкурс - Конкурс на конкурс

Конкурс - Уровни к Laser Squad

Отдохнём - Нечто: один день из жизни программиста

Почтовый ящик - Доска объявлений

Почтовый ящик - Обмен опытом: читы

Почтовый ящик - Письма по играм

Премьера - Color Lines

Программистам - Basic для всех: Basic для программистов

Программистам - Ассемблер для чайников

Программистам - Системы: Редактор миссий к игре Laser Squad

Разное - Amiga: история Амиги

Разное - Перспективы: игрушки


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

Похожие статьи:
Смысл - веченые жизни и Pokes: SexMine Sweper, Marrow in the world of wisdom.
Твоя Игра! - Обзор игра с конкурса Твоя Игра 2002.
Paradox 2000 - Официальные результаты второго южно-российского фестиваля PARADOX'2K.

В этот день...   28 марта