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 вещей, представляющих умеренный интерес (возможно)
-
Текст самой «поэмы» занимает всего 169 байт и хранится в переменной a$. Изначально внутри неё содержались символы возврата каретки (CHR$13), но из-за этого LISTing программы после вставки в строку 1 LET a$="VAL бла-бла и т. д..." становился неудобным, поэтому я решил заменить управляющие коды на 'A' и 'B'. Команда PRINT a$ выводит весь текст целиком.
-
Текстовая строка была внесена в оператор LET a$="VAL etc" с помощью POKE, поскольку вводить некоторые ключевые слова вручную неудобно (особенно те, которые требуют курсора K). Это потребовало перевода токенов в их символьные коды (например, PRINT=245) и поиска оператора BASIC в ОЗУ. Теперь у меня для этих целей есть таблица в Excel с набором символов ZX Spectrum.
-
Графические данные (которые занимают большую часть листинга Бейсика в виде операторов DATA) были созданы с помощью небольшой подпрограммы, написанной мной (тоже на Бейсике). Этот весьма примитивный инструмент для рисования позволял мне выбирать позиции на экране для вывода точек и линий, а затем выдавал числа, которые я мог скопировать в операторы DATA. Оглядываясь назад, я мог бы сохранить эти данные более эффективно. Я экспериментировал с переносом всех этих данных в числовой массив-переменную ARRAY — но доступ к нему оказался значительно медленнее, чем метод RESTORE {вычисленный номер строки}, который я использовал в этом листинге. Кстати, эстетика лайн-арта мне вполне нравится — и операторы DRAW выполняются на самом деле довольно шустро, хотя операторы CIRCLE кажутся мучительно медленными.
-
BEEPER-МУЗЫКА — это любопытный образец минимализма (для тех, кому это интересно и кто увлекается теорией музыки). Значения нот хранятся в операторах DATA в строках 7000, 7005 и 7010. (И проигрываются процедурой в строках 85–96). По сути, эти данные — простые арпеджио аккордов [Am, Am, Dm, E7], которые затем повторяются один раз, а после идет небольшая вариация с чередующимися нисходящими и восходящими пассажами по каждому аккорду. Размер произведения — 6/8, поэтому теоретически до повтора должно было прозвучать 643 = 72 ноты. Однако в ней (намеренно) пропускается каждая шестая нота — тем самым создается пауза. Это отчетливо слышно в мелодии (которая явно состоит из фраз по 5 нот). Самое интересное, что весь набор данных составляет всего 71 ноту — поэтому при зацикливании (после того как проиграны все 71 нота) он начинается сначала; таким образом, при повторе первая сыгранная нота сдвигается на одну позицию вперед по данным. Это означает, что при втором проходе в каждой фразе пропускается уже другая нота. На третьем проходе происходит еще один сдвиг на единицу, и так далее — благодаря чему мы каждый раз слышим разные музыкальные фразы, у которых каждый раз словно меняются акценты.
-
Значение V+0.771 в операторе BEEP нужно для того, чтобы приблизительно настроить бипер в унисон с AY-музыкой — делая переход от биперной интро-мелодии к «внутриигровой» чуть менее резким.
-
AY-МУЗЫКА. Подобного в программах на BASIC я раньше не встречал, и это доставило мне немало головной боли. Я написал процедуру на машинных кодах для режима прерываний interrupt mode 2, вызываемую каждые 1/50 секунды, которая проигрывает музыку и переходит на стандартную подпрограмму прерываний ROM для опроса клавиатуры для BASIC и прочих нужд. Команда RANDOMIZE USR 49060 настраивает все необходимое для IM2. Я не знал точно, сколько музыки напишу, поэтому позаботился о том, чтобы значение CLEAR 49059 было достаточно высоким и позволило уместиться бейсик-программе — но при этом оставило достаточный запас для музыки, подпрограммы IM2 и таблицы векторов IM2. Если только вы не читаете очень медленно, вряд ли музыка успеет зациклиться к тому моменту, как вы дочитаете текст.
-
Выход в BASIC. Выход в BASIC приводит к одному из двух эффектов: если все прошло по плану, вы остаетесь с играющей на фоне музыкой (ad infinitum), пока изучаете листинг программы в режиме 48K Basic. Но на модели 128K при определенных комбинациях подключенной периферии это также может вызвать зависание при выходе в BASIC. Я мог бы предотвратить это, восстановив IM1 в конце программы... но мне очень понравился этот сюрреалистичный эффект, когда ты возвращаешься к командной строке Basic, а музыка все еще продолжает играть, поэтому я захотел сделать это поведением по умолчанию — независимо от используемой модели Spectrum. Что и привело меня к исследованию...
-
Принудительный вход в режим USR0 (режим 48K Spectrum), независимо от того, какой Spectrum вы используете. У загрузчика весьма интересная первая строка, за которую я не могу взять всю славу себе. Я без зазрения совести использовал наработку Slavomir Labsky (https://busy.speccy.cz/tvorba/usr0.htm), чтобы принудительно включить режим USR0 (то есть перейти в режим 48K на 128K Spectrum) и затем продолжить выполнение остальной части BASIC-программы. Существует вероятность несовместимости с некоторыми конфигурациями «железа»/периферией — на этот случай подготовлен «альтернативный» файл .tap (который следует загружать из режима 48K BASIC на 128K Spectrum). Однако обычная версия должна работать в 99% случаев, как мне кажется. (Я надеюсь).
-
В строку REM в загрузчике я нагло втиснул 16 байт машинного кода, который заполняет экран «шахматкой», благодаря чему «загрузочный экран» состоит исключительно из данных атрибутов. (И здесь я обращаю внимание на то, что клавиша 'O' — безусловно, самая забавная на резиновом Speccy. «Oh! Peek at him Poking Out!» («Ой! Глянь, как он торчит/выглядывает!») — словно говорят ключевые слова PEEK, POKE и OUT. Matron!!)
-
Имя файла загрузчика намного длиннее, чем «разрешено», за счёт использования токенов ключевых слов. Чтобы не выбиваться из общей темы токенов Бейсика.
-
RANDOMIZE USR 49093 останавливает музыку (для тех, кто отвык от 48K Бейсика: нажмите клавишу T [RANDOMIZE], затем Sym+Caps для перехода в режим 'Extended', затем L [USR], потом 4,9,0,9,3 и [Enter]). Не то чтобы вам захотелось её остановить — пусть себе играет. И играет.
-
RANDOMIZE USR 3582 — используется по всей программе на BASIC, это подпрограмма ROM, которая скроллит экран. Разве вы не скучаете по команде SCROLL из Бейсика на ZX81? Я вот скучаю.
-
Как заметил Dave (R-Tape), 'Love Tokens' по духу не так уж далека от великолепной 'Camouflage' Криса Сиви (Chris Sievey) (https://www.youtube.com/watch?v=8u9ZyV-BHFA). Удивительно, но этот «анимированный поп-клип» был написан для ZX81 и записан на обратной стороне 7-дюймового сингла. Возможно, в следующий раз я попробую сделать что-то, что синхронизируется с AY-музыкой. ВОТ ЭТО задачка.
Надеюсь, вам понравится.
Andy
Дек 2020.
Поделитесь вашим мнением о статье