Lesson 11
 TI-82 ASM Corner :: Programming Guide :: Lesson 11 Back | Home | Search
Lesson 11 : Evaluating user input

In this lesson, you will learn how to handle keypresses in ASM programs. In this lesson we will use two calls (GET_KEY and KEY_HAND) from the ROM and one call included in CrASH (CR_KHAND). Key reading can also be done using ports, but that's for another lesson.

call GET_KEY | ROM_CALL(KEY_HAND) | call CR_KHAND | example

call GET_KEY

This call gives you the scancode of the key that is currently pressed. This scancode is stored in the A register. If there is no key pressed, A will be zero. The scancodes for all the keys are stored in the keys.inc file, e.g. G_NONE is no key and G_ENTER is the scancode for the enter key.

To evaluate this output you will need to learn two new instructions: CP and SUB.

SUB m

This instruction subtracts the contents of a certain register from the A register. The flags are set according to the answer. The m can be A,B,C,D,E,H,L,(HL),(IX+n),(IY+n) or a data byte.

Some valid examples:

 ``` sub a ; a = a - a = 0 sub b ; a = a - b sub (hl) ; a = a - (hl) sub (IY+\$05) ; a = a - (IY+\$05) sub 10 ; a = a - 10 ```

CP m

This instructions is identical to the SUB instruction, but it does not store the result in the A register. It does affect the flags, though. This way, CP is the ideal register for comparing things.

Suppose we do CP 10, here's what the flags can tell us :

Flags for CP 10
Z C Conclusion
1 (Z) 0 (NC) A is equal to 10
0 (NZ) 1 (C) A is smaller than 10
0 (NZ) 0 (NC) A is bigger than 10
1 (Z) 1 (C) Impossible

What does this mean?

• If the zero flag is set (Z), A is equal to 10.
• If the zero flag is not set (NZ), A is not equal to 10.
• If the carry flag is set (C), A is smaller than 10
• if the carry flag is not set (NC), A is bigger than or equal to 10

Example

Below is a little example of how you can work with GET_KEY. The routine will check if the ENTER or CLEAR key are pressed. If this is the case, a jump is made to some labels elsewhere in the program. If none of these keys is pressed, the program jumps back to the call GET_KEY line and checks the keys again.

 ```WaitForKey: call GET_KEY cp G_ENTER jr z,EnterPressed cp G_CLEAR jr z,ClearPressed jr WaitForKey ```
• ROM_CALL(KEY_HAND)

This call is somewhat different: when no key is pressed, the program does not continue, it just keeps waiting until a valid keypress is encountered. KEY_HAND can also detect 2nd functions and alpha. It is also possible to change the contrast or to take screenshots with your linkcable in this loop.

A dissadvantage is that KEY_HAND also handles 2nd-off. This will turn off the calc. No problem so far. But you might know that Ash relocates the program before it's started. This places the TI-OS in an unstable situation. When a program finishes, Ash normally de-relocates the program so that everything is stable again. When 2nd-off is pressed in a KEY_HAND call, the calc turns off and when it is turned back on, TI-OS is started with the calc still in the unstable state. Guess what happens then... CRASH!

With KEY_HAND, the scancodes are different also. the K_XXX codes from keys.inc are used here.

Example

This example is basically the same as the one I gave with GET_KEY, but I made this one also detect the 2nd-mode keypress and when another key was pressed, a jump is made to OtherKeyPressed.

 ``` ROM_CALL(KEY_HAND) cp K_ENTER jr z,EnterPressed cp K_CLEAR jr z,ClearPressed cp K_QUIT jr z,2nd_MODE_Pressed jr OtherKeyPressed ```

call CR_KHAND

This is a call that is included ONLY in CrASH. Programs that use this call can be compiled only for CrASH and will not run on Ash 3.0

The CR_KHAND call is almost identical to the ROM_CALL(KEY_HAND) call, but CrASH puts the RAM in a stable position before calling it. This way, the calculator won't crash when it is turned off during this loop. After the KEY_HAND romcall the program is relocated back to where it was when CR_KHAND was called and the program can continue.

One 'bad' thing with this routine is that CrASH will clear TEXT_MEM2, so you cannot have important information stored there when calling CR_KHAND.

Example

Once again the same example, but this time with CR_KHAND

 ``` call CR_KHAND cp K_ENTER jr z,EnterPressed cp K_CLEAR jr z,ClearPressed cp K_QUIT jr z,2nd_MODE_Pressed jr OtherKeyPressed ```

Bigger Example

For your pleasure, here's a full program demonstrating the handling of keypresses, the CP instruction and conditional jumps.

 ```.include "ti82.h" ; .include or #include, it's #include "keys.inc" ; exactly the same .org START_ADDR .db "KeyPress Example",0 ROM_CALL(CLEARLCD) ld a,'1' ; A contains ascii code for '1' Loop: ld hl,\$0804 ; row 4 col 8 ld (CURSOR_POS),hl ROM_CALL(TX_CHARPUT) ; write character in A to screen ld b,a ; save contents of A somewhere WaitForKey: CALL GET_KEY cp G_NONE jr z,WaitForKey ; no key pressed? -> keep waiting cp G_LEFT jr z,LeftKeyPressed cp G_RIGTH ; ** jr z,RightKeyPressed cp G_CLEAR ret z ; return when CLEAR key pressed jr WaitForKey ; else, keep waiting for key LeftKeyPressed: ld a,b ; get contents of A back dec a ; decrease contents of A jr nz,Loop ; if not zero, it is OK inc a ; if zero, put it back to one jr Loop RightKeyPressed: ld a,b ; get contents of A back inc a ; decrease contents of A jr nz,Loop ; if not zero, it is OK dec a ; if zero, put it back to \$FF jr Loop .end ```

Note **: I know that G_RIGHT is not how it is supposed to be spelled, but it is also misspelled in the keys.inc file.

This example places a character in the middle of the screen. When you start the program, the character is '1'. You can change it with the left and right keys. When the ascii code of the character is \$01 or \$FF, you can not change it to \$00. Exiting the program is done by pressing the clear key.

In this program, I also used conditions for the RET instruction. The ret instruction can take C,NC,Z,NZ,PO,PE,M and P as conditions.

New instructions

Here is a little table with all the new instructions from this lesson.

New instructions
Mnemonic Operation
SUB m Subtract from A, store answer in a
m can be A, B, C, D, E, H, L, (HL), (IX+n), (IY+n), N
CP m Compare A with m
m can be A, B, C, D, E, H, L, (HL), (IX+n), (IY+n), N
RET cc Return only if the condition is true
cc can be C, NC, Z, NZ, PO, PE, M or P

Previous lesson | Contents | Next lesson