home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / KTOOLS.ZIP / KTOOLS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-04-01  |  11.6 KB  |  375 lines

  1. UNIT KTOOLS;
  2.  
  3. INTERFACE
  4. USES
  5.     Dos,
  6.     Crt;
  7.  
  8. TYPE
  9.     Colors = 0..15;
  10.  
  11. VAR
  12.     ActiveDP  : Byte;     (* Active Display Page               *)
  13.     LineWidth : Integer;  (* Line Width of current video mode  *)
  14.     VideoMode : Byte;     (* Current Video Mode i.e. 0,1,2,3,7 *)
  15.  
  16.  
  17. FUNCTION CurrentVideoMode : Byte;
  18. (*
  19. This function returns the current video mode... 0..3 = color, 7 = mono.
  20. Global variables  LineWidth & ActiveDP are set each time this function
  21. is called.
  22. *)
  23.  
  24. PROCEDURE CursorOn;
  25. (*
  26. This procedure checks the current video mode and restores a normal cursor.
  27. *)
  28.  
  29. PROCEDURE CursorOff;
  30. (*
  31. This procedure sets bit five of the cursor control byte, turning the cursor
  32. off.
  33. *)
  34.  
  35. FUNCTION KUCase(S:String):String;
  36. (*
  37. This function uses upcase procedure to convert an entire string or line from
  38. a text file to all uppercase characters.
  39. *)
  40.  
  41. FUNCTION KLCase(S:String):String;
  42. (*
  43. This function uses CHR & ORD and does just the oppsite of KUCase.
  44. *)
  45.  
  46. FUNCTION Color(FG,BG:Colors):Byte;
  47. (*
  48. This function returns the color attribute result for the combo FG on BG.
  49. The blinking bit is removed.
  50. *)
  51.  
  52. PROCEDURE KAttr(Row,Col,Rows,Cols:Integer;Attr:Byte);
  53. (*
  54. This procedure puts the specified Attribute beginning at Row/Col and goes
  55. Cols by Rows.
  56. *)
  57.  
  58. PROCEDURE KFill(Row,Col,Rows,Cols:Integer;Ch:Char;Attr:Byte);
  59. (*
  60. This procedure puts the specified Character beginning at Row/Col and goes
  61. Cols by Rows.
  62. *)
  63.  
  64. {$V-}
  65. PROCEDURE KTrim(VAR S:String);
  66. (*
  67. This procedure trims all leading and trailing blanks from a string.
  68. *)
  69.  
  70. PROCEDURE KWrite(Row,Col:Integer;Attr:Byte;S:String);
  71. (*
  72. This procedure writes at string beginning at Row/Col with text Attr.
  73. It looks for the actual param on the stack.
  74. *)
  75.  
  76. PROCEDURE KWriteV(Row,Col:Integer;Attr:Byte;VAR S:String);
  77. (*
  78. This procedure writes at string beginning at Row/Col with text Attr.
  79. It looks for the param address on the stack.
  80. *)
  81.  
  82. PROCEDURE KWriteC(Row:Integer;Attr:Byte;S:String);
  83. (*
  84. This procedure writes at string beginning at Row/Col with text Attr.
  85. The output is centered on the screen between column 1 & 80.
  86. *)
  87.  
  88. PROCEDURE KWriteCV(Row:Integer;Attr:Byte;VAR S:String);
  89. (*
  90. This procedure writes at string beginning at Row/Col with text Attr.
  91. The output is centered on the screen between column 1 & 80.
  92. It looks for the param address on the stack.
  93. *)
  94. {$V+}
  95.  
  96.  
  97.  
  98. IMPLEMENTATION
  99. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  100.  
  101. FUNCTION CurrentVideoMode:Byte;
  102. VAR
  103.     Regs:Registers;               {Registers defined in DOS unit}
  104. BEGIN
  105.     Regs.AH := $F;
  106.     Intr($10,DOS.Registers(Regs));
  107.     CurrentVideoMode:=Regs.AL;    {Assign video mode to function name}
  108.     ActiveDP:=Regs.BH;            {Active page returned in register BH}
  109.     LineWidth:=Regs.AH;           {Characters per line returned in AH}
  110. END;
  111. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  112.  
  113. PROCEDURE CursorOn;
  114. VAR
  115.     Regs:Registers;               {Registers defined in DOS unit}
  116.     Mode:Byte;
  117. BEGIN
  118.     Mode := CurrentVideoMode;     {get current video mode}
  119.     IF Mode IN[0..3] THEN
  120.        BEGIN
  121.           Regs.AH := $01;                { Restore Color Cursor }
  122.           Regs.CH := $06;
  123.           Regs.CL := $07;
  124.           Intr($10,DOS.Registers(Regs));
  125.        END
  126.     ELSE
  127.        IF Mode = 7 THEN
  128.           BEGIN
  129.              Regs.AH := $01;            { Restore Mono Cursor }
  130.              Regs.CH := $C;
  131.              Regs.CL := $D;
  132.              Intr($10,DOS.Registers(Regs));
  133.           END
  134.        ELSE
  135.           BEGIN
  136.              Regs.AH := $01;            { We're gonna put a cursor }
  137.              Regs.CH := $1;             { on the screen no matter what }
  138.              Regs.CL := $D;             { one big block  if all else fails }
  139.              Intr($10,DOS.Registers(Regs));
  140.           END;
  141.  
  142. END;
  143. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  144.  
  145. PROCEDURE CursorOff;
  146. VAR
  147.    Regs:Registers;
  148. BEGIN                            { Set bit 5 of cursor control byte }
  149.    Regs.AH := $01;               { which turns cursor off           }
  150.    Regs.CH := $20;
  151.    Intr($10,DOS.Registers(Regs));
  152. END;
  153. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  154.  
  155. FUNCTION KUCase(S:String):String;
  156. VAR
  157.    I: integer;
  158. BEGIN
  159.    FOR I := 1 TO Length(S) DO S[I] := UpCase(S[I]);
  160.    KUCase := S;
  161. END;
  162. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  163.  
  164. FUNCTION KLCase(S:String):String;
  165. VAR
  166.    I: integer;
  167. BEGIN
  168.    FOR I := 1 TO Length(S) DO
  169.       IF S[I] IN['A'..'Z'] THEN   {If character is A-Z }
  170.          S[I]:=CHR(ORD(S[I])+$20);{Add HEX 20 ordinal value for lowercase}
  171.    KLCase := S;
  172. END;
  173. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  174.  
  175. FUNCTION Color(FG,BG:Colors):Byte;
  176. BEGIN
  177.    Color := (FG+(BG SHL 4)) MOD 128;{shift BG 4 places left(nibble) and add FG}
  178. END;                                {MOD 128 removes the blink}
  179. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  180.  
  181. PROCEDURE KAttr(Row,Col,Rows,Cols:Integer;Attr:Byte);
  182. VAR
  183.     Ch,X,Y,R,C:Integer;
  184.     Regs:Registers;
  185. BEGIN
  186.    R:=(Row+(Rows-1));
  187.    C:=(Col+(Cols-1));
  188.    REPEAT
  189.       X:=Col;
  190.          REPEAT
  191.                GOTOxy(x,Row);              {BIOS call to read screen character}
  192.                Regs.AH:=$08;               {and attribute                     }
  193.                Regs.BH:=ActiveDP;          {Specify active page}
  194.                Intr($10,DOS.Registers(Regs));
  195.  
  196.                { Regs.AL contains the character read with service 8.}
  197.  
  198.                Regs.AH:=$09;             {BIOS call to write Character and}
  199.                                          {attribute to screen}
  200.                Regs.BH:=ActiveDP;        {Specify active page}
  201.                Regs.BL:=Attr;            {Specify attribute }
  202.                Regs.CX:=$01;             {write it once }
  203.                Intr($10,DOS.Registers(Regs));
  204.                X:=X+1;                   {INC X i.e col position}
  205.          UNTIL X>C;
  206.       Row:=Row+1;                        {INC Row i.e. Row position}
  207.    UNTIL Row > R;
  208. END;
  209. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  210.  
  211. PROCEDURE KFill(Row,Col,Rows,Cols:Integer;Ch:Char;Attr:Byte);
  212. VAR
  213.     R:Integer;
  214.     Regs:Registers;
  215.  
  216. (**)
  217.  
  218. BEGIN
  219.    R:=(Row+(Rows-1));
  220.    REPEAT
  221.       GOTOxy(col,Row);
  222.       Regs.AH:=$09;
  223.       Regs.AL:=ORD(Ch);
  224.       Regs.BH:=ActiveDP;
  225.       Regs.BL:=Attr;
  226.       Regs.CX:=cols;
  227.       Intr($10,DOS.Registers(Regs));
  228.       Row:=Row+1;
  229.    UNTIL Row > R;
  230. END;
  231.  
  232. (*
  233.  
  234.  {If you don't want to use the Bios calls, comment them out and open this
  235.   section up and recompile. NOTE: BIOS is slower than write if DirectVideo is
  236.   set to true, however by placing the number of cols to fill in the repeating
  237.   register CX the difference is only slightly noticable.}
  238.  
  239.     S : String;
  240.     SavedTextAttr:Integer;
  241.  
  242. BEGIN
  243.    S:='';
  244.    FOR X := 1 to Cols DO
  245.       S:=S+Ch;
  246.    R:=(Row+(Rows-1));
  247.    SavedTextAttr:=CRT.TextAttr;
  248.    CRT.TextAttr:=Attr;
  249.    REPEAT
  250.          GOTOxy(Col,Row);
  251.          Write(s);
  252.          Row:=Row+1;
  253.    UNTIL Row > R;
  254.    CRT.TextAttr:=SavedTextAttr
  255. END;
  256. *)
  257. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  258.  
  259. PROCEDURE KTrim(VAR s : string);
  260. VAR
  261.     x,b,e : Integer;
  262. BEGIN
  263.     For X := 1 to LENGTH(s) DO
  264.        IF s[1]=' ' THEN DELETE(S,1,1); {delete leading spaces}
  265.  
  266.     {This may look wrong to check the entire string, but we look at }
  267.     {S[ 1 ] each time and delete blanks at same until a character appears]
  268.     {From that point on S[1] stays the first character we skipped;}
  269.     {This would work as well
  270.                               REPEAT
  271.                                  IF s[1] = ' ' THEN DELETE(S,1,1);
  272.                               UNTIL s[1] <> ' ';
  273.  
  274.      and on lengthy strings would be faster.  }
  275.  
  276.     b:=1;
  277.     e:=LENGTH(s);
  278.     For X := e DOWNTO b DO
  279.        BEGIN
  280.          IF s[e]=' ' THEN DELETE(S,e,1) {delete trailing spaces}
  281.          ELSE EXIT;  {As mentioned above but this time we'll exit when we}
  282.                      {see our first character (NON BLANK)}
  283.        END;
  284. END;
  285. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  286.  
  287. (*
  288.    The following procedures are straight forward enough and no BIOS is used
  289.    in the code.   TEXTATTR is assigned in the CRT unit and referrenced as
  290.    CRT.TextAttr.  This holds the attribute of the current video page and not
  291.    necessarily a certain character pos. Thus we save it and change it before
  292.    we write to the screen with our string.  Then we put it back the way we
  293.    found it. Centering Text is simply taking the LineWidth minus the length
  294.    of the string divided by 2, which gives us the starting column for our
  295.    gotoxy(?,Row) statement.
  296. *)
  297.  
  298. PROCEDURE KWrite(Row,Col:Integer;Attr:Byte;S:String);
  299. VAR                             {S is actual 'Hello World' or variable }
  300.     SavedTextAttr:Integer;      {VarParm := 'Hello World' }
  301. BEGIN
  302.     SavedTextAttr:=CRT.TextAttr;
  303.     CRT.TextAttr:=Attr;
  304.     GotoXY(Col,Row);
  305.     Write(s);
  306.     CRT.TextAttr:=SavedTextAttr
  307. END;
  308. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  309.  
  310. PROCEDURE KWriteV(Row,Col:Integer;Attr:Byte;VAR S:String);
  311. VAR                           {S must be a variable, only the address is passed}
  312.     SavedTextAttr:Integer;    {to save space on the stack}
  313. BEGIN
  314.     SavedTextAttr:=CRT.TextAttr;    {Save current page text attribute}
  315.     CRT.TextAttr:=Attr;             {Assign our attribute value}
  316.     GotoXY(Col,Row);                {Move cursor to our strating Pos.}
  317.     Write(s);                       {Write our string and attribute}
  318.     CRT.TextAttr:=SavedTextAttr;     {Restore original text attribute}
  319.  
  320.     {We want to restore the original so that TURBO's write & writeln will
  321.      function with a specified global attribute in CRT.TextAttr and we can
  322.      still write our own with no interference}
  323. END;
  324. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  325.  
  326. PROCEDURE KWriteC(Row:Integer;Attr:Byte;S:String);
  327. VAR
  328.     X,SavedTextAttr:Integer;
  329. BEGIN
  330.     SavedTextAttr:=CRT.TextAttr;
  331.     CRT.TextAttr:=Attr;
  332.     X:=(LineWidth-Length(S)) DIV 2; {get cursor pos to write string centered}
  333.     GotoXY(X,Row);
  334.     Write(s);
  335.     CRT.TextAttr:=SavedTextAttr
  336. END;
  337. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  338.  
  339. PROCEDURE KWriteCV(Row:Integer;Attr:Byte;VAR S:String);
  340. VAR
  341.     X,SavedTextAttr:Integer;
  342. BEGIN
  343.     SavedTextAttr:=CRT.TextAttr;
  344.     CRT.TextAttr:=Attr;
  345.     X:=(LineWidth-Length(S)) DIV 2;
  346.     GotoXY(X,Row);
  347.     Write(s);
  348.     CRT.TextAttr:=SavedTextAttr
  349. END;
  350. (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  351.  
  352. (*
  353.    This is done to initialize the ActiveDp and LineWidth variables when the
  354.    program is first run.  The VideoMode variable may also be used along with
  355.    ActiveDP & LineWidth.
  356. *)
  357.  
  358. BEGIN
  359.    VideoMode := CurrentVideoMode;
  360. END.
  361.  
  362. (******************************************************************************
  363. Additions & Revisions
  364.  
  365. {010188}
  366. Changed KFill : placed number of cols to fill in CX versa advancing cursor and
  367. writing one position per call to BIOS. I originally thought this would show how
  368. to use the bios calls to write to different x/y positions, however it was just
  369. to slow to be truly useful.  The current code shows the use of the bios call
  370. plus the use of the CX register in this type of bios function.
  371.  
  372. Added Function : KUCase,KLCase & Color.
  373.  
  374. ******************************************************************************)
  375.