[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]
(*
Written by Yuval Melamed <melamed@star.net.il>, 25-Oct-1997.
This is a very fast implementation of digit plotting on mode 13h.
Infact, I could have made the array to include not only digits, but
the whole ASCII table. The reason I didn't do that, is none but lack
of time. I just showed you the basics, now go on and develope !
One of the great things in this implementation, is the ability to use
different colors, unlike standard bitmaps used in most games and stuff.
As I always like to do, I have optimized this to work with 386+
proccessors. I cannot believe someone still has his XT, right? :)
*)
var
X, Y : Word;
Color,
Time : Byte;
Count : Longint;
const
(* The bitmap of the digits, $FF represent pixel: *)
DigitMap : array[0..9, 1..5] of Longint =
(($FFFFFF00, $FF00FF00, $FF00FF00, $FF00FF00, $FFFFFF00), {0}
($FF000000, $FF000000, $FF000000, $FF000000, $FF000000), {1}
($FFFFFF00, $FF000000, $FFFFFF00, $0000FF00, $FFFFFF00), {2}
($FFFFFF00, $FF000000, $FFFFFF00, $FF000000, $FFFFFF00), {3}
($FF00FF00, $FF00FF00, $FFFFFF00, $FF000000, $FF000000), {4}
($FFFFFF00, $0000FF00, $FFFFFF00, $FF000000, $FFFFFF00), {5}
($FFFFFF00, $0000FF00, $FFFFFF00, $FF00FF00, $FFFFFF00), {6}
($FFFFFF00, $FF000000, $FF000000, $FF000000, $FF000000), {7}
($FFFFFF00, $FF00FF00, $FFFFFF00, $FF00FF00, $FFFFFF00), {8}
($FFFFFF00, $FF00FF00, $FFFFFF00, $FF000000, $FFFFFF00)); {9}
(* 386-optimized procedure to draw a digit on global X,Y, using the
global Color. The only parameter to this procedure is the digit
itself, in order to avoid confusions. *)
procedure PutDigit(Digit : Byte); assembler;
asm
mov ax,0A000h {the video segment}
mov es,ax
mov ax,Y {get Y}
mov di,ax {copy Y}
shl ax,6 {Y * 64}
shl di,8 {Y * 256}
add di,ax {Y * 64 + Y * 256 = Y * 320}
add di,X {Y * 320 + X = offset of (X,Y) in video segment}
lea bx,DigitMap {get offset of digit's bitmap}
mov al,20 {20 = SizeOf(Longint) * 5 = bytes in digit}
mul Digit {calculate offset of the digit's pixels}
add bx,ax {add offset to BX}
mov cl,Color
mov ch,cl
db 66h; shl cx,16
mov cl,Color
mov ch,cl {all bytes of ECX now contain the color value}
db 66h; mov ax,cx (* mov eax,ecx *)
db 66h; and ax,[bx] (* and eax,[bx] {mask digit's line} *)
dw 6626h; mov [di],ax (* mov es:[di],eax {draw digit's line} *)
db 66h; mov ax,cx (* mov eax,ecx *)
db 66h; and ax,[bx+4] (* and eax,[bx+4] *)
dw 6626h; mov [di+320],ax (* mov es:[di+320],eax {draw 2nd line} *)
db 66h; mov ax,cx (* mov eax,ecx *)
db 66h; and ax,[bx+8] (* and eax,[bx+8] *)
dw 6626h; mov [di+640],ax (* mov es:[di+640],eax {draw 3rd line} *)
db 66h; mov ax,cx (* mov eax,ecx *)
db 66h; and ax,[bx+12] (* and eax,[bx+12] *)
dw 6626h; mov [di+960],ax (* mov es:[di+960],eax {draw 4th line} *)
db 66h; mov ax,cx (* mov eax,ecx *)
db 66h; and ax,[bx+16] (* and eax,[bx+16] *)
dw 6626h; mov [di+1280],ax (* mov es:[di+1280],eax {draw 5th line} *)
end;
begin
MemW[$0040:$001A] := MemW[$0040:$001C];
asm
mov ax,13h
int 10h
end;
Randomize;
X := 0;
Y := 0;
Color := 0;
Count := 0;
Time := Mem[$0040:$006C];
while Mem[$0040:$006C] = Time do;
Time := Mem[$0040:$006C];
while Mem[$0040:$006C] = Time do begin
PutDigit(Random(10));
Inc(Count);
end;
Count := Trunc(Count * 18.217);
Color := 15;
X := (Trunc(Ln(Count) / Ln(10)) + 1) * 4;
repeat
PutDigit(Count mod 10);
Count := Count div 10;
Dec(X, 4);
until Count = 0;
Writeln;
Writeln(' Random digits per second');
Writeln(' (inside loop)');
while MemW[$0040:$001A] = MemW[$0040:$001C] do;
asm
mov ax,3h
int 10h
end;
end.
[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]