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
Haha well if we can pad with other code, just put something else that doesn't touch X in place of dex:bmi *-1, and we're down to 10 bytes :)
and put all the init code somewhere that'll be overwritten by decrunched graphics or mainloop code.
With 63 cycles per line on PAL, the delay between the reads must be 63 cycles (and not 62), reading $d012 at cycle 0 and cycle 63 of a video frame's last line (311), which is one cycle longer due to the vertical retrace.
Quoting KrillWith 63 cycles per line on PAL, the delay between the reads must be 63 cycles (and not 62), reading $d012 at cycle 0 and cycle 63 of a video frame's last line (311), which is one cycle longer due to the vertical retrace. Funny, didn't know that. Does Vice emulate it? Hoxs doesn't.
/* Line 0 is 62 cycles long, while line (SCREEN_HEIGHT - 1) is 64 cycles long. As a result, the counter is incremented one cycle later on line 0. */
Ah, bummer. This is the correct one with even-numbered lines only. =)initstabilise ldx #10 lda $d012 lsr ; 2 asl ; 2 - dex ; (10 * 5) + 4 bpl - ; 54 cmp $d012 ; 4 = 62 bne initstabilise; 9 = 71
initstabilise ldx #10 lda $d012 lsr ; 2 asl ; 2 - dex ; (10 * 5) + 4 bpl - ; 54 cmp $d012 ; 4 = 62 bne initstabilise; 9 = 71
newline_loop: ldx #$f7 lda $d012-$f7,x and inc_opcode:#$e8 //-p-a-g-e-b-r-e-a-k bne inc_opcode cmp $d012 bne newline_loop
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