В марте-мае этого года я потратил несколько недель (по вечерам и выходным) на портирование игрушки Lode Runner с БК-0010 на УКНЦ.
Скриншот меню портированной версии:

Игровой экран портированной версии:


БК-0010 это бытовой компьютер конца 1980-х и начала 1990-х, и отчасти школьный компьютер (классы КУВТ-86). УКНЦ это школьный компьютер 1990-х. БК и УКНЦ частично совместимы по архитектуре и системе команд — оба компьютера восходят к семейству PDP-11.

Выбор игры


До этого года я не писал ничего серьёзного под УКНЦ, но приходилось разбираться в машинном коде. Было желание написать что-нибудь, но обычно у меня большие проблемы со свободным временем, так что сделать что-либо с нуля вряд ли получилось бы. И для начала лучше брать задачу попроще. При портировании объём работы обычно намного меньше чем при написании с нуля — сталкиваешься в основном с проблемами несовместимости двух систем.

На форуме zx.pk.ru (одна из площадок где тусуются любители ретрокомпьютинга вообще и PDP-11 совместимых машин в частности) участник hobot расхваливал реализацию Lode Runner на БК — собственно это и стало поводом, для начала я попробовал «посмотреть» на код игрушки, ну и втянулся.

Меню оригинальной версии:

Игровой экран оригинальной версии (на цветном мониторе):


Обратная разработка


Пару недель по вечерам и выходным я потратил время на анализ и дизассемблирование. В эмуляторе BKBTL добавил возможность собирать трассу — то есть, каждая инструкция дизассемблируется и сохраняется в текстовый файл.
Делаю прогон участка который меня интересует с записью трассы, потом сворачиваю трассу (sort & uniq) — получаю фрагменты логики. Добавляю к этому комментарии, получаю постепенно общий файл.

Звучит просто, но на самом деле это довольно сложная работа, основанная на догадках и их подтверждении или опровержении. Например, смотрим что адрес 001756 перед началом игры получает значение 10, потом декрементируется, при достижении 0 игра заканчивается — видимо, это количество жизней. Находим этому подтверждение, расставляем комментарии по тексту где встречается этот адрес. Это довольно простой пример, в более сложных случаях я потратил много времени на то чтобы догадаться что к чему.

Когда полученный объём стал достаточно большим (40+ КБ текста, больше 1500 строк) и я разобрался хотя бы в общих чертах что к чему, как хранится и выводится — стал думать как это перевести на УКНЦ.

Здесь можно посмотреть на итоговый листинг, полученный в результате дизассемблирования:
github.com/nzeemin/uknc-loderunner/blob/master/original/loderunner.lst

Лабиринт


Каждый лабиринт — это 20 строк по 30 блоков, всего 600 блоков.
Тип блока кодируется числом от 0 до 7 — три бита, триплет. На одно 16-разрядное слово получается 5 полных триплетов.
В работе с PDP-11 like машинами повсеместно используется 8-ричная система, поэтому использовать триплеты довольно удобно.
В итоге, каждый лабиринт укладывается в 240 байт.

Типы блоков:
;	0 -- пусто
;	1 -- сплошная стена
;	2 -- кирпичная стена
;	3 -- верёвка
;	4 -- чёрт
;	5 -- человек
;	6 -- сундук
;	7 -- лестница

Спрайты этих объектов расположены в порядке нумерации типов блоков. Когда раскодируется лабиринт, одновременно создаётся «образ лабиринта» в памяти (по байту на блок), и тут же рисуется начальное состояние лабиринта на экране.

Организация экрана


На БК экран адресуется непосредственно обращением к памяти, строки идут одна за другой, по сути это «framebuffer», и я бы сказал что это прекрасно — очень удобно для программирования графики. Строка БК — 256 цветных пикселей, 64 байта на строку. А вот то, сколько пикселей в строке, зависит от того как вы подключили монитор:
если по чёрно-белому выходу, то это 512 ч/б пикселей в строке (1 бит на пиксел, 8 пикселей на байт),
а если по цветному выходу, то это 256 цветных пикселей в строке (2 бита на пиксел, 4 пиксела на байт).

На УКНЦ же организация экрана совсем другая, и намного более сложная. Экран лежит в трёх блоках памяти, трёх «планах». И каждый пиксель это три бита, по биту в каждом плане — получаем 8 цветов. На УКНЦ у нас есть несколько видеорежимов — 640 ? 288, 320 ? 288, 160 ? 288, точнее, у нас всегда ровно 288 строк и к каждой отдельной строке можно применить свой делитель, получая разное разрешение по горизонтали. Для центрального процессора (ЦП) планы экрана не доступны непосредственно, только через обращение к портам. Причём, для ЦП доступны только два плана из трёх.

В данном случае мне хорошо подходил режим 320 ? 288 — строка получается в 320 цветных пикселей длиной 80 байт в каждом из трёх планов. Если использовать два плана, то пиксели получаются тоже четырёхцветные — почти как на БК.

Синтез


Начал писать примеры на ассемблере УКНЦ и несколько приуныл — потому что цикл «скомпилил — слинковал — запустил» получается довольно медленный. Проблема в инструментах. Кросс-ассемблер MACRO11 есть, хоть он и несколько глючный. А вот кросс-линкера нет. Но к счастью, не так давно Patron выложил консольную RT-11: zx-pk.ru/showthread.php?t=24755 — по сути это эмулятор PDP11-совместимой машины, взаимодействующий с командной строкой ОС как с терминалом. Тем самым, стала возможной компиляция и линковка родными средствами RT-11. Это я считаю настоящий прорыв, резко ускорило работу.

После этого дело пошло, сделал отрисовку рамки игрового поля, отрисовку спрайтов, разобрался как биты в спрайтах нужно перемешать (для перемешивания написал программу на C#), затем блоками стал переносить код из общего файла с дизасмом в новые исходники. Взял дамп памяти с БК, выделил блок где лежат уровни, RT11-утилитой DUMP сделал текстовик под уровни.

Сначала перенёс блок кода который выводит уровень, на этом отладил вывод спрайтов. Потом игровую логику стал переносить. Т.е. в целом перенос практически один-к-одному, за исключением мест где вывод на экран идёт. Поэтому есть места в логике которые я не понимаю как работают (тот же AI чёртиков), но это и не важно — главное что работают.

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

Фото работающей игры на реальной машине (спасибо hobot):


Ссылки


Комментарии (10)


  1. eandr_67
    29.08.2015 21:09
    +1

    Забавно, но в конце 1980-х я проделывал тоже самое — но переносил на УК-НЦ игры не для БК, а для ДВК-3 с КГД (контроллер графического дисплея). И там, и там RT-11, у монохромного режима УК-НЦ и КГД организация практически идентичная (разница в длинах строк) и единственной серьёзной проблемой было написание утилиты, загружающей в сопроцессор УК-НЦ программу, перестраивающую графический буфер сопроцессора — чтобы для графики использовались все строки экрана, включая служебную зону.

    А т.к. мониторы на работе в то время были монохромными, то допустил в этой утилите ошибку в настройке цветов — и на цветном мониторе картинка была не черно-белая, а чёрно-лиловая.


    1. eandr_67
      29.08.2015 21:18

      В дополнение: судя по «ЛАТ» в правом верхнем углу, Вы перестройкой видеобуфера не заморачивались. Физически у УК-НЦ не 288, а 320 строк и при желании все их можно использовать: в ОЗУ периферийного процессора (прошу прощения, выше ошибочно назвал его сопроцессором) находится таблица, содержащая адреса и режимы видеострок.


      1. nzeemin
        29.08.2015 23:35

        Да, мне не хотелось заморачиваться перестройкой видеорежима и вообще программой под ПП, я сделал проще — включил формат экрана 80x24 через Esc-последовательность.
        В следующей версии конечно нужно работать с ПП — в частности, сделать звуковое сопровождение.


    1. nzeemin
      29.08.2015 23:46

      А что конкретно вы портировали? Остались какие-то наработки на дискетах или других носителях?
      Приходите вот сюда — zx-pk.ru/forumdisplay.php?f=66 — тут относительно много любителей отечественных PDP-11 и есть определённая движуха.


      1. eandr_67
        30.08.2015 23:05

        Из названий вспоминается только sherif. И это ведь 25 лет назад было и на работе.


  1. AndrewN
    29.08.2015 23:12

    Черт! На УКНЦ же был GOBLIN! Это нечто наподобие lode runner
    Эх, очень мне нравились эти гоблины, жать всего 15 (вроде) уровней


    1. nzeemin
      29.08.2015 23:43
      +1

      Да, было такое.
      image
      image

      Эти и другие скриншоты здесь: github.com/nzeemin/ukncbtl-doc/wiki/Games-ru


      1. AndrewN
        30.08.2015 10:39

        Да, только монитор у меня ч/б был


  1. entze
    30.08.2015 08:07

    Насколько я помню, был эмулятор для запуска игрушек с БК на УКНЦ.
    Обещали поделится со мной бесплатно, но забыли.


    1. nzeemin
      30.08.2015 13:11
      +1

      Вот тут обсуждение: bk0010.org/forum/?id=2516&page=2