initstabilise lda $d012 ldx #10 ; 2 - dex ; (10 * 5) + 4 bpl - ; 54 nop ; 2 eor $d012 - $ff,x; 5 = 63 bne initstabilise; 7 = 70 [...]; timer setup
start: ldx $d011 bpl start: loop: pha cpx $d012 pla inc safe_mem,x bcs loop:
sync: lda $d012 ; will be zero on cycles 0,1,2,3,4,5 or 6 bne sync .res 25,$ea ; replace this with 50 cycles of init code lsr $d012 ; if it's zero, either we're too early on line 0, or we're on line 256.. bcc sync ; fall through if we read on cycle 62, 56 after cycle 6
Like the mathematician's hypothetical can opener, let us assume we have 50 cycles worth of init code that we are happy to run as many as seven times over. Then we can sync with just ten bytes of code, in at most seven frames. sync: lda $d012 ; will be zero on cycles 0,1,2,3,4,5 or 6 bne sync .res 25,$ea ; replace this with 50 cycles of init code lsr $d012 ; if it's zero, either we're too early on line 0, or we're on line 256.. bcc sync ; fall through if we read on cycle 62, 56 after cycle 6 We use lsr instead of lda for the second test, as lda would result in a 63 cycle loop.
sync: ldy #val lax $d012 bne sync // here we are at cycle 3..9 of rasterline $00 (or 2..8 of rasterline $100) /* // 50 cycles of init code go here */ // after that init code block we are @cycle 53..59 of rasterline $00(52..58 of line $100) lda $d012 // the R-cycle occurs @cycle 57..63 -> 63 = cycle 0 of line 1 // in rasterline $100 this will end up @cycle 56..62, thus always without reaching the next line beq sync // branch not taken only when line 1 is reached
[...] sync: ldy #val lax $d012 bne sync // here we are at cycle 3..9 of rasterline $00 (or 2..8 of rasterline $100) /* // 50 cycles of init code go here */ // after that init code block we are @cycle 53..59 of rasterline $00(52..58 of line $100) lda $d012 // the R-cycle occurs @cycle 57..63 -> 63 = cycle 0 of line 1 // in rasterline $100 this will end up @cycle 56..62, thus always without reaching the next line beq sync // branch not taken only when line 1 is reached
sync: lax $d012 bne sync /* // 50 cycles of init code go here */ lda $d012 //-p-a-g-e-b-r-e-a-k- beq sync
sync: inc $d012 ; result will be zero on cycles 0-7 or 8 of raster line $ff bne sync ; (or very rarely, cycle 9..62) .res 27,$ea ; wait 62-8=54 cycles. Replace with 54 cycles of init code inc $d012 ; if result is nonzero then we are too late. bne sync ; carry on if we read on cycle 62, 62 cycles after cycle 0
sync: inc $d012 ; result will be zero on cycles 0-7 or 8 of raster line $ff bne sync ; (or very rarely, cycle 9..62) .res 27,$ea ; wait 62-8=54 cycles. Replace with 54 cycles of init code inc $d012 ; if result is nonzero then we are too late. bne sync ; carry on if we read on cycle 62, 62 cycles after cycle 0 edit: this one probably also compresses better than the earlier versions - the two code snippets both start with EE 12 D0 D0