ORA Opcode weirdness in Nerdy Nights Scrolling Tutorial

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
ORA Opcode weirdness in Nerdy Nights Scrolling Tutorial
by on (#187567)
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.

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


Thank you for any help!

Kind Regards

Hundo
Re: ORA Opcode weirdness in Nerdy Nights Scrolling Tutorial
by on (#187569)
When one of the 2 input bits is 0, Or and Exclusive Or do the same thing:
Code:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1


Exclusive Or only differs from Or when both input bits are 1:
Code:
1 ^ 1 = 0 ; this case is the "excluded" one
1 | 1 = 1
Re: ORA Opcode weirdness in Nerdy Nights Scrolling Tutorial
by on (#187571)
Thanks rainwarrior. I just realized I was COMPLETELY overthinking this and completely screwed up the simple logic of this code in my head.

Hundo