С для профессиональных программистов

       

Работа адаптеров CGA/EGA в графическом режиме


Адаптер CGA всегда располагается в видеопамяти по адресу 8000000h. Адаптер EGA имеет аналогичное расположение для тех режимов, которые совместимы с режимами CGA (более полную информацию о аппаратных средствах поддержки графики вы можете получить в руководстве "IBM Technical Reference"). В 4 графическом режиме каждый байт содержит информацию о цвете для 4 точек растра (для каждой точки растра по 2 бита). Следовательно, для работы с экраном размерностью 320 на 200 требуется 16К памяти. Так как два бита могут содержать только 4 различных значения, в 4 видеорежиме поддерживаются только 4 цвета. Значение каждого двухбитового блока определяет цвет в соответствии с таблицей, приведенной ниже:

Значение

Цвет в палитре

0

Цвет в палитре

1



1

2

3

фон

желтый

красный

зеленый

фон

голубой

пурпурный

булый

Особенность адаптера CGA заключается в том, что четные точки растра будут располагаться по адресу B8000000h, а нечетные - на 2000h (8152 - в десятичном виде) байтов выше, т.е. по адресу B8002000h. Следовательно, каждая строка точек растра требует 80 байтов (40 для четных точек растра, 40 - для нечетных). Внутри каждого байта точки располагаются слева направо, как они появляются на экране терминала. Это означает, что точка растра с номером 0 занимает 6 и 7 биты, в то время, как точка растра с номером 3 - 0 и 1 биты.

Так как каждый байт кодирует значение четырех точек растра, вы должны сохранять значение трех точек при изменении одной из них. Лучший способ сделать это - создание битовой маски со всеми битами, установленными в 1, кроме тех, которые будут изменяться. Значение битовой маски складывается по схеме "И" с действительным значением байта, а затем полученное значение складывается по схеме "ИЛИ" с новым значением. Однако ситуация несколько меняется, если вы хотите сложить по схеме "НЕ-ИЛИ" новое и старое значения. В этом случае вы просто складываете по схеме "ИЛИ" старое значение байта с 0, а затем складываете по схеме "НЕ-ИЛИ" новое двоичное представление цвета и получаете результат. Адрес требуемого байта определяется путем умножения значения координаты X на 40, а затем добавляется значение координаты Y, деленное на


4. Для того, чтобы определить, находится ли точка растра в четном или нечетном блоке памяти, используется остаток от деления значения координаты Х на 2. Если остаток равен 0, блок является четным (используется первый блок), в противном случае - блок нечетный (используется второй блок). Требуемые биты внутри байта вычисляются путем выполнения деления по модулю 4. Остаток

определяет номер двухбитового пакета, который содержит информацию о требуемых точках растра. Для установки байта режима цвета и битовой маски используются операторы побитового сдвига. Хотя манипулирование битами в функции mempoint() несколько запутано, вы, однако, без труда разберетесь в ней, если тщательно изучите что именно и как она делает.

/* Запись точки в CGA/EGA */

void mempoint(x,y,color_code)

int x,y,color_code;

union mask

char c[2];

int i;

 bit_mask;

int i,index,bit_position;

unsigned char t;

char xor; /* "НЕ-ИЛИ" цвета в случае его изменения */

char far *ptr=(char far *) 0xB8000000; /* точка в памяти CGA */

bit_mask.i=0xFF3F; /* 11111111 00111111 в двоичном коде */

if (x<0 || x>199 || y<0 || y>319) return;

xor=color_code & 128; /* проверка, устанавливался ли

режим "НЕ-ИЛИ" */ color_code=color_code & 127; /* маска старших битов */

/*  установка битовой маски и битов режима цвета

в правую позицию */

bit_position=y%4; /* вычисление нужной позиции

в байте */ color_code<<=2*(3-bit_position); /* сдвиг кода цвета

в нужную позицию */ bit_mask.i>>=2*bit_position; /* сдвиг битовой маски в

нужную позицию */

/* определение требуемого байта в памяти терминала */

index=x*40+(y%4);

if (x%2) index+=8152; /* если нечетный, используется

второй блок */

/* запись цвета */

if (!xor)   /* режим изменения цвета */

t=*(ptr+index) & bit_mask.c[0];

*(ptr+index)=t|color_code;

else

t=*(ptr+index) | (char)0;

*(ptr+index)=t & color_code;

 

Заметим, что тип указателя видеопамяти объявлен как far; это необходимо, если вы транслируете в модели маленькой (small) памяти. Вы так же должны заметить, что специальный маркер режима записи XOR, определенный в функциях ROM-BIOS, используется и в функции mempoint().


Содержание раздела