[stella] Re: lovely bit of code

Subject: [stella] Re: lovely bit of code
From: "Andrew Davie" <adavie@xxxxxxxxxxx>
Date: Wed, 8 Jan 2003 02:43:22 +1100
Sorry for the HTML post :(
Accidental.  Following is text-version...

----- Original Message -----
From: Andrew Davie
To: stella@xxxxxxxxxxx
Sent: Wednesday, January 08, 2003 2:41 AM
Subject: lovely bit of code


Had to share this gem...

I have some very very tight code which needs to be in the form of a loop,
repeated several times by block-code-copying (using different variables
inside the loops)...  here's the basic loop shell...

.LAB1C
            nop            ; 2
            nop            ; 2
            nop            ; 6 cycles MUST be here

    ; blah code here.... no free cycles

            dec LoopCount1  ; 5
            bpl .LAB1C     ; 3(2)

now I need to immediately have another like the above, and it has to happen
with EXACT timing...
but the problem is, I've used one LESS cycle on the last iteration because
the branch wasn't taken

So this code won't work...

.LAB1C
            nop            ; 2
            nop            ; 2
            nop            ; 6 cycles MUST be here

    ; blah code here.... no free cycles

            dec LoopCount1 ; 5
            bpl .LAB1C     ; 3(2)

                ;<< NEED A 1-CYCLE (AND ONLY ONE CYCLE!) DELAY HERE!! -
CANNOT DO!
                            ; WELL, ONE *CAN* BUT NOT WITH THE PAGE
CONSTRAINT MENTIONED BELOW...
.LAB1D
            nop
            nop
            nop                    ; 6 cycles MUST be here

    ; blah code here.... no free cycles

            dec LoopCount2
            bpl .LAB1D


Yes, I could put a .byte before the .lab1d to turn the 2 cycle NOP into a
3-cycle instruction... but that solution doesn't work for me because...  a
further problem shows up.  The more of these blocks of code I put in, the
more likely it is that one of those branches will end up having to branch
over a page boundary, causing an extra cycle to be used and buggering things
up.  And, basically, I need a fair few of these blocks of code running one
after the other with NO cycles free.

So the two problems are that each of the loops must be entirely contained
within a page... AND I need to somehow get an extra cycle after the end of
each of the loops... but *ONLY* one extra cycle.

Here's the solution...


            jmp .LAB1C
            ALIGN 256      ; align this loop to a page boundary

.LAB1C      nop            ; 2
            nop            ; 2
            nop            ; 6 cycles MUST be here

    ; blah code here.... no free cycles

            dec LoopCount1 ; 5
            bpl .LAB1C     ; 3(2)        won't branch over a page!

            jmp NEAT       ; 3
            ALIGN 256      ; align the next loop to a page boundary

.LAB1D
            nop            ; 2
NEAT        nop            ; 2
            nop            ; 6 cycles MUST be here

    ; blah code here.... no free cycles

            dec LoopCount2 ; 5
            bpl .LAB1D     ; 3(2)



The addition of the "jmp NEAT" after the loop terminates allows the
insertion of the ALIGN to a page boundary... guaranteeing the 2nd loop (or
nth loop) won't be crossing a page.... and the jump jumps right into the
middle of the subsequent loop, skipping the first nop (2 cycles).  So the
jump + the remaining 2 nops gives 7 cycles which is  (6+1) ie: we've added
just one cycle for the first iteration of the loop only.

It's lovely - I just had to share it.

Cheers
A


----------------------------------------------------------------------------------------------
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/


Current Thread