А надо бы проверить, какой там make
Вид для печати
А надо бы проверить, какой там make
Неужели nmake настолько криво совместим?
С небольшой правкой (stricmp -> strcasecmp) собирается и не под visual studio :-)
Почитал эту тему, столько всего полезного
шпоргалки\вопросы\ответы
а самое главное программы и исправления
(патчи). Поднимаю тему ! ) Очень информативная
и интересная! )
До кучи - может кому пригодится. Пример как делать поиск файлов в каталоге диска, используя только те средтва которые уже есть в системе. Используются функции IGTDIR и IGTENTиз системной библиотеки. Их описание можно найти на bitsavers или у меня в документации по системной библиотеке RT-11. Никаких наворотов-красивостей - только пример, рабочий :)
Вызов функции IGTDIR из системмной библиотеки. Аналогичен форановскму IERR = IGTDIR(64,AREA,0,SEG,,DBLK,FILSPC). Если IERR (R0) не равен нулю - была ошибка.Код:MOV #ARGS1,R5
CALL IGTDIR
TST R0
BNE 20$
Аналогично фортрановскому IERR = IGTENT(AREA,ENTRY,,BLOCK). Если результат меньше 0, больше искать нечего. В противном случае в 7-словыный массив ENTRY получаем запись каталога о файле в стандартном RT-11 формате.Код:10$: MOV #ARGS2,R5
CALL IGTENT
TST R0
BLT 30$
Копируем данные в блок аргументов $EDMSG, печатаем, идем дальше...Код:MOV #ENTRY+2,R0
MOV #FMTARG,R1
CLR (R1)+
MOV (R0)+,(R1)+
MOV (R0)+,(R1)+
MOV (R0)+,(R1)+
CLR (R1)+
MOV (R0)+,(R1)+
MOV #BUFF,R0
MOV #FORMAT,R1
MOV #FMTARG,R2
CALL $EDMSG
CLRB @R0
.PRINT #BUFF
BR 10$
Обработка ошибок, выход.Код:20$: .PRINT #ERROR
30$: CLR R0
.EXIT
Собственно все. FILSPC содержит список файлов которые нужно искать, со всякими *, % (ну и как обычно, опущенное поле считается за *), не более 8 спецификаций через запятую. Другие подробности в RT-11 System Subroutine Library Manual. Программа для простоты использует RSXLIB, описание его здесь.Код:ARGS1: .WORD 7,SIZE,AREA,CHAN,SEG,-1,DBLK,FILSPC
SIZE: .WORD 64.
AREA: .BLKW 64.
CHAN: .WORD 0
SEG: .BLKW 512.
DBLK: .RAD50 /SY /
ARGS2: .WORD 5,AREA,ENTRY,-1,BLOCK
ENTRY: .BLKW 7
BLOCK: .BLKW
FMTARG: .BLKW 6
FORMAT: .ASCIZ /%11<%X%11>%M./
ERROR: .ASCIZ /IGTDIR FAILED/
FILSPC: .ASCIZ /.TXT,%%.SYS,UCL.*/
BUFF: .BLKB 40.
.END START
Код:.RU GTDIR
DD.SYS 5.
DU.SYS 11.
EQ.SYS 10.
LD.SYS 11.
LP.SYS 2.
LS.SYS 5.
MU.SYS 14.
NL.SYS 2.
SD.SYS 24.
SL.SYS 17.
SP.SYS 7.
VM.SYS 3.
XL.SYS 4.
UCL.SAV 16.
UCL.DAT 9.
CUSTOM.TXT 14.
V5NOTE.TXT 36.
.
Решил рассмотреть некоторые моменты для ясности. В качестве первого примера - разборки с командами SET которые прерывают обработку команды (например выполняют .CHAIN или .EXIT). На форуме уже есть несколько таких драйверов.
К примеру, драйвер поддерживает несколько команд SET (скажем [NO]OPT и VALUE) которые просто меняют какие-либо параметры драйвера и ON которая завершается по .EXIT (например для запуска системных команд). В этом случае, понятно, что команда вроде "SET XX ON,OPT" не дойдет до конца и звершится на разборе ON. Чтобы не вводить в заблуждение пользователя, будет полезно если драйвер предупредит об этом...
Данный пример при выполнении команды SET XX ON,NOOPT,VALUE=1 будет выводить предупреждениеКод:.DRSET ON,1,O.ON
;+
;ЗДЕСЬ R5 УКАЗЫВАЕТ НА СИМВОЛ КОМАНДНОЙ СТРОКИ, СЛЕДУЮЩИЙ ЗА ТЕКУЩЕЙ ОПЦИЕЙ.
;НАПРИМЕР ЕСЛИ ДЛЯ "SET XX ON,OPT" R5 УКАЗЫВАЕТ НА СИМВОЛ ",".
;СТРОКА ЗАПИСАНА В ОБРАТНОМ ПОРЯДКЕ.
;+
O.ON: TSTB -(R5) ;ПРОВЕРЯЕМ СЛЕДУЮЩИЙ СИМВОЛ
BEQ O.EXEC ;НУЛЕВОЙ БАЙТ - КОНЕЦ СТРОКИ
JSR R0,10$ ;ПЕЧАТАЕМ СООБЩЕНИЕ
.ASCII /?XX-W-ON must be last option in set command/<15><12>
.ASCIZ /?XX-W-Options ignored - /
.EVEN
;+
;В СТЕКЕ ЛЕЖИТ СОХРАНЕННОЕ СОДЕРЖИМОЕ R0. ДЛЯ ПРИЛИЧИЯ ЕГО МОЖНО
;ДОСТАТЬ, НО МОЖНО И ЗАБИТЬ - ВЕДЬ МЫ БУДЕМ ДЕЛАТЬ .EXIT
;
;ВО ВРЕМЯ ВЫПОЛНЕНИЯ КОМАНЛЫ SET В ПАМЯТЬ СЧИТЫВАЮТСЯ ДВА ПЕРВЫХ
;БЛОКА ДРАЙВЕРА. ПРИ УСПЕШНОМ ЗАВЕРШЕНИИ, МОНИТОР ЗАПИСЫВАЕТ ЭТИ ДВА
;БЛОКА ОБРАТНО В ФАЙЛ ДРАЙВЕРА. В НАШЕМ СЛУЧАЕ МЫ ЗАВЕРШАЕМ ОБРАБОТКУ
;МАКРОВЫЗОВОМ .EXIT, СООТВЕТСТВЕННО ДРАЙВЕР НЕ БУДЕТ ЗАПИСАН ОБРАТНО
;НА ДИСК И НИКТО НАМ НЕ МЕШАЕТ ИСПОЛЬЗОВАТЬ ОБЛАСТЬ ВТОРОГО БЛОКА
;В КАЧЕСТВЕ БУФЕРА.
;-
10$: .ADDR #1000,R1 ;ПОЛУЧАЕМ АДРЕС БУФЕРА
MOV R1,R3 ;СОХРАНЯЕМ ЕГО - ПРИГОДИТСЯ
20$: MOVB (R0)+,(R1)+ ;КОПИРУЕМ СООБЩЕНИЕ
BNE 20$ ;
DEC R1 ;УБИРАЕМ НУЛЕВОЙ БАЙТ
30$: MOVB -(R5),(R1)+ ;КОПИРУЕМ ОСТАТОК КОМАНДЫ SET
BNE 30$ ;
.PRINT R3 ;ПЕЧАТАЕМ СООБЩЕНИЕ
O.EXEC: ;ДЕЛАЕМ ЧТО НУЖНО
.EXIT ;ВЫХОД
Код:?XX-W-ON must be last option in set command
?XX-I-Options ignored - NOOPT,VALUE=1
---------- Post added at 22:05 ---------- Previous post was at 20:42 ----------
При написании драйвера следует помнить, что типы процессоров не ограничиваются одними ВМ1 и ВМ2. Особенно это актуально для ДВК.
Данный драйвер перехватывает прерывание 10, отлавливает команды с кодом 77 и печатает хашик.
Здесь сразу три ошибки. Для XM/ZM мониторов драйвер получит неизвестно что вместо кода команды для виртуальной программы (бит 10 в JSW установлен) или для программы, запущенной через VBGEXE. Код должен быть поправлен:Код:.DRDEF XX,333,0,0,0,0
.DRPTR FETCH=*NO*,LOAD=XXLOA,UNLOAD=XXUNL
.DRBEG XX
XXINT:: MOV @SP,-(SP) ;ПОЛУЧАЕМ ПРЕДПОЛОЖИТЕЛЬНЫЙ АДРЕС
SUB #2,@SP ;КОМАНДЫ
CMP #77,@(SP)+ ;ЕСЛИ КОД КОМАНДЫ НЕ 77
BNE 10$ ;ОТДАЕМ ПРЕРЫВАНИЕ
TSTB @#177564 ;ПЕЧАТАЕМ СИМВОЛ #
BPL .-4 ;
MOVB #'#,@#177566 ;
10$: SEC ;ВОССТАНАВЛИВАЕМ БИТ C
JMP @(PC)+ ;ОТДАЕМ В СИСТЕМУ
XXISR:: .BLKW
.DREND XX
.PSECT SETOVR
XXLOA:: MOV @R5,R5 ;ПОЛУЧАЕМ АДРЕС XXLQE
MOV @#10,XXISR-XXLQE(R5) ;СОХРАНЯЕМ СИСТЕМНЫЙ ОБРАБОТЧИК
ADD #XXINT-XXLQE,R5 ;УСТАНАВЛИВАЕМ НАШ
MOV R5,@#10 ;
RETURN ;ВОЗВРАТ
XXUNL:: MOV @R5,R5 ;ПОЛУЧАЕМ АДРЕС XXLQE
MOV XXISR-XXLQE(R5),@#10 ;ВОССТАНАВЛИВАЕМ ОБРАБОТЧИК
RETURN ;ВОЗВРАТ
.END
Вторая ошибка - тупое восстановление вектора при выгрузке драйвера. Если после нашего драйвера кто-то еще перехватил вектр 10, выгрузка может дать непредсказуемый эффект. Поэтому стоит проверить сначала можно ли делать выгрузку:Код:XXINT:: MOV @SP,-(SP)
SUB #2,@SP
.IF EQ MMG$T
CMP #77,@(SP)+
.IFF
MFPI @(SP)+
CMP #77,(SP)+
.ENDC
Третья ошибка относится к маловероятному (но вполне возможному) случаю когда между сохранением старого значения вектора и установкой нового кто-то успеет перехватить вектор. В FB/XM/ZM мониторах сиуация вполне возможная. Так что такие вещи стоит выполнять на приоритете 7 процессора.Код:XXUNL:: CLR R0 ;ПРИ ОШИБКЕ В R0 МОЖНО
;ПОМЕСТИТЬ АДРЕС СООБЩЕНИЯ
;0-НЕТ СПЕЦИАЛЬНОГО СООБЩЕНИЯ
MOV @R5,R5 ;ПОЛУЧАЕМ АДРЕС XXLQE
MOV R5,R4 ;ПОЛУЧАЕМ АДРЕС XXINT
ADD #XXINT-XXLQE,R4 ;
CMP R4,@#10 ;ПРОВЕРЯЕМ ISR
BNE 10$ ;
MOV XXISR-XXLQE(R5),@#10 ;ВОССТАНАВЛИВАЕМ
TST (PC)+ ;КУ
10$: SEC ;КЮ
RETURN ;
---------- Post added at 22:15 ---------- Previous post was at 22:05 ----------
Еще пара слов про XB/XM/ZB/ZM мониторы (а заодно и про TSX). В случае с драйвером, мы заранее знаем будет он работать в системе с MMU или без. Соответственно многое можно упростить. Например наличие MMU автоматически означает наличие EIS (можно не писать универсальные заменители MUL/DIV/SOB итд). Также наличие MMU гарантирует наличие PSW по адресу 1(77)77776. Команд же MFPS/MTPS вполне может не быть (11/34, Электроника 100/25)...
---------- Post added at 22:43 ---------- Previous post was at 22:15 ----------
Пара слов про драйверы, перехватывающие вектора 4 или 10. Если в момент входа в прерывание значение INTLVL >=0 в RMON, нет смысла что-то делать дальше - при отдаче такого прерывания в систему последовал бы ?MON-F-System halt (однако если драйвер используется чтобы сэмулировать команды процессора которые использует другой драйвер из под .DRAST...). Можно воспользоваться недокументированной фичей для такого случая (на примере прошлого драйвера):Примечание: в RT-11SJ без поддержки таймера нет INTLVL.Код:...
XXINT:: TST @(PC)+
INTLVL: .BLKW
BPL 10$
...
XXLOA:: MOV @R5,R5 ;ПОЛУЧАЕМ АДРЕС XXLQE
MOV $INPTR-XXLQE(R5),R0 ;ПОЛУЧАЕМ АДРЕС $INTEN
CMP (R0)+,(R0)+ ;ПОЛУЧАЕМ АДРЕС INTLVL
MOV R0,INTLVL-XXLQE(R5) ;СОХРАНЯЕМ В ДРАЙВЕРЕ
...
Пара слов о поддержке расширенных номеров устройств в RT-11 V5.5 и новее - вытаскивать эту инфу из документации непросто, а посему напишу здесь как все делается.Код:...
;+
;В ЭТОМ ПРИМЕРЕ ЕСЛИ В .CND ФАЙЛЕ ПРОПИСАНА ПОДДЕРЖКА РАСШИРЕННЫХ
;НОМЕРОВ УСТРОЙСТВ (0-77), МЫ ВКЛЮЧАЕМ ТАКУЮ ПОДДЕРЖКУ ДЛЯ ДРАЙВЕРА.
;ТАКАЯ ЗАВИСИМОСТЬ НЕ ЯВЛЯЕТСЯ ОБЯЗАТЕЛЬНОЙ - ДРАЙВЕР БЕЗ ПОДДЕРЖКИ
;РАСШИРЕННЫХ НОМЕРОВ МОЖЕТ РАБТАТЬ В СИСТЕМЕ С ПОДДЕРЖКОЙ И НАОБОРОТ.
;-
.IIF NDF UNI$64 UNI$64=0
;+
;ДЛЯ ПОДДЕРЖКИ РАСШИРЕННЫХ НОМЕРОВ УСТРОЙСТВ, В ДРАЙВЕРЕ ДОЛЖНО БЫТЬ
;ОПРЕДЕЛЕНО XX$N64=1 (ГДЕ XX - ИМЯ ДРАЙВЕРА).
;-
.IF NE UNI$64
XX$N64 = 1 ;ЕСТЬ ПОДДЕРЖКА
.IFF
XX$N64 = 0 ;НЕТ ПОДДЕРЖКИ
.ENDC
...
.IF NE XX$N64
;+
;В .DRDEF ДОЛЖНО БЫТЬ УКАЗАНО UNIT64=YES ДЛЯ ПОДДЕРЖКИ РАСШИРЕННЫХ
;НОМЕРОВ УСТРОЙСТВ. ПО УМОЛЧАНИЮ ОДНОБУКВЕННОЕ ИМЯ УСТРОЙСТВА СОВПАДАЕТ
;С ПЕРВОЙ БУКВОЙ ИМЕНИ. ЕСЛИ ТРЕБУЕТСЯ ДРУГАЯ БУКВА, НУЖНО
;ОПРЕДЕЛИТЬ XX$PN2=^RY (ГДЕ Y - НУЖНАЯ БУКВА).
;-
.DRDEF XX,367,FILST$!VARSZ$!SPFUN$,0,0,0,UNIT64=YES
.DRPTR FETCH=XXLOA,LOAD=XXLOA,RELEASE=XXUNL,UNLOAD=XXUNL
.IFF
.DRDEF XX,367,FILST$!VARSZ$!SPFUN$,0,0,0
.ENDC
...
MOVB Q$UNIT(R4),R1 ;ПОЛУЧАЕМ НОМЕР УСТРОЙСТВА
BIC #^C7,R1 ;УБИРАЕМ ЛИШНИЕ БИТЫ
.IF NE XX$N64
;+
;ДОПОЛНИТЕЛЬНЫЕ БИТЫ РАСШИРЕННОГО НОМЕРА УСТРОЙСТВ БЕРУТСЯ ИЗ
;Q.FUNC ЭЛЕМЕНА ОЧЕРЕДИ И ОПРЕДЕЛЯЮТСЯ ТАК:
; БИТ: 876543210
; TNNNFFFFF
;
;ЕСЛИ T=0, ЭТО READ, WRITE ИЛИ ФУНКЦИИ РАБОТЫ С ФАЙЛАМИ ДЛЯ SPECL$ УСТРОЙСТВ.
;В ЭТОМ СЛУЧАЕ NNN - СТАРШИЕ БИТЫ НОМЕРА УСТРОЙСТВА, FFFF - ФУНКЦИЯ (000-017)
;
;ЕСЛИ T=1, ЭТО SPFUN, В ЭТОМ СЛУЧАЕ NNN - НУЖНО ИНВЕРТИРОВАТЬ,
;FFFF - ФУНКЦИЯ (360-377)
;-
MOVB Q$FUNC(R4),R2 ;ПОЛУЧАЕМ СТАРШИЕ БИТЫ
BPL 10$ ;PL - OK
COM R2 ;ИНВЕРТИРУЕМ ДЛЯ SPFUN
10$: BIC #^C160,R2 ;УБИРАЕМ ЛИШНЕЕ
ASR R2 ;ДОБАВЛЯЕМ
BIS R2,R1 ;
.ENDC
...
;+
;ДЛЯ МОНИТОРА С ПОДДЕРЖКОЙ РАСШИРЕННЫХ УСТРОЙСТВ И ПРИВЯЗКИ
;УСТРОЙСТВА ТРЕБУЕТСЯ ЗАПОЛНИТЬ/ОЧИСТИТЬ НЕКОТОРЫЕ ТАБЛИЦЫ.
;-
.IF NE XX$N64
.PSECT SETOVR
$SYPTR = 54 ;УКАЗАТЕЛЬ НА RMON
$PNPTR = 404 ;АДРЕС ТАБЛИЦЫ $PNAME
$CNFG3 = 466 ;ТРЕТЬЕ СЛОВО КОНФИГУРАЦИИ СИСТЕМЫ
CF3.OW = 2000 ;В СИСТЕМЕ ЕСТЬ ТАБЛИЦА $OWNER
CF3.64 = 400 ;СИСТЕМА ПОДДЕРЖИВАЕТ РАСШИРЕННЫЕ
;НОМЕРА УСТРОЙСТВ
;+
;НА ВХОДЕ В ПОДПРОГРАММЫ ЗАГРУЗКИ/ВЫГРУЗКИ
;R2 = КОЛИЧЕСТВО СЛОТОВ ДЛЯ УСТРОЙСТВ (*2)
;R5 = УКАЗАТЕЛЬ НА $ENTRY ДРАЙВЕРА
;-
XXLOA:: CALL FIXOWN
BEQ 10$
ADD #XX$X64-XXLQE,@R1
10$: RETURN
XXUNL: CALL FIXOWN
BEQ 10$
CLR @R1
10$: RETURN
;+
;НА ВХОДЕ
;R2 = КОЛИЧЕСТВО СЛОТОВ ДЛЯ УСТРОЙСТВ (*2)
;R5 = УКАЗАТЕЛЬ НА $ENTRY ДРАЙВЕРА
;
;НА ВЫХОДЕ
;Z=1 - НИЧЕГО НЕ ТРЕБУЕТСЯ ДЕЛАТЬ
;-
FIXOWN: MOV @#$SYPTR,R1 ;ПОЛУЧАЕМ АДРЕС RMON
BIT #CF3.64,$CNFG3(R1) ;ЕСТЬ ПОДДЕРЖКА РАСШИРЕННЫХ НОМЕРОВ?
BEQ 10$ ;НЕТ
BIT #CF3.OW,$CNFG3(R1) ;ЕСТЬ ТАБЛИЦА $OWNER
BEQ 10$ ;НЕТ
MOV R2,R3
ASL R3
ASL R3
ADD R2,R3
MOV $PNPTR(R1),-(SP)
ADD R1,@SP
ADD R2,@SP
MOV R5,R1
SUB (SP)+,R1
ADD R5,R1
SUB R3,R1
CMP -(R1),-(R1)
MOV @R5,-(R1)
10$: RETURN
.ENDC
form, а какие есть варианты запуска COM файла из приложения?
через .CHAIN я понимаю - ничего не получится, надо наверное CSI команду
формировать-передавать в MON ? (возможно уже обсуждали, но я что то не нашёл, нашлась только шпора Patrona по обработке приложением входящего CSI в теме pascal/macro-11). Простой пример такой надобности -
к примеру в рамках сборника игр для эмулятора перед стартом игры - поднастроить УК-НЦ палитру или загрузить шрифт, а затем уже стартануть игру. В общем когда нужно цепочку команд выполнить, и есть ли шанс в процессе (наверное опять таки нету) избежать возможности прервать исполнение COM файла пользователем?
Еще пара слов про драйверы... Фича: в инсталяционной процедуре допускается обращение к несуществующей памяти/несуществующему регистру, при этом бит C взводится в случае ошибки. Соответственно можно использовать TST для проверки наличия регистра.