Какие есть упаковщики графики и кода для БК, кроме KOMP2?
Вид для печати
Какие есть упаковщики графики и кода для БК, кроме KOMP2?
Bkpack. Я только им и пользовался. Единственный из упаковщиков такого типа который мне нравился.
Советую LZSA
а в чем проблема - это же удобно.
могу предложить еще вот такой упаковщик. zx0
распаковщик есть и под PDP11
Интересующимся могу предложить глянуть Спектрумовские жамкалки скринов и данных, работали неплохо.
Для данных вообще была прога, создающая sfx-архивы - Hrust. Упаковщик картинок, по памяти - ASC Screen Crasher.
В свое время Писишники переделывали Hrust/Dehrust для распаковки интрух, настолько мало он весил =)
Вложение 75927
Исходники распаковщиков LZSA1, LZSA2, ZX0, ZX1 для БК0010
BKPACK дал хорошие результаты, буду юзать его )
насколько хорошо жмет?
https://introspec.retroscene.org/com...o_20210128.png
лучше чем Shrinker?
Файлы заставок, которые мне нужно сжать, жмет в среднем в два раза:
hallblnk было 40000, стало 22053
mainhall 40000 -> 23502
titr1 40000 -> 15004
titr2 40000 -> 14631
titr3 40000 -> 14573
titr4 40000 -> 12642
tmaincl 40000 -> 30615
Для пробы сжал код:
main.exe 36724 -> 27223
Все числа восьмеричные. Причем это он делает исполняемый файл с встроенным распаковщиком, который надо из них будет выдрать и использовать только в одном экземпляре.
ZX0
TITR1.PIC - 3890dec байт=7462oct байта
TITR2.PIC - 3784dec байт=7310oct байт
+распаковщик 102dec=146oct байт
в PONG Charged я использовал LZSA2 и очень доволен
Оффтоп про распаковщики
Если распаковщик мой, то вариант для pdp11 был совсем неудачный, даже не стал его выкладывать на github. Но и при наличии более эффективного распаковщика актуальность lzsa2 после появления zx0/1 сильно уменьшилась. lzsa1 - быстрый; zx0 - сильно сжимает; zx2 - компактный распаковщик; zx1 - степень сжатия немного уступает zx1, зато скорость почти как у lzsa2, а в варианте для pdp11 даже быстрее, что правда больше говорит о недоработанности того распаковщика lzsa2.[свернуть]
Не подскажешь как в LZSA2 это устроено? Read a nibble... then read a byte. После чтения токена (байта) нужно прочитать ниббл (4 бита), а потом байт. Получается, этот байт сдвинут на 4 бита? То есть расположение данных в памяти выглядит так (побитно, где | означает границы байтов в памяти)?
Код:| tokenmmm | niblbyte | byte.... |
^^^^ ^^^^
Спорное утверждение, например TITR1.PIC и TITR2.PIC zip/deflate сжал в полтора раза лучше, чем bkpack.
пара слов про нибблы в lzsa2
Про формат lzsa2 я вряд ли напишу лучше автора, но если ограничиться нибблами, то можно сказать, что есть как бы параллельный поток нибблов (это как поток битов во многих других упаковщиках), перемежающийся с потоком байтов. Если нужен ниббл, то мы проверяем текущее состояние "буфера нибблов", и
1. если там пусто, читаем следующий байт, берем оттуда один ниббл, а второй - в буфер нибблов.
2. если там не пусто, берем ниббл и помечаем, что "буффер нибблов" пуст.[свернуть]
Распаковщик изначально выглядит так:
Вложение 75933
Он пересылает часть кода в назначенную рабочую область, потом делает JMP на начало этого кода, и первым делом затирает свое начало, пересылая туда 572 байта из конца архива:
Вложение 75934
Таким образом, повторный запуск уже не имеет смысла, потому что там нет изначального кода.
Он ломает себя не тем, что пересылает куда-то кусок своего кода, а тем, что пересылает кусок данных из конца архива в свое начало уже после этого. И архив начинает распаковывать уже после этого. Понятно, что его можно переделать. Но это необратимое таскание своих кусков совсем не вяжется с "он вообще ничего в себе не изменяет". Потому я и спросил, нет ли версии, изначально просто распаковывающей архив в нужный адрес без выкрутасов.
Алгоритм мешает. Он возвращает в начало, взамен модуля автораспаковщика, тот участок упакованных данных, которые должны там находится.
Чтобы всё это исправить, надо по сути написать новую версию упаковщика.
Нет. Основное назначение бкпака - сжатие исполняемых файлов, т.е. файл загрузился, распаковался в памяти и запустился.
Если нужно многократное использование сжатых массивов, то в случае бкпака делали так - копировали сжатый массив в нужное место, и запускали автораспаковщик. Там у него был режим "сжатие данных", когда после распаковки делался не запуск, а просто возврат из п/п RTS PC.
Ну и существенный минус - нужна область для таблиц распаковки.
Для данных, особенно, если массив надо распаковать куда-то в определённое место, на БК использовали самарский Crunch/Decrunch.
Или, как тут советуют, использовать ZXn/DZXn, правда сперва придётся написать нужный упаковщик конкретно для БК.
Чем не устраивает имеющиеся? Проверял их в том числе в эмуляторе БК, работали. Или какие-то проблемы на реале?
Спасибо! А можешь объяснить что такое "match"? Просто документация автора рассчитана на тех, кто знаком с другими его алгоритмами - описаны только особенности lzsa2, а базовые понятия не описаны.
Про биты LL (literals length) я понял: сколько байт из входного потока копировать в выходной поток. Но не понял как при этом используется XYZ (offset). И что делать когда literals length = 0 - пропускать этот токен или разбирать биты MMM?
Про биты MMM (match length) вообще не врубился: что если задано значение и LL, и MMM? Выполнять и то, и другое? Если да, то в каком порядке? Чем match length отличается от literals length и что делать если match length = 0?
Возможно несколько запутывает то, что автору пришлось объединить в "токене", с которого начинается каждый отдельный фрагмент все сразу - и информацию о литералах и о ссылках, все чтобы избежать дробления служебной информации на более мелкие небайтовые куски.
LL отдельно, сколько литералов скопировать, там может быть и 0.
XYZ и MMM отдельно, соответственно смещение и длина ссылки в уже раскодированном блоке, чтобы взять оттуда фрагмент и скопировать его в текущую позицию. Конечно по 3 бита мало на все случаи жизни, поэтому он там расписал, когда и как берутся дополнительные байты для длинных совпадений и дальних ссылок.
А что если LL=1 и MMM=1? Сначала копируем один байт из входного потока, а потом применяем оффсет (1+2)?
Спасибо. По названию "match" я догадывался, но в описании прямо об этом не сказано. Мне кажется немного странным, что нужно устанавливать старшие биты в 1, а потом прибавлять оффсет. Было бы логично биты не трогать и отнимать оффсет. Может быть так и сделаю. Тогда, вроде, надо предварительно увеличить оффсет на 1 (преобразование отрицательных чисел в положительные).
Да, ну и смещение из XYZ (и при необходимости из следующих байт) надо взять.
Для pdp11 это без разницы, а вот для z80 и особенно 8080 это очень важная оптимизация. У z80 команда 16 битного вычитания длиннее и медленнее 16 битного сложения, а у 8080 нет команды 16 битного вычитания. Раньше я даже кое-какие упаковщики переделывал на эту тему.
Ну они изначально существуют только под ПЦ
вот исходники - можно в С собрать.
есть С под БК?