	.TITLE	GD
	.MCALL	.DRDEF,.PRINT,.TTYOU,.EXIT

	.DRDEF	GD,377,RONLY$!WONLY$,0,176644

	.ASECT

	.=70			; Вторая половина помощи
70$:	.ASCII	<11>/[NO]SLOW: /<16>/RABOTAET T]ATELXNEE<17><15><12>
	.ASCII	<11>/SHIFT=N:/<16>/  SDWIG/<17>/ <->/<15><12>
	.ASCIZ	<11>/SYSGEN/
; П/п проверки при установке драйвера
	.=200
200$:	MOV	PC,R0		; Получить адрес строки названия драйвера
	ADD	#342$-.,R0
206$:	COMB	-(R0)		; Раскодировать
	BNE	206$
	INC	R0
	.PRINT			; Вывести на экран
	RETURN
; Команды для загрузки/выгрузки драйвера и его запуска
220$:	.WORD	23
222$:	.ASCIZ	/UNLOAD GD/
	.ASCIZ	/R GD.SYS/
	.BYTE	200
	.EVEN
; П/п переноса команд в область ОЗУ и их запуска
246$:	MOVB	(R0)+,(R3)+	; Перенести в ОЗУ (с адреса 512)
	BPL	246$
	BIS	#40,@#44	; Установить бит запуска ком.файла
	CLR	R0
	.EXIT			; Выход с запуском

	.=302	; Закодированная строка с названием драйвера
	.CRYPT	<11><11>/GD V04.00 [AI]/<11><11><16>/dRA^EW a.i./<17>
342$:

; Область описания SET-параметров
	.DRSET	ON,510,472$
	.DRSET	OFF,510,506$
	.DRSET	SYSGEN,177770,550$
	.DRSET	WIDE,36,570$,NO
	.DRSET	INFORM,<656$-626$+2>,626$
	.DRSET	SLOW,<BR 1062$-1036$+.>,644$,NO
	.DRSET	SHIFT,117,616$,NUM
; Обработка SET GD ON (загрузка и включение драйвера)
472$:	TST	@#24		; Драйвер загружен ?
	BMI	566$		; Да - выход
	CLR	222$		; Команда загрузки (с UNLOAD убрать UN)
	BR	534$		; Дальше на обработку
; Обработка SET GD OFF (выгрузка и выключение драйвера)
506$:	TST	@#24		; Драйвер выгружен ?
	BPL	566$		; Да - выход
	CLR	@#176646	; Установить в ловушке нулевой адрес
	MOV	#26,@#24	; Заглушка на вектор 24
	MOV	#2,@#26
534$:	MOV	PC,R0		; R0 - адрес командного файла
	ADD	#220$-.,R0
	MOV	(R0)+,(R3)+	; Кол-во передаваемых байт в ячейку 510
	JMP	246$		; Дальше на передачу и запуск
; Обработка SET GD SYSGEN (подстройка под параметры генерации монитора)
550$:	MOV	@#54,R0		; Адрес начала RMON
	MOVB	372(R0),60	; Передать параметры генерации монитора
	BICB	R3,60		; Убрать лишние биты
566$:	RETURN
; Обработка SET GD [NO]WIDE
570$:	CLR	R3		; Вход при WIDE. R3 = 0
	BR	602$
	CLR	1270$+2		; Вход при NOWIDE. Режим 80х24. R3 = 36
	BR	610$
602$:	MOV	#1,1270$+2	; Режим 40х24
610$:	MOV	R3,1116$	; Занести R3 в параметр сдвига
	RETURN
; Обработка SET GD SHIFT=num
616$:	MOV	R0,1116$	; Занести R0 в параметр сдвига
	NOP
	RETURN
; Обработка SET GD INFORM (помощь)
626$:	MOV	PC,R0
	ADD	R3,R0		; Адрес первой части помощи
	.PRINT			; Вывод на экран
	ADD	#<70$-656$>,R0	; Адрес второй части помощи
	.PRINT			; Вывод на экран
	RETURN
; Обработка SET GD [NO]SLOW
644$:	MOV	#<NOP>,R3	; Вход при SLOW, в R3 команда NOP
	MOV	R3,1036$	; Вход при NOSLOW, команда BR. Занести
	RETURN
; Первая половина помощи
656$:	.ASCII	/SET GD/<11>"ON / OFF: "<16>"WKL./WYKL. GRAF.REVIMA;"<17><15><12>
	.ASCII	<11>/[NO]WIDE: /<16>/[IROKIJ FORMAT/<17>
; Начало драйвера
	.DRBEG	GD,,,,1012$
; Таблица описания векторов
1012$:	.DRVTB	GD,300,1036$	; Вектор обработки ловушки
	.DRVTB	  , 24,1142$	; Вектор обработки аварии сетевого питания
	.DRVTB    ,304,1142$

GDINT::				; Точка входа обработки прерывания
; Обработчик прерывания от ловушки адреса (вектор 300)
1036$:	BR	1062$		; Переход, если NOSLOW
	MOV	#16,@#14	; Заглушка в вектор отладки с командой RTT
	MOV	#6,@#16
	BIS	#20,2(SP)	; Установить бит T в ССП при возврате
1062$:	JSR	R5,@$INPTR	; Вход в обработку прерывания с сохранением
	.WORD	340		; R4 и R5
	CLR	@#176644	; Запретить прерывание от ловушки адреса
	MOV	@#304,R5	; Прочесть адрес
	CLR	R4		; Разделить на 50. R4 - адрес строки,
	DIV	#50.,R4		; R5 - смещение в строке
	MOV	R5,-(SP)	; Сохранить смещение в стеке
	MUL	#80.,R4		; Умножить на 80 (в формат УКНЦ)
	ADD	(PC)+,R5	; Прибавить сдвиг
1116$:	.WORD	36
	ADD	(SP)+,R5	; Прибавить смещение
	BIS	#100000,R5	; Установить старший бит (видеопамять)
	MOV	R5,@#176640	; Поместить адрес в регистр адреса
	MOV	#701,@#176644	; Разрешить прерывание от ловушки (вектор 300)
	RETURN
; Обработчик прерывания по вектору 24
1142$:	MOV	#304,@#176646	; Адрес для ловушки
	MOV	#701,@#176644	; Разрешить прерывание от ловушки (вектор 300)
	RTI
	.DREND	GD
; Модуль для запуска в ОЗУ ПП
1164$:	MOV	PC,R0		; Получить адрес блока изменяемых ячеек
	ADD	#1270$-.,R0
	TST	@#314		; Вектор RESET ЦП переназначен ?
	BMI	1222$		; Нет
	MOV	1634$,@#314	; Восстановить вектор 314
1206$:	TST	(R0)+		; Цикл восстановления ячеек
	BEQ	1256$
	MOV	@R0,@-(R0)
	ADD	#4,R0
	BR	1206$
1222$:	MOV	@#314,1634$	; Запомнить вектор 314
	MOV	PC,-(SP)	; Получить адрес п/п обработки вектора 314
	ADD	#1522$-.,@SP
	MOV	(SP)+,@#314	; Занести в вектор 314 новый адрес
; Сохранить ячейки из блока и занести новые значения
1242$:	MOV	@(R0)+,-(SP)	; Сохранить старое значение ячейки в стеке
	MOV	@R0,@-(R0)	; Занести новое значение
	TST	(R0)+
	MOV	(SP)+,(R0)+	; Занести старое значение из стека в блок
	TST	@R0		; Конец блока ?
	BNE	1242$		; Нет - продолжим
1256$:	MOV	@#7156,R0	; R0 - формат экрана (80х24, 40х24, ...)
	CALL	@#116502	; Установить новый формат экрана
	RETURN
; Блок изменяемых ячеек
1270$:	.WORD	7156,0		; Формат экрана (80х24)
	.WORD	22752,0		; Рулон (отсутствует)
	.WORD	7170,2		; Рулон УСТ (отсутствует)
	.WORD	2406,2462	; Указатель на видеопамять (убрать служ.стр.)
	.WORD	4536,4540	; Указатель на видеопамять
	.WORD	177026,6	; Замаскировать планы 1 и 2
	.WORD	2400,147750	; Регистр управления цветом верхней служебной
	.WORD	2402,147750	; строки
	.WORD	22614,7		; Цвет символа
	.WORD	22616,7
	.WORD	22620,0		; Цвет знакоместа
	.WORD	22622,0
	.WORD	22624,0		; Цвет фона
	.WORD	22626,0
	.WORD	2470,147750	; Регистр управления цветом экрана
	.WORD	2472,147750	; пользователя
	.WORD	22712,7		; Цвет символа
	.WORD	22714,7
	.WORD	22716,0		; Цвет знакоместа
	.WORD	22720,0
	.WORD	22722,0		; Цвет фона
	.WORD	22724,0
	.WORD	4700,170360	; Регистр управления цветом экрана установки
	.WORD	4702,170360
	.WORD	23010,7		; Цвет символа
	.WORD	23012,7
	.WORD	23014,0		; Цвет знакоместа
	.WORD	23016,0
	.WORD	23020,0		; Цвет фона
	.WORD	23022,0
	.WORD	6750,147750	; Регистр управления цветом нижней служебной
	.WORD	6752,147750	; строки
	.WORD	23106,7		; Цвет символа
	.WORD	23110,7
	.WORD	23112,0		; Цвет знакоместа
	.WORD	23114,0
	.WORD	23116,0		; Цвет фона
	.WORD	23120,0
	.WORD	0
; П/п обработки прерывания по вектору 314 (RESET на магистрали ЦП)
1522$:	MOV	R0,-(SP)	; Сохранить регистры в стеке
	MOV	R1,-(SP)
	MOV	#24/2,@#177010	; Прочесть значение вектора 24 в ОЗУ ЦП
	MOV	@#177014,R0
	BPL	1626$		; Стоит заглушка - выход
	CLC			; Преобразовать адрес в формат для регистра
	ROR	R0		; адреса 177010
	MOV	PC,R1		; Получить адрес п/п обработки вектора 24
	ADD	#1640$-.,R1
	MOV	#7,(PC)+	; Размер п/п - 7 слов
1560$:	.BLKW	1		; Счетчик переданных слов
1562$:	MTPS	#200		; Запретить прерывания
	MOV	R0,@#177010	; Занести адрес в регистр адреса
	MOV	(R1)+,@#177014	; Передать очередное слово в ОЗУ ЦП
	MTPS	#0		; Разрешить прерывания
	INC	R0		; Перейти к следующему адресу
	DEC	1560$		; Уменьшить счетчик переданных слов
	BNE	1562$		; Еще есть данные для передачи
	BIC	#100000,@#177716; Инициировать на магистрали ЦП прерывание
	BIS	#100000,@#177716; по вектору 24
1626$:	MOV	(SP)+,R1	; Восстановить регистры
	MOV	(SP)+,R0
	JMP	@(PC)+		; Далее на обработку вектора 314 (в ПЗУ ПП)
1634$:	.BLKW	1
	.WORD	200
; П/п обработки прерывания 24 в ОЗУ ЦП
1640$:	MOV	#304,@#176646	; Адрес для ловушки
	MOV	#701,@#176644	; Установить вектор 300 для ловушки
	RTI
; Точка запуска по команде R GD.SYS
START:	TST	@#300		; Драйвер загружен ?
	BNE	1756$		; Да
	MOV	#26,@#24	; Заглушка на вектор 24
	MOV	#2,@#26
	CALL	2116$		; Прочесть значение вектора 314 ПП
	BMI	2112$		; Не переназначен(не загружен модуль в ОЗУ ПП)
	MOV	2130$,R0	; Получить адрес загрузки модуля
	ADD	#<1164$-1522$>,R0
	MOV	R0,2242$+4	; Положить адрес в блок запуска
	MOV	R0,2250$+4	; Положить адрес в блок выгрузки
	MOV	#2242$,R0	; Адрес БП запуска модуля в ОЗУ ПП
	CALL	2134$		; Запустить модуль в ОЗУ ПП
1736$:	CALL	2116$		; Прочесть значение вектора 314 ПП
	BPL	1736$		; Модуль еще не освободил вектор - ждем
	MOV	#2250$,R0	; Адрес БП выгрузки модуля
	CALL	2134$		; Выгрузить модуль
	BR	2112$		; На выход
1756$:	TST	1036$		; Первое слово драйвера равно нулю (?)
	BEQ	2000$		; Да
	MOV	#16,@#14	; Поставить заглушку на вектор отладки
	MOV	#6,@#16
2000$:	.PRINT	#2273$		; Запрограммировать клавиши-ключи
	CLR	R1		; Пауза
	SOB	R1,.
	.PRINT	#2260$		; Очистить экран
	SOB	R1,.		; Пауза
	CALL	2116$		; Прочесть значение вектора 314 ПП
	BPL	2112$		; Модуль уже загружен - на выход
	MOV	#2220$,R0	; Адрес БП для запроса памяти
	CALL	2134$		; Запросить память в ОЗУ ПП
	MOV	2220$+4,2230$+4	; Занести адрес ОЗУ ПП в БП записи
	MOV	2220$+4,2242$+4	; Занести адрес ОЗУ ПП в БП запуска
	MOV	#2230$,R0	; Адрес БП записи модуля в ОЗУ ПП
	CALL	2134$		; Записать модуль в ОЗУ ПП
	MOV	#2242$,R0	; Адрес БП запуска модуля в ОЗУ ПП
	CALL	2134$		; Запустить модуль в ОЗУ ПП
2074$:	CALL	2116$           ; Прочесть значение вектора 314 ПП
	BMI	2074$		; Модуль не инициализировался - ждем
	.TTYOU	#14		; Очистить экран
2112$:	CLR	R0
	.EXIT			; Выход  в RT-11
; П/п чтения значения вектора 314 (сигнал RESET на магистрали ЦП) из ОЗУ ПП
2116$:	MOV	#2206$,R0	; Блок параметров для чтения
	CALL	2134$		; Передать БП через канал 2
	TST	(PC)+		; Установить флаги по прочитанному
2130$:	.BLKW	1
	RETURN
; П/п передачи блока параметров через канал 2
2134$:	CALL	2164$		; Передать мл.байт по каналу 2
	SWAB	R0		; Обменять байты в адресе
	CALL	2164$		; Передать ст.байт по каналу 2
	MOVB	#177777,R0	; Байты завершения
	CALL	2164$		; Передать первый байт завершения
	CALL	2164$		; Передать второй байт завершения
	RETURN
; П/п передачи байта по каналу 2
2164$:	TSTB	@#176674	; Канал 2 готов к приему байта
	BGE	2164$		; Нет - ждем
	MOVB	R0,@#176676	; Передать байт по каналу 2
2176$:	TSTB	@#176674	; Канал 2 готов к приему байта
	BGE	2176$		; Нет - ждем
	RETURN
; Блок параметров для чтения вектора 314 в ОЗУ ПП
2206$:	.BYTE	0,10
	.WORD	32,314,2130$,1
; Блок параметров для запроса памяти в ОЗУ ПП
2220$:	.BYTE	0,1
	.WORD	32,0,<START-1164$>/2
; Блок параметров для записи модуля в ОЗУ ПП
2230$:	.BYTE	0,20
	.WORD	32,0,1164$,<START-1164$>/2
; Блок параметров для запуска модуля в ОЗУ ПП
2242$:	.BYTE	0,30
	.WORD	32,0
; Блок параметров для выгрузки модуля в ОЗУ ПП
2250$:	.BYTE	0,2
	.WORD	32,0,<START-1164$>/2
; Esc-последовательность для очистки экрана
2260$:	.ASCII	<33>/%!1/<33>/[0;0r/<200>
; Esc-последовательность для программирования клавиш
2273$:	.ASCII	<33>"P;1|1/1B50;2/1B51;3/1B52;4/1B53;" ; ПФ1-ПФ4
	.ASCII	"5/1B66;6/1B67;7/1B68;"	; ВЫБР, ПРЕД КАДР, СЛЕД КАДР
	.ASCII	"8/1B63;9/1B64;10/1B65;"; НТ, ВСТ, УДАЛ
	.ASCII	"16/1B3F6C;17/1B3F6D;"	; <,> доп., <-> доп.
	.ASCII	"18/1B3F6E;19/1B3F4D;"	; <.> доп., <ВВОД> доп.
	.ASCII	"20/1B3F70;"<33>"/"<200>; <0> доп.
	.END	START
