Изменение save_video() и restore_video()
Kaк только переменной vid_mem присвоен соответствующий адрес, появляется простой способ использовать ее для чтения и записи символов в видео память. Запомните, видео память требует двух байтов для каждого символа, один для символа, а другой для атрибута. Из-за того, что символьный байт первый, а атрибутный - второй, то каждой строке экрана требуется 160 байт. Для того, чтобы определить адрес отдельного символа вы должны использовать формулу:
адрес = адрес_адаптера + X*160 + Y*2
Функции save_video() и restore_video() при использовании прямого доступа к видео памяти выглядят следующим образом.
void save_video(startx,endx,starty,endy,buf_ptr)
unsigned int *buf_ptr;
void restore_video(startx,endx,starty,endy,buf_ptr)
unsigned int *buf_ptr;
Как вы видете, символы и атрибуты записываются или читаются
функции, которые читают и записывают символы преобразуются
подобным образом.
Если весь доступ к дисплею делать прямым, требуется одна новая функция (показанная здесь). Функция write_char() записывает один символ в определенную позицию экрана с определенным атрибутом.
/* запись символа с определенным аттрибутом */
int x,y;
int attrib;
Полная версия исчезающих меню с прямым доступом приведена здесь с тем же простым тестовым примером. Введите его в в свой компьютер и сравните по производительности с версией, использующей BIOS. Как вы увидете, разница потрясающая. Кажется, что меню появляются и исчезают мгновенно.
/* Программа исчезающих меню для текстового режима
с использованием прямого доступа к видео памяти */
#include "dos.h"
#include "stdlib.h"
#define ESC 27
void save_video(),restore_video();
void display_menu(),draw_border();
char far *vid_mem;
char *color[]=
"Красный",
"Желтый",
"Оранжевый",
"Зеленый"
char *apple_type[] =
"Красный деликатес",
"Джонатан",
"Белый налив",
"Антоновка"
main()
cls();
for(i=0;i<25;i++)
char far *v;
v=vid_mem;
v += (x*160) + y*2;
for(i=y; *p; i++)
*v++ =*p++; /* запись символа */
*v++ =attrib; /* запись атрибута */
/* запись символа с определенным аттрибутом */
int x,y;
int attrib;
void save_video(startx,endx,starty,endy,buf_ptr)
unsigned int *buf_ptr;
void restore_video(startx,endx,starty,endy,buf_ptr)
unsigned int *buf_ptr;
void cls()
void goto_xy(x,y)
union REGS r;
r.h.ah=2; /* функция установки курсора */
r.h.dl=y; /* координата колонки */
r.h.dh=x; /* координата строки */
r.h.bh=0; /* видео страница */
int86(0x10,&r,&r);
/* запрос текущего видео режима */
union REGS r;
r.h.ah = 15; /* получить режим */
return int86(0x10,&r,&r) & 255;
is_in(s,c)
register int i;
for(i=0; *s; i++)
if(*s++ == c) return i+1;
return 0;