Love Tokens: Поэзия на токенах Бейсика

Woot! #04

LOVE TOKENS

Написано для WOOT 2020: Andy Jenkinson (uglifruit)

Для ZX Spectrum.

С улучшенным музыкальным сопровождением для Spectrum с чипом AY

(модели 128K или 48K с внешним чипом AY, например, Melodik AY-3-8192 Soundbox или расширением ZX-AY).

Поставляются две версии:

LOVE-TOKENS-(BASIC and AY).tap
LOVE-TOKENS-(BASIC and AY - ALTERNATE - USR0 version).tap *

* Используйте эту версию только в том случае, если другая вызывает несовместимость с нестандартной периферией/моделями Spectrum. Её следует загружать в режиме 48K/USR0.


Эта работа родилась из желания написать что-нибудь, используя исключительно ключевые слова-токены Бейсика, напечатанные на клавиатуре оригинального ZX Spectrum («PRINT, LOAD, SAVE...» и т. д.). Таким образом, это можно считать поэзией в жанре «комбинаторной литературы» (термин, который мог бы использовать выпускник филологического факультета).

После того как я написал текст, используя только токены Бейсика, встала задача проиллюстрировать его. Чтобы продолжить тему, это было сделано исключительно с помощью бейсиковских команд PLOT, DRAW и CIRCLE.

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

13 вещей, представляющих умеренный интерес (возможно)

  1. Текст самой «поэмы» занимает всего 169 байт и хранится в переменной a$. Изначально внутри неё содержались символы возврата каретки (CHR$13), но из-за этого LISTing программы после вставки в строку 1 LET a$="VAL бла-бла и т. д..." становился неудобным, поэтому я решил заменить управляющие коды на 'A' и 'B'. Команда PRINT a$ выводит весь текст целиком.

  2. Текстовая строка была внесена в оператор LET a$="VAL etc" с помощью POKE, поскольку вводить некоторые ключевые слова вручную неудобно (особенно те, которые требуют курсора K). Это потребовало перевода токенов в их символьные коды (например, PRINT=245) и поиска оператора BASIC в ОЗУ. Теперь у меня для этих целей есть таблица в Excel с набором символов ZX Spectrum.

  3. Графические данные (которые занимают большую часть листинга Бейсика в виде операторов DATA) были созданы с помощью небольшой подпрограммы, написанной мной (тоже на Бейсике). Этот весьма примитивный инструмент для рисования позволял мне выбирать позиции на экране для вывода точек и линий, а затем выдавал числа, которые я мог скопировать в операторы DATA. Оглядываясь назад, я мог бы сохранить эти данные более эффективно. Я экспериментировал с переносом всех этих данных в числовой массив-переменную ARRAY — но доступ к нему оказался значительно медленнее, чем метод RESTORE {вычисленный номер строки}, который я использовал в этом листинге. Кстати, эстетика лайн-арта мне вполне нравится — и операторы DRAW выполняются на самом деле довольно шустро, хотя операторы CIRCLE кажутся мучительно медленными.

  4. BEEPER-МУЗЫКА — это любопытный образец минимализма (для тех, кому это интересно и кто увлекается теорией музыки). Значения нот хранятся в операторах DATA в строках 7000, 7005 и 7010. (И проигрываются процедурой в строках 85–96). По сути, эти данные — простые арпеджио аккордов [Am, Am, Dm, E7], которые затем повторяются один раз, а после идет небольшая вариация с чередующимися нисходящими и восходящими пассажами по каждому аккорду. Размер произведения — 6/8, поэтому теоретически до повтора должно было прозвучать 643 = 72 ноты. Однако в ней (намеренно) пропускается каждая шестая нота — тем самым создается пауза. Это отчетливо слышно в мелодии (которая явно состоит из фраз по 5 нот). Самое интересное, что весь набор данных составляет всего 71 ноту — поэтому при зацикливании (после того как проиграны все 71 нота) он начинается сначала; таким образом, при повторе первая сыгранная нота сдвигается на одну позицию вперед по данным. Это означает, что при втором проходе в каждой фразе пропускается уже другая нота. На третьем проходе происходит еще один сдвиг на единицу, и так далее — благодаря чему мы каждый раз слышим разные музыкальные фразы, у которых каждый раз словно меняются акценты.

  5. Значение V+0.771 в операторе BEEP нужно для того, чтобы приблизительно настроить бипер в унисон с AY-музыкой — делая переход от биперной интро-мелодии к «внутриигровой» чуть менее резким.

  6. AY-МУЗЫКА. Подобного в программах на BASIC я раньше не встречал, и это доставило мне немало головной боли. Я написал процедуру на машинных кодах для режима прерываний interrupt mode 2, вызываемую каждые 1/50 секунды, которая проигрывает музыку и переходит на стандартную подпрограмму прерываний ROM для опроса клавиатуры для BASIC и прочих нужд. Команда RANDOMIZE USR 49060 настраивает все необходимое для IM2. Я не знал точно, сколько музыки напишу, поэтому позаботился о том, чтобы значение CLEAR 49059 было достаточно высоким и позволило уместиться бейсик-программе — но при этом оставило достаточный запас для музыки, подпрограммы IM2 и таблицы векторов IM2. Если только вы не читаете очень медленно, вряд ли музыка успеет зациклиться к тому моменту, как вы дочитаете текст.

  7. Выход в BASIC. Выход в BASIC приводит к одному из двух эффектов: если все прошло по плану, вы остаетесь с играющей на фоне музыкой (ad infinitum), пока изучаете листинг программы в режиме 48K Basic. Но на модели 128K при определенных комбинациях подключенной периферии это также может вызвать зависание при выходе в BASIC. Я мог бы предотвратить это, восстановив IM1 в конце программы... но мне очень понравился этот сюрреалистичный эффект, когда ты возвращаешься к командной строке Basic, а музыка все еще продолжает играть, поэтому я захотел сделать это поведением по умолчанию — независимо от используемой модели Spectrum. Что и привело меня к исследованию...

  8. Принудительный вход в режим USR0 (режим 48K Spectrum), независимо от того, какой Spectrum вы используете. У загрузчика весьма интересная первая строка, за которую я не могу взять всю славу себе. Я без зазрения совести использовал наработку Slavomir Labsky (https://busy.speccy.cz/tvorba/usr0.htm), чтобы принудительно включить режим USR0 (то есть перейти в режим 48K на 128K Spectrum) и затем продолжить выполнение остальной части BASIC-программы. Существует вероятность несовместимости с некоторыми конфигурациями «железа»/периферией — на этот случай подготовлен «альтернативный» файл .tap (который следует загружать из режима 48K BASIC на 128K Spectrum). Однако обычная версия должна работать в 99% случаев, как мне кажется. (Я надеюсь).

  9. В строку REM в загрузчике я нагло втиснул 16 байт машинного кода, который заполняет экран «шахматкой», благодаря чему «загрузочный экран» состоит исключительно из данных атрибутов. (И здесь я обращаю внимание на то, что клавиша 'O' — безусловно, самая забавная на резиновом Speccy. «Oh! Peek at him Poking Out!» («Ой! Глянь, как он торчит/выглядывает!») — словно говорят ключевые слова PEEK, POKE и OUT. Matron!!)

  10. Имя файла загрузчика намного длиннее, чем «разрешено», за счёт использования токенов ключевых слов. Чтобы не выбиваться из общей темы токенов Бейсика.

  11. RANDOMIZE USR 49093 останавливает музыку (для тех, кто отвык от 48K Бейсика: нажмите клавишу T [RANDOMIZE], затем Sym+Caps для перехода в режим 'Extended', затем L [USR], потом 4,9,0,9,3 и [Enter]). Не то чтобы вам захотелось её остановить — пусть себе играет. И играет.

  12. RANDOMIZE USR 3582 — используется по всей программе на BASIC, это подпрограмма ROM, которая скроллит экран. Разве вы не скучаете по команде SCROLL из Бейсика на ZX81? Я вот скучаю.

  13. Как заметил Dave (R-Tape), 'Love Tokens' по духу не так уж далека от великолепной 'Camouflage' Криса Сиви (Chris Sievey) (https://www.youtube.com/watch?v=8u9ZyV-BHFA). Удивительно, но этот «анимированный поп-клип» был написан для ZX81 и записан на обратной стороне 7-дюймового сингла. Возможно, в следующий раз я попробую сделать что-то, что синхронизируется с AY-музыкой. ВОТ ЭТО задачка.

Надеюсь, вам понравится.

Andy
Дек 2020.

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