Teledisk: различия между версиями
Panther (обсуждение | вклад) (→Источники и ссылки: new links) |
Xolod (обсуждение | вклад) |
||
| Строка 181: | Строка 181: | ||
== Программы == | == Программы == | ||
* {{zip | * {{zip||Библиотека для работы с форматом Teledisk|software/dsklib/teledisk.0.1.1.zip}} (Pascal/Delphi, исходные коды, пример использования) | ||
* {{zip | * {{zip||Программа Teledisk разных версий|software/dsklib/teledisk-all.zip}} (MS-DOS/Win 9x/Me, в NT/XP/Vista не работает) | ||
[[Категория:Форматы файлов]] | [[Категория:Форматы файлов]] | ||
Текущая версия от 11:49, 21 сентября 2023
| Этот документ создан для Emuverse и распространяется на условиях лицензии CC-BY-SA-3.0. |
Teledisk — формат файлов, содержащий посекторную копию дискеты. Создавался с помощью одноименной утилиты. Внутри файла находятся данные, упакованные по принципу RLE (RLE+LZSS в режиме «Advanced compression»).
Описание формата
Формат файла следующий:
Заголовок Данные
Формат заголовка:
type
TTDHeader = packed record
sig: array [0..1] of Char; //Сигнатура "TD" или "td"
vol: Byte; //Номер тома. 0 для TD0
chk: Byte; //Сигнатура, одинаковая для всех томов
ver: Byte; //Для версий 2.11-2.16 равно 15H
dens: Byte; //Плотность записи. Обычно 0.
typ: Byte; //Тип устройства. 1=360K, 2=1.2M,
//3=720K, 4=1.44M.
flag: Byte; //Старший бит - наличие комментария
dos: Byte; //DOS mode? Обычно 00H
sides: Byte; //Кол-во сторон
crc: Word; //CRC первых 10 байт записи
end;
Если сигнатура равна «TD», за заголовком следуют данные без упаковки LZSS, иначе они упакованы, и требуется распаковка. Далее распакованные данные обрабатываются аналогично формату без компрессии.
Формат данных (отступы сделаны для удобства):
Комментарий (если TTDHeader.flag > 80H)
Заголовок дорожки 0
Заголовок сектора 1
Данные сектора 1
Заголовок сектора 2
Данные сектора 2
..........
Заголовок сектора N
Данные сектора N
Заголовок дорожки 1
..........
Заголовок дорожки M
..........
Общее количество секторов и дорожек может быть получено только после обработки всего файла, в общем заголовке этих данных нет.
Формат комментария:
Заголовок комментария Данные комментария (текст)
Формат заголовка комментария:
TTDComment = packed record crc: Word; //Контрольная сумма комментария len: Word; //Длина комментария в байтах yr, mon, day, //Дата. Год отсчитывается от 1990. hr, min, sec: Byte; end;
Данные комментария представляют собой строки, оканчивающиеся #0. Строк может быть несколько.
Формат заголовка дорожки:
TTDTrack = packed record
nsec: Byte; //Кол-во последующих записей секторов.
//Часть записей должна игнорироваться
trk: Byte; //Номер дорожки
head: Byte; //Номер стороны
crc: Byte; //Контрольная сумма заголовка
end;
Количество секторов может не совпадать с реальным, так как назначение части записей пока не установлено, они должны игнорироваться.
Заголовок сектора:
TTDSector = packed record trk: Byte; //Номер дорожки; head: Byte; //Номер стороны; sec: Byte; //Номер сектора; secz: Byte; //Код размера сектора; cntrl: Byte; //Тип данных; crc: Byte; //Контрольная сумма распакованных данных end;
TDSector.sec=$65 обозначает, что достигнут конец файла, остаток данных нужно пропустить.
Если TDSector.sec > TDTrack.nsec, последующие данные сектора должны быть проигнорированы.
Вычисление размера сектора в байтах: SectSize := 1 shl (TDSector.secz+7);
Данные относятся к реальному сектору, если выполняется следующее условие: ((TDSector.cntrl and $30) = 0) and ((TDSector.secz and $F8) = 0), иначе данные нужно игнорировать.
Если TDSector.cntrl=$10, то сектор содержит пустые данные (возможно, не был прочитан корректно), нужно переходить к чтению заголовка следующего сектора.
Формат блока данных сектора (если сектор непустой):
Длина блока (2 байта) Тип блока (1 байт) Данные блока
Если Тип блока=0, то «данные блока» представляют собой содержание сектора в неупакованном формате, при этом «длина блока» должна совпадать с размером сектора плюс один байт для поля "Тип блока".
Если Тип блока=1, то «данные блока» представляют собой следующую запись:
TTDRepeat = packed record count: Word; //Количество повторений pat: array [0..1] of Byte; //Данные для повторения (2 байта) end;
«Количество повторений» должно быть в два раза меньше размера сектора.
Если Тип блока=2, то «данные блока» представляют собой последовательность записей:
Заголовок записи Данные записи
Формат заголовка записи:
TTDPattern = packed record flag: Byte; count: Byte; end;
Если TDPattern.flag=0, то за заголовком следуют данные длиной TDPattern.count. Иначе, TDPattern.flag обозначает размер блока для повторения, следующий за заголовком, TDPattern.count — количество повторений. Размер блока в байтах вычисляется как PatSize := 1 shl TDPattern.flag;.
Обобщенный алгоритм
--------- основная процедура ---------
Чтение заголовка файла TDHeader
Если TDHeader.sig == ”td” то распаковка данных
Если TDHeader.sig != ”TD” то выход с ошибкой «неправильный формат»
Если TDHeader.flag & 80H > 0 то
Чтение заголовка комментария
Чтение блока данных комментария
Пока не конец данных
Чтение заголовка дорожки TDTrack
Если TDTrack.nsec == 0FFH то окончание работы
Для секторов от 1 до TDTrack.nsec
Чтение заголовка сектора TDSector
Если TDSector.sec == 65H то окончание работы
SectSize := 1 shl (TDSector.secz+7);
Если ((TDSector.cntrl & 30H) == 0) && ((TDSector.secz & 0F8H) == 0) то
Если TDSector.cntrl == 10H то
сектор пустой, переход к следующему
Иначе
Чтение 2-х байт «Длина данных»
Если TDSector.sec <= TDTrack.nsec то
Распаковка_данных(Длина данных)
Иначе
Пропускаем «Длина данных» из входного потока
--------- подпрограмма ---------
Процедура Распаковка_данных(Длина данных)
Чтение 1 байта «Тип блока»
Если «Тип блока» == 0 то
Читаем «Длина данных»-1 в качестве данных сектора
Иначе
Если «Тип блока» == 1 то
Читаем запись TDRepeat
Помещаем в буфер сектора TDRepeat.count повторений TDRepeat.pat
Иначе
Если «Тип блока» == 2 то
Пока не достигнута «Длина данных»-1
Читаем запись TDPattern
Если TDPattern.flag == 0 то
Читаем TDPattern.count байт и помещаем их в буфер сектора
Иначе
PatSize := 1 shl TDPattern.flag;
Читаем «PatSize» данных из входного потока
Пишем эти данные TDPattern.count раз в буфер сектора
Источники и ссылки
Программы
Библиотека для работы с форматом Teledisk (Pascal/Delphi, исходные коды, пример использования)
Программа Teledisk разных версий (MS-DOS/Win 9x/Me, в NT/XP/Vista не работает)