Структура MS-DOS диска.
(C)1997 Digital Man.
Special for ZX POWER.
________________________________
Сразу скажу, что данный мате-
риал предназначаеться для тех
людей, которые уже набили пару
шишек об формат дисков системы
MS-DOS.Итак все диски MS-DOS ор-
ганизованы одинаковым образом.
Размер сектора всегда 512 байт,
все остальное определяет емкость
диска :
┌─────────┬─────────┬──────────┐
│ Емкость │ Трэки │ Сектора │
├─────────┼─────────┼──────────┤
│ 320 kb │ 40 │ 8 │
│ 360 kb │ 40 │ 9 │
│ 720 kb │ 80 │ 9 │
└─────────┴─────────┴──────────┘
В отличии от TR-DOS диска на
дисках MS-DOS'а используется
специальная таблица размещения
файлов (File Alloction Table -
FAT) для отведения дискового
пространства файлам и хранения
информации о свободных секторах.
Из соображения безопасности на
всех дисках хранятся по две ко-
пии FAT. Они хранятся последова-
тельно, начиная со стороны 0,
трека 0, сектора 1 (сектор 0 за-
нят записью начальной загрузки).
Число секторов отведенных под
FAT определяеться размером дис-
ка (далее в тексте есть таблица
при помощи которой можно опреде-
лить рамер FAT). Существуют так-
же два типа построения FAT,
12-битовая FAT или 16-битовая
FAT. Здесь мы рассмотрим только
12-битовые записи. Т.к. 16-бито-
вая FAT используеться для фикси-
рованых дисков AT т.к. у них
кластеров больше чем 4096.
FAT хранит информацию о каж-
дом кластере секторов на диске.
Кластер - это группа стандартных
секторов обедененых головками
чтения/записи, и т.к. у дисково-
дов рамером 5'25 inch всего две
головки то размер кластера ра-
вен двум секторам (исключения
составляют одностороние дисково-
ды, которые иногда встречаются
на компьютерах). Пример разме-
шения FAT на диске размером
720 kb:
┌──────────────────────────────┐
│0 Сектор начальной загрузки │
├──────────────────────────────┤
│1-6 Таблица размешения файлов │
├──────────────────────────────┤
│7-9 Корневой каталог │
└──────────────────────────────┘
Примечание: необходимо пом-
нить, что FAT хранится на диске
в двух копиях!!!
Каждая позиция в таблице раз-
мещения файлов соответствует оп-
ределенной позицию кластера на
диске. Обычно файл занимает нес-
колько кластеров и запись в ка-
талоге содержит номер стартово-
го кластера, в котором хра-
ниться кусочек файла. Затем по
смещению стартового кластера из
FAT берется номер следуюшего
кластера, который в свою оче-
редь содержит номер следующего
кластера в цепочке (рис.1). Для
последнего кластера, занятого
файлом, FAT содержит значения от
#FF8 до #FFF. Свободным класте-
рам соотвествует значение #000,
а дефектным секторам #FF7. Зна-
чениоя от #FF0 до #FF7 приписы-
вают резервным кластерам.
Номер кластера содержит 3 шес-
тнадцатиричные цифры, для хране-
ния которых необходимо 1 1/2
байта. Для уменьшения размеров
FAT числа для двух соседних
кластеров хранятся в трех после-
довательных байтах таблицы.
Первые три байта FAT не ис-
пользуются для номеров класте-
ров. Первый байт содержит тип
диска,а следующие два байта рав-
ны #FF.Поскольку эти позиции за-
няты, то кластеры нумеруются,
начиная с 2, причем кластера 2 и
3 занимают вторую тройку байтов
таблицы.
┌────┬─────────────────────────┐
│Код │ Тип диска │
├────┼─────────────────────────┤
│#FF │двухсторонний, 8 секторов│
│#FE │односторонний, 8 секторов│
│#FD │двухсторонний, 9 секторов│
│#FC │односторонний, 9 секторов│
│#F9 │двухсторонний,15 секторов│
└────┴─────────────────────────┘
При работе с FAT надо соблю-
дать такие правила:
Для нахождения следуюшего
кластера файла:
1.Умножте номер кластера на 1,5.
2.Прочитайте 2 байта с получен-
ным смещением (округляя вниз).
3.Если номер кластера четный, то
возьмите младшие 12 бит, иначе
возьмите старшие 12 бит.
Для преобразования номера
кластера в физическую позицию на
диске необходимы следующие вы-
числения:
1.Умножте результат на число
секторов в кластере (обычно 2)
2.Результат поделите на число
секторов в треке,тем самым по-
лучите трек, а в остатке сек-
тор. Конечно проще,да и лучше,
все это сделать по таблице пе-
ресчета.
Теперь давайте рассмотрим
структуру каталога диска. Но для
начала чтобы определить с каким
именно диском мы работаем необ-
ходимо проанализировать 0 сек-
тор следующим образом:
┌───┬──────┬───────────────────┐
│См.│Длина │ Описание │
├───┼──────┼───────────────────┤
│#03│8байт │Тип системы │
│#0B│1слово│Кол-во байт в сект.│
│#0D│1байт │Секторов в кластере│
│#0E│1слово│Длина BOOT сектора │
│#10│1байт │Кол-во копий FAT │
│#11│1слово│Кол-во файлов │
│#13│1слово│Общее число сектор.│
│#15│1байт │ - │
│#16│1слово│Число секторов FAT │
│#18│1слово│Секторов в треке │
│#1A│1слово│Число сторон │
│#1C│1слово│Число скрытых сект.│
└───┴──────┴───────────────────┘
Сам каталог распологается сра-
зу за копией FAT. Запись в нем
делится на 8 частей:
┌───┬──────┬───────────────────┐
│См.│Длина │ Значение │
├───┼──────┼───────────────────┤
│#00│8 байт│ Имя файла │
│#08│3 байт│ Расширение │
│#0B│1 байт│ Атрибут │
│#0C│10байт│ Зарезервировано │
│#16│2 байт│ Время │
│#18│2 байт│ Дата │
│#1A│2 байт│ Нач.номер кластера│
│#1C│4 байт│ Размер файла │
└───┴──────┴───────────────────┘
Смещение #00 и #08:
Имя и расширение файла обычный
ASCII текст, который не требует
пояснения. Но при создании файла
или при его переименовании жела-
тельно не включать пробелы и
специальные символы, и оставшие-
ся место в записи имени и расши-
рения файла заполнять пробелами.
Смещение #0B:
Атрибут файла построен следую-
щим образом:
┌────────┬─────────────────────┐
│ Бит │ Значение │
│76543210│ │
├────────┼─────────────────────┤
│.......1│Файл только для чтен.│
│......1.│Скрытый файл │
│.....1..│Системный файл │
│....1...│Метка тома │
│...1....│Подкаталог │
│..1.....│Архивный файл │
│.1......│ - │
│1.......│ - │
└────────┴─────────────────────┘
Подкаталог (Директория) хра-
нится на диске как обычный файл.
Формат его записей идентичен
формату записей корневого ката-
лога. Только количество записей
в нем зависит от наличия свобод-
ного места на диске.
Смещение #0C:
Зарезервировано.
Смещение #16:
Время=(Часы*2048)+(Мин. *32)+
+ (Секунды + 2).
Смещение #18:
Дата = (Год - 1980) * 512) +
+ (Месяц * 32) + День.
Смещение #1A:
Стартовый кластер файла.
Смещение #1C:
Размер файла. В этой записи
помешено число без знака длиной
в 4 байта(старший байт идет пер-
вым). Таким образом файл может
иметь довольно большие размеры:
42946967295 байтов.
Пожалуй на этом можно и закон-
чить теорию и показать принцип
чтения файлов и декодировки FAT.
Чтение файла:
Запись Каталога
Имя Расширение Начальный
файла кластер
┌─────┬───┬────────┬────┬──────┐
│MUSIC│MOD│ │0003│ │
└─────┴───┴────────┴─┬──┴──────┘
┌───чтение────┘
│
│┌чтение┐┌──чтение──┐
││ ││ │
FAT
─┬───┬─┴┴┬───┬─┴┴┬───┬───┬─┴─┬──
│002│005│000│008│000│FF7│FFF│
─┴───┴───┴───┴───┴───┴───┴───┴──
2 3 4 5 6 7 8
Под чтение подрозумеваеться чте-
ние кластера с диска.
Декодировка FAT:
ORG #8000 ;начало #8000
LD HL,BUF ;загрузка FAT
LD B,4 ;в буфер
LD DE,1
CALL LOAD
LD DE,BUF
LD HL,3 ;в HL номер
PUSH HL ;кластера
LD B,H ;HL -> STEK
LD C,L ;HL -> BC
AND A ;BC/2
RR B
RR C
ADD HL,HL ;HL*2
ADD HL,BC ;HL+BC
ADD HL,DE ;HL+BUF
LD D,(HL) ;D <- (HL)
INC HL
LD E,(HL) ;E <- (HL+1)
POP HL
BIT 0,L ;проверка на
JR NZ,ODD ;четность и
LD A,#0F ;уход если да
AND H
LD H,A
JR CONT
ODD LD B,4 ;сдвигаем в
LOOP AND A ;право на
RR H ;одну 16-ю
RR L ;цифру
DJNZ LOOP ;в HL номер
CONT . ;следуюшего
. ;кластера
.
RET
LOAD PUSH HL ;чтение
PUSH BC ;секторов
LD C,5 ;диска MS-DOS
CALL #3D13 ;B-длина
POP BC ;HL-куда
POP HL ;DE-тр./сек.
INC H
LD A,E
CP 9 ;кол-во
JR C,NET ;секторов в
INC D ;треке
LD E,0
NET DJNZ LOAD
RET
BUF DEFS 4096 ;отводим
;место для
;4 секторов
Ну вот пожалуй и все! И еще
старайтесь после операций записи
файла, сначала проверить на пра-
вильность изменений FAT, а за-
тем перекопировать FAT в резерв.
________________________________