As mentioned in the last blog entry, timing is cricical down to the cycle. In order to make sure all branches of code execute in the exact same amount of time I’ve created a delay macro. This isn’t an optimal method, I’m sure there are ways to reduce the number of bytes this uses however it does the job, at least it does after a little debugging.

; DELAY for a specified number of clock cycles
; EXPECTS:
;    "counter" 1 byte variable defined
DELAY MACRO clocks
; eat up clock cycles 10 at a time
IF ( (clocks / 10)> 0)
   mov counter, #(clocks / 10)         ; 2
   :loop
      jmp $ + 1                           ; 3 jmp to next instruction
      jmp $ + 1                           ; 3 jmp to next instruction
      djnz counter, :loop                 ; 2/4  (4 if <> zero)
                                          ; 10 cycles per loop, 8 for last loop
ENDIF

; handle remaining delay 1-9 using nops
IF ( (clocks // 10)> 0)
   REPT (clocks // 10)
      NOP                              ; 1 
   ENDR                                
ENDIF

ENDM

After coding the above delay macro, I programmed it into the SX52 and put the SXkey into debug mode which allows you to single step the processor one instruction at a time and view the programs memory/registers and flags. Using various delays of 1, 7, 10, 14 etc I noticed the NOP repeat was only generating a single nop rather than the expected number, this turned out to be because of a missing ENDR directive

The following screenshot (click for a larger view) shows the debugger running the DELAY(14) code and circled in red is the lone NOP instruction. A simple mistakebut one I’m glad I caught early. I might have wasted hours debugging video code later on.

Delay Debugging

Delay Debugging

With the delay loop out of the way, it’s time to make a start on generating accurate h/v signals. Hopefully by the end of tonight.