Скроллинг на Commodore 64

Commodore 64 не был распространён в наших широтах, но в Северной Америке он сыграл наверное такую же роль, как ZX Spectrum в Европе. Вот только он был примерно в два раза дороже и наверное примерно в два раза лучше по усреднённому количеству возможностей своих компонент. Так, например, его видеочип (VIC-II) умел несколько разных видеорежимов, причём как текстовых так и графических, поддерживал аппаратные спрайты и в целом был гораздо более заточен под игровые применения, нежели спектрум.


Вчера я наткнулся на забавную особенность видеочипа Commodore 64 в англоязычной статье про реализацию на этом ПК плавного скроллинга: http://1amstudios.com/2014/12/07/c64–smooth–scrolling/
Дело в том, что в портах ввода–вывода видеочипа были регистры позволяющие использовать аппаратный плавный скроллинг, но общая реализация системы делала его реализацию довольно нетривиальной вещью.

В играх как правило использовался текстовый видеорежим, т.к. графический был совсем неподьёмен для плавной графики.
Фактически текстовый видеорежим является попросту тайловым, как в денди, и главным образом задаётся тремя зонами видеопамяти:
1. массив 256 изображений символов (тайлов) 8x8 (2048 байт)
2. таблица 40x25 кодов символов — содержимое квадратно–текстовой сетки текста/тайлов экрана (1000 байт)
3. таблица 40x25 цветов символов — нижние 4 бита выбирали один цвет символа из фиксированной палитры на 16 цветов (тоже, как понятно, 1000 байт)

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


(Демонстрация цветных символов с одним общим чёрным цветом фона)

В многоцветном режиме на пиксель символа выделялось два бита, при этом массив изображений описывал тайлы 4x8, которые однако вытягивались в два раза на экране таким образом всё равно формируя тайл 8x8 — изображение теряло в горизонтальном разрешении с 320 до 160 пикселей. С цветами было так же хитро — три из них задавались на глобальном уровне и только один, третий, выбирался из цветовой таблицы. В играх это был предпочтительный режим из–за цветности, но как понятно, подбирать палитру на Коммодоре было тем еще творческим занятием, т.к. варьировался по тайлам только один цвет из четырёх.

Например посмотрим на скриншот игры Turrican II:


Так сразу и не скажешь, что три цвета на этой картинке общие между всеми тайлами, хотя какая то ограниченность цветовой палитры несомненно чувствуется.
И вот возвращаемся к вопросу плавного скроллинга — в видеочипе было два 3–битных регистра задающих скроллинг всего текстового экрана по вертикали или горизонтали на от 0 до 7 пикселей.

Техника для, например, горизонтального скроллинга предполагалась следующая:

— в видеочипе включается подавление вывода двух крайних колонок текста для бесшовности
— далее 7 раз экран скроллится попиксельно только лишь записью в регистр горизонтального скроллинга
— а вот на 8–ой раз, когда он уже проворачивается через ноль таблицы символов и их цветов надо было физически сместить на 1 байт левее и дописать в освободившуюся колонку новые номера тайлов и их цветов

Казалось бы ничего сложного, но на последнем шаге и возникала мощная проблема — процессор C64 (MOS 6502) просто не успевал переписать два килобайта массивов тайлов и их цветов за относительно короткий период VBlank (когда видеочип «отдыхает» после вывода очередного кадра на электронно–лучевую трубку монитора, подробнее о чём я писал тут) и проваливаясь в период VDraw (когда видеочип собственно выдаёт построчно на монитор сигнал о картинке на экране) создавал ужасные и неприемлемые вертикальные разрывы и дёргания изображения. Тут надо заметить, что обновление картинки шло с частотой 50 или 60 герц и поэтому временное окно было действительно маленьким.

Чтобы побороть эту проблему и еще оставить пространство для обработки игровой логики, звука и манипуляций со спрайтами приходилось писать довольно изощрённый код.

Во первых — в C64 местонахождение адреса таблицы кодов символов в памяти была настраиваемой величиной, что позволяло делать двойную буферизацию — таким образом обновление этой таблицы можно было разбросать по семи остальным VBlank, чтобы разгрузить наш критический до приемлемых величин. Содержимое активного буфера тайлов кусками переписывается со смещением в теневой буфер, после чего на восьмой такт буфера переключаются. Автор статьи по ссылке разбрасывает его на два других VBlank — их становится достаточно.

Но вот с таблицей цветов такой номер не проходит — она жёстко прошита по фиксированному адресу и даже обновление только её опять не пролазит в нужный VBlank, т.к. нужно еще успевать обрабатывать звук и прочее. Тогда автор приходит к следующему решению — он еще на предыдущем кадре отлавливает момент на фазе VDraw когда видеочип уже выдал информацию о первой строке символов на монитор и начинает переписывать первую половину цветовой таблицы отставая от хода луча ЭЛТ и потому не подрывая процесс, остаток же цветовой таблицы он обновляет уже на наступающем VDraw, половина таблицы уже успешно обновляется за его время.

Таким образом размазывая все эти обновления и скроллинги по разным фазам VDraw и VBlank на Commodore 64 всё–таки становится возможным получить идеальный плавный скроллинг. Возможно автор статьи несколько перемудрил с процессом, у меня закрадывается такое подозрение, но в целом принцип крутится вокруг этого.

В качестве бонуса занимательное видео любительского «порта» игры Limbo на Commodore 64, где используется еще немало других трюков:

7 комментариев

avatar
В общем, сложняки кругом :)
  • VBI
  • +1
avatar
и только лишь на ts-conf, на zx enhanced — есть скроллы для всех графических слоёв и dma для максимальной скорости обновления!
:)
avatar
Ну да, забавная ситуация — скроллинг вроде бы и заложен в железо, но чтобы им воспользоваться надо нагородить кучу нетривиального кода.
На вики вкратце написано лишь, что задача скроллинга на C64 была «relatively complicated, CPU intensive task», так что захотелось разобраться что это означает.
Удивило еще разбазаривание четырёх бит цветовой таблицы — хотя на самом деле там всё еще сложнее, чем я описал.
avatar
> как ZX Spectrum в Европе.
Точнее, как ZX Spectrum в России. БОльшая часть софта и игр на C64 (а их немало!) написаны европейцами для европейцев, что видно из соотношения PAL (и PAL FIXED) vs NTSC. Хотя конечно по разным странам Европы всё по-разному.
P.S.Попытался нагуглить, сколько где продано C64, но не нагуглилось ничего внятного.
  • frog
  • +2
avatar
«P.S.Попытался нагуглить, сколько где продано C64, но не нагуглилось ничего внятного.»

Вот тут: en.wikipedia.org/wiki/Home_computer можно найти неконкретные, но замечания, что:
1. C64 — самая продаваемая модель компьютера в мире всех времён и народов (17 млн. по всему миру). Имеется ввиду именно конкретная модель с незначительными изменениями типа PAL/NTSC.
2. В Европе, однако, британские ПК чаще всего имели более широкое распространение, чем компьютеры из США
avatar
P.S.
И, конечно же, вопрос становится совсем непростым, если учитывать армии клонов — с его учётом картина может значительно поменяться.
avatar
Примерно так же работает горизонтальный скролл на MSX2. Вертикальный там нормальный, а горизонтальный через 'центрирование растра', которое позволяет двигать растр по экрану на 8 пикселей влево-вправо.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.