Системное программное обеспечение персональных ЭВМ


Пример 8



Пример 8

/*== ПРИМЕР 9.6 ==*/ /*================ Функции прерывания 0x10 ===============*/ /* функции 6, 7 - сдвиг экрана; 8, 9 - читать/писать сим- вол/атрибут, 0x0A, 0x0E - вывод символа */ #include <dos.h>

#include <stdlib.h>

#define byte unsigned char #define word unsigned int #define Esc 27 #define Up 0x48 #define Down 0x50 #define Left 0x4b #define Right 0x4d union REGS rr; struct SREGS sr; byte x1=34, y1=7; /* координаты окна (левый,верхний) */ byte x2, y2; /* координаты окна (правый,нижний) */ byte xc, yc; /* координаты курсора */ char *msg[]={"=========Вывод по функции 0x0A==========", "=========Вывод по функции 0x0E==========", "=========Вывод по функции 0x09==========", "=========Вывод по функции 0x13==========", "========Вывод по функции DOS 2==========", "========Вывод по функции DOS 6==========", "========Вывод по функции DOS 9==========$" }; word save[5]; /* для сохранения регистров */ word i; char *s; main() { xc=0; yc=0; /*== Демонстрация функций вывода ==*/ /* очистка экрана и заполн. его случайными атрибутами */ randomize(); for (i=0; i1) { for(y=y1; y=x1; xx1--,xx2--) { getca(xx1,y1,&c,&a); putca(xx2,y2,c,a); } } } /*==== Посимвольный вывод строки функцией 0A ====*/ putstring0A() { for (s=msg[0]; *s; s++) { rr.h.ah=0x0a; /* функция 0A */ rr.h.bh=0; /* страница 0 */ rr.h.al=*s; /* символ */ rr.x.cx=1; /* число повторений */ int86(0x10,&rr,&rr); /* перевычисление координат и сдвиг курсора */ if (++xc>79) { xc=0; yc++; } setcurpos(xc,yc); } } /*==== Посимвольный вывод строки функцией 0E ====*/ putstring0E() { for (s=msg[1]; *s; s++) { rr.h.ah=0x0e; /* функция 0E */ rr.h.al=*s; /* символ */ int86(0x10,&rr,&rr); } /* перевычисление координат, курсор сдвигается сам */ xc+=40; yc+=xc/80; xc=xc%80; } /*==== Посимвольный вывод строки функцией 9 ====*/ putstring09() { char a, c; getca(xc,yc,&c,&a); /* определение атрибута 1-й позиции */ for (s=msg[2]; *s; s++) { putca(xc,yc,*s,a); /* перевычисление коорд., курсор сдвигается в putca */ if (++xc>79) { xc=0; yc++; } } setcurpos(xc,yc); } /*==== Посимвольный вывод строки функцией 13 ====*/ putstring13() { char a, c; getca(xc,yc,&c,&a); /* определение атрибута 1-й позиции */ save[0]=_BP; save[1]=_DI; save[2]=_SI; save[3]=_DS; save[4]=_ES; _BP=FP_SEG(msg[3]); /* адрес строки */ _ES=FP_OFF(msg[3]); _BH=0; /* страница 0 */ _BL=a; /* атрибут */ _DH=xc; _DL=yc; /* координаты начала */ _AX=0x1300; /* функция 13, подфункция 0 */ geninterrupt(0x10); _BP=save[0]; _DI=save[1]; _SI=save[2]; _DS=save[3]; _ES=save[4]; /* перевычисление координат, курсор сдвигается сам */ xc+=40; yc+=xc/80; xc=xc%80; } /*==== Посимвольный вывод строки функцией DOS 2 ====*/ putstringdos2() { for (s=msg[4]; *s; s++) { rr.h.ah=2; /* функция 2 */ rr.h.dl=*s; /* символ */ intdos(&rr,&rr); } /* перевычисление координат, курсор сдвигается сам */ xc+=40; yc+=xc/80; xc=xc%80; } /*==== Посимвольный вывод строки функцией DOS 6 ====*/ putstringdos6() { for (s=msg[5]; *s; s++) { rr.h.ah=6; /* функция 6 */ rr.h.dl=*s; /* символ */ intdos(&rr,&rr); } /* перевычисление координат, курсор сдвигается сам */ xc+=40; yc+=xc/80; xc=xc%80; } /*==== Вывод строки функцией DOS 9 ====*/ putstringdos9() { rr.h.ah=9; /* функция 9 */ rr.x.dx=FP_OFF(msg[6]); /* адрес строки */ sr.ds=FP_SEG(msg[6]); /* символ */ intdosx(&rr,&rr,&sr); /* перевычисление координат, курсор сдвигается сам */ xc+=40; yc+=xc/80; xc=xc%80; } /*==== Установка курсора ====*/ setcurpos(byte x,byte y) { rr.h.ah=2; rr.h.bh=0; rr.h.dh=y; rr.h.dl=x; int86(0x10,&rr,&rr); }

В BIOS имеются средства, позволяющие осуществлять быстрый сдвиг изображения по вертикали: функции 6 (сдвиг окна вверх) и 7 (сдвиг вниз). В регистрах CH и CL задаются соответственно y- и x-координаты левого верхнего угла сдвигаемого окна, в DH и DL - правого нижнего угла; в AL - число строк сдвига (при AL=0 функция 6 очищает окно); а в BH - атрибут, которым заполняются освобождающиеся строки. Во второй части примера 9.6 при сдвиге вверх самая верхняя строка посимвольно копируется под самую нижнюю, а затем все окно, начиная со 2-й строки сдвигается; при сдвиге вверх - наоборот. При сдвигах вправо и влево каждая строка изображения посимвольно (функции 8 и 9) переносится на новое место. При выполнении этой программы хорошо заметно, что эти сдвиги выполняются гораздо медленнее, чем сдвиги по вертикали, лучше для этих целей использовать прямое копирование областей видеопамяти.




- Начало -  - Назад -  - Вперед -