home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / io / io_22 / io22.inc < prev    next >
Encoding:
Text File  |  1987-05-24  |  26.8 KB  |  801 lines

  1. { IO22.INC -- Global I/O procedures to include in programs generally
  2.   by Bill Meacham
  3.   Ver 2.0 -- includes prev_page and next_page, changes where pause text
  4.              is displayed -- 2/26/86.
  5.              Cosmetic improvements -- 4/16/86.
  6.   Ver 2.l -- Add function Pad -- 10/12/86.
  7.   Ver 2.2 -- Add ability to move cursor within input line -- 5/24/87. }
  8.  
  9. { -------------------------------------------------------------------------- }
  10.  
  11. const
  12.                        { ASCII values of cursor control keys, like WordStar. }
  13.                        { Note -- Backspace and Delete are different in CP/M  }
  14.                        {         and PC-DOS.  Proc KEYIN translates them.    }
  15.     prev_char = $13 ;  { ^S }
  16.     next_char = $04 ;  { ^D }
  17.     prev_fld  = $05 ;  { ^E }
  18.     next_fld  = $18 ;  { ^X }
  19.     prev_page = $12 ;  { ^R }
  20.     next_page = $03 ;  { ^C }
  21.     del_char  = $07 ;  { ^G }
  22.     del_left  = $08 ;  { ^H (Backspace) }
  23.     del_fld   = $19 ;  { ^Y }
  24.     del       = $7F ;  { Delete }
  25.     escape    = $1B ;
  26.     carr_rtn  = $0D ;
  27.     space     = $20 ;
  28.     filler    = $2E ;  { . }
  29.  
  30. type
  31.     str_type = string[80] ;
  32.  
  33.     registers = record
  34.         ax,bx,cx,dx,bp,si,di,ds,es,flags : integer ;
  35.     end ;
  36.  
  37.     intset = set of $00 .. $FF ;
  38.  
  39. const  { Turbo typed constants -- initialized variables }
  40.     terminating : intset = [carr_rtn, next_fld, prev_fld, escape, next_page, prev_page] ;
  41.     adjusting   : intset = [prev_char, next_char, del_char, del_fld, del_left] ;
  42.  
  43. var
  44.     fld, scrn   : integer ; { For field & screen cursor control }
  45.  
  46. { -------------------------------------------------------------------------- }
  47.  
  48. { procedure gotoxy (col,row) ; -- Built-in proc in Turbo to place
  49.   cursor on screen.  Upper left is (1,1) not (0,0)! }
  50.  
  51. { procedure clrscr ; -- Built-in proc in Turbo to clear screen. }
  52.  
  53. { procedure clreol ; -- built-in proc in Turbo to clear to end of line }
  54.  
  55. { -------------------------------------------------------------------------- }
  56.  
  57. procedure clrline (col,row : integer) ;
  58.     begin
  59.         gotoxy (col,row) ;
  60.         clreol
  61.     end ;
  62.  
  63. { -------------------------------------------------------------------------- }
  64.  
  65. procedure beep ;
  66.     begin
  67.         write (chr(7))
  68.     end ;
  69.  
  70. { -------------------------------------------------------------------------- }
  71.  
  72. procedure do_fld_ctl (key : integer) ;
  73.   { Adjusts global FLD based on value of key, the ordinal value of last key pressed }
  74.   { global
  75.         fld : integer -- for field cursor control }
  76.     begin
  77.         case key of
  78.           carr_rtn, next_fld : fld := succ(fld) ;
  79.           prev_fld           : fld := pred(fld) ;
  80.           next_page          : fld := 999 ;
  81.           prev_page          : fld := -999 ;
  82.           escape             : fld := maxint ;
  83.         end  { case }
  84.     end ;  { proc do_fld_ctl }
  85.  
  86. { ------------------------------------------------------------ }
  87.  
  88. procedure do_scrn_ctl ;
  89.   { Checks value of FLD and adjusts value of SCRN accordingly }
  90.   { Global
  91.         fld, scrn : integer -- For field and screen cursor control }
  92.     begin
  93.         if fld < 1 then
  94.                 scrn := pred(scrn)
  95.         else if fld = maxint then
  96.                 scrn := maxint
  97.         else
  98.                 scrn := succ(scrn)
  99.     end ;
  100.  
  101. { ------------------------------------------------------------ }
  102.  
  103. procedure write_str (st:str_type ; col,row:integer) ;
  104.     begin
  105.         gotoxy (col,row) ;
  106.         write (st)
  107.     end ;
  108.  
  109. { -------------------------------------------------------------------------- }
  110.  
  111. procedure write_int (int:integer ; width,col,row:integer) ;
  112.     begin
  113.         gotoxy (col,row) ;
  114.         write (int:width)
  115.     end ;
  116.  
  117. { -------------------------------------------------------------------------- }
  118.  
  119. procedure set_bool (var bool : boolean) ;
  120.   { Sets boolean to be undefined, neither true nor false.
  121.     Boolean is stored as one byte:
  122.         $80 = undefined
  123.         $01 = true
  124.         $00 = false.
  125.     Note : Turbo interprets $80 as true because it is greater than zero! }
  126.  
  127.     var
  128.         b : byte absolute bool ;
  129.     begin
  130.         b := $80
  131.     end ;  { proc set_bool }
  132.  
  133. { -------------------------------------------------------------------------- }
  134.  
  135. function defined (bool : boolean) : boolean ;
  136.   { Determines whether the boolean is defined or not }
  137.     var
  138.         b : byte absolute bool ;
  139.     begin
  140.         defined := not (b = $80)
  141.     end ;  { function defined }
  142.  
  143. { -------------------------------------------------------------------------- }
  144.  
  145. procedure write_bool (bool:boolean ; col, row:integer) ;
  146.     begin
  147.         gotoxy (col,row) ;
  148.         if not defined(bool) then
  149.             write ('___')
  150.         else if bool then
  151.             write ('YES')
  152.         else
  153.             write ('NO ')
  154.     end ;
  155.  
  156. { -------------------------------------------------------------------------- }
  157.  
  158. procedure write_real (r:real ; width,frac,col,row:integer) ;
  159.     begin
  160.         gotoxy (col,row) ;
  161.         write (r:width:frac)
  162.     end ;
  163.  
  164. { -------------------------------------------------------------------------- }
  165. (*
  166. { This is for Kaypro CP/M -- comment it out to use IBM }
  167.  
  168. procedure keyin (var ch:char) ;
  169. { Reads a single character from keyboard without echoing it back.
  170.   Maps Kaypro arrow keys to WordStar cursor keys. }
  171.     begin
  172.         read (kbd, ch) ;
  173.         if ch = ^H then              { make Backspace non-destructive }
  174.             ch := chr(prev_char)
  175.         else if ch = ^L then
  176.             ch := chr(next_char)
  177.         else if ch = ^K then
  178.             ch := chr(prev_fld)
  179.         else if ch = ^J then
  180.             ch := chr(next_fld)
  181.         else if ord(ch) = del then
  182.             ch := chr(del_left)     { make Delete key delete to left }
  183.     end ;
  184. *)
  185. { ------------------------------------------------------------ }
  186.  
  187. { This is for IBM PC-DOS -- comment it out for CP/M }
  188.  
  189. procedure keyin (var ch:char) ;
  190. { Reads a single character from keyboard without echoing it back.
  191.   Maps function key scan codes to single keyboard keys.
  192.   From Turbo 3.0 manual, page 360 -- 5/29/85
  193.   Modified for IO20 -- 2/26/86
  194.   Modified for IO22 -- 5/24/87 }
  195.  
  196.     var
  197.         func : boolean ;     { Whether function key or not }
  198.            c : char ;        { Character read }
  199.          key : integer ;     { ORD of character returned }
  200.  
  201.     begin
  202.         func := false ;
  203.         read (kbd,c) ;                    { Get first char }
  204.         if  (ord(c) = escape)             { If there is }
  205.         and keypressed then               { a second ... }
  206.           begin
  207.             read (kbd,c) ;                { Get 2nd char }
  208.             func := true
  209.           end ;
  210.         key := ord(c) ;
  211.  
  212.         if func then                      { Translate function keys }
  213.             case key of
  214.               63,75 : key := prev_char ;  { F5, left-arrow }
  215.               64,77 : key := next_char ;  { F6, right-arrow }
  216.               61,72 : key := prev_fld ;   { F3, up-arrow }
  217.               62,80 : key := next_fld ;   { F4, down-arrow }
  218.               65,73 : key := prev_page ;  { F7, PgUp }
  219.               66,81 : key := next_page ;  { F8, PgDn }
  220.               59,83 : key := del_char ;   { F1, DEL }
  221.               60    : key := del_fld ;    { F2 }
  222.             else      key := 00 ;
  223.             end  { case }
  224.         else  { not a function key }
  225.             case key of                   { CP/M-like control keys }
  226.               $0B   : key := prev_fld ;   { ^K }
  227.               $0A   : key := next_fld ;   { ^J }
  228.               $0C   : key := next_char ;  { ^L }
  229.             end ;  { case }
  230.  
  231.         ch := chr(key)                    { finally, return the character }
  232.     end ;
  233.  
  234. { ------------------------------------------------------------ }
  235.  
  236. function build_str (ch : char ; n : integer) : str_type ;
  237.   { returns a string of length n of the character ch }
  238.     var
  239.         st : str_type ;
  240.     begin
  241.         if n < 0 then
  242.             n := 0 ;
  243.         st[0] := chr(n) ;
  244.         fillchar (st[1],n,ch) ;
  245.         build_str := st
  246.     end ;  { function build_str) ;
  247.  
  248. { -------------------------------------------------------------------------- }
  249.  
  250. function pad (st : str_type ; ch : char ; i : integer) : str_type ;
  251. { Pad string with ch to length of i.  Do not let i exceed 80 (length of str_type! }
  252.   var
  253.     l : integer ;
  254.   begin
  255.     l := length(st) ;
  256.     if l < i then
  257.       begin
  258.         fillchar (st[l+1],i-l,ch) ;
  259.         st[0] := chr(i)
  260.       end ;
  261.     pad := st
  262.   end;
  263.  
  264. { ------------------------------------------------------------ }
  265.  
  266. procedure adjust_str (var st : str_type ;
  267.                       var  p : integer ;  { position of char to left of cursor }
  268.                          key,             { ord of adjusting character }
  269.             maxlen, col, row : integer ) ;
  270.   { Adjusts position of cursor within string, deletes characters, etc. }
  271.     begin
  272.       case key of
  273.         prev_char : if p > 0 then
  274.                         p := pred(p) ;
  275.         next_char : if p < length(st) then
  276.                         p := succ(p) ;
  277.         del_left  : if p > 0 then
  278.                       begin
  279.                         delete (st,p,1) ;
  280.                         write (^H,copy(st,p,maxlen),chr(filler)) ;
  281.                         p := pred(p)
  282.                       end ;
  283.         del_char  : if p < length(st) then
  284.                       begin
  285.                         delete (st,p+1,1) ;
  286.                         write (copy(st,p+1,maxlen),chr(filler))
  287.                       end ;
  288.         del_fld   : begin
  289.                       st := '' ;
  290.                       p := 0  ;
  291.                       write_str (build_str(chr(filler),maxlen),col,row)
  292.                     end
  293.       end  { case }
  294.     end ; { proc adjust_str }
  295.  
  296. { -------------------------------------------------------------------------- }
  297.  
  298. function purgech (instr : str_type ; inchar : char) : str_type ;
  299.     {Purges all instances of the character from the string}
  300.     var
  301.         n      : integer ;  {Loop counter}
  302.         outstr : str_type ; {Result string}
  303.  
  304.     begin
  305.         outstr := '' ;
  306.         for n := 1 to length (instr) do
  307.                 if not (instr[n] = inchar) then
  308.                         outstr := concat (outstr, instr[n]) ;
  309.         purgech := outstr
  310.     end ;
  311.  
  312. { -------------------------------------------------------------------------- }
  313.  
  314. function stripch (instr:str_type ; inchar:char) : str_type ;
  315.     {Strips leading instances of the character from the string}
  316.     begin
  317.         while not (length(instr) = 0)
  318.         and (instr[1] = inchar) do
  319.                 delete (instr, 1, 1) ;
  320.         stripch := instr
  321.     end ;
  322.  
  323. { -------------------------------------------------------------------------- }
  324.  
  325. function chopch (instr:str_type ; inchar:char) : str_type ;
  326.     {Chops trailing instances of the character from the string}
  327.     begin
  328.         while not (length(instr) = 0)
  329.         and (instr[length(instr)] = inchar) do
  330.                 delete (instr, length(instr), 1) ;
  331.         chopch := instr
  332.     end ;
  333.  
  334. { -------------------------------------------------------------------------- }
  335.  
  336. procedure read_str (var st:str_type ; maxlen, col, row:integer) ;
  337.  
  338.   { Read String.  This procedure gets input from the keyboard one
  339.     character at a time and edits on the fly, rejecting invalid
  340.     characters.  COL and ROW tell where to begin the data input
  341.     field, and MAXLEN is the maximum length of the string to be
  342.     returned.
  343.  
  344.     Revised 6/04/85 -- WPM }
  345.  
  346.     var
  347.         ch   : char ;     { character from keyboard }
  348.         key,              { ord(ch) }
  349.         p    : integer ;  { position of char to left of cursor }
  350.  
  351.     procedure add_to_str ;
  352.         begin
  353.           if not (length(st) = maxlen) then
  354.             begin
  355.               p := p + 1 ;
  356.               insert (ch,st,p) ;
  357.               write (copy(st,p,maxlen))
  358.             end
  359.         end ; {--- of add_to_str ---}
  360.  
  361.     begin {--- read_str ---}
  362.         write_str (st, col, row) ;
  363.         write (build_str(chr(filler),maxlen - length(st))) ;
  364.         p := length(st) ;
  365.         repeat
  366.             gotoxy (col + p, row) ;
  367.             keyin (ch) ;
  368.             key := ord(ch) ;
  369.             if key in [$20 .. $7E] then  { printable character }
  370.                 add_to_str
  371.             else if key in adjusting then
  372.                 adjust_str (st,p,key,maxlen,col,row)
  373.             else if key in terminating then
  374.                 do_fld_ctl (key)
  375.             else
  376.                 beep
  377.         until key in terminating ;
  378.         gotoxy (col + length(st), row) ;
  379.         write ('':maxlen - length(st))
  380.     end ; {--- of read_str ---}
  381.  
  382. { -------------------------------------------------------------------------- }
  383.  
  384. procedure read_int (var int:integer ; maxlen, col, row:integer) ;
  385.  
  386.   { Read Integer.  This procedure gets input from the keyboard
  387.     one character at a time and edits on the fly, rejecting
  388.     invalid characters.  COL and ROW tell where to begin the data
  389.     input field, and MAXLEN is the maximum length of the integer
  390.     to be returned.
  391.  
  392.     Revised 6/04/85 -- WPM }
  393.  
  394.     const
  395.         maxst : string[5] = '32767' ;  { string representation of maxint }
  396.  
  397.     var
  398.         ch    : char ;       { character from keyboard }
  399.         key,                 { ord(ch) }
  400.         p     : integer ;    { position of char to left of cursor }
  401.         st    : string[5] ;  { string representation of integer }
  402.         code  : integer ;    { result of string to integer conversion }
  403.  
  404.     procedure add_to_str ;
  405.         begin
  406.           if not (length(st) = maxlen) then
  407.             begin
  408.               p := p + 1 ;
  409.               insert (ch,st,p) ;
  410.               write (copy(st,p,maxlen))
  411.             end
  412.         end ; {--- of add_to_str---}
  413.  
  414.     begin {--- read_int ---}
  415.         str (int:maxlen, st) ;          { convert integer into string }
  416.         st := purgech (st, ' ') ;
  417.         st := stripch (st, '0') ;
  418.         write_str (st, col, row) ;
  419.         write (build_str(chr(filler),maxlen - length(st))) ;
  420.         p := length(st) ;
  421.         repeat
  422.             gotoxy (col + p, row) ;
  423.             keyin (ch) ;
  424.             key := ord(ch) ;
  425.             if key = $2D then                 { minus sign }
  426.               begin
  427.                 if  (pos('-',st) = 0)
  428.                 and (length(st) < maxlen)
  429.                 and (p = 0) then
  430.                     add_to_str
  431.                 end
  432.             else if key in [$30 .. $39] then  {digits 0 - 9}
  433.               begin
  434.                 add_to_str ;
  435.                 if (length(st) = 5)
  436.                 and (st > maxst) then
  437.                   begin
  438.                     delete (st,p,1) ;
  439.                     write (^H,copy(st,p,maxlen),chr(filler)) ;
  440.                     p := p - 1
  441.                   end
  442.               end
  443.             else if key in adjusting then
  444.                 adjust_str (st,p,key,maxlen,col,row)
  445.             else if key in terminating then
  446.                 do_fld_ctl (key)
  447.         until key in terminating ;
  448.         if st = '' then
  449.           begin
  450.             int := 0 ;
  451.             code := 0
  452.           end
  453.         else
  454.             val (st, int, code) ;              {Make string into integer}
  455.         gotoxy (col, row) ;
  456.         if code = 0 then  {Conversion worked OK}
  457.             write (int:maxlen)
  458.         else
  459.           begin
  460.             write ('** conversion error ', code) ;
  461.             halt
  462.           end
  463. end ; {--- of read_int ---}
  464.  
  465. { -------------------------------------------------------------------------- }
  466.  
  467. function equal (r1,r2 : real) : boolean ;
  468.   { tests functional equality of two real numbers -- 4/30/85 }
  469.     begin
  470.         equal := abs(r1 - r2) < 1.0e-5
  471.     end ;  { function equal }
  472.  
  473. { -------------------------------------------------------------------------- }
  474.  
  475. function greater (r1,r2 : real) : boolean ;
  476.   { tests functional inequality of two real numbers -- 5/1/85 }
  477.     begin
  478.         greater := (r1 - r2) > 1.0e-5
  479.     end ;  { function greater }
  480.  
  481. { -------------------------------------------------------------------------- }
  482.  
  483. procedure read_real (var r:real ; maxlen,frac,col,row:integer) ;
  484.  
  485.   { Read Real.  This procedure gets input from the keyboard
  486.     one character at a time and edits on the fly, rejecting
  487.     invalid characters.  COL and ROW tell where to begin the data
  488.     input field; MAXLEN is the maximum length of the string
  489.     representation of the real number, including sign and decimal
  490.     point; FRAC is the fractional part, the number of digits to
  491.     right of the decimal point.
  492.  
  493.     Note -- In Turbo the maximum number of significant digits in
  494.     decimal (not scientific) representation is 11.  In TurboBCD,
  495.     the maximum number of significant digits is 18.  It is the
  496.     programmer's responsibility to limit input and computed output
  497.     to the maximum significant digits.
  498.  
  499.     Revised 6/04/85 -- WPM }
  500.  
  501.     var
  502.         ch   : char ;       { Input character }
  503.         key,                { ord(ch) }
  504.         p    : integer ;    { position of char to left of cursor }
  505.         st   : string[20] ; { String representation of real number -- }
  506.                             { max digits plus minus sign plus decimal point }
  507.         code : integer ;    { Result of VAL conversion }
  508.         rlen : integer ;    { Current length of st to right of dec. pt. }
  509.         llen : integer ;    { Current length to left, including dec. pt. }
  510.         maxl : integer ;    { Max allowable to left, including dec. pt. }
  511.         posdec : integer ;  { position of decimal point in string }
  512.  
  513.   { +++++++++++++++++++++++++++++++++++++ }
  514.  
  515.     procedure compute_length ;
  516.       { Compute length of left and right portions of string }
  517.         begin
  518.             posdec := pos('.',st) ;
  519.             if posdec = 0 then                { If no dec. pt. ... }
  520.                 begin
  521.                     llen := length(st) ;      { the whole string is Left }
  522.                     rlen := 0                 { and none is Right }
  523.                 end
  524.             else    {There is a decimal point ...}
  525.                 begin
  526.                     llen := posdec ;          { Left is all up to and incl. dec. pt. }
  527.                     rlen := length(st) - llen { Right is the rest }
  528.                 end
  529.         end ; { proc compute_length }
  530.  
  531.   { +++++++++++++++++++++++++++++++++++++ }
  532.  
  533.     procedure add_to_str ;
  534.  
  535.         procedure add_it ;
  536.             begin
  537.               p := p + 1 ;
  538.               insert (ch,st,p) ;
  539.               write (copy(st,p,maxlen))
  540.             end ;
  541.  
  542.         begin {add_to_str}
  543.             posdec := pos ('.',st) ;
  544.             if ch = '.' then        { Decimal point; if room, add it }
  545.               begin
  546.                 if  (posdec = 0)
  547.                 and (length(st) - p <= frac) then
  548.                     add_it
  549.               end
  550.                                     { else it's not a decimal point }
  551.                                     { see if digit fits in whole part }
  552.             else if  (    (posdec = 0)
  553.                       and (llen < maxl - 1)  { only dec. pt. allowed in pos. maxl }
  554.                      )
  555.                  or  (    (posdec > 0)
  556.                       and (llen < maxl)
  557.                       and (p < posdec)
  558.                      ) then
  559.  
  560.                 add_it
  561.  
  562.                                     { digit is candidate for fractional part }
  563.             else if  (not(posdec = 0))
  564.                  and (p >= posdec)
  565.                  and (rlen < frac) then
  566.  
  567.                 add_it
  568.  
  569.         end ; {--- of add_to_str---}
  570.  
  571.   { +++++++++++++++++++++++++++++++++++++ }
  572.  
  573.     begin {--- read_real ---}
  574.                               {Initialize}
  575.         maxl  := maxlen - frac ;
  576.  
  577.                               {Set up string representation of real and }
  578.                               {determine length of left & right portions}
  579.  
  580.         str(r:maxlen:frac,st) ;           {Make real into string}
  581.         st := purgech (st, ' ') ;         {Purge all blanks}
  582.         st := stripch (st, '0') ;         {Strip leading zeroes}
  583.         if not (pos('.', st) = 0) then    {If there is a dec. pt ... }
  584.             begin
  585.                 st := chopch (st, '0') ;  {Chop trailing zeroes}
  586.                 st := chopch (st, '.')    {and trailing dec. pt.}
  587.             end ;
  588.         compute_length ;
  589.  
  590.                               {Write string on console}
  591.  
  592.         write_str (st, col, row) ;
  593.         write (build_str(chr(filler),maxlen - length(st))) ;
  594.         p := length(st) ;
  595.  
  596.                               {Get input a character at a time & edit it}
  597.  
  598.         repeat
  599.             gotoxy (col + p, row) ;
  600.             compute_length ;
  601.             if (    (posdec = 0)
  602.                 and (llen > maxl - 1)
  603.                )
  604.             or (    (not (posdec = 0))
  605.                 and (llen > maxl)
  606.                )
  607.             or (rlen > frac) then                   { if number is larger than }
  608.               begin                                 { spec then delete it all }
  609.                 key := del_fld ;
  610.                 adjust_str (st,p,key,maxlen,col,row) ;
  611.                 gotoxy (col,row)
  612.               end ;
  613.             keyin (ch) ;
  614.             key := ord(ch) ;
  615.             if key = $2D  then                      { minus sign }
  616.               begin
  617.                 if  (pos('-',st) = 0)
  618.                 and (p = 0)
  619.                 and (  (    (posdec = 0)
  620.                         and (llen < maxl - 1)
  621.                        )
  622.                     or (    (not (posdec = 0))
  623.                         and (llen < maxl)
  624.                        )
  625.                     ) then
  626.  
  627.                     add_to_str
  628.  
  629.               end
  630.             else if key in [$2E, $30 .. $39] then   { decimal point, numeric digits }
  631.                 add_to_str
  632.             else if key in adjusting then
  633.                 adjust_str (st,p,key,maxlen,col,row)
  634.             else if key in terminating then
  635.                 do_fld_ctl (key) ;
  636.         until key in terminating ;
  637.  
  638.                               {Done getting input, now convert back to real}
  639.  
  640.         if (st = '')                             {If null string ... }
  641.         or (st = '.')
  642.         or (st = '-')
  643.         or (st = '-.') then
  644.             begin
  645.                 r := 0.0 ;                       {Make real zero}
  646.                 code := 0
  647.             end
  648.         else    {Not a null string}
  649.                 val (st, r, code) ;              {Make string into real}
  650.         gotoxy (col, row) ;
  651.         if code = 0 then  {Conversion worked OK}
  652.                 write (r:maxlen:frac)            {Write the real on screen}
  653.         else
  654.             begin
  655.                 write ('** conversion error ', code) ;
  656.                 halt
  657.             end
  658. end ; {--- of read_real ---}
  659.  
  660. { -------------------------------------------------------------------------- }
  661.  
  662. procedure read_yn (var bool:boolean; col,row:integer) ;
  663.   { Inputs "Y" OR "N" to boolean at column and row specified,
  664.     prints "YES" or "NO."
  665.  
  666.     Note -- use this when the screen control will not return
  667.     to the question and the boolean IS NOT defined before the
  668.     user answers the question.  Does not affect global FLD. }
  669.  
  670.     var ch:char ;
  671.     begin
  672.         gotoxy (col,row) ;
  673.         write ('   ') ;
  674.         gotoxy (col,row) ;
  675.         repeat
  676.                 keyin (ch)
  677.         until (ch in ['Y', 'y', 'N', 'n']) ;
  678.         if (ch = 'Y') or (ch = 'y') then
  679.             begin
  680.                 write ('YES') ;
  681.                 bool := true
  682.             end
  683.         else
  684.             begin
  685.                 write ('NO ') ;
  686.                 bool := false
  687.             end
  688.     end ; { proc read_yn }
  689.  
  690. { ------------------------------------------------------------ }
  691.  
  692. procedure read_bool (var bool:boolean; col,row:integer) ;
  693.   { Displays boolean at column and row specified, inputs "Y"
  694.     or "N" to set new value of boolean, prints "YES" or "NO."
  695.     Boolean is "forced;" user cannot cursor forward past undefined
  696.     boolean.  Pressing "Y" or "N" terminates entry.
  697.  
  698.     Boolean is stored as one byte:
  699.         $80 = undefined
  700.         $01 = true
  701.         $00 = false.
  702.     Note : Turbo interprets $80 as true because it is greater than zero! }
  703.  
  704.     var
  705.         ch  : char ;
  706.         key : integer ;
  707.  
  708.     begin
  709.         write_bool (bool, col, row) ;
  710.         gotoxy (col, row) ;
  711.         repeat
  712.             keyin (ch) ;
  713.             key := ord(ch) ;
  714.             if key in [$59,$79] then          { 'Y','y' }
  715.               begin
  716.                 bool := true ;
  717.                 key  := next_fld ;
  718.                 do_fld_ctl(key)
  719.               end
  720.             else if key in [$4E, $6E] then    { 'N','n' }
  721.               begin
  722.                 bool := false ;
  723.                 key  := next_fld ;
  724.                 do_fld_ctl(key)
  725.               end
  726.             else if key in terminating then
  727.               begin
  728.                 if  (not defined(bool))
  729.                 and (key in [carr_rtn, next_fld, next_page]) then
  730.                     key := $00
  731.                 else
  732.                     do_fld_ctl (key)
  733.               end
  734.         until key in terminating ;
  735.         write_bool (bool, col, row)
  736.     end ; {--- of read_bool ---}
  737.  
  738. { -------------------------------------------------------------------------- }
  739.  
  740. procedure pause ;
  741.     {Prints message on bottom line, waits for user response}
  742.     var
  743.         ch   : char ;
  744.         key : integer ;
  745.     begin
  746.         clrline (1,24) ;
  747.         write_str ('PRESS SPACE BAR TO CONTINUE OR UP-ARROW TO GO BACK',14,24) ;
  748.         repeat
  749.                 keyin (ch) ;
  750.                 key := ord(ch) ;
  751.                 case key of
  752.                   $20      : fld := succ(fld) ;
  753.                   prev_fld : fld := pred(fld) ;
  754.                   prev_page : fld := -999 ;
  755.                   escape   : fld := maxint ;
  756.                 end ;
  757.         until key in [$20, prev_fld, prev_page, escape] ;
  758.         clrline (1,24)
  759.     end ; { proc pause }
  760.  
  761. { ------------------------------------------------------------ }
  762.  
  763. procedure hard_pause ;
  764.   { Like Pause, but only accepts space bar or Escape and only goes forward }
  765.     var
  766.         ch   : char ;
  767.         key : integer ;
  768.     begin
  769.         clrline (1,24) ;
  770.         write_str ('PRESS SPACE BAR TO CONTINUE',26,24) ;
  771.         repeat
  772.                 keyin (ch) ;
  773.                 key := ord(ch) ;
  774.                 case key of
  775.                   $20      : fld := succ(fld) ;
  776.                   escape   : fld := maxint ;
  777.                 end ;
  778.         until key in [$20, escape] ;
  779.         clrline (1,24)
  780.     end ; { proc hard_pause }
  781.  
  782. { ------------------------------------------------------------ }
  783.  
  784. procedure show_msg (msg : str_type) ;
  785.   { Beeps, displays message centered on line 23, pauses }
  786.  
  787.     var
  788.         savefld : integer ;
  789.  
  790.     begin
  791.         savefld := fld ;
  792.         beep ;
  793.         clrline (1,23) ;
  794.         write_str (msg,((80-length(msg)) div 2),23) ;
  795.         hard_pause ;
  796.         clrline (1,23) ;
  797.         fld := savefld ;
  798.     end ; { proc show_msg }
  799.  
  800. { ----- EOF IO22.INC ----------------------------------------- }
  801.