┌─────────────────────────────┐
│ │
│ TR DOS ДЛЯ НАЧИНАЮЩИХ │
│ │
└─────────────────────────────┘
(c) В.Сироткин
Продолжение. Начало см. в ZX
РЕВЮ 1996 NN 1-2, 4-5, 6, 7-8;
ZX РЕВЮ 1997 NN 1-2, 3-4.
ПРОГРАММИРОВАНИЕ КОНТРОЛЛЕРА
А теперь разберем несколько
конкретных примеров.
!!! Необходимое напоминание:
не забудьте, что для разных вер-
сий ТРДОС необходимо выставлять
свои адреса подпрограмм !!!
Перед тем, как загрузчик нач-
нет работать, программа должна
определить версию ТРДОС и скор-
ректировать адреса вызовов.
Определять версию и настраивать
загрузчик удобнее всего функцией
ТРДОС C = #13. Мы пропустим эту
часть программы, так как в главе
'ФУНКЦИИ ТРДОС' подробно описа-
но, как это сделать.
Пример 1. Загрузчик файлов
140.
;базовые адреса ПЗУ даны для версии 5.01 *
;в угловых скобках будут указаны адреса для 5.03 *
; головная часть загрузчика
ORG ADRESS ; начальный адрес загрузчика
DI ; запретим прерывания
LD HL,#5800 ; закрасим экран черными атри-
; бутами
; на экране у нас будет буфер
LD DE,#5801 ; для считывания последнего
; сектора файла, чтобы в ОЗУ
; перенести нужное количество
; байтов,
; а также буфер для считы-
; вания каталога диска
LD BC,#01FF
LD (HL),L
LDIR
;------------------
CALL LOAD_CAT ; найти на диске нужный файл
; и его атрибуты (подпрограмма возвращает в ре-
;гистре 'D'- номер Дорожки, в 'E' - номер Секто-
;ра, в 'HL' адрес загрузки в ОЗУ, ; в 'BC'- длину)
;------------------
PUSH BC ; спрятать длину файла
DEC B ; уменьшить длину на 1 сектор
;-------------------
CALL LOAD_SEK ; файл без последних
; 2-х секторов (если 'C'=0,
; то без 1-го последнего)
; загрузить с адреса из 'HL'
;-------------------
PUSH HL ; спрятать последующий адрес
; ОЗУ для оставшихся 2-х,
; (1-го) сектора
LD HL,#4800 ; адрес буфера для сектора
LD B,2 ; ДВА сектора
CALL LOAD_SEK ; загрузить в адрес #4800 два
; последних сектора
POP DE ; достать адрес ОЗУ для остав-
; шихся секторов/сектора
POP BC ; достать длину всего файла
LD B,1 ; один сектор наверняка, и
; остаток длины из 'C'
LD HL,#4800 ; перенести из экрана
LDIR ; в адрес по 'DE'
EI ;
RET ; вернуться в программу
;---------------------------
; подпрограмма считывание каталога и определение
; атрибутов файла
LOAD_CAT LD DE,0000 ; ноль Дорожка и Сектор
LOAD PUSH DE ; спрятать
LD HL,#4800 ; адрес буфера в ОЗУ для
; сектора
PUSH HL ; спрятать
LD B,1 ; Один сектор
CALL LOAD_SEK ; считать сектор номером
; из 'E'
; с НОЛЬ дорожки ; т.е.
; из области КАТАЛОГА диска
POP HL ; начало адреса буфера
LD B,#10 ; счетчик заголовков (на
; секторе их 16)
CIKL PUSH HL ; спрятать адрес начала
LD DE,FILENAME ; адрес в ОЗУ, где ИМЯ
; файла,
; который нужно загрузить
LD C,08 ; счетчик букв имени файла
NAME_F INC HL ; пропустим первую букву в
; имени
; файла в считанном ката-
; логе
LD A,(DE) ; буква НУЖНОГО имени
CP (HL) ; сравним с буквой из ИМЕНИ
; файла считанного с диска
JR NZ,ZAGOLOW ; не совпало - переход
INC DE ; совпало - следующая буква
; имени
DEC C ; уменьшить счетчик букв
; имени
JR NZ,NAME_F ; все буквы? - нет - возврат
; на цикл проверки
POP DE ; Да, имя и тип файла
; совпали !
POP DE ; указатель стека вернем в
; исходное состояние
INC HL ; переходим на атрибуты
; файла
LD E,(HL) ; мл.бит АДРЕСА загрузки
; файла
INC HL
LD D,(HL) ; ст.бит АДРЕСА загрузки
INC HL
LD C,(HL) ; мл.бит ДЛИНЫ
INC HL
LD B,(HL) ; ст.бит ДЛИНЫ
INC HL ; пропустим байт объем в
; секторах
INC HL ;
LD A,(HL) ; Номер первого Сектора
; файла
INC HL
LD H,(HL) ; Номер Дорожки
LD L,A
EX DE,HL ; в HL-адрес загрузки в ОЗУ
; в DE - дорожка / сектор
; в BC - длина згружаемого
; блока
RET ; вернемся
;---------------------------
; счетчик заголовков и секторов каталога
ZAGOLOW POP HL ; вернем адрес текущего
; заголовка
LD DE,#0010 ; длина заголовка
ADD HL,DE ; перейдем на следующий
; заголовок
DJNZ CIKL ; если не весь сектор -
; повторить
POP DE ; вернуть и увеличить номер
INC DE ; сектора
BIT 3,E ; все 7 секторов каталога
JR Z,LOAD ; нет - повторить
JP ERROR ; да, каталог весь,
; но файлы не обнаружены:
; Переход на обработку
; ошибочной ситуации
;---------------------------
; имя файла для поиска в каталоге
FILENAME DEFM 'FNAME_0' ; имя файла без 1-й
; буквы
DEFM 'C' ; файл тип CODE
;----------------------------
;подпрограмма загрузки с диска
LOAD_SEK LD IX,#2F1B < #2F65 > ; адрес подпрограм-
; мы в ПЗУ
;'ВОСТАНОВЛЕНИЕ, т.е. переход на дорожку 0
; адрес является входом в середину процедуры
; #2EF0 < #2F3A > (смотри приложение)
CALL TRDOS ; исполнить подпрограмму
; в ПЗУ
TREK PUSH BC ; спрячем длину блока
PUSH ; и номер дорожки с
; сектором
LD A,D ; номер дорожки
OR A ; преобразуем в номер
; ЦИЛИНДРА
RRA ; и в СТОРОНУ диска
LD C,A ; скопируем номер цилиндра
; в 'C' для работы в ПЗУ
JR NC,UP_TREK ; был 'перенос'?,номер был
; четный ?
LD A,#2C ; если нечетный -
; готовность 'НИЗ'
JR FIND_TRK ; перейти на 'ПОИСК НУЖНОГО
; ТРЕКА'
UP_TREK LD A,#3C ; номер четный -
; готовность 'ВЕРХ'
FIND_TRK LD IX,#2F03 < #2F4D > ; адрес в ПЗУ;
; "ПОИСК"
; этот адрес является входом в середину процедуры
; #2EF0 < #2F3A > (смотри приложение к главе)
CALL TRDOS ; найти нужный цилиндр и
; прижать к нужной стороне
; диска
POP DE ; извлечь номер дорожки,
; сектора
POP BC ; и длину блока
N_SECTOR PUSH BC ; спрятать
; (здесь уже в процессе
PUSH DE ; загрузки будут текущие
; номера
; дорожек и секторов)
LD IX,#2ED1 < #2F1B > ; загрузить сектор
; с номером
; из 'E', в адрес по 'HL'
CALL TRDOS ; исполнить
POP DE ; извлечь номер ДОРОЖКИ
; и СЕКТОРА
; уже загруженного
INC H ; увеличим адрес буфера
; ОЗУ на 1 сектор,
; т.е. поднимем на 256
INC E ; увеличим номер сектора
BIT 4,E ; все сектора на дорожке ?
JR Z, ALL_SEC ; НЕТ- продолжаем загрузку
LD E,00 ; ДА - обнулим номер
; сектора
INC D ; увеличим номер ДОРОЖКИ
POP BC ; посмотрим оставшуюся
; длину
DJNZ TREK ; уменьшим ее на 256
; (на 1 сектор)
; вернемся, если не все
; загружено
RET ; загрузили все что нужно
; выход
;---------------------
ALL_SEK POP BC ; посмотрим оставшуюся
; длину
DJNZ N_SECTOR ; уменьшим ее на 256
; (на 1 сектор)
; згружаем с дорожки
; дальше, если еще не все
RET ; загрузили все что нужно -
; выходим
;---------------------
TRDOS PUSH IX ; адрес на исполнение
; процедуры ПЗУ ТРДОС
JP #3D2F ; вызвать процедуру косвенно
; по адресу из стека
;----------------------------------------------------
2
Данная программа не нуждает-
ся ни в каких системных перемен-
ных и может работать даже в эк-
ранной области. Ею можно загру-
жать как головную часть програм-
мы, так и подгружать последующие
уровни. Единственный недостаток
такого загрузчика - это то, что
все файлы на диске, в каталоге,
должны иметь свою РЕАЛЬНУЮ длину
и адрес загрузки. Если вам это
почему-то не подходит (например,
вы хотите защитить свои програм-
мы), то, добавив в программу еще
несколько команд и применив ме-
тод шифрования длины и адреса
файла во время их создания, мож-
но решить и эту проблему. Но это
разговор для отдельной главы.
Как мы видим, большую часть
места в программе занимает поиск
файла на диске и определение его
атрибутов (длины, старта, номера
дорожки и номера сектора).
Программу можно существенно
сократить, если все это опреде-
лять изначально, когда идет пер-
воначальная загрузка из БЕЙСИКа.
Пока память свободна и область
системных переменных ТРДОС не
перекрыта кодами. Это удобнее
сделать Функциями ДОС, а данные
о файлах передать потом в основ-
ную программу, сохранив их до
поры до времени в свободном мес-
те памяти.
Пример 2
Рассмотрим как раз тот слу-
чай, когда данные о файле (кото-
рый должен подгружаться как пос-
ледующий уровень игры или как
состояние этой игры) переданы в
программу во время ее загрузки.
140.
; * загрузчик * используем подпрограмму
; ТРДОС #3F00 < #3F0A >
; програма стартует с метки START
; данные о файле лежат в адресах ОЗУ
; Номер сектора и номер дорожки - по адресу
; 'ATRIBUT'
; длина файла по адресу 'DLINN'
; адрес загрузки по адресу 'ADR_LO'
;-----------------
ATRIBUT NOP ; сюда передать Номер Сектора
NOP ; сюда передать Номер Дорожки
DLIN NOP ; сюда передать Длину загрузки
NOP
ADR_LO NOP ; сюда передать адрес загрузки
NOP
;-------подпрограмма вызова процедуры ДОС----------
TRDOS PUSH IX ; вызвать подпрограмму
; ТРДОС
JP #3D2F ; адресом из 'IX'
;--------------------------------------------------
;............... СТАРТ..............................
START LD BC,(ATRIBUT) ; возьмем номера дорожки и
; сектора
LD HL,(#5CFE) ; сохраним изменяемые ячейки
PUSH HL ; ОЗУ в системной области
LD HL,(#5D00)
PUSH HL
LD HL,(#5C00)
PUSH HL
LD A,0 ; в (#5C00) должен быть 0
LD (#5C00),0
LD A,C ; Номер сектора
LD C,B
LD (#5CFF),A ; занести N. сектора
PUSH BC ; сохраним N. дорожки
LD IX,#2EF0 < #2F3A > ; найдем дорожку на
CALL TRDOS ; диске
LD BC,00 ; задержимся
WAIT DJNZ WAIT ; и
DEC C ; подождем
JR NZ,WAIT
POP BC ; извлечем N. дорожки
LD IX,#2EF0 < #2F3A > ; так как головка у нас
; вышла на соответствующее место
CALL TRDOS ; то дав 'ПОИСК' этой же дорожки
; мы просто прижмем головку к
; диску и раскрутим диск
LD IX,#3F00 < #3F0A > ; диск крутится, головка
; прижата, теперь -
; команда чтение Сектора
LD HL,(ADR_LO) ; взять адрес Загрузки и
LD (#5D00),HL ; поместить для работы
CALL TRDOS ; считать Один Сектор с диска
; в адрес ОЗУ
............
и т. д. ; далее идут коды пересчета
; сколько осталось загружать,
; какие сектора и дорожки.
;-------------------------------------------------
2
Я думаю, продолжение этой
программы вы сможете дописать
сами (алгоритм можно взять из
предыдущего примера). Не забудь-
те только вернуть при выходе из
программы со стека все сохранен-
ные значения в область системных
переменных.
А теперь несколько слов о
ЗАПИСИ на диск. Если в вышепри-
веденных примерах вызов 'ЧТЕНИЕ
СЕКТОРА' заменить на 'ЗАПИСЬ В
СЕКТОР' и чуть-чуть переделать
программу, то у вас получится
готовая подпрограмма ЗАПИСИ в
фиксированный файл. (Смотри гла-
ву Функции ТРДОС, пример сохра-
нения состояния игры 'ЭЛИТА').
Вы из БЕЙСИКа создаете файл
нужной величины для последующей
записи в него информации из ра-
ботающей программы. Передаете
атрибуты этого файла во время
загрузки в тело программы, где у
вас расположена ваша подпрограм-
ма 'ЗАПИСИ'- и все.
Это самый легкий способ реше-
ния проблемы. Если же вы хотите
написать полную программу
'СОХРАНЕНИЕ', то правила записи
файла на диск остаются такими
же, как в главе 'ФУНКЦИИ ТРДОС'.
А той информации, что вы уже по-
черпнули - вполне хватит, чтобы
сделать это вполне профессио-
нально.
Теперь, когда мы узнали, как
записывать - считывать с диска и
как написать подпрограмму, кото-
рая это делает, поговорим о том,
где эту подпрограмму помещать в
переделываемой программе.
Немного об этом было сказано
в главе 'ФУНКЦИИ ТРДОС', но так
как мы уже вышли на уровень
программирования контроллера, то
у нас и возможностей появилось
больше.
Как встроить приличный
ПОЛНОЦЕННЫЙ 'загрузчик/сохрани-
тель' в программу, которая ис-
пользует ВСЮ ПАМЯТЬ компьютера,
если к тому же не хочется из
этой программы ничего выкиды-
вать, а также не хочется пор-
тить экран ??? Выход есть!
Этот медод может иметь мно-
жество различных вариантов, но
суть одна: в переделываемой
программе встраивают лишь ма-
ленькую подпрограмму-загрузчик
(всего лишь несколько байт), ко-
торая предназначена сохранять
часть ОЗУ с адреса #5C00 до ад-
реса, к примеру, #5FFF (4 сек-
тора нам, надеюсь, хватит) в
фиксированный файл, а на это
место загружать из другого фик-
сированного файла копию - образ
области СИСТЕМНЫХ переменных и
ОСНОВНОЙ загрузчик, который и
будет выполнять главную работу
по ЧТЕНИЮ/ЗАПИСИ.
После окончания работы основ-
ной загрузчик должен передать
управление на ту маленькую под-
программу, которая востановит
сохраненную область ОЗУ из пер-
вого файла на свое место.
Это называется ОВЕРЛЕЙНОЙ
ЗАГРУЗКОЙ или 'вытаскиванием са-
мого себя за волосы'. Вы рас-
сматриваете дисковое простран-
ство как область дополнительной
памяти с жестко заданными адре-
сами и перекачиваете в нее или
из нее то, что нужно вам на дан-
ный момент. Поэтапно это может
выглядеть приблизительно так:
Создаем командами БЕЙСИКА два
файла типа CODE.
> RANDOMIZE USR 15619:REM:SAVE
"BUFFER"CODE любой адрес,1024
Это файл для сохранения об-
ласти ОЗУ из тела переделывае-
мой программы в процессе ее ра-
боты.
> RANDOMIZE USR 15619:REM:
SAVE"SYSBOOT"CODE 23552,1024
Это файл с образом системных
переменных и с основной подпрог-
раммой работы с диском.
Выбираем в переделываемой
программе область для размеще-
ния вспомогательного загрузчика
и вписываем его коды на это мес-
то.
В файле 'SYSBOOT' после копии
всей области системных перемен-
ных и области буфера вписываем
нашу основную подпрограмму рабо-
ты с диском.
Теперь в процессе старта пе-
ределываемой программы мы дол-
жны передать в область вспомога-
тельного загрузчика всего 4 па-
раметра:
- номер первого сектора файла
"BUFFER",
- номер первой дорожки этого
файла,
- номер первого сектора файла
"SYSBOOT",
- номер первой дорожки этого
файла.
Длину передавать не надо, так
как она известна изначально.
Во время работы переделывае-
мой программы, если она выходит
на процесс загрузки или сохране-
ния, запустится вспомогательный
загрузчик, который сначала сох-
ранит область ОЗУ с адреса #5C00
по #5FFF в файле "BUFFER", а за-
тем на это место в ОЗУ загрузит
из файла "SYSBOOT" копию облас-
ти системных переменных и
ОСНОВНУЮ подпрограмму работы с
диском и передаст ей управление.
Так как все системные пере-
менные и ТРДОС и SOS востановят-
ся, основная подпрограмма может
работать с диском через любые
ФУНКЦИИ ТРДОС. А это значит, что
у вас отпали все проблемы с
поиском нужного файла на диске и
с пересчетом номеров дорожек и
секторов - при считывании с дис-
ка, а при записи - проблема за-
писи информации о файле в ката-
лог и в 8-й системный сектор!
Не забудьте, в регистре IY у
вас должено быть значение #5C3A,
и установлено прерывание 1. А
также - переустановите стек, ес-
ли он был настроен на ту об-
ласть, которая сохраняется на
диске.
После завершения своей рабо-
ты основная подпрограмма должна
передать управление опять во
вспомогательный загрузчик, кото-
рый востановит из файла "BUFFER"
всю область программы, сохранен-
ную на диске, на старое место в
ОЗУ.
Единственное неудобство в та-
ком методе - это необходимость
иметь ко всем прочим файлам
программы еще и 2 наших файла.
Можно отказаться и от файлов,
если поместить буфер сохранения
и основную подпрограмму работы с
диском в конкретные сектора, на
конкретной дорожке диска. Напри-
мер, можно использовать пустую-
щие сектора на НУЛЕВОЙ дорожке.
Вспомним, что каталог у нас на
первых семи секторах, системный
сектор - восьмой, а остальные
сектора свободны и системой не
используются (их использует под-
программа ПЗУ ТРДОС во время
сохранения МАГИК-файла).
Если поступить таким образом,
то вы получите программу, кото-
рая будет работать только на
этом диске. С одной стороны, это
создаст проблемы при копирова-
нии вами этой программы на дру-
гой диск. Необходимо будет копи-
ровать не толко файлы программы,
но и сектора НУЛЕВОЙ дорожки,
где у вас будет записана основ-
ная подпрограмма работы с дис-
ком.
А с другой стороны, модуль
работы с диском, записанный на
этих секторах, может использо-
вать сразу несколько программ, а
сами программы будут защищены от
несанкционированного копирова-
ния с вашего диска, так как заг-
рузочный модуль на НУЛЕВОЙ до-
рожке при попытке 'сдуть' у вас
программу останется нескопиро-
ванным.
Такой диск можно будет скопи-
ровать только целиком ТРЕКОВЫМ
КОПИРОВЩИКОМ.
А если пойти дальше и распо-
ложить сектора с нашей подпрог-
раммой на специально размечен-
ной дорожке с номером, например
161, о которой системе будет
просто неизвестно, то полноцен-
но скопировать этот диск не смо-
жет никакой копировщик. Но о за-
щите дисков мы поговорим немно-
го позднее.
А сейчас рассмотрим те аспек-
ты программирования контроллера,
которые до сих пор упоминались
лишь вскользь.
ФОРМАТИРОВАНИЕ
Процесс форматирования - это
запись некоторой специальной
последовательности кодов на выб-
ранный ЦИЛИНДР и сторону диска.
Наибольшее число цилиндров на
диске зависит прежде всего от
дисковода, так как у одних дис-
ководов ограничитель хода голо-
вок стоит на 80, а у других он
может стоять на 86 (ограничитель
чисто механический).
ТРДОС форматирует диск на 80
цилиндров, записывая в 8-м сек-
торе 0 дорожки информацию-сигна-
нализатор - какой это диск и
сколько свободных секторов на
диске.
Процедура для форматирования
одной дорожки находится в ПЗУ по
адресу #1FC1 <#1FFD>. Перед этим
головки должны быть выведены на
нужный цилиндр и прижаты к вер-
хней (четной) или нижней (нечет-
ной) стороне диска. Затем по-
дается команда 'ЗАПИСЬ ДОРОЖКИ'-
#F4.
Форматирование происходит
следующей последовательностью
байтов (эти байты подаются в
порт #7F в подпрограмме по адре-
су #2075 <#20B1>).
Для наглядности приводим таб-
лицу - что подается для записи
на диск и что записывается на
диске, так как некоторые байты в
команде 'ЗАПИСЬ ДОРОЖКИ ' интер-
претируются микросхемой ВГ93,
как вложенные субкоманды.
ТАБЛИЦА МАССИВА ДЛЯ ОДНОГО СЕКТОРА
┌────────────────────────────────┬───────────────────┐
│ ЧТО ПОДАЕТСЯ В ПОРТ ДЛЯ ЗАПИСИ │ ЧТО ЗАПИСЫВАЕТСЯ │
├────────────────────────────────┴───────────────────┤
│ 10 байтов #4E ( нач. пробел ) │
├────────────────────────────────────────────────────┤
│ 12 байтов НОЛЕЙ │
├────────────────────────────────┬───────────────────┤
│ 3 раза код #F5 (инициализация │ код #A1, метка │
│ счетчика контр.суммы) │ начало I.A.M │
├────────────────────────────────┴───────────────────┤
│ код #FE (адресная индексная метка) │
├────────────────────────────────────────────────────┤
│ Байт НОМЕР ДОРОЖКИ │
│ (ВНИМАНИЕ!!! НОМЕР ДОРОЖКИ на диске ТРДОС записы- │
│ вает и на ВЕРХНЕЙ и на НИЖНЕЙ стороне диска с ОДИ- │
│ НАКОВЫМ номером - НОМЕРОМ ЦИЛИНДРА. Определение, │
│ какая дорожка из 160 где находится, происходит │
│ чисто программным путем). │
├────────────────────────────────────────────────────┤
│ Байт СТОРОНЫ диска │
│ (ВНИМАНИЕ!!! ТРДОС и верхнюю и нижнюю сторону │
│ диска метит байтом 0, определение, какая сторона │
│ диска принадлежит какой из 160 дорожек, происходит │
│ чисто программным путем). │
├────────────────────────────────────────────────────┤
│ Байт НОМЕР СЕКТОРА ( отсчет с 1 до 16) │
├────────────────────────────────────────────────────┤
│ Байт РАЗМЕР СЕКТОРА ( в ТРДОС = 1 ,т.е. 256 байт) │
├────────────────────────────────┬───────────────────┤
│ Байт #F7 (субкоманда - │ Два байта │
│ записать подсчитанную к.сумму) │ конрольной суммы │
├────────────────────────────────┴───────────────────┤
│ 22 байта #4E ( пробел перед данными) │
├────────────────────────────────────────────────────┤
│ 12 байтов НОЛЕЙ │
├────────────────────────────────┬───────────────────┤
│ 3 раза код #F5 (инициализация │ код #A1, начало │
│ счетчика контр.суммы) │ метки данных │
├────────────────────────────────┴───────────────────┤
│ код #FB (адресная метка данных) │
├────────────────────────────────────────────────────┤
│ 256 НОЛЕЙ │
│ (это поле данных) │
├────────────────────────────────┬───────────────────┤
│ Байт #F7 (субкоманда - │ Два байта │
│ записать подсчитанную к.сумму │ контрольной суммы │
├────────────────────────────────┴───────────────────┤
│ 50 байтов #4E ( остаточный пробел) │
└────────────────────────────────────────────────────┘
После того, как все 16 секто-
ров на дорожке размечены, остав-
шееся место дорожки заполняется
кодом #4E.
Этот массив форматирования
предназначен для дисководов
двойной плотности. Для дисково-
дов одинарной плотности он бу-
дет другой.
Для дисководов двойной плот-
ности (режим Модифицированной
Частотной модуляции ) в процес-
се выполнения команды "ЗАПИСЬ
ДОРОЖКИ" микросхема восприни-
мает и рассматривает как субко-
манды следующие байты:
байт #F5 - запись кода #A1 и за-
пуск счетчика кон-
трольной суммы;
байт #F6 - запись кода C2;
байт #F7 - запись подсчитанной
контрольной суммы на
диск.
В процессе программирования у
вас может возникнуть желание от-
форматировать отдельные дорожки
на диске по-другому. Например, в
процессе создания защищенных
дисков или для скрытого загруз-
чика. Нет проблем!
Вы можете отформатировать,
например, 163-ю дорожку на своем
диске всего с одним сектором
длиною в 1024 байта и с систем-
ным номером 223, и об этом бу-
дет знать только ваша программа,
работающая с этой дорожкой, и вы
сами.
При попытке кого-либо друго-
го прочитать вашу секретную до-
рожку и сектор, скорее всего,
его постигнет неудача, так как
этот кто-то не будет знать сис-
темного номера этого сектора.
Микросхема ВГ93 его просто не
найдет на дорожке, не говоря уж
о попытке прочитать его содержи-
мое.
(Когда вы прочтете эту книгу
до конца и затратите определен-
ные усилия, вы сможете без тру-
да копировать любые подобные
диски с любой ЛОГИЧЕСКОЙ
ЗАЩИТОЙ).
Форматирование дорожки можно
выполнить и через другую под-
программу ТРДОС, а именно #3FC0
<#3FCA> (см.выше). Сформировав в
области ОЗУ весь массив дорожки,
каким он должен быть на диске,
можно одним махом записать ин-
формацию из ОЗУ в диск на дорож-
ку, и таким образом отформатиро-
вать ее.
Посчитаем из таблицы, сколько
байтов в ОЗУ займет у нас весь
массив:
376 байт - это на одном
секторе и 376*16= 6016 байт на
всей дорожке (плюс довесок,
приблизительно в 200 байт).
При форматировании дорожки
своими форматами вы должны учи-
тывать это, и длина всего масси-
ва вашего формата не должна пре-
вышать эту цифру. Лишняя инфор-
мация просто не запишется на до-
рожку.
ОПРЕДЕЛЕНИЕ РАЗМЕТКИ ДИСКА
В некоторых случаях вам мо-
жет потребоваться определить,
как размечен тот или иной диск
(например, для 'вскрытия' защи-
щенных дисков или дисков, разме-
ченных нестандартно). В системе
команд ВГ93 есть команда: 'ЧТЕ-
НИЕ АДРЕСА', но она предназначе-
на для нормально размеченных
дисков, т.е. без всяких выкрута-
сов.
С ее помощью можно читать ин-
дексную адресную метку и ТРДОС-
овских, и MSDOS-овских дисков, и
CP/M дисков, но если вы попытае-
тесь прочитать индексно-адресную
метку на диске, где на одной до-
рожке существуют сектора с раз-
ной длиной и с номерами, взятыми
с потолка - то вы прочитаете
метку одного сектора, но узнать,
какие сектора, сколько их и ка-
кие у них номера, вы вряд ли
сможете. Для этого существует
'хитрый' способ.
Вспомним. У нас в резерве
осталась команда ВГ93 'ЧТЕНИЕ
ДОРОЖКИ ЦЕЛИКОМ'. При этой ко-
манде микросхема читает с дорож-
ки все: и метки, и синхронизи-
рующие байты, и данные - в об-
щем, все, все, все. Единственный
недостаток этой команды - это
то, что при чтении информации с
диска читаемые байты не строби-
руются. Но это нам не помешает.
Итак! Представим, к вам попал
диск с подозрительной разметкой.
Выводите головки дисковода на
какую-нибудь дорожку (обычно на
нулевую ), прижимаете головки к
поверхности, даете команду 'ЧТЕ-
НИЕ ДОРОЖКИ' и выходите на под-
программу ТРДОС #3FDB <#3FE5> -
чтение массива из порта Данных в
адрес M (HL) (естественно, перед
этим вы должны зарезервировать
буфер для считываемых данных,
размером приблизительно 6300
байта, можно даже на экране).
Повторите эту процедуру чте-
ния раза 2-3 подряд для более
надежного считывания, т.к. бай-
ты не сопровождаются синхросиг-
налом. И вот у вас в буфере ока-
жется массив данных целой дорож-
ки со всеми служебными метками.
А дальше совсем просто.
Вспомним, с каких байтов на-
чинается I.A.M. - индексно-ад-
ресная метка. Правильно - с бай-
тов #A1 и #FE (кто не вспомнил -
смотри предыдущую таблицу масси-
ва форматирования). (Для дисков
с ОДИНАРНОЙ плотностью байт пе-
ред кодом #FE будет другой (мо-
жет быть и 00, и #C9, и #FF - в
зависимости от изначального мас-
сива форматирования).
Находим эти байты в буфере, а
после них, пожалуйста, все дан-
ные одного сектора: номер дорож-
ки, сторона, номер и длина сек-
тора. Запомним эти данные в ка-
ких-нибудь ячейках ОЗУ. Ищем
следующие два байта #A1 и #FE; и
так, пока весь буфер не кончит-
ся. После этого у нас окажутся
на руках все козыри, какой бы ни
был хитроумный формат на дорож-
ке. Просканировав весь диск, мы
получим карту формата всех доро-
жек и секторов. Но обычно бы-
вает достаточно просканировать
2-4 дорожки.
Продолжение следует