PDA

Просмотр полной версии : Сжатие данных



Страницы : [1] 2

ivagor
27.10.2018, 14:01
Чтобы не засорять тему по средствам разработки решил создать новую. За неделю есть подвижки по нескольким распаковщикам, начну c LZ4.
Решил хакнуть smallz4 (https://create.stephan-brumme.com/smallz4/), чтобы
1) Удобно для 8080 (да и для z80) хранить смещения
2) Убрать заголовок, чтобы его не надо было пропускать или отрезать сторонними программами
В итоге получилось сократить (размер каждого рапаковщика указан в исходнике в комментариях) и ускорить распаковщики. Можно еще сократить на байт все варианты, если разрешить портить упакованные данные (т.е. одноразовая распаковка), но чтобы не захламлять исходники убрал эту фичу.
Предыдущая версия для стандартного smallz4 здесь (http://zx-pk.ru/threads/9532-vektor-06ts-sredstva-razrabotki.html?p=981853&viewfull=1#post981853). Ее тоже можно чуть оптимизировать, но при наличии v4 не вижу смысла выкладывать такой вариант.

ivagor
28.10.2018, 12:46
Следующий номер программы - zx7. Выкладывал (http://zx-pk.ru/threads/9532-vektor-06ts-sredstva-razrabotki.html?p=983364&viewfull=1#post983364) вариант, оптимизированный по размеру. Его удалось еще немного сократить и ускорить. И сделал 2 варианта оптимизированных по скорости, быстрейший из которых вплотную приблизился к распаковщику MegaLZ b2mа (210 байт) все еще выигрывая по размеру.
Относительная скорость распаковки разными вариантами на примере теста устройств:
compact (101/106 байт - одноразовый/многоразовый) - на 49% медленнее MegaLZ
normal (125 байт) - на 17% медленнее MegaLZ
fast (170 байт) - на 7% медленнее MegaLZ

ivagor
29.10.2018, 19:29
Лучший по степени сжатия упаковщик для восьмибиток несомненно exomizer. Со времени обновления версии распаковщика для 8080 (http://sensi.org/scalar/ware/694/) прошло уже несколько лет, но зато будет сразу много улучшений.
Важный момент - теперь для сжатия нужно использовать версию не ниже 3 (https://bitbucket.org/magli143/exomizer/wiki/Home) (текущая 3.0.1), т.к. все представленные распаковщики требуют опции -P1. Что интересно, еще даже не обновили версии распаковщиков для z80, хотя для z80 есть exoopt для exomizer2.
Второй момент - теперь 2 набора по 4 распаковщика. Два набора соответствуют общим опциям -P1 и -P1 -M255. А 4 варианта внутри наборов соответствуют четырем распаковщикам для z80: "полный", -С, -B, -C -B. Т.е. теперь поддерживаются "простые" и "обратные" распаковщики.
Т.к. версий стало много, поддерживать и оптимизировать для всех них варианты под 8085 и 580ВМ1 нет возможности и я их убрал.
Скорость распаковки очень заметно возросла (на примере теста устройств): "полный" распаковщик на 27% быстрее, простой на 28 %. С -M255 все еще лучше: "полный" на 35% быстрее, простой на 36%. Простые и обратные распаковщики короче. Простые практически всегда быстрее, обратные - в зависимости от файла. Недостаток "простых" и -M255 - несколько худшая степень сжатия.
Требуемые опции сжатия и размеры упаковщиков указаны в комментариях.

Cheburashka
21.07.2019, 22:26
Перенес сообщение в тему "Архивирование, сжатие, упаковка"

Ссылка (https://zx-pk.ru/threads/296-arkhivirovanie-szhatie-upakovka.html?p=1021162&viewfull=1#post1021162)

ivagor
22.07.2019, 07:40
Cheburashka, думаю есть соответствующеая спековская тема и распаковщики "только z80" лучше туда. aplib для 8080 я выкладывал (https://zx-pk.ru/threads/9532-vektor-06ts-sredstva-razrabotki.html?p=983364&viewfull=1#post983364).

Error404
22.07.2019, 11:39
А упаковщики для них где выложены?

ivagor
22.07.2019, 12:08
Большинство упаковщиков (и не только упаковщиков) можно скачать одним архивом здесь (http://hypr.ru/blog/dev/740.html) (ссылку туда я постил (https://zx-pk.ru/threads/9532-vektor-06ts-sredstva-razrabotki.html?p=981704&viewfull=1#post981704)). В некоторых случаях (когда упаковщик свой или новый) упаковщики или ссылки на них приведены прямо в соответствующем сообщении.

Error404
26.07.2019, 16:21
Большинство упаковщиков (и не только упаковщиков) можно скачать одним архивом здесь (http://hypr.ru/blog/dev/740.html) (ссылку туда я постил (https://zx-pk.ru/threads/9532-vektor-06ts-sredstva-razrabotki.html?p=981704&viewfull=1#post981704)). В некоторых случаях (когда упаковщик свой или новый) упаковщики или ссылки на них приведены прямо в соответствующем сообщении.

Нет времени сравнивать, но может опытным взглядом оценишь эффективность вот этого пакера (https://github.com/serge-404/AltairDOS/tree/master/App/source/bitbuster) (а может она уже известна)? Я им пользуюсь для производства пакованных игр под Альтаир-ДОС (это клон CP/M), убивая сразу несколько зайцев:
- Код игр часто больше размера TPA, а после пакера он всегда туда влезает
- быстро распаковывает, компактный распаковщик (тут субъективное ИМХО, не сравнивал)
- Депакер состоит из двух независимых побайтовых стримов - один стрим на вход и один на выход, что делает очень простой задачу распаковки в страницу памяти, отличную от страницы памяти TPA (как в большинстве случаев и происходит).

ivagor
26.07.2019, 16:49
"Все уже сравнили до нас" (с)
В вышеприведенном обзоре (http://hypr.ru/blog/dev/740.html) BitBuster упоминается. Можно сказать, что он "устарел", т.к. есть два его наследника: zx7 и Pletter5. Не хочу пересказывать обзор, лучше там посмотреть, есть варианты более эффективные по степени сжатия, есть более быстрые, есть более компактные распаковщики. В зависимости от приоритетов по тому обзору можно выбрать подходящий упаковщик/распаковщик для z80.
Для 8080 все примерно аналогично, только я не все распаковщики конверснул в 8080 и не вижу в этом необходимости. Самое сильное сжатие (и медленная распаковка) - exomizer, послабее/побыстрее - aplib, еще слабее/быстрее - megalz/zx7, самый слабый/быстрый - lz4. Самый маленький распаковщик (+ еще плюшки) - zx7mini. Надо бы выложить слегка оптимизированный вариант распаковщика megalz b2ma, если нужен сбалансированный вариант и не нужны рекорды (по степени сжатия, по скорости, по размеру распаковщика) то он близок к оптимуму.

ivagor
24.08.2019, 11:20
Лучший по степени сжатия упаковщик для восьмибиток несомненно exomizer.
Лучше поздно, чем никогда. introspec в своем обзоре почему-то обошел стороной Real Information Packer и спековский rar/unrar. Судя по описанию RIP уступает RARу, поэтому попробовал только RAR. Упаковал с использованием писишного RARa 2.50, распаковал спековским UNRARом - все сработало, файл совпал с исходным.
RAR (по крайней мере с режимом сжатия Best) совсем чуть-чуть, но превосходит exomizer по степени сжатия, поэтому должен признать, что exomizer не лучший упаковщик для восьмибиток. Скорость распаковки не сравнивал.
Вряд ли кто-то будет переделывать unrar для 8080 (я точно не собираюсь), поэтому для вектора exomizer остается лучшим упаковщиком на обозримую перспективу.
RIP, RAR и exomizer насколько я понял очень похожи по "принципу действия" и есть шанс, что будущие версии exomizera станут жать чуть сильнее и обойдут RAR 2.x.

ivagor
25.08.2019, 13:12
И это еще не все. Есть пара упаковщиков для C64, которые превосходят или примерно соответствуют exomizerу по степени сжатия: ALZ64 (превосходит) и subsizer (примерно соответствует). Но их распаковщики только для 6502, даже вариантов для z80 нет.

- - - Добавлено - - -


Что интересно, еще даже не обновили версии распаковщиков для z80, хотя для z80 есть exoopt для exomizer2.
Теперь версии распаковщиков для z80 с поддержкой самых нужных опций exomizera 3 можно скачать здесь (https://github.com/antoniovillena/deexo)

ivagor
03.09.2019, 18:40
Для полноты картины еще стоит упомянуть амижный Shrinkler, для которого написали распаковщик для z80. По степени сжатия с переменным успехом соревнуется с exomizerом, по скорости и размеру распаковщика exomizer безоговорочно выигрывает. Кроме того shrinklerу нужно дополнительно 3 Кб памяти, а exomizerу - 156 байт. Смысла в shrinklere для 8080 совсем не вижу (да и для z80 на мой взгляд его сделали для галочки, а не для практического использования).

ivagor
09.09.2019, 05:28
Смысла в shrinklere для 8080 совсем не вижу (да и для z80 на мой взгляд его сделали для галочки, а не для практического использования).
Беру свои слова обратно, shrinkler самый крутой по степени сжатия, смысл в нем есть для любой восьмибитки.

KTSerg
09.09.2019, 07:47
Сразу скажу, что со сжатием данных экспериментировал только на Векторе, и только в первой половине 90-ых.
Соответственно вопрос может быть не актуальным.
У этих изучаемых программ (для сжатия данных) есть специализация? Ну например предназначен для сжатия кода (программ), графики или текста.
Ну или что-то из этого сжимает значительно лучше других.

ivagor
09.09.2019, 09:10
Что касается универсальных архиваторов для 8080, то краткая характеристика здесь (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1021629&viewfull=1#post1021629), начиная с абзаца "Для 8080 все примерно аналогично".
Хотя с тех пор есть заметные изменения. В номинациях "самый быстрый" и "золотая середина" есть новый фаворит - LZSA (https://github.com/emmanuel-marty/lzsa/releases). Там два варианта сжатия:
1. LZSA1. С быстрой распаковкой, на замену LZ4, его я пока не пробовал
2. LZSA2. "Золотая середина", на замену MegaLZ. Вот его я уже конверснул на 8080 и распаковщик получился компактнее и быстрее MegaLZ b2ma (и даже его оптимизированных вариантов). При этом LZSA еще и сжимает в этом режиме лучше MegaLZ. Еще подумаю над распаковщиком LZSA2 и выложу.

Пара слов про zx7. Сделали (https://github.com/antoniovillena/zx7b) его "генерализованный" вариант (saukav.exe). В отличие от оригинального zx7 он позволяет настраивать 3 параметра: направление упаковки/распаковки (прямое/обратное), разрядность смещения, тип гамма-кода.
1. Направление - обратные распаковщики чуть компактнее и быстрее. Если сжатие вперед и назад примерно одинаковое, то лучше использовать обратный распаковщик.
2. Разрядность смещения. Там две градации:
2.1 Минимальное допустимое смещение (o0) фактически дает замену zx7mini
2.2 Остальные варианты (o1-o8) позволяют улучшить сжатие. С этой фичей вплотную приближается к MegaLZ.
3. Тип гамма-кода - по моим тестам вариант g0 дает лучшее сжатие. И его удалось лучше оптимизировать.
Все бы хорошо, но
1. Формат битстрима немного несовместим с zx7 (и g0 и g1), пришлось заново переписывать и оптимизировать распаковщики.
2. Появился LZSA и убил MegaLZ и zx7. Возможно для zx7 остается ниша распаковщика коротких и очень коротких файлов, когда выигрыш LZSA2 в степени сжатия компенсируется компактностью распаковщиков zx7, а скорость для маленьких файлов не так важна.

Сжатие графики я отдельно не тестировал, но могу сказать, что векторовские графические форматы (карандаш, spr) проигрывают всем современным компрессорам, возможно посоревнуются только с LZ4 и то не уверен.

- - - Добавлено - - -

В номинации "максимальное сжатие" скоро тоже будут хорошие новости.

ivagor
15.09.2019, 17:50
Переделал распаковщики LZSA1 spke/intoscpecа для i8080. Под влиянием svofski выложил на gitlab (https://gitlab.com/ivagor/lzsa1), а не как обычно.

LZSA1 это замена LZ4, т.е. очень быстрый распаковщик. Сжимает сильнее LZ4, размер распаковщиков сравнимый, скорость распаковки чуть меньше.
Если сравнить скорость с LZ4v4 (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=984028&viewfull=1#post984028), то
LZSA1_small примерно на 10% медленнее LZ4 compact
LZSA1_fast примерно на 5% медленнее LZ4 fast/faster

Поддерживается прямая и обратная упаковка/распаковка (в отличие от LZ4). В распаковщике для "обратного" варианта нужно раскомментировать строку
;#DEFINE BACKWARD_DECOMPRESS

Прямой вариант быстрее и компактнее.

- - - Добавлено - - -

Наверно стоит пояснить, какие скорости достигнуты. Если говорить о быстрых вариантах распаковщиков LZ4 и LZSA1, то скорости практически соответствуют простой пересылке байта в цикле {mov a,m\ stax d\ inx h\ inx d\ dcx b\ mov a,b\ ora c\ jnz $-7}. А тут ведь не просто пересылка, а распаковка.

ivagor
16.09.2019, 18:26
Выложил (https://gitlab.com/ivagor/lzsa8080) распаковщик LZSA2.
После более полного тестирования (больше 20 файлов) могу сказать, что это не совсем убийца MegaLZ, скорее очень серьезный конкурент.
1. Степень сжатия. Первые попробованные мною файлы LZSA2 сжимал лучше MegaLZ, но по результатам теста более 20 файлов все же MegaLZ большинство файлов сжимает чуть-чуть лучше. Выигрыш от нескольких десятков байт до двух-трех сотен, максимум - 400 байт. С другой стороны LZSA2 несколько файлов сжал лучше и там где сильнее сжал LZSA2 максимальный выигрыш составил аж 3.5 килобайта.
2. Размер распаковщика. b2m не стал использовать в MegaLZ самомодифицирующийся код и я наступил на горло собственной песне и убрал пару фрагментов такого кода из LZSA2, т.е. оба распаковщика можно исполнять из пзу.
MegaLZ - 210 байт (прямой), LZSA2 - 188 байт (прямой) / 193 байта (обратный).
3. Скорость распаковки. Выигрыш LZSA2 в скорости на разных файлах от 1.08 до 1.5 раз

ivagor
18.09.2019, 20:02
Дополнение про скорость LZSA. Вышеприведенные данные получены при сжатии с опциями по умолчанию, т.е. с оптимизацией по степени сжатия. Попробовал опцию m, позволяющую увеличить скорость распаковки.
LZSA1_fast уже при m4 обгоняет LZ4 Faster, при этом сжимает немного лучше. При m5 распаковка еще быстрее, но сжимает похуже.
Думал, что LZSA сделает ненужным MegaLZ, а он убрал LZ4.
Получается такая цепочка от самой быстрой скорости и худшего сжатия к лучшему сжатию и меньшей скорости:
-f1 -m5; -f1 -m4; -f1 -m3; -f1; -f2 -m5; -f2 -m4; -f2 -m3; -f2

ivagor
19.09.2019, 19:04
Ни дня без новостей про LZSA. Свежая версия 1.0.8 чуть-чуть лучше сжимает с использованием LZSA2. Но в целом на соревнование с MegaLZ по степени сжатия это практически не повлияло, как сжимал MegaLZ 14 файлов из 20 (70%) чуть лучше LZSA2 так и сжимает. Если смотреть отдельно на эти 14 файлов, то в 12 сжатие улучшилось на считанные байты, а в 2 - ухудшилось на те же считанные байты. В остальных 6 файлах есть примеры более серьезного улучшения сжатия.

ivagor
22.09.2019, 10:48
Респект автору LZSA, версия 1.0.9 стала сжимать лучше и счет LZSA2:MegaLZ сменился на моем тестовом наборе с 6:14 на 8:12. И нет файлов, которые стали бы сжиматься хуже.
Обновил репозиторий (https://gitlab.com/ivagor/lzsa8080). Свел LZSA1 и LZSA2 в один - LZSA8080.
Распаковщики LZSA1 старые, а LZSA2 обновил и дополнил.
"Обычный" стал на байт короче (187 прямой / 192 обратный) и чуть-чуть быстрее. Добавил "быстрый" распаковщик (201 байт прямой / 206 байт обратный) - он на 7% (для некоторых файлов больше) быстрее обычного.

ivagor
24.09.2019, 19:21
Пригляделся к shrinklerу, вернее к его распаковщику для z80 (http://www.cpcwiki.eu/forum/programming/shrinkler-z80-decrunch-routine/).
Самая шокирующая вещь - это время распаковки. Тест устройств (исходный 25600 байт, упакованный - 14280 байт) на 3 МГц z80 (без тормозов) распаковывается 68.5 секунд! Это на два десятичных порядка медленнее lzsa1 и lz4. Если переделать умножение на развернутый цикл, то распаковка ускоряется почти в полтора раза, но и размер распаковщика увеличивается на 3/4. И это еще для z80, версия для 8080 будет медленнее и больше по размеру. Вот так выглядит LZMA-подобная штука для восьмибиток без быстрого аппаратного умножения и большого количества регистров.

ivagor
27.09.2019, 18:58
Похвастаюсь про shrinkler. После некоторых раздумий стало ясно, что цикл умножения можно разворачивать экономно, аккуратно и сильно выиграть в скорости при минимальном увеличении размера. Да и умножение не единственное место для приложения сил. Но над версией z80 есть кому думать, а я примерился к 8080. Поставил такую цель - получить скорость официальной версии для z80 при размере не больше разогнанной версии для z80. И это получилось выполнить и перевыполнить. В итоге при размере разогнанной версии для z80 версия для 8080 опережает по скорости официальную для z80 на 25%. Это позволило при векторовских тормозах получить быстродействие как у официальной для z80 без тормозов на той же частоте. Аналогично будет для компов на ВМ80 с частотой 2.4-2.5 МГц и прозрачным озу (корвет, океан, орион).
Можно поставить галочку - распаковщик shrinkler для 8080 есть. Но хочется еще доработать, потом собираюсь выложить на gitlab или github.

morozov
28.09.2019, 05:01
Подскажите, есть ли аналог Laser Compact v5.2 (http://www.worldofspectrum.org/infoseekid.cgi?id=0021446) для PC? На текущий момент из всего, что я перепробовал, он сжимает изображения лучше всего, особенно в связке с Screen Optimizer v4.2 (http://www.worldofspectrum.org/infoseekid.cgi?id=0021314). Пробовал ZX7 (http://www.worldofspectrum.org/infoseekid.cgi?id=0027996), ZLF (https://www.tomdalby.com/other/lzf.html), Hrust 1.3 / Hrum 3.5 (https://github.com/psbhlw/hrust13-hrum35-pc). Все они вроде как общего назначения и от этого хуже справляются.

ivagor
28.09.2019, 06:03
Лучше в спековской теме спросить, для вектора таких утилит не было, да и экран у вектора совсем другой.

Lethargeek
28.09.2019, 13:24
morozov, непонятно, упаковщик на пц для спектрума нужен штоле? ну, есть мои поделия https://zx-pk.ru/blogs/680-lethargeek.html
должны жать типичные скрины лучше лазера (правда, декомпрессор для z80 сложнее и распаковка медленней раза в три))
лазер на пц с исходником тоже есть, где-то в спековских разделах тема была; и конечно, всё лежит на vtrd

- - - Добавлено - - -

адаптировать спековские методы к векторовским плоскостям в принципе несложно, и даже код скорей всего упростился бы
(точней, проще стал бы код для z80, а вот с убогим 8080 результат может оказаться куда печальней)

ivagor
28.09.2019, 19:25
Если подумать, утилит типа laser compacta для вектора не было, зато самые популярные графические редакторы сохраняли картинку в сжатом виде (scr, spr). Соответственно для писи "утилитой для компрессии векторовского экрана" можно назвать sprview или утилиту yura (хотя я не помню точно, у него только смотрит или еще и сжимает). SPRview точно сжимает. А если говорить о современности, то shrinkler победит любого векторовского конкурента, даже если его не дополнять разными вариантами сканирования/обхода картинки и перекодирования цветового пространства. Правда для него желательны не убогие процы типа 8080 или z80, а что-нибудь покруче. Для 8080 (и z80) есть exomizer (если нужно только распаковывать, а упаковывать на писи) - по сравнению со shrinklerом он просто мгновенный и я серьезно оптимизировал его распаковщики, ближе к новому году появятся исходники.

ivagor
29.09.2019, 11:13
Краткий поверхностный тест сжатия графики на примере картинок сконверченных Романом Пантелеевым (9 файлов).
До общественности они дошли в виде spr файлов, поэтому в качестве базы для сравнения беру цифру 9*(32768+16)=295056 байт, т.е. полностью 256x256, хотя некоторые картинки не на полную ширину. Фактически lzsa, exomizer и shrinkler сжимали .o32 файлы, которые представляют собой копию видеопамяти вектора с перевернутыми столбцами и 128 байтным заголовком и реальная степень сжатия для этих форматов даже чуть-чуть больше, но эта крошечная фора не спасет spr.


Оригинал 295056 байт - 100%
SPR 134656 байт - 45.64%
LZSA1 115128 байт - 39.02%
LZSA2 109294 байт - 37.04%
Exomizer 105206 байт - 35.66%
Shrinkler 102128 байт - 34.61% (-2)
Shrinkler 101004 байт - 34.12% (-9)

7z (формат zip)102916 байт - 34.88%
7z (формат 7z) 99119 байт - 33.59%

Использовал LZSA 1.1.0, exomizer 3.0.2 и shrinkler 4.4. 7z "старый" - 15.14

Стоит отметить, что в очередной версии LZSA 1.1.0 опять чуть улучшено сжатие в LZSA2, но счет LZSA2:MegaLZ по сравнению с 1.0.9 на моем наборе файлов не изменился.

KTSerg
29.09.2019, 12:15
Я в 90-ых изучал алгоритм сжатия картинок в SСR-формат, для использования в своей программе. Обнаружил, что графический редактор (сохранявший картинку) не использует все возможности алгоритма. Внёс не большие изменения в алгоритм компрессора, сжиматься картинки стали лучше, а декомпрессор подходил стандартный.
Правда выигрыш был не большой (но было приятно), о времени сжатия я не задумывался.

ivagor
29.09.2019, 13:12
Улучшение сжатия в рамках старого формата хранения это хорошая тема и есть немало подобных примеров (например 7z лучше сжимает в zip, чем классический zip; в LZSA формат не меняется а сжатие улучшается, в exomizere аналогично и т.д.).
Время сжатия сейчас в эпоху писи с неубогими процами не так важно как время распаковки. Ну а степень сжатия всегда будет очень важна.
Возможно стоит потестировать в сравнении с современными и лучшие классические упаковщики: Press Бобкова и LZ77 Луппова. Они 100% проиграют лучшим современным, зато могут сжимать на векторе.
Еще лучше бы сделать большое сводное тестирование пригодных для распаковки на 8080 компрессоров, типа того, что делал introspec/spke, но это надо сильно захотеть и потратить много времени.

- - - Добавлено - - -

Добавил в сравнение 7z в качестве ориентира.

ivagor
30.09.2019, 06:30
Уточнил данные для 7z. Т.к. предыдущие форматы сжимали в raw то и для zip/7z привел цифры без заголовка (поэтому цифра zip стала меньше). Кроме того для 7z/LZMA2 пережал без непрерывного сжатия (поэтому для 7z цифра стала больше), т.к. все остальные сжимали файлы по отдельности.

ivagor
01.10.2019, 19:39
Дошел до еще одного хорошего упаковщика/распаковщика, который не попал в обзор introspeca. Оказалось, что для deflate в его gzip инкарнации есть распаковщики для z80 (ссылки в английской вики). Попробовал версию для msx - отлично работает. По степени сжатия между exomizer и shrinkler, по скорости - несколько медленнее exomizer и более чем на порядок быстрее shrinklera. Нет ничего удивительного в том, что {LZ+Хаффман} заметно быстрее {LZ+арифметическое кодирование}, было бы здорово, если в этом направлении поработали авторы упаковщиков для восьмибиток. Все же gzip слишком взрослый, хотелось бы что-то попроще, меня его распаковщики для z80 несколько подавляют своей серьезностью.

ivagor
02.10.2019, 17:38
Shrinkler сжимает хорошо, но по результатам тестирования осталась некоторая неудовлетворенность, вроде должен еще лучше. Планировал покрутить настройки, но оказалось, что в версии 4.5 все упростили - есть пресеты. Вариант по умолчанию соответствует пресету "-2", а лучшее сжатие "-9". Добавил в сравнение сжатия графики (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1028270&viewfull=1#post1028270) строку shrinkler -9.

Обновил в репозитории (https://gitlab.com/ivagor/lzsa8080/) lzsa1_small.asm - сократил на один байт. Это не результат напряженной работы мысли, просто заметил, что раньше забыл убрать лишнюю команду. Разница в быстродействии практически незаметная, меньше одного процента.

ivagor
06.10.2019, 12:14
Довел распаковщик shrinklera для 8080 до приемлемого вида и выложил на gitlab (https://gitlab.com/ivagor/deshrinkler8). Размер в полтора раза больше "официальной" версии для z80. Если без торможения, то на 25% быстрее "официальной" версии для z80, с векторовским торможением на 5% быстрее.
Добавил реинициализацию переменной d2, чтобы распаковщик можно было вызывать неоднократно. В описании отметил, что адрес назначения д.б. четный, так было и в оригинале, но там не было про это написано.

Rus
09.10.2019, 13:45
А существует ли в природе распаковщик shrinklera для 8086?

ivagor
09.10.2019, 14:41
Не гуглится, но для 8086 есть несколько вариантов.
1. Если в принципе нужен LZMA для 8086, то стоит посмотреть UPX (https://github.com/upx/upx/releases/tag/v3.95).
2. Если нужен именно shrinkler
2.1. Можно попробовать полуавтоматически транслировать z80->8086 рекомпилятором Валерия Бостана.
2.2. Можно вручную транслировать 8080->8086, это не самый лучший вариант, но очень простой. А потом оптимизировать, хотя бы как минимум умножение заменить на команду умножения.

Rus
09.10.2019, 15:19
Гуглил, но, увы, безуспешно.. Нужно максимально возможное сжатие для компа уровня IBM PC-5150, а скорость распаковки не очень важна.
Тестил LZ4 - слабо, LZSA2 - неплохой результат, но Shrinkler показал результаты еще лучше на 10%, а то и больше.. Упаковывал ресурсы игрушки. Как раз этих процентов и не хватает для того, чтобы все поместилось в память. Ручную трансляцию рассматривал, но, с оптимизациями, которые используют для депакеров, высока вероятность ошибок, для 8080 не кодил.. Нужно все же полностью понимать принцип работы. Получается все же вслепую транслировать придется, раз готовых вариантов нет.

ivagor
09.10.2019, 16:55
Лично мне было бы проще конверснуть 8080->8086, но если 8080 не особо знаком, то возможно лучше все же посмотреть upx. Сжатые им с опцией --8086 .comы в эмуляторе поиска работают.

ivagor
09.10.2019, 21:40
Быстро и грязно конверснул shrinkler для 8088/8086, добавил в репозиторий (https://gitlab.com/ivagor/deshrinkler8). Много не проверял, но на первый взгляд работает. Для tiny модели памяти, si - адрес сжатых данных; di - куда распаковывать. Получилось 217 байт, пока что код ужасный, уверен, что можно улучшить.

- - - Добавлено - - -

Забыл в исходнике упомянуть, что компилировал FASMом. Не то, чтобы это было принципиально, но на всякий случай.

ivagor
10.10.2019, 18:07
Выложил (https://gitlab.com/ivagor/deshrinkler8) оптимизированную версию для 8088/86. Она на 25 байт короче и на 30% быстрее (замерял в emu).
Чтобы оправдаться за оффтоп напишу, что в процессе баловства с 8088 появилась идея по оптимизации и версии для 8080.

svofski
10.10.2019, 18:50
Не оффтоп ни разу.
Надо для Вектора эмуляцию 8088.

ivagor
10.10.2019, 19:14
У меня смутные воспоминания, что вроде обсуждали эту тему, поэтому скорее всего повторюсь. Я за эмуляторы всего на всем. Если конкретнее, то и за 8088 на 8080 тоже. Сложность в объеме работ (и тестирования) и, понятное дело, в чудовищно низкой производительности. Но я все равно за. Осталось дождаться увлеченного человека, который сделает сам или богатого спонсора, который купит аутсорсных программеров. В Индии вроде еще используют киты с 8085 для обучения (хотя я несколько лет назад что-то читал, может уже и не используют), наверно там можно найти людей в теме.

ivagor
27.10.2019, 17:40
Немного оптимизировал версии LZSA1 для 8080 (https://gitlab.com/ivagor/lzsa8080/). Убрал самомодификацию и сократил быстрый вариант на 4 байта, компактный - на 2.

KTSerg
27.10.2019, 19:14
Пардон за фоотоп.
В начале "нулевых" читал рассказ (распространявшийся по Фидо и BBS) про программиста. Который писал код для микроконтроллера, и программа, после всех возможных оптимизаций, не помещалась в ПЗУ на 1 Байт. Как попытки оптимизировать этот Байт довели его почти до безумия... но привели к "прозрению"... В результате программа поместилась в память, но интересен был именно сюжет, размышления.
Просто напомнило :)

ivagor
27.10.2019, 19:46
"Все почти с ума свихнулись, даже кто безумен был".
Достижение нулевого размера всех распаковщиков и их бесконечной скорости неминуемо завершит прогресс в этой области, но скорее всего я не буду заходить так далеко и просто ограничусь выкладыванием имеющихся наработок до НГ.

dbk
19.11.2019, 10:48
Пардон за фоотоп.
В начале "нулевых" читал рассказ (распространявшийся по Фидо и BBS) про программиста. Который писал код для микроконтроллера, и программа, после всех возможных оптимизаций, не помещалась в ПЗУ на 1 Байт. Как попытки оптимизировать этот Байт довели его почти до безумия... но привели к "прозрению"... В результате программа поместилась в память, но интересен был именно сюжет, размышления.
Просто напомнило :)

История одного байта https://habr.com/ru/post/27055/

ivagor
09.05.2020, 16:15
По степени сжатия между MegaLZ/LZSA2 и exomizer располагается aPLib/aPack, но предыдущий рапаковщик, который я выкладывал, был медленноват (ближе к exomizer и в 2 раза медленнее MegaLZ). Новый распаковщик (https://gitlab.com/ivagor/unapack/-/tree/master/8080) медленнее MegaLZ уже только в полтора раза, по размеру равен быстрому распаковщику MegaLZ b2ma (210 байт) и не использует самомодифицирующийся код.
Сделал еще в прошлом году, думал может еще оптимизирую, но новые идеи не появились. Зато появились два новых хороших упаковщика: apultra (https://github.com/emmanuel-marty/apultra) от автора LZSA и oapack (https://zx-pk.ru/threads/23155-szhatie-i-upakovka-obsuzhdenie-i-sravneniya.html?p=1061809&viewfull=1#post1061809). apultra быстрый, oapack очень медленный, но иногда выигрывает несколько байтов.

ivagor
13.05.2020, 16:07
Глянул распаковщик spke для z80 из комплекта apultra и там он отметил, что в распаковщиках для z80 пропускали детект длинных смещений. И действительно, в использованном мною в качестве прототипа варианте тоже пропустили. Доработал (https://gitlab.com/ivagor/unapack), +5 байт, а что делать.

ivagor
31.12.2020, 11:28
Автор распаковщика shrinklera для z80 обновил (https://www.cpcwiki.eu/forum/programming/modified-shrinkler-without-parity-context/) его и соответственно доработал упаковщик. Сплошные плюсы: сжимает чуть лучше, распаковщик компактнее и работает чуть быстрее. Добавил такую версию и для 8080 (https://gitlab.com/ivagor/deshrinkler8/-/tree/master/i8080)

NEO SPECTRUMAN
31.12.2020, 13:42
Автор распаковщика shrinklera
а ему надо только 2К буфер? и надо ли еще7
или он тоже лезет в распакованное?

ivagor
31.12.2020, 14:23
а ему надо только 2К буфер? и надо ли еще7
или он тоже лезет в распакованное?
Шринклер - это lz+арифметическое кодирование, он лезет в распакованное +еще 2.5 Кб на таблицы.

ivagor
11.01.2021, 21:06
Новый эксомизер (https://bitbucket.org/magli143/exomizer/wiki/Home) 3.1.0 - сжимает лучше, фич больше, багов меньше. Распаковщики для 8080 (и не только) в комплекте. Поправлю Магнуса - "experimental split encoding feature for encoding reuse" поддерживается не только распаковщиком для 6502, но и для 8080 (P43E).

NEO SPECTRUMAN
12.01.2021, 09:00
Новый эксомизер 3.1.0 - сжимает лучше, фич больше
и как оно в сравнении с Shrinkler-ом теперь?

если быть точнее мне надо максимально сильно запаковать пзу-шку от 48-го для распаковки на 8080 :)

ivagor
12.01.2021, 09:05
Глобально ничего не изменилось, shrinkler сжимает сильнее, но распаковывает очень-очень долго, а эксомизер сжимает немного хуже, но распаковывает хотя и долго, но за приемлемое время. Шринклер8080 годится разве что для небольших дем (килобайт до 4), а эксомизер самый мощный из практичных, им можно и 40-50 Кб запаковать и дождаться пока распакует.

NEO SPECTRUMAN
12.01.2021, 09:10
очень-очень долго
блин поделил такты из таблицы и немножко охренел
быстрей загрузить с мафона чем распаковать :v2_lol:

NEO SPECTRUMAN
21.01.2021, 05:13
8080 версия для SJASM мнемониками z80 (компактная та что P43)

Exomizer_3_i8080_depacker r0005
https://www.mediafire.com/file/gy7hrhjcddknev2/Exomizer_3_i8080_depacker_r0005.7z/file

как всегда в виде готового темплета рабочего из коробки

проверены все 4 варианта на 2-х файлах

реюзабельность как таковая не проверялась

использовать на свой страх и риск
Я не гарантирую 100% работоспособность

NEO SPECTRUMAN
21.01.2021, 15:50
ivagor, а ты втыкал зачем переменная reuse_offset_state?

и зачем для reusable-а
нужен inc a?

mov b,a
mov c,a
#IFDEF REUSABLE
inr a
#ENDIF
jmp exo_mainloop



exo_mainloop:
sta reuse_offset_state+1


я подправил для работы в ПЗУ
с такой инициализацией при старте


ld a,$01
ld (reuse_offset_state),a


и теперь этот инкримент выглядит совершенно непонятно зачем
тем более в маинлупе

- - - Добавлено - - -

да и без него теперь по ходу и не работает о_О

- - - Добавлено - - -

3Ы речь про P43 без E

b2m
15.02.2021, 10:47
Интересную картинку увидел на соседнем форуме:

https://introspec.retroscene.org/compression/pareto_20210128.png

ivagor
15.02.2021, 12:06
zx0 рулит, практически убил эксомизера, это и к лучшему.

b2m
15.02.2021, 12:55
Интересно, где бы оказался мой распаковщик MegaLZ для i8080, правее, или левее?

ivagor
15.02.2021, 17:03
Выложил распаковщик (https://gitlab.com/ivagor/dezx0/) ZX0 (прямой+обратный) для 8080. Можно чуть ускорить за счет самомодифицируемого кода, но пусть лучше будет максимально универсальная версия. Жить стало лучше и веселее, aplib/apultra теперь совсем не нужен, exomizer почти совсем не нужен (он изредка может сжать чуть сильнее zx0, но распаковщики в 2-3 раза медленнее и в 2.5-3 раза крупнее и еще нужно место под таблицу). Выбор упаковщиков/распаковщиков общего назначения для 8080 упростился, если выстроить от быстрых к мощным, то: lzsa1 - lzsa2 - zx0. Для некоторых специальных случаев подойдут обобщенный zx7 от автора zx0 или shrinkler.


Интересно, где бы оказался мой распаковщик MegaLZ для i8080, правее, или левее?
Если вопрос о сравнении с ZX0, то твой megalz правее (быстрее почти на четверть), но распаковщик ZX0 можно немного разогнать, тем более текущий вариант в 2 раза меньше твоего megalz. И на данный момент, если устраивает степень сжатия megalz, то лучше lzsa2, его распаковщик быстрее и немного компактнее.

Eugene85
15.02.2021, 20:55
b2m, хоть бы ссылку на форум дали

ivagor
16.02.2021, 08:09
Возможно у кого-то возникнет вопрос "а как же zx1?". Он распаковывает быстрее zx0, но
1. По степени сжатия соревнуется с megalz с переменным успехом
2. Немного не догнал megalz b2m по скорости (хотя небольшой резерв есть)
3. Размер распаковщика несколько больше, чем у zx0, и пришлось использовать самомодифицирующийся код. Тем не менее почти двукратная разница с megalz по этому параметру, это плюс. Но zx0 то еще компактнее и сжимает сильнее, а проигрыш по скорости на мой взгляд не такой принципиальный. Если важна именно скорость при близком к megalz и zx1 сжатии, то есть lzsa2.

b2m
16.02.2021, 13:27
b2m, хоть бы ссылку на форум дали
Та ради Бога: http://www.nedopc.org/forum/viewtopic.php?p=159208#p159208

Но ноги растут вот отсюда: https://hype.retroscene.org/blog/933.html

ivagor
16.02.2021, 17:01
Переосмыслил, доработал и выложил распаковщик ZX1 для 8080 (https://gitlab.com/ivagor/dezx1).
1. Разогнал до "быстрее megalz".
2. Убрал самомодифицирующийся код.
3. Внимательно перепроверил степень сжатия с учетом размеров распаковщиков (распаковщик ZX1 на 79 байт, т.е. более чем на треть, короче megalz). Оказалось, что там, где zx1 проигрывает megalz, это более чем компенсируется компактным распаковщиком. А вот там, где zx1 сжимает лучше, выигрыш может быть гораздо более заметным (в отдельных случаях до нескольких килобайт!). В итоге по степени сжатия в этой паре безоговорочная победа у zx1.

Обновленная шкала упаковщиков/распаковщиков общего назначения для 8080 от быстрых к сильно сжимающим: lzsa1 - lzsa2 - zx1 - zx0
Еще один момент - у всех перечисленных распаковщиков есть прямой и обратный варианты (у megalz только прямой).

MegaLZ хороший упаковщик и распаковщик b2mа в свое время поднял планку и задал ориентир для подражания на платформе 8080, но современные еще лучше.

ivagor
17.02.2021, 09:03
обобщенный zx7 от автора zx0
Поправка - оригинальный zx7 от автора zx0 (Einar Saukas), а автор обобщенного - Antonio Villena.

ivagor
17.02.2021, 17:02
Немного оптимизировал распаковщики ZX0 (https://gitlab.com/ivagor/dezx0) и ZX1 (https://gitlab.com/ivagor/dezx1)

ivagor
22.02.2021, 09:03
Еще ускорил и сократил распаковщики zx0 (https://gitlab.com/ivagor/dezx0) (теперь и прямой и обратный меньше 100 байт) и особенно zx1 (https://gitlab.com/ivagor/dezx1).

ivagor
23.02.2021, 15:02
Сегодня можно отметить день оптимизации распаковщиков.
ZX0 (https://gitlab.com/ivagor/dezx0) - на байт короче и чуть быстрее.
Успехи в оптимизации ZX0/1 мотивировали вернуться к LZSA (https://gitlab.com/ivagor/lzsa8080). Т.к. LZSA по степени сжатия не соревнуется с ZXами, сосредоточился на их сильной стороне - скорости.
LZSA2:
Стандартный +3 байта, зато обогнал быстрый вариант предыдущей версии.
Быстрый +1 байт и стал еще быстрее.
LZSA1:
Компактный +3 байта, но заметно ускорился.
Быстрый -25 байт! и при этом немного обгоняет предыдущую версию.

Improver
24.02.2021, 13:16
ivagor, заглянул в исходники быстрого распаковщика LZSA1 (LZSA1_unlzsa1_fast.asm), сразу заинтересовал один момент:

BLOCKCOPY1:
mov a,m
stax d
NEXT_HL
NEXT_DE
dcr c
jnz BLOCKCOPY1
dcr b
jz $+6
jmp BLOCKCOPY1
pop h
и

BLOCKCOPY2:
mov a,m
stax d
NEXT_HL
NEXT_DE
dcr c
jnz BLOCKCOPY2
dcr b
jz $+6
jmp BLOCKCOPY2
pop psw
Почему бы там не сделать так:

BLOCKCOPY1:
mov a,m
stax d
NEXT_HL
NEXT_DE
dcr c
jnz BLOCKCOPY1
dcr b
jnz BLOCKCOPY1
pop h
и

BLOCKCOPY2:
mov a,m
stax d
NEXT_HL
NEXT_DE
dcr c
jnz BLOCKCOPY2
dcr b
jnz BLOCKCOPY2
pop psw
Вроде, будет короче ещё на 6 байт... Или такой вариант приведёт к снижению скорости распаковки?

ivagor
24.02.2021, 14:16
Или такой вариант приведёт к снижению скорости распаковки?
Да, так (на типичных файлах) быстрее, т.к. преобладают короткие пересылки. Вариант

Почему бы там не сделать так
есть в zx1, но он там вынесен в отдельную ветку (если занести в основную ветку, то будет медленнее). Проверял lzsa1 с таким же вариантом как сейчас в zx1, было чуть-чуть быстрее, но +7 байт, посчитал, что того не стоит. У меня есть "секретный" мегатурбо вариант lzsa1, он еще быстрее, но большой до такой степени, что счиатю его непрактичным.

ivagor
24.02.2021, 17:06
Идея b2mа (dcr старшей половины\ jp ldir для фрагментов<8100h байт), которую он потер, интересная. По скорости немного уступает выложенному варианту и практически совпадает с невыложенным (про который написал выше), только на 6 байт короче. Это здорово, но для таких специфических вещей я сейчас предпочитаю поддержку упаковщика. Или чтобы он писал при сжатии максимальную длину пересылаемого фрагмента или лучше обобщенный вариант с возможностью выбора параметров (как saukav для zx7).

b2m
24.02.2021, 17:20
Я исходил из того, что копирование 32Кб данных в адресном пространстве, которое только 64Кб, вряд-ли случится.

- - - Добавлено - - -

Хотя, если копирование используется и для повторения коротких одинаковых фрагментов (а-ля копирование вперёд с пересечением), то да, таки случится...

- - - Добавлено - - -

Поэтому и потёр.

ivagor
24.02.2021, 22:24
Improver, спасибо! После многочисленных замен я зарапортавался и затупил, конечно убирание jz $+6 убавит 6 байт (по скорости практически без изменений). Заменил unlzsa1_fast.asm и unlzsa2_fast.asm. Быстрее было, когда в процедуре rz\ jmp цикл (как в небыстрых вариантах), а когда занес в тело программы, замена rz на jz ничего хорошего не дает, кроме плохого. Вариант пересылок в zx1 еще быстрее, но он и больше по размеру. b2mу тоже спасибо, заставил задуматься.

b2m
25.02.2021, 10:23
зарапортавался и затупил, конечно убирание jz $+6 убавит 6 байт
Мне сначала тоже так показалось, но я подумал, что может я чего-то не понимаю. Потом я хотел предложить inr d перед циклом, чтобы избавиться от FastLdir, но оказалось, что твой вариант всё-же быстрее. Потом я предложил хоть что-то, но подумав, взял и потёр всё. А ты, как оказалось, всё-же заметил мои поползновения :)

ivagor
25.02.2021, 11:06
Твой вариант имеет смысл при двух условиях:
1. Длина пересылаемого фрагмента <8100h
2. После завершения цикла старший байт счетчика не обязан быть =0
Тогда преимущество перед вариантом, который оптимизировал Improver - можно убрать преинкремент, т.е. -1 байт и чуть быстрее

ivagor
25.02.2021, 17:03
Получилось неплохо ускорить zx1 (https://gitlab.com/ivagor/dezx1) без увеличения размера.

ivagor
25.02.2021, 21:06
Все же "простая" быстрая пересылка не совсем правильная, пришлось доработать и усложнить. zx1, lzsa1_fast и lzsa2_fast исправил, lzsa2 и lzsa1_small вернул. Мораль такова, что пересылка все же стала быстрее, но она громоздкая и ускорение меньше, чем у простого неправильного варианта.

ivagor
26.02.2021, 19:03
Досообразил более компактный (но и чуть более медленный) вариант ускорения цикла, апгрейдил unlzsa1_small и unlzsa2. Вряд ли я первым изобретаю этот велосипед, тема оптимизации циклов с 16 разрядным счетчиком актуальна и для z80 (речь не про ldir), наверняка спектрумисты и/или msxники уже писали что-то такое, интересно бы сравнить.
Из сообщений может показаться, что все упирается только в пересылку, на самом деле например в последних модификациях dzx1 основной выигрыш связан с другими модификациями. Скорость переброски наиболее важна в простых распаковщиках типа lzsa1.

- - - Добавлено - - -

Действительно, msxники писали (http://map.grauw.nl/articles/fast_loops.php#fastloops) про эту тему, и я даже когда-то давно читал, но потом забыл. Компактный вариант фактически украл с z80 (с поправкой на отсутствие djnz), а вот более быстрый я получается все же допридумал. Но с z80 просто не было необходимости, у них компактный по скорости равен быстрому, у 8080 inr/dcr/inx/dcx медленнее, поэтому есть разница.

NEO SPECTRUMAN
28.02.2021, 11:04
Компактный +3 байта, но заметно ускорился.
ну обычно компактные не ускоряют а уменьшают
чтоб вставлять в 128бит демке :)

ivagor
28.02.2021, 13:01
Главное достоинство lzsa1 - скорость и любые варианты его распаковщиков плохо подходят для sfx версий суперкомпактных программ. Для микродем и других подобных применений есть zx7mini, а еще лучше saukav с соответствующими настройками.

ivagor
01.03.2021, 17:04
Оказалось, что для упрощения изобретения велосипеда с быстрым циклом не обязательно было вспоминать msxную статью. Уже год лежат распаковщики lzsa для ГеймБоя использующие эту фишку.

ivagor
18.03.2021, 19:06
Для микродем и других подобных применений есть zx7mini, а еще лучше saukav с соответствующими настройками.
Einar Saukas сделал отдельный упаковщик ZX2 (https://github.com/einar-saukas/ZX2) и для решения этой задачи. К сожалению мне негде выложить распаковщики, но их сравнительно просто можно переделать из уже выложенных (проще взять за основу ZX0). Для 8080 получилось 68-79 байт (в зависимости от опций).

einar
02.04.2021, 20:37
Спасибо всем за интерес к ZX0, ZX1 и ZX2, я очень ценю это. Отдельное спасибо ivagor за отличную работу по портированию их на PDP11 и 8080!

К сожалению, репозитории ivagor на gitlab перестали работать несколько дней назад. Кто-нибудь знает, переехали ли они по другому адресу? Я хотел бы дать ссылку на них в своей документации, но нигде не могу их найти.

ivagor
02.04.2021, 21:03
Einar, thank you for very good compressors! I'm searching for a new place for decompressor sources.

einar
02.04.2021, 22:42
Я очень рекомендую https://github.com/

ivagor
05.04.2021, 19:04
Пробую github, для начала распаковщики для ZX0/1/2 (https://github.com/ivagorRetrocomp/DeZX). Про ZX0/1 писал раньше, добавлен ZX2 (хорошо подходит для небольших файлов, замена для zx7mini/saukav). Поддерживаются все опции, в зависимости от них размер распаковщика 68-79 байт. Это больше, чем самый компактный распаковщик zx7mini (53 байта), но на примере теста техпрогона (исходно 1024 байта):
zx7mini: 53 байта распаковщик + 898 байт упакованный файл = 951 байт
zx0: 97 байт распаковщик + 813 байт упакованный файл = 910 байт
zx2: 68 байт распаковщик + 822 байта упакованный файл = 890 байт
Пока я не нашел маленьких файлов, на которых zx7mini был бы лучше zx2 по суммарному размеру связки распаковщик+упакованный файл. Слишком маленькие и плохо сжимаемые файлы в соревновании не участвовали, т.к. если распаковщик+упакованный файл больше исходного, то конечно нет смысла в такой упаковке.

einar
05.04.2021, 19:42
благодарю вас!

ivagor
05.04.2021, 20:14
Einar, it would be great to add option to force limited block length (maybe modified -y ?) for ZX2 even if it is not optimal. For example we got 100 short separately compressed fragments in programm and for 99 of them limited length is enough. I want to use limited block length unpacker for all 100 of them in this case.

einar
07.04.2021, 06:04
Einar, it would be great to add option to force limited block length (maybe modified -y ?) for ZX2 even if it is not optimal. For example we got 100 short separately compressed fragments in programm and for 99 of them limited length is enough. I want to use limited block length unpacker for all 100 of them in this case.

Yes, I was already planning to make parameter -y work this way, but I need more time.

It's easy to make ZX2 compressor generate a non-optimal output with limited length. But not so easy to make ZX2 compressor generate the best possible output within this length limit. Some of my current implementation optimizations assume unlimited length so I have to rethink everything to make this work properly.

ivagor
12.04.2021, 19:02
Довыложил "старые" распаковщики на github (https://github.com/ivagorRetrocomp). Постарался соблюсти минимализм по широте охвата (добавил только LZSA и Shrinkler) и по глубине (количество вариантов).

ivagor
16.08.2021, 17:08
Сократил (прямой на 4, обратный на 3 байта) и немного ускорил распаковщик zx0 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX0/8080).
Распаковщик zx2 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX2/8080) сократил на байт, скорость не изменилась.
Интересно, что у zx0 и zx2 примерно одинаково масштабировался размер, варианты для 8080 в 1.37-1.39 раза больше, чем для z80. Понятно, что использованные команды и их сочетания примерно одинаковые, но все равно интересно получилось.
Еще вспомнил и выложил распаковщик shrinklera для x86 (https://github.com/ivagorRetrocomp/DeShrinkler/tree/main/x86) (ему хватает 8088/8086).

ivagor
17.08.2021, 17:02
Сократил прямой zx0 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX0/8080) еще на 2 байта и чуть-чуть ускорил.
Попробовал посчитать вклад отдельных отличий z80 от 8080 в разницу размеров версий (всего +23 байта):
1. ldir - +13 байт
2. jr vs j* - +5 байт
3. Неаккумуляторные команды ротации - +3 байта
4. Дополнительный регистр - +2 байта
Думаю, что граница оптимизации по размеру или достигнута или совсем рядом.

ivagor
19.08.2021, 17:07
В zx2 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX2/8080) заметил, что с опцией -y можно сократить на байт, соответственно и минимальный размер распаковщика уменьшился до 66 байт

ivagor
20.08.2021, 18:23
И еще оптимизировал вариант zx2 с опциями -y -b. Вижу в этом сразу 2 плюса:
1. Минимальный (обратный) вариант стал на байт короче - 65 байт.
2. Избавился от перекрестного влияния опций на размер, теперь каждая опция убавляет заданное число байт независимо от других, проще понять, что выбрать.

ivagor
13.09.2021, 16:07
Небольшой комментарий по поводу последних модификаций ZX0.
1. Оптимизация обратного распаковщика для z80 не вдохновила, если сделать аналогично для 8080, то весь эффект ограничивается небольшим замедлением распаковщика.
2. Смена формата упаковщика для прямого сжатия еще менее интересна. Распаковщик 8080 с ее учетом становится на байт длиннее и чуть медленнее. Проблем тут не возникает, можно пользоваться или предыдущей версией упаковщика или последней с опцией -c. По степени сжатия у v1 и v2 разницы никакой, только распаковщики v2 для z80 на байт компактнее и чуть-чуть быстрее.

ivagor
05.10.2021, 17:03
Einar Saukas выложил экспериментального соперника для своего zx0 - zx5 (https://github.com/einar-saukas/ZX5), а я сделал вариант распаковщика для 8080 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX5/8080). Официально экспериментальность влияет на скорость сжатия (очень-очень-очень медленно) и в принципе на возможность оптимального сжатия некоторых файлов. Скорость сжатия меня не сильно волнует, один раз сжимаем, потом всю жизнь пользуемся. А вот то, что из моих тестовых файлов (21 штука) один не получилось сжать оптимально - это немного печально, но не смертельно. Больше расстраивает то, что большинство моих файлов zx5 сжал хуже, чем zx0. Если учитывать размер распаковщика, то zx5 выиграл на 3 файлах из 21. В общем если размер упакованного файла очень критичен и zx0 немного не дожимает, можно попробовать zx5. Если zx5 не помог, то остаются exomizer и shrinkler, но их распаковщики еще больше по размеру и еще медленнее, особенно shrinkler. Распаковщик zx5 я оптимизировал по размеру, но с ограничением - без использования самомодифицирующегося кода. С самомодификацией можно немного ускорить и сократить.

ivagor
22.10.2021, 17:06
Хочется чем-то заполнить пробел между zx0 и shrinklerом. Первое, что приходит в голову - LZ+Хаффман. Из этой оперы есть распаковщики формата Deflate для z80, один из них (samflate, поддерживает контейнер gzip) я попробовал.
1. Степень сжатия. Для максимального сжатия использовал 7zip с уровнем сжатия ultra. Неожиданно оказалось, что на моем наборе файлов deflate расположился между zx0 и zx1. Некоторые файлы сжал лучше, некоторые хуже, победить zx0 не получилось.
2. Скорость распаковщика. Распаковывает медленнее exomizera, но все равно намного быстрее shrinklera. Хотелось бы быстрее, но и так терпимо.
3. Размер распаковщика. А вот тут совсем беда - 2 Кб + нужно место для таблиц.
Примеривался я к deflate с прицелом на конверсию для 8080, но по совокупности полученных результатов конверсить расхотелось.

Также более подробно потестировал unrar 0.61 для z80, про который уже немного писал раньше. Он поддерживает формат rar 2.0 и по степени сжатия на моем наборе файлов оказался очень близок к deflate в исполнении 7zip, между zx0 и deflate. Но когда начал тестировать распаковку из 5 первых попробованных файлов правильно распаковались только 2, дальше не стал пробовать. Если доработают можно будет вернуться, а пока для меня rar отпадает.

Итоги:
1. На базе samflate можно сделать распаковщик gzip для вектора с z80, но вроде особой потребности в этом нет.
2. Нужен более удобный для слабосильных ретрокомпьютеров вариант формата LZ+Хаффман, чтобы размер распаковщика был сравним со shrinklerом или чуть больше.

Eugene85
23.10.2021, 02:33
ivagor,
Под п.2 из существующих более-менее подходит RIP и mRIP.

ivagor
23.10.2021, 07:12
Eugene85, я читал про rip (и даже писал (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1024606&viewfull=1#post1024606)). Сейчас меня от более близкого знакомства с rip/mrip отталкивают две вещи:
1. Нет упаковщика для PC, или я его просмотрел.
2. По степени сжатия, насколько я понял, уступает rar, т.е. уступает и zx0, что еще снижает интерес.

metamorpho
17.11.2021, 00:07
Написал для Вектора демку - получилось 274 байта, а нужно 256 байт.
Для интереса попробовал 7zip-ом упаковать - получилось 386 байт
Попробовал zip-ом упаковать - получилось 412 байт
Попробовал gzip-ом упаковать - получилось 286 байт
Т.е. итоговый файл больше чем исходный.
Я не очень хорошо ориентируюсь в упаковщиках, поэтому подскажите
каким упаковщиком и распаковщиком лучше воспользоваться для Вектора ?

svofski
17.11.2021, 01:13
Я пользовался zx7mini в адаптации ivagor-a под 8080.

https://github.com/svofski/bazis-bbstro/tree/master/zx7mini

ivagor
17.11.2021, 06:10
274 байта это слишком мало, для того чтобы эффективно использовать упаковщики. zx7mini был хорош до появления zx2 (https://github.com/einar-saukas/ZX2), в настоящее время zx2 лучший вариант для микродем и других подобных применений (распаковщик для 8080 (https://github.com/ivagorRetrocomp/DeZX/blob/main/ZX2/8080/dzx2.asm)). Но он будет эффективен начиная с размеров байт 900-1000 (учитывая размер распаковщика), а 274, на мой взгляд, можно только руками попробовать сократить.

metamorpho
17.11.2021, 10:04
svofski, ivagor спасибо за ответы !!

Что ж буду вручную ужимать код. Хотя кажется уже всё что можно было сократил.
Осталось убрать 18 байт :)

metamorpho
17.11.2021, 13:28
На всякий случай попробовал сжать

-->> zx7mini выдал файл rom на 358 байта (это вместе с распаковщиком)
-->> zx2 выдал файл fzx на 242 байта (это БЕЗ распаковщика)

т.е. всётаки нужно самому вручную оптимизировать код моей демки

Sandro
17.11.2021, 14:06
274 байта это слишком мало, для того чтобы эффективно использовать упаковщики.

Мало, но всё таки возможно. Моя экспериментальная no copper пратически целиком состоит из распаковщика и упакованной картинки. https://www.pouet.net/prod.php?which=87753

ivagor
17.11.2021, 14:21
В частном случае, когда микродема состоит в значительной степени из картинки, упаковка конечно может помочь, но тут уже скорее кастомизация упаковщика/распаковщика будет предметом демомейкерства.

reddie
17.11.2021, 14:54
буду вручную ужимать код. Хотя кажется уже всё что можно было сократил.
Всегда можно найти, что еще оптимизировать =)) Когда идеи закончатся, можно выложить, а там народ поскажет, где и как.

Sandro
17.11.2021, 15:35
В частном случае, когда микродема состоит в значительной степени из картинки, упаковка конечно может помочь, но тут уже скорее кастомизация упаковщика/распаковщика будет предметом демомейкерства.

Ну да, у меня там так и есть. Всё написание микродемы (около двух недель) было посвящено изобретению алгоритма упаковки, позволяющего запихать туда эту картинку. Изобрёл, правда, чуть более общий, там можно что угодно на картинке нарисовать, ну да ладно.

Собственно, вот код с детальными комментариями: https://github.com/sandro-tishin/nocopper/blob/main/nocopper11m.asm

Повторюсь, это я просто в качестве иллюстрации, что паковать даже при таком размере имеет смысл.

Eugene85
19.03.2022, 22:26
Сделал компрессоры RIP и mRIP на PC.
Кто там хотел компрессор на базе LZ+Хаффман и заполнить пробел между zx0 и shrinklerом? Всё как заказывали :)

https://gitlab.com/eugene77/rip
https://gitlab.com/eugene77/mrip

ivagor
20.03.2022, 07:01
Набор тестовых файлов у меня на другом компе, но предварительные тесты (пробовал только RIP) показывают, что очень хороший вариант, похоже жмет лучше, чем gzip. Распаковщик для 8080 будет (если будет) большой и медленный, но все же явно быстрее шринклера.

Sandro
20.03.2022, 09:40
Сделал компрессоры RIP и mRIP на PC.
Кто там хотел компрессор на базе LZ+Хаффман и заполнить пробел между zx0 и shrinklerом? Всё как заказывали :)


Жаль, формат данных не документирован хоть как-нибудь. Без этого сложно оценивать алгоритм. Я правильно понимаю, что в начале количеством единиц кодируется адрес в таблице, откуда распаковываются длины кодов смещения и количества, сколько там бит ещё прочитать из потока для из заполнения?

lexarr
21.03.2022, 16:11
Исходник распаковщика, использующего алгоритм NRV2d из библиотеки UCL (такие упаковщики уже были, основной способ сжатия UPX).
Размер - около 200 байт. Сжатие - неплохое, но уступает остальным (zx0, hrust, apack, rip). Распаковка одна из самых быстрых, это основное преимущество. Обращаю внимание, оригинальный поток, запакованный с помощью утилиты uclpack, не подходит. Как переделать написано: в функции ucl_nrv_99_compress() поменять одно значение (финальный маркер, с длинного на короткий), и осуществить пересборку из исходника (упаковщик n2dpack прилагается). Пример использования (https://zx-pk.ru/attachment.php?attachmentid=74083) (для ПК «Специалист»): исходный размер – 17 кБ, сжатый – 5 кБ.
Оставлю, может кому пригодится.

Eugene85
21.03.2022, 17:48
Sandro, неправильно.

Добавил краткое описание формата (https://gitlab.com/eugene77/rip/-/blob/master/format_description.txt).

ivagor
24.03.2022, 17:04
Прикидочная (за час) версия derip8080 получилась 372 байта и почти в 5 раз медленнее zx0. Оптимизировать несомненно можно и по размеру и по скорости, но вряд ли в разы. RIP с упаковщиком Eugene85 хорошая, но все же ограниченно пригодная для 8080 штука.

Eugene85
25.03.2022, 00:38
Я только сейчас осознал, что тема не имеет отношения к Спектруму :) Всё думал, причём тут 8080....


и почти в 5 раз медленнее zx0
Ну то есть примерно как на Z80.

ivagor
27.03.2022, 08:17
RIP (или какой-нибудь другой упаковщик будущего с LZ+Хаффманом) можно сделать более дружественным для 8080 (и не только для 8080), если реализовать пару вещей, которые дружно сделаны в новейших ретроупаковщиках:
1. Развернуть битовый поток в другую сторону. Делал такую утилиту постобработки для эксомизера, но потом там добавили опцию в самом упаковщике, что, конечно, более удобно.
2. Сделать смещение отрицательным, чтобы учитывать его не по SBC, а по ADD. Это уже потребует не совсем механических правок распаковщика и не так важно, как п.1

Eugene85
27.03.2022, 16:21
1. Развернуть битовый поток в другую сторону.
Это, конечно, легко. Если когда-нибудь публично появится декомпрессор, ориентированный на это, сделаю опцию, не проблема.


2. Сделать смещение отрицательным
А вот это проблема. Декомпрессор придётся существенно удлинить, а он и так немаленький; в общем, нет смысла. Не знаком с архитектурой 8080, но думаю можно использовать 8-битные SUB+SBC, как это сделано в декомпрессоре mRIP (https://gitlab.com/eugene77/mrip/-/blob/master/z80/demrip_fast.asm).
Другое решение: сжатие задом наперёд, тогда нужна будет именно ADD.

ivagor
27.03.2022, 17:07
можно использовать 8-битные SUB+SBC
Примерно так я и делаю, вопрос не в принципиальной невозможности, а в компактности кода.

Декомпрессор придётся существенно удлиннить
Если речь про z80, то (по аналогии с декомпрессорами, использующими такой подход) думаю можно переделать и без удлинения, но надо внимательно посмотреть и подумать.

ivagor
28.03.2022, 07:19
Развернул битовый поток. derip8080 стал на 9 байт короче и на 4 с копейками процента быстрее.

ivagor
30.03.2022, 07:13
Свет в конце тоннеля есть, сократил derip8080 до 330 байт и теперь он не в 5 раз медленнее zx0, а в 4. Меня пока не совсем устраивает, но уже похоже на что-то приемлемое. Т.к. для rip, в отличие от эксомизера, можно просто развернуть все биты в байтах, то думал воспользоваться какой-нибудь готовой бесплатной утилиткой и потом дать на нее ссылку на гитхабе, но неожиданно не нашел такой. Свою я конечно накропал, но может кто подскажет готовую?

lexarr
30.03.2022, 14:25
... можно просто развернуть все биты в байтах, то думал воспользоваться какой-нибудь готовой бесплатной утилиткой и потом дать на нее ссылку на гитхабе, но неожиданно не нашел такой. Свою я конечно накропал, но может кто подскажет готовую?
Без изменения порядка байт:
81887

ivagor
30.03.2022, 15:10
Спасибо! Еще и компактнее, собственный вариант у меня получился 9.5 Кб, а тут 3.5

ivagor
04.04.2022, 20:12
При адаптации z80->8080 один из вопросов - во сколько раз увеличится размер? Можно попробовать оценить для такой задачи, как распаковщики LZ(+). Если взять zx0 и zx2, которые долго и упорно оптимизировал именно по размеру, то они разбухли в 1.33 и 1.35 раз соответственно. Текущий derip8080 в 1.38 раз больше deripz80, похоже это говорит о том, что он не так далек от предела.

ivagor
09.04.2022, 07:57
Выложил derip8080 на гитхабе (https://github.com/ivagorRetrocomp/DeRIP). Как уже писали ранее, по степени сжатия упаковщик Eugene85 между zx0 и shrinklerом. По скорости распаковщик в 4 раза медленнее zx0 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX0/8080) и намного быстрее шринклера (https://github.com/ivagorRetrocomp/DeShrinkler/tree/main/8080). Размер распаковщика 317 байт, можно сократить на 4 байта, но замедлится на 17%, поэтому не стал. И не забывайте после компрессии ripом битреверсить файл, например утилитой lexarr.

lexarr
10.04.2022, 21:46
В упаковщик rip непосредственно встроена функция реверсинга битов.

ivagor
30.04.2022, 16:02
После долгого перерыва попробовал улучшить zx0 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX0/8080/OLD_V1). Сократить не получилось, зато чуть-чуть ускорил. Обратите внимание, что адрес упакованных данных теперь в DE, не в HL (стало единообразно с zx1). Еще немного дополнил текстовую преамбулу, указал опции для упаковки и чем компилировать. Распаковщик нового формата для 8080 по-прежнему на байт длиннее и чуть медленнее, поэтому выкладываю только для "классики".

ivagor
03.05.2022, 20:09
Дошли руки и до zx1 (https://github.com/ivagorRetrocomp/DeZX/tree/main/ZX1/8080). Новая версия на 2% быстрее, теперь безоговорочно опережает даже самый быстрый вариант распаковщика megalz для 8080, который почти в два раза больше, и сжимает megalz похуже. Размер прямой версии не изменился, обратная укоротилась на 2 байта.

ivagor
20.06.2022, 18:03
Накопились обновления DeLZSA (https://github.com/ivagorRetrocomp/DeLZSA) и DeZX (https://github.com/ivagorRetrocomp/DeZX), теперь и на гитхабе.
LZSA1 - ускорил быстрый вариант, но он стал побольше. Компактную "прямую" версию сократил на байт.
LZSA2 - добавил вариант с самомодификацией, он немного короче и быстрее. Вариант без самомодификации сократил на байт.
ZX2 - чуть ускорил вариант с опцией -y
ZX5 - немного сократил

Давно надо было прорекламировать альтернативный архиватор для формата zx0 - salvador (https://github.com/emmanuel-marty/salvador)
Он решает основную проблему оригинального упаковщика - сжимает радикально (на порядки!) быстрее, его можно спокойно включать в автоматическую сборку промежуточных вариантов и при этом не терять время. salvador почтиоптимальный, но иногда даже чуть опережает оригинальный оптимальный упаковщик, что вызывает вопрос к оригиналу. Автор пишет о 0.02% разницы в среднем. salvador поддерживает ограничение размера окна поиска совпадений, можно сделать потоковый распаковщик с циклическим буфером. Еще бы добавить ограничение на длину последовательности литералов и поддержать zx1/2 и стало бы совсем хорошо.

parallelno
04.07.2022, 21:18
ivagor, перечитал все ветку на одном дыхании. Как захватывающий фильм. :) Ты проделал огромную работу! Спасибо!

ivagor
04.07.2022, 21:35
Спасибо на добром слове, но основной респект конечно авторам современных архиваторов для ретрокомпов. Ну и некоторым авторам распаковщиков, которые высоко устанавливают планку и дают примеры, как ее преодолеть.

parallelno
13.07.2022, 18:07
metamorpho, выложи пожалуйста свою микродему. Это будет хороший челендж для мини распаковщиков. Я хочу проверить чисто rle компрессорам. Влезет или нет. :)

metamorpho
13.07.2022, 19:39
parallelno, вот здесь она лежит
http://sensi.org/scalar/ware/915/

parallelno
16.07.2022, 12:02
metamorpho, выложи плиз тот вариант который не влазил в 256 байт. Этот упаковывается в 250, но распаковщик в 6 байт нереально для меня написать. :)

metamorpho
16.07.2022, 21:35
metamorpho, выложи пожалуйста свою микродему. Это будет хороший челендж для мини распаковщиков. Я хочу проверить чисто rle компрессорам. Влезет или нет. ...........
metamorpho, выложи плиз тот вариант который не влазил в 256 байт. Этот упаковывается в 250, но распаковщик в 6 байт нереально для меня написать. :)

parallelno, вариант который не влазил был размером 274 байта. Т.е. мне оставалось избавиться от 18 байт. На том этапе я пытался использовать упаковщик - какие были результаты и какие мысли высказали по поводу использования упаковщиков для микродемок, можно посмотреть вот здесь начиная с этого места и дальше
https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1136662&viewfull=1#post1136662

В итоге я убрал 18 лишних байт вручную - при этом видоизменив некоторые моменты демки.

Если тебе нужно для эксперимента воссоздать размер, который не умещался, т.е. 274 байта, то можно добавить вконце ассемблерного кода строку
.db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 ;========== для эксперимента

И получится вот этот ROM (см. вложение)

parallelno
21.07.2022, 07:25
parallelno, вариант который не влазил был размером 274 байта. Т.е. мне оставалось избавиться от 18 байт. На том этапе я пытался использовать упаковщик - какие были результаты и какие мысли высказали по поводу использования упаковщиков для микродемок, можно посмотреть вот здесь начиная с этого места и дальше
https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1136662&viewfull=1#post1136662

В итоге я убрал 18 лишних байт вручную - при этом видоизменив некоторые моменты демки.

Если тебе нужно для эксперимента воссоздать размер, который не умещался, т.е. 274 байта, то можно добавить вконце ассемблерного кода строку
.db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 ;========== для эксперимента

И получится вот этот ROM (см. вложение)

для эксперимента как раз хочется не синтетические данные, а реальные. но это не страшно если тот вариант не сохранился. все равно выглядит что ужать достаточно сильно у меня не получается.
Для интереса написал LZ77 алгоритм, получилось 246 байт, 10 сэкономилось, но распаковщик у меня в 10 никак не влезает. Распаковщик получился в 58 байт.

Хоть и не получилось осилить челендж, но зато многое узнал про алгоритмы сжатия. :)

svofski
28.07.2022, 19:03
ivagor, навскидку -- dzx0 переднепроходный можно переделать на поточный с циклическим буфером 256 байт типа как у меня это получилось с dzx7 ? Или там есть какие-то отличия, которые могут помешать ?

ivagor
28.07.2022, 20:05
Переделать можно все, вопрос в двух параметрах: какие будут скорость и размер распаковщика. Кстати, а ты пробовал сжимать интересующий файл salvadorом с опцией -w255?

svofski
28.07.2022, 20:19
Не-а, я пока только пробовал только zx0 -c, как ты завещал в заголовках к dzx0_CLASSIC.asm. По-моему компромиссы тут приемлемы, размер распаковщика в любом случае маленький, а распаковывать надо, если я понимаю правильно, по 16 байт на кадр, так что ничего страшного. Кстати, Arkos Tracker 2 умеет сохранять ym сгруппированный по регистрам. Делать 16 параллельных потоков zx0 вряд ли хорошая идея, но может быть в этом случае обычный RLE даст хороший результат.

svofski
29.07.2022, 01:49
В общем повозился чуть чуть и адаптировал dezx0 для окна 255 потоком. Жутко криво, надо конечно сделать потом поаккуратней, но в общем это работает.

Примеры: текст (https://svofski.github.io/pretty-8080-assembler/?https://gist.githubusercontent.com/svofski/7880084e5be5a0a62107c875bac61984/raw/7e6a15f7a1bec43037bb0b5f090a7e403f111b76/stardoc.com), шансон 1 (https://svofski.github.io/pretty-8080-assembler/?https://gist.githubusercontent.com/svofski/7880084e5be5a0a62107c875bac61984/raw/7e6a15f7a1bec43037bb0b5f090a7e403f111b76/cancion-nueva.rom), шансон 2 (https://svofski.github.io/pretty-8080-assembler/?https://gist.githubusercontent.com/svofski/7880084e5be5a0a62107c875bac61984/raw/7e6a15f7a1bec43037bb0b5f090a7e403f111b76/ea-demosong.asm).

Если переделать колбаск на немного более человеческий, чтобы можно было поженить с обычным циклом или прерыванием, в общем музон как музон. Но размер получается слонопотамский. Надо все-таки попробовать ym файл, сгруппированный по регистрам.

parallelno
29.07.2022, 10:59
svofski, чистой воды магия! :) Ты потоком распаковываешь музыку и проигрываешь?
А в случае с текстом ты как делаешь? Используешь какую-то функцию операционки для вывода буфера длинной 256 байт?

svofski
29.07.2022, 12:33
parallelno, это было бы разумно так делать, но я просто сделал тупой колбек на каждый символ и печатаю их один за другим. С музыкой то же самое (колбаск следит, когда накопится строка из 16 регистров и выплевывает их в AY). Собственно переделка распаковщика сводится к тому, что по адресу назначения находится циклический буфер 256 байт и inx b заменяется на inr c (и еще пара нюансов связанных с тем же самым). Этот же буфер является окном, поэтому и паковать надо с -w 255.

Думал про группировку ym по регистрам (это когда сначала все фреймы регистра 0, потом все фреймы регистра 1 итд). RLE там делать нечего, по крайней мере на тех примерах, что у меня. Допустим музон "EA demosong" по строкам с окном 255 упаковывается в 17322 байт, а если он по столбцам -- в 2141 при том же размере окна. Но чтобы таким воспользоваться, надо либо распаковать его целиком, что невозможно (ок, можно в кваз, но это неспортивно совсем), либо запаковывать и распаковывать 14 потоков параллельно. Для 14 параллельных потоков надо 14 буферов в 256 байт, что ну как бы тоже так себе прикол -- получается, что мы сэкономили на сжатии, но потом ту же самую память отжали на распаковку. Но с другой стороны это всего 3584 байта, то есть размер более-менее сопоставимый с плохо рекомпилированным плеером pt2.

Еще интересный вариант -- использовать микро-окна. Например 16 байт дает 12137 байт, или 32 байта дают 5836 байт. Допустим для окна 32, нужно всего 448 байт на распаковку 14 потоков и собственно данные 5836 байт.

В принципе этот способ конечно не самый красивый, но мне нравится его универсальность. И для ви53 таким образом тоже можно.

Meanwhile, я заинтересовался плеером в демке polet4k, которая на Базыре не светится так ярко и может быть он покомпактней и поприятней на ощупь. Но это надо вынимать.

ivagor
29.07.2022, 13:11
Насчет 255 это я зря написал, лучше -w256. И я бы особо не рассчитывал на буфер <256 при сжатии сравнительно больших блоков, слишком уж упадет степень сжатия.
Если ты скачал AY_Emul из альтернативного источника и можешь генерировать psg, то есть еще один подход. Можно сжать спецупаковщиком (http://psndcj.blogspot.com/) psg, распаковщик я переводил в 8080, он там простой. Результат упаковки ориентировочно в 3-3.5 раза больше исходного pt3. zx0 с большим окном жмет лучше, с маленьким где-то в этом районе.

svofski
29.07.2022, 13:27
И я бы особо не рассчитывал на буфер <256 при сжатии сравнительно больших блоков, слишком уж упадет степень сжатия.
Я написал в прошлом сообщении цифры, полученные на отдельно взятом, но реальном примере. Буфер = 32 -- золотая середина при организации данных по столбцам. Вот если по строкам, разумеется это вообще почти что ничего.

Вопрос 255 vs 256 меня беспокоил, но время было ближе к 4 утра и я пока оставил его без внимания. Размер выхлопа на этом примере был одинаковый или отличался на пару байт, не стоило того.

Есть еще такой момент, что в YM есть два столбца для регистров, которых у нас нет, и там все равно нули. Но при сжатии по строкам это удобно, потому что выровнено по 16.

Жматель PSG интересно.

- - - Добавлено - - -

"Vortex Tracker - в принципе стандартный ProTracker 3.x (размер плэера 1617 байт)"

Вот тут хочется заплакать. 1617 байт. И в них каждая вторая инструкция не "sta L1234+1 \ L1234 mvi a, 0", вот наверняка.

ivagor
29.07.2022, 14:05
Я написал в прошлом сообщении цифры, полученные на отдельно взятом, но реальном примере. Буфер = 32 -- золотая середина при организации данных по столбцам.
Если я правильно понял, при 255 - 2141, при 32 - 5836. Если такое соотношение устраивает, то вопросов нет.

svofski
29.07.2022, 14:13
Если я правильно понял, при 255 - 2141, при 32 - 5836. Если такое соотношение устраивает, то вопросов нет.

Спору-то нет, что 2141 лучше, чем 5836. Но 2141 потребует дополнительных почти 4кб на распаковку. Но зато их проще попробовать.

Для параллельных потоков в любом случае надо будет вывернуть распаковщик наизнанку, чтобы можно было их несколько штук раунд-робином гонять.

ivagor
29.07.2022, 15:17
Вот тут хочется заплакать. 1617 байт. И в них каждая вторая инструкция не "sta L1234+1 \ L1234 mvi a, 0", вот наверняка.
На запретном сайте есть, среди прочих, вариант плеера (https://bulba.untergrund.net/PTxTools.7z) без самомодификаций (PT3PROM). Размер немного> 2 Кб.

svofski
29.07.2022, 15:26
(Да че-то это malwarebytes дал маху. Жаль, раньше была хорошая штука.)

Но как pt3prom поможет? Он написан на густом z80 с индексными регистрами, бит тестами и проч. Или я куда-то не туда смотрю?

ivagor
29.07.2022, 16:04
На тебя не угодишь :)
Ты покритиковал тот вариант плеера за самомодифицируемость, а я написал, что плееры есть разные (но тоже, увы, не для 8080).

svofski
29.07.2022, 17:49
Сама по себе самомодифицируемость меня в контексте таких вещей вообще не напрягает. Но одно дело, когда это осознанно и автор принял решение, что так будет компактней и быстрее и даже может быть красивше, что на 8080 очень часто случается. Другое дело, когда видно, что автор решения принимал совсем другие и на другой архитектуре, а тут мы имеем просто полуразложившиеся затычки-макроподстановки, которые уже никакой эффективностью и не пахнут.

ivagor
29.07.2022, 20:16
Ждем героя, который портирует pt3 на 8080, а пока жмем дампы. Для меня это одна из задач, которую уже много лет собираюсь решить, но продвижения почти нет.

svofski
30.07.2022, 04:41
а пока жмем дампы
Заметьте, не я это предложил. Декодирование 14 параллельных потоков на ходу (https://svofski.github.io/pretty-8080-assembler/?https://gist.githubusercontent.com/svofski/f41ec5939d75b69bd7a2933f81489df1/raw/8fa591cab4e9a13ee82911005841c6c3f7664a69/gigachad.asm) -- вчерашний пример на 17.5кб усох до 2.5кб. Пришлось написать маленькую RTOS. Не очень эффективно вышло, в 39 экранных строк. Можно бы все-таки не на каждый байт переключать задачи. А еще лучше переписать распаковщик в более подходящем виде -- хотя этот вид оказался совершенно замечательным с точки зрения адаптации: параметр offset на стеке -- это настоящий xthlъ. Сначала я хотел уступать планировщику после LDIR-а, но так выходило не понятно, как синхронизировать потоки -- одни медленно ползут, другие за два лдира пролетают. Проще всего оказалось вставить переключение контекста при сохранении байта. Очень жирно, но зато решает вопрос синхронизации всех потоков. Ржачно получилось по-моему, особенно в Базыре эта шарманка лихо смотрится.

ivagor
30.07.2022, 09:02
Вот так, решил музычку поиграть, и бац - многопоточность с элементами ОС, впечатляет.

ivagor
30.07.2022, 20:05
Возможно ты сам уже оптимизнул, но у меня руки чесались кое-что сократить

parallelno
30.07.2022, 21:09
Класс! Я правда мало что понимаю пока. Но стриминг штука интересная особенно в несколько потоков! Клёва!

svofski
30.07.2022, 22:32
ivagor, я вот заметил, что на многих музонах, где есть что-то напоминающее бас, у меня получается страшное тарахтение. При этом остальные звуки в порядке, так что я не думаю, что тут что-то с распаковкой. Может быть есть какие-то особенности вывода регистровых дампов в AY, которые я не учитываю?

Оптимизацию пока не смотрел, постараюсь попозже.

- - - Добавлено - - -

P.S. Догадываюсь, что это сброс огибающей при записи в R13.
P.P.S Правда, в YM файле в R13 кроме всего прочего записывается FF в пропусках.

ivagor
31.07.2022, 06:24
Здорово, что ты доразобрался с YM, и многопоточность - это круто. Но для полноты картины хорошо бы сравнить с нерасщепленным примерноравнобуферным (256*16=4096, 256*14 неудобно) вариантом. Даже можно не реализовать распаковку (понятно, что будет быстрее и компактнее), просто интересно, до скольки сожмется.

svofski
31.07.2022, 12:54
Этот же пример -- 2069 байт сумма всех потоков если по колонкам и 7742 байт если сохранить по строкам и окно 4096. Вариант по строкам может оказаться полезным если не хватает времени на распаковку всех потоков, например, он однозначно проще и быстрее. Хотя, покумекав, можно было бы и 14-поточный сделать допустим чтобы он сохранял по 16 байт, а не по одному.

- - - Добавлено - - -

Посмотрел на оптимизации. Если я ничего не пропустил -- ты сделал создание тасков менее занудным и вставил две версии лдиров на свои места, чтобы не тратить время на проверку какой нужен.

Кстати, вот скрипт (https://gist.github.com/svofski/f41ec5939d75b69bd7a2933f81489df1#file-ym6break-py), которым я превращаю xyz.ym в xyz.inc. Он рассчитывает, что salvador.exe лежит в том же каталоге и промежуточный хлам складывает в tmp там же. ym6 сохраняет тот же Ay_Emul. Единственное, что он сохраняет его сразу в lha и надо сначала вынуть оттуда Ay_Emul.ym (я это делаю просто фаром).

- - - Добавлено - - -

P.S. обновил в гисте gigachad.asm с новыми лдирами и выводом в AY. Создание тасков оставил как было, потому что нагляднее. Для практики конечно твой вариант лучше подходит.

parallelno
31.07.2022, 13:06
А можешь поподробнее написать что эта фраза означает. Все никак понять не могу.
"параметр offset на стеке -- это настоящий xthlъ. Сначала я хотел уступать планировщику после LDIR-а,"
Ldir это что? И что означает фраза"offset на стеке -- это настоящий xthlъ"?

svofski
31.07.2022, 14:22
А можешь поподробнее написать что эта фраза означает. Все никак понять не могу.
"параметр offset на стеке -- это настоящий xthlъ. Сначала я хотел уступать планировщику после LDIR-а,"
Ldir это что? И что означает фраза"offset на стеке -- это настоящий xthlъ"?

В процедуре dzx0 есть локальная переменная last_offset, которая задает смещение в буфере, откуда брать данные (см. сишный сорец (https://github.com/einar-saukas/ZX0/blob/main/src/dzx0.c)). Обычно когда мы пишем код на ассемблере, мы не думаем о том, где держать переменные и кладем их куда-нибудь в статическую ячейку памяти поблизости. А в ivagor-овском dzx0 локальная переменная сделана по-взрослому локальной, расположенной на фрейме стека, откуда она достается с помощью довольно редко встречающейся инструкции XTHL. Так бы я и не заметил, но здесь если бы переменная была глобальной, адаптировать процедуру для нескольких контекстов было бы значительно труднее.

LDIR - это инструкция Z80, которая позволяет одной инструкцией скопировать кусок памяти. В версии для 8080 на ее месте подпрограмма с циклом. Это тоже оказалось удобно, потому что если бы у нас была инструкция LDIR, мне пришлось бы ее заменять на подпрограмму самому.

Ъ это просто потому что XTHL такая очень редкая и трудная для понимания инструкция с адской мнемоникой и твердый знак добавляет ей карикатурного анахронизма. Редкий случай, когда я считаю, что у z80 получилось лучше и проще -- EX (SP), HL.

- - - Добавлено - - -

Планировщик -- это часть программы, которая вызывает задачи. Во взрослой ОС он был бы в ядре и немного посложнее. Тут он просто перебирает все задачи подряд по кругу.

Когда задача считает, что ее дело сделано, она вызывает yield. yield сохраняет все регистры в контексте задачи и возвращается в планировщик.

Планировщик переходит к следующей задаче -- берет ее контекст (это указатель стека), восстанавливает состояние процессора, делая pop всем регистрам со стека и исполняет ret. И так далее.

С точки зрения каждой задачи, она просто делает волшебный вызов "call yield". Когда он возвращается, она продолжает свое исполнение как ни в чем не бывало.

Теперь на более высоком уровне, почему я это упомянул. Каждое переключение задачи обходится дорого, потому что нужно сохранить контекст одной задачи и восстановить контекст следующей. Лучше их делать как можно реже. Поэтому я изначально надеялся делать это например после подпрограммы LDIR. Но это оказалось плохой идеей потому что потоки распаковываются неравномерно и совершенно непонятно, как их потом сводить в один.

На самом деле я уже знаю, как это сделать более оптимально, хотя это необязательно будет хорошо с точки зрения монотонности фреймрейта. Идея очень простая:
- LDIR уступает всегда на границе 16 байт
- в основном коде строка регистров AY собирается прямо из буферов. Текущая строка = номер кадра, и перебираем столбцы.

Дальше есть варианты. Можно просто вызывать планировщик один раз в 16 кадров. Нормально, если есть возможность пожертвовать значительной частью кадра.
Другой вариант -- вызывать по одной задаче на кадр. С задержкой в 16 кадров у нас будут все те же самые строки в буферах, но на каждый кадр времени будет уходить значительно меньше. Еще два кадра останутся пустыми, или можно еще пару каких-нибудь интересных потоков туда запихать.


Казалось бы, не проще бы было уж на этом этапе сделать обычный pt3-плеер? =)

svofski
31.07.2022, 19:26
Ну вот, вариант gigachad16 (https://svofski.github.io/pretty-8080-assembler/?https://gist.githubusercontent.com/svofski/f41ec5939d75b69bd7a2933f81489df1/raw/a04c31d08124503cfa6799c45f7dd86658a2a10d/gigachad16.asm). Каждая таска декодирует по 16 байт за тик. Каждый тик запускается только одна таска. Два тика пропускаем для выравнивания. Получается музыка за 20 строк (худшее, что попадалось пока, обычно 5-15).

ivagor
31.07.2022, 20:09
Очень может быть, что честно портированный проигрыватель не будет сильно быстрее, а то и наоборот. Да и по размеру музыки, как понимаю, различия небольшие. Правда тут нужно 4 Кб под буфер.

svofski
31.07.2022, 22:29
Все это ржачно и в общем совершенно валидный оказался способ, но хотелось бы иметь какой-то нормальный плеер тоже.

- - - Добавлено - - -

Улиточный плеер отрабатывает за 43 строки в худшем случае, в случае получше -- за 29. Но это конечно крайне плохой пример для подражания.

parallelno
31.07.2022, 23:54
Спасибо за подробное обьяснение! То есть вместо плеера и зажатой музыки в его формате, ты используешь многопоточный распаковщик который отправляет несжатую музыку пряма в AY?
А если сравнивать какой нибудь плеер и музыку в его формате с твоим подходом. Где будет преимуществао в скорости и объеме данных?

svofski
01.08.2022, 00:40
То есть вместо плеера и зажатой музыки в его формате, ты используешь многопоточный распаковщик который отправляет несжатую музыку пряма в AY?
Именно так. Это как проигрывание семплов, только семплы у нас тут не звуковые, а регистры, которые управляют AY, а частота обновления 50 Гц.


А если сравнивать какой нибудь плеер и музыку в его формате с твоим подходом. Где будет преимуществао в скорости и объеме данных?
Про объем -- размер данных в файле сопоставим, но для воспроизведения gigachad16 нужен буфер чуть меньше 4К (14 буферов распаковщика + 14 стеков).

Сравнение с единственным имеющимся у меня плеером pt2 для 8080 я привел в предыдущих сообщениях: gigachad16 5..20 строк, player-fml - 29..43. Если написать плеер честно, я думаю он будет все же заметно лучше, но пока никто этого не сделал.

ivagor
01.08.2022, 09:01
Размер немного> 2 Кб
Уточню - 2207 с блоком переменных, сам код 1636 байт.

parallelno
01.08.2022, 11:31
>gigachad16 5..20 строк, player-fml - 29..43
Строки это команды ассемблера?

- - - Добавлено - - -

В твоём "плеере" они выполняются каждое прерывание из последовательных 14, а два следующих прерывания не тратят процессорного времени. Плюс буфер 4к. Так?
В случае с плеером pt2. 2k плеер, и не нужен буфер. Объем сжатой музыки примерно одинаков. Так?

svofski
01.08.2022, 12:08
Строки это команды ассемблера?
Строки это строки экранной развертки. Так удобнее считать время, чем в тактах. Про прерывания и буфер правильно.

Про плеер нет. Имеющийся у нас плеер pt2 - 3067 байт и переменные его раскиданы как попало, в том числе он по-моему пишет куда-то еще в необозначенную область памяти (LA36E_ lxi sp, 08A32h etc - Достаточно взглянуть бегло на исходник (https://gist.github.com/svofski/19aeb8641cbcce4fa56fa79f3400fca4)). А тот плеер, про который говорит ivagor, его просто нет для 8080. Его надо сначала сделать.

parallelno
01.08.2022, 18:48
А сколько строк хороший плеер на z80 занимает про который говорил ivagor? Просто хочется узнать есть ли причина конвертить его на 8080.

svofski
01.08.2022, 18:58
А сколько строк хороший плеер на z80 занимает про который говорил ivagor? Просто хочется узнать есть ли причина конвертить его на 8080.
Чтобы узнать сколько он займет строк, надо сначала его сконвертить.

ivagor
01.08.2022, 19:12
Могу привести цифры для z80 с учетом векторовского торможения (смотрел в emu80). В среднем в районе 5000 тактов, максимумы (редкие) до 8000. Причина его конвертить - все же он будет несколько компактнее 14 поточного разжимальщика (думаю килобайта 3 максимум). Насколько медленнее - в худшем случае раза в полтора, если постараться - то быстрее. Но вряд ли кто-то будет стараться.

svofski
01.08.2022, 19:33
Но вряд ли кто-то будет стараться.
Я на самом деле, затаив дыхание, думал, вдруг ты напишешь -- "завтра-послезавтра выложу версию для 8080 на 10 строк" :)

С поточным плеером еще далеко не все сказано. Например, 256 -- удобный размер буфера и отличный компромисс, но бывают и окна поменьше. Например, все тот же EA Demosong при окне 64 сжимается до 3991 байт + 1204 байта буфера + стеки = 5195, а при буферах 256 на все вместе с данными нужно 6202, то есть можно килобайт сэкономить. Но это надо переписывать на менее удобные буфера.

parallelno
02.08.2022, 01:38
Напомните пожалуйста сколько одна строка таков?

svofski
02.08.2022, 11:35
parallelno, 59904 / 312 = 192.

Еще интересное отношение: частота процессора 3e6 / строчная частота 15625 = 192.

parallelno
02.08.2022, 11:52
А можно программу не самомодифицирующуся в квазидиске выполнять или хотя бы читать с квазидиске когда все 4 экранных плоскости заняты под видимую графику?

parallelno
17.08.2022, 07:12
Ну вот, вариант gigachad16 (https://svofski.github.io/pretty-8080-assembler/?https://gist.githubusercontent.com/svofski/f41ec5939d75b69bd7a2933f81489df1/raw/a04c31d08124503cfa6799c45f7dd86658a2a10d/gigachad16.asm). Каждая таска декодирует по 16 байт за тик. Каждый тик запускается только одна таска. Два тика пропускаем для выравнивания. Получается музыка за 20 строк (худшее, что попадалось пока, обычно 5-15).

Скажи пожалуйста какие форматы твой плеер проигрывает и как конвертнуть музыка например от сюда? -> https://zxart.ee/eng/music/top-100/
реально ли воспроизвести музыку такого качества на векторовском AY?
https://zxart.ee/eng/authors/l/linde/lightyears-from-you/
https://zxart.ee/eng/authors/s/shiru/duck-tales-nes-moon/

reddie
17.08.2022, 09:06
реально ли воспроизвести музыку такого качества на векторовском AY?
Там совершенно другой чип, даже не AY. Цитата с сайта по ссылке: Sound device: FM (3 channel YM2203)

svofski
17.08.2022, 12:36
То есть реально, если игра будет на своем картридже со своим чипом :)

- - - Добавлено - - -


Скажи пожалуйста какие форматы твой плеер проигрывает и как конвертнуть музыка например от сюда?

Все форматы, которые Ay_Emul воспроизводит и сохраняет в .ym.

В принципе версия в гисте юзабельная, но у меня есть чуть-чуть более новая + чуть-чуть более удобный питонский скрипт для подготовки. Если интересно, могу почесаться и попробовать выложить отдельно в ближайшее время. Или можно подождать до выходных и я выложу всю работу (это маленькая демка для Undefined).

parallelno
17.08.2022, 12:48
Подождать не проблема. :) Спасибо!

parallelno
21.08.2022, 09:18
Этот же пример -- 2069 байт сумма всех потоков если по колонкам и 7742 байт если сохранить по строкам и окно 4096. Вариант по строкам может оказаться полезным если не хватает времени на распаковку всех потоков, например, он однозначно проще и быстрее. Хотя, покумекав, можно было бы и 14-поточный сделать допустим чтобы он сохранял по 16 байт, а не по одному.

- - - Добавлено - - -

Посмотрел на оптимизации. Если я ничего не пропустил -- ты сделал создание тасков менее занудным и вставил две версии лдиров на свои места, чтобы не тратить время на проверку какой нужен.

Кстати, вот скрипт (https://gist.github.com/svofski/f41ec5939d75b69bd7a2933f81489df1#file-ym6break-py), которым я превращаю xyz.ym в xyz.inc. Он рассчитывает, что salvador.exe лежит в том же каталоге и промежуточный хлам складывает в tmp там же. ym6 сохраняет тот же Ay_Emul. Единственное, что он сохраняет его сразу в lha и надо сначала вынуть оттуда Ay_Emul.ym (я это делаю просто фаром).

- - - Добавлено - - -

P.S. обновил в гисте gigachad.asm с новыми лдирами и выводом в AY. Создание тасков оставил как было, потому что нагляднее. Для практики конечно твой вариант лучше подходит.

попытался сконвертить твоим скриптом пару песен предварительно сохраняя их в YA6 формат с помощью Ay_Emul.
https://zxart.ee/eng/authors/m/mmcm/doubtful-future/
https://zxart.ee/eng/authors/m/mmcm/jungle-bit-pops-acid/

скрипт сжимает только данные для нулевого регистра. для остальных пустые файлы. Может у меня Ay_Emul старый? я использую Ay_Emul29b32W64
так же попытался сохранить в AY6 с помощю Vortex Tracker2, тоже самое. Ay_Emul проигрывает корректно сохраненные файлы в формате AY6.

Не знаешь в чем может быть дело?

- - - Добавлено - - -

И еще в догонку вопрос. Где почитать про формат AY6? меня походу в интернетах забанили. Ниодного толкового описания не могу найти. :(
только ввот такое
https://vgmrips.net/wiki/AY_File_Format
но там местами пропущены детали.

- - - Добавлено - - -

неужто нашел...
https://documentation.help/AY-3-8910.12-ZX-Spectrum/ay_e04vt.htm

svofski
21.08.2022, 10:32
parallelno, та версия скрипта не умеет lha. Можно вручную распаковать, но это занудно.

Бери отсюда https://github.com/svofski/v06c-arzak/blob/master/tools/ym6break.py
Ей нужен lhafile.

parallelno
21.08.2022, 10:57
Спасибо!
Прочитал описание формата ay. Сверился с файлами которые у меня есть. Чет не соответствует. Понял что ничего не понял. Lha это формат хранения word , типа low, hi? Есть ли у тебя описание формата?

svofski
21.08.2022, 11:51
lha это архиватор древний, популярен на атари, откуда формат ym родом.Внутри архива будет один файл формата ym6. Там сколько-то заголовков (LeOnArD! итд) из которых важно только количество записей, допустим их 100. Дальше идет 100 байт регистр 0, затем 100 байт регистр 1 итд до регистра 15 (регистры 14 и 15 не используются, но пишутся).

parallelno
21.08.2022, 13:06
Да, тяжело с мертвыми форматами работать ...
Скрипт твой заработал. Спасибо!

- - - Добавлено - - -

svofski, ты этот формат по памяти знаешь или есть описание?

- - - Добавлено - - -

svofski, ещё вопрос про модель звукового чипа
Я ковертнул вот эту песенку
https://zxart.ee/eng/authors/m/mmcm/...bit-pops-acid/
И она нормально играет. Но в странице с описанием написано что тип чипа YA-2149f. Но в твоём примере на базыре написано что чип AY 8910. Они аналоги, можно музыку для любого из них конвертить?

svofski
21.08.2022, 13:43
есть описание, поищи ym6 leonard. я сейчас далеко от компа.

ay-3-8910 и ym-2149 логически вроде эквивалентны, но в деталях там есть отличия и звучат они, говорят, по-разному.

parallelno
21.08.2022, 20:46
Я на самом деле, затаив дыхание, думал, вдруг ты напишешь -- "завтра-послезавтра выложу версию для 8080 на 10 строк" :)

С поточным плеером еще далеко не все сказано. Например, 256 -- удобный размер буфера и отличный компромисс, но бывают и окна поменьше. Например, все тот же EA Demosong при окне 64 сжимается до 3991 байт + 1204 байта буфера + стеки = 5195, а при буферах 256 на все вместе с данными нужно 6202, то есть можно килобайт сэкономить. Но это надо переписывать на менее удобные буфера.

А если буфера и стеки вынести на квазидиск в подэкранные области? Кстати сжатые стримы с окном 256 прилично сжимаются zx0 без окна.
То есть можно музыку держать дважды сжатой в игре. Потом распоковывать на квазидиск в подэкранные области и оттуда проигрывать в теории. По крайней мере у меня такой план. Или тут есть какие подводные камни?

svofski
21.08.2022, 22:41
Камней особых вроде нет.

Если не так критичен каждый такт, а память в цене, то может быть все же один из stc плееров, или плеер pt2 могут лучше подойти. Там степень сжатия будет самая высокая.

parallelno
22.08.2022, 00:07
память как раз не в цене так как квазидиск есть. Нужно кстати сравнить pt2, stc и zx0 по памяти.

- - - Добавлено - - -

Кстати музон который я конвертировал для тестов
В pt3 занимает 5.4kB, дважды пожатый в zx0 4kB.

svofski, ещё хочу сказать большое спасибо за гига Чад плеер. Очень классно написан!

svofski
22.08.2022, 18:01
В pt3 занимает 5.4kB, дважды пожатый в zx0 4kB.
Я так понимаю, что дважды пожатый zx0 -- это регистровые дампы сжатые для гигачада закатанные потом вместе со всем остальным без ограничения окна. pt3 тогда тоже надо сравнивать аналогично -- в замаринованном виде.


svofski, ещё хочу сказать большое спасибо за гига Чад плеер. Очень классно написан!
Спасибо, мне и самому понравилось. Забавно получилось, я думал чисто ржаки ради сделать акробатический трюк, а получилось вполне практично.

Но все равно было бы здорово как-нибудь сочинить полноценный плеер для 8080 без портов и рекомпиляций.

parallelno
14.10.2022, 19:04
ivagor, я попытался обновить zx0 чтобы он мог распаковывать в квазидиск, но что-то пошло не так и он портит данные. Совсем чуть чуть. Не могу понять в чем беда. Помоги найти баг пожалуйста.


; unpack to the ram-disk $8000-$FFFF
; in:
; de - compressed data addr
; bc - uncompressed data addr
; a - ram-disk activation command
dzx0RD:
sta @ramDiskCmd1+1
sta @ramDiskCmd2+1

lxi h, $ffff
push h
inx h
mvi a,$80
@literals:
call Elias
call ldir
jc newOffset
call Elias
@copy:
xchg
xthl
push h
dad b
xchg
call ldirUnpacked
xchg
pop h
xthl
xchg
jnc @literals
newOffset:
call Elias
mov h, a
pop psw
xra a
sub l
rz
push h
rar
mov h, a
ldax d
rar
mov l, a
inx d
xthl
mov a, h
lxi h, 1
cnc EliasBacktrack
inx h
jmp @copy

Elias:
inr l
EliasLoop:
add a
jnz EliasSkip
ldax d
inx d
ral
EliasSkip:
rc
EliasBacktrack:
dad h
add a
jnc EliasLoop
jmp Elias

ldir:
push psw
ldirLoop:
ldax d
push psw
; turn on the ram-disk
@ramDiskCmd1:
mvi a, TEMP_BYTE
out $10
pop psw
stax b
; turn off the ram-disk
xra a
out $10

inx d
inx b
dcx h
mov a, h
ora l
jnz ldirLoop
pop psw
add a
ret

ldirUnpacked:
push psw
; turn on the ram-disk
@ramDiskCmd2:
mvi a, TEMP_BYTE
out $10
ldirUnpackedLoop:
ldax d
stax b
inx d
inx b
dcx h
mov a, h
ora l
jnz ldirUnpackedLoop

; turn off the ram-disk
xra a
out $10

pop psw
add a
ret

ivagor
14.10.2022, 20:10
Мне не хватает данных об условиях применения. Если упакованные данные и распакованный блок не пересекаются, то просто включаем кваз в нужное состояние перед распаковкой и используем обычный распаковщик. Специальный распаковщик нужен если пересекаются.

parallelno
14.10.2022, 21:04
ivagor, упакованные данные могут лежать по тем же адресам что и распакованные. выше $8000

- - - Добавлено - - -

Забыл сказать что прерывания запрещены

ivagor
14.10.2022, 22:02
Примерно так

parallelno
14.10.2022, 23:36
ivagor, спасибо. но все равно что-то корраптит данные, но уже в других местах.

- - - Добавлено - - -

я использую форвард распаковку и распаковываю из адрессов ниже $8000 по адрессу $8000 в нулевой банк квазидиска если это поможет.

- - - Добавлено - - -

если я указываю команду 0 и распаковываю в основную память, а затем перемещаю в квазидиск c помощью PUSH, то данные корректные

- - - Добавлено - - -

сравнил твой код со своим. выглядит идентично. Может ли быть что гдето вне этого куска ниже код читает/пишет распакованые данные?


push psw
dzx0_setqd2:
mvi a,0
out 10h
dzx0_ldir2:
ldax d
stax b
NEXT_DE
NEXT_BC
dcx h
mov a,h
ora l
jnz dzx0_ldir2
xra a
out 10h
pop psw
add a




push psw
dzx0_ldir1:
ldax d
push psw
dzx0_setqd1:
mvi a,0
out 10h
pop psw
stax b
xra a
out 10h
NEXT_DE
NEXT_BC
dcx h
mov a,h
ora l
jnz dzx0_ldir1
pop psw
add a


- - - Добавлено - - -

вроде кроме двух ldax ничего не читает и не пишет данные вне ldir. проверил их несколько раз, вроде они адрессуют только область ниже $8000. Непонятно. Еще более непонятно то что если программу выполнять по шагам в Emu80 дебаге, то данные копартятся в другом месте. может это бага эмулятора? В v06x тоже данные копартятся но в другом месте.

- - - Добавлено - - -

Блин. нашел ошибку. все таки одна из процедур разрешала прерывания :)

ivagor
22.10.2022, 17:05
Неожиданно и от демопатей бывает польза. Впечатлил новый упаковщик upkr (https://github.com/exoticorn/upkr/tree/master/z80_unpacker) - мой тестовый набор сжал лучше шринклера, при этом в распаковщике умножение всего лишь (если сравнивать со шринклером) 8x8. Ждем распаковщика для 8080.

svofski
23.10.2022, 02:00
Забавно, что эта демка по духу близка progdemo. Я не очень понял, почему ее загнали в wild.

ivagor
23.10.2022, 07:23
Wild cкорее всего потому что это галерея картинок из 90х не нарисованных специально для этой демы.

ivagor
23.10.2022, 18:18
Если кто-то параллельно адаптирует распаковщик upkr для 8080, то мои текущие результаты такие: 268 байт (умножение развернутое, для сравнения шринклер 311 байт) и в 1.9 раза быстрее шринклера. Скорость распаковки примерно 6000 бит/секунду (в 2 раза медленнее loadfm, зато в разы быстрее традиционных форматов), очень медленно, но как упаковщик крайнего случая для дем 2k-4k подойдет. А шринклер теперь не нужен.

ivagor
24.10.2022, 17:03
Дожал upkr (гитхаб (https://github.com/ivagorRetrocomp/DeUpkr)). Еще ускорить не получилось, зато подсократил (227 байт прямой, 257 - быстрый прямой, обратные на байт короче). Уже традиционно хочу оценить качество портирования по соотношению размеров вариантов 8080 и z80:
227/170=1.34
257/195=1.32
Судя по предыдущим результатам (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1151274&viewfull=1#post1151274) это хорошие, близкие к пределу цифры для распакощиков LZ и LZ+
Обращаю внимание, что в upkr есть опции --max-offset и --max-length, соответственно можно переделать распаковщик на кольцевой буфер.

ivagor
25.10.2022, 17:03
Добавил версию deupkr (https://github.com/ivagorRetrocomp/DeUpkr) с умножением по таблице квадратов, там нужно сначала вызвать (один раз) процедуру генерации таблицы, потом (сколько угодно раз) можно вызывать распаковщик. Эта версия примерно на 9% быстрее варианта с развернутым циклом умножения (а само умножение быстрее более чем в полтора раза). За это пришлось заплатить увеличением размера распаковщика на 33 байта и местом под таблицу квадратов (1024 байта). Если сравнивать со шринклером, то эта версия deupkr все равно компактнее, занимает меньше места под таблицы и более чем в 2 раза быстрее. Разумных вариантов дальнейшего ускорения умножения 8x8 я на данный момент не вижу, а неразумные (например занять 128 Кб кваза под полную таблицу умножения) даже пробовать не хочется.

ivagor
01.11.2022, 17:02
Отколупал от базовых версий deupkr 2 байта, от табличной 4.
Потестировал в эмуляторе 6128 - 8085 очень неплохо ускоряет upkr (пробовал квадратно-табличный) за счет более быстрого выполнения части команд, на 16-17%. Можно еще немного оптимизировать по размеру и скорости за счет недокументированных команд, но этот выигрыш незначительный.
Сделал версию (https://github.com/ivagorRetrocomp/DeUpkr/tree/main/x86) для 8088/86, можно считать что под Вектор 1608Ц (подойдет и для менее экзотических машинок типа Поиска или МС-1502).

ivagor
01.11.2022, 21:26
Извините за оффтоп, но раз сказал A, то и следующую букву надо проговорить. Убрал тупизну из варианта 8086 (давно не брал я в руки шашки), стало на 23 байта короче и сильно быстрее. Критерием того, что этот вариант уже приемлемый считаю то, что он стал меньше компактного варианта для z80.

ivagor
25.11.2022, 06:56
Может возникнуть вопрос - зачем сделал свой вариант распаковщика upkr для 8088, если есть штатные?
1. Штатные используют команды 286 и 386, у меня только 8088/86.
2. Пресеты --x86 и --x86b на тех файлах, которые я попробовал, обеспечивают несколько худшее сжатие, чем --z80, но тут обобщать не берусь.
3. Мой вариант поддерживает и прямую и обратную распаковку.
У штатных есть и плюс - там можно без дополнительных телодвижений распаковать готовый .com, а не только абстрактные данные из одной области памяти в другую. Ну и признаюсь, что когда качал репозиторий upkr, там еще не было распаковщиков для x86 (когда выкладывал свой вариант они уже были, но я их не смотрел). Возможно если вовремя скачал бы образцовые распаковщики, то ограничился бы их адаптацией для 8088/86, зато теперь есть разнообразие вариантов.

ivagor
01.12.2022, 17:19
После появления zx0 я среди прочих "отменил" и exomizer, но должен признать, что был излишне категоричен. Пусть в среднем по больнице zx0 пожалуй все же выигрывает (особенно для sfx с учетом более компактного распаковщика), но нашлась ниша для exomizera - сжатие "мультимедийных" данных, графики и музыки, особенно при использовании для распаковки циклического буфера 256 байт. У zx0 быстрее падает эффективность при уменьшении размера буфера. Еще лучше подошел бы rip, но для него нет упаковщика с возможностью ограничения длины смещений. Ну а upkr несомненно лучше всех, но очень уж медленный. В порядке оффтопа - выложил на гитхаб deupkr для R800. Вот там он работает на приемлемой скорости, остается только позавидовать продвинутым msxникам.

ivagor
03.12.2022, 16:05
Удалось сократить deupkr для 8080 (https://github.com/ivagorRetrocomp/DeUpkr/tree/main/8080) на 1-2 байта и чуть разогнать. И даже получилось сделать один микроскопический момент лучше чем в прототипе для z80.
Еще попробовал сделать небитстримные варианты - чуда не произошло, как и прогнозировал (или он просто попробовал) автор распаковщика для z80 они уступают битстримному. У меня создалось впечатление, что для их эффективной реализации нужны регистры по 24-32 бита и быстрое умножение 8x16 (или хотя бы 8x12), т.е. это не z80 и не 8080/88/86.

ivagor
08.12.2022, 17:08
Еще немного про upkr (потихоньку закругляюсь с этой темой, по крайней мере для 8080).
1. Сообразил, как оптимизировать версию с развернутым циклом умножения, стало на 3 байта короче и на 2% быстрее. Более того, оптимизация этого момента позволила ускорить и сократить на 2 байта оригинальную версию для z80, поэтому добавил на гитхаб и оптимизированный вариант для z80 (https://github.com/ivagorRetrocomp/DeUpkr/tree/main/z80).
2. Единицы процентов - это хорошо, но мало, хотелось прорывов, поэтому попробовал умножение с большими таблицами. Оказалось, что в голый вектор влезает самый быстрый вариант с таблицей 6x8. Дальнейшее увеличение таблицы не ускоряет умножение, т.к. выигрыш съедают накладные расходы на работу с квазидиском. По 5 вариантам построил зависимость общего времени распаковки upkr8080 от времени умножения. Оказалось, что она (зависимость) очень хорошо аппроксимируется (MATLAB, polyfit, polyval) прямой линией. И по этой аппроксимации получается, что при сокращении времени умножения до 4-8 тактов общее время распаковки уменьшится примерно в 2 раза относительно самой медленной версии с умножением в цикле, вот такие пределы роста.

ivagor
09.12.2022, 06:40
Небольшое дополнение.
1. Если обозначить общее время распаковки y и время умножения x, то зависимость между ними y=x+const, т.к. const зависит только от содержания потока бит, который постоянен для одного файла и не зависит от времени умножения.
2. Хорошо, линейность зависимости очевидна, зачем нужна ползучая эмпирика с аппроксимацией, почему бы не посчитать x и const по тактам? Собственно x я и посчитал по тактам, для процедур умножения это возможно. Хотя внимательность нужна, т.к. большинство процедур умножения (в моей выборке все кроме одной) содержат условные переходы и нужно посчитать пути по всем веткам и усреднить, если нет заметных перекосов вероятностей сомножителей (судя по линейности полученной аппроксимации, я посчитал правильно, по крайней мере без серьезных ошибок). А вот const включает в себя слишком много условных переходов и циклов. За одним умножением, т.е. за одним декодированным битом может следовать запись одного литерала или накопление части литерала или копирование ссылки или декодирование длины ссылки или смещения, вариантов слишком много чтобы их все аккуратно и правильно посчитать. Проще и точнее определить y (общее время распаковки).

ivagor
10.12.2022, 20:05
Подбираю крошки за буржуинами. В оригинальной версии upkr для z80 есть такая штука

archived: possible LUT variant of updating probs value, requires 512-aligned 512B table (not tested)
...
table generator is not obvious and probably not short either, 20+ bytes almost for sure, maybe even 30-40
У меня генератор получился 30 байт. Это почти первая прикидочная версия, наверняка можно немного оптимизировать. Выигрыш от LUT для вектора примерно 2%. Малину портят две LUTые команды mov r,r по 8 тактов, для z80 и 8085 (да и для 8080 без торможения) эффект от LUT будет чуть больше.

ivagor
16.12.2022, 17:04
Итоговые распаковщики и небольшие комментарии будут потом, а пока демонстрация использования deupkr (самый компактный и медленный вариант) для распаковки картинок.
Две картинки 208x256 (16 цветов), на реале и в Emu80 такой размер выглядит как квадрат (оригинальные картинки квадратные). При конверсии использовал палитру наиболее близкую к Emu80, для VV тоже хорошо подходит, для Emu похуже. С палитрой v06x пока не разбирался, похоже она отличается и от Emu80/VV и от Emu. После старта распаковывается первая картинка и ждет нажатия РУС/ЛАТ. Потом вторая картинка (и тоже ждет РУС/ЛАТ). И так по кругу. Только upkr позволил уместить одновременно 2 картинки такого разрешения и цветности в памяти.
РУС/ЛАТ в эмуляторах:
Emu и VV - RCtrl
Emu80 - Insert
v06x - F6

ivagor
16.12.2022, 21:08
И небольшие комментарии.
В базовой версии (https://github.com/ivagorRetrocomp/DeUpkr/blob/main/8080/deupkr.asm) удалось чуть ускорить вариант с развернутым умножением. Версию с таблицей квадратов (https://github.com/ivagorRetrocomp/DeUpkr/blob/main/8080/deupkr_qsqrmul.asm) разогнал на 3% и сократил на байт. Думаю примерно такие варианты и останутся. При желании можно наплодить промежуточных версий, которые по размеру и скорости будут между существующими, но не вижу в этом особого смысла.
Про обновление вероятностей с LUT (как раз пример одной из опций, которую можно реализовать). Несколько раз полностью переписал генератор таблицы, удалось его сократить до 23 байт и сильно ускорить (что неважно на фоне времени распаковки). А для z80 получается 21 байт, т.е. практически на нижней границе оценки автора распаковщика для z80 ("20+ bytes almost for sure"). Исходя из границ возможного это весьма хороший результат, но по критерию {ускорение/добавочный размер} не очень, разгон умножения более эффективен. Другое дело, что когда умножение уже разогнано до упора и хочется еще быстрее, тогда да. Если будут соревнования спортивных распаковщиков upkr, то можно туда добавить.
В целом повторю очевидную вещь: upkr - очень крутой упаковщик с очень медленной распаковкой. По сравнению со шринклером несомненный шаг в правильную сторону и по степени сжатия и по скорости и по размеру распаковщика, плюс еще и с полезными опциями упаковщика. Надеюсь все же в будущем появится что-то между rip и upkr.

nzeemin
21.12.2022, 16:12
ivagor, скажите, а вот эти новые алгоритмы если расположить на вот этом общем графе, где они примерно встанут?

https://github.com/emmanuel-marty/lzsa/blob/master/pareto_graph.png

ivagor
21.12.2022, 17:39
upkr удобно сравнивать с идеологически близким шринклером, он примерно в 2 раза быстрее шринклера, соответственно правее. На моем тестовом наборе (20 векторовских программ) upkr сжал немного лучше шринклера, но если говорить конкретно про тот график, то там надо брать и соответствующий тестовый набор (который мне не интересен применительно к вектору). Скорее всего upkr все же и на том тестовом наборе чуть выше, но это даже не принципиально при том выигрыше в скорости, размере распаковщиков и таблиц, который он демонстрирует. Еще можно сравнить циферки тут (https://github.com/uniabis/z80depacker). Плюс еще возможность ограничивать дальность ссылок, что позволяет при необходимости распаковывать в круговой буфер (для шринклера нет такого упаковщика).
Кстати, если взять картинки upkrdemo в пиксельном, а не в битплановом представлении и сжать с ограничением для буфера 256 байт, то выигрыш >2 килобайт (это даже с учетом 256 байт). Т.е. можно уместить две полновысотные картинки шире 208 точек.
Ну и я все еще не против общения на ты.

Eugene85
23.01.2023, 20:38
nzeemin,
Если вы про UPKR, то точка будет (LDIR x 189; 2.29)

Eugene85
01.04.2023, 16:48
но для него нет упаковщика с возможностью ограничения длины смещений.
Как же нет, когда есть (https://gitlab.com/eugene77/rip) :)

ivagor
11.06.2023, 11:35
Сократил DeRIP (https://github.com/ivagorRetrocomp/DeRIP) на 7 байт и чуть ускорил. Изменил описание, т.к. новый RIP (https://gitlab.com/eugene77/rip) сам умеет переворачивать битовый поток.

Pyk
10.10.2023, 00:45
ivagor, а что с репозиторием на github?

NEO SPECTRUMAN
10.10.2023, 06:34
ivagor, а что с репозиторием на github?
Оо!
И такого опасного для ваших банковских щетов ivagor-а зашадов прибанили :v2_lol:

- - - Добавлено - - -

ivagor, это ты не включил 2FA?

- - - Добавлено - - -

хотя те кто ужо давно не ходит в/на гитх00б еще вроде есть


или это ивагор там был просто раньше зареган?
а тем уйти в 404 еще не пришло время

NEO SPECTRUMAN
30.10.2023, 00:57
ivagor, так ты сам удолилсо или тя удолили?

Improver
08.05.2024, 12:40
ivagor, вопрос есть по распаковщику... Решил сделать упакованный вариант какой-нибудь игрушки, попалась MoonBugs (https://caglrc.cc/scalar/ware/140/) (moonbugs.rom), упаковал её при помощи LZSA с ключами "-f1 -r" и дополнил таким распаковщиком на основе твоего unlzsa, когда-то имевшегося на гитхабе:

.ORG 100H
START: DI
LXI SP,000F0H
LXI H,PAKPR ; откуда
LXI D, 0A000H ; куда
BEGIN: MOV A,M
STAX D
INX H
INR E
JNZ BEGIN
INR D
MOV A,D
CPI 0FFH
JC BEGIN ; цикл до адреса FF00h
LXI D, START
PUSH D ; для запуска распакованного
LXI H, PDATA
JMP 0A000H
PAKPR: .db 0FFh
;
.org 0A000H ; после компиляции удалить область от PAKPR до 0A000H и дописать в конец архив
;
;input: hl=compressed data start
; de=uncompressed destination start
unlzsa1:
mvi b,0
jmp ReadToken
;
NoLiterals:
xra m
push d
inx h
mov e,m
jm LongOffset
ShortOffset:
mvi d,0FFh
adi 3
cpi 15+3
jnc LongerMatch
CopyMatch:
mov c,a
CopyMatch_UseC:
inx h
xthl
xchg
dad d
mov a,m
inx h
stax d
inx d
dcx b
mov a,m
inx h
stax d
inx d
dcx b
dcx b
inr c
BLOCKCOPY1:
mov a,m
stax d
inx h
inx d
dcr c
jnz BLOCKCOPY1
xra a
ora b
jz $+7 ; >>>
dcr b
jmp BLOCKCOPY1
pop h ; <<<
ReadToken:
mov a,m
ani 70h
jz NoLiterals
cpi 70h
jz MoreLiterals
rrc
rrc
rrc
rrc
mov c,a
mov b,m
inx h
mov a,m ; <<<
stax d
inx h
inx d
dcr c
jnz $-5 ; >>>
push d
mov e,m
mvi a,8Fh
ana b
mvi b,0
jp ShortOffset
LongOffset:
inx h
mov d,m
adi -128+3
cpi 15+3
jc CopyMatch
LongerMatch:
inx h
add m
jnc CopyMatch
mov b,a
inx h
mov c,m
jnz CopyMatch_UseC
inx h
mov b,m
mov a,b
ora c
jnz CopyMatch_UseC
pop d
ret ; >>>>>>>>>>>>>>>
;
MoreLiterals:
xra m
push psw
mvi a,7
inx h
add m
jc ManyLiterals
CopyLiterals:
mov c,a
CopyLiterals_UseC:
inx h
dcx b
inr c
BLOCKCOPY2:
mov a,m
stax d
inx h
inx d
dcr c
jnz BLOCKCOPY2
xra a
ora b
jz $+7 ; >>>
dcr b
jmp BLOCKCOPY1
pop psw ; <<<
push d
mov e,m
jp ShortOffset
jmp LongOffset
ManyLiterals:
mov b,a
inx h
mov c,m
jnz CopyLiterals_UseC
inx h
mov b,m
jmp CopyLiterals_UseC
;
PDATA: .END
Начало, вроде, отрабатывает нормально, но при распаковке после адреса 3BC4h сыпет мусор в память. Что я там не так сделал, подскажи?
Собранный распаковщик с архивом игры, для тестов: moonbugp.rar

ivagor
08.05.2024, 13:44
Вероятно когда ты преобразовывал исходник для себя сделал одну неправильную замену. В конце цикла BLOCKCOPY2 должно быть jmp BLOCKCOPY2 вместо jmp BLOCKCOPY1

Improver
08.05.2024, 14:59
когда ты преобразовывал исходник для себя сделал одну неправильную заменуСпасибо, исправил. Эту подпрограмму я скопировал из РДС, и там та же ошибка, но, наверно, повезло -- в РДС она себя не проявила...

ivagor
08.05.2024, 15:08
Если в сжатом файле нет последовательностей литералов>255 байт (как вероятно в РДС), то проверка старшего байта счетчика будет обойдена (и в распаковщике таких файлов ее можно даже удалять).

- - - Добавлено - - -

Кстати, если углубляться, то такую статистику упаковщик выдает по ключу -stats

CityAceE
10.10.2024, 11:31
LZSA2. "Золотая середина", на замену MegaLZ. Вот его я уже конверснул на 8080 и распаковщик получился компактнее и быстрее MegaLZ b2ma (и даже его оптимизированных вариантов). При этом LZSA еще и сжимает в этом режиме лучше MegaLZ. Еще подумаю над распаковщиком LZSA2 и выложу.
ivagor, можешь поделиться исходником декомпрессора LZSA2 для i8080?

ivagor
10.10.2024, 12:09
Могу, но с тех пор появился сжимающий сильнее zx0 (еще удобнее salvador (https://github.com/emmanuel-marty/salvador)). Исходники распаковщика для 8080 можно взять здесь (https://github.com/DenisGrachev/OldTowerVector06c/blob/main/include/dzx0_CLASSIC_z80.asm) (мнемоники z80) или здесь (https://github.com/nzeemin/vector06c-desolate/blob/master/desolcod0.asm) (мнемоники 8080).

CityAceE
10.10.2024, 13:09
ivagor, спасибо! Действительно, поэкспериментировал, и zx0 дал большую компрессию.

Набор экранов в уровне 30 экранов по 800 байт. Каждый экран сжимался отдельно.

Без сжатия - 24000 байт
LZSA1 - 12443 байта
LZSA2 - 11460 байт
ZX0 - 10851 байт

А исходники распаковщика нашёл как раз у Дениса Грачёва в нужной мне мнемонике Z80 ;) Где-то в подсознании осело, что он именно ZX0 использовал в своих играх.

Titus
10.10.2024, 13:46
Набор экранов в уровне 30 экранов по 800 байт. Каждый экран сжимался отдельно.
Попробуй сжимать и распаковывать по 2 или 4 экрана. Если промежуточный буфер позволяет где-то в памяти. Может оказаться интереснее результат.

ivagor
10.10.2024, 14:27
Если есть место для распаковки сразу трех экранов, то можно попробовать паковать по одному но RIP (https://gitlab.com/eugene77/rip)ом (и ему еще понадобится рабочая область в районе полутора килобайт). Он конечно медленнее распаковывает, но для 800 байт это не критично.

ivagor
11.10.2024, 07:13
Все же на отдельных фрагментах по 800 байт RIP может и проиграть. Тут скорее подойдет exomizer (https://bitbucket.org/magli143/exomizer/wiki/Home). Крупные файлы он сжимает хуже RIP, но
1. Рабочая область всего 256 байт вместо полутора килобайт. Если сжимать по несколько уровней, то скорее всего получится группировать по столько же, как и с zx0 (в худшем случае на один меньше).
2. Есть режим сжатия -E с общим "словарем", в данном случае он как раз может подойти.

CityAceE
14.10.2024, 10:56
А вот такой вопрос, опять же применительно к моей ситуации. Например, у меня есть непрерывный бинарник, содержащий в себе 30*800 байт = 24000 байт. Мы его целиком сжимаем. А потом как-то дополнительно проходимся по нему, получая адреса где начинаются сжатые данные для каждой комнаты. И когда нужно, мы указываем на адрес с сжатом массиве и сколько байт начиная с этого адреса нужно распаковать. Я не особо изучал методы сжатия, и скорее всего так нельзя делать, но спросить на всякий случай решил. Наверное, это получается что-то типа сжатия каждой отдельной комнаты, но с общим словарём. Но может быть если оно всё идёт единым блоком, то это как-то может благотворно повлиять на степень сжатия?

ivagor
14.10.2024, 11:15
Если правильно понимаю, ты про "поточный" распаковщик с кольцевым буфером ("окном"). Современные упаковщики в основном умеют сжимать в расчете на это, например salvador для zx0 (опция -w).
Упаковываем файл целиком, а распаковываем последовательно частями по мере необходимости. Размер буфера удобно выбирать по степеням двойки - 16,32,...,256,...,1024 и т.д. байт. У svofski есть готовый распаковщик zx0 для окна 256 байт (и у меня вроде есть, но у svofski он давно выложен в открытый доступ), что в данном случае мало, его надо модифицировать в бОльшую сторону.

svofski
14.10.2024, 11:40
svofski он давно
Наверное вот это можно адаптировать, если буфер 256 байт: https://github.com/svofski/v06c-progdemo/blob/master/dzx0_chunk256.asm

Но для уровней интересно было бы попробовать составить общий словарь.

ivagor
14.10.2024, 12:07
Для уровней 800 байт минимальное оправданное окно 1024 байта (а лучше больше), иначе проще паковать по одному уровню.

- - - Добавлено - - -

Для zx0 "словарем" являются распакованные данные, или кольцевой буфер, если он используется.

ivagor
14.10.2024, 16:03
Сам себя поправлю/дополню - для zx0 не только распакованные данные являются словарем, но и "префикс", если он использовался при упаковке. Возможно svofksi больше про этот вариант написал.

ivagor
18.10.2024, 17:04
Сравнил сжатие уровней Старой башни (Денис Грачев), 21 уровень по 880 байт=18480 байт. Каждый уровень сжимался отдельно.
ZX0 (взял сжатые файлы из исходников игры): 7787 байт, распаковщик 92 байта
Exomizer 3.1.2 -P43: 7608 байт, распаковщик 264 байта, временная таблица 156 байт
ZX5 v2.0: 7579 байт, распаковщик 147(151) байт
Exomizer 3.1.2 -P43 -E: <7337 байт + временная таблица 156 байт> или <7311 байт + на постоянку таблица 156 байт>, распаковщик 279 байт
RIP v2023.03.30 -rb: 7211 байт, распаковщик 310 байт + временно 1474 байта рабочая область
UPKR 0.2.2 --z80: 6590 байт, распаковщик 224 байта + временно 320 байт рабочая область

Для полного счастья надо бы еще и время распаковки протестировать, но если не вдаваться в детали, то во всех случаях кроме UPKR им можно пренебречь. UPKR придется подождать, скорее всего больше секунды на уровень, но если экономить каждый байт, то хороший вариант применения этого специфического упаковщика.

svofski
18.10.2024, 17:45
Уровень это один экран, или сразу много?

ivagor
18.10.2024, 18:11
В Старой башне уровни со скроллом, поэтому нельзя сказать, что один экран. Для определенности - я о файлах mapXX.tmx.mapa, где XX от 00 до 20

CityAceE
18.10.2024, 18:11
У меня пока ещё немножко места в памяти есть. Как в очередной раз упрусь, то буду экспериментировать. А пока же остановился на ZX0. Но уже прикинул, откуда взять 1,5 килобайта на распаковку.

svofski
18.10.2024, 18:52
В Старой башне уровни со скроллом, поэтому нельзя сказать, что один экран. Для определенности - я о файлах mapXX.tmx.mapa, где XX от 00 до 20

А как в Золоте Монтесумы, там по экранам или пачками? Это наверное скорее к CityAceE вопрос.

CityAceE
18.10.2024, 19:02
там по экранам или пачками?
У меня по экранам запаковано. И распаковывается по мере перехода на соседний экран.

ivagor
19.10.2024, 07:00
Для полноты картины результаты сжатия уровней Старой башни в zx0 с окнами от 512 до 2048 байт и по 2 уровня.
salvador -classic -w512: 7576 байт
salvador -classic по 2 уровня: 7434 байта
salvador -classic -w1024: 7037 байт
salvador -classic -w2048: 6842 байт

Признаю, что был неправ, когда написал, что в данном случае нужны окна >=1024. Начиная с 512 уже сжимает лучше за счет возможности ссылки на предыдущий уровень, пусть и неглубокой. Надо учитывать, что оконный распаковщик распухнет по сравнению с обычным.

ivagor
13.08.2025, 10:23
В БК3D.Arena ("прямой") распаковщик zx0 догнал по размеру распаковщик 8080 - 92 байта. Посмотрел еще раз - новых идей по сокращению версии 8080 не появилось. Для вектора можно сократить на байт, но получится не универсальный вариант, если прерывания разрешены, то зависит от особенностей обработчика. Для БК тоже есть резерв с возможным повторным использованием RET. Достаточно интересная ситуация, инструкции PDP11 в среднем более толстые, но это компенсируется тем, что они и более емкие. Единственный плюс, что для 8080 версия без самомодификации, но это не особо критично для распаковщика современного формата, который практически всегда работает в озу. Версия dzx0 8080 с самомодификацией тоже есть, она быстрее, но больше по размеру.

ivagor
23.08.2025, 16:00
Помощь в преодолении застоя с zx0 неожиданно пришла со стороны 6502. Модификация zx02 (https://github.com/dmsc/zx02) в среднем по больнице на моем наборе тестовых файлов чуть-чуть проигрывает zx0, но на 10 файлах из 21 выигрывает, а на 2 дает одинаковый размер. Самое приятное - распаковщик получилось сделать на 2 байта короче dzx0. Если модифицировать упаковщик и вернуть отрицательный формат хранения смещения, то можно сократить еще на 2 байта.

ivagor
23.08.2025, 21:18
Если модифицировать упаковщик и вернуть отрицательный формат хранения смещения, то можно сократить еще на 2 байта.
Или компромиссный вариант для ленивых - сжимать с опцией -b (в обратную сторону), при этом смещения останутся положительные, но направленные в нужную сторону для сложения. Обратный распаковщик на байт короче прямого в отличие от zx0, где он на 2 байта длиннее из-за более громоздкой проверки окончания распаковки.

ivagor
25.08.2025, 17:03
Мотивация со стороны БК в итоге привела к сокращению распаковщика zx0 на 2 байта после 4 лет застоя. Это пока позволило сохранить мою картину мира, в которой код 8080 в среднем компактнее PDP11. Просто для полноты картины добавил опцию для распаковки нового формата v2, в чем для 8080 нет практического смысла, т.к. на 2 байта длиннее и немного медленнее.
Ну и дожал dzx02 прямой до 86 и обратный до 85 байт. Кроме того распаковщики zx02 примерно на 5-8% быстрее zx0.
Обратите внимание, что адрес источника в dzx0 вернулся в HL (в dzx02 аналогично).

Upd 28.08.2025: Исправил (в релизе от 25 августа случайно стер метку в одном из вызовов процедуры) и оптимизировал dzx02. Теперь 85/84 байта и чуть быстрее.

Upd 30.08.2025: Еще чуть ускорил dzx02.

ivagor
28.08.2025, 07:19
Исправил и оптимизировал dzx02 (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1217606&viewfull=1#post1217606)

ivagor
30.08.2025, 10:09
Добрался до zx02 с опцией -1 (далее коротко zx12) - оказался отличный вариант, скорость распаковки практически как lzsa2, степень сжатия примерно как zx1. Он может заменить их обоих, тем более при всем этом еще и распаковщик заметно компактнее, особенно по сравнению с lzsa2 (в 2 раза). Новая "базовая" линейка от быстрых к мощным (слева направо) для меня теперь такая:
lzsa1 - zx12 - zx02/zx0 - rip - upkr
dzx12 можно еще немного ускорить, но ценой неоправданного разбухания, текущий вариант на мой взгляд удачно сочетает скорость и компактность. В отличие от zx0 и zx02 здесь используется самомодификация, зато в одноразовом варианте можно сократить на 7 байт (не забудьте поменять адрес источника с DE на HL).
Попутно ковыряния в dzx12 подсказали, как можно ускорить примерно на 1% и dzx02 (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1217606&viewfull=1#post1217606) без увеличения размера.

metamorpho
01.09.2025, 11:55
.....dzx12....

А как и чем упаковать данные для dzx12 ?
Есть ли текст dzx12 не для tаsm, а для PrettyAssemblera ? (а то вставил имеющийся текст в Pretty и большая часть кода "покраснела")

svofski
01.09.2025, 12:22
А как и чем упаковать данные для dzx12 ?
Есть ли текст dzx12 не для tаsm, а для PrettyAssemblera ? (а то вставил имеющийся текст в Pretty и большая часть кода "покраснела")

Вообще совместимое пересечение тасма и прекрасма близко к 100%, но конечно есть нюансы. Посмотри что именно покраснело -- если там есть дефайны, их надо вручную развернуть -- скорее всего там совсем немного. Обычно это все, что нужно.

ivagor
01.09.2025, 12:43
А как и чем упаковать данные для dzx12 ?
Есть ли текст dzx12 не для tаsm, а для PrettyAssemblera ?
Скачиваем zx02 (https://github.com/dmsc/zx02/releases/download/v2/zx02-progs-v2-win32.zip), упаковываем с опцией -1
zx02 -1 входной_файл выходной_файл
Добавил (https://zx-pk.ru/threads/29679-szhatie-dannykh.html?p=1217763&viewfull=1#post1217763) вариант прямого многоразового распаковщика для Pretty 8080 Assembler

metamorpho
01.09.2025, 15:30
svofski, а можно вот из этой темы
https://zx-pk.ru/threads/36272-pt3-pleer-dlya-vektora-06ts.html?p=1216108&viewfull=1#post1216108

Твой bin2db.py, можешь сделать его экзешник из кода , который ты там давал ( два раза пытался установить питона, чтобы скомпилировать экзешник, но выдает какой-то системный запрет на его установку)

svofski
01.09.2025, 15:37
svofski, а можно вот из этой темы
https://zx-pk.ru/threads/36272-pt3-pleer-dlya-vektora-06ts.html?p=1216108&viewfull=1#post1216108

Твой bin2db.py, можешь сделать его экзешник из кода , который ты там давал ( два раза пытался установить питона, чтобы скомпилировать экзешник, но выдает какой-то системный запрет на его установку)

Попробуй тут https://py2exe.com/convert
Но это крайне неэффективно, такие инструменты заворачивают целиком питонский рантайм вместе со скриптом на три строчки. Будет более перспективно разобраться что за проблема у тебя с установкой Питона. Если ты не можешь поставить от имени администратора, его можно ставить в юзерский каталог. Ну или может найти другую программу.