Из журнала ZX Format #1, Санкт-Петербург, 11.1995 Рубрика "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 - рестартах печати символов и строк. Из журнала ZX Format #2, Санкт-Петербург, 12.1995 Рубрика "IS-DOS - программистам". No 2 Елисеев В. А. "Оконная система IS-DOS" (журнальный вариант) (C) PENCRAFT 1995 (C) IskraSoft 1995 Продолжение, начало в No 1. _________________________________________ Рестарты печати. Следующая важнейшая операция - пе- чать текстовых сообщений - представлена в системе IS-DOS целой группой рестартов, различающихся, главным образом, способом задания исходных параметров и некоторыми дополнительными возможностями. Всего в составе уровня WIND.SYS имеется 7 рестартов, относящихся к про- цессу печати текстов. Первые три из них отличаются использованием в качестве координат печати информации, заключенной в векторе окна (Print pos, Print size, Y-coord). Практически эти три рестарта представляют собой одну программу, имею- щую три точки входа для задания различ- ных параметров. lwt (#65) lwt(#65) - позволяет распечатать в окне заданное количество строк из тексто- вого буфера с заданным отступом по 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 ;отступ по Y LD B,4 ;количество строк RST #10 CALL WAIT ;печать строк текста из буфера в окне 2 LD IX,WIND2 LD HL,TEXT2 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 ;дополнительные процедуры 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 см. на Рис. 4. +---------------------------------------+ | | | +=======================+ | | | Рестарт lwt(#65) | | | | позволяет печатать | | | | в окне текст из | | | | текстового буфера | | | | | | | | | | | +=======================+ | | | | +-----------------------+ | | | в регистре B задано | | | | количество строк, | | | | которое необходимо | | | | напечатать | | | | | | | | | | | +-----------------------+ | | | | | +---------------------------------------| | Рис. 4: Печать текста в окне lwt(#65) | +---------------------------------------+ adrwt (#66) adrwt(#66) - предназначен для распечатки в окне текста, расположенного непосредственно после вектора окна. Входные параметры: 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 ;дополнительные процедуры 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 ;**************************************** lenwt (#67) lenwt(#67) - так же предназначен для распечатки текста в окне, однако текст не закрепляется за вектором конкретного ок- на, а может находиться в произвольном месте программы. Основное преимущество рестарта 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 ;дополнительные процедуры 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 ;**************************************** Результат работы программы Листинг 6 представлен на рис. 5: +---------------------------------------+ | | | +=======================+ | | | Рестарт lenwt(67) | | | | позволяет печатать | | | | текст, находящийся | | | | в любом месте | | | | программы | | | | | | | +=======================+ | | | | +-----------------------+ | | | Рестарт lenwt(67) | | | | позволяет печатать | | | | текст, находящийся | | | | в любом месте | | | | программы | | | | | | | +-----------------------+ | | | | | +---------------------------------------| | Рис. 5: Печать текста lenwt(#67) | +---------------------------------------+ prstr (#68) Рестарт 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. При формировании текстового бу- фера, задании отступа и числа печатаемых символов необходимо самостоятельно сле- дить за тем, чтобы текст не вышел за пре- делы окна. При ширине строки, большей чем ширина поля печати окна выравнивание ав- томатически осуществляется по левому краю, независимо от состояния двух стар- ших битов регистра A. Подфункция 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. Рассмотрим пример. Изобразим на экра- не рамку из звездочек в двух разных ва- риантах для двух окон (см. Рис. 6): +---------------------------------------+ | | | ************************* | | * * * | | * * * | | ************************* | | * * | | * * | | * * | | * * | | ************************* | | | | ************************* | | * * * * | | * * * * | | * * * * | | ************************* | | * * * | | * * * | | * * * | | ************************* | | | +---------------------------------------| | Рис. 6: Рамки из звездочек для | | демонстрации работы prstr | +---------------------------------------+ Для рисования двух этих рамок при по- мощи подфункции 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 ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** Подфункция 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 "с выравниванием" ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** Подфункция 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 ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** Подфункция 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 ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT $XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** Следующие два рестарта предназначены для печати на экране в абсолютных коорди- натах, не привязанных к конкретному окну. str (#6C) Рестарт 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 ;дополнительные процедуры 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 ;**************************************** lnstr (#6D) Рестарт 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 " координатах" ;дополнительные процедуры 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 ;**************************************** Еще один рестарт печати tylin(#71) имеет непосредственное отношение к работе строкового редактора edstr(#7F), поэтому он будет рассмотрен в одной из следующих статей нашей рубрики. Продолжение следует ... В следующем номере нашего журнала Вы поз- накомитесь с довольно большой группой вспомогательных рестартов, также входя- щих в состав уровня WIND.SYS. _________________________________________ Из журнала ZX Format #3, Санкт-Петербург, 03.1996 Рубрика "IS-DOS - программистам". No 3 Елисеев В. А. "Оконная система IS-DOS" (журнальный вариант) (C) PENCRAFT 1995 (C) IskraSoft 1995 Окончание, начало в No 1, 2. Вспомогательные рестарты. _________________________________________ wtpos (#6B) К двум последним рестартам печати не- посредственно примыкает рестарт wtpos(#6B), позволяющий модифицировать текущие координаты печати для рестартов lnstr и str. Рестарт 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" ;дополнительные процедуры 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 ;**************************************** То же с использованием 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" ;дополнительные процедуры 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 ;**************************************** scrol (#70) Еще один чрезвычайно полезный при ра- боте с текстами рестарт - scrol(#70). Он позволяет смещать содержимое рабочей об- ласти окна на строку вверх или вниз. При работе рестарта предусмотрено программирование заполнения крайнего ле- вого и крайнего правого знакомест в осво- бодившейся строке (нижней при движении вверх и наоборот). Входные параметры: IX - вектор окна HL - значение крайних байтов заполнения освободившейся строки (образ коди- руется в двоичном представлении, например: одинарная линия по краю кодируется как 10000000 00000001 и т. п. ) A - режим работы: A=0 - настройка рестарта на вектор окна - вызывается один раз перед началом работы в данном окне. Настройка сохраняется на все время работы до следующего вызова scrol c нулевым значением в регистре A. A=1 - скроллинг на строку вверх A=2 - скроллинг на строку вниз Для нормальной работы scrol необходи- мы еще два параметра, добавляемые к стан- дартному вектору окна и располагающиеся непосредственно перед ним: IX-1 скорость скроллинга - возможные значения - 1, 2, 4, 8 определяет время, в течение которого строка перемещается на 8 пикселей по вер- тикали IX-2 задержка скроллинга - возможные значения от 0 до 255 - регулирует время паузы между последовательны- ми вызовами рестарта Подбором этих двух параметров дости- гается наибольшая плавность движения при требуемой скорости скроллинга. Пример: ;**************************************** ;Листинг 15 Применение scrol(#70) ORG #5D64 ;открытие окна CALL CLS LD IX,WIND LD C,#61 LD A,2 RST #10 ;настройка процедуры scroll ;на вектор окна: LD IX,WIND ;вектор окна LD C,#70 ;код рестарта LD HL,#0000 ;заполнение XOR A ;в рег. A - 0 RST #10 ;печать строки prstr подфункция 3 LD IX,WIND LD HL,TEXT LD C,#68 LD E,3 LD A,%00001010 LD B,1 RST #10 ;скроллинг окна вверх в цикле на 5 строк LD B,5 M1 PUSH BC LD C,#70 ;код рестарта LD A,1 ;скроллинг вверх LD IX,WIND ;вектор окна LD HL,#0000 ;заполнение RST #10 POP BC DJNZ M1 CALL WAIT JP EXIT ;вектор окна + 2 байта для рестарта ;scrol(#70) DEFB 25 ;задержка DEFB 01 ;скорость WIND DEFB 0 DEFB 5 DEFB 12 DEFB 25 DEFB %00000111 DEFB %00000001 DEFB 2 DEFB 25 ;текст для печати TEXT DEFM "Так работает scrol(#70) " DEFB #0D DEFB #03 ;Дополнительные процедуры: CLS LD C,#73 ;рестарт cls RST #10 ;для очистки экрана RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;выход в IS-DOS LD A,#F4 RET ;**************************************** Применение рестарта scrol вместе с рестартами печати (например prstr) позво- ляет организовать на экране режим "бегу- щего текста". Рассмотрим еще один пример: ;**************************************** ;Листинг 16 Программа "бегущий текст" ORG #5D64 ;процедура открытия окна CALL CLS LD IX,WIND LD C,#61 LD A,2 RST #10 ;настройка процедуры scrol ;на вектор окна: LD IX,WIND LD C,#70 LD HL,0 XOR A RST #10 ;входные параметры для процедуры печати LD A,%00001010 ;в рег. A - биты 7 и 6 определяют режим ; выравнивания ; биты 5...0 определяют отступ ; от верхнего края ; окна LD B,1 ;номер строки в ;тексте (строки ;отделяются друг ;от друга символом ;с кодом #0D) M1 PUSH AF ;сохранить рег. A PUSH BC ;сохранить BC ;печать строки по номеру ее в тексте LD IX,WIND ;адрес вектора окна LD HL,TEXT ;адрес нач. текста LD C,#68 ;код prstr LD E,3 ;код подфункции RST #10 CALL SCROLL ;вызов scrol POP BC ;восстановить BC INC B ;увеличить номер ;строки в тексте LD A,B ;проверка на число CP 9 ;напечатанных строк JP Z,END ;выход, если все ;строки напечатаны POP AF ;восстановить A JR M1 ;переход к печати ;следующей строки ;вектор окна + 2 байта для рестарта ;scrol(#70) DEFB 25 ;задержка DEFB 01 ;скорость WIND DEFB 1 DEFB 1 DEFB 12 DEFB 28 DEFB %00000111 DEFB %00000001 DEFB 4 DEFB 35 ;текст для печати TEXT DEFM " Эта программа " DEFB 13 DEFM " представляет собой пример" DEFB 13 DEFM " организации в системе " DEFB 13 DEFM " IS-DOS работы с экраном " DEFB 13 DEFM " в режиме 'бегущий текст'" DEFB 13 DEFM " Вывод текста организуется" DEFB 13 DEFM " при помощи рестартов" DEFB 13 DEFM " scrol(#70) и prstr(#68)" DEFB 13 ;Дополнительные процедуры: CLS LD C,#73 ;рестарт cls RST #10 ;для очистки экрана RET SCROLL LD C,#70 ;процедура скрол- LD A,1 ;линга окна на LD IX,WIND ;строку вверх LD HL,#0000 RST #10 RET END POP AF ;завершение работы CALL WAIT JR EXIT WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;выход в IS-DOS LD A,#F4 RET ;**************************************** ... ... cls (#73) Следующий рестарт - cls(#73) уже неоднократно встречался в наших примерах. Рассмотрим более подробно как с его по- мощью можно очистить экран дисплея. Если при вызове рестарта cls в регис- тре A находится 0, то происходит полная очистка экрана - все пиксели сбрасывают- ся, область цветовых атрибутов заполняет- ся текущим значением системной перемен- ной PAPER, находящейся в векторе экрана, адрес которого можно получить, используя рестарт q_scr(#72), о чем будет идти речь ниже. Также при этом цвет бордюра приво- дится в соответствие с текущим значением системной переменной BORD из того же век- тора. Формат задания значений цветов стандартный, атрибуты бордюра кодируются тремя младшими байтами, остальные байты игнорируются. Если же перед вызовом cls в регистре A находится число, отличное от нуля, то сброс пикселей не происходит, а инициали- зируется только область атрибутов экрана, причем значение регистра A трактуется как байт атрибутов в стандартном представле- нии. Изменения цвета бордюра в этом слу- чае не происходит. Как уже говорилось выше, доступ к системным переменным PAPER и BORD можно получить через вектор экрана, адрес кото- рого возвращает в регистре HL' рестарт q_scr(#72). Вектор экрана (не путать с вектором окна) представляет собой об- ласть системных переменных, уровня WIND.SYS. Необходимые нам переменные рас- полагаются в нем следующим образом: Если в регистре IX - адрес вектора экрана, то (IX+0) - значение PAPER (IX+1) - значение BORD Остальные системные переменные этого вектора будут рассмотрены позднее. Процедура для занесения необходимых значений цветов в соответствующие систем- ные переменные может выглядеть примерно так: LD C,#72 ;код рестарта q_scr RST #10 EXX ;HL - адрес вектора PUSH HL ;переносим его POP IX ;в регистр IX LD A,%00101010 LD (IX+0) ;загрузка атрибутов ;экрана LD A,%00000100 LD (IX+1) ;загрузка атрибутов ;бордюра После этого Вы смело можете обнулять регистр A и вызывать cls: XOR A LD C,#73 RST #10 значения цветов будут установлены именно так, как Вы и хотели. Рассмотрим пример: ;**************************************** ;Листинг 17 Пример работы cls ORG #5D64 ;установка цветовых атрибутов без ;сброса пикселей (A - байт атрибутов) LD A,%00111000 LD C,#73 ;код рестарта cls RST #10 CALL WAIT ;установка значений системных переменных ;PAPER и BORD LD C,#72 ;получение адреса RST #10 ;вектора экрана EXX ;в HL - адрес PUSH HL ;перенос адреса POP IX ;в регистр IX LD A,%00101010 LD (IX+0),A ;установка цветов ;экрана LD A,%00000011 LD (IX+1),A ;установка цветов ;бордюра ;полная очистка экрана, цвета берутся из ;системных переменных PAPER и BORD XOR A ;в A - 0 LD C,#73 RST #10 CALL WAIT JR EXIT ;дополнительные процедуры: WAIT LD C,#07 ;ожидание клавиши RST #10 EXIT XOR A ;выход в IS-DOS LD A,#F4 RET ;**************************************** awt (#63), awtc (#64) Еще несколько служебных рестартов мо- гут пригодиться при работе с окнами в 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 ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** y (#76), n (#77) Еще два рестарта отвечают за включе- ние и выключение в текущей позиции экра- на мигающего курсора. Положение курсора определяется уже знакомой нам системной переменной XYPOS, находящейся в векторе символьного устрой- ства вывода. Рестарт y(#76) включает курсор в те- кущей позиции, а рестарт n(#77) - выклю- чает. Координаты курсора абсолютные. Процедура изображения мигающего кур- сора добавляется в цепочку процедур, вы- зываемых по прерываниям от таймера прим помощи рестарта im2(#1E) из уровня DOS.SYS. При включении следующего курсора не забывайте убирать предыдущий, хотя ника- ких серьезных последствий, кроме "засоре- ния" экрана останками курсоров это не вы- зовет, а рестарт n(#77) спокойно уберет их все за один прием. Пример: ;**************************************** ;Листинг 19 Пример работы с курсором ORG #5D64 ;открытие окна CALL CLS LD IX,WIND LD C,#61 LD A,2 RST #10 ;печать строк текста из буфера в окне ;через подфункцию 3 рестарта prstr LD IX,WIND LD C,#68 LD E,3 LD HL,TEXT LD A,%11000010 LD B,1 RST #10 LD C,#68 LD E,3 LD B,2 LD HL,TEXT LD A,%11000100 RST #10 CALL WAIT ;включение и перемещение курсора ;по экрану LD B,12 LD H,4 ;Y-смещение для ;wtpos LD L,5 ;X-смещение для ;wtpos M1 PUSH BC PUSH HL LD C,#6B ;вызов wtpos, уста- RST #10 ;новка начальных ;координат курсора LD C,#76 ;включение курсора RST #10 CALL WAIT ;ожидание клавиши LD C,#77 ;выключение курсора RST #10 POP HL ;увеличение смеще- INC HL ;ния координат POP BC DJNZ M1 ;перейти к началу ;цикла с новыми ;координатами CALL WAIT JP EXIT ;вектор окна WIND DEFB 1 DEFB 1 DEFB 8 DEFB 30 DEFB %00001111 DEFB %00000001 DEFB 3 DEFB 38 ;текстовый буфер TEXT DEFM "Рестарты y(#76) " DEFM "и n(#77) " DEFB #0D DEFM "включение-выключение" DEFM " курсора" DEFB #0D DEFB #03 ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** d_a (#7C), a_d (#7D) Еще два рестарта могут быть необходи- мы Вам при работе с числами. Они позво- ляют переводить целые числа из стандар- тного 2-х или 4-х байтового представле- ния в ASCII-строку и наоборот. При помо- щи этих двух рестартов Вы сможете привес- ти любое число в форму, приемлемую для печати на экране, а также сможете сде- лать понятным компьютеру число, введен- ное в символьной форме. Рестарт d_a(#7C) - преобразует целое 2-х или 4-х байтовое число в ASCII-строку. Входные параметры: C - код рестарта (#7C) DE - адрес числа HL - адрес выходного буфера A - длина выходного буфера B - основание системы счисления (2, 8, 10, 16) Состояние флага C определяет формат числа: флаг C=0 - 2-х байтовое число флаг C=1 - 4-х байтовое число На выходе образуется требуемое число в символьной форме, причем строка внутри буфера выравнивается по правой границе, а оставшаяся левая часть дополняется пробе- лами. При переполнении буфера рестарт возвращается в вызывающую программу с ус- тановленным флагом C (независимо от его первоначального состояния) и кодом ошиб- ки 1 (переполнение буфера) в регистре A. При переводе чисел в 16-ричную, 8-ричную и двоичную системы символы этих систем (#, o, % и т. п. ) не применяются и в буфер не вносятся, поэтому за принад- лежностью числа к той или иной системе следите самостоятельно. Рассмотрим пример: ;**************************************** ;Листинг 20 Перевод чисел в символьную ; форму и распечатка их в окне ORG #5D64 ;открытие окна CALL CLS LD IX,WIND LD C,#61 LD A,2 RST #10 ;перевод числа из 2-х байтовой формы ;в символьную (в DE - число) LD C,#7C ;код рестарта LD DE,#9C40 ;исходное число LD HL,TEXT ;адрес буфера LD A,5 ;длина буфера SCF ;сбросим CCF ;флаг C LD B,10 ;десятичная система ;счисления RST #10 ;печать числа в символьной форме ;через подфункцию 1 рестарта prstr LD IX,WIND LD C,#68 LD E,1 LD HL,TEXT LD A,%11000010 LD B,5 RST #10 CALL WAIT ;перевод числа из 4-х байтовой формы ;в символьную (в DE - адрес числа) LD C,#7C ;код рестарта LD HL,TEXT ;адрес буфера LD DE,TABL ;адрес числа LD A,8 ;длина буфера LD B,16 ;16-ричная система ;счисления SCF ;установим флаг C RST #10 ;печать числа в окне LD IX,WIND LD C,#68 LD E,1 LD HL,TEXT LD A,%11000100 LD B,8 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 " " ;исходное 4-х байтовое число TABL DEFW #0000 ;младшие 2 байта DEFW #9C40 ;старшие 2 байта ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** ... ... Рестарт a_d(#7D) предназначен для об- ратного перевода числа из символьной фор- мы в стандартную четырехбайтовую. Он преобразует ASCII-строку указанной длины, или завершенную кодом #0D, игнорируя ве- дущие пробелы. Результат располагается в альтернативных регистрах - младшие байты в регистровой паре HL', старшие байты - в регистровой паре DE', при этом в регис- тровой паре BC' остается адрес продолже- ния входного буфера. Входные параметры: C - код рестарта (#7D) HL - адрес входного буфера A - длина входного буфера; если A=0, то преобразуется строка до символа с кодом #0D B - основание системы счисления по умолчанию. Основание системы счис- ления не должно быть больше 16, причем 0 трактуется как 10 (деся- тичная система) Система счисления может также опреде- ляться первым символом ASCII-строки: # h H - 16-ричная система . d - десятичная система o O - восьмеричная система % b - двоичная система Выходные параметры: HL'- старшие байты числа DE'- младшие байты числа BC'- адрес следующего символа ASCII буфера Этот рестарт в комплексе с предыду- щим позволяет производить арифметические действия над числами, хранящимися в сим- вольной форме (например внутри текста). Рассмотрим пример. Пусть необходимо напечатать строку "10000+12=", выполнить указанное в ней арифметическое действие и напечатать результат (см. Листинг 21). ;**************************************** ;Листинг 21 Пример использования a_d(#7D) ; арифметические действия над ; числом в символьной форме ORG #5D64 ;открытие окна CALL CLS LD IX,WIND LD A,2 LD C,#61 RST #10 ;печать строки с исходным числом LD HL,TEXT LD C,#68 LD E,1 LD B,9 ;длина всей строки LD A,%11000001 RST #10 CALL WAIT ;перевод числа в 4-х байтовую форму LD HL,TEXT ;адрес входного ;буфера LD A,5 ;кол-во символов ;в исходном числе LD B,10 ;система счисления LD C,#7D ;код рестарта RST #10 EXX ;на выходе в HL - младшие байты, ;а в DE - старшие LD BC,12 ;сложение чисел ADD HL,BC PUSH DE ;помещение резуль- PUSH HL ;тата в буфер LD HL,TABL POP DE LD (HL),E INC HL LD (HL),D INC HL POP DE LD (HL),E INC HL LD (HL),D ;перевод числа в символьную форму ;результат помещается в текст на место ;исходного числа LD C,#7C LD HL,TEXT LD A,5 ;кол-во символов ;числа - результата LD B,10 LD DE,TABL SCF RST #10 ;печать результата LD C,#68 LD E,1 LD IX,WIND LD HL,TEXT LD B,5 LD A,%11000011 RST #10 CALL WAIT JP EXIT ;вектор окна WIND DEFB 1 DEFB 1 DEFB 5 DEFB 30 DEFB %00000111 DEFB %00000001 DEFB 3 DEFB 35 ;текстовый буфер TEXT DEFM "10000+12=" ;буфер числа TABL DEFB #00 DEFB #00 DEFB #00 DEFB #00 ;Дополнительные процедуры: CLS LD C,#73 ;рестарт cls RST #10 ;для очистки экрана RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;выход в IS-DOS LD A,#F4 RET ;**************************************** Еще одним практическим примером ис- пользования рестартов a_d и d_a может служить Листинг 22 - программа перевода чисел из одной системы счисления в другую: ;**************************************** ;Листинг 22 Перевод чисел в 16-ричную ; систему (пример использова- ; ния d_a ORG #5D64 ;открытие окна CALL CLS LD IX,WIND LD C,#61 LD A,2 RST #10 ;печать пояснительного текста LD C,#66 RST #10 ;ввод числа с клавиатуры START LD C,#88 ;рестарт ed_dig LD A,17 ;из уровня SHELL LD DE,#0402 ;будет рассмотрен LD HL,#0000 ;в следующих LD IX,WIND ;выпусках серии RST #10 JP C,START JP NZ,EXIT ;помещение числа в буфер EXX EX DE,HL LD HL,TABL LD (HL),E INC HL LD (HL),D ;перевод числа из 4-х байтовой формы ;в символьную (в DE - адрес числа) LD C,#7C ;код рестарта LD HL,TEXT ;адрес буфера LD DE,(TABL) ;адрес числа LD A,16 ;длина буфера LD B,16 ;система ;счисления SCF CCF ;сбросим флаг C RST #10 ;печать числа в окне LD IX,WIND LD C,#68 LD E,1 LD HL,TEXT LD A,%10000100 LD B,16 RST #10 CALL WAIT CP #10 JP Z,EXIT JP START ;вектор окна WIND DEFB 1 DEFB 1 DEFB 8 DEFB 30 DEFB %00001111 DEFB %00000001 DEFB 3 DEFB 36 ;пояснительный текст DEFM " Перевод чисел в 16-ричную" DEFM " систему" DEFB #0D DEFM " Входное значение " DEFM " Результат " DEFB #0D DEFB #0D DEFM " " DEFM " 0" DEFB #0D DEFB #0D DEFM " (C) PENCRAFT 1994 " DEFM "SS+A - Выход" DEFB #0D DEFB #03 ;текстовый буфер TEXT DEFM " " ;буфер числа TABL DEFW #0000 ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET EXIT XOR A ;стандартный выход LD A,#F4 ;в IS-DOS RET ;**************************************** analys (#7E) Рестарт analys(#7E) позволяет органи- зовать в Вашей программе таблицу проце- дур. Он находит в таблице адрес необходи- мой процедуры по ее коду и передает ей управление. Входные параметры: HL - адрес таблицы процедур A - код процедуры Таблица состоит из записей по три байта, из которых первый - код процедуры, а два оставшихся - ее адрес в стандар- тном формате (первый байт - младший). Последней записью должна быть проце- дура обработки ситуации "код не найден", для нее зарезервирован код #FF, после ко- торого и следует поместить ее адрес. На выходе из рестарта при передаче управления процедуре в регистре HL сохра- няется адрес таблицы, в A - код команды, а регистр BC' содержит адрес процедуры, которой передается управление. Остальные регистры (кроме альтернативного набора) не изменяются и могут быть использованы для передачи параметров. Переход к проце- дуре осуществляется путем помещения ее адреса рестартом analys на стек и пода- чей команды RET, поэтому передача пара- метров через стек в данном случае нежела- тельна во избежание путаницы с адресами. Все процедуры должны заканчиваться инструкцией RET, которая возвращает уп- равление в точку, следующую за вызовом рестарта analys. При помощи рестарта analys можно ор- ганизовать, например, программу для обра- ботки клавиш управления курсором переда- вая управление процедурам перемещения его в разных направлениях в зависимости от кода нажатой клавиши (см. Листинг 23). ;**************************************** ;Листинг 23 Вызов процедур по таблице ; рестарт analys(#7E) ORG #5D64 CALL CLS ;установка координат курсора LD H,10 ;Y-coord курсора LD L,20 ;X-coord курсора LD C,#0C ;вызов prapd, уста- RST #10 ;новка начальных ;координат курсора ;основная программа MAIN LD C,#76 ;включение курсора RST #10 LD C,#12 ;вызов вектора RST #10 ;символьного устр. EXX ;вывода, HL - адрес INC HL ;коорд. курсора EX DE,HL ;помещаем его в DE CALL WAIT ;ожидание клавиши ;в A - код клавиши PUSH AF ;сохраним его LD C,#77 ;выключение курсора RST #10 POP AF ;восстановим рег. A LD HL,TABL ;адрес таблицы ;процедур LD C,#7E ;код рестарта ;analys RST #10 ;вызов рестарта ;управление передается по адресу из ;таблицы в сответствии с кодом клавиши ;по окончании отработки процедуры - ;возврат по RET на следующую после вызова ;рестарта команду CP #F4 ;проверка на RET Z ;окончание работы JP MAIN ;повторить цикл ;таблица процедур TABL DEFB #0B ;CS+7 DEFW UP DEFB #0A ;CS+6 DEFW DOWN DEFB #08 ;CS+5 DEFW LEFT DEFB #09 ;CS+8 DEFW RIGHT DEFB #10 ;SS+A DEFW END DEFB #FF ;остальные клавиши DEFW NO_KEY ;процедуры UP EX DE,HL ;увеличение INC HL ;координаты Y DEC (HL) RET DOWN EX DE,HL ;уменьшение INC HL ;координаты Y INC (HL) RET LEFT EX DE,HL ;уменьшение DEC (HL) ;координаты X RET RIGHT EX DE,HL ;увеличение INC (HL) ;координаты X RET NO_KEY RET ;"ключ не найден" END XOR A ;установка парамет- LD A,#F4 ;ров для выхода в RET ;IS-DOS и флага Z ;для выхода из ;цикла MAIN ;после отработки процедур инструкция RET ;осуществляет переход к следующей после ;вызова рестарта analys команде ;дополнительные процедуры CLS LD C,#73 ;очистка экрана RST #10 RET WAIT LD C,#07 ;ожидание клавиши RST #10 RET ;**************************************** Итак, в первой статье рубрики "IS-DOS - программистам" мы с Вами расмотрели большую часть уровня WIND.SYS, организую- щего в системе работу с окнами и строка- ми текста. Помимо описанных выше рестар- тов, к этому уровню относятся еще четыре: panel(#6A) - работа с файловыми панелями, edstr(#7F), smbgt (#6E) и tylin(#71) - строковый редактор. Описание этих доста- точно сложных рестартов будет опубликова- но в одной из следующих статей. _________________________________________