Формат упакованных данных представляет собой жестокую смесь словарного и RLE методов. Все команды распаковщика (за исключенияем команды расширения) имеют один и тот же формат. Три старших бита каждой команды представляют собой непосредственно индекс команды, определяющий ее дальнейший формат. Младшие 5 бит всегда являются (независимо от типа команды) счетчиком байт. Счетчик может быть числом от 0 до 31, что дает возможность одной командой кодировать в выходной последовательности от 1 до 32 байт. За байтом команды следуют данные, в зависимости от команды имеющие разную длину. [000][00000] [...] | | | Код Счетчик Прочие данные Далее описаны все возможные варианты индексов команд. Все команды оперируют с последовательностями байтов, счетчик хранит количество обрабатываемых в команде байт. Выходной указатель всегда увеличивается и указывает всегда на конец распакованных данных. 1. Raw 0x0 - 0x1f Скопировать следующие за кодом байты в буфер. {обычный текст [000][xxxxx] [xxxxxxxx]...[xxxxxxxx] | | | | +---------------------+ | | Число байтов Указанное количество байт для копирования для копирования 2. Rle8 0x20 - 0x3F Заполнить буфер следующим за кодом байтом. {пустые поля [001][xxxxx] [xxxxxxxx] | | | | +--------+ | | Количество Указанный для повторений заполнения байт 3. Rle16 0x40 - 0x5F Заполнить буфер следующим за кодом словом. {the B Button, crisis [010][xxxxx] [xxxxxxxx][xxxxxxxx] | | | | +------------------+ | | Количество Указанное для повторений заполнения слово 4. RleAsc 0x60 - 0x7F Заполнить буфер арифметической прогрессией. Начальный байт следует за кодом, шаг всегда равняется единице. {Stuff ,defeat [011][xxxxx] [xxxxxxxx] | | | | +--------+ | | Количество Начальный байт прогрессии членов прогрессии 5. Lz 0x80 - 0x9F Скопировать часть уже распакованных данных по смещению от начала буфера (указатель источника копирования увеличивается). [100][xxxxx] [xxxxxxxx] [xxxxxxxx] | | | | | | +--------+ +--------+---+ | | | Количество байт Старший байт Младший байт для копирования смещения смещения 6. LzInv 0xA0 - 0xBF Скопировать часть уже распакованных данных по смещению от начала буфера, обращая в каждом байте порядок бит (указатель источника копирования увеличивается). [101][xxxxx] [xxxxxxxx] [xxxxxxxx] | | | | | | +--------+ +--------+---+ | | | Количество байт Старший байт Младший байт для копирования смещения смещения 7. LzRev 0xC0 - 0xDF Скопировать часть уже распакованных данных по смещению от начала буфера в обратном порядке (указатель источника копирования уменьшается). [110][xxxxx] [xxxxxxxx] [xxxxxxxx] | | | | | | +--------+ +--------+---+ | | | Количество байт Старший байт Младший байт для копирования смещения смещения 8. Ext 0xE0 - 0xFF Код расширения, указывает, что количество битов счетчика увеличено вдвое. [111][xxx][xx][xxxxxxxx] [xxxxxxxx]...[xxxxxxxx] - Прочие данные | | | | | | +--------+-----------------+ | +------------+ | Действительный | | код, аналогичный Старшие два бита | описанным выше нового счетчика Младшие биты счетчика Алгоритм распаковки: главный цикл начинается всегда выборкой очередного байта - команды кодировщика. По трем его старшим битам определяется дальнейшее ветвление: 0. Установка указателя источника на упакованные данные, установка указателя приемника на начало буфера в ОЗУ, сохранение в переменной адреса начала буфера в ОЗУ 1. Выборка байта-команды, если 0xFF - конец распаковки 2. Проверка на расширенный код (&0xE0), полученное число в любом случае записывается как код команды. Если код равен 0xE0, то переход на 2.1, иначе - 3 2.1. Вместо кода 0xE0, код команды берется из следующих трех бит байта и записывается в переменную кода команды 2.2. Оставшиеся два бита записываются в старший байт счетчика 2.3. Считывается следующий байт данных, записывается в младший байт счетчика 2.4. Переход на 4 3. Запись оставшихся пяти бит в младший байт переменной-счетчика 4. Увеличение переменной-счетчика на 1 5. Проверка старшего бита кода, если ноль, то 5.1, иначе - 6 5.1. Ветвление в зависимости от двух младших бит кода - 4 ветки: 5.1.00.1 Считать байт упакованных данных 5.1.00.2 Записать его в буфер 5.1.00.3 Увеличить указатель на упакованные данные и приемник, уменьшить счетчик, повторить 5.1.00.1 пока не ноль 5.1.01.1 Считать байт упакованных данных 5.1.01.2 Записать его в буфер 5.1.01.3 Увеличить указатель приемника, уменьшить счетчик, повторять 5.1.01.2 пока не ноль 5.1.10.1 Считать два байта упакованных данных 5.1.10.2 Записать их в буфер 5.1.10.3 Увеличить указатель приемника на два, уменьшить счетчик, повторять 5.1.10.2 пока не ноль 5.1.11.1 Считать байт упакованных данных 5.1.11.2 Записать его в буфер 5.1.11.3 Увеличть считанный байт на 1, увеличить указатель приемника, уменьшить счетчик, повторять 5.1.11.2 пока не ноль 6. Считывание двух следующих байт из упакованных данных. Сложение получившегося слова с сохраненным адресом начала буфера в ОЗУ. Результатом является адрес заданного участка уже раскодированных данных, находящихся в буфере 6.1. Ветвление в зависимости от двух младших бит кода - 3 ветки: 6.1.00.1 Считать байт по адресу источника в ОЗУ 6.1.00.2 Записать байт по адресу приемника 6.1.00.3 Увеличить указатель источника и приемника, уменьшить счетчик, повторить 6.1.00.1 пока не ноль 6.1.01.1 Считать байт по адресу источника в ОЗУ 6.1.01.2 Инвертировать в байте порядок бит 6.1.01.3 Записать байт по адресу приемника 6.1.01.4 Увеличить указатель источника и приемника, уменьшить счетчик, повторить 6.1.01.1 пока не ноль 6.1.10.1 Считать байт по адресу источника в ОЗУ 6.1.10.2 Записать байт по адресу приемника 6.1.10.3 Увеличить указатель приемника, уменьшить указатель источника, уменьшить счетчик, повторить 6.1.10.1 пока не ноль 7. Возврат на 1.