home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / turbopas / pstui100.zip / PTUIVCRT.PAS < prev    next >
Pascal/Delphi Source File  |  1993-03-12  |  27KB  |  1,091 lines

  1. {
  2.  
  3.                                                       ╔══════════════════╗
  4.                                                       ║  PTUI Virual     ║
  5.                                                       ║  Screen Driver   ║
  6.                                                       ║    Rev. 1.00     ║
  7.                                                       ╚══════════════════╝
  8.  
  9. }
  10.  
  11. {$F-} {$O-} {$A+} {$G-}
  12. {$V-} {$B-} {$X-} {$N+} {$E+}
  13.  
  14. {$I FINAL.PAS}
  15.  
  16. {$IFDEF FINAL}
  17.   {$I-} {$R-}
  18.   {$D-} {$L-} {$S-}
  19. {$ENDIF}
  20.  
  21. Unit PTUIVCRT;
  22.  
  23. Interface
  24.  
  25. Uses CRT,Strings;
  26.  
  27. Const
  28.   LMem_CRTPortBase = $463;
  29.   LMem_BufferLength= $44c;
  30.   LMem_NumberOfRows= $484;
  31.   LMem_NumberOfCols= $44a;
  32.   LMem_CurrentMode = $449;
  33.   LMem_BIOSFlags   = $489;
  34.  
  35.   MonoCard         =    1;
  36.   ColorCard        =    2;
  37.   Blink            =  128;
  38.   Black            =    0;
  39.   Blue             =    1;
  40.   Green            =    2;
  41.   Cyan             =    3;
  42.   Red              =    4;
  43.   Magenta          =    5;
  44.   Brown            =    6;
  45.   LightGray        =    7;
  46.   LightGrey        =    7;
  47.   DarkGray         =    8;
  48.   DarkGrey         =    8;
  49.   LightBlue        =    9;
  50.   LightGreen       =   10;
  51.   LightCyan        =   11;
  52.   LightRed         =   12;
  53.   LightMagenta     =   13;
  54.   Yellow           =   14;
  55.   White            =   15;
  56.  
  57. Type
  58.   MonoOrColor      = MonoCard..ColorCard;
  59.  
  60.   VideoScrollTypes = (ScrollAutoDetect, ScrollMethod1, ScrollMethod2,
  61.                       ScrollMethod3);
  62.  
  63.   VideoCardTypes   = (MDA,CGA,EGA,VGA,SVGA,BWVGA,HerculesInColor);
  64.  
  65.   VideoStateType   = Record
  66.                        FunctionalityInfo :Pointer;
  67.                        VideoMode         :Byte;
  68.                        Columns           :Word;
  69.                        RegenBufferLength :Word;
  70.                        RegenBufferAddr   :Word;
  71.                        CursorPos         :Array[1..8,1..2] of Byte;
  72.                        CursorType        :Word;
  73.                        ActivePage        :Byte;
  74.                        CRTControllerAddr :Word;
  75.                        Register3x8       :Byte;
  76.                        Register3x9       :Byte;
  77.                        Rows              :Byte;
  78.                        CharacterHeight   :Word;
  79.                        DisplayCode       :Byte;
  80.                        DisplayCodeAlt    :Byte;
  81.                        ColoursSupport    :Word;
  82.                        TotalDisplayPages :Byte;
  83.                        TotalScanLines    :Byte;
  84.                        PrimaryCharBlock  :Byte;
  85.                        SecondaryCharBlock:Byte;
  86.                        StateInformation  :Byte;
  87.                        Reserved1         :Array[1..3] of Byte;
  88.                        VideoMemory       :Byte;
  89.                        SavePointerState  :Byte;
  90.                        Reserved2         :Array[1..14] Of Byte;
  91.                      End;
  92.  
  93.   OneVideoCard     = Record
  94.                        XSize           :Word;
  95.                        YSize           :Word;
  96.                        SX1,SY1,                   {Screen}
  97.                        SX2,SY2         :Word;
  98.                        WX1,WY1,
  99.                        WX2,WY2         :Word;     {Window View Port}
  100.                        Address         :Word;     {Screen Segment to Display}
  101.                        CardType        :VideoCardTypes;
  102.                        CharacterHeight :Byte;
  103.                        CharacterLength :Byte;
  104.                        ScrollMethod    :VideoScrollTypes;
  105.                      End;
  106.  
  107. Var
  108.   VideoCard             :Array [MonoCard..ColorCard] of OneVideoCard;
  109.   Card                  :MonoOrColor;
  110.   TextAttr              :Byte;               {Background, Forground}
  111.   LastMode              :Byte;
  112.   Cursor                :Boolean;
  113.   VX                    :Word;
  114.   VY                    :Word;
  115.  
  116. Function  VideoWriteAddress(X1,Y1:Word):Pointer;
  117. Procedure InitVideoCards;
  118. Procedure SetVirtualScreen (XSize,YSize:Word);
  119. Procedure ScreenOrigin     (X,Y:Word);
  120.  
  121. Procedure PositionCursor;
  122. Procedure GotoXY           (X,Y:Word);
  123. Function  WhereX           :Word;
  124. Function  WhereY           :Word;
  125. Procedure ClrScr;
  126. Procedure ClrEOL;
  127. Procedure DelLine;
  128. Procedure InsLine;
  129. Procedure TextMode         (AL:Byte;BX,CX,DX:Word);
  130. Procedure TextColor        (Forg:Byte);
  131. Procedure TextBackground   (Backg:Byte);
  132. Procedure VideoColor       (Forg,Backg:Byte);
  133. Procedure HighVideo;
  134. Procedure LowVideo;
  135. Function  BackgroundColor  :Byte;
  136. Function  ForgroundColor   :Byte;
  137. Procedure Window           (X1,Y1,X2,Y2:Word);
  138. Procedure WriteChr         (Charac:Char);
  139. Procedure WriteStr         (Line:String);
  140. Procedure WriteStrLn       (Line:String);
  141. Procedure ReadStr          (X,Y:Word;MaxLets:Byte;Upper:Boolean;
  142.                             Var MainStr:String);
  143. Procedure EditStr          (X,Y:Word;MaxLets:Byte;Upper:Boolean;
  144.                             Var MainStr:String);
  145. Procedure Pad              (Count:Word;WithChar:Char);
  146. Procedure Barometer        (X,Y:Word;MaxLen:Byte;WithMe:Char;
  147.                             Current,EndPoint:LongInt);
  148. Procedure FillBlock        (X1,Y1,X2,Y2:Word;WithChar:Char);
  149. Function  TextImageSize    (X1,Y1,X2,Y2:Word):LongInt;
  150. Procedure GetTextImage     (X1,Y1,X2,Y2:Word;Data:Pointer);
  151. Procedure PutTextImage     (X1,Y1:Word;Data:Pointer);
  152. Procedure WindowToVScreen  (Var X1,Y1:Integer);
  153. Procedure WindowToVScreen4 (Var X1,Y1,X2,Y2:Integer);
  154. Procedure ScreenToVScreen  (Var X1,Y1:Integer);
  155. Procedure ScreenToVScreen4 (Var X1,Y1,X2,Y2:Integer);
  156.  
  157. Implementation
  158.  
  159. Function VideoWriteAddress(X1,Y1:Word):Pointer;
  160. Begin
  161.   Inc(X1,VideoCard[Card].WX1 - 1);
  162.   Inc(Y1,VideoCard[Card].WY1 - 1);
  163.   VideoWriteAddress:=Ptr(VideoCard[Card].Address,
  164.                          (((Y1-1)*VideoCard[Card].XSize*2)+((X1-1)*2)));
  165. End;
  166.  
  167. Procedure InitVideoCards;
  168. Begin
  169.   VideoCard[MonoCard].XSize    :=80;
  170.   VideoCard[MonoCard].YSize    :=25;
  171.   VideoCard[MonoCard].SX1      :=1;
  172.   VideoCard[MonoCard].SY1      :=1;
  173.   VideoCard[MonoCard].SX2      :=80;
  174.   VideoCard[MonoCard].SY2      :=25;
  175.   VideoCard[MonoCard].WX1      :=1;
  176.   VideoCard[MonoCard].WY1      :=1;
  177.   VideoCard[MonoCard].WX2      :=80;
  178.   VideoCard[MonoCard].WY2      :=25;
  179.   VideoCard[MonoCard].Address  :=$B000;
  180.   VideoCard[MonoCard].CardType :=MDA;
  181.   VideoCard[MonoCard].CharacterHeight:=16;
  182.   VideoCard[MonoCard].CharacterLength:=8;
  183.   VideoCard[MonoCard].ScrollMethod   :=ScrollAutoDetect;
  184.  
  185.   VideoCard[ColorCard].XSize    :=80;
  186.   VideoCard[ColorCard].YSize    :=25;
  187.   VideoCard[ColorCard].SX1      :=1;
  188.   VideoCard[ColorCard].SY1      :=1;
  189.   VideoCard[ColorCard].SX2      :=80;
  190.   VideoCard[ColorCard].SY2      :=25;
  191.   VideoCard[ColorCard].WX1      :=1;
  192.   VideoCard[ColorCard].WY1      :=1;
  193.   VideoCard[ColorCard].WX2      :=80;
  194.   VideoCard[ColorCard].WY2      :=25;
  195.   VideoCard[ColorCard].Address  :=$B800;
  196.   VideoCard[ColorCard].CardType :=CGA;
  197.   VideoCard[ColorCard].CharacterHeight:=16;
  198.   VideoCard[ColorCard].CharacterLength:=9;
  199.   VideoCard[ColorCard].ScrollMethod   :=ScrollAutoDetect;
  200.  
  201.   If MemW[$0:$0463] = $3B4 then
  202.     Card := MonoCard
  203.   Else
  204.     Card := ColorCard;
  205. End;
  206.  
  207. Procedure SetVirtualScreen(XSize,YSize:Word);
  208. Begin
  209.   VideoCard[ColorCard].XSize    :=XSize;
  210.   VideoCard[ColorCard].YSize    :=YSize;
  211.   VideoCard[ColorCard].SX1      :=1;
  212.   VideoCard[ColorCard].SY1      :=1;
  213.   VideoCard[ColorCard].WX1      :=1;
  214.   VideoCard[ColorCard].WY1      :=1;
  215.   VideoCard[ColorCard].WX2      :=XSize;
  216.   VideoCard[ColorCard].WY2      :=YSize;
  217.  
  218.   Asm
  219.     xor   ax, ax
  220.     mov   es, ax
  221.     mov   ax, XSize
  222.     mov   es:[LMem_NumberOfCols], ax
  223.     mov   cx, ax
  224.     mov   bx, YSize
  225.     dec   bx
  226.     mov   es:[LMem_NumberOfRows], bl
  227.     inc   bx
  228.     mul   bl
  229.     shl   ax, 1
  230.     mov   es:[LMem_BufferLength], ax
  231.  
  232.     shr   cx, 1
  233.     mov   ah, cl
  234.     mov   al, 13h
  235.     mov   dx, es:[LMem_CRTPortBase]
  236.     out   dx, ax
  237.   End;
  238. End;
  239.  
  240. Procedure ScreenOrigin(X,Y:Word);
  241.  
  242. Var
  243.   SX,
  244.   SY,
  245.   BytesPerRow     :Word;
  246.   CharacterHeight :Byte;
  247.   CharacterLength :Byte;
  248.   ScrollMethod    :VideoScrollTypes;
  249.  
  250. Label
  251.   UseAutoDetect,
  252.   Method1,
  253.   Method2,
  254.   Method3,
  255.   Continue;
  256.  
  257. Begin
  258.   BytesPerRow        :=VideoCard[Card].XSize * 2;
  259.   CharacterHeight    :=VideoCard[Card].CharacterHeight;
  260.   CharacterLength    :=VideoCard[Card].CharacterLength;
  261.   ScrollMethod       :=VideoCard[Card].ScrollMethod;
  262.  
  263.   SX                 :=VideoCard[Card].SX2 - VideoCard[Card].SX1;
  264.   SY                 :=VideoCard[Card].SY2 - VideoCard[Card].SY1;
  265.   VideoCard[Card].SX1:=(X Div CharacterLength) + 1;
  266.   VideoCard[Card].SY1:=(Y Div CharacterHeight) + 1;
  267.   VideoCard[Card].SX2:=VideoCard[Card].SX1 + SX;
  268.   VideoCard[Card].SY2:=VideoCard[Card].SY1 + SY;
  269.  
  270.  
  271.   Asm
  272.     xor    ax, ax
  273.     mov    es, ax
  274.  
  275.     mov    ax, X
  276.     mov    bx, Y
  277.  
  278.     xor    ch, ch
  279.     mov    cl, CharacterLength
  280.     div    cl
  281.  
  282.     mov    dl, ScrollMethod
  283.     cmp    dl, ScrollAutoDetect
  284.     je     UseAutoDetect
  285.     cmp    dl, ScrollMethod1
  286.     je     Method1
  287.     cmp    dl, ScrollMethod2
  288.     je     Method2
  289.     cmp    dl, ScrollMethod3
  290.     je     Method3
  291.  
  292.                                 {AL = X / CharacterLength}
  293.                                 {AH = Remainder}
  294.                                 {BX = Y}
  295.  
  296. UseAutoDetect:
  297.  
  298.     mov    cl, es:[LMem_CurrentMode]
  299.     cmp    cl, 7
  300.  
  301.     je     Method2
  302.     ja     Method1
  303.     test   byte ptr es:[LMem_BIOSFlags], 1
  304.     jnz    Method2
  305.     jz     Method3
  306.  
  307. Method1:
  308.  
  309.     mov    cl, ah
  310.     xor    ah, ah
  311.     xchg   ax, bx             {BL = X / CharacterLength}
  312.     mul    BytesPerRow        {AX = Y * BytesPerRow}
  313.     jmp    Continue           {CL = Remainder of X / CharacterLength}
  314.  
  315. Method2:
  316.  
  317.     dec    ah
  318.     jns    Method3
  319.     mov    ah, 8
  320.  
  321. Method3:
  322.  
  323.     mov    cl, ah             {CL = Remainder of X / CharacterLength}
  324.     xor    ah, ah
  325.     xchg   ax, bx
  326.     div    CharacterHeight    {BL = Y / CharacterLength}
  327.                               {AL = Y / CharacterHeight, AH = Remainder}
  328.     xchg   ah, ch             {AH = 0, CH = Remainder}
  329.     mul    BytesPerRow        {AX = (Y / CharacterHeight) * BytesPerRow / 2}
  330.     shr    ax, 1
  331.  
  332. Continue:
  333.  
  334.     add    bx, ax
  335.     mov    dx, es:[LMem_CRTPortBase]
  336.     add    dl, 6
  337.  
  338. @@1:
  339.     in     al, dx
  340.     test   al, 8
  341.     jz     @@1
  342.  
  343. @@2:
  344.     in     al, dx
  345.     test   al, 8
  346.     jnz    @@2
  347.  
  348.     cli
  349.     sub    dl, 6
  350.  
  351.     mov    ah, bh
  352.     mov    al, 0ch
  353.     out    dx, ax
  354.  
  355.     mov    ah, bl
  356.     inc    al
  357.     out    dx, ax
  358.  
  359.     sti
  360.  
  361.     add    dl, 6
  362.  
  363. @@3:
  364.     in     al, dx
  365.     test   al, 8
  366.     jz     @@3
  367.  
  368.     cli
  369.  
  370.     sub    dl, 6
  371.     mov    ah, ch
  372.     mov    al, 8
  373.     out    dx, ax
  374.  
  375.     mov    dl, 0c0h
  376.     mov    al, 13h or 20h
  377.     out    dx, al
  378.  
  379.     mov    al, cl
  380.     out    dx, al
  381.  
  382.     sti
  383.   End;
  384. End;
  385.  
  386. Procedure PositionCursor;
  387.  
  388. Var
  389.   X,Y   :Word;
  390.  
  391. Begin
  392.   X:=VX + (VideoCard[Card].WX1 - 1) - 1;
  393.   Y:=VY + (VideoCard[Card].WY1 - 1) - 1;
  394.   Asm
  395.     mov   ah, 2
  396.     mov   bx, X
  397.     mov   cx, Y
  398.     mov   dl, bl
  399.     mov   dh, cl
  400.     xor   bh, bh
  401.     int   10h
  402.   End;
  403. End;
  404.  
  405. Procedure GotoXY(X,Y:Word);
  406. Begin
  407.   VX:=X;
  408.   VY:=Y;
  409.   If Cursor Then PositionCursor;
  410. End;
  411.  
  412. Function WhereX:Word;
  413. Begin
  414.   WhereX:=VX;
  415. End;
  416.  
  417. Function WhereY:Word;
  418. Begin
  419.   WhereY:=VY;
  420. End;
  421.  
  422. Procedure ClrScr;
  423.  
  424. Var
  425.   Total,
  426.   Temp   :Word;
  427.  
  428. Begin
  429.   Temp :=VideoCard[Card].Address;
  430.   Total:=VideoCard[Card].YSize*VideoCard[Card].XSize;
  431.   Asm
  432.     cld
  433.     mov    ax, Temp
  434.     mov    es, ax
  435.     xor    di, di
  436.     mov    ah, TextAttr
  437.     mov    cx, Total
  438.     mov    al, 32
  439.     rep    stosw
  440.   End;
  441.   VX:=1;
  442.   VY:=1;
  443.   If Cursor Then PositionCursor;
  444. End;
  445.  
  446. Procedure ClrEOL;
  447.  
  448. Var
  449.   Q          :Pointer;
  450.   TotalChars :Integer;
  451.  
  452. Begin
  453.   TotalChars:=VideoCard[Card].XSize - VX + VideoCard[Card].WX1;
  454.   Q:=VideoWriteAddress(VX,VY);
  455.   Asm
  456.     cld
  457.     les   di, Q
  458.     mov   cx, TotalChars
  459.     mov   ah, TextAttr
  460.     mov   al, 32
  461.     rep   stosw
  462.   End;
  463. End;
  464.  
  465. Procedure DelLine;
  466.  
  467. Var
  468.   LineSize:Word;
  469.   Total   :Word;
  470.   Q       :Pointer;
  471.  
  472. Begin
  473.   LineSize:=VideoCard[Card].XSize;
  474.   Total   :=(VideoCard[Card].YSize - VY)*VideoCard[Card].XSize;
  475.   Q       :=VideoWriteAddress(1,VY);
  476.  
  477.   Asm
  478.     cld
  479.     mov    bx, LineSize
  480.     shl    bx, 1
  481.     mov    cx, Total
  482.     les    di,Q
  483.     mov    si, di
  484.     add    si, bx
  485.  
  486.     push   ds
  487.     mov    ax, es
  488.     mov    ds, ax
  489.     rep    movsw
  490.     pop    ds
  491.   End;
  492.   FillBlock(1,VideoCard[Card].YSize,VideoCard[Card].XSize,VideoCard[Card].YSize,' ');
  493. End;
  494.  
  495. Procedure InsLine;
  496.  
  497. Var
  498.   LineSize:Word;
  499.   Total   :Word;
  500.   Q       :Pointer;
  501.  
  502. Begin
  503.   LineSize:=VideoCard[Card].XSize;
  504.   Total   :=(VideoCard[Card].YSize - VY)*VideoCard[Card].XSize;
  505.   Q       :=VideoWriteAddress(VideoCard[Card].XSize,VideoCard[Card].YSize);
  506.  
  507.   Asm
  508.     std
  509.     mov    bx, LineSize
  510.     shl    bx, 1
  511.     mov    cx, Total
  512.     les    di,Q
  513.     mov    si, di
  514.     sub    si, bx
  515.  
  516.     push   ds
  517.     mov    ax, es
  518.     mov    ds, ax
  519.     rep    movsw
  520.     pop    ds
  521.   End;
  522.   FillBlock(1,VY,VideoCard[Card].XSize,VY,' ');
  523. End;
  524.  
  525. Procedure TextMode(AL:Byte;BX,CX,DX:Word);
  526.  
  527. Var
  528.   NewModeInfo   :VideoStateType;
  529.   P             :Pointer;
  530.  
  531. Begin
  532.   Asm
  533.     xor   ah, ah
  534.     mov   al, &AL
  535.     mov   bx, &BX
  536.     mov   cx, &CX
  537.     mov   dx, &DX
  538.     int   10h                   {Set Video Mode}
  539.   End;
  540.  
  541.   FillChar(NewModeInfo,SizeOf(NewModeInfo),0);
  542.   P:=Addr(NewModeInfo);
  543.   If VideoCard[Card].CardType=SVGA Then
  544.   Begin
  545.     Asm
  546.       les   di, P
  547.       mov   ax, 1B00h
  548.       xor   bx, bx
  549.       int   10h                   {Get Video Mode Information}
  550.     End;
  551.  
  552.     VideoCard[Card].XSize    :=NewModeInfo.Columns;
  553.     VideoCard[Card].YSize    :=NewModeInfo.Rows;
  554.     VideoCard[Card].SX1      :=1;
  555.     VideoCard[Card].SY1      :=1;
  556.     VideoCard[Card].SX2      :=NewModeInfo.Columns;
  557.     VideoCard[Card].SY2      :=NewModeInfo.Rows;
  558.     VideoCard[Card].WX1      :=1;
  559.     VideoCard[Card].WY1      :=1;
  560.     VideoCard[Card].WX2      :=NewModeInfo.Columns;
  561.     VideoCard[Card].WY2      :=NewModeInfo.Rows;
  562.     VideoCard[Card].Address  :=$B800;
  563.     VideoCard[Card].CharacterHeight:=NewModeInfo.CharacterHeight;
  564.     If NewModeInfo.Columns>=80 Then
  565.       VideoCard[Card].CharacterLength:=8
  566.     Else
  567.       VideoCard[Card].CharacterLength:=9;
  568.     VideoCard[Card].ScrollMethod   :=ScrollAutoDetect;
  569.   End;
  570.  
  571.   VX:=1;
  572.   VY:=1;
  573. End;
  574.  
  575. Procedure TextColor(Forg:Byte);
  576. Begin
  577.   Forg:=Forg And $8F;
  578.   TextAttr:=TextAttr And $F0;
  579.   TextAttr:=TextAttr Or Forg;
  580. End;
  581.  
  582. Procedure TextBackground(Backg:Byte);
  583. Begin
  584.   Backg:=Backg shl 4;
  585.   TextAttr:=TextAttr And $0F;
  586.   TextAttr:=TextAttr Or Backg;
  587. End;
  588.  
  589. Procedure VideoColor(Forg,Backg:Byte);
  590. Begin
  591.   TextAttr:=Forg And $8F;
  592.   Backg:=Backg shl 4;
  593.   TextAttr:=TextAttr Or Backg;
  594. End;
  595.  
  596. Procedure HighVideo;
  597. Begin
  598.   If (TextAttr And $0F)<8 Then Inc(TextAttr,8);
  599. End;
  600.  
  601. Procedure LowVideo;
  602. Begin
  603.   If (TextAttr And $0F)>7 Then Dec(TextAttr,8);
  604. End;
  605.  
  606. Function ForgroundColor:Byte;
  607. Begin
  608.   ForgroundColor:=TextAttr And $8F;
  609. End;
  610.  
  611. Function BackgroundColor:Byte;
  612. Begin
  613.   BackgroundColor:=TextAttr And $70;
  614. End;
  615.  
  616. Procedure Window(X1,Y1,X2,Y2:Word);
  617. Begin
  618.   VideoCard[Card].WX1:=X1;
  619.   VideoCard[Card].WY1:=Y1;
  620.   VideoCard[Card].WX2:=X2;
  621.   VideoCard[Card].WY2:=Y2;
  622.   VX:=1;
  623.   VY:=1;
  624.   If Cursor Then PositionCursor;
  625. End;
  626.  
  627. Procedure WriteChr(Charac:Char);
  628.  
  629. Var
  630.   Q     :Pointer;
  631.  
  632. Begin
  633.   Q:=VideoWriteAddress(VX,VY);
  634.   Asm
  635.     cld
  636.     les   di, Q
  637.     mov   ah, TextAttr
  638.     mov   al, Charac
  639.     stosw
  640.     inc   VX
  641.   End;
  642.  
  643.   If VX>VideoCard[Card].XSize Then
  644.   Begin
  645.     Inc(VY,VX Div VideoCard[Card].XSize);
  646.     VX:=VX Mod VideoCard[Card].XSize;
  647.   End;
  648.   If Cursor Then PositionCursor;
  649. End;
  650.  
  651. Procedure WriteStr(Line:String);
  652.  
  653. Var
  654.   X     :Word;
  655.   Q     :Pointer;
  656.  
  657. Label
  658.   EndLoop,
  659.   CopyLoop;
  660.  
  661. Begin
  662.   Q:=VideoWriteAddress(VX,VY);
  663.   Asm
  664.     cld
  665.     push  ds
  666.     les   di, Q
  667.     mov   ah, TextAttr
  668.  
  669.     lea   si, Line
  670.     mov   cx, ss
  671.     mov   ds, cx
  672.     lodsb
  673.     mov   cl, al
  674.     xor   ch, ch
  675.     mov   dx, cx
  676.     jcxz  EndLoop
  677.  
  678. CopyLoop:
  679.  
  680.     lodsb
  681.     stosw
  682.  
  683.     loop  CopyLoop
  684.  
  685. EndLoop:
  686.  
  687.     pop   ds
  688.  
  689.     add   VX, dx
  690.   End;
  691.  
  692.   If VX>VideoCard[Card].XSize Then
  693.   Begin
  694.     Inc(VY,VX Div VideoCard[Card].XSize);
  695.     VX:=VX Mod VideoCard[Card].XSize;
  696.   End;
  697.   If Cursor Then PositionCursor;
  698. End;
  699.  
  700. Procedure WriteStrLn(Line:String);
  701. Begin
  702.   WriteStr(Line);
  703.   Inc(VY);
  704.   If VY>VideoCard[Card].YSize Then
  705.   Begin
  706.     VX:=1;
  707.     VY:=1;
  708.     DelLine;
  709.     VY:=VideoCard[Card].YSize;
  710.   End;
  711.   VX:=1;
  712.   If Cursor Then PositionCursor;
  713. End;
  714.  
  715. Procedure ReadStr(X,Y:Word;MaxLets:Byte;Upper:Boolean;Var MainStr:String);
  716. Begin
  717.   MainStr:='';
  718.   EditStr(X,Y,MaxLets,Upper,MainStr);
  719. End;
  720.  
  721. Procedure EditStr(X,Y:Word;MaxLets:Byte;Upper:Boolean;Var MainStr:String);
  722.  
  723. {Procedure Edits a string allowing for cursor keys and backspace keys.}
  724. {It reads the string at X,Y and will only allow MaxLets number of letters}
  725. {to be entered.  It puts the letters into MainStr.  Optionally UpperCase Only.}
  726.  
  727. Var
  728.   Ins             :Boolean;   {Boolean for the Insert Key Status}
  729.   C               :Char;      {Current Character}
  730.   Count,                      {Number Of Chars In String}
  731.   CurXPos         :Byte;      {Current X Position of Cursor}
  732.   CursorSizeSave  :Word;
  733.   OldCur          :XYPosData; {Old Cursor Position}
  734.   OldCurVal       :Boolean;
  735.  
  736. Begin
  737.   OldCurVal:=Cursor;
  738.   Cursor:=True;
  739.   SaveCursorSize(CursorSizeSave);
  740.   CursorSize(1,VideoCard[Card].CharacterHeight);    {Set the cursor size to a block}
  741.   Ins:=False;                {The Insert key has not yet been pressed}
  742.   CurXPos:=1;                {Current Relative X Position+1}
  743.   SaveXYPos(OldCur);         {Save the Cursor Position}
  744.   GotoXY(X,Y);
  745.   UnPadVar(MainStr,MainStr);
  746.   If Length(MainStr)>MaxLets Then
  747.     MainStr:=Copy(MainStr,1,MaxLets);
  748.   WriteStr(MainStr);
  749.   Pad(MaxLets-Length(MainStr),' ');
  750.   Count:=Length(MainStr)+1;  {How many letters in the string+1}
  751.  
  752.   Repeat                     {Repeat Until [Return] is Pressed}
  753.     GotoXY(X+CurXPos-1,Y);   {Goto the Requested Area}
  754.     If Upper Then
  755.       C:=UpCase(ReadKey)
  756.     Else
  757.       C:=ReadKey;
  758.  
  759.     If C=Chr(0) Then         {Check for a cursor key}
  760.     Begin
  761.       C:=ReadKey;            {Which cursor key}         {Numeric Keypad Value}
  762.       If (C='O') Then CurXPos:=Count;                            {1}
  763.       If (C='P') And (CurXPos>=3) Then Dec(CurXPos,2);           {2}
  764.       If (C='Q') And (CurXPos>=4) Then Dec(CurXPos,3);           {3}
  765.       If (C='K') And (CurXPos>1) Then Dec(CurXPos);              {4}
  766.       If (C='M') And (CurXPos<Count) Then Inc(CurXPos);          {6}
  767.       If (C='G') Then CurXPos:=1;                                {7}
  768.       If (C='H') And (CurXPos<=Count-2) Then Inc(CurXPos,2);     {8}
  769.       If (C='I') And (CurXPos<=Count-3) Then Inc(CurXPos,3);     {9}
  770.       If (C=#7 ) Then MainStr[0]:=Chr(CurXPos-1);                {Shift-Del}
  771.       If (C='S') And (Count>1) Then                              {Del}
  772.       Begin
  773.         Delete(MainStr,CurXPos,1);
  774.         GotoXY(X,Y);
  775.         WriteStr(MainStr+' ');
  776.         Dec(Count);
  777.         GotoXY(X-1+CurXPos,Y);
  778.       End;
  779.       If (C='R') Then                                            {Ins}
  780.       Begin
  781.         Ins:=Not Ins;
  782.         If Ins Then
  783.            CursorSize(VideoCard[Card].CharacterHeight-1,VideoCard[Card].CharacterHeight)
  784.         Else
  785.            CursorSize(1,VideoCard[Card].CharacterHeight);
  786.       End;
  787.       GotoXY(X-1+CurXPos,Y);
  788.     End  {End Extended Key}
  789.     Else
  790.     Begin
  791.  
  792.       If (C=#17) Then                           {^Q}
  793.       Begin
  794.         C:=ReadKey;
  795.         If C=#0 Then
  796.           C:=ReadKey
  797.         Else
  798.         If C in ['y','Y',#25] Then
  799.         Begin
  800.           MainStr[0]:=Chr(CurXPos-1);
  801.           Count:=CurXPos;
  802.           GotoXY(X,Y);
  803.           WriteStr(MainStr);
  804.           Pad(MaxLets-Length(MainStr),' ');
  805.         End;
  806.       End
  807.       Else
  808.       If (C=#27) Then
  809.       Begin
  810.         GotoXY(X,Y);
  811.         Pad(MaxLets,' ');
  812.         MainStr:='';
  813.         C:=#13;
  814.       End
  815.       Else
  816.       If (C=#8) Then                     {Was BackSpace Presssed?}
  817.       Begin
  818.         If (CurXPos>1) Then              {Can I BackSpace?}
  819.         Begin
  820.           Delete(MainStr,CurXPos-1,1);   {Delete the char}
  821.           GotoXY(X,Y);
  822.           WriteStr(MainStr+' ');            {Redisplay the String}
  823.           Dec(Count);                    {One less char}
  824.           Dec(CurXPos);                  {Move Back}
  825.           GotoXY(X-1+CurXPos,Y);         {Goto Position}
  826.         End;                             {End 'Can I BackSpace?'}
  827.       End                                {End 'Was BackSpace Pressed?'}
  828.       Else                               {No Not BackSpace - A Normal Letter}
  829.         If (CurXPos<=MaxLets) And (C<>#13) Then    {Is there Space?}
  830.         Begin
  831.           If Ins Or (CurXPos>=Count) Then   {Must I Insert the Char?}
  832.           Begin
  833.             If Count<=MaxLets Then
  834.               Begin
  835.                 Insert(C,MainStr,CurXPos);  {Insert the Char}
  836.                 Inc(Count);                 {Add 1 to Count}
  837.                 Inc(CurXPos);               {Move Cursor}
  838.               End;                          {End Check for Space in String}
  839.           End                               {End Check to see if Ins was True}
  840.           Else                              {No, Do not Insert, Overwrite}
  841.           Begin
  842.             MainStr[CurXPos]:=C;      {Overwrite char}
  843.             Inc(CurXPos);             {Move Cursor}
  844.           End;                        {End Insert / Overwrite}
  845.  
  846.           If CurXPos<Count Then       {If the char was Inserted, Rewrite}
  847.           Begin                       {the entire String to the screen}
  848.             GotoXY(X,Y);
  849.             WriteStr(MainStr);
  850.             GotoXY(X-1+CurXPos,Y);
  851.           End                         {End Rewrite the String to the screen}
  852.           Else                        {Need Not Rewrite the entire String}
  853.              WriteChr(C);             {Just Display the new char}
  854.         End;
  855.     End;                              {End Area which accepts a BackSpace or a Letter}
  856.   Until C=#13;
  857.  
  858.   RestXYPos(OldCur);
  859.   RestCursorSize(CursorSizeSave);
  860.   UnPadVar(MainStr,MainStr);
  861.   Cursor:=OldCurVal;
  862. End;
  863.  
  864. Procedure Pad(Count:Word;WithChar:Char);
  865.  
  866. Var
  867.   Q     :Pointer;
  868.  
  869. Begin
  870.   Q:=VideoWriteAddress(VX,VY);
  871.   Asm
  872.     cld
  873.     les    di, Q
  874.     mov    cx, Count
  875.     add    VX, cx
  876.     mov    ah, TextAttr
  877.     mov    al, WithChar
  878.     rep    stosw
  879.   End;
  880.   If VX>VideoCard[Card].XSize Then
  881.   Begin
  882.     Inc(VY,VX Div VideoCard[Card].XSize);
  883.     VX:=VX Mod VideoCard[Card].XSize;
  884.   End;
  885.   If Cursor Then PositionCursor;
  886. End;
  887.  
  888. Procedure Barometer(X,Y:Word;MaxLen:Byte;WithMe:Char;
  889.                     Current,EndPoint:LongInt);
  890.  
  891. Const
  892.   Previous:Byte = 0;
  893.  
  894. Var
  895.   HowFar:Byte;
  896.  
  897. Begin
  898.   GotoXY(X,Y);
  899.   HowFar:=(Current*MaxLen) Div EndPoint;
  900.   If HowFar<>Previous Then Pad(HowFar,WithMe);
  901.   Previous:=HowFar;
  902. End;
  903.  
  904. Procedure FillBlock(X1,Y1,X2,Y2:Word;WithChar:Char);
  905.  
  906. Var
  907.   Q        :Pointer;
  908.   LineSize :Word;
  909.  
  910. Label
  911.   CopyLoop;
  912.  
  913. Begin
  914.   Q       :=VideoWriteAddress(X1,Y1);
  915.   LineSize:=VideoCard[Card].XSize;
  916.  
  917.   Asm
  918.     cld
  919.     mov    cx, Y2
  920.     sub    cx, Y1
  921.     inc    cx
  922.  
  923.     mov    bx, X2
  924.     sub    bx, X1
  925.     inc    bx
  926.  
  927.     mov    si, LineSize
  928.     sub    si, bx
  929.     shl    si, 1
  930.  
  931.     les    di, Q
  932.     mov    ah, TextAttr
  933.     mov    al, WithChar
  934.  
  935. CopyLoop:
  936.     mov    dx, cx
  937.     mov    cx, bx
  938.     rep    stosw
  939.     add    di, si
  940.     mov    cx, dx
  941.     loop   CopyLoop
  942.  
  943.   End;
  944. End;
  945.  
  946. Function TextImageSize(X1,Y1,X2,Y2:Word):LongInt;
  947. Begin
  948.   TextImageSize:=((
  949.                    (LongInt(Y2)-LongInt(Y1)+1) *
  950.                    (LongInt(X2)-LongInt(X1)+1)
  951.                   ) * 2
  952.                  )+4;
  953. End;
  954.  
  955. Procedure GetTextImage(X1,Y1,X2,Y2:Word;Data:Pointer);
  956.  
  957. Var
  958.   Q          :Pointer;
  959.   XSize      :Word;
  960.  
  961. Label
  962.   CopyLoop;
  963.  
  964. Begin
  965.   Q     :=VideoWriteAddress(X1,Y1);
  966.   XSize :=VideoCard[Card].XSize;
  967.  
  968.   Asm
  969.     cld
  970.     mov    ax, X2
  971.     sub    ax, X1
  972.     inc    ax
  973.  
  974.     les    di, Data
  975.  
  976.     stosw
  977.     mov    dx, ax
  978.  
  979.     mov    ax, Y2
  980.     sub    ax, Y1
  981.     inc    ax
  982.     mov    cx, ax
  983.  
  984.     stosw
  985.  
  986.     mov    bx, XSize
  987.     sub    bx, dx
  988.     shl    bx, 1
  989.  
  990.     push   ds
  991.  
  992.     lds    si, Q
  993.  
  994. CopyLoop:
  995.     mov    ax, cx
  996.     mov    cx, dx
  997.     rep    movsw
  998.     add    si, bx
  999.     mov    cx, ax
  1000.     loop   CopyLoop
  1001.  
  1002.     pop    ds
  1003.   End;
  1004. End;
  1005.  
  1006. Procedure PutTextImage(X1,Y1:Word;Data:Pointer);
  1007.  
  1008. Var
  1009.   Q          :Pointer;
  1010.   XSize      :Word;
  1011.  
  1012. Label
  1013.   CopyLoop;
  1014.  
  1015. Begin
  1016.   Q     :=VideoWriteAddress(X1,Y1);
  1017.   XSize :=VideoCard[Card].XSize;
  1018.  
  1019.   Asm
  1020.     cld
  1021.     push   ds
  1022.     lds    si, Data
  1023.     lodsw
  1024.     mov    dx, ax
  1025.     lodsw
  1026.     mov    cx, ax
  1027.     les    di, Q
  1028.  
  1029.     mov    bx, XSize
  1030.     sub    bx, dx
  1031.     shl    bx, 1
  1032.  
  1033. CopyLoop:
  1034.     mov    ax, cx
  1035.     mov    cx, dx
  1036.     rep    movsw
  1037.     add    di, bx
  1038.     mov    cx, ax
  1039.     loop   CopyLoop
  1040.  
  1041.     pop    ds
  1042.   End;
  1043. End;
  1044.  
  1045. Procedure WindowToVScreen(Var X1,Y1:Integer);
  1046. {Converts Window Area Address to VScreen Address}
  1047. Begin
  1048.   X1:=X1 - 1 + VideoCard[Card].WX1;
  1049.   Y1:=Y1 - 1 + VideoCard[Card].WY1;
  1050. End;
  1051.  
  1052. Procedure WindowToVScreen4(Var X1,Y1,X2,Y2:Integer);
  1053. {Converts Window Area Address to VScreen Address}
  1054. Begin
  1055.   X1:=X1 - 1 + VideoCard[Card].WX1;
  1056.   Y1:=Y1 - 1 + VideoCard[Card].WY1;
  1057.   X2:=X2 - 1 + VideoCard[Card].WX2;
  1058.   Y2:=Y2 - 1 + VideoCard[Card].WY2;
  1059. End;
  1060.  
  1061. Procedure ScreenToVScreen(Var X1,Y1:Integer);
  1062. {Converts Screen Area Address to VScreen Address - Ideal For Mouse}
  1063. Begin
  1064.   X1:=X1 - 1 + VideoCard[Card].SX1;
  1065.   Y1:=Y1 - 1 + VideoCard[Card].SY1;
  1066. End;
  1067.  
  1068. Procedure ScreenToVScreen4(Var X1,Y1,X2,Y2:Integer);
  1069. {Converts Screen Area Address to VScreen Address - Ideal For Mouse}
  1070. Begin
  1071.   X1:=X1 - 1 + VideoCard[Card].SX1;
  1072.   Y1:=Y1 - 1 + VideoCard[Card].SY1;
  1073.   X2:=X2 - 1 + VideoCard[Card].SX2;
  1074.   Y2:=Y2 - 1 + VideoCard[Card].SY2;
  1075. End;
  1076.  
  1077. Begin
  1078.   TextAttr:=$0007;
  1079.   Asm
  1080.     mov   ah, 0fh
  1081.     int   10h
  1082.     mov   LastMode, al
  1083.   End;
  1084.   VX:=1;
  1085.   VY:=1;
  1086.   Cursor:=True;
  1087.   InitVideoCards;
  1088. End.
  1089.  
  1090. { Copyright 1993, Michael Gallias }
  1091.