Software - Обзор упаковщиков данных для ZX Spectrum от Noby (Quido, Pressor VI, Tolkien, Hrust, ZX7, LZX)

  1. Packing (Noby)
  2. Как я не портировал ассемблер на Mattel Aquarius (dex)
  3. Shooter (Mike/ZT)
  4. Shooter — исходный код (Mike/ZT)
  5. Calm Commander (Shrek)

Packing

Компрессия, packing, пакование, упаковка. Разные способы сложить и записать данные так, чтобы они занимали как можно меньше места. Обычно речь о том, чтобы сохранённая программа была как можно короче и занимала при сохранении — типично на кассете — как можно меньше места, и тем самым сокращалось время загрузки. Часто бывает, что в программе есть свободные места: на разные буферы, кэш, но особенно в графике — пустые или сплошные площади, либо повторяющиеся узоры.

Пакование отродясь было частью крякинга — деятельности, цель которой — чтобы игру можно было копировать, либо копировать легче. Здесь нужно сохранить весь блок используемой памяти; пакование укорачивает пустые места между данными, часто до 2 байт. Если решать это на PC, то есть на Помощном Computer’е, подходящий инструмент — программа Quido от Roman Bórik. Это классическая консольная утилита, работающая и под Windows, и на Linux. Того, что она изначально предназначена для PMD 85, не пугайтесь: есть возможность генерации кода и для i8080, и для Z80. Плюс в том, что умеет прикрепить распаковочную рутину прямо к данным, так что они автоматически развернутся или запустятся. К тому же можно сразу сгенерировать загрузочный Basic — и всё это сохранить в TAP-файл.

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

Типичный пример — Pressor VI, который предназначен для картинок и умеет работать с вырезками, то есть с выбранной частью изображения. Поскольку мы у DISKzine, его преимущество в том, что он для D40/80, так что результат красиво сохраняем сразу на дискету. На PC это, правда, немного бой с эмулятором, не всегда решаемый. Другой пример — Tolkien, который уже для текстов, и у него есть вариант и на PC.

Затем есть, я бы сказал, современные пакеры вроде Hrust, ZX7, LZX и других.

У Hrust первые версии нативно для Spectrum (осторожно: при паковании нужен 128, для распаковки уже нет), но есть и продолжатели для PC. У LZX куча возможностей, две одноцелевые подварианты, и всегда находится оптимальное решение для как можно более коротких данных. Потом к данным нужно применить правильную версию распаковочной рутины и при необходимости правильно сконфигурировать её под использованную оптимальную версию компрессии.

ZX7 относительно универсален, не достигает столь совершенных результатов, как LZX, и имеет три распаковочные рутины — они отличаются только длиной и скоростью: действует обратная пропорция — чем длиннее рутина, тем быстрее. Данные всегда одни и те же, так что какую использовать — всё равно, зависит от предпочтений и привычки.

Общее у них то, что у вас есть запакованные данные и распаковочная рутина; рутину можно иметь одну, а данных несколько — типично спрятать в страницах картинки, тексты, данные уровней, другие демоэффекты и распаковывать их в рабочую память, только когда нужны. Затем в HL кладётся адрес расположения данных, в DE — куда распаковывать. В некоторых случаях эти места могут частично перекрываться, но я бы на это особо не полагался (надо пробовать) — и исходные запакованные данные тогда будут перезаписаны и, стало быть, уничтожены.

У всего есть плюсы и минусы: это тяжело для организации памяти, программист потом теряется в разных таблицах с пятизначными числами (в десятичной системе; в HEX, разумеется, четырёхзначными). Распаковка длится по-разному, и при заковыристых данных и особенно хитром методе пакования это может быть удивительно долго. Это особенно верно для LZX; разумеется, метод пакования ему можно навязать параметром, но эффективность тогда уже не та. Тем не менее потом можно творить такие чудеса, что в программах куча графики, текстов, эффектов и прочих дефектов. Вопрос — стоит ли это в эпоху, когда у нас большие носители и возможность загружать с них с большой скоростью. Скорость загрузки картинки с DivMMC выше, чем длится распаковка некоторыми из вышеупомянутых методов, что доказывают некоторые сомнительные slideshow, грузящиеся прямо с DivIDE или DivMMC, либо видео, создаваемые для DivIDE.

Так что — удачного пакования! Noby


Как я не портировал ассемблер на Mattel Aquarius

Любопытно, что с 2005 года мне не удалось закончить ни одного проекта. Да, в 2018 я выпустил ерунду Wall 3D для 3D-очков VR64, но это даже не полноценный и доведённый проект — лишь результат немногого свободного времени на весенних каникулах. И тех нужных 3D-очков у меня построено недостаточно, и лучший софт для них я тоже не довёл.

Одной из вещей, о которых я говорил себе, что это достаточно просто, чтобы не отняло много времени и действительно можно было довести до конца, был порт ассемблера с ZX Spectrum на Mattel Aquarius.

К Aquarius я пришёл при изучении обскурных платформ, конкретно семейства компьютеров с процессором Z80. Это типичный продукт менеджерских решений: должно быть для программирования и не конкурировать с нашей игровой консолью — так что не дадим никакой графики, RAM оставим два кила, звуковой чип и возможность подключения джойстиков дадим только как опциональный модуль.

А какой софт на это выпустим? Ну конечно игры!

И так Aquarius наделён играми для текстового режима, в котором нельзя переопределить знаки; единственные доступные языки для него — Basic и Logo. Сначала я подумывал о Tiny Pascal, но компьютер, для которого нет ассемблера? Так не может быть!

Ещё одна несколько странная вещь — современное дисковое расширение для Aquarius. MicroExpander от австралийского автора даёт доступ к файлам на USB-флешке в формате FAT, но сделан несколько необычно. В железе компьютера, правда, есть сигнал CPM (бит 0 на порту FD), предназначенный для отстраничивания ROM и переадресации памяти (по сути меняет местами верхние и нижние 16 кило адресного пространства), чтобы была возможна как раз реализация CP/M или другой системы, но MicroExpander его не использует и работает иначе.

Оригинальную ROM оставляет там, где она есть, а в верхних 16 килах эмулирует cartridge, содержащий USB-Basic — Basic, расширенный относительно исходного восьмикилобайтного от Microsoft. Он произведён от BL-Basic; BL значит BootLoad — изначально он возник затем, чтобы из программы, написанной на Basic, создать образ cartridge, который после включения компьютера сразу запускается. Достигает этого интересным способом — команда LDUMP посылает содержимое сгенерированного cartridge на последовательный порт, изначально предназначенный для подключения принтера. А поскольку пользователи ретрокомпьютеров давно уже работают не с реальными машинами, а с эмуляторами, здесь в эмуляторе можно настроить вывод в файл, который из TXT просто переименуете в ROM.

В BLBasic есть команды SCR, PUT и GET для работы с текстовыми «спрайтами»; их из USB Basic убрали и дополнили командами для чтения и сохранения файла на USB. Это, однако, значит, что единственный способ загрузить или сохранить программу или данные — командой в Basic.

В момент, когда в виртуальный cartridge вместо USB-Basic загружаете какую-то программу — скажем, текстовый редактор или базу данных — вы теряете возможность общаться с USB-устройством записи и остаётесь только с работой через магнитофон.

Ещё один недостаток: MicroExpander несёт всего 32 кила RAM, из которых 16 кило использует для эмуляции cartridge. Программа, запущенная из cartridge, таким образом имеет в распоряжении только 18 кило RAM (2 кила встроены в компьютер), а 16 кило адресного пространства остаются неиспользованными.

Ну и наконец добираемся до ZX Spectrum.

Когда я смотрел, какой ассемблер лучше всего подойдёт для порта, я прочёсывал воды софтварного оснащения ZX Spectrum. Разумеется, идеально, чтобы к данному ассемблеру был исходник — это немного сужало круг выбора. Тем не менее я наткнулся на идеального кандидата. Интересно, что это именно тот ассемблер, который Sinclair официально поставлял к ZX Spectrum как средство разработки!

Zeus assembler изначально возник для компьютера Nascom. Для нас, чехословаков, Nascom интересен тем, что Nascom Basic от Microsoft был дизассемблирован и комментированный исходник тогда уже был и у нас — благодаря чему возник G-Basic для PMD 85. Nascom-версию Zeus assembler я нигде не нашёл, зато мне показалось интересным, сколько для него существует трансляторов Pascal — рядом с HiSoft Pascal ещё Nascom Pascal, небольшой Integer Pascal или BLS Pascal — предшественник Turbo Pascal.

Но обратно к Spectrum.

Авторы ассемблера для Spectrum — Neil Mottershead, написавший сам ассемблер, и Simon Brattel, писавший монитор. Оба позже были авторами многих известных игр для Spectrum — Dark Star, Forbidden Planet, The Warlock of Firetop Mountain, Halls of the Things, Return of the Things, Invasion of the body snatchas! Также выпустили отдельный монитор и дизассемблер, который Sinclair тоже продавал под своей маркой.

Оригинальный исходник ассемблера не сохранился, однако авторы в 2020 году программу дизассемблировали и спустя годы попытались её и прокомментировать. Zeus assembler написан поистине гениально и имеет несколько интересных свойств. Во-первых, у него такой быстрый перевод, что в одном журнале при тестировании разных ассемблеров даже не заметили, что Zeus что-то скомпилировал, и титул самого быстрого транслятора присудили программе в 60 раз более медленной. Далее — у него нет команд для загрузки или сохранения исходного текста и результирующей переведённой программы. Это потому, что он позволяет держать в памяти несколько исходных текстов и переключаться между ними — лишь бы они не перекрывались. Но это предъявляет к пользователю определённые требования, и для начинающих может быть слишком сложно.

Ассемблер сообщает пользователю, откуда куда у него сохранён исходный текст (команда T) или переведённый код; чтение и сохранение пользователь обслуживает сам командами LOAD и SAVE CODE в Basic. Переключение между исходниками делается лишь перенастройкой начального адреса текущего исходного текста (приказ O) или созданием нового исходника (приказ N). То, что на Spectrum несколько неудобно, может быть преимуществом для Aquarius — не нужно ограничиваться магнитофоном: достаточно выскочить из ассемблера в USB-Basic и читать и сохранять с USB-флешки!

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

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

Но разобраться в такой вещи, особенно когда она написана очень экономно и прокомментирована похожим образом? Особенно если время взглянуть на исходник есть лишь изредка, а между тем забываешь, что в нём собственно есть — это не так легко.

Особенно интересен редактор, сдвиг знака по строкам и столбцам. Не говоря о том, что программа уже однажды была перенесена с компьютера, у которого знаковый режим с 48 знаками в строке (правда, со строками, адресуемыми по 64 байта — 16 байт на Nascom просто не отображаются), оптимизация для компьютера с 32 знаками в строке восхитительна, а рутины невероятно короткие благодаря необычным проверкам на конец строки. Используется то, что число больше или меньше 31 (00011111) просто маскируется масками E0 и 1F.

У Aquarius 40 знаков в строке, и число больше или меньше 00100111 так легко не замаскировать — приходится заменить вычитанием, а это значит ещё и исходное значение куда-то спрятать; при переполнении нельзя просто замаскировать переполнившийся бит — нужно вручную задать новое значение. Оставить редактор на 32 знаках в строке нельзя, потому что тогда на Aquarius строки не будут правильно переноситься, а будут нечитаемо следовать одна за другой — так что эту работу просто придётся сделать.

Zeus assembler — просто неортодоксальный, но превосходно написанный кусок программы. Sinclair хорошо сделал, что выбрал именно этот ассемблер для дистрибуции под своей маркой. В конце концов, я наткнулся на упоминание, что некоторые софтверные издатели меняли в нём сообщение о copyright и давали его сотрудникам для разработки как фирменный ассемблер.

Да, позже мы дождались более комплексных программ, которые умели в редакторе больше знаков в строке, include исходных текстов или бинарных файлов (чаще при работе с Microdrive, как Editor/Assembler от OCP) или приспособили управление — особенно загрузку и сохранение файлов — для тех, кто пришёл из Basic (как Editor/Assembler от Picturesque); некоторые были действительно комплексными, как Laser Genius; наибольшей славы, наверное, достиг GENS — и Zeus постепенно перестали использовать.

За его несомненные качества, впрочем, не удивительно, что позже Zeus развился в кросс-ассемблер для MS-DOS с макросами, циклами и условной трансляцией, где использовался для разработки игр для ZX Spectrum и Amstrad CPC. А почитать исходник версии для ZX Spectrum я действительно рекомендую.

Исходник для чтения (zeus1.zip), MS-DOS-версию и исходники некоторых игр издательств Crystal Computing и Design Design найдёте по URL http://www.desdes.com/products/oldfiles/zeus.htm.

Специально для RESTORE 2 написал dex.


(Для продолжения нажмите клавишу X.)

Поделитесь вашим мнением о статье