[comp.lang.pascal] Readkey without "use crt"

yubing@vax.cs.pitt.edu (Bing Yu) (11/16/89)

In article <79164@linus.UUCP: carlson@gateway.mitre.org (Bruce Carlson) writes:
:In article <1261@rodan.acs.syr.edu> wwtaroli@rodan.acs.syr.edu (Bill Taroli) writes:
:>I believe this may have been discussed before, but I need this information
:>in a hurry.  Is anyone aware of a function in TP that will allow one to 
:>strobe the keyboard... or basically check the queue to see if a key is 
:>waiting to be read?
:>Bill Taroli
:>WWTAROLI@RODAN.acs.syr.edu
:
:The function KeyPressed (boolean) determines if a key has been pressed.  It
:is nondestructive, so the value is still in the keyboard buffer.
:It does not detect the 'shift' keys like Alt, Shift, Numlock, etc.
:
:The function ReadKey reads the value in the keyboard buffer, and you can
:then assign this value to one of your variables.  If it is a special 
:key (function key, etc.) that generates an extended scan code it will
:have two bytes.  The first is #0 and the second is the extended scan code.
:The extended scan code keys therefore require two executions of ReadKey.
:
:Bruce Carlson

I have a problem similar to this: I want to have a function same as
Readkey but do NOT want to "use crt".  The reason for this is that
I want to force the crt i/o go through dos so that it can be handled
by a driver similar to ansi.sys.  I tried read(input,c) but have to
press RETURN after the key is pressed.  Does anyone know how to make it
work?  Thanks.

Bing Yu
yubing@vax.cs.pitt.edu

jrwsnsr@nmtsun.nmt.edu (Jonathan R. Watts) (11/17/89)

In article <6233@pitt.UUCP>, yubing@vax.cs.pitt.edu (Bing Yu) writes:
> I have a problem similar to this: I want to have a function same as
> Readkey but do NOT want to "use crt".  The reason for this is that
> I want to force the crt i/o go through dos so that it can be handled
> by a driver similar to ansi.sys.  I tried read(input,c) but have to
> press RETURN after the key is pressed.  Does anyone know how to make it
> work?  Thanks.

It is possible to "use crt" and still have the output go through DOS.  I don't
remember the exact procedure (something like re-opening input and output),
but it is in the manual somewhere!

  - Jonathan Watts

jrwsnsr@jupiter.nmt.edu

taylorj@yvax.byu.edu (11/21/89)

There are two solutions to this problem:

1) Use CRT but make the I/O go through DOS.  All you have to do is add the
lines
  Assign(input, ''); reset(input);
  Assgign(output, ''); rewrite(output);
to the start of your program.  (TP 5.0 manual p.135)

2) Go directly to DOS or BIOS to read a key.
To read a key using DOS, you'll need something like
  var
    regs :registers;

  regs.ah := 8;
  msdos(regs);
  if regs.al = 0 then begin
    msdos(regs);
    {do whatever you want to recognize extended key codes}
  end;
  key = regs.al;

This can be redirected, so if you want to always read from the keyboard you
might want to use BIOS instead:

  regs.ah = 1;
  intr($16, regs);
  if regs.al > 0 then key := regs.al
  else begin
    key := regs.ah;
    {do whatever to recognize extended key codes}
  end;

Both of these wait until a character is pressed.  There are other calls to
check to see if a key has been pressed.


Jim Taylor
Microcomputer Support for Curriculum
Brigham Young University
taylorj@yvax.byu.edu

ts@uwasa.fi (Timo Salmi LASK) (11/23/89)

In article <922taylorj@yvax.byu.edu> taylorj@yvax.byu.edu writes:
>There are two solutions to this problem:
>1) Use CRT but make the I/O go through DOS.  All you have to do is add the
>lines
>  Assign(input, ''); reset(input);
.... stuff deleted ...

Right.  But some incompatible PCs work better still if the Crt unit
is omitted altogether, so your solution below might be preferable. 

>2) Go directly to DOS or BIOS to read a key.
>To read a key using DOS, you'll need something like
>  var
>    regs :registers;
>  regs.ah := 8;
.... stuff deleted ...

Right.  And for those interested in the subject there is more
information in Ezzel, Programming the IBM User Interface. 

...................................................................
Prof. Timo Salmi                                (Site 128.214.12.3)
School of Business Studies, University of Vaasa, SF-65101, Finland
Internet: ts@chyde.uwasa.fi Funet: vakk::salmi Bitnet: salmi@finfun

LAUFMAN-H@osu-20.ircc.ohio-state.edu (Harry Laufman) (11/23/89)

KeyBoard reading without Unit CRT.
I have used FUNCTION KEYHIT instead of KEYPRESSED for quite awhile
now since it is demonstrably faster.  On reading the "Readkey without
Unit CRT" query, it seemed it could be done by reading memory directly
with the Turbo Mem and MemW (byte and word based) arrays.  With the
help of the cited manual I pieced together a Turbo 5.5 compiled code
which seems to work OK.  I did find I had to re-assign the keyboard
buffer head address to the keyboard buffer tail address.  Apparently
the Turbo call to ReadKey does this.
Good Luck, Harry LAUFMAN-H@osu-20.ircc.ohio-state.edu
Reference and source code follow:
--------------------------------------------------------------------------
                        DOS TECHNICAL INFORMATION
 Programming Technical Reference - IBM
 Copyright 1988, Dave Williams  { found a DOSTECH.ZIP on many BBSs }
 { many lines omitted }
                   Reserved Memory Locations in the IBM PC
 
addr.  size            description
 { many lines omitted }
40:17  byte    keyboard flag byte 0 (see int 9h)
               bit 7  insert mode on      3  alt pressed
                   6  capslock on         2  ctrl pressed
                   5  numlock on          1  left shift pressed
                   4  scrollock on        0  right shift pressed
40:18  byte    keyboard flag byte 1 (see int 9h)
               bit 7  insert pressed      3  ctrl-numlock (pause) toggled
                   6  capslock pressed    2  PCjr keyboard click active
                   5  numlock pressed     1  PCjr ctrl-alt-capslock held
                   4  scrollock pressed   0
40:19  byte    storage for alternate keypad entry (not normally used)
40:1A  word    pointer to keyboard buffer head character
40:1C  word    pointer to keyboard buffer tail character
40:1E  32bytes 16 2-byte entries for keyboard circular buffer, read by int 16h
{ many lines omitted }
-----------------------------------------------------------------------------
program readmem;
{** This could certainly be tersed up with lose of clarity **}
var
    Address : Word;
    AChar   : Char;
 
Function KeyHit:Boolean;
begin KeyHit := Mem[$0040:$001A] <> Mem[$0040:$001C] end;
                { Kbd Buffer Head <> Kbd Buffer Tail }
begin
Writeln('*** Begin ***');
Achar := 'a';
 
Repeat
If Keyhit then
   begin
   Address := MemW[$0040:$001A];        { Where the Kbd Buffer Head is }
   AChar   := Chr(MemW[$0040:Address]); { What it is }
   Mem[$0040:$001A] := Mem[$0040:$001C];{ Set Head = Tail }
   writeln(AChar);                      { See what we got }
   end;
Until AChar = 'x';                      { A way out }
 
 
Writeln('*** End ***');
readln;                                 { Wait for <Enter> }
end.