Search code examples
assemblydelay68000easy68k

Delay Loop in 68k Assembly


I want to write a delay loop in assembly. It shall create a delay of N cycles.

My idea was to create a for loop and iterate over the NOP instruction. In this case, would I have to decrease N by the number of cycles caused by other parts of the program, such as calling the for loop? Moreover, does each iteration of the for loop count as 1 cycle or 2 cycles?

In the best case - does anyone have an implementation of such a delay cycle?


Solution

  • There is no 68k instruction that would execute in exactly one cycle. Even a simple NOP already takes four cycles - so you will need to adjust your expectations a bit.

    The most simple delay loop one can imagine is

           move.w #delay-1,d0
    loop:  dbf    d0,loop       ; 10 cycles per loop + 14 cycles for last 
                                ; (branch not taken) 
    

    This will delay delay * 10 number of cycles. Note that delay is word-sized, so the construct is limited to delays between 14 and 65534 cycles. If you want a wider range, you need to use a different construct that uses long word counters:

           move.l  #delay,d0
           moveq.l #1,d1
     loop: sub.l   d1,d0        ; 6 cycles for Dn.l->Dn.l
           bne.s   loop         ; 10 cycles for branch
    

    This eats 16 cycles per iteration. It does, however, accept a long word loop counter.

    If you want to increase the achievable delay, you may think about nested delay lops or more complex instructions and addressing mode inside the loop. These two are, however, the shortest possibe delay loops.