Как стать автором
Обновить

Как ID Software удалось выжать невозможное из EGA-карт

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров16K
Всего голосов 90: ↑90 и ↓0+90
Комментарии24

Комментарии 24

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

Но заметьте: всего лишь добавилось чуть больше памяти на видеокарточке, и всё, эти трюки сразу же начали обламываться и пришлось использовать некрасивый медленный вариант.
Вот примерно так оно и происходит. Именно поэтому у нас такой тормозной софт, который под 95% ресурсов железа растрачивает впустую. Потому что фрагментация.
Когда вы программируете под конкретное железо с чётко фиксированным разрешением экрана — это такой кайф…
А вот когда надо сделать так, чтобы ваша программа работала на смартфонах и планшетах всех типоразмеров, да чтобы разрешение менялось динамически прямо в процессе работы, да чтобы в качестве устройств ввода поддерживались мышь, клавиатура, геймпад и сенсорный экран, да чтобы оно работало под x86 и под arm, когда в качестве ОС могут быть Windows, Android, iOS, macOS, Linux… Вот тут нам остаётся лишь печально вздохнуть и расчехлить Electron с Unity, потому что никакого другого способа решить эту задачу за приемлемое время при вменяемых финансовых затратах просто не существует.

Поблемка в том что ленивые программисты стали применять этот подход там где он вообще не нужен: в системах с жестко заданной конфигурации. в результате сеснорный экран с двумя кнопками (вспоминаем многочисленные компьютерные игры :) ) тянет за собой малинку (они же буквально на земле валяются, в СанФранциско) и веб интерфейс, но потом малинку типа дорого - и запускают на чем нить более тормозном и вес это уже дико бесить начинает пользователя, а там хватило бы atmega для нормальной работы, а лучше просто тупо две кнопки, физическиие.

При чём проблемы могут быть самые неочевидные.
Ну вот к примеру я купил 4к 120гц телевизор. Но у меня был только HDMI 2.0.
Ну и какие проблемы, подумал я, пока не поменяю видеокарту буду играть в шутеры 100fps ycbcr 422. А в более медленные игры в 60гц в честном RGB.
Но возникла проблема, в одной из медленных игр разработчик не предусмотрел выбор частоты монитора и автоматом выбирал максимально возможную частоту 120гц ycbcr 420
Да, игрой в окне во весь экран проблема решалась(правда там была какая-то другая проблема, почему я хотел играть в фулскрине).

Во второй трилогии Keen использовался более хитрый трюк — мы просто продолжали смещаться и перерисовывать передний край, позволив экрану возвращаться назад на краю окна 64 КиБ

Хитрый, это громко сказано, ИМХО.

В любой старой консоли с тайловыми видеосистемами примерно так и рисуется - по 1 столбику за экраном. Разработчики CRTC всё предусмотрели. Никакого хитрого программирования железа нет. Тайлов тут нет, но пишем в невидимую часть экрана.

Вопрос почему ID сразу не сделали так в CK. Это же тупо проще чем ATR.

В общем халява - это не на спектруме делать плавный скролл на процессоре или полноценные игры с цветовыми атрибутами 8х2 вместо 8х8

https://youtu.be/JWW1W8fRvTw?t=480

Статейку налабал Fabien Sanglard, ему однозначно плюсик за картиночки и проч. Эх, есть же время у людей заниматься цифровой археологией! Ему-то я думаю пояснять смысла нет.

...Commander Keen (90й год) даже чисто визуально клон Mario Bros, поэтому Кармак на момент создания C.K. прекрасно знал и играл в игры на 8-битках и знал как они устроены.

Все эти трюки были давным-давно выработаны на 8-битных машинах, у которых узким местом является не ISA/EGA, а либо малая мощность процессора, либо аппаратное строение экрана (у ZX-Spectrum экран можно "раскрасить" только квадратами 8x8 "черно-белых" пикселей - это можно представлять и использовать как тайловую организацию экрана), либо же сама аппаратная организация "видеопроцессора": NES 2C02, Yamaha V9938 итд.

А там были, надо сказать, свои нюансы. У видеоконтроллера (видеопроцессор) память чаще всего не мэпилась на основное адресное пространство, а была отдельной и была доступна всего лишь через регистры. Что создавало узкое место (как ISA) поэтому обновлять приходилось экономно, в точности такими же методами.

У ZX Spectrum организация видеопамяти настолько упорота, что при изучении работы с графикой на этом девайсе я никак не мог отделаться от ощущения, что разработчики этой штуки сидели на какой-то тяжёлой синтетике. Потому что так всё устроить — это ж ещё постараться надо было.
На этом фоне необходимость учитывать тайловость 8x8 просто теряется, там при организации скроллинга вынос мозга куда серьёзнее.

У ZX Spectrum организация видеопамяти настолько упорота

...по сравнению с РС. Во времена ZX Spectrum делать подобные вещи было обычным делом. Когда у тебя попиксельно крохотный монохромный экран занимает 6К из твоего 48- или даже 16-килобайтного ОЗУ в 64-килобайтном адресном пространстве, а тебе надо добавить туда и цвет, современный вариант с "давайте просто увеличим количество бит на пиксель" вообще не канает. Потому и приходилось придумывать отдельные атрибуты на целое знакоместо и т.д.

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

Если бы систему действительно проектировали специально под вывод символов 8x8, то сделали бы как в NES: отдельная таблица из 256 тайлов 8x8, а в видеобуфер кладутся их индексы, по 1 байту на знакоместо. Такое и программировать не в пример проще (в том числе работу с графикой, а не только с текстом), и на памяти могли бы сэкономить, и работало бы быстрее, потому что для каждого квадрата 8x8 требовалось бы записать всего один байт, а не восемь.

Тогда железо будет дороже. А так там всё максимально просто и дёшево.

Согласен, простыми счетчиками, пусть и реализованными в единой сбис, для упрощения адресации сделали что следующая строка символа это инкремент старшего байта адреса, а при 32 символах следовательно это блоки из 8 символов, при полном символьном в 192 строки — 3 таких полосы.
Т.е. расчет произвольной точки — да, сложен для самостоятельного изменения, но для максимально простого совмещения знакоместо+аттрибуты сделано изумительно, с точки зрения проектирования железа.

Вход : H - Y (0-191), L - X (0-255).
Выход: HL - адрес, B - номер бита (0-7).

   CORHL   LD  A,L
           AND 7
           LD  B,A
           XOR L
           LD  L,A
           LD  A,H
           AND 7
           LD  C,A
           XOR H
           RRA
           SCF
           RRA
           RRA
           LD  H,A
           AND 7
           OR  L
           RRCA
           RRCA
           RRCA
           LD  L,A
           LD  A,H
           AND 248
           OR  C
           LD  H,A
           RET

https://zxpress.ru/article.php?id=14305

Из вашего сообщения непонятно, с какой целью вы эту простыню написали. Чтобы подтвердить, или наоборот, опровергнуть?

Код, который вычисляет адрес в линейной памяти (y * 32 + (x >> 3)), не сильно быстрее.

Код выше занимает 118 тактов

Код ниже занимает 115 тактов

LD A,L       
AND 7
LD B,A
XOR L
RRCA
RRCA
RRCA
LD L,H
LD H,#40/32 ; стартовый адрес в памяти #4000
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD A,L
LD L,A
RET

Как можно убедиться - разница несущественная. Да и в любом случае так никто не делал, а делали просто табличку адресов, если нужна была скорость.

Переход к следующей строке в правильной организации

INC H (4 такта)

В случае линейной памяти

ADD HL,DE (11 тактов, занята регистровая пара)

Так что как ни крути, в Спектруме экран сделан просто и оптимально.

не ссорьтесь — вот простое объяснение. первоначально были м/с памяти медленее, чем на зх128 и клонах, и просто при использовании ДРАМ, идёт раздельно строка и столбец. чтобы сохранить верхнюю часть адреса и уменьшить выборку символ и аттрибут с 320 до 170нс., и был такой изврат с адресами.
вот ссылка на статью на wasm.in — https://wasm.in/threads/pochemu-u-zx-spectrum-nelinejnaja-raskladka-videopamjati.34420/
кстати — там есть и аналогичный вашим асм-портянкам на z80 asm-е.

это нужно чтобы кто то брал из какой то памяти тайтлы и их вырисовывал, для этого в текстовые времена отдельные контроллеры были, по сути видеокарта. В NES еще и попиксельные спрайты сделаны и все это требует соответствующего железа, которое надо разработать. И как мы видим даже по этой статье программисты все равно хотели превзойти возможности железа софтовыми трюками.

они просто напросто переставили местами несколько линий адресов - с аппаратной точки зрения это несколько упрощало схему. задачу делать плавный скролинг 50fps всего экрана создатели этой аппаратуры вообще не ставили

В те времена ОЗУ стоило очень дорого, экономили как могли.

 У ZX Spectrum организация видеопамяти настолько упорота .

Если вы так пишете, значит не разобрались что к чему.

Как уже тут было сказано, это сделано для ускорения вывода текста.

И не только. Векторную графику рисовать тоже можно быстро.

*посмотрел на код в конце статьи и придумал как сделать ещё быстрее*

сделали бы как в NES: отдельная таблица из 256 тайлов 8x8, а в видеобуфер кладутся их индексы

У Синклера была задача сделать как можно более дешёвый и простой компьютер.

Делать игровую консоль он не собирался.

Экран в 32х24 знакоместа это 768 тайлов. Будучи сделан так, как вы хотите, Спектрум бы потерял возможность показывать полноэкранную графику и тексты со шрифтами меньшими чем 8х8.

Ок, делаем 768 тайлов + двух-байтные пары индекс-атрибут. Цвета придётся порезать до 8, ведь остаётся только 6 бит на атрибуты.

Но одних тайлов мало - нужны и аппаратные спрайты и прерывания по HSYNC.

А чтобы рисовать и спрайт и тайлы, нужна быстрая память. В старых консолях стоит дорогостоящая статическая память в качестве VRAM.

 Такое и программировать не в пример проще (в том числе работу с графикой

Хотите задачку? У вас заняты все тайлы и нужно чтобы плавно летал десяткок спрайтов поверх них, а аппаратных спрайтов нет. Удачи =)

Вот тут кстати рисуются линии в тайловом экране, но он ограниченного размера:

https://www.youtube.com/watch?v=WlMl8XKCb1Y&t=18s

@Alexey2005

У ZX Spectrum организация видеопамяти настолько упорота, что при изучении работы с графикой на этом девайсе я никак не мог отделаться от ощущения, что разработчики этой штуки сидели на какой-то тяжёлой синтетике. Потому что так всё устроить — это ж ещё постараться надо было.


В том что у ZX Spectrum такая организация экрана есть аппаратная причина, связанная с выбранными микросхемами памяти и скоростью их работы. Если интересно, дайте знать, напишу.

Насколько я помню из книги "Masters of Doom", id Software сначала предлагала Nintendo портировать Mario на PC при помощи ATR, но интереса по понятным причинам не вызвала (Nintendo нужно было свою консоль продвигать). Так и появился Commander Keen.

Отличная статья (читал на английском), но заголовок всё же не от мира всего. Если невозможно, то значит не сделать, тут же вопрос не в том что на ЦПУ в 5 МГц смогли сделать 10, тут как раз трюки в разработке - очень умелом использовании железа.

Эх, бабушка EGA! Помнится делал на ассемблере якобы скроллинг фона в текстовом режиме, заполнив экран одинаковыми символами, и сдвигал сам шрифт этого символа.

спасибо за кусочек детства )

Зарегистрируйтесь на Хабре, чтобы оставить комментарий