Inferno #05
30 апреля 2004
  Софт  

Sofтинка - обзор экранных упаковщиков для ZX Spectrum.


Программное обеспечение Описание Упаковщики и архиваторы

ASCLZPAK, MSP1.6, Lazy Pack
            ASC Screen Crusher
 

   Один из первых серьёзных экранных паке-
ров, ASCLZPAK  (1991)  определил  основные 
идеи структуры большинства последующих фо- 
 рматов и соответствующих им депакеров. 
   А  именно, хотя  данные  в файле пока и
лежат только байтами,но впервые реализова- 
на довольно оптимальная последовательность 
просмотра экрана - ломаными столбцами. При 
этом экран логически разбивается на 3 тре- 
ти и атрибуты,где атрибуты линейны,а трети 
состоят из столбцов байт. Этот способ даёт 
возможность сжатия незначительно хуже спо- 
соба с полными столбцами, зато здесь проще 
пересчёт линейной модели в реальный экран. 

   Познакомим  читателя  с  идеей линейной
модели ZX экрана.
   Заключается она в том,что каждому адре-
су на экране взаимно однозначно соответст-
вует  виртуальный адрес в линейной модели,
причём  последовательность адресов экрана,
порождаемая  порядком  просмотра (в данном
случае - ломаными  столбцами)  выглядит на
линейной модели последовательностью подряд
идущих виртуальных адресов. Т.е.при после-
довательном  переборе  виртуальных адресов
линейной модели - адреса на реальном экра-
не  будут перебираться ломаными столбцами.
Разумеется, для  этого  нужно использовать
процедуры  пересчета виртуальных адресов в
реальные.
   Как правило, начальные адреса реального
и  виртуального  экранов  совпадают, чтобы
адреса атрибутов не пересчитывались.
   Вот как выглядит пересчёт экранного ад-
реса  из  виртуального в реальный по ASC'у
(страшновато,но примите во внимание,что он
первый!):
────────────────────────────────────────── 
                LD A,H
                AND #58
                CP #58
                JR Z,atr
                LD C,A
                LD A,L
                AND 7
                OR C
                LD C,A
                ADD HL,HL
                ADD HL,HL
                LD A,H
                AND #1F
                LD H,A
                LD A,L
                AND #E0
                OR H
                LD L,A
                LD H,C
         atr 
────────────────────────────────────────── 
   Распаковщик  ASCLZPAK, согласно  тради-
ции,перемещаем и для этого настраивает три
пары  ячеек  программы  под текущий адрес.
Опасного использования стека нет.
   Перемещение  по экрану ведётся в реаль-
ных адресах, и для координации этого (нес-
тандартное  решение) применено 3 регистра-
счётчика:
 

   A' = 8·номер столбца + 3-номер трети;
   B' = строка внутри знакоместа;
  C' = номер ряда знакомест внутри трети.

   Упакованные данные располагаются непос-
редственно после программы.Формат простой:

 %0bbbbHHH,LLLLLLLL - ссылка  назад,  disp= 
 =HHHLLLLLLLL, puts=bbbb+3
%10000000 - конец файла 
 %10bbbbbb,байты -  bbbbbb  байт  взять  из 
 потока
 %11bbbbbb,байт - повторить  байт  bbbbbb+3 
  раз (можно повторить байт до 66 раз, т.е.
 больше, чем через ссылку)


        Maxsoft Screen Packer 1.6
 

   Упаковщик  Maxsoft  Screen  Packer  1.6
поддерживает 3 режима распаковки и в связи 
с этим 3 различных распаковщика: 
 

  1. Непосредственно  на  экран,  ломаными
 столбцами; 
   2. Через буфер ломаными столбцами;
  3. Непосредственно  на  экран в экранной
структуре. 

   Последний  вариант  наиболее  прост, но
имеет,что понятно, худшее качество сжатия.
Распаковка же через буфер ничем принципиа-
льно не отличается от распаковки на экран.
Поэтому  ниже будет рассматриваться именно
режим  распаковки  на  экран  (1) - RTD  в
терминологии  автора  программы  (RealTime
Depack). Следует отметить, что распаковщик 
MSP1.6 является наиболее запутанным экран- 
ным  распаковщиком  из всех, с которыми мы
будем иметь дело. Если же сравнивать еще и
с кодовыми, то рядом можно поставить разве
что deHrust 1.x.

   В упакованных данных имеется два потока
- битовый и байтовый. Выборка битов из по-
тока производится  парами байт (ADD HL,HL:
DJNZ:POP HL:LD B,C), c использованием двух 
дополнительных регистров: B - счетчик, C -
константа 16. Начало байтового потока (DEC
SP:POP AF) приходится  на третий байт фай- 
ла,после двух первых байт битового потока.
В дальнейшем потоки чередуются в зависимо-
сти от структуры файла.Битовый поток - уп-
равляющий.
   Для  перемещаемости  депакера указатель
основного  стека  сохраняется  в  регистре
IY, а не  в памяти. Также две смежных яче- 
йки  программы подстраиваются под адрес её
расположения:
────────────────────────────────────────── 
                DI
                CALL #52
                DEC SP,SP
                POP DE
                LD HL,#110
                ADD HL,DE
                EX DE,HL
                LD BC,#98 ;адрес ldto
                ADD HL,BC ;(см.ниже)
                LD (HL),E
                INC HL
                LD (HL),D
────────────────────────────────────────── 
   Таким образом реализуется подобие вызо-
ва подпрограммы nxtde, которая, как вполне
понятно, делает  обычную операцию перевода
указателя  DE  на следующий байт экрана по
структуре ломаных столбцов:
────────────────────────────────────────── 
         nxtde  INC DE 
                LD A,D
                CP #58
                JR NC,atr
                DEC DE
                INC D
                LD A,D
                AND 7
                JR NZ,atr
                LD A,E
                ADD A,#20
                LD E,A
                JR NC,sub8
                INC E
                BIT 5,E
                RES 5,E
                JR NZ,atr
         sub8   LD A,D 
                SUB 8
                 LD D,A
          atr    JR ... ;смещение в этом JR
             ;может принимать 2 разл.знач.
────────────────────────────────────────── 
(атрибуты - линейно). 

   Вызов происходит так:
────────────────────────────────────────── 
                LD A,#8B ;смещение exjr
         ldto=$+1 
         ldjr   LD (atr+1),A 
                JR nxtde
         exjr   EX DE,HL 
                LD A,#90 ;смещение okjr
                JR ldjr
         okjr   EX DE,HL 
────────────────────────────────────────── 
   Указанный  фрагмент  всегда  проходится
насквозь, то  есть  решалась задача именно
смещения ОБОИХ указателей - HL и DE (вход-
ного и выходного при копировании, соответ-
ственно).Это связано с тем,что перемещение
по экрану ведётся в реальных адресах,как в
ASCLZPAK. 
 

   Заголовка у файла нет, следует он непо-
средствено  за  распаковщиком. Первый байт 
байтового потока (3-й байт файла) является 
первым байтом экрана,далее по битовому по- 
току: 

%0 - просто байт (из байтового потока) 
%100 - puts=3 
 %1010 -  puts=2  (обратите  внимание,  код 
  длиннее предыдущего. Это должно означать,
  что ссылки длиной 2 встречаются реже ссы-
 лок с длиной 3 )
 %1011,байт: -1 =конец файла, -2 =16-битное 
  значение puts (POP BC),  иначе puts=байт+
 +10 (puts=10..263)
%1100 - puts=4 
%1101 - puts=5 
%11100 - puts=6 
%11101 - puts=7 
%11110 - puts=8 
%11111 - puts=9 
 

   Если  puts  не равен 2, то производится
декодирование старшего байта смещения (по- 
ложительного disp): 

%1 - 0 
%0000 - 1 
%0001 - 2 
%00100 - 3 
%00101 - 4 
%00110 - 5 
%00111 - 6 
%010000 - 7 
%010001 - 8 
%010010 - 9 
%010011 - 10 
%010100 - 11 
%010101 - 12 
%010110 - 13 
%0101110 - 14 
%0101111 - 15 
%0110000 - 16 
%0110001 - 17 
%0110010 - 18 
%0110011 - 19 
%0110100 - 20 
%0110101 - 21 
%0110110 - 22 
%0110111 - 23 
%0111000 - 24 
%0111001 - 25 
%0111010 - 26 
%0111011 - 27 
%0111100 - 28 
%0111101 - 29 
%0111110 - 30 
 %0111111 - 31 
   (ссылки  с длиной 2  все короткие, т.е.
dispH=0 ) 
   Коды dispH>27 нельзя использовать в эк-
ране,и это придаёт формату некоторую неже-
лательную избыточность.
   Далее  байт из байтового потока опреде-
ляет младший байт смещения. Вычитание сме-
щения из текущего адреса в виртуальном эк-
ране ( IX адресует его  в линейной модели)
реализовано достаточно остроумно:
────────────────────────────────────────── 
                DEC SP
                POP AF
                SUB LX
                CPL
                CCF
                LD L,A
                LD A,HX
                SBC A,H
                LD H,A
────────────────────────────────────────── 
   После  этого виртуальный адрес в HL пе-
ресчитывается в экран и происходит копиро-
вание блока. Затем всё описанное повторяе-
тся и т.д.

               Lazy Pack 2.0
 

   К  сожалению, этим  упаковщиком экранов
могут воспользоваться не все - по непонят- 
ным  причинам на большинстве версий TR-DOS 
программа  при сохранении уничтожает ката- 
лог  диска. Но формат заслуживает рассмот- 
 рения. 
   В  формате использованы почти все хоро-
шие  идеи  по сжатию экранов, какие только 
реализованы  в LC5.2, но по длине распако- 
вщика Lazy 2.0, безусловно, проигрывает LC 
5.2. 

   Имеются  битовый  и  байтовый  потоки в
простейшем  варианте: битовый поток извле-
кается  побайтно в регистр D', B'=счётчик,
C'=константа 8  для помещения в B'. Первый 
байт файла принадлежит битовому потоку.
   Виртуальный адрес экрана в линейной мо-
дели  содержится  в IX, реальный адрес - в
DE. 
   Распаковщик не привязан к экрану, вызы-
вается с параметром: HL=адрес упакованного
экрана. Не использует стек (входные данные
в  HL' ). Распаковывает на экран #4000, но
это число легко исправить на любое кратное
#2000. Если  немного изменить код, то и на 
любое  кратное #800. Распаковщик достигает
перемещаемости, организуя в области MEMBOT
системных переменных бейсика три JP на три
внутренние подпрограммы распаковщика,усло-
вно назовём их get,down и bit. Определение
своего адреса распаковщик делает через DEC
SP,SP, поэтому нужно проследить,чтобы пре- 
рывания были выключены.

   get (+#aa, #5c97) - извлекает  из бито-
вого потока  в аккумулятор число 0...23 по 
следующему дереву: 
%1 - 0 
%01 - 1 
%0010 - 2 
%0011 - 3 
%000100 - 4 
%000101 - 5 
%000110 - 6 
%000111 - 7 
%00001000 - 8 
%00001001 - 9 
%00001010 - 10 
%00001011 - 11 
%00001100 - 12 
%00001101 - 13 
%00001110 - 14 
%00001111 - 15 
%00000000 - 16 
%00000001 - 17 
%00000010 - 18 
%00000011 - 19 
%00000100 - 20 
%00000101 - 21 
%00000110 - 22 
%00000111 - 23 
   down (+#cc,#5c9a) - пересчитать адрес в
DE,  чтобы  он  соответствовал  следующему 
байту  на экране (в порядке ломаных столб- 
цов). 
   bit (+#ea, #5c94) - взять  один  бит из
битового  потока (результат во флаге пере- 
носа). 

   Формат:

 %1 - просто взять байт (из байтового пото- 
 ка);
 %0 - вызываем get. 
  Если результат =7:
   Читаем  некий  byte из байтового потока.
   Если  он  не -1, то  puts=byte+25, иначе
   вызываем get (putsH), потом извлекаем из
   байтового потока putsL.
  Если результат <7:
   Прибавляем 2, получаем puts=2..8.
  Если результат >7:
   Прибавляем 1, получаем puts=9..24.
  Далее  вызываем  get (dispH) и берём байт
  dispL из байтового потока.Реализуем полу-
 ченную ссылку и т.д.

   Специального кода выхода из распаковщи-
ка не предусмотрено. Распаковщик сам конт-
ролирует окончание экрана.

                       подготовил А. Кодер



Другие статьи номера:

CacheVox - Пакет программ для импорта и последующего проигрывания с дискет цифровой музыки.

For Coderz - RAYCASTING - сделай себе немного DOOM'a. Алгоритм трассировки 3D лабиринта как в игре WOLF.

Inferno - О журнале.

DIY - Приспосабливаем мышь от Amiga к ZX Spectrum.

Sofтинка - обзор экранных упаковщиков для ZX Spectrum.

Inferno - Авторы и контакты редакции.

Gameland - описание игры Stronghold (Бастион).

Sofтинка - Пакет CacheVox v1.0 для импорта и проигрывания с дискет цифровой музыки.

Интервью - интервью с Disabler'ом - кодером, художником и железячником из Ростова-на-Дону.

Others - Глюки записи на дискеты. Причины и методы борьбы.

Gameland - Краткое описание проблем игры Dune: Imperia 2.

Inferno - Ошибки в предыдущих номерах.

For Coderz - Маленькие программерские хитрости.

Spectrum - Форматы упакованных данных на ZX Spectrum.

Gameland - об игре Hexagonal Filler.

Sofтинка - Hrum 3.5i - самый быстрый LZ-распаковщик с битовым потоком.

DIY - Изготовление хвоста для мышки.

Железо - Исследуем микросхему К561ИЕ10A.

Железо - Исследуем микросхему КР1533ИЕ7.

Железо - Исследуем микросхему К561ТЛ1. .

Sofтинка - экранный компрессор Laser Compact 4.0.

Inferno - Письма в редакцию.

Sofтинка - компрессор текстов MS Pack 01.96.

Inferno - Об оболочке.

Sofтинка - преимущества архиватора Rar.

Sofтинка - Упаковщик RGB картинок Powerful Code Decreaser v6.2.

Ликбез - Что такое плюс и минус напряжения.

Ликбез - Как работает защита элементов цепи.

For Coderz - Нюансы Raycasting-а.

Sofтинка - Real Information Packer 0.2x - один из самых мощных компрессоров на ZX.

For Coderz - Автосборка программы. Оптимизируем процесс сборки.

Inferno - Вступление.

Others - Результаты анкетирования.

Others - The Compo. Об анкетировании.

О Спектруме - размышления о будущем спектрума.

Железо - Еще раз о защите микросхемы КР1818ВГ93.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Премьера - Упаковщик файлов HG-Packer.
Обзорчик SYS - Обзор системных программ: Bytamare v2.0, Hrum v3.5, PCD v6.2.
Sofтинка - Архиватор ZXRar v0.29. История изменений.

В этот день...   18 декабря