[TI ASM] full key scan optimizing

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] full key scan optimizing

Post by King Harold »

I made a little routine:

Code: Select all

FullScan:	;stores resulting scan at HL, buffer should be 7 bytes
	ld c,1		; [7](2)
	ld b,$FF	 ; [7](2)
	ld e,$7F	 ; [7](2)
	ld d,e		; [4](1)
-: out (c),b	; [12](2)
	ld a,e		; [4](1)
	rlca		  ; [4](1)
	cp d		  ; [4](1)
	out (1),a	; [11](2)
	ret z		 ; [5/11](1)
	ld e,a		; [4](1)
	in a,(1)	 ; [11](2)
	ld (hl),a	; [7](1)
	inc hl		; [6](1)
	jr {-}		; [12](2)
and I was wondering: can I squeeze any more cc's or bytes out of this?
the last JR can be replaced by a JP to trade a byte for 2 cc's of course
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Instead of two loads for b and c:

Code: Select all

   ld bc,$FF01
User avatar
tr1p1ea
Maxcoderz Staff
Posts: 4141
Joined: Thu 16 Dec, 2004 10:06 pm
Location: I cant seem to get out of this cryogenic chamber!
Contact:

Post by tr1p1ea »

Same could be said for a load into DE.
"My world is Black & White. But if I blink fast enough, I see it in Grayscale."
Image
Image
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Uhm, yes got a point there, what about the rest though?
I meant that middle loop to be as fast as possible without being too fast for the hardware (so the ret is after that out)

edit: double loading makes it:

Code: Select all

	ld bc,$FF01	; [10](3)
	ld de,$7F7F	; [10](3)
-: out (c),b	  ; [12](2)
	ld a,e		  ; [4](1)
	rlca		    ; [4](1)
	cp d		    ; [4](1)
	out (1),a	  ; [11](2)
	ret z		   ; [5/11](1)
	ld e,a		  ; [4](1)
	in a,(1)	   ; [11](2)
	ld (hl),a	  ; [7](1)
	inc hl		  ; [6](1)
	jr {-}		  ; [12](2)

edit: that's why I asked, I can overlook things :oops:
CoBB
MCF Legend
Posts: 1601
Joined: Mon 20 Dec, 2004 8:45 am
Location: Budapest, Absurdistan
Contact:

Post by CoBB »

It seems to me that my way is faster besides being more straightforward. And there’s at least one obvious way to make the loop faster. Check out input.inc in the AG source, or look below for a copy of the code.

The main loss in your case is using both a ret and a jump to take care of the loop. You should really believe that djnz is your friend. ;)

Code: Select all

ReadKeyboard:      ; Fills 7 bytes at KeyPressed; if a key is pressed, the corresponding
 ld hl,KeyPressed  ; bit is set to ZERO. Works with disabled interrupts as well.
 ld b,7
 ld c,$fe
RK_Loop:
 ld a,$ff
 out (1),a
 ld a,c
 out (1),a
 in a,(1)
 ld (hl),a
 inc hl
 rlc c
 djnz RK_Loop
 ret
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 »

Code: Select all

   ld bc,$0701   ; [10](3)
   ld de,$FF7F   ; [10](3)
loop:
   out (c),d     ; [12](2)
   rlc e         ; [8](2)
   out (c),e     ; [12](2)
   nop           ; [4](1)
   nop           ; [4](1)
   ini           ; [16](2)
   jr nz,loop    ; [12](2)
   ret           ; [10](1)
You do realize that a port read is faster and smaller than most memory reads, right? The only faster smaller ones use more registers.
Image
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Thanks CoBB! :)
Should I point out that you also have RET and a jump there though? The CP sortof kills my routine lol I'll see what I can make of this

Code: Select all

FullKeyScan:
 ld hl,KeyPressed -1
 ld bc,$0701
 ld de,$FFFE
Loop:
 out (c),d
 inc hl
 out (c),e
 rlc e
 in a,(1)
 ld (hl),a
 djnz Loop
 ret
how about this?

edit: Posted before I saw Jim E's post: that looks cool! that's the fastest it will ever be is it not? *worships Jim E*
edit again: INI is brilliant!
CoBB
MCF Legend
Posts: 1601
Joined: Mon 20 Dec, 2004 8:45 am
Location: Budapest, Absurdistan
Contact:

Post by CoBB »

King Harold wrote:Should I point out that you also have RET and a jump there though?
Yes, but the ret is not inside the loop.

And yes, ini was invented for this kind of stuff. :)
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

CoBB wrote:Yes, but the ret is not inside the loop.
very true.. it added 5+4 needless cc's to that code of mine..
CoBB wrote:And yes, ini was invented for this kind of stuff. :)
It's brilliant! I don't see it often though
CoBB
MCF Legend
Posts: 1601
Joined: Mon 20 Dec, 2004 8:45 am
Location: Budapest, Absurdistan
Contact:

Post by CoBB »

King Harold wrote:It's brilliant! I don't see it often though
Well, the peripherals of the TIs are simply not the kind that allow block I/O instructions to be used in a meaningful way in most cases.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

You could make an array with the crystal timers :)
I doubt that has ever happened lol but it would be cool
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 »

King Harold wrote:You could make an array with the crystal timers :)
I doubt that has ever happened lol but it would be cool
Go check the Usb8x code, Dan doesn't just use ini, he uses inir and otir. The usb ports are probably the best opportunity to use them.
Image
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

That code is too big fit into my brains properly..
But I'll give it a try (it'll be the first time I'll get to see inir and otir in action so it'll be worth it :) )

edit: I found an otir!

Code: Select all

SendLoop:
       ld     b,d                         ;Send max size
       ld     a,e
       sub    d                           ;Unless bytes left - max packet carries
       ld     e,a
       jr     nc,$f
;       ld     b,e
       add    a,d
       ld     b,a
       ld     e,0                         ;This is the last packet
$$:

       LOG    DataStart,b
 IF  LOGGING_ON=0
       otir
 ELSE
 $$:
       ld     a,(hl)
       LOG    Data,a
       out    (c),a
       inc    hl
;       dec    b
       djnz   $b
 ENDIF
       push   bc
       ld     a,c
       sub    0A0h
       ld     b,a
       ld     c,01
not the end of the sendloop but no one wants to see all that on a forum anyway..
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

OTIR is frequently used on the Master System to dump data into VRAM. :) (You only need to be careful about timing during the active display period). It would be nice if we could do something similar with the TI display driver...
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

It would be uber cool if we could just OTIR a buffer to the screen! stupid slow lcd :(
Apparently the USB ports are fast enough though, it's a pity they're not fully documented (or are they? It's not all on wikiTI.. maybe someone is keeping it secret)
Post Reply