                 Формат файла UDI ( Ultra Disk Image )
                 Версия 1.0 (Alex Makeev, Редакция 24 марта 2002 г.)
                 Версия 2 (deathsoft, согласовано с Alex Makeev)

--------------------------------------------------------------------------------
                           Формат файла UDI:

Offset          Length  Comment
----------      ------  ----------------------------------------------------
0x00000000      0x0004  Идентификатор "UDI!", если идентификатор
                           записан маленькими буквами ("udi!"), то 
                           применено сжатие данных, алгоритм сжатия
                           пока не определен, но вероятно будет аналогичен 
                           TELEDISK'у
                           Упаковываются данные, начиная с образа первой 
                           дорожки, т.е. сразу после основного 
                           (и дополнительных) заголовка
0x00000004      0x0004  Размер файла после распаковки без учета CRC 
                           (если файл не упакован, то просто размер файла - 4)
0x00000008      0x0001  Версия формата, для UDI 1.0 содержит #00,
                        для UDI 2 содержит #01
0x00000009      0x0001  Максимально доступный цилиндр (0x00...0xFF),
                           итого макс. число цилиндров = 256
0x0000000A      0x0001  Максимальный номер поверхности диска:
                           0x01 - DoubleSided, 0x00 - SingleSided
                           (0x02..0xFF -reserved!)
0x0000000B      0x0001  В этой версии не используется поэтому всегда 0x00
0x0000000C      0x0004  EXTHDL - Длина дополнительного заголовка 
                           (всегда 0, в противном случае структура данных
                           может быть другая...)


Далее следуют образы каждой из дорожек, в порядке размещения на диске
(Trk00, Side00; Trk00, Side01; Trk01, Side00; Trk01, Side01; ...):

0x00000010      0xXXXX  Образ дорожки см. ниже...
0xXXXXXXXX      0xXXXX  Образ следующей дорожки
0xXXXXXXXX      0xXXXX  Образ следующей дорожки
...
...
0xXXXXXXXX      0x0004  CRC файла (для версии 1.0 CRC_UDI, алгоритм см. приложение 1)
                                  (для версии 2 CRC32 (правильный), алгоритм см. приложение 2)


Образ дорожки:

Offset          Length     Comment
----------      ------  ----------------------------------------------------
0x00000000      0x0001  Определяет формат дорожки:
                              0x00 - Decoded MFM  (например TR-DOS-ный формат)
                              0x01 - аналогичен 0x00 но с поддержкой областей запись/чтение
                                     в которые дает ошибки
                              0x02 - RAW MFM (биты в том виде в котором они читаются с дискеты без
                                     декодирования контроллером). Дорожка DD дискеты содержит
                                     ~50000бит
                              другие значения форматов пока запрещены!
                              (т.к. еще не известно сколько доп. инфы
                               нужно хранить)


***Для формата дорожки 0x00 (Decoded MFM):


0x00000001      0x0002  tlen - Длина дорожки в байтах (типичная длина
                           дорожки 6250 байт)
                           ВНИМАНИЕ! Для MFM DoubleDensity (ВГ93) крайне
                           не рекомендуется задавать длину
                           дорожки, сильно отличающуюся от 6250 байт!!!
0x00000003      tlen    Побайтовый образ дорожки - включая пробелы,
                           синхропробелы, синхроимпульсы (маркеры MFM), 
                           адресные маркеры, заголовки, массивы данных, etc.
                           Другими словами здесь записаны те байты,
                           которые будут выданы ВГ93 по команде "чтение дорожки"

0x0003+tlen     сtlen   Битовый массив, описывающий тип CLK для каждого
                           байта образа дорожки (см. приложение 1);
                           Один бит соответствует одному байту образа дорожки:
                              0 - записано с обычным CLK (обычные данные)
                              1 - записано с маркерным CLK (метки #A1 и #C2)
                           Например имеем последовательность байт:
                              { 0xA1,0xA1,0x00,0xA1,0xFE,0x00,0x00,0x01 }
                              где 0xA1 - MFM маркеры
                           тогда байт битового массива будет равен 0x0B.

                           Для типичной длины дорожки 6250 байт:
                           ctlen = tlen/8 + ((tlen-(tlen/8)*8)? 1:0) = 782 байт
                           Лишние биты - незначащие, их рекомендуется
                           заполнять нулями.

                           Программы, создающие/записывающие UDI файлы обязаны
                           обеспечивать присутствие реальных CRC кодов для 
                           массивов данных и адресных массивов по алгоритму 
                           CRC с полиномом F = X^16 + X^12 + X^5 + 1

                           Симуляцию ошибочного CRC синтетическим способом,
                           при конвертировании из файлов FDI, рекомендуется
                           производить с помощью выражения C = RC^0xFFFF,
                           где C - crc которую нужно записать, RC - crc
                           синтетическая, корректно вычисленная по 
                           алгоритму CRC...   это чтоб накладок не выходило,
                           запишешь bad CRC равный нулю или еще чему-нибудь,
                           глядишь, а он и впрямь окажется равным нулю -
                           получается реально bad'овый CRC будет определятся
                           как безошибочный 

***Для формата дорожки 0x01 (Decoded MFM со сбойными участками):
(пока не реализовано)

***Для формата дорожки 0x02 (RAW MFM):
(пока не реализовано)

***Для других форматов дорожки:

#0001+tlen      4       MTIL - Длина блока, описывающего дорожку

#0005+tlen      MTIL     Блок описывающий формат дорожки

--------------------------------------------------------------------------------


Почему типичная длина дорожки 6250 байт?
Изучив процедуру форматирования у TR-DOS и утилиты FUT я выяснил, что
реальная длина (она естественно зависит от аппаратуры) должна лежать в 
диапазоне 6208...6464 байт, для других длин произойдет ошибка. Однако, 
просчитав timing, учитывая что на один бит информации уходит 4мкс - получаем 
время 32мкс на байт; время одного полного оборота диска известно - 200000 мкс; 
далее просто считаем длину дорожки: 200000 / 32 = 6250 байт.


   Вниманию разработчикам эмуляторов: большая просьба - своих корректив в
формат UDI без согласования с автором не вносить.

-------------------------------------------------------------------------------

                            ПРИЛОЖЕНИЕ 1

                Алгоритм вычисления CRC_UDI для файла UDI(версии 1.0)
{deathsoft, реально это не алгоритм CRC32, а ошибочная реализация CRC32 дающая совершенно другие результаты }


Начальное значение CRC = 0xFFFFFFFF  (-1l).

Функция обновления CRC32 для одного байта Symbol:

long CalcCRC32(long CRC, unsigned char Symbol)
{
   long temp;
   CRC ^= -1l ^ Symbol;
   for(int k = 8; k--;) 
      { temp = -(CRC & 1), CRC >>= 1, CRC ^= 0xEDB88320ul & temp; }
   CRC ^= -1l;
   return CRC;
}

Эту функцию нужно вызвать для каждого байта из файла UDI (исключая последние
4 байта CRC). 

Первый аргумент функции - текущая CRC, второй аргумент - байт данных,
результат - новая CRC.

-------------------------------------------------------------------------------

                            ПРИЛОЖЕНИЕ 2

              Алгоритм вычисления CRC32 (UDI 2 и выше)
static uint32_t crc32(const void *data, unsigned len)
{
   const uint8_t *d = (const uint8_t *)data;

   uint32_t crc = 0xFFFFFFFF;
   while(len--)
   {
      uint32_t byte = *d++;
      crc ^= byte;
      for(int j = 7; j >= 0; j--)
      {
         uint32_t mask = -(crc & 1);
         crc = (crc >> 1) ^ (0xEDB88320 & mask);
      }
   }
   return ~crc;
}

crc32("The quick brown fox jumps over the lazy dog") == 0x414FA339
-------------------------------------------------------------------------------
