Be careful.
Code: Select all
RESET:
SEI ; Ignore Interupts
LDA #$00 ; Load zero.
STX $2000 ; Store it to $2000 (PPU - graphics) - disable NMI
STX $2001 ; Store it to $2001 (PPU - graphics) - disable rendering
STX $4010 ; Store it to $4010 (DMC IRQ) - disable DMC IRQ
STX $4015 ; Store it to $4015 (APU) - disable APU sound
You're storing X which has an undefined value at this point. Replace those STXs with STA so you're storing zero and not whatever was in X before you reset the game.
Don't mess with the scroll ($2005) outside of the NMI until you really know what you're doing.
Code: Select all
BNE LoadNametableLoop
LDA #$00
STA $2005
LDA #%00011110
STA $2001
What's more $2005 (and $2006) are double-write registers. Typically if you stored the same value to the same location (like... say RAM) twice in a row, it wouldn't be different than doing it once. This is not true for double write registers, where writing to them twice in a row will make the same value do different things. There's no real way to know which write will affect which thing unless you reset them, which you do by reading $2002.
Code: Select all
lda #$00
sta $2005;This will affect either the X or Y scroll value.
lda #$20
sta $2005;This will affect which scroll value that the previous write DIDN'T. (If the first write changed X, this would change Y. If the first write changed Y, this would change X.)
So with the above code alone, you might end up with an X scroll value of $00 and a Y scroll value of $20, or you might end up with an X scroll value of $20 and a Y scroll value of $00. To avoid this Schrodinger's code, read $2002 first and always write to $2006/$2005 twice.
Code: Select all
bit $2002;(This reads from $2002 without changing A. If you don't care if A is changed, LDA will work too)
lda #$00
sta $2005;This will set the X scroll to $00.
lda #$20
sta $2005;This will set the Y scroll to $20
You are doing this properly with your $2006 code in your NMI:
Code: Select all
LDA $2002
LDA #$3F
STA $2006
LDA #$00
STA $2006
You read $2002 which makes sure the first write will set the high byte of the address. Another interesting thing is that $2005 and $2006 share the same "toggle". So if after the above code, you wrote a value to $2005, it would reliably write the X scroll. You would not need to read $2002 again to ensure this.
Therefore, this would be fine:
Code: Select all
LDA $2002
LDA #$3F
STA $2006
LDA #$00
STA $2006
LDX #$00
LoadPal:
LDA PaletteData,x
STA $2007
INX
CPX #$20
BNE LoadPal
lda (whatevervalue you need for $2000)
sta $2000
lda #$00
STA $2005 ;X scroll is zero
STA $2005 ;Y scroll is zero
As stated by rainwarrior, $2005/$2000 need to be rewritten after any writes to $2006/$2007 are made, and they need to be done after those writes are complete.