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