home *** CD-ROM | disk | FTP | other *** search
- { IO20.INC -- Global I/O procedures to include in programs generally
- Version 2.0 includes prev_page and next_page, changes where pause text
- is displayed -- WPM -- 2/26/86 }
-
- { ------------------------------------------------------------ }
-
- const
- prev_fld = $0b ; { ^K -- up_arrow on Kaypro II '83 }
- next_fld = $0a ; { ^J -- linefeed, down_arrow }
- backspace = $08 ; { ^H -- Backspace key }
- del_fld = $19 ; { ^Y }
- prev_page = $12 ; { ^R }
- next_page = $03 ; { ^C }
- escape = $1b ;
- carr_rtn = $0d ;
- del = $7f ;
- filler = $2e ; { . }
-
- type
- str_type = string[80] ;
-
- intset = set of $00 .. $ff ;
-
- const { Turbo typed constants -- initialized variables }
- terminating : intset = [carr_rtn, next_fld, prev_fld, next_page,
- prev_page, escape] ;
- adjusting : intset = [backspace, del_fld, del] ;
-
- var
- fld, scrn : integer ; {For field & screen cursor control}
-
- { ------------------------------------------------------------ }
-
- { procedure gotoxy (col,row) ; -- Built-in proc in Turbo to place
- cursor on screen. Upper left is (1,1) not (0,0)! }
-
- { procedure clrscr ; -- Built-in proc in Turbo to clear screen. }
-
- { procedure clreol ; -- built-in proc in Turbo to clear to end of line }
-
- { ------------------------------------------------------------ }
-
- procedure clrline (col,row : integer) ;
- begin
- gotoxy (col,row) ;
- clreol
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure clreos ;
- begin
- write (chr($17)) {Clear to end of screen on Kaypro & ADM-3A}
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure beep ;
- begin
- write (chr(7))
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure do_fld_ctl (key : integer) ;
- { Adjusts global FLD based on value of key, the ordinal value of last key pressed }
- { global
- fld : integer -- for field cursor control }
- begin
- case key of
- carr_rtn, next_fld : fld := fld + 1 ;
- prev_fld : fld := fld - 1 ;
- next_page : fld := 999 ;
- prev_page : fld := -999 ;
- escape : fld := maxint ; { NOTE -- different from MT+ }
- end { case }
- end ; { proc do_fld_ctl }
-
- { ------------------------------------------------------------ }
-
- procedure do_scrn_ctl ;
- { Checks value of FLD and adjusts value of SCRN accordingly }
- { Global
- fld, scrn : integer -- For field and screen cursor control }
- begin
- if fld < 1 then
- scrn := scrn - 1
- else if fld = maxint then
- scrn := maxint
- else
- scrn := scrn + 1
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure write_str (st:str_type ; col,row:integer) ;
- begin
- gotoxy (col,row) ;
- write (st)
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure write_int (int:integer ; width,col,row:integer) ;
- begin
- gotoxy (col,row) ;
- write (int:width)
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure write_bool (bool:boolean ; col, row:integer) ;
- begin
- gotoxy (col,row) ;
- if bool then write ('YES') else write ('NO ')
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure write_real (r:real ; width,frac,col,row:integer) ;
- begin
- gotoxy (col,row) ;
- write (r:width:frac)
- end ;
-
- { ------------------------------------------------------------ }
-
- { This is for Kaypro CP/M -- comment it out to use IBM }
-
- procedure keyin (var ch:char) ;
- { Reads a single character from keyboard without echoing it back.
- Modified to trap WordStar commands, 4/29/85 }
- begin
- read (kbd, ch) ;
- if ch = ^S then
- ch := chr(backspace)
- else if ch = ^E then
- ch := chr(prev_fld)
- else if ch = ^X then
- ch := chr(next_fld)
- end ;
-
- { ------------------------------------------------------------ }
-
- { This is for IBM PC-DOS -- comment it out for CP/M }
- (*
- procedure keyin (var ch:char) ;
- { Reads a single character from keyboard without echoing it back.
- Maps function key scan codes to single keyboard keys.
- Modified for IBM -- from Turbo 3.0 manual, page 360 -- 5/29/85
- Modified for IO20 -- 2/26/86 }
-
- var
- func : boolean ; { Whether function key or not }
- c : char ; { Character read }
- key : integer ; { ORD of character returned }
-
- begin
- func := false ;
- read (kbd,c) ; { Get first char }
- if (ord(c) = escape) { If there is }
- and keypressed then { a second ... }
- begin
- read (kbd,c) ; { Get 2nd char }
- func := true
- end ;
- key := ord(c) ;
-
- if func then { Translate func. keys }
- case key of
- 61,72 : key := prev_fld ; { F3, up-arrow }
- 62,80 : key := next_fld ; { F4, down-arrow }
- 65,73 : key := prev_page ; { F7, PgUp }
- 66,81 : key := next_page ; { F8, PgDn }
- 59,83,75 : key := backspace ; { F1, DEL, left-arrow }
- 60 : key := del_fld ; { F2 }
- else key := 00 ;
- end { case }
- else { not a function key }
- case key of
- $13 : key := backspace ; { ^S -- Like WordStar }
- $05 : key := prev_fld ; { ^E }
- $18 : key := next_fld ; { ^X }
- end ; { case }
-
- ch := chr(key) { finally, return the character }
- end ;
- *)
- { ------------------------------------------------------------ }
-
- function purgech (instr : str_type ; inchar : char) : str_type ;
- {Purges all instances of the character from the string}
- var
- n : integer ; {Loop counter}
- outstr : str_type ; {Result string}
-
- begin
- outstr := '' ;
- for n := 1 to length (instr) do
- if not (instr[n] = inchar) then
- outstr := concat (outstr, instr[n]) ;
- purgech := outstr
- end ;
-
- { ------------------------------------------------------------ }
-
- function stripch (instr:str_type ; inchar:char) : str_type ;
- {Strips leading instances of the character from the string}
- begin
- while not (length(instr) = 0)
- and (instr[1] = inchar) do
- delete (instr, 1, 1) ;
- stripch := instr
- end ;
-
- { ------------------------------------------------------------ }
-
- function chopch (instr:str_type ; inchar:char) : str_type ;
- {Chops trailing instances of the character from the string}
- begin
- while not (length(instr) = 0)
- and (instr[length(instr)] = inchar) do
- delete (instr, length(instr), 1) ;
- chopch := instr
- end ;
-
- { ------------------------------------------------------------ }
-
- procedure adjust_str (var st : str_type ; key, maxlen, col, row : integer ) ;
- { deletes a character or the whole entry }
- var
- i : integer ;
- begin
- case key of
- del_fld : begin
- st := '' ;
- gotoxy (col, row) ;
- for i := 1 to maxlen do
- write (chr(filler)) ;
- gotoxy (col, row)
- end ;
- backspace,
- del : if length(st) = 0 then
- beep
- else
- begin
- write (chr(backspace), chr(filler), chr(backspace)) ;
- delete (st, length(st), 1)
- end
- end { case }
- end ; { proc adjust_str }
-
- { ------------------------------------------------------------ }
-
- procedure read_str (var st:str_type ; maxlen, col, row:integer) ;
-
- { Read String. This procedure gets input from the keyboard one
- character at a time and edits on the fly, rejecting invalid
- characters. COL and ROW tell where to begin the data input
- field, and MAXLEN is the maximum length of the string to be
- returned. }
-
- var
- ch : char ;
- i,key : integer ;
-
- procedure add_to_str ;
- begin
- if length(st) = maxlen then
- beep
- else
- begin
- st := concat(st, ch) ; {concatenate char. onto str.}
- write (ch)
- end
- end ; {--- of ADD_TO_STR---}
-
- begin {--- READ_STR ---}
- write_str (st, col, row) ;
- for i := (length(st)+1) to maxlen do
- write (chr(filler)) ;
- gotoxy ((col + length(st)), row) ;
- repeat
- keyin (ch) ;
- key := ord(ch) ;
- if key in [$20 .. $7e] then
- add_to_str
- else if key in adjusting then
- adjust_str (st,key,maxlen,col,row)
- else if key in terminating then
- do_fld_ctl (key)
- else
- beep ;
- until key in terminating ;
- write ('':maxlen - length(st))
- end ; {--- of READ_STR ---}
-
- { ------------------------------------------------------------ }
-
- procedure read_int (var int:integer ; maxlen, col, row:integer) ;
-
- { Read Integer. This procedure gets input from the keyboard
- one character at a time and edits on the fly, rejecting
- invalid characters. COL and ROW tell where to begin the data
- input field, and MAXLEN is the maximum length of the integer
- to be returned. }
-
- var
- ch : char ;
- i,key : integer ;
- st : string[5] ;
- maxst : string[5] ;
- code : integer ;
-
- procedure add_to_str ;
- begin
- if length(st) = maxlen then
- beep
- else
- begin
- st := concat(st, ch) ; {concatenate char. onto str.}
- write (ch)
- end
- end ; {--- of ADD_TO_STR---}
-
- begin {--- READ_INT ---}
- str (maxint:5, maxst) ; {Make integer into string}
- str (int:maxlen, st) ;
- st := purgech (st, ' ') ;
- st := stripch (st, '0') ;
- write_str (st, col, row) ;
- for i := (length(st)+1) to maxlen do
- write (chr(filler)) ;
- gotoxy ((col + length(st)), row) ;
- repeat
- keyin (ch) ;
- key := ord(ch) ;
- if key = $2d then { minus sign }
- begin
- if length(st) = 0 then
- add_to_str
- end
- else if key in [$30 .. $39] then {digits 0 - 9}
- begin
- add_to_str ;
- if (length(st) = 5)
- and (st > maxst) then
- adjust_str (st,del,maxlen,col,row)
- end
- else if key in adjusting then
- adjust_str (st,key,maxlen,col,row)
- else if key in terminating then
- do_fld_ctl (key)
- else
- beep ;
- until key in terminating ;
-
- if st = '' then
- begin
- int := 0 ;
- code := 0
- end
- else
- val (st, int, code) ; {Make string into integer}
- gotoxy (col, row) ;
- if code = 0 then {Conversion worked OK}
- write (int:maxlen)
- else
- begin
- write ('** CONVERSION ERROR ', code) ;
- halt
- end
- end ; {--- of READ_INT ---}
-
- { ------------------------------------------------------------ }
-
- function equal (r1,r2 : real) : boolean ;
- { tests functional equality of two real numbers -- 4/30/85 }
- begin
- equal := abs(r1 - r2) < 1.0e-5
- end ; { function equal }
-
- { ------------------------------------------------------------ }
-
- function greater (r1,r2 : real) : boolean ;
- { tests functional inequality of two real numbers -- 5/1/85 }
- begin
- greater := (r1 - r2) > 1.0e-5
- end ; { function greater }
-
- { ------------------------------------------------------------ }
-
- procedure read_real (var r:real ; maxlen,frac,col,row:integer) ;
-
- { Read Real. This procedure gets input from the keyboard
- one character at a time and edits on the fly, rejecting
- invalid characters. COL and ROW tell where to begin the data
- input field; MAXLEN is the maximum length of the string
- representation of the real number, including sign and decimal
- point; FRAC is the fractional part, the number of digits to
- right of the decimal point.
-
- Note -- In TURBO the maximum number of significant digits in
- decimal (not scientific) representation is 11. It is the
- programmer's responsibility to limit input and computed output
- to 11 significant digits. }
-
- var
- ch : char ; {Input character}
- i,key : integer ; {Loop control ; ORD of CH}
- st : string[13] ; {String representation of real number}
- code : integer ; {Result of VAL conversion}
- rlen : integer ; {Current length of ST to right of dec. pt.}
- llen : integer ; {Current length to left, including dec. pt.}
- maxl : integer ; {Max allowable to left, including dec. pt.}
-
- procedure compute_length ;
- begin
- if pos ('.', st) = 0 then { If no dec. pt. ... }
- begin
- llen := length(st) ; {the whole string is Left}
- rlen := 0 {and none is Right}
- end
- else {There is a decimal point ...}
- begin
- llen := pos ('.', st) ; {Left is all up to dec. pt.}
- rlen := length(st) - llen {Right is the rest}
- end
- end ; { proc compute_length }
-
- procedure add_to_str ;
- procedure add_it ;
- begin
- st := concat(st, ch) ;
- write (ch)
- end ;
- begin {ADD_TO_STR}
- if ch = '.' then { Decimal point: if not one already, add it }
- begin
- if pos('.', st) = 0 then
- add_it
- else
- beep
- end
- { else it's not a decimal point }
- else if pos('.',st) = 0 then
- { There's no dec pt in string, so digit goes on left. }
- begin
- if llen = (maxl - 1) then
- beep { Only a dec pt is allowed in pos MAXL }
- else
- add_it
- end
- else { There is a dec pt in string, so digit goes on right }
- begin
- if rlen = frac then
- beep
- else
- add_it
- end
- end ; {--- of ADD_TO_STR---}
-
- begin {--- READ_REAL ---}
- {Initialize}
- maxl := maxlen - frac ;
- {Set up string representation of real and }
- {determine length of left & right portions}
- str(r:maxlen:frac,st) ; {Make real into string}
- st := purgech (st, ' ') ; {Purge all blanks}
- st := stripch (st, '0') ; {Strip leading zeroes}
- if not (pos('.', st) = 0) then {If there is a dec. pt ... }
- begin
- st := chopch (st, '0') ; {Chop trailing zeroes}
- st := chopch (st, '.') {and trailing dec. pt.}
- end ;
-
- {Write string on console}
- write_str (st, col, row) ;
- for i := (length(st)+1) to maxlen do
- write (chr(filler)) ;
- gotoxy ((col + length(st)), row) ;
-
- {Get input a character at a time & edit it}
- repeat
- compute_length ;
- keyin (ch) ;
- key := ord(ch) ;
- if ch = '-' then
- begin
- if length(st) = 0 then
- add_to_str
- else
- beep
- end
- else if (ch = '.')
- or (ch in ['0' .. '9']) then
- add_to_str
- else if key in adjusting then
- adjust_str (st,key,maxlen,col,row)
- else if key in terminating then
- do_fld_ctl (key)
- else
- beep
- until key in terminating ;
-
- {Done getting input, now convert back to real}
- if (st = '') {If null string ... }
- or (st = '.')
- or (st = '-')
- or (st = '-.') then
- begin
- r := 0.0 ; {Make real zero}
- code := 0
- end
- else {Not a null string}
- val (st, r, code) ; {Make string into real}
- gotoxy (col, row) ;
- if code = 0 then {Conversion worked OK}
- write (r:maxlen:frac) {Write the real on screen}
- else
- begin
- write ('** CONVERSION ERROR ', code) ;
- halt
- end
- end ; {--- of READ_REAL ---}
-
- { ------------------------------------------------------------ }
-
- procedure read_yn (var bool:boolean; col,row:integer) ;
- { Inputs "Y" OR "N" to boolean at column and row specified,
- prints "YES" or "NO."
-
- Note -- use this when the screen control will not return
- to the question and the boolean IS NOT defined before the
- user answers the question. }
-
- var ch:char ;
- begin
- gotoxy (col,row) ;
- write (' ') ;
- gotoxy (col,row) ;
- repeat
- keyin (ch)
- until (ch in ['Y', 'y', 'N', 'n']) ;
- if (ch = 'Y') or (ch = 'y') then
- begin
- write ('YES') ;
- bool := true
- end
- else
- begin
- write ('NO ') ;
- bool := false
- end
- end ; {--- of READ_YN ---}
-
- { ------------------------------------------------------------ }
-
- procedure read_bool (var bool:boolean; col,row:integer) ;
- { Displays boolean at column and row specified, inputs "Y"
- or "N" to set new value of boolean, prints "YES" or "NO."
-
- Note -- use this when the screen control may return to the
- question and the boolean IS defined before the user answers
- the question. }
-
- var
- ch : char ;
- key : integer ;
-
- begin
- write_bool (bool, col, row) ;
- gotoxy (col, row) ;
- repeat
- keyin (ch) ;
- key := ord(ch) ;
- if key in [$59, $79] then { 'Y', 'y' }
- begin
- bool := true ;
- key := next_fld ;
- do_fld_ctl(key)
- end
- else if key in [$4e, $6e] then { 'N', 'n' }
- begin
- bool := false ;
- key := next_fld ;
- do_fld_ctl(key)
- end
- else if key in terminating then
- do_fld_ctl(key)
- else
- beep ;
- until key in terminating ;
- write_bool (bool, col, row)
- end ; {--- of READ_BOOL ---}
-
- { ------------------------------------------------------------ }
-
- procedure pause ;
- {Prints message on bottom line, waits for user response}
- var
- ch : char ;
- key : integer ;
- begin
- clrline (1,24) ;
- write_str ('PRESS SPACE BAR TO CONTINUE OR UP-ARROW TO GO BACK',14,24) ;
- repeat
- keyin (ch) ;
- key := ord(ch) ;
- case key of
- $20 : fld := fld + 1 ;
- prev_fld : fld := fld - 1 ;
- prev_page : fld := -999 ;
- escape : fld := maxint ;
- end ;
- until key in [$20, prev_fld, prev_page, escape] ;
- clrline (1,24)
- end ; {--- of PAUSE ---}
-
- { ------------------------------------------------------------ }
-
- procedure hard_pause ;
- { Like Pause, but only accepts space bar or Escape and only goes forward }
- var
- ch : char ;
- key : integer ;
- begin
- clrline (1,24) ;
- write_str ('PRESS SPACE BAR TO CONTINUE',26,24) ;
- repeat
- keyin (ch) ;
- key := ord(ch) ;
- case key of
- $20 : fld := fld + 1 ;
- escape : fld := maxint ;
- end ;
- until key in [$20, escape] ;
- clrline (1,24)
- end ; {--- of hard_pause ---}
-
- { ------------------------------------------------------------ }
-
- procedure show_msg (msg : str_type) ;
- { Beeps, displays message centered on line 23, pauses }
-
- var
- savefld : integer ;
-
- begin
- savefld := fld ;
- beep ;
- clrline (1,23) ;
- write_str (msg,((80-length(msg)) div 2),23) ;
- hard_pause ;
- clrline (1,23) ;
- fld := savefld ;
- end ; { --- of SHOW_MSG --- }
-
- { ----- EOF IO20.INC ----------------------------------------- }
- e and only goes forward }
-