[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]
{
VGAXDEMO -- VGA ModeX graphics demo. Mode setup, pixel plotting.
}
{$G+}
program vgaxdemo;
uses crt;
{--------------------------------------------------------------------}
var
color_buf:byte;
{--------------------------------------------------------------------}
procedure setmode(mode:integer); assembler;
asm
mov ax,mode;
xor ah,ah;
int 10h;
end;
{--------------------------------------------------------------------}
procedure cls; assembler;
asm
mov ax,0A000h; { ES = video memory }
mov es,ax;
mov dx,03C4h; { Select all planes }
mov ax,0F02h;
out dx,ax;
xor di,di; { Set up for clear }
xor ax,ax;
mov cx,9600
rep stosw; { Clear the screen }
end;
{--------------------------------------------------------------------}
procedure setmodex;
const
xdata : array[1..10] of Word = (
$0011, $0B06, $3E07, $EA10, $8C11,
$DF12, $0014, $E715, $0416, $E317);
var
i:integer;
begin
setmode($13); { Set mode 13h 320x200x256 }
port[$03C2] := port[$03CC] or $C0;
portw[$03C4] := $0604; { Set ModeX 320x240x256 }
for i := 1 to 10 do begin
portw[$03D4] := xdata[I];
end;
cls;
end;
{--------------------------------------------------------------------}
procedure putpixel(x, y, color:integer); assembler;
asm
mov ax,0A000h; { ES = video memory }
mov es,ax;
mov cx,x; { CX = X }
mov dx,03C4h; { Set the memory plane }
mov ax,1102h;
rol ah,cl;
out dx,ax;
imul di,y,80; { DI = offset in video memory }
shr cx,2;
add di,cx;
mov ax,color; { Set the pixel }
stosb;
end;
{--------------------------------------------------------------------}
function getpixel(x, y:integer):integer; assembler;
asm
mov ax,0A000h; { ES = video memory }
mov es,ax;
mov cx,x; { CX = X }
mov dx,03CEh; { Set the memory plane }
mov al,4;
mov ah,cl;
and ah,3;
out dx,ax;
imul di,y,80; { DI = offset in video memory }
shr cx,2;
add di,cx;
mov al,es:[di]; { Read the pixel }
or al,es:[di]; { Buggy video card fix }
xor ah,ah;
end;
{--------------------------------------------------------------------}
procedure line(x1, y1, x2, y2, color:integer); assembler;
asm
push bp; { Save BP }
mov ax,0A000h; { ES = video memory }
mov es,ax;
mov ax,color; { Set up color buffer }
mov color_buf,al;
mov ax,x1; { Get parameters }
mov bx,y1;
mov cx,x2;
mov dx,y2;
mov si,cx; { Get X distance }
sub si,ax;
jge @l_skip1;
neg si; { X distance must be positive }
xchg ax,cx;
xchg bx,dx;
@l_skip1:
mov di,dx; { Get Y distance }
sub di,bx;
jge @l_skip2;
neg di;
@l_skip2:
cmp si,di; { Y-major? }
jle @l_ymajor;
sub cx,ax; { CX = distance }
sub dx,bx; { DX = Y increment }
sar dx,16;
add dx,dx;
inc dx;
xchg cx,dx; { Rotate registers }
mov bp,si; { BP = X distance }
shr si,1; { SI = error term }
sub si,di;
neg si;
imul bx,bx,80; { BX = offset in video memory }
ror ax,2;
add bl,al;
adc bh,0;
shr ax,14;
push cx; { Save CX }
mov ah,11h; { AH = plane }
mov cl,al;
rol ah,cl;
pop cx; { Restore CX }
imul cx,cx,80; { CX = Y increment }
mov al,ah; { AL = plane value }
@l_xloop:
or ah,al; { OR in plane }
cmp si,1; { Check error value }
jl @l_xstr; { ZF clear if taken }
push dx; { Save registers }
push ax;
mov dx,03C4h; { Set bit planes }
mov al,2;
out dx,ax;
pop ax; { Restore registers }
pop dx;
mov ah,color_buf; { AH = color }
mov es:[bx],ah; { Write pixels }
add bx,cx; { Next line }
sub si,bp;
xor ah,ah; { Clear buffer, set ZF }
@l_xstr:
rol al,1; { Next plane }
jnc @l_x2; { New byte? }
jz @l_x1; { Buffer empty? }
push dx; { Save DX }
mov dx,03C4h; { Set bit planes }
mov al,2;
out dx,ax;
pop dx; { Restore DX }
mov al,color_buf; { AL = color }
mov es:[bx],al; { Write pixels }
mov ax,11h; { Clear buffer }
@l_x1:
inc bx; { Next byte }
@l_x2:
add si,di;
dec dx; { Loop back }
jnl @l_xloop;
mov dx,03C4h; { Set bit planes }
mov al,2;
out dx,ax;
mov al,color_buf; { Write last pixels }
mov es:[bx],al;
jmp @l_done; { Return }
@l_ymajor:
xchg cx,dx; { Switch X2, Y2 }
mov dx,di; { DX = distance }
sub cx,bx; { CX = Y increment }
sar cx,16;
add cx,cx;
inc cx;
mov bp,si; { BP = X distance }
mov si,di; { SI = error term }
shr si,1;
sub si,bp;
neg si;
imul bx,bx,80; { BX = offset in video memory }
ror ax,2;
add bl,al;
adc bh,0;
shr ax,14;
push cx; { Save CX }
xchg cx,ax; { AH = plane value }
mov ah,11h;
rol ah,cl;
pop cx; { Restore CX }
push dx; { Save DX }
mov al,2; { Set first plane }
mov dx,03C4h;
out dx,ax;
pop dx; { Restore DX }
imul cx,cx,80; { CX = Y increment }
@l_yloop:
mov al,color_buf; { AL = color }
mov es:[bx],al; { Set the pixel }
test si,si; { Check error value }
jle @l_ystr;
rol ah,1; { Move in X direction }
adc bx,0;
push dx; { Save DX }
mov al,2; { Set new plane }
mov dx,03C4h;
out dx,ax;
pop dx; { Restore DX }
sub si,di; { Adjust error term }
@l_ystr:
add bx,cx; { Go straight }
add si,bp;
dec dx; { Loop back }
jnl @l_yloop;
@l_done:
pop bp; { Restore BP }
end;
{--------------------------------------------------------------------}
var
i:integer;
begin
setmodex;
while not keypressed do begin
for i := 1 to 200 do
putpixel(random(320), random(240), random(256));
end;
while keypressed do readkey;
cls;
while not keypressed do begin
for i := 1 to 20 do
line(random(320), random(240),
random(320), random(240), random(256));
end;
while keypressed do readkey;
cls;
setmode($03);
end.
[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]