[comp.sys.amiga.programmer] Checking for a Keystroke

mueller@schaefer.math.wisc.edu (Carl Mueller) (06/19/91)

This question probably will require a somewhat lengthy answer.  I hope that
someone out there will take the time.

I have the SAS/C compiler for the AMIGA and I want to write a routine that
I can call that will check for a keypress.  If a key is being pressed, I want
the routine to report the key being pressed.  If not I want it to return -1
or some such thing.  Can anyone tell me how to do this (or direct me to some
source code that does this)?  I have a feeling that I'm going to have to use
the keyboard device or the input device or the console device.  If so, I'm
really going to need some help getting started.

Thanks much in advance.

Carl Mueller (mueller@math.wisc.edu)

mark@zach.fit.edu ( Mark R. Craig) (06/20/91)

In article <1991Jun19.131033.14578@schaefer.math.wisc.edu> mueller@math.wisc.edu writes:
 >This question probably will require a somewhat lengthy answer.  I hope that
 >someone out there will take the time.
 >
 >I have the SAS/C compiler for the AMIGA and I want to write a routine that
 >I can call that will check for a keypress.  If a key is being pressed, I want
 >the routine to report the key being pressed.  If not I want it to return -1
 >or some such thing.  Can anyone tell me how to do this (or direct me to some
 >source code that does this)?  I have a feeling that I'm going to have to use
 >the keyboard device or the input device or the console device.  If so, I'm
 >really going to need some help getting started.
 >
 >Thanks much in advance.
 >
 >Carl Mueller (mueller@math.wisc.edu)

I would be VERY interested in such code!  I would think that there would be
a system register that contains the keypress (a buffer perhaps) that could
be scanned.  I know on UNIX the solution would be an ioctl call (do a
read with FIONREAD flag or something like that (I forget the exact call)) -
it worked like a charm.  
   On a similar topic, I originally used a lot of overhead stuff for reading
the joystick (OpenPort, etc.)...then after looking at an old Amiga World, I
replaced all that stuff (I'm holding back on saying garbage - don't want
to get flamed by real gurus :-) ) with about 8 or so lines of code.  One 
problem with this method is that it doesn't buffer joystick responses - but
that's what I wanted anyways....

Hope someone comes up with an easy way of doing the keyboard scan! 

Mark


Mark R. Craig
Internet:  mark@zach.fit.edu
UUCP:      ...!winnie!zach!mark

Alex_Topic@tvbbs.UUCP (Alex Topic) (06/21/91)

  Well about keyboard scan..heh  Well one time when I was makeing one of
those take over the machine demos, I wanted to have keyboard control. For
instance
I want 2 keys that would switch to NTSC or PAL right away.. just a test
thingy I wanted to do/
     
      You scan the CIA chip..   $bffd00 something not too sure..hmm let me
check the manual..heh
      Not too sure on what it is. What you get is a RAW keyvalue..and just
take the value and compare it to what you want it to do. ONly problem I get
different values..Its weird..hmm      later..
 
 A.t.

black@beno.CSS.GOV (Mike Black) (06/22/91)

In article <1991Jun19.131033.14578@schaefer.math.wisc.edu> mueller@math.wisc.edu writes:
>This question probably will require a somewhat lengthy answer.  I hope that
>someone out there will take the time.
>
>I have the SAS/C compiler for the AMIGA and I want to write a routine that
>I can call that will check for a keypress.  If a key is being pressed, I want
>the routine to report the key being pressed.  If not I want it to return -1
>or some such thing.  Can anyone tell me how to do this (or direct me to some
>source code that does this)?  I have a feeling that I'm going to have to use
>the keyboard device or the input device or the console device.  If so, I'm
>really going to need some help getting started.
>

Here's what I use for Aztec C...I believe it should work on SAS also:

P.S.  This is a little demo that allows the numeric keypad to act like
cursor control until 'q' is pressed at which time you will see a 
stream of periods run across the screen until you press 'q' again.
This demonstrates the use of getchar() under RAW i/o and the small
inkey() function that I added.


#include <stdio.h>
#include <stdlib.h>
#include <sgtty.h>

main()
{
    char c;
    int x,y;

    raw(1); /* turn on raw mode */
    puts("Enter 'q' to quit");
    while((c=getchar()) != 'q') {
        switch (c) {
            case '8': printf("%c%c%c",27,'[','A'); /* cursor up */
                      break;
            case '2': printf("%c%c%c",27,'[','B'); /* cursor down */
                      break;
            case '6': printf("%c%c%c",27,'[','C'); /* cursor right */
                      break;
            case '4': printf("%c%c%c",27,'[','D'); /* cursor left */
                      break;
            case '0': printf("%c%c%c",27,'[','H');       /* cursor home */
                      break;
            case '.': printf("Enter x y:");
                      raw(0); /* turn off so we can see the x y on screen */
                      scanf("%d%d",&x,&y);
                      raw(1);
                      printf("%c[%d;%dH",27,x,y);
                      break;
            case '-': printf("%c",12); /* clear screen */
                      break;
        }
        fflush(stdout);
    }
    /* test inkey function */
    while((c=inkey()) != 'q') {printf("%c.",c);fflush(stdout);}
    raw(0);
    putchar(12); /* just to neaten the screen a little */
    return 0;
}

raw(int flag)
{
    static struct sgttyb stty,sttysave;
    static int saved;

    if (flag && !saved) {
        ioctl(fileno(stdin),TIOCGETP,&sttysave);
        ioctl(fileno(stdin),TIOCGETP,&stty);
        stty.sg_flags |= RAW;
        ioctl(fileno(stdin),TIOCSETP,&stty);
        saved=1;
    }
    else {
        if (saved) {
            ioctl(fileno(stdin),TIOCSETP,&sttysave);
            saved = 0;
        }
    }
}

int inkey(void) /* returns 0 if no key available */
{
    if (WaitForChar(Input(),1)) return getchar();
    else return 0;
}

--
-------------------------------------------------------------------------------
: usenet: black@beno.CSS.GOV   :  land line: 407-494-5853  : I want a computer:
: real home: Melbourne, FL     :  home line: 407-242-8619  : that does it all!:
-------------------------------------------------------------------------------

entity@cccan.uucp (Cybernetworx) (06/27/91)

In article <Alex_Topic.3452@tvbbs.UUCP> Alex_Topic@tvbbs.UUCP (Alex Topic) writes:
>
>  Well about keyboard scan..heh  Well one time when I was makeing one of
>those take over the machine demos, I wanted to have keyboard control. For
>instance
>I want 2 keys that would switch to NTSC or PAL right away.. just a test
>thingy I wanted to do/
>     
>      You scan the CIA chip..   $bffd00 something not too sure..hmm let me
>check the manual..heh

Heh..nice way of checking the keyboard :-)   Anyhow, what you are looking
for is $bfec01.  This holds the char as its transmitted from the keyboard.
 
>      Not too sure on what it is. What you get is a RAW keyvalue..and just
>take the value and compare it to what you want it to do. ONly problem I get
>different values..Its weird..hmm      later..
 
Actually, the different values you got were dependant on whether the key
was pressed down or was still up.  I can't remember off hand, but I think
the high bit was set if the key was up, and cleared if it was down.  (It
might not have been the high bit...as a matter of fact, I think it was
bit 0.)

> 
> A.t.
 
One other thing, this method of checking the keyboard is totally unadvised!
If you want to maintain system multitasking and everything, there are many
other ways of reading the keyboard.  In fact, C has several functions
built right in, if you don't care to go through the system routines.  The
above method would only be useful in something where you don't want an
input.handler hogging CPU time, and where you are definitely taking over
the machine.  If you are going this route, make sure CIA-A, Timer A is
left running, since this is what performs the serial transmission from the
keyboard.
 
-- 
          __
    __   ///
    \\\ ///               UUCP:   ...uunet!utai!lsuc!becker!cccan!entity
 CYBERNETWORX             INET:   entity@cccan.UUCP

mykes@amiga0.SF-Bay.ORG (Mike Schwartz) (06/28/91)

In article <1991Jun27.013554.11040@cccan.uucp> entity@cccan.uucp (Cybernetworx) writes:
>In article <Alex_Topic.3452@tvbbs.UUCP> Alex_Topic@tvbbs.UUCP (Alex Topic) writes:
>>
>>  Well about keyboard scan..heh  Well one time when I was makeing one of
>>those take over the machine demos, I wanted to have keyboard control. For
>>instance
>>I want 2 keys that would switch to NTSC or PAL right away.. just a test
>>thingy I wanted to do/
>>     
>>      You scan the CIA chip..   $bffd00 something not too sure..hmm let me
>>check the manual..heh
>
>Heh..nice way of checking the keyboard :-)   Anyhow, what you are looking
>for is $bfec01.  This holds the char as its transmitted from the keyboard.
>

YUP
 
>>      Not too sure on what it is. What you get is a RAW keyvalue..and just
>>take the value and compare it to what you want it to do. ONly problem I get
>>different values..Its weird..hmm      later..
> 

Not the same as what intuition gives you for RAWKEYs at all.

>Actually, the different values you got were dependant on whether the key
>was pressed down or was still up.  I can't remember off hand, but I think
>the high bit was set if the key was up, and cleared if it was down.  (It
>might not have been the high bit...as a matter of fact, I think it was
>bit 0.)
>

YUP, it is bit 0.  If you want it to be in bit 7 for some reason, you
can do a ror.b instruction...

>> 
>> A.t.
> 
>One other thing, this method of checking the keyboard is totally unadvised!
>If you want to maintain system multitasking and everything, there are many
>other ways of reading the keyboard.  In fact, C has several functions
>built right in, if you don't care to go through the system routines.  The
>above method would only be useful in something where you don't want an
>input.handler hogging CPU time, and where you are definitely taking over
>the machine.  If you are going this route, make sure CIA-A, Timer A is
>left running, since this is what performs the serial transmission from the
>keyboard.
> 

You can read the keyboard port without harming multitasking in any way.
All you need to do is to check $bfe001 periodically and if it changes,
a new key event has happened.  There are drawbacks to this, since the
keycodes for future keyboards might be different (doubtful, but assume
it anyway).

The stuff about CIA-A timer is news to me.  If the system isn't running,
then it should be free to use.  If the system is running, you must also
be sure not to read the CIA ISR register, because it clears the bits
and can get the OS in a confused state.

By the way, if you want to work the keyboard directly, you need to wait
at least 200 microseconds on the handshake to work with all keyboards.
Actually, I might be mistaken in that it might be 300 microseconds...
DO NOT USE THE CPU to time this out.  You'd be better off looking at the
beam position register and waiting a few scanlines...

>-- 
>          __
>    __   ///
>    \\\ ///               UUCP:   ...uunet!utai!lsuc!becker!cccan!entity
> CYBERNETWORX             INET:   entity@cccan.UUCP

--
****************************************************
* I want games that look like Shadow of the Beast  *
* but play like Leisure Suit Larry.                *
****************************************************

hinds@repair.stanford.edu (Alexander Hinds) (06/29/91)

mykes@amiga0.SF-Bay.ORG (Mike Schwartz) writes:

>In article <1991Jun27.013554.11040@cccan.uucp> entity@cccan.uucp (Cybernetworx) writes:
>>In article <Alex_Topic.3452@tvbbs.UUCP> Alex_Topic@tvbbs.UUCP (Alex Topic) writes:
>>>
>>>  Well about keyboard scan..heh  Well one time when I was makeing one of
>>>those take over the machine demos, I wanted to have keyboard control. For
>>>instance
>>>I want 2 keys that would switch to NTSC or PAL right away.. just a test
>>>thingy I wanted to do/
>>>     
>>>      You scan the CIA chip..   $bffd00 something not too sure..hmm let me
>>>check the manual..heh
>>
>>Heh..nice way of checking the keyboard :-)   Anyhow, what you are looking
>>for is $bfec01.  This holds the char as its transmitted from the keyboard.
>>

>YUP
> 
>>>      Not too sure on what it is. What you get is a RAW keyvalue..and just
>>>take the value and compare it to what you want it to do. ONly problem I get
>>>different values..Its weird..hmm      later..
>> 

>Not the same as what intuition gives you for RAWKEYs at all.

>>Actually, the different values you got were dependant on whether the key
>>was pressed down or was still up.  I can't remember off hand, but I think
>>the high bit was set if the key was up, and cleared if it was down.  (It
>>might not have been the high bit...as a matter of fact, I think it was
>>bit 0.)
>>

>YUP, it is bit 0.  If you want it to be in bit 7 for some reason, you
>can do a ror.b instruction...

>>> 
>>> A.t.
>> 
>>One other thing, this method of checking the keyboard is totally unadvised!
>>If you want to maintain system multitasking and everything, there are many
>>other ways of reading the keyboard.  In fact, C has several functions
>>built right in, if you don't care to go through the system routines.  The
>>above method would only be useful in something where you don't want an
>>input.handler hogging CPU time, and where you are definitely taking over
>>the machine.  If you are going this route, make sure CIA-A, Timer A is
>>left running, since this is what performs the serial transmission from the
>>keyboard.
>> 

>You can read the keyboard port without harming multitasking in any way.
>All you need to do is to check $bfe001 periodically and if it changes,
>a new key event has happened.  There are drawbacks to this, since the
>keycodes for future keyboards might be different (doubtful, but assume
>it anyway).

>The stuff about CIA-A timer is news to me.  If the system isn't running,
>then it should be free to use.  If the system is running, you must also
>be sure not to read the CIA ISR register, because it clears the bits
>and can get the OS in a confused state.

>By the way, if you want to work the keyboard directly, you need to wait
>at least 200 microseconds on the handshake to work with all keyboards.
>Actually, I might be mistaken in that it might be 300 microseconds...
>DO NOT USE THE CPU to time this out.  You'd be better off looking at the
>beam position register and waiting a few scanlines...

>>-- 
>>          __
>>    __   ///
>>    \\\ ///               UUCP:   ...uunet!utai!lsuc!becker!cccan!entity
>> CYBERNETWORX             INET:   entity@cccan.UUCP

>--
>****************************************************
>* I want games that look like Shadow of the Beast  *
>* but play like Leisure Suit Larry.                *
>****************************************************

	Could somebody post some (C) code detailing the above?  I've 
been wanting to do this for a while, but I can't seem to make sense 
of the keyboard/CIA stuff in the hardware manual. Thanks.

mykes@amiga0.SF-Bay.ORG (Mike Schwartz) (07/01/91)

In article <hinds.678140261@repair> hinds@repair.stanford.edu (Alexander Hinds) writes:

>	Could somebody post some (C) code detailing the above?  I've 
>been wanting to do this for a while, but I can't seem to make sense 
>of the keyboard/CIA stuff in the hardware manual. Thanks.

Call this often (several times per second would be good) to check the
CIA keyboard port directly:

UBYTE	CheckKey() {
	UBYTE far	*cia = 0xbfec01;	/* note the "far" kludge */
	static UBYTE	last = 0;
	UBYTE		retval = 0;

	retval = *cia;
	if (retval != last)
		last = retval;
	else
		retval = 0;
	/* 
	 * since 'C' is totally bad about not providing things like ROR.B 
	 * you get really bad looking stuff like the following:
	 */
	retval = ((retval & 1) << 7) + ((retval>>1)&0x7f);
	return retval;
}

To check if it is a keyup/down, look at bit 8.  The remaining bits are the
hardware scan code.

--
****************************************************
* I want games that look like Shadow of the Beast  *
* but play like Leisure Suit Larry.                *
****************************************************