[TI-ASM] key scanner with low values

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] key scanner with low values

Post by King Harold »

Some time ago I made a keyscanner which returns nice low scan values, $38 I think is the highest. The purpose of this was that the highest 2 bits would be free to put the Alpha and Shift flags in, to get a complete keycode.
I thought it would be nice to share, since someone might have use for it..

Code: Select all

	ld bc,$0701
	ld de,$FEFF
	ld hl,$0800
-:	out (c),e
	push hl	;delay
	out (c),d
	sll d
	pop hl		;delay
	in a,(1)
	xor e   ;edited to save a byte and 3 tstates (thanx spencer, I didn't see it)
	jr nz,{+}
	ld a,l
	add a,h
	ld l,a
	djnz {-}
	xor a
	ret     ;edited to return the code in A
+:
-:	inc l
	rra
	jr nc,{-}
	ld a,l   ;edited to return the code in A
	ret
note that it returns the scancode in L, not A.
This routine obviously is not optimal, but it works (that is, it returns the right scancode)

edit: I originally returned the code in L because I would load something else in H and then save them off at the same time, but if everyone wants it to be in A that's fine

these are the scancodes:
(I did NOT make a mistake with the inconsistent $ !)
some names may be mis-spelled so watch out.

Code: Select all

skdown		=	1
skleft		=	2
skright	=	3
skup		=	4
skgraph	=	$31
sktrace	=	$32
skzoom		=	$33
skwindow	=	$34
skyequ		=	$35
sk2nd		=	$36
skalpha	=	$30
skmode		=	$37
skdel		=	$38
skgraphvar	=	$28
skstat		=	$20
skmath		=	$2F
skapps		=	39
skprgm		=	31
skvars		=	23
skclear	=	15
skrecip	=	46
sksin		=	38
skcos		=	30
sktan		=	22
skpow		=	14
sksquare	=	45
skcomma	=	37
sklparen	=	29
skrparen	=	21
skdiv		=	13
sklog		=	44
sk7		=	36
sk8		=	28
sk9		=	20
skmul		=	12
skln		=	43
sk4		=	35
sk5		=	27
sk6		=	19
skminus	=	11
sksto		=	42
sk1		=	34
sk2		=	26
sk3		=	18
skadd		=	10
sk0		=	33
skdcpt		=	25
skneg		=	17
skenter	=	9
Last edited by King Harold on Sat 25 Aug, 2007 10:10 am, edited 1 time in total.
User avatar
Halifax
Sir Posts-A-Lot
Posts: 225
Joined: Mon 01 Jan, 2007 10:39 am
Location: Pennsylvania, US

Post by Halifax »

Just in case.

SPASM compatible version

Code: Select all

   ld bc,$0701
   ld de,$FEFF
   ld hl,$0800
_   
   out (c),e
   push hl   ;delay
   out (c),d
   sll d
   pop hl      ;delay
   in a,(1)
   xor $FF
   jr nz,+_
   ld a,l
   add a,h
   ld l,a
   djnz -_
   ld l,0
   jr ++_
_   
   inc l
   rra
   jr nc,-_
_  
   ret
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

ah obviously that last jr should be a ret..

as I said, it's not optimal :P
Spencer
Extreme Poster
Posts: 346
Joined: Mon 17 Jan, 2005 8:56 am
Location: Indiana

Post by Spencer »

Code: Select all

#define make16(vh, vl) vh << 8 + vl
   ld bc,make16(7, 1)
   ld de,make16($FF, $FF)
   ld hl,make16(8, 1)
input_loop:  
   out (c),e
   sll d
   out (c),d
   in a,(1)
   xor e
   jr nz,bit_to_value
   ld a,l
   add a,h
   ld l,a
   djnz input_loop
   xor a
   ret
bit_to_value:   
   inc l
   rra
   jr nc,bit_to_value
   ld a,l
   ret
Don't overuse temp labels
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Thanx for optimizing it ;)
*goes to upgrade my code*

edit: d has got to be $FE though, not $FF
User avatar
Halifax
Sir Posts-A-Lot
Posts: 225
Joined: Mon 01 Jan, 2007 10:39 am
Location: Pennsylvania, US

Post by Halifax »

I wasn't trying to. I was just keep it concurrent with his code considering I really didn't know what he was doing.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

It is really almost the standard key scanner, except that I do stuff with L to keep the values as low as easily possible, they could be slightly lower since there are 'gaps' in the keyboard, places that you can test but do not have a key: bit 5 through 7 in group FE, the on key, and bit 7 in groups FD and FB.

I overused reusable labels a bit because well, they are reusable anyway, and they don't hurt do they?
User avatar
Halifax
Sir Posts-A-Lot
Posts: 225
Joined: Mon 01 Jan, 2007 10:39 am
Location: Pennsylvania, US

Post by Halifax »

Hmm I don't know I thought he was talking to me.

Generally I only use local labels for if-then type stuff and nothing else that deserves a real label.
Spencer
Extreme Poster
Posts: 346
Joined: Mon 17 Jan, 2005 8:56 am
Location: Indiana

Post by Spencer »

King Harold wrote:Thanx for optimizing it ;)
*goes to upgrade my code*

edit: d has got to be $FE though, not $FF
It's $FF, since the value is shifted first before being output.
King Harold wrote:I overused reusable labels a bit because well, they are reusable anyway, and they don't hurt do they?
That's not the point -- they hurt people reading your code.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Ok, but anyway, SLL on $FF doesn't do very much does it?
To my knowledge it will always stay $FF that way
Ok so this way removes the need for additional delays, but how does it work?
Spencer
Extreme Poster
Posts: 346
Joined: Mon 17 Jan, 2005 8:56 am
Location: Indiana

Post by Spencer »

Ah I see what you meant to do. SLL doesn't exist as its mnemonic suggests, you oughta use SL1 (they're the same binary).

Code: Select all

#define make16(vh, vl) vh << 8 + vl
   ld bc,make16(7, 1)
   ld de,make16($FF, $FF)
   ld hl,make16(8, 1)
input_loop: 
   out (c),e
   out (c),d
   sl1 d
   in a,(1)
   xor e
   jr nz,bit_to_value
   ld a,l
   add a,h
   ld l,a
   djnz input_loop
   xor a
   ret
bit_to_value:   
   inc l
   rra
   jr nc,bit_to_value
   ld a,l
   ret
You can put delays as you feel necessary
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Ok that works :)
SLL/SL1 or even SLIA (z80 bits) are a bit odd, sl1 would be the only mnemonic with a digit in it, and no one seems to use the same mnemonic for the opcode it translates to :P

I would suggest something between the two outs.. especially on SE's and 84's, something like ld a,(hl) perhaps?
User avatar
driesguldolf
Extreme Poster
Posts: 395
Joined: Thu 17 May, 2007 4:49 pm
Location: $4080
Contact:

Post by driesguldolf »

I haven't completely read everything, but in this case I think you should use a rotate instead of a shift because the rest of the mask consists of ones.

btw: You shouldn't spend so much time on optimizing a key read thingy, because It won't be executed that much times to make a real difference, does it? I've learned that lesson a while ago: "Know when to optimize". Altough you do it probabely for esthetic reasons or for the fun :D
User avatar
Halifax
Sir Posts-A-Lot
Posts: 225
Joined: Mon 01 Jan, 2007 10:39 am
Location: Pennsylvania, US

Post by Halifax »

I know when to optimize, and that is all the time. It does matter how many times it is called or not. Always optimize. Optimizing for size or speed does not matter.
User avatar
driesguldolf
Extreme Poster
Posts: 395
Joined: Thu 17 May, 2007 4:49 pm
Location: $4080
Contact:

Post by driesguldolf »

I meant that (ex) in a critical loop in your game you should optimize for speed and for loading stuff or things that barely get executed (ex showing 'game over') you should optimize for size, in that sense I wasn't clear enough, yes always optimize. But if you optimize everything (I mean that ex if you spend 2 weeks to optimize the intro screen for speed) you will waste tons of valuable time

That's my opinion tough :P
Post Reply