Хабрахабр

Программирование под БК 0010 в 2019-ом году

Зачем?

Если Вы — энтузиаст ретро-компьютеров, то мотивационную речь можете смело пропустить и перейти к следующему разделу.

На фестивале Chaos Constructions наша работа заняла второе место, за что мы получили денежный приз 35 тысяч рублей, который честно поделили поровну. Весь август 2018-го года я и мой 13-летний сын Ivanq потратили на написание демки Good Apple. Очевидно, и я мог потратить своё время с большей экономической выгодой… Но только не август! Для ребёнка это неплохой доход, хотя, созданием сайтов он зарабатывал столько же за меньшее время. Программировать в своё удовольствие — это роскошь, которую можно позволить себе только в отпуске. Надо же когда-то отдыхать от работы.

Удивительно, что демка для забытого советского компьютера собрала тысячи просмотров на youtube и попала в плейлист с почти сотней тысяч просмотров. Good Apple demo by SandS

Материальное вознаграждение, конечно, не служит мотивацией, но закрепляет положительные эмоции. Возможно, сама невероятность происходящего и порождает такой эмоциональный подъём. Но ещё более удивительно, что в 2018-ом году за неё вручают денежный приз!

Однако, есть кое-что более важное.

Прежде всего, хотелось добиться одинаково устойчивой работы с жёсткими дисками формата IDE и с их современными заменителями в виде Compact Flash. При создании “Good Apple” нам пришлось работать с реальным железом, так как мы использовали возможности компьютера, которые эмуляторы воспроизводят не совсем корректно.

Дефектное железо. Именно на этом проекте мой 13-летний сын обрёл бесценный опыт промышленной разработки. Документация, которая составлена с ошибками. Хорошее железо, которое ведёт себя не так, как описано в документации. Написание собственных тестов для выявления проблем с железом. Отсутствие документации по ряду вопросов. Тестирование на разных машинах и конфигурациях. Выходящие сроки. И, наконец, после короткого празднования успеха — обязательный выпуск финальной версии, исправляющей ряд багов. Написание собственного кросс-ассемблера (когда стало понятно, что существующие решения тормозят процесс разработки).

По факту же, нам пришлось погрузиться в самые дебри схемотехники. На первый взгляд кажется, что подобный опыт можно было получить и с каким-нибудь современным Arduino. В разных типах памяти это время отличается. Мы вычисляли число тактов, за которое исполняются инструкции. Длительность исполнения подпрограммы не равна сумме длительностей команд этой подпрограммы. Контроллер памяти и процессор работают на разных частотах, поэтому одинаковые команды могут выполняться разное время даже в памяти одного типа. Нам пришлось писать собственные инструменты для тестирования и оптимизации кода на реальном железе.

Утилита для замера скорости выполнения фрагмента кода

— я в этом уже ничего не понимаю). Закончилось тем, что сын изучал схемотехнику БК 0011 (какие фронты сигналов куда приходят, когда срабатывает RPLY и т.д. Так он пришёл к идее сделать собственный эмулятор БК, совместимый с реальным железом с точностью до такта, и даже написал ядро… Впрочем, это уже другая история.

Всё это было бы невозможно без главного: Планирование. Итого, за месяц — от изучения ассемблера до создания собственных средств разработки, от хардварных тестов до готового мультимедийного произведения. Берёшь невозможную задачу. Пожалуй, наиболее ценный вынесенный урок. Планируешь. Понимаешь, что столкнёшься с непреодолимыми сложностями. Результат поражает всех настолько, что даже знатоки обвиняют в читерстве (“вы разогнали процессор!”). Делаешь.

Почему не ZX Spectrum?

Odnazhdy demo by Excess team

Судя по объявлениям на Avito, в среднем БК 0010 стоит в несколько раз дороже, чем ZX Spectrum. Опять начну со странного: с финансов. Но БК 0011м в полной комплектации всё равно выйдет дороже. Понятно, что за редкий экземпляр родного Спектрума в идеальном состоянии запросят круглую сумму. Цены говорят сами за себя: коллекционная значимость БК 0010 выше. Если вообще удастся найти. Иметь такой компьютер дома очень приятно. А БК 0011м — и подавно.

В БК 0010 нет ничего 8-разрядного. Второй аргумент – 16-бит. 16-битность во всём. Процессор даже не умеет складывать 8-битные числа, у него нет команды ADDB. Многие называют систему команд процессора PDP-11 самой удачной и самой удобной из когда-либо созданных. Причиной тому – архитектура DEC PDP-11. Но вот один факт: на прошедшем в Яндексе фестивале “Демодуляция” было три семинара, посвящённых архитектурам процессоров, и два из них о PDP-11. Конечно, найдутся желающие поспорить с этим утверждением. БК 0010 даёт возможность прикоснуться к этой легенде. Это, действительно, легенда, важнейшая веха в истории вычислительной техники, которая до сих пор продолжает будоражить умы энтузиастов. И не просто прикоснуться, а разобраться в ней до мельчайших деталей, прочувствовать всю красоту и изящество DEC’овского ассемблера: абсолютно равноправные регистры, восемь методов адресации, линейная память – красота!

Для БК 0010 — меньше полусотни, считая мелкие 256-байтные и 4-килобайтные. Третий довод: для ZX Spectrum написано множество демок. Место на демосцене почти свободно, есть где себя проявить даже начинающему!

Я наблюдаю за российской демосценой с 1994-го года. И последнее соображение, чисто субъективное. Конечно, есть и прекрасные дружелюбные люди! Тусовка спектрумистов представляется мне, к сожалению, более токсичной и враждебной. Но в целом – вероятно из-за своей массовости – спектрумовская сцена наполнилась конфликтами, выяснением отношений и даже интригами типа name-voting (когда на конкурсах голосуют только за “своих”). Испытываю огромное уважение к ним и к их творчеству. Повторю: это моё сугубо личное впечатление, которое вы можете проигнорировать. В то время как на маленькой БК-шной сцене не ставят вопросов типа “кто круче” и рады каждому новому участнику.

Реальное железо

Прошло 20 лет, прежде чем я вернулся к написанию программ для БК. За эти 20 лет многое изменилось. Лично для меня главный сдвиг произошёл в сознании: “Think Different”. Именно этот слоган помещён в заключительные титры нашей демки “Good Apple”.

Затем появились контроллеры дисководов. Раньше мы по 5 минут грузили игры с магнитофона. Потом новодельные реплики контроллеров с Compact Flash на борту. За ними – жёсткие диски. Так давайте возьмём стандартный аудио-шнур DIN-5 — mini jack (даже перепаивать не придётся) и будем грузить БК с iPhone на высокой скорости. Теперь на ретро-сцене принято эмулировать дисководы флешками… Но постойте, в 2019-ом году у нас есть высококачественный портативный источник звука – iPhone.

Я прошёлся трассировкой по ПЗУ, выявил как можно слегка перехитрить алгоритм загрузки с магнитофона и заставить БК читать данные в 4 раза быстрее.

И загрузчик, и данные помещались друг за другом в единый WAV-файл (конвертер написал Ленар Закиров). Следующим этапом стало написание микро-загрузчика, который считывал данные в специально разработанном турбо-формате. Частоты в турбо-формате доходят до 22 КГц, поэтому требования к качеству источника звука высоки. БК 0010 считывает и автоматически запускает микро-загрузчик, а тот, в свою очередь, читает остаток данных из файла. Хороший музыкальный плеер тем более. iPhone справляется. Звуковая карта компьютера тоже.

В него были добавлены опции сохранения программы в WAV (как в стандартном, так и в турбо-формате). Затем настала очередь кросс-ассемблера. Только представьте, насколько ускорилась разработка! Более того, кросс-ассемблер умеет сразу проиграть WAV через звуковую карту. Просто вносишь изменения в код, нажимаешь “Build”, звук льётся в БК и через несколько секунд программа уже запущена на реальном железе. Не нужно возиться с записью образа диска на CF-карту после каждой компиляции. Для передачи звука в турбо-формате нужно предварительно запустить микро-загрузчик (у меня он автоматически запускается с жёсткого диска при включении БК; в любой момент можно выйти в систему, нажав клавишу СТОП). Для приёма звука в стандартном формате достаточно нажать на БК 0011 клавиши L (Load) и Enter (загружать первую встреченную программу).

Загрузка программ в БК 0011м с компьютера

Нужно спаять кабель с “тюльпаном” на одном конце и DIN-5 на другом. Подключить БК к телевизору проще всего в монохромном режиме, в обычный композитный AV-вход. Земле традиционно соответствует 2-ой контакт DIN-5. Монохромный сигнал выходит с 4-го контакта DIN-5 разъёма БК, обозначенного “ТВ”.

Но большинство игр и все демки предпочтительней смотреть в цвете. Лично я поклонник монохромных ЭЛТ дисплеев – они обеспчивают чёткость изображения, недостижимую на цветных мониторах с их апертурной решёткой. Контакты 3, 4, 5 на DIN-5 – соответственно красный, синий, зелёный. Для этого используют “ТВЦ” выход БК и подключение к телевизору через RGB SCART. Контакт 2 – земля. Контакт 1 – синхронизация. 5 вольт обычно берут с соседнего разъёма “ТВ” (контакт 1). В случае подключения к ЖК-телевизору полезно подать +5 вольт на 16-ый контакт SCART (через резистор 200 Ом или около того).

Сразу предупрежу, что БК выводит изображение с частотой не 50 кадров в секунду, а 48. Можно воспользоваться конвертером SCART-HDMI. Я решил эту проблему заменой 12-мегагерцового кварцевого резонатора БК на 12. 83, поэтому вместо плавного скроллинга на ЖК-мониторах будет заметно периодическое подёргивание. Впрочем, подёргивание было заметно только в некоторых демках. 288 МГц. Большинство программ на БК не использует синхронизацию с кадровой частотой.

Я обнаружил четыре вещи, которые плохо эмулируются: Почему не довольствоваться эмулятором, для чего вообще может понадобиться реальный компьютер?

  1. Поведение динамика на высоких частотах.
  2. Синхронизация изображения и палитр с ходом луча.
  3. Точное время исполнения команд (важно для музыки через Covox).
  4. Работа с жёсткими дисками IDE на высоких скоростях.

Если вы не планируете делать ничего из вышеперечисленного, вам вполне хватит эмулятора.

Эмуляция

На MacOS я использую эмулятор BK2010. Он не очень точный, но для большинства задач подходит.

Он также запускается в CrossOver под MacOS и в Wine под Linux. Самый продвинутый на сегодняшний день эмулятор GID работает под Windows. В эмуляторе хороший отладчик, просмотрщик страниц памяти и тому подобное.

Но чаще передаю данные по звуковому каналу. Для записи образов дисков на Compact Flash пользуюсь мультиплатформенной утилитой Etcher.

Средства разработки

Компиляция из Sublime Text кросс-ассемблером PDPy11

Сперва мы пользовались им, но вскоре Ivanq написал свой собственный – мультиплатформенный, на Python. Ребята из демогруппы Excess Team подсказали кросс-ассемблер Алексея Морозова. Тут и поддержка многофайловых проектов, и сложные арифметические выражения, типы данных double word, интеграция с Sublime Text и расширенная поддержка ошибок компиляции, сохранение результата в формате звукового файла, компиляция не только под БК, но и под УКНЦ, и многое другое. Он работает медленней, зато гораздо богаче функционально. Обо всём этом можно почитать в официальной документации.

Кросс-ассемблер называется PDPy11.

Макро-ассемблер – это в некотором смысле другой язык. Некоторые из ветеранов жалуются, что в PDPy11 не хватает макросов классического DEC’овского макро-ассемблера (Macro-11). Иронично: для исходников БК-шных программ принято использовать расширение фала .mac (от “макро”) даже в тех ассемблерах, которые не поддерживают макросы. Он, вероятно, хорош для написания системных программ, но серьёзные игры и демки для БК писали, насколько я знаю, на обычном классическом ассемблере. В любом случае, возможностей PDPy11 хватает для написания программ любого уровня сложности.

Он позволяет задать адреса точек останова, в любой момент прерывать или продолжать исполнение программы, смотреть содержимое регистров и памяти, выполнять программу пошагово, изменять содержимое памяти и т.д. Отладчик встроен в эмулятор GID.

Разрешение БК – 256x256 точек в цветном режиме или 512x256 в монохромном. Для конвертации графики в формат БК мы написали онлайн-конвертер. Картинки большего размера лучше не подавать на вход конвертеру.

Документация

Прекрасное пособие по программированию на ассемблере написал Юрий Зальцман. Об отличиях БК 0011м от БК 0010 написано здесь. Существовала ещё модель БК 0011 (без “м”), но её быстро сняли с производства, признав неудачной.

Любая программа, корректно написанная для БК 0010, запустится и на БК 0011м. Несмотря на то, что БК 0011м обладает большими возможностями (цветовые палитры, дополнительные страницы памяти), поначалу я советую программировать под БК 0010 — эта модель проще и понятней.

Устройство процессора и набор инструкций хорошо описаны в Wikipedia.

Для самых отважных — программирование в кодах.

Hello, world!

Область экранной памяти в БК 0010 начинается с адреса 40000 (левый верхний угол) и заканчивается адресом 77777 (правый нижний угол экрана). Как нетрудно догадаться, в архитектуре PDP-11 используют 8-ричную систему счисления. Но кросс-ассемблер PDPy11 позволяет, конечно, записывать числа также в двоичной, десятичной, шестнадцатиричной системе – поступайте как вам привычней.

Аргументы в DEC’овском ассемблере записываются слева направо: источник, затем приёмник Например: Чтобы поставить точку на экране, нужно записать какое-нибудь число в область экранной памяти.

MOV #100000,@#60040 ; поставить точку в середину экрана

Знак # означает, что аргумент – просто число (а не адрес). Знак @# означает, что аргумент — абсолютный адрес (то есть он не изменится при переносе программы в другое место памяти).
Очистка экрана выглядит так:

MOV #40000,R1 ; начальный адрес MOV #20000,R0 ; счётчик цикла
1: CLR (R1)+ ; очищаем слово по адресу, после увеличиваем R1 SOB R0,1 ; оператор цикла

Косвенная адресация (R1) использует регистр R1 как указатель адреса. Память в БК адресуется побайтно, но инструкция CLR очищает сразу два соседних байта: сначала 40000 и 40001, на следующем шаге цикла 40002 и 40003, и так далее. Запись (R1)+ означает, что после использования аргумента нужно его увеличить. В данном случае на 2, потому что команда обрабатывает 2 байта. Счётчиком цикла может быть любой регистр. SOB вычитает единицу из регистра и переходит на метку 1. Локальные метки обозначаются цифрами и двоеточием, их область видимости между двумя глобальными метками. Глобальные метки должны начинаться с буквы и также заканчиваться двоеточием.

Тогда CLRB (R1)+ будет увеличивать регистр R1 уже не на 2, а на 1. Инструкцию CLR можно заставить работать с байтами, дописав букву “B”.

MOV #40000,R1 MOV R1,R0 ; теперь счётчик цикла должен быть вдвое больше
1: CLRB (R1)+ SOB R0,1

Можно сделать то же самое короче. Очищаем экран снизу вверх при помощи индексного метода адресации:

MOV #40000,R0
1: CLRB 37777(R0) ; по сути это (37777+R0) SOB R0,1

Если нужна высокая скорость, то лучше очищать память не побайтно, а сразу словами. Получится вдвое быстрее. Но можно ускориться сверх того: по какой-то причине команда CLR работает медленней, чем MOV. Поэтому:

CLR R2 ; записываем ноль в регистр R2 MOV #40000,R1 ; начальный адрес MOV #20000,R0 ; счётчик цикла
1: MOV R2,(R1)+ ; очищаем слово по адресу, после увеличиваем R1 SOB R0,1 ; оператор цикла

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

MOVB #0b00001100,@#50010 MOVB #0b00110000,@#50112 MOVB #0b11000000,@#50313

Цвета в каждой паре битов кодируются так: если установлен только чётный бит — зелёная точка, только нечётный бит — синяя, установлены оба бита — красная, сброшены оба бита — чёрная. Ну а монохромный монитор показывает каждый бит как отдельную точку.
Команда MOVB записывает в экранную память сразу 4 точки, а команда MOV — 8 точек. Если вы не хотите затрагивать соседние точки, используйте команду BIC (Bit Clear) и BIS (Bit Set), например:

BICB #0b00001100,@#50112 ; стереть точку BISB #0b00000100,@#50112 ; поставить синюю точку

Интересный момент: в тексте мы записываем младшие биты правее старших. А на экране наоборот: точки, соответствующие младшим битам, появляются левее.
Вот, собственно, и всё об устройстве экранной памяти БК 0010.

А что же на счёт вывода текста?

MOV #Text,R1 ; адрес текстовой строки EMT 20 ; вызов зашитой в ПЗУ процедуры печати текста HALT ; останов программы
Text: .ASCII “Hello, World!” .BYTE 0 ; строка должна заканчивать нулевым байтом

Покажите исходники!

Road2CAFe 256 bytes intro by Excess team

Легче всего будет начать, посмотрев исходники готовых демок:

Ностальгический рассказ о ранней демосцене впридачу. In Your Space — демо для Covox, исходники в архиве.
Good Apple — исходники на GitLab (сложный многофайловый проект).
EIS — эмулятор инструкций расширенной арифметики с исходниками.
Исходники трёх 256-байтных демок.
В 28-ом выпуске журнала Downgrade большая статья про эволюцию алгоритмов трекерной музыки на БК 0010, с фрагментами программ и подробными разъяснениями.

Когда приступать?

Прямо сейчас. Через 4 недели в Казани состоится демопати CAFe 2019. В программе фестиваля есть конкурс БК 0010 — 512 байт. В такой размер уместится от 85 до 256 инструкций – идеально для начинающих. Двух недель вам хватит на то, чтобы разобраться с инструментарием и написать первую простенькую демку. После этого ещё останется неделя-полторы на написание второй, более серьёзной работы.

Телеграм-чат, форум на zx-pk — везде вам помогут. Дерзайте, вы можете! Scene is alive! присылайте работы на конкурс, а лучше ещё и приезжайте сами.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»