Сей рестарт проверяет на правильность
и корректирует прямо во входном буфере имя и расширение файла или каталога. В
регистре 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
Этот рестарт ищет установленный
драйвер или резидент по имени. 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$
…
Этот рестарт подобно рестарту
$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
Запуск резидентной задачи по номеру ее
канала в регистре 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
Запуск программы (.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
…