Применение прерываний для работы с курсором и видеопамятью
Для вызова обработчика прерываний bios используется код прерывания 10h (см. Приложение). Код функции располагается на регистре AH. Остальные регистры содержат параметры, необходимые для выполнения функции, такие как – номера строк или столбцов для работы с экраном, атрибуты символов, количество строк, если запрашивается скроллинг, различные параметры для управления режимом отображения на мониторе, вид и размер курсора и т.п. В каждом запросе для размещения параметров используется, включая код функции, от 1 до 6 регистров. Так, например, для получения информации о текущем видеорежиме используется код функции 0Fh (на регистре AH), а результат выполнения запроса отображается следующим образом:
- код видеорежима – на регистре AL,
- число символов в строке – на регистре AH,
- номер используемой видеостраницы – на регистре BH.
Пример
Функция выключает или восстанавливает форму курсора в зависимости от параметра. Если значение параметра ON (некоторая константа), то восстанавливается ранее сохраненная форма курсора. Если форма курсора не сохранялась, то ничего не делается и выход. Если значение параметра – OFF, то курсор не отображается, а его форма сохраняется в статической переменной.
void cursor(int mode)
{
static unsigned shape; // данные о форме курсора
if(mode == ON)
{
if(shape)
{
_CX = shape;
shape = 0;
}
else
return;
}
else
{
shape = *(unsigned far *)MK_FP(0x40, 0x60);
_CX = 0x2000; // бит 6 = 0, бит 5 = 1
};
_AH = 01;
geninterrupt(0x10);
}
В реализации данной функции учитывается, что функция управления 1h позволяет установить размер курсора, его видимость и мерцание. На регистре CH указывается номер верхней ограничивающей линии курсора в пределах знакоместа (4 младших разряда), на регистре CL – номер нижней ограничивающей линии курсора в пределах знакоместа (4 младших разряда). Кроме того, на регистре CH 5-й и 6-й разряды могут влиять на отображение курсора следующим образом: 00 – нормальное мерцание, 01 – не видимый курсор, 10 – повышенная скорость мерцания, 11 – неравномерное мерцание.
В определении функции используется дальний тип указателя far. Он задает полный физический адрес и занимает 4 байта (а точнее - 20 разрядов). Его создание выполняется на основе применения макрокоманды MK_FP:
void far * MK_FP(unsigned seg, unsigned ofs),
где seg – сегментная часть адреса и ofs – смещение в пределах сегмента.
Если регистр _DS перезагружать соответствующим образом, то для доступа к данным через указатели, можно применять указатели типа near.
Пример
Функция перемещает курсор в требуемую позицию на экране с указанием номера видеостраницы:
void goto_xy(unsigned stroke, unsigned stolb, unsigned page)
{
_DH = stroke;
_DL = stolb;
_BH = page;
_AX = 0x0200;
geninterrupt(0x10);
}
Соответствующая данной функции загрузка регистров – очевидна. Координаты курсора можно, также указать непосредственно в ячейках в области данных bios – 40:50h и 40:52h. Но на экране курсор займет указанное положение только после выполнения какого-либо запроса к bios, связанного с воздействием на видеопамять.
Уровень bios довольно медленный при работе с видеопамятью, т.к. для вывода строк символов необходимы отдельные запросы для каждого выводимого символа.
Пример
Функция hor_prn() выполняет вывод строки на экран дисплея по горизонтали.
#include <dos.h>
…………………………………..
int hor_prn(int stroke, int stolb, char *str, char attr)// 4-й параметр – атрибуты символов
{
register char cur_page;
union REGS r;
// определение активной видеостраницы из ячейки 40:62h области данных bios
cur_page = *(char *)MK_FP(0x40, 0x62);
// контроль корректности параметров
if(goto_xy(stroke, stolb, cur_page) == BAD_PARAM)
return BAD_PARAM;
while(*str)
{
// посимвольный вывод, включая атрибуты символов
r.h.bh = cur_page; r.h.bl = attr; r.x.cx = 1;
r.h.ah = 0x09; r.h.al = *str++;
int86(0x10, &r, &r);
stolb++; // переход к следующей позиции символа
// снова контроль – нет ли выхода за пределы экрана
if(goto_xy(stroke, stolb, cur_page) == BAD_PARAM)
return END_OF_SCREEN;
}
return OK;
}
Распределение регистров для выполнения функции 0x09 – очевидно. Реализация функции goto_xy() совпадает с представленной выше реализацией, дополненной контролем выхода за пределы экрана. Информация об используемом режиме видеосистемы, длине строки и количестве строк хранится в соответствующих ячейках области данных bios.
Дата добавления: 2016-05-26; просмотров: 1604;