Skip to content
Game 0 Unit 13 of 16 1 hr learning time

Working With Bits

Change one bit without disturbing the rest. Meet and, or and xor — clear, set and flip individual bits — the everyday way to flip a single flag like an attribute's BRIGHT.

81% of Meet The Machine

Back in The Machine Can Hear You you tested a single bit with bit. 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:

  • or nset every bit that's 1 in n, and leave the rest alone.
  • and nkeep every bit that's 1 in n, and clear the rest.
  • xor nflip every bit that's 1 in n.

A byte is often not one number but eight little switches — the attribute byte from Beat 6 is exactly that (FLASH, BRIGHT, PAPER, INK all packed in). These three instructions are how you throw one switch and leave the others where they were.

What you'll see by the end

The screen surrounded by a magenta border.
A magenta border — colour 3. We started at colour 2 (red) and OR'd in bit 0: red with blue added, one switch thrown, the rest untouched.

A magenta border — colour 3. We started with colour 2 (red), ored in bit 0, and got 3. In colour terms that's red with blue added; in bit terms it's "set the bottom bit and leave the rest." One switch thrown.

Setting a bit

; ============================================================================
; PRIMER — Beat 13: Working With Bits
; ============================================================================
; In Beat 8 you TESTED a bit (bit 0, a). Now you change them. Three tools, one
; bit-at-a-time each:
;
;   or  n   -- SET the bits that are 1 in n   (leaves the rest alone)
;   and n   -- CLEAR the bits that are 0 in n  (keeps the bits that are 1)
;   xor n   -- TOGGLE (flip) the bits that are 1 in n
;
; This is how you flip a single flag -- like the BRIGHT bit of an attribute --
; without disturbing the others. Here we start with colour 2 (red) and OR in
; bit 0, turning it into colour 3 (magenta): red + blue = magenta, one bit set.
; ============================================================================

            org     32768

start:
            ld      a, %00000010     ; bit 1 set -> colour 2 (red)
            or      %00000001        ; SET bit 0 -> %00000011 = 3 (magenta)
            out     ($FE), a         ; show it

.loop:
            halt
            jr      .loop

            end     start

%00000010 is colour 2. or %00000001 sets bit 0 without disturbing bit 1, giving %00000011 = 3. The power of or is that it's surgical: it only ever turns bits on, so the colour you already had survives.

Assemble and run

pasmonext --sna working-with-bits.asm primer.sna

Red, with one bit set, becomes magenta.

Try this: clear a bit with and

Start from ld a, %00000111 (colour 7, white) and and %00000110. The and keeps only the bits that are 1 in the mask — so bit 0 is cleared and you're left with %00000110 = 6 (yellow). and is the surgical off switch, the mirror of or.

Try this: flip a bit with xor

Take any value and xor %00000111. Each of the bottom three bits 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 xor is the heart of sprite drawing — a topic for later.)

When it's wrong, see why

  • or/and/xor won't assemble with a target. They name only the mask: or %00000001, not or a, %00000001. A is assumed.
  • The colour didn't change as expected. Work the mask bit by bit against the starting value: or turns bits on, and keeps the masked ones, xor flips. Sketch the eight bits if you have to.
  • You set bits above bit 2 and the border looks unchanged. The border only shows the low 3 bits; higher bits are still set (check the register view) — they just don't colour the border.

What you've learnt

or sets bits, and clears them, xor 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 can run to 65535. Next — Bigger Than a Byte — registers pair up to hold 16-bit numbers, and add hl, de lets a pointer step by more than one, the way the tiny game walks down a wall.