#50 (80) $fncor
Сей рестарт проверяет на правильность и корректирует прямо во входном буфере имя и расширение файла или каталога. В регистре HL на входе подается адрес 11-байтового буфера с именем и расширением файла. Признак каталога - установленный 5-й бит регистра A на входе, т.о. в регистр A Вы можете положить регистр состояния файла (11-ый байт описателя). Рестарт проверяет 11 байт на наличие среди них запрещенных, а запрещены все кроме тех, которые разрешены. Это: латинские и русские символы, цифры и еще 8 символов: #$&+-=_` (коды: #23,#24,#26,#2B,#2D,#3D,#5F,#60).
С 21.IX.1999 к разрешённым добавлены символы: !@%'(){|}~ для упрощения копирования файлов из MS-DOS. При наличии запрещенных символов в имени выдается ошибка 31. В случае каталога все маленькие буквы заменяются большими.
Пример из программы mkdir.com(.res):
;Позиционирование в окне для ввода имени каталога:
WTPOS LD HL,#301
LD C,$wtpos
RST 16
;редактирование имени:
LD A,8 ;длина строки
LD DE,#A01 ;ПРОПИСНЫЕ
LD HL,FILE ;текстовый буфер
LD BC,#100+$smbgt
RST 16
JR NZ,1$ ;отказ
OR A ;длина введенной строки
JR Z,1$ ;пустая строка
;Проверка на корректность:
LD A,#20 ;каталог
LD C,$fncor
RST 16
JR C,WTPOS ;повторить ввод
JR MAKE ;создать файл
;выход по отказу с перепечаткой текущей панели:
1$ XOR A
LD A,#F8
RET
#51 (81) $fndev
Этот рестарт ищет установленный драйвер или резидент по имени. 8-буквенное имя резидента или драйвера хранится в канале драйвера (резидента), со смещением 10. 18-байтовый канал создается при установке резидента (драйвера) программой set.com и удаляется ей же при его снятии.
На входе в рестарт подается адрес буфера с именем в регистре HL и устанавливаются границы поиска: A=номер канала, с которого начинать поиск, B=число каналов перебора. Рекомендуемые значения регистров A и B приведены в следующей таблице:
|
|
A |
B |
|
res |
#D8 |
10 |
|
key |
#E8 |
8 |
|
typ |
#F0 |
8 |
|
blk |
#F8 |
8 |
Выход: A=номер канала в указанном диапазоне. HL'= адрес тела канала. Подробно он описывался в ПРИЛОЖЕНИИ 8. Таблица приводилась в описании рестартов #14..#1D, работающих с каналами. Напомним лишь, что со смещением 4 лежат 2 байта адреса резидента в памяти, 6(2) - длина.
Возможные ошибки:
37 - Нет резидента с таким именем
124 - Ошибка в структуре области каналов
Этим рестартом пользуются такие программы как: set.com, dev.com и новейшая программа antipod.com, откуда и приведем пример:
_mon DEFM "mon"
_mon_ DEFM "mon+"
;Ищем резидента mon.res:
LD HL,_mon
LD A,#D8
LD BC,#1000+$fndev
RST 16
JR NC,1$ ;нашли
CP 37 ;нет такого?
SCF
RET NZ ;другая ошибка
;Ищем резидента mon+.res:
LD A,#D8
LD HL,_mon_
RST 16
JR NC,1$
CP 37
SCF
RET NZ
;Печать сообщения "mon.res not installed"
LD DE,mon
CALL TY_NO
JR 2$
1$ EXX
;в HL - канал резидента:
INC HL
INC HL
INC HL
INC HL
LD E,(HL)
INC HL
LD D,(HL)
;DE=адрес резидента в памяти
EX DE,HL
LD DE,Mon
LD A,MonSZ ;размер модели
;поиск по модели:
CALL Search
JR NZ,2$
…
#52 (82) $opres
Этот рестарт подобно рестарту $opcat(#43) обрабатывает командную строку, находящуюся в системном буфере, однако предназначен для поиска не файлов, а резидентов и драйверов. В отличие от $opcat ключей снимать не умеет. По имени и типу (после точки) ищет установленного резидента или драйвер. "@" понимает как "bat.res". Выход без флага C полностью аналогичен предыдущему рестарту, т.е. A=номер канала резидента, HL'=тело канала. Возможные ошибки тоже те же. В старых версиях системы (до 25.II.1997) ошибка 37 на выходе (флаг C, A=37) подменялась сброшенными флагами C и Z, т.е. признаком нормального завершения был установленный флаг Z при сброшенном флаге C.
Пример из программы scan.res:
DEFS 4 ;начало резидента
XOR A
LD (RNCSR+1),A
LD C,$opres
RST 16
RET C
LD (RSRN+1),A ;номер канала
;Старый стандарт. Восстановим Status Quo:
LD A,37
SCF
RET NZ
#53 (83) $exres
Запуск резидентной задачи по номеру ее канала в регистре A. Передает резиденту все регистры кроме AF. Возврат напрямую из резидента, также как в случае с рестартом $run. Используется резидентами univ и scan для запуска других резидентов.
Возможные ошибки:
124 - Ошибка в структуре области каналов
125 - Нет канала
Плюс все ошибки, возвращаемые данным резидентом.
Еще один кусок резидента scan.res в качестве примера (см. также рестарт $opres):
;Процедура, вызываемая после открытия каждого следующего файла:
_WORK LD C,$bkfcb
RST 16
EXX
;Сравнение имени и расширения с шаблоном:
LD DE,TRAF
LD C,$cpfil
RST 16
RET NZ ;не подходит
PUSH HL
LD BC,11
ADD HL,BC
LD A,(HL) ;CSR файла
POP HL
RNCSR XOR 0 ;маска каталогов
AND #20 ;каталог ?
RET NZ
RSRN LD A,-1
;Восстановим указатель в командной строке, чтобы вызываемый резидент мог снова
;снять те же самые параметры (ключи):
pathBC LD BC,0
pathHL LD (0),BC
LD DE,TRAF ;шаблон для ren.res
LD BC,#7700+$exres
RST 16
RET
TRAF DEFS 11
#54 (84) $swrun
Запуск программы (.com-файла или резидента) аналогично рестарту $run(#48) с сохранением части памяти в файле Q:swap0.swp.
Вход: HL - адрес командной строки для run'a,
IX - адрес начала сохраняемой области памяти,
DE - размер сохраняемой области.
После возвращения из вызванной этим рестартом программы востанавливается область памяти из swap-файла. Применяется в случае острой нехватки памяти, например в базах данных подобным образом вызывается программа print.com. Ранняя версия программы vicomm.com (X-MODEM) с помощью этого рестарта вызывала tv.com для просмотра файлов не выходя из программы. Затем автор отказался от этой тормозной и, в данном случае, не самой необходимой функции.
Возможные ошибки - это ошибки рестартов $swblk(#1C), $crfil(#23), $run(#48).
Специально написанный тестовый пример:
ORG 26000
START XOR A
LD IX,`OKHO
LD C,$wt
RST 16
LD C,$adrwt
RST 16
LD C,$kwait
RST 16
DEC C
RST 16
CP #10
LD A,#F4
RET Z
LD IX,START
LD DE,SIZE
LD HL,LINE
LD C,$swrun
RST 16
RET C
JR START
`OKHO DEFB 4,8,7,24,#38,1,7,29
DEFM "Пример использования рестарта"
DEFM "$swrun(#54). Нажмите любую"
DEFM "клавишу для вызова tv.com по-"
DEFM "верх тестовой программы или"
DEFM "<Ss/A> для выхода."
DEFB #D
LINE DEFM "tv S:extent.txt"
DEFB #D
SIZE EQU $-START
…