MS Pack 01.96
По мнению Hrumer'а, автора упаковщиков
Hrust, лучшим компрессором текстов на ZX
до 2000 года был MS Pack. Жаль,конечно,что
Hrumer никогда не писал статей по вопросам
компрессии и не стал отвечать на мои воп-
росы лично, а ведь его имя и программы
всплывают в этом разделе уже не первый
раз. Однако,что же представляет собой фор-
мат компрессора Microspace?
Распаковщик, к сожалению,неоптимален по
длине. Структура переходов поддаётся опти-
мизации, лишний XOR A, малополезное сохра-
нение HL'... Но скорость декомпрессии при-
личная - например,для упаковки ПЗУ MS Pack
и сегодня почти незаменим. Ведь в нём сло-
варь, в отличие от Hrum, составляет всю
длину файла. Конечно,это сказалось на ско-
рости самого упаковщика. Хэширования для
ускорения поиска повторов нет ни в Hrum,
ни в MS Pack.
Имеются битовый и байтовый потоки,бито-
вый поток выбирается по 2 байта. Для рабо-
ты используется стек (принцип ADD HL,HL:
DJNZ:POP HL:LD B,C ).
Упакованный блок должен лежать после
распаковщика (Hrum-подобный принцип). Бу-
дем отсчитывать байты от начала распаков-
щика:
+#e9 - адрес,по которому лежат 5 байт кон-
ца файла. Точнее,адрес+4, т.к.байты копи-
руются через LDDR. Почему 5 байт не лежат
непосредственно без указателя? Тем более
что 4 байта (или даже 6, если в конце де-
компрессора не JP, а RET) до упакованного
блока не используются? Если бы 5 байт ко-
нца файла лежали впритык за депакером, их
не пришлось бы и перебрасывать! Так что
это решение авторов довольно странно.
+#eb - 2 байта HL для перемещения упако-
ванного блока (с помощью LDDR );
+#ed - 2 байта DE, аналогично;
+#ef - 2 байта BC, аналогично;
+#f1 - адрес, куда распаковывать (DE');
+#f3 - первые 2 байта битового потока.
Далее согласно битовому потоку:
%0 - просто байт (из байтового потока);
%100 - puts=2. Короткая ссылка: disp8 в
байтовом потоке (1..256, причём 0 соотве-
тствует 1 и т.д.!);
%101 - puts=3;
%110 - puts=4;
%11101 - puts=5;
%11110 - puts=6;
%1111100 - puts=7;
%1111101 - puts=8;
%1111110 - puts=9;
%111111100 - puts=10;
%111111101 - puts=11;
%111111110 - puts=12;
%11111111100 - puts=13;
%11111111101 - puts=14;
%11111111110 - puts=15;
%11111111111 - puts=16;
%11100 - взять некий byte из байтового по-
тока. Если -1, то прервать распаковку.
Если -2, то следующие 2 байта в байтовом
потоке - это puts, иначе puts=byte+17=
=17..270.
Потом для всех ссылок,кроме puts=2 (для
неё выше было написано особо), следующим
образом вычисляется disp (учтите, что в MS
Pack disp нестандартный - он вычитается из
адреса-1! Именно поэтому в puts=2 уточне-
но, что чему соответствует!):
%1 - аналогично puts=2;
%0000 - dispH=1, здесь и далее dispL берё-
тся из байтового потока после dispH;
%0001 - dispH=2;
%00100 - dispH=3;
%00101 - dispH=4;
%00110 - dispH=5;
%00111 - dispH=6;
%010000 - dispH=7;
%010001 - dispH=8;
%010010 - dispH=9;
%010011 - dispH=10;
%010100 - dispH=11;
%010101 - dispH=12;
%010110 - dispH=13;
%0101110 - dispH=14;
%0101111 - dispH=15;
%0110000 - dispH=16;
...
%0111110 - dispH=30;
%0111111 - dispH из байтового потока.
подготовил А. Кодер