Глава 4. Основы видео
Для многих людей дисплей и есть компьютер. О программе
некоторые «гении» судят исключительно по качеству «картинки»
на экране. В этой главе мы расскажем о том, как формируется
изображение и покажем как использовать это на практике.
4.1 Адаптеры дисплеев
Большинство пользователей компьютеров семейства Спектрум
сталкиваются с таким понятием, только когда читают журналы о
IBM PC. 99% имеющий стандартных Спектрум даже не подозревают
о существовании других экранов. Всем им суждено работать со
стандартным экраном.
На текущий момент мне известны следующие типы адаптеров:
Стандартный адаптер
(Standart Graphics Adapter SGA)
Улучшенный адаптер
(Enhanced Graphics Adapter EGA)
Моноадаптер Профи
(Profi-mono Graphics Adapter PMGA)
Цветной адаптер Профи
(Profi-color Graphics Adapter PCGA)
Адаптер АТМ
(ATM-Turbo Graphisc Adapter AGA)
Все они отличаются своими характеристиками. Наилучшим из
них является EGA. Все эти адаптеры являются графическими, в
них нет такого принципиального режима как текстовой (за исключением АEGA)
В последнее время появилась информация о АТМ-ТУРБО 2,
где имеется улучшенный адаптер AEGA (ATM-Turbo 2 Enhanced
Graphics Adapter). Он имеет характеристики как у EGA+AGA, но
кроме всего этого имеет текстовой режим. К сожалению я не
имел общения с ним, поэтому утверждать точно не буду. Вот их
характеристики:
SGA
256*192 2 цвета из 8*2 для 8*8 точек.
EGA
640*350 16 цветов для каждой точки
PMGA
512*240 2 цвета на весь экран
PCGA
512*240 8 цветов+мерцание на 8 точек
512*240 16 цветов на 8 точек
AGA
640*200 8 цветов для каждой строки
320*200 16 цветов для каждой точки
Так как в настоящее время распространен SGA, поэтому мы
и будем рассматривать только его.
4.2 Видеопамять SGA
Видеопамять, или, точнее, оперативная память, используется для хранения изображения, физически расположена вместе
с остальными компонентами на плате компьютера. Логически эта
память является частью адресного пространства процессора.
Для этого зарезервирована область памяти, начиная с адреса
#4000. Область логически разделена на две части: область
черно-белого изображения и область атрибутов — цветов. Область черно-белого изображения и область атрибутов очень
сложна, поэтому мы рассмотрим ее подробно. Начинается область с #4000 до #5AFF, что дает 6144 байта. Спектрумовский
SGA экран разделен на знакоместа (тексел от TEXt ELement) —
области в виде квадратиков 8 на 8 точек. Для каждого знакоместа свои атрибуты. На экране 24 ряда по 32 символа в ряду:
всего 768 атрибутов. Каждые 8 точек хранятся в одном байте,
т. е на хранение изображения 1 знакоместа тратиться 8 байт +
1 байт знакоместа 768*8, что и дает 6144.
Вообще существует два способа изучить структуру экранной
области ZX Spectrum. Один — рассмотреть как грузиться экран
с кассеты, другой это внимательно прочить данную главу. Если
вы выбрали последнее крайне рекомендую набирать все примеры
на клавиатуре, это будет способствовать большему запоминанию
материала.
Экран начинается с адреса 16384. Попробуем закрасить
крайний левый верхний угол. Дадим ряд команд:
LD A,%11111111 LET A=255
LD (#4000),A POKE 16384,A
LD A,%00001111 LET A=15
LD (#4000),A POKE 16384,A
LD A,%10101010 LET A=170
LD (#4000),A POKE 16384,A
После этого примера вы наверно убедились, что биты в
байте соответствуют пикселям на экране.
LD (#4001),A
LD (#4002),A
….. и так далее
Вы будете изменять содержимое экрана, двигаясь по горизонтали или говоря точнее, вы будете модифицировать нулевые
линии в нулевом знакоместе нулевого ряда. Увеличивая адрес
вы перемещается вправо по экрану, находясь в том же нулевой
линии. Т. к. столбцов 32 то попробуем пропустить 32 байта и
занести туда значение: LD (#4000+#20),A
Но в результате мы получили нечто иное чем, следовало
ожидать. Изменилась нулевая линия в первом ряду. Чтобы изменить первую линию в нулевом знакоместе следует пропустить
256 байт.
Теперь вы убедились в сложности экрана. Чтобы немного
отдохнуть можете загружать картинки, пройти 72 комнату
EXOLON’а и выпить 2-3 кружечки кофе, после чего можете продолжить сие чтиво.
На первый взгляд такое расположение экранной области нелепо. Но на практике это облегчает работу (шутка) — надо
только все понять.
Итак, вернемся к экрану. Экрана также разбит на трети.
Отсчет в каждой трети начинается заново. Каждая треть начинается с адресов:
#4000
#4800
#5000
В кодах адрес как правило храниться в регистровой паре
HL. Полный адрес можно представить в виде:
┌──────H──────┐ ┌──────L──────┐
┌┴┬─┬─┬─┬─┬─┬─┬┴┬┴┬─┬─┬─┬─┬─┬─┬┴┐
│0│1│0│ │ │ │ │ │ │ │ │ │ │ │ │ │
└─┴─┴─┴┬┴┬┴┬┴─┴┬┴┬┴─┴┬┴┬┴─┴─┴─┴┬┘
└┬┘ └─┬─┘ └─┬─┘ └───┬───┘
1 2 3 4
1 Номер трети
2 Смещение внутри знакоместа
3 Номер ряда
4 Номер столбца
Чтобы сместиться вправо дадим команду INC L. Чтобы переместиться по вертикали в одном знакоместе дадим команду INC
H. Когда вы пройдете все знакоместо и выйдете за границу,
номер столбца обнулится, а номер рада увеличиться. Все
просто, пока дело не доходит до других третей.
На практике часто на экране графика используется только
на одной трети. Конечно она есть и на других третьих, но чаще
статическая, не подвижная.
Большую теоретическую информацию вы найдете в любой литературе по Спектруму, а нам пора перейти к атрибутам, предварительно пройдя уровень ZYNAPS’а
Атрибуты каждого знакоместа занимают 1 байт, причем
структура их очень проста. Байты располагаются слева направо
и сверху вниз. Адрес можно вычислить как 22588+32*Y+X.
На ассемблере это делается следующим образом:
LD D,X
LD E,Y
LD H,0
LD L,Y
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD A,E
ADD A,L
LD L,A
JR NC,$+3
LD DE,#5800
ADD HL,DE
В результате чего мы получим в регистре HL адрес байта
в памяти. У нас еще остался бордюр. На него конечно нельзя
выводить графику, но можно менять цвет. Для этого код цвета
нужно выдать в порт #00FE.
Цвета кодируются следующим образом:
0 черный
1 синий
2 красный
3 фиолетовый или малиновый
4 зеленый
5 голубой
6 желтый
7 белый
Следует вспомнить, что в «128К» имеется два экрана. В
ПЗУ нет подпрограмм, которые бы работали с новым экраном.
Структура его такая же как и старого, адреса его расположения другой (#C000, 7 страница). Для получения адреса можно
выше указанной схемой для регистра HL, с некоторым отличием.
Старший бит регистра Н будет указывать номер экрана.
Для активизации нового экрана следует активизировать 7
страницу и установить бит 3 порта #7FFD или ячейки #5B5C,
после чего можно вернуть прежнюю страницу.
Для активизации старого экрана достаточно сбросить бит
#7FFD. И напоследок главы совет: полезно изменять координаты
печать по X не с помощью команды INC L, а с помощью: LD A,L
ADD A,1 LD L,A
Это конечно несет потерю в 4 байта, но имеет некоторые
плюсы, связанные с флагами. Вообще, на практике часто применяется следующий прием: в памяти сохраняется таблица с адресами всех строк экрана и адрес можно выбирать как смещение
внутри таблицы.
4.3 Управление дисплеем
Управлять экраном дисплея, как и выполнять другие операции на компьютере, можно тремя способами:
— используя функции языка программирования
— используя служебные функции DOS или ROM-BIOS
— управляя аппаратурой напрямую через память или порты
Служебные функции для работы с изображениями доступные
через языки программирования, автоматически помещают данные
в видеопамять ROM-BIOS имеет множество очень мощных функций
выполняющих почти все операции, необходимые для генерации
вывода на экран.
Выбирая прямой вывод на экран мы должны отдавать себе
отсчет в том, что при этом мы может мешать другим системам,
например работающими с окнами. Тем не менее, многие существующие программы созданные для ZX-Spectruma, генерируют не-
посредственный вывод информации на экран, настолько многие,
что это уже стало стандартным способом вызова. Все понимают,
что это не хорошо, но все так и поступают.
Вообще прямой вывод следует применять только когда в
этом есть особая необходимость.