[comp.lang.pascal] VAX readkey

bobb@vice.ICO.TEK.COM (Bob Beauchaine) (11/20/90)

  What's the secret to reading single character input from the keyboard
  in VAX Pascal? W/O echo would be nice, but doing a readln(char) just
  doesn't cut it for a user interface.  Any ideas appreciated, even 
  programming system resources.  

  Bob Beauchaine
  bobb@vice.ICO.TEK.COM

phys169@canterbury.ac.nz (11/21/90)

In article <6337@vice.ICO.TEK.COM>, bobb@vice.ICO.TEK.COM (Bob Beauchaine) writes:
>   What's the secret to reading single character input from the keyboard
>   in VAX Pascal? 

(1) use:  Sys_Stat:=$Assign(DevNam:='SYS$COMMAND',chan:=Tt_Chan);
(2) then: Sys_Stat:=$QIOW(,Tt_Chan,
              IO$_ReadLblk + IO$M_NoEcho + IO$M_NoFiltr + IO$M_Escape,
              IOstat_Block,,,Buffer.Body,1,2,%REF Prompt,0 )
  
The demo below is hacked out of a longer program; I've left some bits in that
aren't needed for reading a keystroke, but could be interesting anyway.
The longer program implements Turbo-like graphics output routines to draw
graphics in Tektronics-compatible screens (e.g. Wyse 99GT), and first checks
to see what type of screen you have attached; if anyone wants the full source,
let me know. The following extracted demo *might have mistakes*; the original
didn't, but in chopping it down to a convenient size, I may have introduced
errors; still, it's good enough to see what sort of thing is involved.

[INHERIT ('SYS$LIBRARY:STARLET','SYS$LIBRARY:PASCAL$LIB_ROUTINES')]
program Demo(input,output);

{author: M.Aitchison}
{date:   Oct 1990}

type
    Word_Integer = [WORD] 0..65535;     {for compatibility with Turbo Pascal}
            byte = [BYTE] 0..255;       {ditto}
          string = varying[255] of char;{ditto}

       IO_status = record IO_Stat,Count : Word_Integer; {used by QIOW}
			Device_Info   : integer;
			end;
      ModeBuffer = record TerminalClass,     {also used by QIOW, etc}
                          TerminalType : byte;
                          PageWidth : Word_Integer;
                          {PageLength : byte;}
                          BasicCharacteristics : integer;
                          ExtendedCharacteristics : unsigned;
                          end;
var 
    TTYP: packed array[1..30] of char; { name of terminal type}
    SStat : integer;
    CharacteristicsBuffer : ModeBuffer;
    buffer : varying[80] of char;
    TT_Chan : [volatile] Word_Integer;
    AST_Output : [volatile] text;
    IO_Func : Word_Integer;
    IOStat_Block: [Volatile] IO_Status;
    SYS_Stat : integer;

function ReadKey : char;
begin
buffer:=chr(0);

IO_Func:=IO$_ReadLblk + IO$M_NoEcho + IO$M_NoFiltr + IO$M_Escape;
if odd(Sys_Stat) 
   then Sys_Stat:=$QIOW(,Tt_Chan,IO_Func,IOstat_Block,,,Buffer.Body,1,2,
            ,%REF Prompt,0 )
   else write('Err=',sys_stat);
if not odd(Sys_Stat) 
	then TimedInput:=false
	else TimedInput:= (IOstat_Block.IO_stat = SS$_NORMAL);
end;

function TimedInput : boolean; {Reads 1 byte into Buffer.Body in <= 2 seconds,
                                or returns false}
begin
Buffer:='_';
(* this is in the main part of the program:
 Sys_Stat:=$Assign(DevNam:='SYS$COMMAND',chan:=Tt_Chan);
*)

IO_Func:=IO$_ReadLblk + IO$M_NoEcho + IO$M_Timed + IO$M_NoFiltr + IO$M_Escape;
if odd(Sys_Stat) 
   then Sys_Stat:=$QIOW(,Tt_Chan,IO_Func,IOstat_Block,,,Buffer.Body,1,2,
            ,%REF Prompt,0 )
   else write('Err=',sys_stat);
if not odd(Sys_Stat) 
	then TimedInput:=false
	else TimedInput:= (IOstat_Block.IO_stat = SS$_NORMAL);
end;


{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}
{{                                                          {}
{{        main prog.                                        {}
{{                                                          {}
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}

begin
{The following is required to let us to use QIOW for timed input}
Sys_Stat:=$Assign(DevNam:='SYS$COMMAND',chan:=Tt_Chan); {assign chan to term}
IO_Func:=IO$_SenseMode;
SStat:=$QIOW(,Tt_Chan,IO_Func,IOstat_Block,,,CharacteristicsBuffer,12, ,,,);

{stuff involving ReadKey and TimedInput}

(*You may even need the following, to writing bytes unbuffered to the screen 
open(screen,FILE_NAME:='SYS$OUTPUT',CARRIAGE_CONTROL:=NONE); 
rewrite(screen);
*)

end.