TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: David Noon
from: Murray Lesser
date: 1996-01-01 18:58:00
subject: Pl/i `Getch` Redux

Hi Dave,

    I have modified, slightly, the getch-equivalent subroutine I posted
last week to make it a function/subroutine procedure, optionally
returning a value: a two-byte string containing the character code and
scan code as found by KBD16CHARIN.  If you use this procedure as a
subroutine, it merely waits for any key to be pressed before returning,
thereby becoming the equivalent of the previous version.

    The source code for pligetch.pli (horrible name!) is as follows:

 pligetch: proc() options(linkage(pascal16)) returns(byaddr char(2));
   define alias UCHAR char;
   define alias USHORT fixed bin(16) unsigned;
   define alias ULONG fixed bin(31) signed;
   define structure
       1 KBDKEYINFO unaligned,
          2 chChar type UCHAR,
          2 chScan type UCHAR,
          2 fbStatus type UCHAR,
          2 bNlsShift type UCHAR,
          2 time type ULONG;
   dcl KbdChar entry (
          byaddr type KBDKEYINFO,
          type USHORT,
          type USHORT)
          returns(optional byvalue fixed bin(16) unsigned)
          ext ( 'KBD16CHARIN' )
          options(byvalue nodescriptor linkage(pascal16)) external;
   dcl keybdinfo type kbdkeyinfo;
   call KbdChar(keybdinfo, 0, 0);
   return (keybdinfo.chChar||keybdinfo.chScan);
  end pligetch;

    Besides modifying the proc statement to reflect the return, the only
addition to the previous version (keywait.pli) is the expression in the
RETURN statement.  A demonstration retrieving the two CHARs from the
string returned by pligetch is shown in the following:

 /* testing pligetch procedure */
 tryit: proc options(main);
   dcl pligetch external entry ()
     options (linkage(pascal16))
     returns(optional byaddr char(2));
   dcl input char(2);
   dcl (chChar, chScan) char(1);

 around:
   display ('press any key');
   input = pligetch();
   chChar = substr(input,1,1);
   chScan = substr(input,2,1);
   display ('Char code is '||hex(chChar)||'h');
   display ('Scan code is '||hex(chScan)||'h');
   display (' ');
   goto around;
 end tryit;

    I leave deciphering the two bytes to determine which key was pressed
as an exercise for the reader.

    You will note that tryit.pli is an infinite loop.  Unless the
compile-time and run-time default INTERRUPT options were modified before
compiling, you break the loop with Ctrl-C.

    Last night, I discovered the TRANSLATE built-in function.  I was
stewing around as to how I was going make upper case displayed output
out of lower case keyed input; I couldn't figure out how to convert CHAR
data to BIT data (so I could play & on it) and then back to CHAR data.
My wife, who worked in IBM Research (inventing design automation
algorithms written in PL/I for the 15 years previous to retiring in
1988) insists there is a way to do the bit manipulations from CHAR data,
but she has carefully forgotten how to program and is not about to
figure it out again just for me .  She thinks she wrote subroutines
(in PL/I) to do it.  While TRANSLATE has solved my immediate problem, I
would still like to know how she did it.  Any suggestions?

    Happy New Year,

          --Murray

___
 * MR/2 2.25 #120 * If you are not confused, you don't understand the situation
                                                                           
                              
---
* Origin: 2" x 4" bbs - a basic board - (914) 271-9407 (1:2625/108)
SEEN-BY: 270/101 620/243 711/401 409 410 413 430 808 809 934 955 712/407 515
SEEN-BY: 712/517 628 713/888 800/1 7877/2809
@PATH: 2625/108 1 2619/211 3615/50 396/1 270/101 712/515 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.