Радио-86РК/Радио 04-90/Организация окон в программах на Basic

Материал из Emuverse
Перейти к: навигация, поиск
Red copyright.png Данный материал защищён авторскими правами!

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

Автор: Г. ШТЕФАН

Источник: http://retro.h1.ru/RK86/WinBas/MakeWin.html

При описании драйвера оконного интерфейса в предыдущей статье упоминалось, что его можно использовать совместно с программами на языке БЕЙСИК. К сожалению, непосредственно из БЕЙСИК — программ обращаться к оконному драйверу нельзя, так как, во-первых, в интерпретаторе не был решен вопрос передачи параметров подпрограммам в кодах, а во-вторых, при разработке МОНИТОРа не была предусмотрена возможность перехвата обращений к подпрограммам МОНИТОРа по основным точкам входа. Поэтому для практического использования драйвера разработано несколько вспомогательных подпрограмм на АССЕМБЛЕРе для сопряжения БЕЙСИК — программ с драйвером. Исходный текст этих подпрограмм приведен в табл.1.

				Таблица 1
	ORG A8BEН
; ПАРАМЕТРЫ НАСТРОЙКИ НА П/П ДРАЙВЕРА
NUMWND:	EQU 		; СМ. ДРАЙВЕР ОКОННОГО ИН-СА
RESETW:	EQU 		; СМ. ДРАЙВЕР ОКОННОГО ИН-СА
WRITEC:	EQU 		; СМ. ДРАЙВЕР ОКОННОГО ИН-СА
SAVEW:	EQU 		; СМ. ДРАЙВЕР ОКОННОГО ИН-СА
FRAME:	EOU 		; СМ. ДРАЙВЕР ОКОННОГО ИН-СА
RESTW:	EQU 		; СМ. ДРАЙВЕР ОКОННОГО ИН-СА
;
A0004H:	EOU 0004Н 	; АДРЕС АДРЕСА НАЧАЛА ИНТЕРЛР.
А0388Н:	EQU 0388Н 	; АДРЕС ОБРАЩЕНИЯ К П/П МОН-РА
А1600H:	EQU 1600Н 	; АДРЕС НАЧАЛА ИНТЕРПРЕТАТОРА
АF809Н:	EQU 0F809H 	; АДРЕС П/П ВЫВОДА СИМВОЛА
; ОБЛАСТЬ СВЯЗИ BASIC-ПРОГРАММ И ДРАЙВЕРА.
BASE:	EQU x 		; НАЧАЛО ОБЛАСТИ СВЯЗИ.СМЕЩЕНИЕ
	JMP BEGIN 	; ИНИЦИАЛИЗАЦИЯ ДРАЙВЕРА <+в>
	JMP OPEN 	; ОТКРЫТЬ ОЧЕРЕДНОЕ ОКНО (+3)
	JMP CLOSE 	; ЗАКРЫТЬ АКТИВНОЕ ОКНО (+6)
;
; ПАРАМЕТРЫ ОТКРЫВАЕМОГО ОКНА
; КООРДИНАТЫ ВЕРХНЕГО ЛЕВОГО УГЛА ОКНА
	DB 0 		; НОМЕР СТОЛБЦА ЭКРАНА 0:63 (+9) 
	DB 0 		; НОМЕР СТРОКИ ЭКРАНА в:24 < + 1в>
; РАЗМЕРЫ ОТКРЫВАЕМОГО ОКНА
	DB 0 		; ШИРИНА ОКНА (С РАМКОЙ) (+11) 
	DB 0 		; ВЫСОТА ОКНА (С РАМКОЙ) (+12)
;+++++++++++++++++++++++++++++++++++++++++++++++++
;  BEGIN" - ВОССТАНОВЛЕНИЕ ИНТЕРПРЕТАТОРА ПОСЛЕ  +
;+ СБРОСА ПРИ НАЛИЧИИ АКТИВНОГО ОКНА             +
BEGIN0:	CALL UNCNCT 	; ВОССТАНАВЛИВАЕМ ИНТЕРПРЕТАТОР
	JMP А1600Н 	; НА НАЧАЛО РАБОТЫ ИНТЕРПРЕТ. ;
;++++++++++++++++++++++++++++++++++++++++++++++++++++
;+ BEGIN - ИНИЦИАЛИЗАЦИЯ ОКОННОГО ДРАЙВЕРА И/ИЛИ    +
; + ВОССТАНОВЛЕНИЕ КОДОВ ИНТЕРПРЕТАТОРА 	    +
;++++++++++++++++++++++++++++++++++++++++++++++++++++
begin:	push н 		; сохранить регистры 
	push d 
	push в
	CALL RESETW 	; ИНИЦИАЛИЗАЦИЯ ДРАЙВЕРА 
	CALL UNCNCT 	; ВОССТАНОВЛЕНИЕ BASIC'A 
	POP В 		; ВОССТАНОВИТЬ РЕГИСТРЫ 
	POP D 
	POP H 
	RET
; OPEN - НАСТРОЙКА ИНТЕРПРЕТАТОРА И ОТКРЫТИЕ
; нового окна.
; ВХОД: ПРЕДВАРИТЕЛЬНО УСТАНОВИТЬ ПАРАМЕТРЫ
; ОТКРЫВАЕМОГО ОКНА
; ВЫХОД: НОМЕР АКТИВНОГО ОКНА
OPEN:	PUSH H
	PUSH D 		; СОХРАНИТЬ РЕГИСТРЫ
	PUSH В
	LDA NUMWND 	; ЗАГРУЗ.НОМЕР АКТИВНОГО ОКНА ОRА А 
			; БЫЛО М ОТКРЫТОЕ ОКНО CZ CONNCT
			; СВЯЗАТЬ ДРАЙВЕР С BASIC-ИНТЕР. 
	LHLD BASE+11 	; ЗАГРУЗИТЬ РАЗМЕРЫ ОКНА XCHG
	LHLD BASE+9 	; ЗАГРУЗИТЬ КООРДИНАТЫ ОКНА 
	MVI А,24 	; ПРИВЕДЕМ КООРДИНАТМ К ВИДУ 
	SUB H 		; ПРИНЯТОМУ В БЕЙСИКЕ MOW H,A 
			; ДЛЯ УСТАНОВКИ КУРСОРА CALL SAVEW 
			; СОХРАНИТЬ ЭКРАН CALL FRAME 
			; ПОСТРОИТЬ РАМКУ POP В 
			; ВОССТАНОВИТЬ РЕГИСТРЫ 
	POP D 
	POP H
	LDA NUMWND 	; НОМЕР АКТИВНОГО ОКНА
	RET 		; ВЕРНУТЬ В BASIC
;+++++++++++++++++++++++++++++++++++++++++++++++++++++
;+ CLOSE- СТИРАНИЕ АКТИВНОГО ОКНА.                   +
;+++++++++++++++++++++++++++++++++++++++++++++++++++++
;+ ВЫХОД: НОМЕР АКТИВНОГО ОКНА                       +
;+++++++++++++++++++++++++++++++++++++++++++++++++++++
CLOSE:	PUSH H 		; СОХРАНЯЕМ РЕГИСТРЫ
	PUSH D
	PUSH В
	CALL RESTW 	; СТИРАЕМ АКТИВНОЕ ОКНО
	LDA NUMWND 	; НОМЕР АКТИВНОГО ОКНА 
	ORA А 		; ЕСЛИ ЕГО НЕТ.
	CZ UNCNCT 	; ВОССТАНОВИТЬ ИНТЕРПРЕТАТОР
	POP В 		; ВОССТАНОВИТЬ РЕГИСТРЫ
	POP D
	POP H
	LDA NUMWND 	; НОМЕР АКТИВНОГО ОКНА
	RET 		; ВЕРНУТЬ В BASIC
; CONNCT - ПРИСОЕДИНИТЬ ДРАЙВЕР К ИНТЕРПРЕТАТОРУ
; ОБРАИЕНИЕ ИНТЕРПРЕТАТОРА К ТОЧКЕ ВХОДА 0F809Н
; ЗАМЕНЯЕТСЯ НА ОБРАЩЕНИЕ К П/П ДРАЙВЕРА WRITEC
; ПЕРЕХВАТЫВАЕТСЯ ТОЛЬКО ВЫВОД ПО ОПЕРАТОРУ
; PRINT И INPUT.
connct:	lxi h,writec	; адрес п/п драйвера
	SHLD А0388Н 	; ЗАНЕСТИ В ИНТЕРПРЕТАТОР
	LXI H,BEGIN0	; АДРЕС П/П ВОССТАНОВЛЕНИЯ
	SHLD А0004Н 	; ВМЕСТО ПЕРЕХОДА НА НАЧАЛО
	RET 		; РАБОТЫ ИНТЕРПРЕТАТОРА
;++++++++++++++++++++++++++++++++++++++++++++++++
;+ UNCNCT - ВОССТАНОВЛЕНИЕ ИНТЕРПРЕТАТОРА       +
;++++++++++++++++++++++++++++++++++++++++++++++++
uncnct:	lxi h,АF809H	; адрес п/п вмвода символа
	SHLD Ав388Н 	; ВОССТАНОВИТЬ В ИНТЕРПРЕТ. 
	LXI Н,А1600Н	; АДРЕС НАЧАЛА РАБОТЫ ИНТЕРП 
	SHLD А0004Н 	; ВОССТАНОВИТЬ В ИНТЕРПРЕТ. 
	RET

Рассмотрим подробнее, как они работают и как можно организовать совместное выполнение программ на БЕЙСИКе с программами в кодах.

Для выполнения нескольких подпрограмм, написанных на АССЕМБЛЕРе, передачи им параметров и для получения результатов их работы на практике обычно применяют следующий прием: в части ОЗУ, не занятой интерпретатором и не используемой программой на БЕЙСИКе, выделяется специальная область, называемая областью связи. Положение этой области в ОЗУ и ее структура определяются при разработке ассемблерных и БЕЙСИК — программ. Область связи может включать точки перехода на различные подпрограммы, например, так, как это сделано в МОНИТОРе. Несколько байтов в области связи может быть выделено для передачи параметров подпрограмм, а при необходимости и для возврата результатов. В программах на БЕЙСИКе до перехода на подпрограмму при помощи оператора РОКЕ записывают значения передаваемых параметров в заданные ячейки области связи. Переход на подпрограмму осуществляется при выполнении функции USR. Результат работы подпрограмм либо возвращается функцией USR, либо его можно прочитать функцией РЕЕК, из заданных ячеек области связи. Благодаря тому, что интерпретатор «МИКРОН» обрабатывает шестнадцатиричные числа, все операции по передаче параметров и переходу на подпрограммы осуществляются достаточно просто.

Чтобы уменьшить зависимость программы на БЕЙСИКе от расположения области связи и подпрограмм в ОЗУ, абсолютное значение адреса можно задавать только для начала области связи, а все остальные адреса различных полей области связи смещением от ее начала (см. комментарии к области связи и пример программы на БЕЙСИКе в табл.4).

Часто для решения поставленной задачи может оказаться недостаточно написания части программы в кодах или на АССЕМБЛЕРе, а требуется расширение возможностей или изменение алгоритма работы самого интерпретатора. В этих случаях прибегают к временной модификации кодов интерпретатора таким образом, что выполняемая программа заменяет одни команды интерпретатора на другие, а по окончании работы вновь восстанавливает их. Такой прием применяется, например, в программе RAMDOS (см. [1]), такой же прием использован и для подключения оконного драйвера.

Следует отметить, что модификация кодов интерпретатора является вынужденной мерой, и такое решение имеет много недостатков: подпрограммы, использующие этот прием, могут работать только с данным интерпретатором БЕЙСИКа и перестают работать при смене его версии. Даже с этой же версией интерпретатора, но помещенной в ПЗУ, применить такой прием невозможно.

При отсутствии накопителя на гибком магнитном диске программисты любую часто используемую программу стремятся поместить в ПЗУ, чтобы иметь ее постоянно доступной. А интерпретатор БЕЙСИКа, работающий в ПЗУ,— это вдвойне удобно. Если, например, в ПЭВМ «Партнер 01.01», сходной по архитектуре и программному обеспечению с РК-86, интерпретатор БЕЙСИКа поместить в ПЗУ, то можно освободить 8 кБ в младших адресах ОЗУ и, следовательно, увеличить допустимый объем программ на БЕЙСИКе. Однако в этом случае подключить оконный драйвер описанным выше способом уже невозможно, но благодаря тому, что в МОНИТОРе «Партнера 01.01» предусмотрены так называемые «крюки» для перехвата обращений к МОНИТОРу, подключить оконный драйвер удается уже без модификации интерпретатора. Такой прием не зависит от версии интерпретатора и методологически более правилен.

Тексты подпрограмм оконного драйвера и подпрограмм для его сопряжения с программами на БЕЙСИКе даны на языке АССЕМБЛЕРа и, очевидно, будут больше полезны подготовленным читателям. Для тех, кого интересуют возможности создания окон только в программах на БЕЙСИКе, в табл.2 приведены коды области связи и всех подпрограмм оконного драйвера, оттранслированные с адреса 6800Н. Область связи занимает первые 13 байт.

Команда перехода на подпрограмму инициализации оконного драйвера дана со смещением (+0): в этой подпрограмме производится восстановление кодов интерпретатора, поэтому с ее выполнения рекомендуется начинать и заканчивать работу с оконным драйвером. Со смещением (+3) дана команда перехода на подпрограмму открытия очередного окна. Предварительно в ячейки области связи со смещением (+9) и (+10) необходимо записать координаты левого верхнего угла окна. Начало координат находится в левом нижнем углу, поэтому координаты задаются так же, как и в операторе БЕЙСИКа CUR. В ячейки со смещением (+11) и (+12) записываются размеры открываемого окна. Во время открытия первого окна коды интерпретатора модифицируются так, чтобы обеспечивались работа оконного драйвера и полное восстановление интерпретатора после его рестарта по команде МОНИТОРа GO.

Команда перехода на подпрограмму стирания активного окна дана со смещением (+6). Параметров у этой подпрограммы нет. При стирании последнего активного окна восстанавливаются коды интерпретатора. Подпрограммы открытия и стирания окна возвращают номера активного окна.

Коды подпрограмм расположены с адреса 681ЗН по 684FH. С адреса 6850Н начинается рабочая область оконного драйвера. Для перемещения кодов подпрограмм и области связи в табл.3 приведена соответствующая таблица коррекции BITMAP. Контрольные суммы и кодов программ и таблицы BITMAP нулевые.

6800: C3 13 68 C3 28 68 C3 42 68 00 00 00 00 CD 63 68
4810: C3 88 14 E5 D5 C5 CD 81 68 CD 63 68 Cl Dl El C9
6820: E5 D5 C5 3A 58 6A B7 CC 56 68 2A 0B 68 EB 2A 89
6830: 68 3E 18 94 67 CD 8E 68 CD 44 69 Cl Dl El 3A 58
6848: 6A C9 E5 05 C5 CD E0 68 3A 58 6A 87 CC 63 68 Cl
6850: D1 El 3A 58 6A C9 21 A8 69 22 88 83 21 8D 68 22
6860: 04 88 C9 21 09 FB 22 B8 83 21 00 16 22 04 00 C9
6870: C3 89 FB C3 1B F8 C3 83 FB C3 21 F8 C3 1E FB 60
6880: 6A E5 AF 32 58 6A 2A 7F 68 22 59 6A El C9 D5 E5
6890: E5 CD 1C 6A 22 56 6A 2A 59 6A E3 CD 26 6A 24 E3
68A8: 43 CD 79 68 77 23 8E 18 CD 78 68 05 C2 Al 68 15
68B0: C2 9A 68 33 33 EB 2A 54 6A CD D9 68 2A 52 6A CD
68C8: D9 68 2A 56 6A CD D9 68 2A 59 6A CD D9 68 EB 22
68D0: 59 6A 21 58 6A 34 El Dl C9 EB 73 23 72 23 EB C9
68E8: E5 D3 C5 3A 58 6A 3D FA 39 69 32 58 6A 2A 59 6A
68F0: EB CD 3D 69 22 59 6A CD 3D 69 22 56 6A CD 3D 69
6900: E5 CD 3D 69 E5 2A 52 6A EB 14 14 2A 54 6A 25 2D
6918: E5 2A 59 6A E3 CD 26 6A 24 E3 43 4E CD 78 68 23
6920: 05 C2 1B 69 15 C2 14 69 33 33 Dl El 22 52 6A EB
6930: 22 54 6A 2A 56 6A CD 26 6A Cl Dl El C9 EB 2B S6
6948: 2B 5E EB C9 E5 D5 CD 26 6A 13 15 43 21 81 69 CD
6958: 6B 69 42 CD 6B 69 43 CD 6B 69 42 CD 6B 69 CD 1C
6960: 6A 22 54 6A EB 22 52 6A Dl El C9 05 CA 78 69 E5
6970: CD 73 68 El 85 C2 6F 69 CD 73 68 23 CD 73 68 23
6980: C9 17 88 1A 88 88 17 1A 08 88 00 17 08 08 88 19
6998: 18 88 17 19 88 08 18 1A 88 7E B7 CA A6 69 4F CD
69A0: AB 69 23 C3 99 69 23 C9 3A 58 6A B7 CA D5 69 79
69B0: B7 FA D5 69 FE 8D C2 BF 69 CD 09 69 C3 D8 69 FE
69C0: 8C C2 CA 69 CD EE 69 C3 D8 69 FE 1F C2 D5 69 CD
69D0: F7 69 C3 DB 69 CD 70 68 C9 C5 0E 0D CD 78 68 3A
69E8: 54 6A 47 8E 1B CD 78 68 05 C2 E5 69 Cl C9 E5 2A
69F8: 54 6A CD 26 6A El C9 E5 D5 C5 2A 52 6A EB 2A 54
6A00: 6A CO 26 6A 43 85 85 8E 28 CD 78 68 85 C2 87 6A
6A10: 24 15 C2 01 6A CD EE 69 Cl Dl El C9 CD 7C 68 D5
6A20: 11 F8 FC 19 Dl C9 E5 05 C5 11 20 20 19 EB 21 5F
6A30: 6A 36 88 2B 73 2B 72 2B 36 59 2B 36 1B CD 73 68
6A40: Cl D1 El C9 28 73 29 7B 74 65 66 61 6E 88 1A 18
0300: 24 81 00 90 04 48 81 20 81 22 88 82 00 00 00 00
0310: 84 90 12 44 18 22 28 92 49 24 48 00 04 49 12 49
0320: 11 04 11 02 11 82 24 88 88 82 44 44 91 02 21 22
0330: 00 00 00 84 44 22 18 92 12 42 49 02 41 18 40 00
0340: 90 11 89 82 00 00 00 81 00 00 00 00 00 00 Cl 8D


С помощью программы «DATA — ТРАНСЛЯТОР» вы можете получить коды подпрограмм в виде набора данных DATA и включать их непосредственно в текст программ на БЕЙСИКе.

В табл.4 приведена программа на языке БЕЙСИК, которая с интервалом в 2С строит на экране пять одинаковых окон, а затем с интервалом в 1С стирает их. Чтобы лучше усвоить работу оконного драйвера, попробуйте выполнить эту программу несколько раз: прервав ее нажатием на клавишу F4 и выполнением оператора LIST, перезапуском интерпретатора после сброса компьютера и т. д.

				Таблица 4
10 REM ПРИМЕР ИСПОЛЬЗОВАНИЯ ОКОННОГО ДРАЙВЕРА
20 REM В ПРОГРАММАХ НА BASIC "МИКРОН"
30 В=4А800 : REM АДРЕС ОБЛАСТИ СВЯЗИ
40 A=USR(B): REM ИНИЦИАЛИЗАЦИЯ ДРАЙВЕРА
50 WX=5 :WY=22: REM КООРДИНАТЫ ОКНА
69 LX=20:LY=6 : REM РАЗМЕРЫ ОКНА
70 FOR I=1 ТО 5
80 РОКЕ В+9,WХ+(I-1)*2: РОКЕ В+10,WY-(I-1)*2
90 POKE B+11,LX: POKE B+12,LY
100 NW=USR(B+3): REM ОТКРЫВАЕМ ОКНО NW
110 PRINT CHR$(&,1F) ;"ВЫВОД В ОКНО"
120 PRINT "НОМЕР ";NW
130 PAUSE 2 
140 NEXT I 
150 FOR I=1 ТО 5 
160 NW=USR(B+6): REM ЗАКРЫВАЕМ ОКНА
170 PAUSE 1
180 NEXT I
190 REM ВОССТАНАВЛИВАЕМ КОДЫ ИНТЕРПРЕТАТОРА
200 A=USR(B)
210 STOP 


Очень часто окна используют в диалоговых программах для организации ветвящихся многоуровневых меню. На каждом уровне, как правило, предлагается выбрать один из нескольких возможных пунктов меню. На БЕЙСИКЕ организовывать подобные многоуровневые меню несложно. Для включения их в программы на АССЕМБЛЕРе в табл.5 предлагается текст двух вспомогательных модулей СНТАВ и UPDOWN и пример их использования совместно с оконным драйвером в реальной диалоговой, программе.

Модуль СНТАВ осуществляется поиск по таблице вида символ/адрес, располагаемой сразу же за командой обращения к модулю. При совпадении аккумулятора с символом из таблицы осуществляется переход по соответствующему адресу. Один из символов может быть зарезервирован под признак конца таблицы, если предполагается, что поиск может не увенчаться успехом.

Второй модуль — UPDOWN — позволяет осуществить выбор пункта меню, пользуясь только клавишами «Курсор вверх», «Курсор вниз» и «ВК». Предварительно курсор должен быть установлен в строку с первым пунктом меню. В регистр D загружается число пунктов меню, в регистр Е — начальный номер пункта меню. Этот пункт меню помечается указателем, который может перемещаться вверх и вниз, с помощью клавиш управления курсором. После нажатия на клавишу «ВК» в регистре А возвращается номер выбранного пункта.

Модуль ЕХАМР включает пример комплексного использования подпрограмм оконного драйвера и организации меню в интерактивной системе. (Вместо модулей обработки стоят «заглушки».) В первом окне меню содержит три пункта. Один из пунктов разворачивается во втором окне в меню из семи пунктов.

Г. ШТЕФАН, г. Москва

ЛИТЕРАТУРА
  1. Лукьянов Д. RAMDOS для «Радио-86РК».— Радио, 1989, № 9, 10.
  2. Дмитриев А., Игнатьев Ю. Программа «DATA — ТРАНСЛЯТОР».- Радио, 1989, № 7, с. 50-52.
  3. Барчуков В., Фадеев Е. Бейсик «МИКРОН».— Радио, 1988, № 8, с. 37—43.
  4. Штефан Г. О перемещении программ в машинных кодах.— Радио, 1989, № 3, с. 51—54.

Отсканировано с журнала Радио № 4 1990 г.
Отредактировано Лесных Ю. 2001 г.