[TI-ASM/hardware?] That silly key port

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

[TI-ASM/hardware?] That silly key port

Post by King Harold »

I noticed I sometimes couldn't get the key port to detect over 6 or 7 keypresses at a time (depending on the group, and less for the arrow group ofcourse)
Why does the key port behave like this?
User avatar
Timendus
Calc King
Posts: 1729
Joined: Sun 23 Jan, 2005 12:37 am
Location: Netherlands
Contact:

Post by Timendus »

I've had some weird behaviour with it too lately... Maybe there's a bug in PTI? :) Or perhaps I'm using routines that don't reset the key port properly.. I don't know.

I do know that it doesn't detect keypresses properly, and that that makes my program "feel" suckish...
http://clap.timendus.com/ - The Calculator Link Alternative Protocol
http://api.timendus.com/ - Make your life easier, leave the coding to the API
http://vera.timendus.com/ - The calc lover's OS
CoBB
MCF Legend
Posts: 1601
Joined: Mon 20 Dec, 2004 8:45 am
Location: Budapest, Absurdistan
Contact:

Post by CoBB »

If this is about emulation, then keep in mind that PC keyboards have limitations on what keys can be pressed simultaneously. As for the real calc, there might be something similar. I never experimented with this, although I seem to recall that pressing all arrow keys or something lits up (well, zeroes) an unused bit in the arrow group, at least on my calc.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

I don't really know what the problem in, but it seems ot have difficulties with F3 (group $BF ofcourse) and not with other combinations of F keys.
code to which this is happening:

Code: Select all

	ld a,$BF
	out (1),a
-:
	bcall(_homeup)
	ld a,$BF
	out (1),a
	nop
	nop
	in a,(1)
	call dispbits
	jr {-}
	
	ret
dispbits:
	ld c,a
	ld a,$30
	ld d,a
	ld b,8
-:
	rl c
	ld a,d
	adc a,0
	bcall(_PutC)
	djnz {-}
	ret
Oh also, pressing the [STAT] button gives the same result as pressing [8] [LeftBrack] and [cos(] at the same time (on hardware).
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

You need to clear the key port (output $FF to it) before using other masks, as subsequent masks are ANDed (or similar?) with the existing one. Try adding an ld a,$FF \ out (1),a in there and seeing if that helps matters.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

I know about the $FF, but seeing as this practically works (perhaps the bcall's something to do with it?) in most cases, except the one with F3 combined with a lot of other Fkeys and esc and shift (seriously - try it)
It didn't seem to be needed since it works all fine except for the rare case of F3, and on hardware something is happening to a completely different program, which makes [STAT] look like [cos(] AND [8] AND [leftbrack] which all are in the same group (strange or what?).

I tried it - out-ing FF doesn't help. Thanx for reminding me anyway ;)
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Alright, the keyport is weird. It would have been logical if it CPL-ed everything first, but we'll have to live with it.
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Hm? How do you mean?

If you're referring to the way that buttons pressed are zero, and buttons released are one, remember that the Z80 tends to favour active-low logic and so it does make some sort of sense.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Ofcourse it does, for itself :P
but I tend to think active-high :)
But I'll get used to it, I allready got used to little-endian, so I think I can get used to active-low aswell ;)
User avatar
Halifax
Sir Posts-A-Lot
Posts: 225
Joined: Mon 01 Jan, 2007 10:39 am
Location: Pennsylvania, US

Post by Halifax »

You do not have to clear the key port before detecting the keys pressed from different ports and its been proven true ever since I used 4 different key sets in one loop and the program worked fine
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Post by Liazon »

er, iirc clearing the keyport is just so that keys w/ the same keycode but different groups won't set of the key bit. it's not that the keys you're interested in won't work, it's just that other keys will probably work too.

duno why they would design a keyboard that way, but i heard someone mentioning that not clearing the keyboard would make checking all keys faster somehow. like i said before, duno how that's helpful if a bunch of keys from different groups can all activate the same bit.
Image Image Image
User avatar
Jim e
Calc King
Posts: 2457
Joined: Sun 26 Dec, 2004 5:27 am
Location: SXIOPO = Infinite lives for both players
Contact:

Post by Jim e »

Halifax wrote:You do not have to clear the key port before detecting the keys pressed from different ports and its been proven true ever since I used 4 different key sets in one loop and the program worked fine
No, you do. You have likely encountered a situation that works for you because of the circumstance.

My guess is, that you are checking the keys in different groups sequentially and jumping away from the checks. So that when the first key gets check you don't bother going through the others. What this means is that when you check the next group you are less likely to get a bad read because you weren't pressing any keys in the prior group.

Another possibility is that you are checking the arrow keys then another group, if in the other group you only check bits 4-7 then there will be no interaction. The upper 4 bits from the arrow group are unused, so it should never cause a problem.

There may also simply just be some key port resets in there that you don't know about, for example enough halts and TI will reset the port it self.


necropost
Image
User avatar
driesguldolf
Extreme Poster
Posts: 395
Joined: Thu 17 May, 2007 4:49 pm
Location: $4080
Contact:

Post by driesguldolf »

hmmm I have some questions on all this keyport stuff:
in 83pa28d it says nothing about resetting the keybord but the stuff everyone says seems logic, also some people do put two "nop"s between reading and writing and others dont??? whenever other people dont write the nops it works fine, when I try that it doesnt... any suggestions?

I also made my own getcsc routine in wich I don't reset the port and everything works fine (this is unlikely to be buggy because he checks all the values)???
User avatar
Jim e
Calc King
Posts: 2457
Joined: Sun 26 Dec, 2004 5:27 am
Location: SXIOPO = Infinite lives for both players
Contact:

Post by Jim e »

driesguldolf wrote:hmmm I have some questions on all this keyport stuff:
in 83pa28d it says nothing about resetting the keybord but the stuff everyone says seems logic, also some people do put two "nop"s between reading and writing and others dont??? whenever other people dont write the nops it works fine, when I try that it doesnt... any suggestions?
28days doesn't tell you to reset the keypad? That's really bad.

The keypad is running on a driver, So it takes a bit of time to process everything. Typically on the old 83's that time is nearly non existent,l so it was mostly okay not to put the nop's. Probably be an issue if you tested several groups quickly.

If you plan to have your program run on the 84 and the like, than you may need more than 2, especially if its gonna run at 15mhz.

Getcsc is an instance where you probably wont need to reset the key port.
Image
User avatar
driesguldolf
Extreme Poster
Posts: 395
Joined: Thu 17 May, 2007 4:49 pm
Location: $4080
Contact:

Post by driesguldolf »

Jim e wrote:28days doesn't tell you to reset the keypad? That's really bad.
Nope it doesn't, altough it uses the reset in an example program but only mentions "Resets the keybord" as a comment, not really useful :S .
Jim e wrote:The keypad is running on a driver, So it takes a bit of time to process everything. Typically on the old 83's that time is nearly non existent,l so it was mostly okay not to put the nop's. Probably be an issue if you tested several groups quickly.
That's correct but some people don't put the nops but do change the keygroup rapidely (I don't have an example tough), anyway the nops method works so I'm happy :) .
Jim e wrote:If you plan to have your program run on the 84 and the like, than you may need more than 2, especially if its gonna run at 15mhz.
It does work fine if it's running in slow mode (wich it is always unless you change it manually)
Jim e wrote:Getcsc is an instance where you probably wont need to reset the key port.
You think?

Code: Select all

.module scankeypad
;----------------------------------------------------------------
;		Scans the keypad for keys
;----------------------------------------------------------------
;Author		Dries Guldolf
;Output		A	Key pressed
;		z-flag	Set if A is not zero, reset otherwise	
;Variables	byte	(lastkey)	Holds the key that is being pressed
;Destroys	flags, BC, D
;Remarks	Defines lastkey inside itself if allowsmc is defined (faster)
;		If multiple keys are being pressed it returns only the first one (as listed)
;		If no key is being pressed
;			A=0, D=sk_nokey, (lastkey)=0
;		If a key is being pressed but has already been registered
;			A=0, D=key, (lastkey)=key
;		If a new key is pressed
;			A=key, D=key, (lastkey)=key
;		If you regular reset (lastkey) then keys will be reread
;Other	Version	1.2
;	Size	39 bytes (38 if allowsmc is defined)

scankeypad:
	ld d, 1			; Keys start from 1
	ld c, $BF		; Start key group ($BF)
_grouploop:
	ld a, c			; Set the key group we're going to read from
	out (1), a		;
	nop			; The keybord needs time to react from the change of keygroup
	nop			;
	in a, (1)		; Time to see if a key is being pressed
	ld b, 8			; Eight keys to check
_keyloop:
	rrca			; Maybe this key is pressed
	jr nc, _keyfound	; Stop if it is pressed
	inc d			; Next key
	djnz _keyloop		;
	rrc c			; Next group
	jr c, _grouploop	;
	xor a			; If there was no key pressed
	ld (lastkey), a		; reset A and (lastkey)
	ret			; Note that the z-flag is reset
_keyfound:
#ifdef allowsmc
lastkey		equ	$ + 1	; Define lastkey inside the program if allowsmc is defined
	ld a, 0			;
#else
	ld a, (lastkey)		; Otherwise fetch it
#endif
	sub d			; Check if the key was already pressed last time
	ret z			; Note that A is zero and the z-flag is reset
	ld a, d			; Set the new key
	ld (lastkey), a		;
	ret			; Note that the z-flag is set because the processor passed a "RET Z" instruction
hmmm, can I change the tab length to 8 "spaces"?
Last edited by driesguldolf on Fri 18 May, 2007 7:53 am, edited 1 time in total.
Post Reply