The <kbd.h> Header File

Keyboard handling routines

Language Extensions

BEGIN_KEYTEST
Starts a _keytest_optimized block.
END_KEYTEST
Ends a _keytest_optimized block.

Functions

_keytest_optimized
Optimized low-level keyboard reading for single keys.
_keytest
Low-level keyboard reading for single keys.
_rowread_internal
Low-level keyboard reading without inverting.
_rowread_inverted
Low-level keyboard reading with inverting.
_rowread
Low-level keyboard reading.
alphaLockOff
Turns the alpha-lock off on the TI-89.
alphaLockOn
Turns the alpha-lock on on the TI-89.
GetAlphaStatus
Returns the current alpha-lock status.
GKeyDown
Checks for currently-available keystrokes.
GKeyFlush
Flushes the keyboard queue.
GKeyIn
Gets character from the keyboard, with additional possibilities.
kbhit
Checks for unread keystrokes.
KeyYesOrNo
Checks if a key value represents a 'yes' or 'no' key.
ngetchx
Gets character from the keyboard, without echoing to the screen.
OSGetStatKeys
Checks whether an arrow key (TI-89) or status key (TI-92+) is pressed.
OSInitBetweenKeyDelay
Sets the rate at which a key autorepeats.
OSInitKeyInitDelay
Sets the initial autorepeat key delay.
pushkey
Replaces the keystroke in the keyboard queue with the given code.
restoreAlphaLock
Restores the alpha-lock status.
SetAlphaStatus
Sets the alpha-lock status on the TI-89.

Global Variables

OSFastArrows
A variable determining whether arrow keys are repeated slowly or quickly.

Constants

KB_AUTOREPEAT
A constant defining the "auto-repeat" bit.
NULL
A null-pointer value.

Predefined Types

Arrows
An enumeration for describing the four arrow keys.
Bool
An enumeration to describe true or false values.
CommonKeys
An enumeration for describing common key codes.
GKeyFlags
Enumerates different key options flags for the GKeyIn routine.
SCR_RECT
A scructure for defining a rectangular area.
StatKeys
An enumeration for describing modifier key values.

BEGIN_KEYTEST

Starts a _keytest_optimized block.

BEGIN_KEYTEST is used to start a block of key reading using _keytest_optimized.

See also: END_KEYTEST, _keytest_optimized


END_KEYTEST

Ends a _keytest_optimized block.

END_KEYTEST is used to end a block of key reading using _keytest_optimized.

See also: BEGIN_KEYTEST


_keytest_optimized

short _keytest_optimized (short row, short col);

Optimized low-level keyboard reading for single keys.

_keytest_optimized behaves like _keytest, but it produces better code if keys from the same row are read sequentially. You have to use it together with BEGIN_KEYTEST and END_KEYTEST.

An example probably best explains the usage of this function. The following piece of code waits until an arrow key is pressed. Since all arrows are in the same row, only one call to _rowread is necessary.

for (;;)
  {
    BEGIN_KEYTEST
      if (_keytest_optimized (RR_LEFT)
       || _keytest_optimized (RR_RIGHT)
       || _keytest_optimized (RR_UP)
       || _keytest_optimized (RR_DOWN))
        break;
    END_KEYTEST
  }

_keytest

short _keytest (short row, short col);

Low-level keyboard reading for single keys.

_keytest uses _rowread to read the key in a specific row and column. If the parameters are constants, the argument for _rowread and the return mask are optimized into single values.

_keytest returns TRUE if the key is being held down, and FALSE otherwise.

Be sure to read the notes about _rowread.

compat.h defines constant pairs for all keys. Using these constant pairs, you can use _keytest in this way:

if (_keytest (RR_ESC))
  ...

See also: _keytest_optimized


_rowread_internal

#define _rowread_internal(row) (~(_rowread (row)))

Low-level keyboard reading without inverting.

_rowread_internal is a function which was previously used internally by _rowread. Unlike _rowread, it does not invert the return value.


_rowread_inverted

#define _rowread_inverted(row) (_rowread (~((short)(row))))

Low-level keyboard reading with inverting.

_rowread_inverted is similar to _rowread, but it also inverts the row passed to it.


_rowread

unsigned short _rowread (unsigned short row);

Low-level keyboard reading.

_rowread is a function for low-level keyboard reading. It is implemented for simultaneous reading of more than one key (useful in games), or for reading keys when interrupts are disabled (useful if you want to avoid displaying status line indicators, which are displayed from Auto-Int 1).

Setting a bit in row masks the corresponding row of the keyboard from being read, so if row is zero, all rows are read at the same time. Take a look at _rowread_inverted as well. In the result, all bits (cols) corresponding to keys which are being held down are set. See below for some examples.

Here is a table which describes how the keyboard matrix is organized on both the TI-89 and TI-92 Plus:

TI-89:
  C o l u m n
R
o
w
   Bit 7     Bit 6     Bit 5     Bit 4     Bit 3     Bit 2     Bit 1     Bit 0  
Bit 0alphaDiamndShift2ndRightDownLeftUp
Bit 1F5CLEAR^/*-+ENTER
Bit 2F4BckSpcT,963(-)
Bit 3F3CATLGZ)852.
Bit 4F2MODEY(7410
Bit 5F1HOMEX=|EESTOAPPS
Bit 6       ESC

TI-92 Plus:
  C o l u m n
R
o
w
   Bit 7     Bit 6     Bit 5     Bit 4     Bit 3     Bit 2     Bit 1     Bit 0  
Bit 0DownRightUpLeftHandShiftDiamnd2nd
Bit 1321F8WSZ 
Bit 2654F3EDX 
Bit 3987F7RFCSTO
Bit 4,)(F2TGVSpace
Bit 5TANCOSSINF6YHB/
Bit 6PENTER2LNF1UJN^
Bit 7*APPSCLEARF5IKM=
Bit 8 ESCMODE+OLqBckSpc
Bit 9(-).0F4QAENTER1-

Note for TI-92+: ENTER1 is on the alphabetic and numeric keypads. ENTER2 is next to the cursor pad.

You can use binary numbers to mask out the rows you need. You can also make use of the fact that a value where only bit i is set equals 1<<i.
Use the bitwise NOT operator ('~') to invert the value.

These four expressions all check whether '9' on the TI-89 or 'E' on the TI-92+ is held down. In fact, they are all equal:

_rowread(~((short)(1<<2))) & (1<<3)
_rowread(~0b100) & 0b1000
_rowread(~0x4) & 0x8
_rowread(0xFFFB) & 0x8

But generally it is much easier to use the _keytest macro instead.

Because of the way the TI-89 and TI-92+'s keyboard is wired, if you hold down three keys that form the corners of a rectangle, the calculator will think you are also holding down the key at the fourth corner. The ON key is special. It is not part of the keyboard matrix and therefore cannot be read with _rowread. It triggers a special interrupt instead.

Note: It is recommended to redirect Auto-Int 1 and 5 while reading the keyboard using _rowread, because keyboard reading routines implemented in these two interrupts may interfere with _rowread if an interrupt occurs just while _rowread is executing. See DUMMY_HANDLER from intr.h for information on how to do this.

About the internal implementation: _rowread sends row to the I/O port 0x600018 (keyboard row mask), waits a while to allow the I/O to recover, then returns the byte read from 0x60001B (inverted for easier testing in C programs).

See also: _rowread_internal, _rowread_inverted, _keytest


alphaLockOff

AMS 2.00 or higher

void alphaLockOff (unsigned char *Status);

Turns the alpha-lock off on the TI-89.

alphaLockOff first returns the current alpha-lock keyboard status in Status. Then it turns the alpha-lock off. This routine exists on both the TI-89 and TI-92+, but as there is no alpha-lock on the TI-92+, this function does nothing on the TI-92+.

See also: alphaLockOn, restoreAlphaLock, SetAlphaStatus, GetAlphaStatus


alphaLockOn

AMS 2.00 or higher

void alphaLockOn (unsigned char *Status);

Turns the alpha-lock on on the TI-89.

alphaLockOn first returns the current alpha-lock keyboard status in Status. Then it turns the alpha-lock on. This routine exists on both the TI-89 and TI-92+, but as there is no alpha-lock on the TI-92+, this function does nothing on the TI-92+.

See also: alphaLockOff, restoreAlphaLock, SetAlphaStatus, GetAlphaStatus


GetAlphaStatus

AMS 2.00 or higher

unsigned char GetAlphaStatus (void);

Returns the current alpha-lock status.

GetAlphaStatus returns TRUE if the alpha-lock is on, and FALSE otherwise.
On the TI-92+, the function will always return FALSE.

See also: SetAlphaStatus


GKeyDown

short GKeyDown (void);

Checks for currently-available keystrokes.

Although GKeyDown is different entry in the TIOS jump table than kbhit, there is no difference between these two functions. GKeyDown just calls kbhit and does nothing more.


GKeyFlush

void GKeyFlush (void);

Flushes the keyboard queue.

GKeyFlush flushes the keyboard queue by repeatedly calling GKeyIn until the queue is empty.


GKeyIn

short GKeyIn (SCR_RECT *cursor_shape, unsigned short Flags);

Gets character from the keyboard, with additional possibilities.

GKeyIn acts similarly to ngetchx, with following differences:

The parameter Flags can be a combination of the following, defined in the GKeyFlags enumeration:
GKF_NORMALNo special key processing. This is the usual value to set.

Note: GKF_NORMAL is actually 0 (i.e. no flags are set).
GKF_MODALIf the pressed key is a modal key (see QModeKey for information on what is a "modal" key for the TIOS), GKeyIn will return KEY_ESC instead of the real keystroke code, and the keystroke will not be picked from the keyboard queue. If the pressed key is not a mode key, GKeyIn behaves as usual.

Note that DIALOG boxes usually set GKF_MODAL and GKF_SYS so that if the user presses [VAR-LINK] in the dialog box, the dialog box is closed and then the [VAR-LINK] key is acted on (though there is a flag to allow [VAR-LINK] to be activated from inside a dialog box).
GKF_REPUSH_KEYGKeyIn will not pick the keystroke from the keyboard queue, so the "keypress" flag will remain set. You must explicitely pick it using ngetchx or flush the queue using GKeyFlush.
GKF_ACCEPTThe purpose of this flag is unknown for the moment.
GKF_SYSIf the pressed key is a system key (see QSysKey for information on what is a "system" key for the TIOS), GKeyIn will return KEY_ESC instead of the real keystroke code, and the keystroke will not be picked from the keyboard queue. If the pressed key is not a system key, GKeyIn behaves as usual.
GKF_NO_EVSPressing the [CATALOG] key will be ignored.

Except in noted special cases, GKeyIn returns the same value as ngetchx. Menus and dialog boxes usually set GKF_MODAL and GKF_SYS, so that if a user presses say the VAR-LINK key in the dialog box, the dialog box is closed and then the VAR-LINK key is acted on.

Note: TI doesn't recommend to use GKeyIn as it bypasses the event manager’s handling of keys. Programs should use the event manager to process keys in most cases. GKeyIn should only be used in special cases where the event manager is not accessible. For games, you'll probably be better off using kbd_queue or _keytest.

Note: Thomas Nussbaumer informed me that idle interferes with grayscale graphics. As GKeyIn calls the idle function, the use of GKeyIn while grayscale mode is active is not recommended.

See also: ngetchx, kbhit, kbd_queue, OSFastArrows


kbhit

short kbhit (void);

Checks for unread keystrokes.

kbhit checks to see if a keystroke is currently available. Any available keystrokes can be retrieved with ngetchx. If a keystroke is available, kbhit returns a nonzero integer (in fact, it returns the exactly same value as ngetchx); if not, it returns 0. Note that kbhit does not pick a keystroke from the keyboard queue. So, kbhit will continue to return non-zero value until "keypress" flag is reset by calling ngetchx, GKeyFlush or GKeyIn.

Note: kbhit function is slow, because it also handles receiving eventual bytes from the link port (used mainly internally in TIOS when the calculator is in the Home screen). See kbd_queue for much faster way to check the keyboard state.

See also: ngetchx, GKeyIn, kbd_queue, OSFastArrows


KeyYesOrNo

AMS 2.00 or higher

short KeyYesOrNo (unsigned short key);

Checks if a key value represents a 'yes' or 'no' key.

KeyYesOrNo returns:

Here is an example (called "Key Yes or No"):

// Check whether typed keys represent "Yes" or "No"
// in current language

#define USE_TI89              // Compile for TI-89
#define USE_TI92PLUS          // Compile for TI-92 Plus
#define USE_V200              // Compile for V200

#define OPTIMIZE_ROM_CALLS    // Use ROM Call Optimization
#define MIN_AMS 200           // Compile for AMS 2.00 or higher
#define SAVE_SCREEN           // Save/Restore LCD Contents

#include <tigcclib.h>         // Include All Header Files

// Main Function
void _main(void)
{
  short k, a;
  ClrScr ();
  while ((k = GKeyIn (NULL, 0)) != 32)
    // While the user doesn't type SPACE
  {
    a = KeyYesOrNo(k);
    if (a == 0)
      DrawStr (0, 0, "FALSE  ", A_REPLACE);
    else if (a == 1)
      DrawStr (0, 0, "TRUE   ", A_REPLACE);
    else
      DrawStr (0, 0, "NEITHER", A_REPLACE);
  }
  DrawStr (0, 0, "SPACE  ", A_REPLACE);
  GKeyIn (NULL, 0);
}

ngetchx

short ngetchx (void);

Gets character from the keyboard, without echoing to the screen.

ngetchx reads a single character directly from the keyboard, without echoing to the screen. If the keyboard queue is empty, ngetchx will wait for the keypress, else the character will be picked from the keyboard queue.

ngetchx returns the code of the character read from the keyboard. This code is mainly the same as TI-Basic function GetKey returns. All keypresses which correspond to the ASCII character will return the ASCII code of it, for example pressing on '+' key will return the ASCII code of '+' (which is 43 in decimal), so you can write

if (ngetchx () == '+') ...

Codes for some other common keypresses which do not have an ASCII representation (ESC, ENTER, function keys, etc.) and which are the same on the TI-89 and TI-92 Plus are defined in the enum CommonKeys (for example, KEY_ESC, KEY_ENTER etc.).

Be aware that codes assigned to arrow keys is shuffled in comparation with TI-Basic. These codes are also different on TI-89 and TI-92 Plus. Note that the documentation of releases of TIGCCLIB prior to 2.0 has an error: it recommends usage of OSGetStatKeys as a calculator-independent method for reading arrow keys. This is simply not true. Here is a table of return codes for pressing arrow keys on TI-89 and TI-92 Plus:

TI-89:

Key Normal +Shift +2nd +Diamond +alpha
Up337852944331672133105
Right344853644401672833112
Down340853244361672433108
Left338853044341672233106

TI-92+:

Key Normal +Shift +2nd +Diamond +alpha
Up338167224434853033106
Right340167244436853233108
Down344167284440853633112
Left337167214433852933105

It is interesting that the ngetchx function is able to handle pressing to more than one arrow keys at the same moment. The returned value is then simply logical OR of values for a particular key.

To increase compatibility between TI-89 and TI-92 Plus, a header file compat.h is implemented. This file (among others) defines pseudo-constants (known from DoorsOS) like KEY_LEFT, KEY_RIGHT, KEY_UP and KEY_DOWN which represent return values for arrow keys. These "pseudo-constants" have different values on the TI-89 and TI-92 Plus, so if you use testing like

if (key == KEY_LEFT) ...

such test will work fine on both the TI-89 and TI-92 Plus. These pseudo-constants works in both "nostub" and "DoorsOS" mode. Pseudo-constants KEY_UPRIGHT and KEY_DOWNLEFT are also defined, with obvious meaning.

Codes of keystrokes like <Diamond> + <key> are also different in comparison with the TI-Basic GetKey function. I will not give a complete table here, because such keystrokes are rarely used in programs. If you are interested for a code of the concrete keystroke, you can easily find it by yourself. Principally, the code for a keystroke like <Diamond> + <key> is mainly equal to the code for <key> increased by KEY_DIAMOND. This is also a pseudo-constant with value 16384 on TI-89 and 8192 on TI-92 Plus. The same is true for keystrokes like <Shift> + <key>, and the appropriate pseudo-constant which need to be added is called KEY_SHIFT (8192 on TI-89 and 16384 on TI-92 Plus).

As a side effect, ngetchx also sets the activity in the status bar to BUSY, so the "BUSY" indicator will appear in the status bar. If you want later to remove the "BUSY" indicator, you must call ST_busy function to do this.

Note: ngetchx function is slow, because it also handles receiving eventual bytes from the link port. This is used in TIOS mainly when the calculator is in the Home screen, but principally, if the program is waiting for a keypress using ngetchx function, any valid data which come to the link port will be received and processed accordingly (for example, the program waiting for a keypress can accept another program via the link port during waiting). See kbd_queue for much faster way to gets characters from the keyboard.

See also: GKeyIn, kbhit, kbd_queue, OSFastArrows


OSGetStatKeys

short OSGetStatKeys (void);

Checks whether an arrow key (TI-89) or status key (TI-92+) is pressed.

OSGetStatKeys is a strange function: it behaves differently on TI-89 and on TI-92 Plus. On TI-89 it returns ARROW_LEFT, ARROW_RIGHT, ARROW_UP or ARROW_DOWN if one of the corresponding arrow keys is pressed (these constants are defined in enum Arrows). On TI-92 Plus it returns STAT_2ND, STAT_DIAMOND, STAT_SHIFT of STAT_HAND if one of the corresponding status key is pressed (these constants are defined in enum StatKeys). If no arrow keys is pressed (TI-89) or if no status keys is pressed (TI-92 Plus), this function returns zero. OSGetStatKeys does not wait for a keypress. If more than one arrow/status key is pressed, OSGetStatKeys returns a garbage value.

Note: The information about this functions in releases of TIGCCLIB prior to 2.0 were incomplete: I didn't notice different behaviour on TI-89 and TI-92 Plus. So, avoid this function in portable programs.


OSInitBetweenKeyDelay

short OSInitBetweenKeyDelay (short rate);

Sets the rate at which a key autorepeats.

OSInitBetweenKeyDelay sets the rate at which a key autorepeats to rate (note that only few keys have an autorepeat feature, namely arrow keys and backspace). The measuring unit for this function is 1/395 s (because Auto-Int 1 is triggered 395 times per second), and the default value for rate is 48. OSInitBetweenKeyDelay returns the previous autorepeat rate.

Greg Dietsche pointed out that on HW2 (precisely, if the gateArray field of the structure returned by FL_getHardwareParmBlock exists and is 2 or higher), TIOS immediately multiplies the value passed to it by 3/4. This is probably a bug, as this implies that there is no way to restore the rate to the value previously returned by OSInitBetweenKeyDelay. To work around this problem, OSInitBetweenKeyDelay is defined as a macro which detects this modification in a smart way, and tries to revert it for the return value.


OSInitKeyInitDelay

short OSInitKeyInitDelay (short delay);

Sets the initial autorepeat key delay.

OSInitKeyInitDelay sets the time that a key has to be held down before it starts to repeat to delay (note that only few keys have autorepeat feature, like arrow keys and backspace). Measuring unit for this function is 1/395 s (because Auto-Int 1 is triggered 395 times per second), and the default value for delay is 336 (slightly shorter than 1 second). OSInitKeyInitDelay returns previous autorepeat key delay.


pushkey

void pushkey (short code);

Replaces the keystroke in the keyboard queue with the given code.

If the keyboard queue is empty, pushkey pushes code in the keyboard queue, then sets the "keypressed" flag. If the keyboard queue is not empty, pushkey replaces the keystroke on the top of the keyboard queue with code. In each case, the next call of ngetchx will return code.


restoreAlphaLock

AMS 2.00 or higher

void restoreAlphaLock (unsigned char *Status);

Restores the alpha-lock status.

restoreAlphaLock restores the alpha-lock status to the value saved in Flags, which is obtained through a call to alphaLockOn or alphaLockOff. It seems that these are the valid values for *Status:

0 Alpha-lock is turned off.
1 Alpha-lock is turned on.
2 Uppercase alpha-lock is turned on. However, GetAlphaStatus will then return FALSE. This is the value which is used if the user presses SHIFT and then ALPHA.
3 Uppercase alpha-lock is turned on. GetAlphaStatus will return TRUE.

On the TI-92+, the function does nothing.

See also: alphaLockOn, alphaLockOff, SetAlphaStatus


SetAlphaStatus

AMS 2.00 or higher

void SetAlphaStatus (unsigned char Status);

Sets the alpha-lock status on the TI-89.

There are two valid values for Status: TRUE turns the alpha-lock on; FALSE turns it off.
On the TI-92+, the function does nothing.

See also: GetAlphaStatus


OSFastArrows

unsigned char OSFastArrows;

A variable determining whether arrow keys are repeated slowly or quickly.

OSFastArrows tells ngetchx, GKeyIn, and OSdequeue how to handle the arrow keys.

Once a key value is pushed onto the key queue, the same key value is not pushed again until the key is released, unless that key is one of the following: any of the arrow keys, the contrast keys, delete, or backspace. These keys are allowed to "auto-repeat". If one of these keys is pressed and held, after an initial delay, the same key value will be pushed again. If the keypress continues to be active, the key value will continue to be pushed at a rate set by a delay which is slightly shorter than the initial delay. If a key is pushed as a result of this auto-repeat feature, the value KB_AUTOREPEAT is OR’d with the key value prior to pushing the key value onto the key queue.

It seems that the following values are allowed:

0 Keys are repeated at normal speed. This is the default. In this case, ngetchx will clear the KB_AUTOREPEAT bit from the key value.
1 Same as 0 for ngetchx, but in text editors like the home screen entry line, keys are not repeated at all.
2 The key delay is ignored; ngetchx returns immediately if an arrow key is pressed. In text editors, the busy indicator is visible, but keys do not seem to be repeated.

Further information is welcome.

See also: ngetchx, OSInitBetweenKeyDelay, OSInitKeyInitDelay


KB_AUTOREPEAT

#define KB_AUTOREPEAT (1<<11)

A constant defining the "auto-repeat" bit.

KB_AUTOREPEAT is a constant defining the "auto-repeat" bit in key values, please see OSFastArrows for more informations.

See also: OSFastArrows


Arrows

enum Arrows {ARROW_UP = 1, ARROW_LEFT = 2, ARROW_DOWN = 3, ARROW_RIGHT = 4};

An enumeration for describing the four arrow keys.

Arrows is an enumeration for describing the return values of the function OSGetStatKeys, which is used for reading arrow keys (TI-89 only).


CommonKeys

enum CommonKeys {KEY_F1 = 268, KEY_F2 = 269, KEY_F3 = 270, KEY_F4 = 271, KEY_F5 = 272, KEY_F6 = 273, KEY_F7 = 274, KEY_F8 = 275, KEY_ESC = 264, KEY_QUIT = 4360, KEY_APPS = 265, KEY_SWITCH = 4361, KEY_MODE = 266, KEY_BACKSPACE = 257, KEY_INS = 4353, KEY_CLEAR = 263, KEY_VARLNK = 4141, KEY_CHAR = 4139, KEY_ENTER = 13, KEY_ENTRY = 4109, KEY_STO = 258, KEY_RCL = 4354, KEY_SIGN = 173, KEY_MATH = 4149, KEY_MEM = 4150, KEY_ON = 267, KEY_OFF = 4363};

An enumeration for describing common key codes.

CommonKeys is enumerated type for decribing codes of various common keypresses, which usually does not ASCII representation, and which are the same on TI-89 and TI-92 Plus. Note that codes of keypresses like HOME, CATALOG etc. are not defined here, because they are not the same on TI-89 and TI-92 Plus. See compat.h for more info how to detect the calculator version.


GKeyFlags

enum GKeyFlags {GKF_NORMAL=0, GKF_MODAL=1, GKF_REPUSH_KEY=2, GKF_ACCEPT=4, GKF_SYS=8, GKF_NO_EVS=16};

Enumerates different key options flags for the GKeyIn routine.

Enumerates different key options flags. The meanings of these flags are given in GKeyIn.

See also: GKeyIn


StatKeys

enum StatKeys {STAT_2ND = 1, STAT_DIAMOND = 2, STAT_SHIFT = 3, STAT_HAND = 4};

An enumeration for describing modifier key values.

StatKeys is an enumerated type for describing the return values of the function OSGetStatKeys, which is used for reading the status keys (TI-92 Plus only).


Return to the main index