I've been doing some power/reset research and have found justification for the "PPU warmup" code. I tested the following after power and reset to see if the PPU address was set to $1111. After power, it failed 50% of the time (10 trials). After reset, it failed 11% of the time (50 trials).
The VBL flag is set about half the time at power, and 11% of the time at reset (when reset is pressed while the flag is set, most likely). The VBL flag is next set at reset+27383 CPU clocks. Writes to $2006 are ignored until reset+29658 CPU clocks. So merely waiting until two $2002 reads have the high bit set isn't enough if you plan on writing to $2006 immediately after. Adding one more $2002 read makes it work every time after power and reset:
$2006 isn't the only register I've found to be ignored like this, just one example that justifies this warmup wait.
Code:
reset: sei ; Standard init
cld
ldx #$FF
txs
inx
stx $2000
stx $2001
: bit $2002 ; wait for VBL flag
bpl :-
: bit $2002 ; wait for VBL flag again
bpl :-
lda #$11 ; VADDR=$1111
sta $2006
sta $2006
cld
ldx #$FF
txs
inx
stx $2000
stx $2001
: bit $2002 ; wait for VBL flag
bpl :-
: bit $2002 ; wait for VBL flag again
bpl :-
lda #$11 ; VADDR=$1111
sta $2006
sta $2006
The VBL flag is set about half the time at power, and 11% of the time at reset (when reset is pressed while the flag is set, most likely). The VBL flag is next set at reset+27383 CPU clocks. Writes to $2006 are ignored until reset+29658 CPU clocks. So merely waiting until two $2002 reads have the high bit set isn't enough if you plan on writing to $2006 immediately after. Adding one more $2002 read makes it work every time after power and reset:
Code:
reset: ...
bit $2002 ; clear VBL flag (ADDED)
: bit $2002 ; wait for VBL flag
bpl :-
: bit $2002 ; wait for VBL flag again
bpl :-
...
bit $2002 ; clear VBL flag (ADDED)
: bit $2002 ; wait for VBL flag
bpl :-
: bit $2002 ; wait for VBL flag again
bpl :-
...
$2006 isn't the only register I've found to be ignored like this, just one example that justifies this warmup wait.