Matrix-codes consist of two bytes. The first byte
represents the key-column (6..1 from left to right), the second the key-row
(1..9 from bottom to top). Matrix codes are closely related to the physical
wiring of the keys, while keycodes are not.
Schematics
matrixcode ↔ key relationship
|
|
|
DIAG |
|
OSUPD |
|
0B |
|
|
|
|
|
|
|
0A |
F1 |
F2 |
F3 |
F4 |
F5 |
F6 |
|
09 |
SHIFT |
OPTN |
VARS |
MENU |
← |
↑ |
|
08 |
ALPHA |
^2 |
^ |
EXIT |
↓ |
→ |
|
07 |
XTT |
log |
ln |
sin |
cos |
tan |
|
06 |
ab/c |
F↔D |
( |
) |
, |
→ |
|
05 |
7 |
8 |
9 |
DEL |
|
|
|
04 |
4 |
5 |
6 |
x |
div |
|
|
03 |
1 |
2 |
3 |
+ |
- |
|
|
02 |
0 |
. |
EXP |
(-) |
EXE |
|
|
01 |
|
|
|
|
|
|
AC |
00 |
06 |
05 |
04 |
03 |
02 |
01 |
00 |
|
OSUPD: OS update contact P104 (matrixcode can be entered with syscall 248 or
24F).
DIAG: Diagnostic Mode contact P103 (matrixcode can be entered with syscall 248
or 24F).
matrixcode ↔ key relationship (slim)
|
|
|
DIAG |
|
OSUPD |
|
0B |
|
|
|
|
|
|
|
0A |
MENU |
XTT |
SHIFT |
ALPHA |
|
|
|
09 |
F1 |
log |
^2 |
^ |
← |
↑ |
|
08 |
F2 |
ln |
, |
OPTN |
↓ |
→ |
|
07 |
F3 |
sin |
→ |
VARS |
HELP |
LIGHT |
|
06 |
F4 |
cos |
7 |
4 |
1 |
0 |
|
05 |
F5 |
tan |
8 |
5 |
2 |
. |
|
04 |
F6 |
ab/c |
9 |
6 |
3 |
EXP |
|
03 |
EXIT |
F↔D |
DEL |
x |
+ |
(-) |
|
02 |
|
( |
) |
div |
EXE |
- |
|
01 |
|
|
|
|
|
|
AC |
00 |
06 |
05 |
04 |
03 |
02 |
01 |
00 |
|
System call 0x1032 will return a pointer to a matrixcode/keycode
mapping table (in newer versions of the OS (1.04->)). The official SDK
includes a table (symbol __$gb_KeyCodeTable in FXADDINror.abs) in the binary,
but will use the OS provided map, if the OS has the system call.
The (SDK-provided, compiled in) table is of type
int table[12][7], and the
matrix code components can be used for lookups. Unused entries are -1
(0xFFFFFFFF)
0x247:
KeyBoard_GetKeyWait(int*column, int*row, int
type_of_waiting, int timeout_period, int menu, unsigned
short*keycode );
column receives the column number of
the next key in keyboard buffer
row receives the row number of the next key in keyboard buffer
type_of_waiting can be
KEYWAIT_HALTON_TIMEROFF (0) If there are no characters in the key buffer, this
function waits until a character arrives and then returns immediately.
KEYWAIT_HALTOFF_TIMEROFF (1) this function returns immediately.
KEYWAIT_HALTON_TIMERON (2) If no character arrives within the time (seconds)
specified by the time parameter, this function times out.
timeout_period may be 0..3600 seconds.
This function is a 6 parameter call!
If menu is zero and type_of_waiting is not
KEYWAIT_HALTOFF_TIMEROFF, the function jumps to the main menu, if the MENU-key
is hit.
If menu is not zero or type_of_waiting is
KEYWAIT_HALTOFF_TIMEROFF, the function returns column and row
of the MENU-key, if the MENU-key is hit. Hence you have to provide for an exit
yourself.
In *keycode the function returns a keycode, if previously set by
Keyboard_PutKeycode(0x910) or zero, if not.
With type_of_waiting == KEYWAIT_HALTOFF_TIMEROFF, the function does
not heed for key chatter!
The matrixcodes returned start with 0x0101. The most other matrixfunctions
return codes starting with 0x0000.
columnnumber 7..2 from left to right.
rownumber 2..10 from bottom to top
Examples:
F1: 0x070A
EXE: 0x0302
exception AC/on: 0x0101
returns
KEYREP_NOEVENT (0): no key available (only with type_of_waiting is
KEYWAIT_HALTOFF_TIMEROFF )
KEYREP_KEYEVENT (1): key available
KEYREP_TIMEREVENT (2): timeout (only with type_of_waiting is
KEYWAIT_HALTON_TIMERON )
0x249: short
Keyboard_GetPressedTime(void);
The
function returns a counter that is constantly increased while any key is
pressed.
0x24A: int
Keyboard_GetPressedKey(short*matrixcode);
If a key is pressed, its matrixcode is put into
matrixcode and 1 is returned. If no key is currently pressed, 0 is
returned.
Especially 0x24A could be appropriate to detect any key-press, without using
GetKey (locks your central loop), GetKeyWait (is broken), IsKeyDown(monitors
only specific keys) or SetTimer(which has to be synchronized with your central
loop).
If only these routines are used to monitor the keyboard, its buffer fills up.
To prevent those stored codes from triggering unwanted actions, it is
recommended to clear the keyboard buffer with 0x241 when
finalizing the program at the latest.
0x24B/0x24C: int
Keyboard_IsKeyPressed(short*matrixcode);
returns 0 if the key
with matrix-code matrixcode is presently not pressed
returns 1 otherwise
obviously this call is not used by SDKs IsKeyDown.
0x24B and 0x24C operate nearly identically.
Both activate a matrix row injector-line (using port B and port M) depending
on the matrix code to check. They both read port A several times to check for
the pressed key, if key is not detected at first. 0x24B reads
up to 5 times. 0x24C reads up to 10 times. They use the WDT
to implement local timing behaviour, which is identical in both functions.
IsKeyPressed-queries should not be mixed with GetKey-queries. They follow
different concepts. If your central loop is occupied with some time-consuming
work between two KeyPressed-queries a key press could be missed by your
program but interrupt-driven produces an entry in the keybuffer. That can lead
to an async-situtation.
0x24D: int Keyboard_KeyDown(
void );
If a key is down, 1
is returned. If no key is currently down, 0 is returned.
The function simply queries port A (return port A != 0xFF).
0x24E: void
Keyboard_SecondaryInterruptHandler( void );
called by 0x25E.
0x25E: void
Keyboard_PrimaryInterruptHandler( void );
PINT0..PINT7 interrupt answering handler.
0x251: void
Keyboard_TimerHandler( void );
Timer 2
answering handler.
0x90F: int GetKey( unsigned
int*keycode );
Gets
the next pressed key into *keycode.
returns 0 in case of a CTRL-key.
returns 1 in case of a CHAR-key.
0x910: int PutKey(int
keycode, int mode);
Puts a keycode
into the keybuffer. Possibly interesting for demo-modes.
keycode: value to inject exactly as returned by GetKey.
mode controls the matrixcode, which are set.
returns
0 if the function fails (keybuffer full)
1 if the function succeeded.
0x910 puts -1,-1 (if mode==1) or -2,-2 (if mode!=1) into the
matrixcode buffer .
0x910 puts the GetKey-compatible keycode itself into an area
beginning at 0x880061DC.
-1,-1 and -2,-2 are no real matrix codes.
Any special key processing like MENU, SHIFT AC/on a. s. o. is processed
matrixcode-based inside of 0x247, which is called by GetKey.
To invoke those special behaviour, matrixcodes have to be injected (0x248,
0x24F).
0x0248: int
Keyboard_PutKeyCode(int X, int Y, int KeyCode);
If X and
Y both are below zero (-1,-1 or -2,-2), KeyCode is injected into
the keybuffer 0x880061DC.
The next call of GetKey returns this keycode. This is true both for the
emulator and the calc.
Any special key processing like MENU, SHIFT AC/on a. s. o. is processed
matrixcode-based inside of 0x247, which is called by GetKey.
To invoke those special behaviour, matrixcodes have to be injected (see below).
If X and Y are above or equal to zero, these codes are
injected into the matrixcode-buffers 0x880061BC and 0x880061CC.
KeyCode will be ignored. Example: MENU is 0x04, 0x09.
However, matrixcode-injection only works, while GetKey is already waiting. It
has to be performed f. i. from out of a timer
handler, which has to be started before GetKey is invoked!
Example:
static short
matrixcode = 0x020C; // OS
update contact
void TimerHandler(){
if ( matrixcode
){ Keyboard_PutKeyCode(
matrixcode >> 8, matrixcode &
0xFF, 0 );
};
matrixcode = 0; // only
once in this example
}
int AddIn_main(int
isAppli, unsigned short
OptionNum){
unsigned int key;
TIMER_Install( 6,
(void*)&TimerHandler,
1 );
TIMER_Start( 6
);
GetKey( &key );
TIMER_Deinstall( 6
);
...
0x24F: int
Keyboard_PutMatrixCode(short*matrixCode);
Every single byte of matrixCode is increased by
one and then injected into the matrixcode-buffers 0x880061BC and 0x880061CC.
Example: MENU is 0x0308 (the numbering differs from syscall 248 by 0x0101).
However, matrixcode-injection only works, while GetKey is already waiting. Is
has to be performed f. i. from out of a timer
handler, which has to be started before GetKey is invoked!
Example:
static short
matrixcode = 0x010B; // OS
update contact
void TimerHandler(){
if ( matrixcode
){ Keyboard_PutMatrixCode(
&matrixcode ); }
matrixcode = 0; // only
once in this example
}
int AddIn_main(int
isAppli, unsigned short
OptionNum)
see above
...
0x477: void
EnableGetkeyToMainFunctionReturn( void );
This call enables the
special MENU-key function.
0x478: void
DisableGetkeyToMainFunctionReturn( void );
This call disables
the special MENU-key function. After calling this function, it is not longer
possible to change to the main menu!
An application should not try to return with the special MENU-key function
disabled. The special MENU-key function has to be enabled, before leaving the
application.
0xA1F: void
Keyboard_RemapFKeyCode( TFKeyDef*workspace, TFKeyDef*source,
int mode );
The function installs
a table source, which is used to instruct syscall 0x90f
to return other values for FKey-hits than the default ones 0x7539..0x753E
workspace is used as working space and has to provide for a
TFKeyDef-array with 6 items.
It contains source on return.
mode has to be set to 1.
See 0x4CB for details.
0x4CB:
void Keyboard_RemapFKeyCode( int mode, TFKeyDef*source );
The function installs
a table source, which is used to instruct syscall 0x90f
to return other values for FKey-hits than the default ones 0x7539..0x753E
mode has to be set to 0.
f. i.
TFKeyDef source[6]={
0xICON0002, 0x00000001,
0xICON0002, 0x00000002,
0xICON0002, 0x00000003,
0xICON0002, 0x00000004,
0xICON0002, 0x00000005,
0xICON0002, 0x00000006}
A subsequent call of syscall 0x90f returns 1..6, instead of 0x7539..0x753E,
when a FKey is hit.
where
typedef struct{
int FKeyDef1;
int FKeyDef2;
} TFKeyDef;
FKeyDef1 holds the FKey-icon-number in its upper WORD. Its lower WORD normally
is 2.
A 3 as lower WORD would cause syscall 0x90f to return 0, if the correspondig
F-key is hit.
FKeyDef2 holds the keycode to return in its lower WORD. Its upper WORD
normally is 0.
Obvioulsly most of the system functions use this FKey-re-mapping. The display
of the icons is done with syscall 0x4B0.
0x6C4: int
Keyboard_PRGM_GetKey( TBCDvalue*result );
0x6C4 is the
PRGM-GetKey function and calls 0x247 with KEYWAIT_HALTOFF_TIMEROFF, t. i.
non-blocking.
result is a pointer to a 12 byte buffer. The buffer receives the
matrixcode as BCD-value.
In case of the slim the matrixcode is automatically converted to the standard
type's code! Hence the function is calctype-independent.
The function decrements the row-number by 1 to prevent the occurence of the
invalid BCD-digit "A". F. i. the key F1 yields 79, whereas syscall 0x0247
would return (0x07;0x0A) in this case.
Exception:
in case of the "AC/on"-key BCD-error 1 is returned, t. i. exponent==0xF00 and
first nibble of the mantissa==1.
If no key is available, the function returns a BCD-value 0 in result*.
The function's int-return-value is 0 in case of the "AC/on"-key, else 1.
To yield the same function result as PRGM-GETKEY one could use this:
int PRGM_GetKey(){
unsigned char buffer[12];
Keyboard_PRGM_GetKey(
buffer );
return
( buffer[1]
& 0x0F ) *
10 + ( (
buffer[2]
& 0xF0 ) >>
4 );
}
(26.05.2012 07:02:35)