[comp.lang.pascal] Scan codes in TurboPascal

iam@waikato.ac.nz (Ian McDonald) (09/15/90)

How do you pick up Scan codes in TP 5.5?  From my reading of the manuals you
have to resort to machine code.  I am after picking up Ctrl-ESC as well as just
Esc as ReadKey doesn't differentiate.

-------------------------------------------------------------------------
Ian McDonald |
1 June Place |
Hamilton     |   This space free for advertising !!
New Zealand  |
+64-7-567714 |

oivindt@ulrik.uio.no (Oivind Toien) (09/16/90)

In article <1561.26f20a24@waikato.ac.nz> iam@waikato.ac.nz (Ian McDonald) writes:
> How do you pick up Scan codes in TP 5.5?  From my reading of the manuals you
> have to resort to machine code.  I am after picking up Ctrl-ESC as well as

You can read the keyboard memory buffer. I do not have the specific
code you want, but take a look at these examples, they checks whether
the key is depressed:

Function CtrlPressed:Boolean;
begin
   If (MEM[0:$417] and 4)<>0
   then CtrlPressed:=true
   else CtrlPressed:=False;
end;

Function ShiftPressed:Boolean;
begin
  If (MEM[0:$417] and 2)<>0
  then ShiftPressed:=true
  else ShiftPressed:=False;
end;

Hope this helps.

Oivind

ergo@netcom.UUCP (Isaac Rabinovitch) (09/17/90)

In <1561.26f20a24@waikato.ac.nz> iam@waikato.ac.nz (Ian McDonald) writes:

>How do you pick up Scan codes in TP 5.5?  From my reading of the manuals you
>have to resort to machine code.  I am after picking up Ctrl-ESC as well as just
>Esc as ReadKey doesn't differentiate.

Correction:  ReadKey *does* know about scan codes.  (I gather you knew
that, but your writing style makes precise interpretation a
nondeterministic procedure.)  You're right about ReadKey treating
CTL-ESC the same as ESC, but that's not ReadKey's fault -- it
sends a signal to the BIOS saying it wants a key, and reports what it
gets.

One way around this is to talk to the BIOS yourself.  Now, this is
indeed a low-level function, but you can do it in a high-level
language if you've got the right function libraries -- and as it
happens, the Turbo Pascal DOS Unit is such a library.  With the INTR
function, you can send arbitrary software interrupts almost as easily
as any assembly-language hacker.  The following function uses INTR to
invoke interrupt 16h, function 2h:  interrogate shift status byte.

	uses dos;

	function shifts : byte;
		var
			r : Registers;
		begin
			r.ah := $02;
			intr($16, r);
			shifts := r.al;
		end;

The word returned by shifts is the sum of the following values:

	1 -- right shift key depressed
	2 -- left   "     "    "
	4 -- ctrl key depressed
	8 -- alt   "     "
	16 -- scroll lock on
	32 -- num     "   "
	64 -- caps    "   "
	128 -- insert mode on

Note that this gives you the shift status *now*, which is not
necesarily  what the shift status was when ReadKey returned; you'll
want to interrogate shifts *very* soon after calling ReadKey.
-- 

ergo@netcom.uucp			Isaac Rabinovitch
{apple,amdahl,claris}!netcom!ergo	Silicon Valley, CA

Collins's Law:
	If you can't make a mistake, you can't make anything.

Corollaries ("Rabinovitch's Rules of Sane Dialogue"):
	1. Everybody who matters is stupid now and then.
	2. If I'm being stupid, that's my problem.
	3. If my being stupid makes you stupid, that's your problem.
	4. If you think you're never stupid, boy are you stupid!

ergo@netcom.UUCP (Isaac Rabinovitch) (09/18/90)

In <OIVINDT.90Sep15195258@ulrik.uio.no> oivindt@ulrik.uio.no (Oivind Toien) writes:

>> How do you pick up Scan codes in TP 5.5?

>You can read the keyboard memory buffer. I do not have the specific
>code you want, but take a look at these examples, they checks whether
>the key is depressed:

>Function CtrlPressed:Boolean;
>begin
>   If (MEM[0:$417] and 4)<>0
>   then CtrlPressed:=true
>   else CtrlPressed:=False;
>end;
>(further examples deleted)

I guess that'll work just as well as my suggestion (using the intr
function to ask for the shift byte), and it's probably a little more
efficient.  But whenever you access bios memory directly like that,
you're demanding a higher level of IBM compatibility.  I suppose most
clone makers are at least this compatibile, but why take unnecessary
risks?
-- 

ergo@netcom.uucp			Isaac Rabinovitch
{apple,amdahl,claris}!netcom!ergo	Silicon Valley, CA

Collins's Law:
	If you can't make a mistake, you can't make anything.

Corollaries ("Rabinovitch's Rules of Sane Dialogue"):
	1. Everybody who matters is stupid now and then.
	2. If I'm being stupid, that's my problem.
	3. If my being stupid makes you stupid, that's your problem.
	4. If you think you're never stupid, boy are you stupid!