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 из байтового потока. 

                       подготовил А. Кодер