Автор: Shacks. Дата публикации: 17.10.2004
Данный модуль предназначен для демонстрации того, как можно
в DOS записать информацию о пикселе непосредственно в видеопамять
минуя прерывания BIOS.
Прежде всего, необходимо помнить, что если перебирать последовательно
все адреса видеопамяти, то строчки будут заполняться чересстрочным
способом ( то есть сначала рисуются ВСЕ нечетные строки, а потом ВСЕ
четные).
Рассмотрим пример:
Запись пиксела напрямую в видеопамять
Данный модуль предназначен для демонстрации того, как можно
в DOS записать информацию о пикселе непосредственно в видеопамять
минуя прерывания BIOS.
Прежде всего, необходимо помнить, что если перебирать последовательно
все адреса видеопамяти, то строчки будут заполняться чересстрочным
способом ( то есть сначала рисуются ВСЕ нечетные строки, а потом ВСЕ
четные).
Рассмотрим пример:
uses crt;
const pi:real=3.1415926536;
var
t:real;
x,y,x1,UmX,UmY,Faza:integer;
procedure PutPixel (x,y:integer;Color:byte);
var
i:integer;
DecI,Temp:real;
Bit:byte;
begin
{Определение является строчка чётной или она нечётная}
if y mod 2 = 1 then
{строка нечётная}
begin
inc(y); {так как нумерация начинается с нуля, фактически происходит
сдвиг строк вверх, то есть четные становятся нечётными и наоборот}
DecI:=(80*(y/2)+(x/4))+8112; {вычисление номера БАЙТА, который отвечает
за нужный нам пиксел. Число, которое мы получим - дробное число, в
котором целая часть - это номер байта}
Temp:=frac(DecI)*8;
Bit:=6-trunc(Temp); {дробная часть числа, после некоторых преобразований
становится номером пары бит в пределах байта, которая отвечает за
пиксел. Так как в данном случае цветов 4, каждый цвет кодируется двумя
битами}
i:=trunc(DecI);
dec(y);
end;
if y mod 2 = 0 then
{строка чётная}
begin
inc(y);
DecI:=80*((y/2)-0.5)+(x/4);
Temp:=frac(DecI)*8;
Bit:=6-trunc(Temp);
i:=trunc(DecI);
dec(y);
end;
asm
mov ax, 0b800h { 0b800h-адрес в памяти, по которому находится
видеобуфер. Эот адрес одинаков для любой машины использующий
данный монитор( в данном случае используется монитор EGA). Данные
об адресах видеобуферов для других мониторов, можно найти в
интернете}
mov es, ax { адрес сегмента в регистр es}
mov di, i
mov al, byte ptr(es:di) { считываем байт, отвечающий за пиксел в регистр al}
mov cl, Bit
ror al, cl { сдвигаем содержимое регистра al таким образом, чтобы
нужная нам пара бит оказалась в начале регистра}
mov ah, Color
and al, 11111100b { обнуляем первые два бита регистра}
add al, ah { записываем в них новую информацию о цвете}
rol al, cl { возвращаем пару бит на свои места}
mov byte ptr(es:di), al { записываем изменённый байт на его место}
end;
end;
begin
UmX:=80;
UmY:=80;
asm
mov ax,4
int 10h { переход в видеорежим 320 Х 200, 4 цвета}
end;
repeat
repeat
{delay(5);}
y:=trunc(UmY*sin((2*pi*1500*t)*pi/180))+100;
x:=trunc(UmX*sin((2*pi*1000*t+Faza)*pi/180))+160;
x1:=trunc(UmX*sin((2*pi*1000*t+(Faza-1))*pi/180))+160;
PutPixel (x1,y,0);
PutPixel (x,y,1);
t:=t+0.0008;
until(t>(145*0.0008));
t:=0;
inc(Faza);
if Faza=360 then Faza:=0;
until(keypressed);
end.
Комментарии |
отсутствуют |
Добавление комментария |