
РАБОТА С ОСНОВНЫМИ ГРАФИЧЕСКИМИ УСТРОЙСТВАМИ
34
Для 16цветных режимов под каждый пиксел изображения необходимо выделить 4 бита
видеопамяти (2 = 16). Однако эти 4 бита выделяются не последовательно в одном байте, а
разнесены в 4 разных блока (цветовые плоскости) видеопамяти.
Вся видеопамять карты (обычно 256 Кбайт)
делится на 4 равные части, называемые цветовыми
плоскостями. Каждому пикселу ставится в
соответствие по одному биту в каждой плоскости,
причем все эти биты одинаково расположены
относительно ее начала. Обычно эти плоскости
представляют параллельно расположенными одна над
другой, так что каждому пикселу соответствует 4
расположенных друг под другом бита. Все эти
плоскости проектируются на один и тот же участок
адресного пространства процессора, начиная с адреса
0xA000:0. При этом все операции чтения и записи
видеопамяти опосредуются видеокартой! Поэтому, если вы записали байт по адресу 0xA000:0,
то это вовсе не означает, что посланный байт в действительности запишется хотя бы в одну из
этих плоскостей, точно так же как при операции чтения прочитанный байт не обязательно
будет совпадать с одним из 4 байтов в соответствующих плоскостях. Механизм этого
опосредования определяется логикой карты, но для программиста существует возможность
известного управления этой логикой (при работе одновременно с 8 пикселами).
Для работы с пикселом необходимо определить адрес байта в видеопамяти, содержащего
данный пиксел, и позицию пиксела внутри байта (поскольку один пиксел отображается на
один бит в каждой плоскости, то байт соответствует сразу 8 пикселам).
Поскольку' видеопамять под пикселы отводится последовательно слева направо и сверху
вниз, то одна строка соответствует 80 байтам адреса и каждым 8 последовательным пикселам,
начинающимся с позиции, кратной 8, соответствует один байт. Тем самым адрес байта
задается выражением 80*у+(x>>3), а его номер внутри байта задается выражением x&7, где (x,
y) координаты пиксела.
Для идентификации позиции пиксела внутри байта часто используется не номер бита, а
битовая маска байт, в котором отличен от нуля только бит, стоящий на позиции пиксела.
Битовая маска задается следующим выражением: 0х80>>(x&7).
На видеокарте находится набор специальных 8битовых регистров. Часть из них
доступна только для чтения, часть только для записи, а некоторые вообще недоступны
программисту. Доступ к регистрам осуществляется через порты ввода/вывода процессора.
Регистры видеокарты делятся на несколько групп. При этом каждой группе соответствует
пара последовательных портов (порт адреса порт значения). Для записи значения в регистр
видеокарты необходимо сначала записать номер регистра в первый порт (порт адреса), а затем
записать значение в следующий порт (порт значения). Для гения регистра в порт адреса
записывается номер регистра, а затем его значение читается из порта значения.
Ниже приводится файл, определяющий необходимые константы inlineфункции для
работы с портами видеокарты. Функции WriteReg и ReadReg служат для доступа к регистрам.
!// File Ega.h
#ifndef __EGA__
#define __EGA__
#include <dos.h>
#define EGA_GRAPHICS0x3CE // Graphics Controller base addr
#define EGA_SEQUENCER 0x3C4 // Sequencer base addr
#define EGA_CRTC 0x3D4