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.
After coding up the above 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 missed the ending ENDR directive
-
;
-
; 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
The following screenshot (click for a larger view) shows the debugger running the DELAY(14) code and circled in red the lone NOP instruction. A simple mistake putting an extra slash but one which would if not caught render the video output useless. Glad I caught it early, otherwise I might have wasted hours debugging my video code.
With the delay loop out of the way, its time to final make a start on generating accurate h/v signals. Hopefully by the end of tonight ![]()




