Hi all. Just Hundo here still mudding through tuts. I started the Nerdy Nights scrolling tutorials and there is some logic weirdness going that I don't understand in one of his examples. In the example, bunny swaps the nametable to ensure that scrolling continues properly from left to right across the screen. He does this by doing a swap check at the start of NMI to see what nametable is scrolling from left to right at the current moment. When the screen wraps from 255 to 0 in its scroll The swap check uses EOR to flip bit 0 in a flag variable named "nametable" which is to be used later in NMI.
The $2000 write at the end of NMI is manipulated by ORA'ing the value with the value previously stored into the nametable variable. My question is, why does ORA work here to continually flip the bits. Logically, it shouldn't work in my mind. Only EOR should work, and in fact, if I change the ORA to EOR it DOES work and I get the exact same visual result in scrolling as using ORA. The reason I think ORA shouldn't work, is I believe we are supposed to swapping bit 0 of the $2000 write at the end of NMI each time. ORA should swap 0 to 1, but not 1 back to 0 when needed. How is the ORA accomplishing this? Do I just not understand the EOR/ORA truth table? Here is the code in question.
Thank you for any help!
Kind Regards
Hundo
The $2000 write at the end of NMI is manipulated by ORA'ing the value with the value previously stored into the nametable variable. My question is, why does ORA work here to continually flip the bits. Logically, it shouldn't work in my mind. Only EOR should work, and in fact, if I change the ORA to EOR it DOES work and I get the exact same visual result in scrolling as using ORA. The reason I think ORA shouldn't work, is I believe we are supposed to swapping bit 0 of the $2000 write at the end of NMI each time. ORA should swap 0 to 1, but not 1 back to 0 when needed. How is the ORA accomplishing this? Do I just not understand the EOR/ORA truth table? Here is the code in question.
Code:
NMI:
INC scroll ; add one to our scroll variable each frame
NTSwapCheck:
LDA scroll
BNE NTSwapCheckDone
NTSwap:
LDA nametable ;load current nametable number (0 or 1)
EOR #$01 ;exclusive OR of bit 0 will flip that bit
STA nametable ;so if nametable was 0, now 1
;if nametable was 1, now 0
NTSwapCheckDone:
LDA #$00
STA $2003
LDA #$02
STA $4014 ; sprite DMA from $0200
; run other game graphics updating code here
LDA #$00
STA $2006 ; clean up PPU address registers
STA $2006
LDA scroll
STA $2005 ; write the horizontal scroll count register
LDA #$00 ; no vertical scrolling
STA $2005
;;This is the PPU clean up section, so rendering the next frame starts properly.
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
STA $FF
ORA nametable ; select correct nametable for bit 0
STA $2000
LDA #%00011110 ; enable sprites, enable background, no clipping on left side
STA $2001
; run normal game engine code here
; reading from controllers, etc
RTI ; return from interrupt
INC scroll ; add one to our scroll variable each frame
NTSwapCheck:
LDA scroll
BNE NTSwapCheckDone
NTSwap:
LDA nametable ;load current nametable number (0 or 1)
EOR #$01 ;exclusive OR of bit 0 will flip that bit
STA nametable ;so if nametable was 0, now 1
;if nametable was 1, now 0
NTSwapCheckDone:
LDA #$00
STA $2003
LDA #$02
STA $4014 ; sprite DMA from $0200
; run other game graphics updating code here
LDA #$00
STA $2006 ; clean up PPU address registers
STA $2006
LDA scroll
STA $2005 ; write the horizontal scroll count register
LDA #$00 ; no vertical scrolling
STA $2005
;;This is the PPU clean up section, so rendering the next frame starts properly.
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
STA $FF
ORA nametable ; select correct nametable for bit 0
STA $2000
LDA #%00011110 ; enable sprites, enable background, no clipping on left side
STA $2001
; run normal game engine code here
; reading from controllers, etc
RTI ; return from interrupt
Thank you for any help!
Kind Regards
Hundo