ZX Review
#5-6
04 ноября 1997 |
|
TR-DOS для начинающих - Продолжение.
┌─────────────────────────────┐ │ │ │ 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 дорожки. Продолжение следует
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября