[TI ASM] Fastest way to check for a keypress

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

Post Reply
User avatar
L4E_WakaMol-King
Maxcoderz Staff
Posts: 342
Joined: Tue 01 Nov, 2005 6:34 am

[TI ASM] Fastest way to check for a keypress

Post by L4E_WakaMol-King »

What is the fastest method to check if a certain key (in this care the right arrow) key is being pressed at a particular moment? I don't want a looping check like _getkey... just a "check if it's pressed, and it not, move on" kind of thing.
Image - Now Under Development - [Progress]
CoBB
MCF Legend
Posts: 1601
Joined: Mon 20 Dec, 2004 8:45 am
Location: Budapest, Absurdistan
Contact:

Post by CoBB »

Direct input. It takes three port accesses altogether:

1. output $ff to (1)
2. output group mask ($fe for arrow keys) to (1)
3. input state from (1); in the case of arrows bits 0-3 correspond to down, left, right, up, respectively; a zero bit means a key being pressed
User avatar
NanoWar
Extreme Poster
Posts: 365
Joined: Fri 17 Dec, 2004 6:39 pm
Location: #$&"%§!
Contact:

Post by NanoWar »

Code: Select all

	ld	a,0ffh
	out	(1),a
	ld	a,Group1
	out	(1),a
	in	a,(1)
	cp	KRight
	...
Key codes (long):

Code: Select all

;0ffh - resets the keyboard
Group1      =0feh
Group2      =0fdh
Group3      =0fbh
Group4      =0f7h
Group5      =0efh
Group6      =0dfh
Group7      =0bfh

;Group 1
KDown       .equ 254
KLeft       .equ 253
KRight      .equ 251
KUp         .equ 247

;Group 2
KEnter      .equ 254
KPlus       .equ 253
KMinus      .equ 251
KMul        .equ 247
KDiv        .equ 239
KPower      .equ 223
KClear      .equ 191

;Group 3
kMinus2     .equ 254 
kThree      .equ 253
kSix        .equ 251
kNine       .equ 247
kRbracket   .equ 239
kTan        .equ 223
kVars       .equ 191

;Group 4
KPoint      .equ 254
KTwo        .equ 253
KFive       .equ 251
KEight      .equ 247
KLbracket   .equ 239
KCos        .equ 223
KPrgm       .equ 191
KStat       .equ 127

;Group 5
KZero       .equ 254
KOne        .equ 253
KFour       .equ 251
KSeven      .equ 247
KComma      .equ 239
KSin        .equ 223
KMatrx      .equ 191
KX          .equ 127

;Group 6
KSto        .equ 253
KLn         .equ 251
KLog        .equ 247
kX2         .equ 239
kX-1        .equ 223
kMath       .equ 191
kAlpha      .equ 127

;Group 7
KGraph      .equ 254
KTrace      .equ 253
KZoom       .equ 251
KWindow     .equ 247
KY          .equ 239
k2nd        .equ 223
kMode       .equ 191
kDel        .equ 127
Revolution Software
CoBB
MCF Legend
Posts: 1601
Joined: Mon 20 Dec, 2004 8:45 am
Location: Budapest, Absurdistan
Contact:

Post by CoBB »

NanoWar wrote:

Code: Select all

	ld	a,0ffh
	out	(1),a
	ld	a,Group1
	out	(1),a
	in	a,(1)
	cp	KRight
	...
Never use cp! It will fail if there is another key pressed in the same group. Either use and (destructive) or a bit instruction (which is practically a nondestructive and).
User avatar
NanoWar
Extreme Poster
Posts: 365
Joined: Fri 17 Dec, 2004 6:39 pm
Location: #$&"%§!
Contact:

Post by NanoWar »

So you are doing:

Code: Select all

    bit     X,a     ;X = 0-7
    jp      z,...   ;is the z flag set if true?
?
Revolution Software
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Post by Liazon »

Code: Select all

    and     X,a     ;X = 0-7
    jp      z,...   ;is the z flag set if true?
?

why shouldn't you use cp? I don't get it, I are you saying all the keys in the group will register? Also, how will you check multiple keys in the same group?
Image Image Image
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Let's say you have two keys pressed in a keygroup. The value you read from the port would look like this:

Code: Select all

    in a,(1) ; suppose %10111110 read from key port

key_1 = %10111111 ; Assume these are key constants
key_2 = %11111110
The two zeroes are the two keys pressed in that group. Evidently, cp key_1 or cp key_2 won't work, even though both are pressed. You'd need to do something like this...

Code: Select all

    in a,(1) ; suppose %10111110 read from key port

    bit 6,a
    jr nz,_key_1_not_pressed

    ; Key 1 is pressed

_key_1_not_pressed

    bit 0,a
    jr nz,_key_2_not_pressed

    ; Key 2 is pressed

_key_2_not_pressed
...in which case both code blocks will be run.
User avatar
NanoWar
Extreme Poster
Posts: 365
Joined: Fri 17 Dec, 2004 6:39 pm
Location: #$&"%§!
Contact:

Post by NanoWar »

I'm not sure how you use "bit" correctly.
Edit: Cross post benryves: "bit X,a ; X=0-7" seems to be right.

Multiple key presses:
Look at this:

Code: Select all

KDown       .equ 254 ; = %11111110
KLeft       .equ 253 ; = %11111101
KRight      .equ 251 ; = %11111011
KUp         .equ 247 ; = %11110111
When you press right and up at the same time the result will become

Code: Select all

%11111011
%11110111 + (and)
-----------------
%11110011 (=243)
Revolution Software
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

The bit instructions are very useful. Going with bit (for testing) there are set and res (which you might know from setting/resetting bits on the OS flags).
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Post by Liazon »

and example please? I've been checking all 8 arrow key cases in the past.
Image Image Image
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Code: Select all

    ld a,$FF
    out (1),a 
    ld a,Group1 
    out (1),a 
    in a,(1)
    ld b,a ; Assume that move_* doesn't destroy b

    bit 0,b \ call z, move_down
    bit 1,b \ call z, move_left
    bit 2,b \ call z, move_right
    bit 3,b \ call z, move_up
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

What I do is I write the key pressed into memory. By xoring the last key with the current key, you can detect key presses or releases as well. Yes Kerm Martian, I'm talking to you. :)

ld a,$FF
out (1),a
ld a,<some key group>
out (1),a
in a,(1)
cpl
ld b,a
ld a,(key)
xor b
ld (keychanges),a
ld a,b
ld (key),a

Then to check the keys in the group, I use the AND instruction with the compliment of the key equate.
and ~kLeft

To check if a key has been pressed (not held down, but pressed), just check if (key & ~kLeft) && (keychanges & ~kLeft). To detect key releases, use !(key & ~kLeft) && (keychanges & ~kLeft). Sorry for the C syntax, I just use it all the time.
You know your hexadecimal output routine is broken when it displays the character 'G'.
Post Reply