[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]

USES dos, crt;

CONST
    v_vidseg   : WORD = $B800;  { $B000 for mono }
    v_columns  : BYTE = 80;     { Number of CRT columns }

VAR
    x : BYTE;
{
the dspat routine, as you can see.  Displays a string QUICKLY
If 'Col' (=columns, NOT color) is negative (-1) the centence will be centered.
Works also in exotic screenmodes, like 132x44, 100x44 or whatever you like.
}
procedure dspat(Str : string; Col : integer; Row,Attr : byte); assembler;
asm
  push ds          { Save Turbo's DS }
  mov es,v_vidseg  { Place VideoBuffer in es }
  xor dh,dh        { Clear DH }
  mov dl,v_columns { Bytes per row }

  lds si,Str       { DS:SI pts to Str }
  xor cx,cx        { clear CX }
  mov cl,[si]      { String len counted in CX }
  jcxz @l5         { If null, quit }
  inc si           { Point DS:SI to first char }

  mov ax,Col       { Get Column value }
  cmp ax,0
  jge @l6          { Absolute, or centered? }

  mov ax,dx
  sub ax,cx        { Substract stringlen from total }
  shr ax,1         { Centre}

 @l6:
  mov di,ax
  shl di,1         { Double for attributes }

  mov al,Row       { Get Row value }
  mul dl           { Times rows }
  shl ax,1

  add di,ax        { ES:DI pts to lst pos }
  cld              { Direction flag forward }
  mov ah,Attr      { Get Attribute }
 @l1:
  lodsb            { Get a character}
  stosw            { Write it with attribute }
  loop @l1         { Go do next }
 @l5:
  pop ds           { Restore DS and quit }
end;

procedure filltext(Dir : char; X1,Y1,X2,Y2,Col : byte); assembler;
asm
  push ds          { Save Turbo's DS }

  xor dh,dh        { Clear DH }
  mov dl,v_columns { Bytes per row (number of columns) }

  xor ah,ah
  mov es,v_vidseg  { Place VideoBuffer in ES and DS }
  mov al,[X1]
  mov di,ax
  shl di,1         { Double for attributes }
  mov al,[Y1]      { Get Row value }
  mul dl           { Times rows }
  shl ax,1
  add di,ax        { ES:DI pts to upperleft corner }

  xor ch,ch
  mov cl,[X2]
  inc cl
  sub cl,[X1]      { Number of bytes to move in CL (columns) }
  xor bh,bh
  mov bl,[Y2]
  inc bl
  sub bl,[Y1]      { Number of rows to move in BL }

  sub dl,[X2]      { Substract right site }
  dec dl
  shl dx,1         { Times two for attribs }
  xor ah,ah        { Clear AH }
  mov al,[X1]      { Left site }
  shl ax,1         { Times two for attribs }
  add dx,ax        { Calculated difference between last col - first col }

  mov al,[Dir]
  mov ah,[Col]

  cld              { Direction flag forward }
 @L1:
  push cx
  rep stosw
  pop cx
  add di,dx
  dec bl
  jnz @L1

  pop ds           { Restore DS and quit }
end;

{ Displays Veritical scrollbar }
procedure ScrollBar(BarXPos,
                    BarYPos : byte;
                    CurPos,
                    ScrLen,                     { max screen row }
                    NofItems : word;
                    ColAttr : byte);
var barpos,maxpos : word;
begin
  dspat(#30,barxpos,barypos,colattr);
  dspat(#31,barxpos,barypos+scrlen-1,colattr);
  filltext('±',barxpos,barypos+1,barxpos,barypos+scrlen-2,colattr);
  if nofitems >= 1 then begin
    maxpos := scrlen-3;
    if nofitems <> 1 then barpos := round(((curpos-1)/(nofitems-1))*maxpos)
    else barpos := 0;
    dspat('þ',barxpos,barypos+barpos+1,colattr);
  end;
end; { ScrollBar }

BEGIN  { demo coded by Gayle Davis for SWAG 8/18/94 }

   ClrScr;
   { put at col 40 of Row x, 3rd item selected }

   FOR X := 1 to 24 DO
       BEGIN
       ScrollBar(40,1,x,22,40,31);
       DELAY(300);
       END;

END.

The assembler stuff is nicely documented, so shouldn't be a problem. What's
missing here, you can define as constants at the top of your source, or try to
find out using interrupt-calls or whatever...

Btw: these routines are taken from my very private video-unit, and seem to work
on many different configurations (so far...) But that's also due to the fact
that the v_columns is found through some interrupt-calls and stuff...
The routines work also in 132x44 or whatever strange video-mode.

Another point of discussion: no snow-checking is performed. I got in some
anoying discussions about this, because (imho) CGA's are hardly used these
days. So it seems a little ... nuts ... to make support for that hand full of
CGA-users. Ah well, enclose the sc yourself. it's not hard, but it REALY slow's
stuff down. And these routines were designed with SPEED as first concern and
compatibily with MODERN hardware as a second...

 _    _
|_]  | _
|__].|__].

[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]