{ 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.