Рекомендации
пользователю по написанию прикладных программ.
Если прикладная программа не может
целиком разместиться в памяти, то рекомендуется разделить ее на несколько
частей и общие функции этих частей вынести в главный модуль, который
загружается в память и поручить ему управлять оверлеями. Для связи частей с
главным модулем рекомендуется использовать 7-й уровень системы,
зарезервированный для пользователя, рестарты с 224 по 255. Для этого главный
модуль должен содержать 32-словную адресную таблицу функций, доступных
оверлейным модулям. Адрес этой таблицы необходимо сообщить системе при загрузке
главного модуля.
При работе с вложенными структурами
рекомендуется использовать следующий механизм операционной системы. Все
вложенные программы должны иметь доступ к одному общему байту, содержащему 0,
если рекурсивная цепочка отсутствует, или номер канала, описывающего самый
верхний уровень вложенности. Канал должен иметь следующую структуру:
0-й байт - номер устройства
1-й и 2-й байты - номер каталога
3-й байт - номер файла
4-й байт - номер канала,
описывающего предыдущий уровень рекурсии
5-й и остальные байты - используются
прикладной программой
При входе в следующий уровень рекурсии менеджер каналов
выделяет новый канал, номер которого помещается в общий байт, прежнее
содержимое которого сохраняется в 4-м байте выделенного канала. При выходе из
очередного уровня рекурсии содержимое 4-ого байта канала, описывающего этот
уровень, помещается в общий байт, а канал освобождается. Для удаления всех
уровней используется системный рестарт функции второго уровня $rsdel - 77.
Автостарт дискеты с iS-DOS
Первоисточник: Black crow #02
Перед любой операцией с диском TR-DOS загружает
девятый сектор нулевой дорожки в специально выделяемый для этого буфер по
адресу 23845. Буфер имеет длину 257 байтов. За этим буфером будет лежать область
описателей каналов. TR-DOS не может прочитать часть сектора, она грузит его
целиком, какой бы длины он ни был. В результате сектор длиной больше, чем 256
байтов, затирает собой описатели каналов. Но TR-DOS об этом не знает и пытается
идентифицировать диск. Первым делом она проверяет в этом секторе байт со смещением
231, и если он не равен 16, то происходит немедленное прерывание операции с
выдачей сообщения Disc Error. Выдача сообщения идет
через канал K. Вот тут-то и срабатывает механизм автозагрузки. Достаточно в
ячейки со смещением 257 и 258 записать адрес вашего загрузчика, который
размещается в том же секторе. Загрузчик запустится, а там уж делайте, что
хотите.
СТРУКТУРА БЛОЧНОГО УСТРОЙСТВА
Каталоговое (блочное) устройство в системе iS-DOS
может располагаться как на дисках, так и в дополнительной памяти компьютера
(т.н. "быстрый диск"). Файловая служба (уровень DUD.SYS) не делает
различий между ними (тонкостями занимаются уровень DOS.SYS и драйверы). Т.о. с
точки зрения DUD.SYS блочное устройство представляет собой набор блоков
(размером 256 байт) с номерами от 0 до некоего максимального. На 0-ом блоке находится
заголовок тома (см. ПРИЛОЖЕНИЕ 1). В нем указаны размер устройства, полезная
информация для драйвера и ссылка на главный каталог устройства (для
80-дорожечного двухстороннего диска это обычно 3-ий блок). Все каталоги в
iS-DOS, включая и главный, представляют собой почти обычные файлы. Файл в
iS-DOS - это набор блоков располагающихся на устройстве подряд (непрерывные
файлы) или состоящие из нескольких (от 1 до 85) непрерывных участков
("сегментов"). Сегментированные файлы имеют в своем 32-байтовом
описателе, лежащем в каталоге ссылку на специальный блок, описывающий
сегментную структуру файла. 0-ой байт этого блока содержит число сегментов
файла. Остальные 255 байт рассматриваются как 85 3-байтовых записей, каждая из
которых описывает 1 сегмент файла. Первые 2 байта записи - номер 0-го блока
(адрес на устройстве) сегмента, а последний байт записи - размер сегмента в
блоках. Файл 0-ой длины имеет заполненный нулями блок описателя сегментов. К
сегментированным файлам можно добавить блок или несколько в начало или
середину, (а в конец даже с точностью до байта), а также удалить блоки.
Непрерывные файлы и каталоги можно только укорачивать (рестартом $ecut(#32)),
зато доступ к ним - быстрее. Если известны правила использования каталога, его
лучше делать непрерывным и нужного размера. 32-байтовые описатели файлов
располагаются в файле каталога подряд по 8 записей в блоке. Каталог - тоже
файл, но у него 2 описателя (кроме главного каталога устройства, у которого
только 1: внутренний): внешний, в старшем каталоге, и внутренний - 0-ой файл
самого каталога. Вся информация о размерах, количестве файлов, уровне
вложенности хранится во внутреннем описателе. Именно этот описатель загружается
в память при открытии каталога рестартами $open1(#21) и $fopen(#25). Каталог,
как и любой файл, может быть непрерывным или сегментированным. В первом случае
при заполнении каталога файлами до предела (8 файлов на блок) Вы получите
удовольствие наблюдать сообщение об ошибке с кодом 105. Программа rename.com
поможет Вам устранить неудобство. Сегментированный каталог при его наполнении
файлами сам увеличится до нужного размера. Пределом будет лишь ограничение на
128 файлов в каталоге, вызванное несколько небесконечными размерами памяти ZX‑Spectrum,
что однако, на наш взгляд, полностью компенсируется возможностью создавать
подкаталоги до 6-го уровня вложенности.
Переполнение блока описателя сегментов файла (ошибка
94) - еще одна неприятная ситуация, в которой можно оказаться при
бесконтрольном добавлении и удалении блоков в файлах большой (более 85 блоков)
длины. При добавлении в конец файла с излишней сегментированностью файла легко
справиться, добавляя к файлу по несколько блоков сразу, и удаляя все лишнее по
окончании рабочего процесса. Так делает, на пример, программа prt.com при
печати в файл, добавляя к файлу по 5 блоков. Если же программа добавляет блоки
в середину файла, как к примеру edit.com, то выход можно найти лишь в
периодическом копировании файлов или разбиении большого файла на несколько
поменьше.
Еще одно маленькое неудобство для любителей всего
большого: рестарты $crfil(#23) и $crf__(#3B) обнуляют старший байт длины, после
чего получают число блоков файла округляя младшие 2 байта. В результате сходу
Вы сможете получить файл длиной от 0 до 65280 байт (255 блоков). Далее Вы
можете воспользоваться рестартами добавления $fadd(#2F) или $eadd(#31). В
результате нехитрых махинаций Вы получите файл до 21675 блоков длиной (5548800
байт), что в 6 с лишним раз превышает вместимость дискеты. Если этот путь Вас
по каким-либо причинам не устраивает, Вы можете напрямую обратиться к бит-карте
диска (файл device.sys, блоки 1,2). 1 бит на блок, 0-му блоку диска
соответствует 7-ой бит 0-го байта 1-го блока device.sys, 1-ому блоку - 6-ой
бит, 8-ому блоку - 7-ой бит 1-го байта и т.д.
В главном каталоге первый файл, как правило,
device.sys. Чтобы он не выбирался по маске, отметке и т.п. в его регистре
состояния подняты все биты. Т.е. он невидим, защищен и даже вроде как бы
каталог. В нем находятся заголовок тома и бит-карта блоков тома. Т.о
пользователь получает к ним доступ через файл. Открыть файл можно рестартом
$find(#34), а рестартом $fopen(#25) и обращающимися к ней процедурами уровня
COM в данном случае пользоваться не рекомендуется. Если диск загрузочный, то в
главном каталоге обязан присутствовать еще один файл, защищенный подобным
образом: boot.sys. Он также создается при инициализации тома программами
format.com и create.com. В нем программа boot.com
размещает загрузчик системы.
На загрузочном диске также должен находится файл
????_dos.sys, представляющий собой выгруженную на диск память компьютера с
системой iS-DOS. Сохранение на диске производит программа sv.com. Пример: sv
smal. Программа sv.com при подобном обращении создаст файл smal_dos.sys в
текущем каталоге. Чтобы система загружалась именно из этого файла, необходимо
присоединить этот файл к тому программой con.com.
При загрузке происходит автозапуск командного файла S:autoexec.bat. На системном диске необходимо наличие файла
S:extent.txt, определяющего действия системы в зависимости от расширения файла
при нажатии клавиши Enter на этом файле. Также обязательно наличие каталога
S:SHELL и файлов extkey.txt, extview.txt и extprin.txt, определяющих действия
системы (строго говоря, уровня SHELL) при отработке всех прочих клавиш и клавиш
<6> - "VIEW" и - "HARDCOPY" в зависимости
от расширения файла. Все файлы ищутся на диске Q - "quick", т.н.
"быстром" диске. Им разумно назначить электронный диск, если у Вас
имеется дополнительная память и соответствующий драйвер. Для работы редактора
необходим каталог Q:EDIT со всеми нужными редактору файлами.
Все остальные программы могут располагаться в
зависимости от желания пользователя.
Некоторые
требования и рекомендации по программированию на ассемблере в IS'DOS.
1.Системные рестарты.
Все системные рестарты возвращают на выходе значения
регистров HL,DE,BC,IX, как в случае успешного, так и неуспешного (установлен
флаг С на выходе и код ошибки в регистре А) завершения. Остальные регистры не сохраняются.
Выходные значения рестартов передаются через дополнительные регистры и регистр
A.
2.Текущая среда.
Под текущей средой здесь понимается
текущее открытое устройство каталог и файл. Самая компактная полная запись
среды состоит из 4 байт:
1 номер устройства;
2,3 номер блока каталога;
4 номер файла в каталоге или #FF, если файл не
открыт;
В iS'DOS'е
принят следующий стандарт работы со средой:
- Выполняемые файлы загружаются системным рестартом
$exebat, который открывает устройство, каталог и файл из буфера командной
строки, но, перед передачей управления загруженной им программе, сам восстанавливает
среду, а среда этой программы записывается в вектор командной строки (см.
описание рестарта $exebat).
- Перед выходом из программы, она сама должна
восстановить среду, если во время ее работы среда менялась.
В случае необходимости узнать свою среду программа
должна достать ее, например так:
LD C,$gcom
RST 16
EXX
LD BC,-9
ADD HL,BC ;теперь HL указывает
адрес 4 байт искомой среды;
Для открытия "себя" теперь осталось
воспользоваться $g_stat:
PUSH HL
POP IX
XOR A
LD C,$g_stat
RST 16
RET C
;теперь программа открыла свою среду и
может сама модифицировать свой файл, например, записав перенастроенные
пользователем параметры.
Системные рестарты, изменяющие среду, уровня
интерпретатора командной строки сохраняют среду в спец. векторе. (Его адрес
дает регистр DE' после запуска $g_com.)
После каждого такого рестарта возможно вернуть
предыдущую среду с помощью $fmrst.
Часто бывает удобнее сохранять среду в начале
программы в своем векторе по $p_stat и восстанавливать ее при выходе из
программы по $g_stat:
JR SVMED
VCTMED DEFS 4
SVMED LD IX,VCTMED
XOR A
LD C,$p_stat
RST 16
RET C
...
...
...
LD IX,VCTMED
XOR A
LD C,$g_stat
RST 16
RET C
3.Системные рестарты чтения-записи.
Эти рестарты находятся в уровне файловой службы
IS'DOS (коды #20-#3F).
Самые безопасные и универсальные рестарты
записи-чтения - это $wpart и $rpart. Они позволяют работать с точностью до
байта. Рестарты $rvblk и $wvblk работают с одним блоком. Эти четыре рестарта
работают через кэш диск, и всегда обеспечивают наличие на кэш диске последней
версии рабочих блоков, т.е. не может быть ситуации, когда блок на устройстве
является более "свежим", чем на кэш диске. Хотя обратное допустимо,
и, чтобы блок наверняка попал на устройство, в конце работы Вашей программы
необходимо вызвать системный рестарт $flush. (Не забывайте, что $flush
сохраняет кэш-блоки только текущего устройства, и в случае расположения выходных
файлов на разных устройствах необходимо вызывать $flush несколько раз).
Два рестарта записи-чтения нескольких блоков $wifle и
$rifle требуют очень внимательного и осторожного применения, т.к. работают мимо
кэш диска, и за ситуацию, когда на кэш диске остается "устаревший"
блок, ответственность несет программист.
Учитывая, что в конце каждой утилиты
или программы IS'DOS должен быть $flush, при запуске новой программы на кэш не
будет "устаревших" блоков, но выходить в IS'DOS после использования
$wifle нужно с пересозданием или очисткой кэш диска (рестарты $shel0, $clear
или выход с флагом Z и кодами #F6 или #F7).
Каналам в iS-DOS'е
выделяется область памяти фиксированной длины под самым нижним резидентом или
драйвером. Под областью каналов располагается кэш блочных устройств. Таким
образом, когда программа set.com устанавливает в память новый резидент или
драйвер, либо снимает его оттуда, она каждый раз сдвигает область каналов, а
также кэш. Изменить размер области каналов можно с помощью утилиты channel.com.
Размер кэша аналогично меняется программой cache.com. При сохранении системы на
диске программой sv.com все установки сохраняются.
Итак область каналов
(ОК). В векторе ядра системы (см. ПРИЛОЖЕНИЕ 3 и рестарт $g_cnf(#10)) со смещением 32..37
последовательно лежат: адрес начала области каналов, адрес конца ОК и указатель
заполнения ОК, т.е. адрес за концом последнего канала. Прямо по адресу начала
ОК лежит первый канал. Номер его может быть любым. Все каналы нумеруются от 0
до 255 и имеют следующую структуру:
Структура канала
|
смещение
|
имя
|
длина
|
комментарий
|
0
|
|
1
|
номер
канала
|
1
|
CHLEN
|
2
|
длина
канала (без головы)
|
3
|
|
CHLEN
|
тело
канала
|
Каналы с определенными номерами имеют следующее жестко
фиксированное предназначение:
Номера
|
Назначение каналов
|
#00-#07
|
каналы
блочных устройств
|
#08-#0F
|
символьные
устройства вывода
|
#10-#17
|
символьные
устройства ввода
|
#18-#D7
|
каналы
пользователя
|
#D8-#E7
|
описывают
резидентные задачи
|
#E8-#EF
|
описывают
драйверы символьных устройств ввода
|
#F0-#F7
|
описывают
драйверы символьных устройств вывода
|
#F8-#FF
|
описывают
драйверы блочных устройств
|
Каналы #00..#17 называют
"каналами, описывающими устройства" или "каналами
устройств" или "устройствами". Они ссылаются на каналы,
описывающие драйверы (#E8...#FE), называемые в свою очередь "каналами
драйверов". Последние содержат гораздо больше информации чем устройства.
Так, на пример, их можно находить по именам ($fndev(#51)).
Структура (тел) каналов #00...17
приведена в ПРИЛОЖЕНИИ 7,
а каналов #E8...#FE - в ПРИЛОЖЕНИИ 8.
В iS-DOS'е
можно одновременно установить до 8 драйверов каждого из 3 типов (блочные,
клавиатуры и печати) и на каждый из них "повесить" от 1 до 8
устройств, но так, чтобы суммарное количество устройств одного типа не
превышало 8. Так драйвер sys_driv.blk обычно имеет 2 устройства: 0-е и 1-е,
обслуживающие дисководы A и B соответственно, но при желании можно и устройства
C и D подключить к этому драйверу, либо наоборот, освободить устройство B.
Устройства при установке драйвера создает программа set.com, ориентируясь на
19-ый байт описателя файла драйвера. Добавить или убрать устройство можно
программой dev.com.
Леонтьев А. Г.