Несколько слов о прямой работе с терминалом
Решил немного поворчать на тему программ, работающих с терминалом напрямую через регистры (надо же чем-то заняться пока пиво пьется). Неработающие подобные проги доставали еще в начале 80ых, а сейчас и подавно. Речь идет о том, что многие программеры считали, что достаточно сделать в программе
как наступает чудо: программа может работать с терминалом на уровне регистров, а система при этом под ногами не путается. К сожалению это далеко не всегда верно. А посему немного расскажу о том как писать программы, чтобы они работали вообще в любом случае - вдруг современные программеры RT-11 (гы) будут писать правильно ;)
Для начала перечислю случаи когда вышеописанная методика не работает (экзотические случаи вроде DEC Pro не рассматриваем):
- Первый случай очевиден: когда консольный регистр не 177560. Случай не частый, но тем не менее ничего невозможного в нем нет.
- Система многотерминальная. Тут целых две проблемы: во-первых консольный терминал может быть любым из сконфигуренных в системе; во-вторых при поддержке таймаута терминалов система постоянно приводит терминалы в порядок (в том числе заботится, чтобы прерывания от клавиатуры были разрешены)
Небольшой кусок кода в программе легко справляется со всем этим и делает программу рабочей в любой системе (здесь не рассматриваются хитрости которые зависят от конкретной версии или сборки монитора - только универсальный способ).
Для начала определения используемых смещений и битов.
Код:
$JSX = 4 ;РАСШИРЕНОЕ СЛОВО СОСТОЯНИЯ ЗАДАНИЯ
NOVBG$ = 100 ;БИТ ЗАПРЕТА VBGEXE
$SYPTR = 54 ;УКАЗАТЕЛЬ НА ДАНЫЕ RMON
$SYSGE = 372 ;ПАРАМЕТРЫ ГЕНЕРАЦИИ СИСТЕМЫ (RMON)
MTTY$ = 20000 ;БИТ ПОДДЕРЖКИ МНОГОТЕРМИНАЛЬНОСТИ
TSXP$ = 100000 ;БИТ TSX-PLUS
$TTKS = 304 ;АДРЕС CSR КЛАВИАТУРЫ
$CNTXT = 320 ;АДРЕС БЛОКА ОПИСАНИЯ ТЕКУЩЕГО ЗАДАНИЯ
I.CNSL = 16 ;УКАЗАТЕЛЬ НА TCB ТЕРМИНАЛА ЗАДАНИЯ
T.STAT = 14 ;СЛОВО СОСТОЯНИЯ ТЕРМИНАЛА
T.CSR = 16 ;CSR ТЕРМИНАЛА
DH11$ = 20000 ;ТЕРМИНАЛ НА DH-11 МУЛЬТИПЛЕКСОРЕ
DZ11$ = 10000 ;ТЕРМИНАЛ НА DZ-11 МУЛЬТИПЛЕКСОРЕ
Не касается терминалов напрямую, но... Совсем не помешает в начале программы следующий кусок (который к тому же места не занимает):
Код:
.ASECT
.=$JSX
.WORD NOVBG$
.PSECT
Этим мы добиваемся того, что в RT-11 V5.x программа не будет запускаться через VBGEXE. Потому как если запускать ее через VBGEXE, программа просто не увидит страницу ввода/вывода (на самом деле можно установить другой битик чтобы программа видела страницу ввода-вывода из под VBGEXE, но лучше таким баловством не заниматься).
Код:
START: MOV @#$SYPTR,R0 ;ПОЛУЧАЕМ АДРЕС СЕКЦИИ ДАННЫХ RMON
TST $SYSGE(R0) ;ЭТО TSX-PLUS (ПОМНИМ: TSXP$ = 100000)?
BMI TSX ;MI -> ДА. ВСЕ СОБСТВЕННО...
BIT #MTTY$,$SYSGE(R0) ;МНОГОТЕРМИНАЛЬНАЯ СИСТЕМА?
BEQ 10$ ;EQ -> НЕТ
;ЕСЛИ СИСТЕМА МНОГОТЕРМИНАЛЬНАЯ, СМЕЩЕНИЯ $TTKS, $TTKB, $TTPS И $TTPB
;НЕ ИСПОЛЬЗУЮТСЯ В ПРИНЦИПЕ, ДА И САМ ТЕРМИНАЛ МОЖЕТ БЫТЬ ВЫБРАН ЛЮБОЙ.
;НАША ЗАДАЧА - ПРОВЕРИТЬ, ЧТО ТЕКУЩИЙ ТЕРМИНАЛ - DL11 (ИНАЧЕ МЕТОД
;РАБОТЫ С РЕГИСТРАМИ СОВЕРШЕННО ДРУГОЙ), УЗНАТЬ CSR АДРЕС ТЕРМИНАЛА
;И СКАЗАТЬ СИСТЕМЕ, ЧТОБЫ НЕ МЕШАЛАСЬ.
MOV $CNTXT(R0),R0 ;ПОЛУЧАЕМ АДРЕС БЛОКА ОПИСАНИЯ ЗАДАНИЯ
MOV I.CNSL(R0),R0 ;ПОЛУЧАЕМ АДРЕС TCB ТЕРМИНАЛА
BIT #DH11$!DZ11$,T.STAT(R0) ;ПРОВЕРЯЕМ НЕ МУЛЬТИПЛЕКСОР ЛИ ЭТО
BNE MUX ;NE -> ДА, ПРИПЛЫЛИ.
;СЧАСТЬЕ ЕСТЬ И У НАС ОБЫЧНЫЙ DL11. В ПОЛЕ T.CSR БЛОКА УПРАВЛЕНИЯ ТЕРМИНАЛОМ
;(TCB) ХРАНИТСЯ АДРЕС CSR КЛАВИАТУРЫ.
ADD #T.CSR,R0 ;ПОЛУЧАЕМ УКАЗАТЕЛЬ НА CSR
MOV @R0,R5 ;СОХРАНЯЕМ ЕГО В R5
MOV #FAKE,@R0 ;ПОДСТАВЛЯЕМ ЛЕВЫЙ АДРЕС ВМЕСТО НЕГО
;И ПУСТЬ СИСТЕМА ПОДАВИТСЯ ;)
BR 20$ ;ДАЛЬШЕ ОБЩИЙ КОД
;У НАС ОДНОТЕРМИНАЛЬНАЯ СИСТЕМА. ТУТ ВСЕ ПРОСТО: АДРЕС РЕГИСТРА КЛАВИАТУРЫ
;ХРАНИТСЯ ПО СМЕЩЕНИЮ $TTKS В RMON.
10$: MOV $TTKS(R0),R5 ;СОХРАНЯЕМ CSR В R5
;СОБСТВЕННО ВСЕ. С ЭТОГО МЕСТА ИМЕЕМ ОБЩИЙ КОД, CSR В R5, ВСЕ ОБРАЩЕНИЯ
;К ТЕРМИНАЛУ ЧЕРЕЗ НЕГО И ДЕЛАЕМ.
20$: CLR @R5 ;ЗАПРЕЩАЕМ ПРЕРЫВАНИЯ ОТ КЛАВИАТУРЫ
...
;ПО ВЫХОДУ ИЗ ПРОГРАММЫ НЕ ЗЫБЫВАЕМ РАЗРЕШИТЬ ПРЕРЫВАНИ ОТ КЛАВИАТУРЫ
;И ВОССТАНОВИТЬ АДРЕС CSR ЕСЛИ СИСТЕМА МНОГОТЕРМИНАЛЬНАЯ.
FAKE:: .BLKW 4 ;ФАЛЬШИВЫЙ НАБОР CSR ЧТОБ МОНИТОР
;ИМИ ПОДАВИЛСЯ
Вот собственно и все. Мы получили прогу которая работает при нестандартном CSR, а также работает с правильным терминалом независимо от SET TT CONSOL=n, и система-вредитель нам не мешает!
Можно было бы конечно разобрать случай использования напрямую регистров в TSX, но это отдельная тема и без особого смысла: в TSX любой функционал ради которого в RT-11 используют регистры можно включить и без этого, не говоря уже о последствиях прямого тыкания в железо в многопользовательской системе ;)