How do I read extended scan codes? 
Author Message
 How do I read extended scan codes?

Quote:

> How can I read an extended keyboard scan code? What I mean is: how
> can I check if something like 'F1' is pressed?

> Here's what I tried:

> {***********}
> S := String;

> Begin
>   Repeat
>     S := Crt.ReadKey;
>   Until S = Chr(59);  {59 is the extended code for 'F1'}
> End.
> {***********}

> This works, except for the inconvenient fact that Chr(59) is also
> the semicolon (;) character. How do I read F1 without reading a ';'
> ?

This is a FAQ, and is probably covered in Timo's TP FAQ:

ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip

In short, extended characters send two codes to the keyboard buffer.  F1
is actually #0;#59, not just #59.  Check for the #0 first.

Quote:
> --
> Nestor Custodio



--
Scott Earnest        | We now return you to our regularly |



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

How can I read an extended keyboard scan code? What I mean is: how
can I check if something like 'F1' is pressed?

Here's what I tried:

{***********}
S := String;

Begin
  Repeat
    S := Crt.ReadKey;
  Until S = Chr(59);  {59 is the extended code for 'F1'}
End.
{***********}

This works, except for the inconvenient fact that Chr(59) is also
the semicolon (;) character. How do I read F1 without reading a ';'
?

--
Nestor Custodio




Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

Quote:

> How can I read an extended keyboard scan code? What I mean is: how
> can I check if something like 'F1' is pressed?

> Here's what I tried:

> {***********}
> S := String;

> Begin
>   Repeat
>     S := Crt.ReadKey;
>   Until S = Chr(59);  {59 is the extended code for 'F1'}
> End.
> {***********}

> This works, except for the inconvenient fact that Chr(59) is also
> the semicolon (;) character. How do I read F1 without reading a ';'
> ?

> --
> Nestor Custodio



Hi Nestor,

Extended keyboard scan codes (IE function keys) are always preceeded by a null
byte Chr(0) and then the extended keyboard code.  For example, you want to
trap the 'F1' key.  The extended keyboard scan code for 'F1' is 00,59 in
decimal. So scan for keyboard input.  If you see normal keyboard scan codes,
either process or ignore them. However, when you see a null byte you know that
an extended keyboard scancode is coming in the next byte.  That is how you do
it.

Hope this helps.

Best Regards,
Scott McIntyre

======================================================================

  11400 ROBINWOOD DRIVE                PHONE: 301-790-2800 x327
  HAGERSTOWN MD 21742-6590 USA           FAX: 301-739-0737
======================================================================
              Home Page: http://www.western-md.com/hjc/
======================================================================



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

I think that extended codes return TWO characters.
The first is ascii nul (0h).
The second is the extended key code.

EG - F1 :-

repeat
   repeat
        {do blah blah bah do stuff in here if required}
   until keypressed = true;
   inkey:=readkey;
   if ord(inkey) = 0 then  {extended key code!}
   begin
      inkey = readkey;
      if ord(inkey) = 59 then
      begin
         { do f1 stuff that you want }
      end;
      inkey:=char(0); {set to null, so as to be ignored}
   end;
until inkey='Q'; { keep going until 'Q' for quit }

----------
Che Rowley



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

Each of the keys has a scan code that is stored in one word of data.
the high byte is the ASCII byte and the low one the extended byte. If
the character is one of the 256 ASCII characters then it's code is
stored in the ASCII byte and the extended is left as 0 or undefined.
Alternatively if the key is a "special" key eg PgUp the ascii byte is
0 and the extended byte is set (in this case to 73).

When you strike a key or keys the words are stored in the circular 32
byte keyboard buffer (located at $0040:$001E) and the characters are
read from there one word at a time.
The characters are stored first come first served and overwrite the
previous contents in a sort of queue. The start of the queue is
pointed to by the head which is at $0040:$001A and the tail at
[$0040:$001C] points to the next open slot. The head and tail are not
part of the queue itself but the bytes in these positions have values
from $1E to $3C indicating the offsets they reference.The tail just
keeps incrementing until all 15 slots are filled and the buffer is
full. You get a beep from your pc if you try to enter more.
 Once at the end of the buffer, the tail wraps around and is reset to
the lowest location.

If the head and tail point to the same place the buffer is empty.

You can access the data in the buffer using the MEM array. So for
example the line

if keypressed then ......

is equivalent to

if Mem[$0040:$001A] <> Mem[$0040:$001C] then ...

If you want to be sure that you are reading the correct keystrokes you
can flush the buffer using one of these routines

Procedure Fbuffer;
var   MT:char;
begin
 while keypressed do MT:=readkey;
end;  {uses CRT rqd}

or just

procedure FBuffer;
begin
 Mem[$0040:$001A] := Mem[$0040:$001C];
end;  {head pointer := tailpointer}

Hope this Helps

Dave

On 28 Apr 1997 01:56:46 GMT, "Nestor Custodio"

Quote:

>How can I read an extended keyboard scan code? What I mean is: how
>can I check if something like 'F1' is pressed?

>Here's what I tried:

>{***********}
>S := String;

>Begin
>  Repeat
>    S := Crt.ReadKey;
>  Until S = Chr(59);  {59 is the extended code for 'F1'}
>End.
>{***********}

>This works, except for the inconvenient fact that Chr(59) is also
>the semicolon (;) character. How do I read F1 without reading a ';'
>?

>--
>Nestor Custodio





Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

{Run this.}
Program TESTKEY; {identifies the ASCII value of keys}
uses crt;

var c : char;

begin
      writeln('Press some keys (ESC to quit).');
   repeat
      c := readkey;
      if c = #0 then c := readkey;{}
      writeln('you pressed ',c, ' whose ASCII value is ',ord(c),'.');
   until c = #27;
   writeln(' Goodbye!');
end.

Stephen Wright



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?



Quote:
> {Run this.}
> Program TESTKEY; {identifies the ASCII value of keys}
> uses crt;

> var c : char;

> begin
>       writeln('Press some keys (ESC to quit).');
>    repeat
>       c := readkey;
>       if c = #0 then c := readkey;{}

The other option is :
        c := readkey;
        if keypressed then c := readkey;
Quote:
>       writeln('you pressed ',c, ' whose ASCII value is ',ord(c),'.');
>    until c = #27;
>    writeln(' Goodbye!');
> end.

> Stephen Wright



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

Quote:



>> {Run this.}
>> Program TESTKEY; {identifies the ASCII value of keys}
>> uses crt;

>> var c : char;

>> begin
>>       writeln('Press some keys (ESC to quit).');
>>    repeat
>>       c := readkey;
>>       if c = #0 then c := readkey;{}

>The other option is :
>    c := readkey;
>    if keypressed then c := readkey;

Well Professor Zen, you're not shedding much enlightenment here.
If you are going to suggest alternative solutions you should at
least insure your method is equal to or better than the previous
post.  

Your suggestion assumes that keys will never be entered faster
than the program is able to process,  If this were true then we
wouldn't need a type-ahead buffer to prevent characters from being
missed.  If keys are entered faster than your program can handle,
then you blindly discard every other key.

In addition to suggesting that we replace a good solution with one
that may fail under certain circumstances, you replace a simple
comparison of a variable with a constant with a less efficient
comparison of a variable with the result of a function call.  

    ...red



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?


Quote:

>{Run this.}
>Program TESTKEY; {identifies the ASCII value of keys}
>uses crt;

>var c : char;

>begin
>      writeln('Press some keys (ESC to quit).');
>   repeat
>      c := readkey;
>      if c = #0 then c := readkey;{}

Since it's possible for someone two just hold down the Alt button and press 0
on the numeric pad, I think it would be better to do this:

  if (c = #0) and (keypressed) then c:=readkey;

Quote:
>      writeln('you pressed ',c, ' whose ASCII value is ',ord(c),'.');
>   until c = #27;
>   writeln(' Goodbye!');
>end.

>Stephen Wright

--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
anti-Exon

"All animals are equal, but some are more equal than others."
   --The pigs from Animal Farm
"All speech is equal, but some is more equal than other."
   --paraphrazing Senator Exon


Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?


Quote:

>Since it's possible for someone two just hold down the Alt button and press 0
>on the numeric pad, I think it would be better to do this:

>  if (c = #0) and (keypressed) then c:=readkey;

It is indeed possible to perform those actions, but on my PC no
character is generated (tested in COPY CON F:Z / DEBUG F:Z).

Remember also that one may be typing ahead.
--

  Web URL: http://www.merlyn.demon.co.uk/ -- includes FAQqish topics and links.
  Correct 4-line sig separator is as above, a line comprising "-- " (SoRFC1036)
  Before a reply, quote with ">" / "> ", known to good news readers (SoRFC1036)



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

Surely:

Uses Crt;

Var Ch, Extended : Char;

Begin
      Ch:=Readkey;
If keypressed then Extended:=Readkey;
End.

Quote:
>  if (c = #0) and (keypressed) then c:=readkey;

>>      writeln('you pressed ',c, ' whose ASCII value is ',ord(c),'.');
>>   until c = #27;
>>   writeln(' Goodbye!');
>>end.



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?


Quote:

>Each of the keys has a scan code that is stored in one word of data.
>the high byte is the ASCII byte and the low one the extended byte. If
>the character is one of the 256 ASCII characters then it's code is
>stored in the ASCII byte and the extended is left as 0 or undefined.

The scan code is by no means undefined. It is however in most cases
ignored and IMO should be ignored unless necessary. (One might use the
scan code to tell the difference between numbers from the number row and
key pad for example)

Quote:
>Alternatively if the key is a "special" key eg PgUp the ascii byte is
>0 and the extended byte is set (in this case to 73).

The ASCII byte can also be 224. This is the way to tell the difference
between the grey function keys and the ones in the key pad. The standard
BIOS functions change the 224 to zero to hide the difference. They also
strip keys F11 and F12.

Quote:

>You can access the data in the buffer using the MEM array. So for
>example the line

>if keypressed then ......

>is equivalent to

>if Mem[$0040:$001A] <> Mem[$0040:$001C] then ...

That is incorrect. Keypressed can also be true if there is a scancode
in the one byte buffer internal to CRT unit.

Quote:
>If you want to be sure that you are reading the correct keystrokes you
>can flush the buffer using one of these routines

>Procedure Fbuffer;
>var   MT:char;
>begin
> while keypressed do MT:=readkey;
>end;  {uses CRT rqd}

>or just

>procedure FBuffer;
>begin
> Mem[$0040:$001A] := Mem[$0040:$001C];
>end;  {head pointer := tailpointer}

That does not work as it does not flush the internal buffer. Only
readkey can do that.

Osmo



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

[...]

Quote:
> >or just

> >procedure FBuffer;
> >begin
> > Mem[$0040:$001A] := Mem[$0040:$001C];
> >end;  {head pointer := tailpointer}

> That does not work as it does not flush the internal buffer. Only
> readkey can do that.

> Osmo

Who cares if the CRT internal buffer has anything in it?

I have been using a similar procedure for years with no problems. I
have no missing keystrokes, I get every key combination that can be
pressed, and never have any problems confusing desired ASCII characters
from cursor keys - even Alt and Ctrl combinations.

Just drop ReadKey and use kbhead and kbtail exclusively - all your
keyboard handling problems disappear!

MRM



Wed, 18 Jun 1902 08:00:00 GMT  
 How do I read extended scan codes?

Quote:


>[...]

>> >or just

>> >procedure FBuffer;
>> >begin
>> > Mem[$0040:$001A] := Mem[$0040:$001C];
>> >end;  {head pointer := tailpointer}

>> That does not work as it does not flush the internal buffer. Only
>> readkey can do that.

>> Osmo

>Who cares if the CRT internal buffer has anything in it?

Maybe you should care if you want your programs to work correctly in all
situations. Flushing the keyboard buffer that way can cause problems if
a function key has been only partially read. This could happen for
example if you write:

Writeln('Press a key');
readkey;
FBuffer;

Quote:
>I have been using a similar procedure for years with no problems. I
>have no missing keystrokes, I get every key combination that can be
>pressed, and never have any problems confusing desired ASCII characters
>from cursor keys - even Alt and Ctrl combinations.

>Just drop ReadKey and use kbhead and kbtail exclusively - all your
>keyboard handling problems disappear!

Of course if one wants to reinvent the wheel one can freely do so, but
at least use BIOS calls.

Quote:
>MRM

Osmo


Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Scan Code Conversion

2. Q: Keyboard Scan Codes as Hex.

3. Scan Code Conversion

4. help on keyboard scan codes

5. XT Scan Codes?

6. Scan codes

7. scan codes

8. Keyboard Scan Code Help needed!

9. Help on keyboard scan-code problem

10. (FPU) EXTENDED type read by C program

11. Need pascal code for doing matrix algebra

12. Need pascal code for doing matrix algebra

 

 
Powered by phpBB® Forum Software