SuperH-based fx calculators
fx legacy: keyboard

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 );
Ge
ts 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)