Karma Universe - demuynck.org 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