Skip to content
Game 0 Unit 15 of 18 1 hr learning time

Working With Bits

Change one bit without disturbing the rest. Meet ora, and and eor — set, clear and flip individual bits — the everyday way to throw a single switch in a byte.

83% of Meet The Machine

Back in The Joypad in Your Hand you tested a single bit by masking it. Often you want to change one — set a flag, clear a flag, flip a flag — without touching the seven bits around it. Three instructions do exactly that, one bit at a time:

  • ora n — OR with A: set every bit that's 1 in n, leave the rest alone.
  • and nkeep every bit that's 1 in n, clear the rest.
  • eor n — Exclusive-OR: flip every bit that's 1 in n. (On the 6502, XOR is spelt eor.)

A byte is often not one number but eight little switches — the controller you read in Unit 10 was exactly that, its buttons arriving bit by bit. These three instructions are how you throw one switch and leave the others where they were.

What you'll see by the end

The NES screen filled with pale pink.
Red ($16) became pink ($36) by ORing in one higher bit — one switch thrown, the rest left alone.

A pink screen — colour $36. We started with $16 (red), ora'd in bit 5, and got $36. In bit terms it's "set one bit and leave the rest"; in colour terms, red lightened to pink. One switch thrown.

Setting a bit

; ============================================================================
; Meet the Machine (NES) - Unit 15: Working With Bits
;
; Change one bit without touching the other seven. ora sets, and clears, eor
; flips. Here we take red and set a single bit to turn it green.
; ============================================================================

.segment "HEADER"
    .byte "NES", $1a
    .byte 2
    .byte 1
    .byte $00, $00

.segment "CODE"

reset:
    sei
    cld
    ldx #$40
    stx $4017
    ldx #$ff
    txs
    inx
    stx $2000
    stx $2001
    stx $4010
warm1:
    bit $2002
    bpl warm1
warm2:
    bit $2002
    bpl warm2

    ; ----------------------------------------------------------- YOUR CODE START
    lda #%00010110          ; $16 - red
    ora #%00100000          ; SET bit 5, leave the rest alone
    ;                       -> %00110110 = $36 (a pink)
    ; ------------------------------------------------------------- YOUR CODE END

    sta $00
    bit $2002
    lda #$3f
    sta $2006
    lda #$00
    sta $2006
    lda $00
    sta $2007

forever:
    jmp forever

nmi:
    rti
irq:
    rti

.segment "VECTORS"
    .word nmi
    .word reset
    .word irq

.segment "CHARS"
    .byte $00,$00,$00,$00,$00,$00,$00,$00
    .byte $00,$00,$00,$00,$00,$00,$00,$00
    .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
    .byte $00,$00,$00,$00,$00,$00,$00,$00
    .res 8192 - 32, $00

%00010110 is $16, red. ora #%00100000 sets bit 5 without disturbing the others, giving %00110110 = $36. The power of ora is that it's surgical: it only ever turns bits on, so whatever you already had survives. (On the NES palette, that higher bit is the "brightness" half of the colour code — which is why setting it lightened red toward pink.)

Assemble and run

ca65 bits.asm -o bits.o && ld65 -C nes.cfg bits.o -o bits.nes

Red, with one bit set, becomes pink.

Try this: clear a bit with and

Start from lda #%00111000 ($38) and and #%00110000. The and keeps only the bits that are 1 in the mask — so the bottom bits clear and you're left with %00110000 = $30 (white). and is the surgical off switch, the mirror of ora.

Try this: flip a bit with eor

Take any value and eor #%00100000. Bit 5 flips — on becomes off, off becomes on. Run it twice on the same value and you're back where you started: flipping twice undoes itself. (That reversibility is exactly why eor is the heart of some sprite-drawing tricks — a topic for later.)

If it doesn't work

  • ora/and/eor won't assemble. They take an immediate mask: ora #%00100000. The # matters — without it you'd OR with the contents of an address, not the bits you wrote.
  • The colour didn't change as expected. Work the mask bit by bit against the starting value: ora turns bits on, and keeps the masked ones, eor flips. Sketch the eight bits if you have to.
  • The screen came out black. Some NES colour codes (the $xD/$xE/$xF ones) are black or blank — if your bit-twiddling lands on one, you'll see black. Pick bits that keep you on a visible colour.

What you've learnt

ora sets bits, and clears them, eor flips them — so you can change one bit of a byte and leave the other seven untouched.

What's next

A byte tops out at 255 — too small for a screen address, which runs to 65535. Next — Bigger Than a Byte — we hold a number in two bytes and add it by hand, and the carry flag from last unit turns out to be the bridge that makes it work.