ИНТЕРПРЕТАТОР КОМАНДНОЙ СТРОКИ COM.SYS
Рестарты 2-го уровня системы (с #40-го
по #54) занимаются в основном обработкой текстовых командных строк, из которых
состоят batch-файлы, которые подаются в строковом мониторе mon.res
(mon.com) и которыми запускаются любые командные файлы из
оболочки при отработке нажатых клавиши <Enter>
(строки пишутся в файле Q:extent.txt), клавиш <3> и <H> (extview.txt и extprint.txt в каталоге Q:SHELL
соответственно) и, наконец, всех остальных клавиш, строки для которых описаны в
файле Q:SHELLextkey.txt. Обрабатывается командная строка в специальном
системном буфере уровня. Размер буфера 128 байт. Адрес буфера можно получить с
помощью рестарта $g_com(#45). Признаком конца строки служит символ #0D.
Обрабатывается строка слева направо. Указатель в буфере двигается до первого
пробела или конца строки (#0D). После запуска командного файла рестартом $run(#48)
или $exbat(#44) указатель в строке указывает на первый пробел
после имени и расширения файла или символ #0D.
Как и для рестартов 0-го и 1-го уровня
флаг C на выходе большинства рестартов является признаком
ошибки. Своих кодов ошибок у уровня COM совсем немного. Это:
код ошибки
|
рестарт
|
комментарии
|
31
|
$fncor
|
Запрещенные символы в
имени файла
|
37
|
$run
$exebat
$fndev
$opres
$exeres
|
Нет резидентной задачи
с таким именем или номером
|
79
|
$run
$exbat
|
Неверное имя устройства
в командах L_S, L_Q, L_T
|
130
|
$run
$exbat
|
Запускаемая программа
не влезает под кэш
|
138
|
$rcdel
|
Неверный номер канала в
рекурсивной цепочке
|
139
|
$p_com
|
Длина командной строки
превышает 128 символов
|
250
|
$run
$exbat
|
Неверная контрольная
сумма запускаемого com'a
|
Т.о. все остальные ошибки, которые Вы
можете здесь заполучить - это ошибки двух нижних уровней, т.е. 0-го и 1-го.
Например: 62, 80, 81, 85, 86, 87, 121, 125. При вызове рестартов $run,
$exbat, $exres, $swrun, т.е. рестартов обращающихся к командным файлам или
к резидентным задачам, Вы можете получить на выходе практически все что угодно
в зависимости от конкретной запускаемой задачи.
Для рестартов $oparm, $comst,
$opcat выходной флаг NZ при
сброшеном флаге C сигнализирует о конце командной строки (или о пустой
командной строке).
Для всех рестартов, кроме $exbat, $run,
$exres и $swrun сохраняются все прямые регистровые пары кроме AF.
Эти же 4 рестарта возвращаются в программу напрямую из вызываемых задач и
передают все выходные регистры задачи.
Путь может быть задан как в символьном
виде, так и в упакованном формате, т.е.:
Смещение
|
Длина
|
Примечание
|
0
|
1
|
код 8
|
1
|
1
|
номер устройства (диск)
|
2
|
2
|
каталог (см. g_stat(#37))
|
4
|
11
|
файл (имя и тип либо шаблон (см. trans(#46))
|
Открыть файл-параметр. Рестарт удобен тем, что за
один прием открывает сразу и путь к файлу, и сам файл. Однако данный рестарт не
умеет распознавать ключи, т.е. символьные последовательности начинающиеся с
косой черты "/" и заканчивающиеся пробелом или символом #0D. Ключ,
нечаянно затесавшийся в строку, обрабатываемую рестартом $oparm будет
воспринят, как имя файла. В этом случае, скорее всего, Вы получите ошибку 81 и
бредовую надпись типа:
Признак нормального завершения -
сброшенный флаг C и установленный Z.
Возможные ошибки - ошибки
нижних уровней:
81 - Нет
файла или каталога
85 -
Неверный блок описателя сегментов каталога
86 -
Каталог не открывается
87 - Нет
устройства на диске
121 -
Устройство с данным номером не установлено
6 - Нет
диска в дисководе
7 - Ошибка
чтения
20 - Чтение прервано
Пример из
начала программы tv.com. Рестартом $oparm программа пытается открыть
файл-параметр. Все возможные ключи задаются лишь после параметра и
обрабатываются программой "вручную" через рестарт $g_com(45)! Если
параметр не задан (флаг NZ), файл открывается по курсору.
LD (STACK+1),SP
;Сперва
сохраняется текущая среда:
LD IX,strtID
LD C,$p_sta
XOR A
RST 16
…
LD C,$oparm
RST 16
RET C
;+8 byte:
JR Z,VIEW_1
;откроем
файл под курсором:
G_CURS LD SP,(STACK+1)
LD C,$g_cur
RST 16
;A=номер
файла под курсором
LD C,$opnum
RST 16
RET C
VIEW_1
…
Восстановление среды до последнего
вызова какого-либо рестарта данного уровня, меняющего среду, например $oparm,
$comst, $opcat, $nwcom, $nwcat. Среда (4 байта) хранится в системном векторе уровня
по адресу, подаваемом в DE' рестартом $g_com. Особенность выходных флагов этого
рестарта в том, что при отсутствии собственных ошибок он сохраняет входное
значение AF.
Возможные ошибки те же, что и у
рестарта $g_sta:
86 -
каталог не открывается
80 - номер
файла слишком велик
121 - нет
устройства
124 -
испорчена область каналов
125 - нет
канала
7 - ошибка чтения/записи (драйвер)
Пример: главный цикл программы exebat.com:
RSTRT
;Открыть
bat-файл и прочитать следующую командную строку в буфер COM-уровня:
CALL GLIN
RET C
;Восстановить
текущую среду:
LD C,$fmrst
RST 16
RET C
;Напечатать
командную строку на экране:
CALL PRINT
;Запустить
командную строку
XOR A
LD C,$exbat
RST
16
RET C
;И
так далее...
JR RSTRT
Открывает устройство и каталог по
пути, указанному в текстовой строке или снимает ключ (часть строки,
начинающаяся с косой черты и заканчивающаяся пробелом или символом #0D). Вход:
HL - адрес командной строки. Выход в зависимости от флага:
C -
ошибка. Восстанавливается прежняя среда
NC,Z - A=0:
ПУТЬ[файл]:
В этом случае в HL' будет 11-байтовый описатель или
шаблон файла. Шаблоном называется описатель частично или полностью заполненный
символами #FF, что означает "любой символ". Такое может случиться,
если на вход преобразующей процедуре подать имя файла, содержащее символы
"?" и/или "*". Тот же эффект будет при отсутствии имени
файла в командной строке.
NC, Z, A≠0 - Обнаружен ключ. HL' - адрес
символа "/", A - символ после знака "/"
NC, NZ - Или ключа нет, или пути нет, или синтаксическая
ошибка с командной строке.
Возможные ошибки:
81 - Нет
каталога с таким именем
86 -
каталог не открывается
121 - нет
устройства
7 - ошибка чтения/записи (драйвер)
Пример из
программы tree.com:
;Программа
вывалилась из рестарта $panel с кодом клавиши в регистре A:
CP #D ;Enter?
JR NZ,FCMON ;обратно в $panel
LD E,(IX-34)
LD D,(IX-33)
;DE=номер
записи панели (номер строки)
CALL G_PATH
;HL=путь, соответствующий строке
;Вернуть панель iS-DOS'у:
CALL RESTOR
;Открыть
выбранный каталог:
LD C,$comst
RST 16
RET C
;Закрепить выбранный каталог в среде для $fmrst. Для
этого на вход подается пус-
;тая строка (по адресу в HL: #0D). Это позволит
вызывать tree.com из bat-файла:
LD HL,ENTER
LD C,$comst
RST
16
RET C
;Выход
в iS-DOS с перепечаткой панели:
XOR A
LD A,#F1
RET
В принципе то же, что и предыдущий
рестарт, но только работающий с внутренним буфером командной строки уровня COM.
Т.о. на вход данному рестарту ничего подавать не требуется. Этот рестарт
чрезвычайно удобен для снятия входных параметров из командной строки. Он
используется во многих com-файлах, работающих с файлом-параметром и/или
ключами. Например: cache.com, flush.com, delete.com, filecopy.com, sort.com и во многих других.
Возможные ошибки те же, что и у предыдущего
рестарта.
Пример из
программы sort.com:
OPCAT LD C,$opcat
RST 16
RET C
JR NZ,OPEX
;A=ключ,
т.е. первый байт после "/":
CP "-"
JR NZ,1$
;"-": инверсия
LD A,#D4 ;CALL NC вместо CALL C
LD (INVER),A
JR OPCAT
1$ CP "c"
JR Z,__C
CP "e"
JR Z,__E
CP "d"
JR NZ,OPCAT
;D:date - дата
LD A,1
LD (DAT+1),A
JR OPCAT
;Extention - расширение
__E LD A,2
LD (EXT+1),A
JR OPCAT
;Catalogue - каталоги
__C LD A,1
LD (CATS+1),A
JR OPCAT
OPEX
Смотрите также пример к
рестарту $opnum(#26) из программы calc.com и пример к рестарту $erf__(#3C) из
программы delete.com.
Как и предыдущие 3 рестарта ($oparm,
$comst и $opcat), сей рестарт также работает с командной строкой, но в отличие
от них не только открывает путь к файлу и файл, но и запускает этот файл на
исполнение. Причем, пользоваться этим рестартом можно по-разному в зависимости
от входных данных:
1. Если
системный буфер не пуст, то отрабатывается командная строка в нем, а регистры
HL, DE и A не имеют значения. Командная строка исполняется до первого пробела
или, за отсутствием таковых, до конца строки, т.е. до кода #0D. Формат строки
тот самый, что и у bat-файлов (см. любое описание системы для пользователей):
[ПУТЬ]файл [параметры]
здесь: файл - имя командного файла или
@резидент [параметры]
при запуске резидентной программы
Параметры рестарт не обрабатывает, путь открывается,
но перед самым запуском командного файла восстанавливается среда запуска.
2. Если
системный буфер строки пуст, т.е. первый байт в буфере #0D, то по адресу в HL
этому рестарту надо подать первые 12 байт описателя файла. Тогда, если регистр
A=0, рестарт откроет файл Q:extent.txt, найдет в нем строку с расширением файла
по адресу в HL, сделает из всего этого новую командную строку и отработает ее
так же, как и в первом варианте. Поскольку в регистре HL подается описатель
файла, то для нормальной работы в этом режиме, файл должен находится в текущем
каталоге.
Такой способ использует рестарт $exbat система при
нажатии клавиши <Enter> на файле. Первым же способом пользуется программа
exebat.com для отработки командных строк bat-файлов. Именно этот рестарт удобен
для данной программы, т.к. у программы exebat.com нет места для буфера
командной строки. Для всех прочих же случаев обычно удобнее рестарт $run(#48).
При A>0 во втором случае в регистре DE подается адрес строки с путем файла
формата extent.txt.
Адрес системного буфера командной строки доступен с
помощью рестарта $g_com(#45):
LD C,$g_com
RST 16
EXX
;HL=адрес
командного буфера
Размер буфера: 128 байт. Заполнить буфер можно с
помощью рестрарта $p_com(#49).
Возможные ошибки:
81 - нет
каталога или файла с таким именем
86 -
каталог не открывается
121 - нет
устройства
7 - ошибка
чтения/записи (драйвер)
130 -
запускаемый файл не влезает под кэш
250 -
неверная контрольная сумма запускаемого com-файла
+ все возможные ошибки, которые может
получить и передать дальше запущенный com-файл.
Пример из
программы exebat.com. Главный цикл программы:
RSTRT
;Заполнить командный буфер новой строкой:
CALL GLIN
RET C
;Восстановить
текущую среду:
LD C,$fmrst
RST 16
RET C
;Напечатать
строку на экране:
CALL PRINT
;Отработать
строку:
XOR A
LD C,$exbat
RST 16
RET C
JR RSTRT
Пример из
4-го уровня системы:
RUN
;Отработка клавиши <Enter>:
LD A,($FLCUR+11) ;CSR файла
AND #20 ;каталог?
JR Z,CNRN0
;иначе открытие каталога...
VIEW
;Отработка клавиши <3>:
LD HL,$IMAVW
;HL указывает на "Q:SHELLextview.txt"
JR $EXRUN
PRNT
;Отработка
клавиши <h>:
LD HL,$PRNT
;HL указывает на "Q:SHELLextprint.txt"
$EXRUN
;Заполнить буфер соответствующей строкой:
CALL DCRUN
EX DE,HL
PUSH DE
;Зажечь "VIEW" на экране:
LD A,"3"
CALL $BLICK
POP DE
LD A,-1
CNRN0 LD HL,$FLCUR ;имя и
CSR файла
LD B,2
$CNrun LD C,$exbat
OUTRST RST 16
RET C
RET Z
ORFF OR -1
RET
Этот рестарт выдает в регистрах HL' и DE' адреса
системных векторов уровня COM. HL:
Смещение
|
Длина
|
Описание значения
|
-11
|
1
|
проверять контрольную сумму com-файлов при запуске
|
-10
|
1
|
не используется
|
-9
|
4
|
среда последнего $exebat'а ($run'а). Позволяет запущенному com-файлу
найти самого себя
|
-5
|
2
|
указатель в командной строке. Перемещается от начала к концу
рестартами $oparm(#40) и $opcat(#43). Устанавливается
рестартами $exbat(#44) и $run(#48)
|
-3
|
2
|
Текущая дата (см. ПРИЛОЖЕНИЕ 23)
|
-1
|
1
|
Номер канала bat-файла в рекурсивной цепочке. Используется
программой exebat.com и рестартом $rcdel(#4D).
Позволяет вызывать один bat-файл из другого подобно подпрограмме
|
0
|
128
|
Буфер командной строки
|
Системный вектор в DE:
Смещение
|
Длина
|
Описание значения
|
-3
|
1
|
Номер канала "PATH", содержащего пути для дополнительного
поиска командных файлов, запускаемых рестартами $exbat и $run. Используется,
если путь не указан. Если 0, значит канала "PATH" нет. Устанавливается
и снимается программой path.com
|
0
|
4
|
Среда для $fmrst(#41). Активно используется практически всеми
рестартами уровня COM, которые открывают устройства и каталоги
|
Регистровая пара AF сохраняется.
Пример использования рестарта $g_com из программы date.com.
Данная процедура открывает файл date.com и сохраняет в нем параметры текущего
режима работы:
curID DEFS
4
;Сперва сохраним текущую среду в curID:
SVST_1 LD IX,curID
XOR A
LD C,$p_stat
RST
16
;Откроем
файл date.com:
LD C,$g_com
RST 16
EXX
LD BC,-9
ADD HL,BC
PUSH HL
POP IX
XOR A
LD C,$g_stat
RST 16
RET C
;Запишем
в него 1 байт со смещением 2:
LD IX,WDCSR
LD DE,1
XOR A
LD HL,2
LD C,$wpart
RST 16
RET C
;Обязательно
сосчитаем новую контрольную сумму!
LD HL,CALC
LD C,$run
RST 16
JR NC,1$
CP 37
SCF
RET NZ
;Зафиксируем
все на дискете:
1$ LD C,$flush
RST
16
RET C
;Восстановим
текущую среду:
LD IX,curID
XOR A
LD C,$g_stat
RST
16
RET C
;Вот ещё 1 способ восстановить среду для
exebat.com. Предыдущий способ - пустой $comst или $opcat использовался в примере
из программы tree.com к рестарту $comst(#42). Если этого не сделать, то после
вызова из bat-файла текущим каталогом может стать каталог, в котором находится
date.com.
LD C,$g_com
RST 16
EXX
LD HL,curID
LD BC,4
LDIR
RET
CALC DEFM /@calc/
DEFB 13
Этот рестарт преобразует имя и расширение файла,
написанные через точку, как они пишутся в командной строке, в 11-байтовый
описатель файла, по которому этот файл могут найти или создать рестарты 1-го
уровня. Адрес входного буфера подается на входе в регистре HL, выходного - в
DE. Входной буфер заканчивается символом #0D или пробелом. Символы
"*" и "?" на входе преобразуются в коды #FF на выходе. При
этом устанавливается флаг С на выходе, сообщающий, что на входе был подан шаблон,
требующий специальной обработки. Такая обработка осуществляется теми
программами, которым это необходимо, например: copy.com, find.com, scan.res,
mark.com.
Пример из программы qu.com:
TRANS
;Преобразуем в 11-байтовый формат:
LD HL,FILE
LD DE,F_11
LD C,$trans
RST 16
;Если
встретились символы "?" или "*", то изменить в редакторе:
JR C,SMBGT
;Проверим
на правильность:
EX DE,HL
LD C,$fncor
RST 16
;Если
всё OK, то отправимся на поиски:
JR NC,FIND
;Иначе
попросим скорректировать имя:
SMBGT
;Спозиционируемся в окне для вывода строки редактора:
LD HL,#202
LD C,$wtpos
RST 16
;Отредактируем
строку из 12 символов:
LD HL,FILE
LD DE,#100
LD BC,#8100+$smbgt
LD A,12
RST 16
JP NZ,NEXT ;<Ss/A> -
отказ
JR TRANS ;Ещё раз
FIND
;Поиск файла:
LD C,$find
RST 16
;Если
нашли, то поменять имя:
JR NC,SMBGT
;Ошибка
81 - нет файла.
CP 81
SCF
RET NZ
…
F_11 DEFS
11
FILE DEFS 13
Данный рестарт заполняет буфер либо
канал текстовой строкой с путем текущего подкаталога. Неиспользованное место
заполняется пробелами.
Входные регистры: A>0 - номер канала, в который записать путь. Не рекомендуется
пользоваться системными каналами, особенно с номерами менее #18 и более #D8. И
вообще, этим способом пользуется система, а для домашнего употребления удобнее второй
метод:
A=0, тогда в HL - адрес буфера, в DE
- размер буфера. Разумный размер буфера: 6x9+2=56 байт.
Среда после вызова сохраняется почти полностью, за
исключением текущего файла.
Возможные ошибки:
6 - нет
дискеты в дисководе
7 - диск
не читается
86 -
каталог не открывается
125 - нет
канала
Вот как используется этот рестарт в программе
unicolor.com:
G_WAY
;Сохраним
текущую среду, т.к. впоследствии будем пытаться открыть каталог HELP
;Рестарт $g_way переоткрывает каталог, посему
сохранить номер текущего файла также будет не вредно...
XOR A
LD IX,tmpID
LD C,$p_sta
RST 16
;адрес
буфера + его размер:
LD HL,PATH+8+pathSZ
;Очистим
его:
LD B,pathSZ
DEC HL
LD (HL)," "
DJNZ $-3
;Положим
в него путь:
XOR A
LD DE,56
LD C,$g_way
RST 16
RET C
;Сразу
за путем поместим имя файла: ищем первый пробел от начала:
1$ LD A,(HL)
CP " "
INC HL
JR NZ,1$
DEC HL
;Достанем
опмсатель текущего файла:
LD C,$bkfcb
RST 16
PUSH HL
EXX
POP DE
;Положим
его имя в буфер:
LD C,$convr
RST 16
RET C
…
Этот рестарт предназначен
исключительно для запуска командных файлов или резидентных задач из командной
строки, т.е. он выполняет одну из функций рестарта $exbat(44), но
проще в использовании, т.к. командная строка может находиться где угодно. Адрес
командной строки подается на входе в регистре HL. Рестарт
сам сперва копирует эту строку в системный буфер уровня, поэтому размер строки
не должен превышать 128 символов. Завершаться строка должна символом #0D.
Поэтому к возможным ошибкам рестарта $exbat добавьте 139-ую. Рестарт
передает вызываемой программе регистры IX и B
(резиденту можно передать также регистр DE). Возврат
происходит из программы напрямую, т.о. все регистры содержат на выходе все, что
угодно, в зависимости от вызываемой программы.
Пример из программы coca.com:
LENWT
LD HL,#5FF ;координаты окна
LD (WIND+1),HL
LD HL,LIN_1 ;печать строки
LD C,$lenwt
RST 16
XOR A
LD IX,curID
LD C,$p_sta ;сохранить среду
RST 16
;Запустить com-файл mkdir или copy25:
LD HL,LINE
LD C,$run
RST 16
RET C
XOR A
LD IX,curID
LD C,$g_sta ;Восстановить среду:
RST
16
RET
WIND DEFB
0,0,3,32,0,-1,0,42
copy DEFM "copy25 *.*"
copLN EQU $-copy
LINE DEFM "Q:SHELL"
LIN_1 DEFM "mkdir /c /s00 /f"
PATH EQU $
Рекомендуем также все
примеры, запуска резидента calc.res для подсчета новой контрольной суммы (рестарт $g_com(45),
программа date.com).
Данный рестарт копирует командную
строку в системный буфер. В HL на входе подается адрес строки. Строка должна
заканчиваться кодом #0D. Единственная возможная ошибка с номером 139 может
возникнуть при длине строки более 128 символов.
На практике рестарт почти не применяется.
Единственная программа из просмотренных мной, которая могла бы им
воспользоваться, без него таки обошлась. Это процедура сохранения системы
sv.com:
LD C,$g_com
RST 16
EXX
PUSH HL
LD DE,LINE
LD BC,LINESZ
EX DE,HL
LDIR
POP HL
…
LINE DEFM "Q:SHELLexebat
Q:autoexec.bat"
DEFB
13
LINESZ EQU $-LINE
Этот рестарт работает исключительно с
регистром A на входе и на выходе. Он преобразует т.н. логическое имя устройства
в физическое, т.е. заданное символьно в виде буквы от "A" до
"H" или букв "S", "Q" или "T"
(обязятельно латинских!) в номера устройств им соответствующих, т.е. числа от 0
до 7, означающие номера каналов устройств. При отсутствии данного логического
устройства (на входе вместо символов A..H,Q,S,T подано что-то другое) на выходе
флаг Z будет сброшен.
Пример из
программы image.com:
JP START
…
;Обработка
ключа:
OPTION CP "-"
JR NZ,OPCAT
INC HL
INC HL
LD A,(HL) ;логическое имя устройства
LD C,$dvtrn
RST 16
JR NZ,OPCAT
;A=физическое
имя устройства. Сравним с текущим
LD HL,FROM+2
CP (HL)
JR Z,OPCAT ;Защита от дурака
LD (Dest+1),A ;Выходное устр-во
ADD A,"A"
LD (destin+11),A ;для печати
JR OPCAT
START
…
LD C,$g_blk
RST 16
LD
(FROM+2),A ;Текущее устр-во
;Обработка параметров командной строки:
OPCAT LD C,$opcat ;следующий параметр
RST 16
RET C
EXX
JR NZ,OPEX ;конец ком. строки
OR A
JR NZ,OPTION ;ключ
;иначе - файл:
LD DE,FILE
LD BC,11
LDIR
JR OPCAT
OPEX
…
Этот рестарт полностью аналогичен
рестарту $comst(#42), т.е. он открывает устройство и каталог по пути, указанном
в текстовой строке, но при обращении к устройству вызывает рестарт $binit(#0F),
что желательно при обращении к новому диску, т.к. в принципе iS-DOS
поддерживает разные форматы дисков, хотя на практике используется обычно лишь
один формат.
Возможные ошибки,
соответственно все те же, что и у $comst плюс две ошибки рестарта $binit:
9 - не
исдос-устройство
10 - конфликт диска и дисковода
Рестарт применяется, похоже, только в копировщиках.
Вот пример из filecopy.com:
PROVER
;Открыть новое устройство и путь:
LD HL,$PATH
LD C,$newco
RST 16
JR NC,PRO_OK ;Если
O.K.
;иначе
- ошибка:
CP 81 ;нет каталога?
JR Z,PRO_81
CP 9 ;не iS-DOS-формат?
SCF
RET NZ
;Не iS-DOS диск:
CALL NOTISD ;Печать: "Not iS-DOS"
JR PROCRE
PRO_81 CALL NOPATH ;Печать: "No path!"
;Пересоздать кэш блочных устройств:
PROCRE
LD A,($BLOK)
LD C,$creat
RST 16
XOR A
INC A ;Выход с NZ
RET
PRO_OK
JR NZ,PRO_81
EXX ;имя
выходного файла
LD DE,TRAF
LD BC,11
LDIR
LD C,$g_cat
RST 16
LD
($DIS0+1),A ;текущий диск
EXX
LD
(OPISK2+1),HL ;тек. каталог
XOR A
RET ;Выход
с Z
Аналог $opcat(#43) для нового диска.
Как и предыдущий рестарт, дергает $binit сразу после переключения на новое
устройство. На практике почти не применяется, разве что в программе copy.com,
отрывок из которой очень напоминает предыдущий пример:
TRAF DEFS 11
NEWCAT
LD C,$newcat
RST 16
RET C
RET NZ
PROV1 EXX
LD DE,TRAF
LD BC,11
LDIR
LD C,$g_cat
RST 16
RET C
LD (DIS1+2),A
EXX
LD (OPISK2+1),HL
LD B,A
XOR A
RET
Данный рестарт удаляет рекурсивную
цепочку каналов, созданную программой exebat.com или, теоретически любую другую
цепочку. В регистре A подается на входе номер последнего рестарта. Каждый канал
цепочки в своем 4-ом байте должен содержать номер предыдущего канала. У первого
канала 4-ый байт должен быть равен 0.
Возможные ошибки:
124 -
неверная структура области каналов
125 - нет
канала
138 - ошибка в рекурсивной цепочке. Возникает, если
номер канала меньше #18 или больше #D8.
На практике используется, кажется, только рестартом
$shexe(93):
SHEXE
LD SP,$ADRSP ;Перехват стека
;Уже
знакомый Вам рестарт:
LD C,$g_com
RST 16
EXX
DEC HL
LD A,(HL) ;канал последнего bata
OR A
JR Z,Exbat
;А
вот и он...
LD C,$rcdel
RST 16
JR C,Shout
Exbat XOR A
;Отработка командной строки:
LD C,$exbat
RST 16
LD HL,$ERCSR
;Если все O.K., то выполняем $shel(80):
JR NC,SHEL00
;Одноразовый обход ошибки "нет файла".
Чтобы не ругалась при загрузке, когда
нет autoexec.bat:
BIT 0,(HL)
SET 0,(HL)
JR NZ,Shout
CP 81
JR Z,SHEL00
SCF
Shout JP $SHOUT
Этот рестарт ищет в таблице слово.
Вход: DE - адрес таблицы слов, разделенных
символом #0D. Длина слов от 1 до 7 байт. Первые 2 байта таблицы - размер самой
таблицы (без 2 байт длины).
В HL - адрес искомого слова в строке или
тексте. Слово должно заканчиваться символом менее #41 (буква A латинская).
Выход:
если поиск увенчался успехом, то флаг Z будет установлен, и в регистре A -
номер слова в таблице (нумерация от 0). В HL' - продолжение текста после
найденной модели, в DE' - продолжение таблицы. Если модель не найдена - флаг Z
сброшен.
Пример из
программы unicolor.com. Здесь с помощью рестарта $cp_ir анализируется
расширение файла, создаваемого пользователем для хранения в нем цветов. Таблица
содержит список запрещенных расширений.
;Копируем
расширение файла в буфер, чтобы в оно оканчивалось на 0-ой байт:
LD HL,FILE+8 ;расширение файла
LD DE,TPBUF
LD BC,3
PUSH DE
LDIR
POP HL
LD DE,EXTAB
LD C,$cp_ir
RST 16
JR NZ,FIND
;Печать
окна: "Неверное расширение файла"
LD IX,`WRNG1
LD A,(color+5)
CALL WRNG_1
JP INNAME
;Ищем файл:
FIND LD HL,FILE
LD C,$find
RST 16
RET
`WRNG1 DEFB 9,11,3,13,7,1,13,15
DEFM "Wrong extention"
TPBUF DEFS 4
d EQU #D
EXTAB DEFW TABLEN
DEFB
"b","a","t",d
DEFB
"b","l","k",d
DEFB
"c","o","m",d
DEFB
"d","a","t",d
DEFB
"d","o","c",d
DEFB
"d","p","r",d
DEFB
"h","l","p",d
DEFB
"k","e","y",d
DEFB
"l","p","r",d
DEFB
"n","m","i",d
DEFB
"o","v","r",d
DEFB
"p","a","c",d
DEFB
"r","e","s",d
DEFB
"s","y","s",d
DEFB
"t","x","t",d
DEFB
"t","y","p",d
DEFB
"w","e","t",d
TABLEN EQU $-EXTAB-2
Этот рестарт совершает преобразование
обратное тому, что делает рестарт $trans(#46), т.е. он получает на
входе первые 11 байт с именем и расширением файла, и формирует на выходе
текстовую строку с именем и расширением файла, разделенными точкой и символом #0D
в конце. Адрес входного буфера подается в HL, выходного - в DE. На выходе DE'
будет указывать на символ #0D в конце строки. Флаг на выходе смысла не имеет.
Пример из программы image.com:
;Ищем
файл, поданный в командной строке:
OPEX LD HL,FILE
LD C,$find
RST 16
RET C
;Положим
его имя и расширение в текстовый буфер окна:
EXX
LD DE,NAME
LD C,$convr
RST 16
EXX
;Забьем
пробелом ненужную "ВКашку":
LD A," "
LD (DE),A
EXX
;Размер
файла в блоках (2 байта):
LD BC,15
ADD HL,BC
LD DE,DSIZE+1
LDI
LDI
…
;Вектор окна:
`PROM DEFB 5,8,7,22,0,0,8,27
DEFM "Copy file"
NAME DEFM " "
DEFB 13
destin DEFM "To device: A"
out DEFB 13,13
DEFM "<Enter> to continue"
DEFB 13
DEFM "<SS/A> to quit"
DEFB 3
См. также пример из
программы unicolor.com к рестарту $g_way(#47).