# SPK-101 Cognitive Tools: A Supplement for Younger Learners

*Three mental models for the concepts in SPK-101 that take the most brain-power to grasp: addresses and values, addressing modes, and the bitplane encoding that stores NES sprites. Each tool is a picture you can hold in your head or draw on paper. None of them require a computer.*

*Reading level: aimed at a motivated 12-year-old working independently. Instructors: see INSTRUCTOR-GUIDE.md for the pacing notes that accompany these tools.*

---

## Tool 1: The Mailbox Metaphor for RAM (addresses vs. values)

### The idea

Your computer's RAM is a very long row of tiny storage slots. Each slot holds one byte (one number from 0 to 255). Every slot has an address -- a number that tells you where that slot is in the row.

Picture it as a wall of mailboxes: the kind you might see in an apartment building lobby. Each mailbox has a number on the door (the address) and holds a small piece of paper inside (the value stored there).

*Notation note: this tool uses `$` as the prefix for hexadecimal numbers, following 6502/Commodore convention (so `$FF` = decimal 255, `$00` = decimal 0). FND-101 uses the `0x` prefix (C/Linux convention). The two prefixes mean the same thing.*

```
Address:  $00   $01   $02   $03   ... $FF
         +----+----+----+----+    +----+
         | 42 | 17 | 00 | 83 |...| 05 |
         +----+----+----+----+    +----+
```

The number on the front of the mailbox is the address. The paper inside is the value. These are two different things.

### Why this matters in 6502 assembly

Two 6502 instructions look almost the same but mean completely different things:

| Instruction | What it means |
|---|---|
| `LDA #$01` | Load the literal number 1 into the accumulator. Do not look in any mailbox. The `#` means "the number right here." |
| `LDA $01` | Go to mailbox number $01. Take out the paper inside. Load that number into the accumulator. |

The only visible difference is the `#`. That `#` is the most important symbol in 6502 assembly for new learners.

### Three worked examples

**Example 1: Store a value in a mailbox**

```
LDA #$42    ; Load the literal number $42 (= 66 in decimal) into A.
STA $00     ; Store A's value into mailbox $00.
            ; Mailbox $00 now holds $42.
```

After this code runs, mailbox $00 holds the value $42. The address ($00) and the value ($42) are different numbers.

**Example 2: Read from a mailbox**

```
LDA $00     ; Go to mailbox $00. Read the paper inside. Load it into A.
            ; If mailbox $00 holds $42, then A now holds $42.
```

**Example 3: Confusing an address with a value**

A common mistake: a student wants to load the value 1 into the accumulator, so they write `LDA $01` instead of `LDA #$01`. What actually happens: the CPU goes to mailbox $01 and reads whatever is stored there. If mailbox $01 happens to hold the number 1, the result looks correct -- but if it holds something else (say, $FF), the program behaves wrong in a way that is hard to trace.

The fix: whenever you mean "the literal number X," write `#$X`. Whenever you mean "the value stored at address X," write `$X` without the `#`.

### The NES zero page as a 16x16 mailbox grid

The NES's zero page (addresses $00 through $FF) is the fast-access part of RAM -- the first 256 mailboxes. You can picture it as a 16x16 grid:

```
      $0   $1   $2   $3   $4   $5   $6   $7   $8   $9   $A   $B   $C   $D   $E   $F
$00: [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ]
$10: [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ]
...
$F0: [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ]
```

Each cell in the grid is one mailbox. The address of a cell is its row prefix + its column. For example, row $20, column $5 = address $25.

NES games use zero-page addresses constantly because the CPU accesses them faster than the rest of RAM. When you see a lot of `LDA $xx` instructions where xx is between $00 and $FF, the game is reading from its "frequently used mailboxes."

### Where this metaphor recurs

The Mailbox metaphor is the standard way the Virtus Cyber Academy introduces memory addresses. You will see it again in CSA-101 Chapter 3 (Memory), where the same 16x16 grid will recur in the context of the RV32I-Lite memory map. If you learn to see addresses as mailbox numbers now, that picture carries forward without needing to re-learn it.

---

## Tool 2: The Addressing Mode Flowchart

### The idea

When you see a 6502 instruction, you need to figure out what kind of operand it has. The flowchart below gives you a decision tree. Start at the top every time you see an operand you are not sure about.

### The decision tree

```
Look at the operand.
         |
         v
Does it start with #?
    /         \
  YES          NO
   |            |
   v            v
Immediate.    Does the operand have TWO hex bytes
The number    (e.g., $0200, $FFFC)?
in the            /             \
instruction     YES              NO
is the value.    |               |
                 v               v
              Is there a       Zero Page.
              ,X or ,Y         One byte.
              after it?        Address is
                 /    \        in the range
               YES     NO      $00-$FF.
                |       |
                v       v
           Indexed     Absolute.
           absolute.   Full 16-bit
           Address +   address.
           X (or Y).
```

**Bonus branch: Indirect**

If the operand is `($XXXX)` with parentheses, that is indirect mode: go to address $XXXX, read the two bytes stored there, use those two bytes as the real destination address. Only `JMP` uses this in common 6502 code.

### The one rule to tattoo on your brain

**`#` = literal value. No `#` = address.**

Every other distinction in the flowchart is secondary. Getting the `#` question right eliminates 90% of addressing mode confusion.

### Worked examples for each leaf

| Instruction | Mode | Meaning |
|---|---|---|
| `LDA #$05` | Immediate | A = 5 (the literal number 5) |
| `LDA $80` | Zero Page | A = value stored at address $80 |
| `LDA $0200` | Absolute | A = value stored at address $0200 |
| `LDA $0200,X` | Indexed Absolute | A = value stored at address ($0200 + X) |
| `LDA $80,X` | Indexed Zero Page | A = value stored at address ($80 + X) |
| `JMP ($FFFC)` | Indirect | Jump to address stored at $FFFC-$FFFD |
| `STA $0200` | Absolute | Store A's value into address $0200 |

Notice that `STA #$0200` is NOT a valid instruction. You cannot store TO a literal number -- a literal is not a location. The destination of a store must always be an address.

### How to use this during labs

Print or draw the flowchart on a piece of paper. Keep it next to you during Lab 3.2 (reading the Mesen debugger) and Lab 4.1 through 4.4. Every time you see an instruction you are not sure about, start at the top of the flowchart. It takes less than 10 seconds.

After about 30-40 instructions, you will not need the paper anymore. The pattern becomes automatic.

### Where this flowchart recurs

The same addressing mode logic recurs in CSA-101 Chapter 4 (Machine Language, RV32I-Lite instruction formats). The 6502 and RISC-V have different instruction encodings, but the question "is this operand a literal value or an address?" is the same question. Getting fluent with the 6502 version now makes the RISC-V version much easier to absorb later.

---

## Tool 3: The Bitplane Decomposer

### The idea

An NES sprite tile is an 8x8 grid of pixels. Each pixel can be one of four colors (called color 0, 1, 2, 3). Two bits per pixel times 64 pixels = 128 bits = 16 bytes.

The 16 bytes are stored as two separate 8-byte "planes." Plane A is bytes 0-7 (one bit per pixel for the low bit of the color index). Plane B is bytes 8-15 (one bit per pixel for the high bit of the color index).

<img src="../assets/diagrams/spk-101-ppu-bitplane-decomposer.svg" alt="NES PPU 2bpp bitplane decomposer. Left half walks the worked example: Plane A row 0 byte (0x4C, amber-bit cells) and Plane B row 0 byte (0x2A, green-bit cells) feed an OR-shift formula that produces an 8-pixel decoded row showing colors 0, 1, 2, 0, 3, 1, 2, 0 in the 4-color palette. Right half shows a full 8x8 tile rendered from 8 plane-A bytes and 8 plane-B bytes (a diamond / plus motif), with the 16 byte values listed in hex and binary alongside." />

*Figure T3. The same worked example the §"Step-by-step: decode one row by hand" section walks in prose. The amber Plane A row contributes the low bit of each pixel's color; the green Plane B row contributes the high bit; the decoded row at the bottom is what the PPU draws to screen for row 0 of that tile. The full 8x8 tile on the right shows how all 16 bytes (8 plane-A + 8 plane-B) become one tile of graphics.*

```
Tile layout in memory:
  Byte 0:  [b7][b6][b5][b4][b3][b2][b1][b0]   <- Plane A, row 0
  Byte 1:  [b7][b6][b5][b4][b3][b2][b1][b0]   <- Plane A, row 1
  ...
  Byte 7:  [b7][b6][b5][b4][b3][b2][b1][b0]   <- Plane A, row 7
  Byte 8:  [b7][b6][b5][b4][b3][b2][b1][b0]   <- Plane B, row 0
  ...
  Byte 15: [b7][b6][b5][b4][b3][b2][b1][b0]   <- Plane B, row 7
```

For pixel at column C, row R:
- Bit C of Plane-A byte R = the low bit of that pixel's color
- Bit C of Plane-B byte R = the high bit of that pixel's color
- Color index = (high bit << 1) | low bit = 0, 1, 2, or 3

### Step-by-step: decode one row by hand

Say byte 0 (Plane A, row 0) = `0100 1100` in binary.
Say byte 8 (Plane B, row 0) = `0010 1010` in binary.

Work across from bit 7 (leftmost pixel) to bit 0 (rightmost pixel):

| Pixel | Plane A bit | Plane B bit | Color (B<<1 | A) |
|---|---|---|---|
| 0 (leftmost) | 0 | 0 | 0 |
| 1 | 1 | 0 | 1 |
| 2 | 0 | 1 | 2 |
| 3 | 0 | 0 | 0 |
| 4 | 1 | 1 | 3 |
| 5 | 1 | 0 | 1 |
| 6 | 0 | 1 | 2 |
| 7 (rightmost) | 0 | 0 | 0 |

Row 0 of the tile, left to right: colors 0, 1, 2, 0, 3, 1, 2, 0.

### The graph-paper exercise

Before touching any software in Lab 2.2 or Lab 4.3:

1. Draw an 8x8 grid on graph paper (8 columns, 8 rows).
2. Write out the 16 bytes of tile 0 as two rows of 8 binary numbers.
3. For each row of the grid, fill in the color index for each pixel using the method above.
4. Color in the grid with four pencils or pens (one per color).

This is slow. It is supposed to be slow. After doing it once by hand, you will never misread a byte offset or mix up Plane A and Plane B again.

### What each byte controls

If you want to change the color of pixel (row=0, col=7):
- Low bit: bit 0 of byte 0 (Plane A, row 0)
- High bit: bit 0 of byte 8 (Plane B, row 0)

Change bit 0 of byte 0 from 0 to 1: the low bit of pixel (0,7) changes. The pixel shifts from color 0 to color 1.

Knowing this lets you predict what a byte edit will do before you make it. You should always be able to state your prediction out loud before touching the hex editor.

### Limitation and forward pointer

The graph-paper method works but is slow. The proposed Visual Bitplane Editor (a browser tool, not yet built) will let you toggle individual bits and immediately see the resulting 8x8 tile update in real time. Once that tool is available, the graph-paper pass becomes optional. Until then, graph paper is the right tool.

---

## Where these tools recur across the academy

All three tools address abstraction-density problems that appear in multiple academy courses, not just SPK-101.

| Tool | SPK-101 | CSA-101 | RE-011 |
|---|---|---|---|
| Mailbox metaphor | Week 2-4 (RAM addresses, ROM offsets) | Ch 3 (Memory), Ch 4 (machine language) | Week 3 (ELF sections, segment addresses) |
| Addressing Mode Flowchart | Week 3-5 (6502 addressing) | Ch 4 (RV32I-Lite addressing modes) | Week 4-5 (System V AMD64 operands) |
| Bitplane Decomposer | Week 2-4 (NES sprite format) | -- (not directly covered in CSA-101) | Week 2 bit-field decoding (e_type/e_flags fields in ELF byte-level view) |

The Mailbox metaphor is the strongest cross-course candidate for a shared handout. If you are working through CSA-101 after SPK-101, the mailbox grid will recur in Chapter 3. The picture is the same; only the scale changes (CSA-101 has a 32-bit address space instead of the 6502's 16-bit one, but the idea of "address on the front, value on the paper inside" is unchanged).

Instructors: if you are running both SPK-101 and CSA-101, you can use the Mailbox diagram from this supplement in CSA-101's Chapter 3 session without adaptation. The vocabulary is consistent by design.

---

*Supplement v0.1. Engineering tools (Integrated Offset Calculator, Visual Bitplane Editor) are deferred to separate development briefs. This document covers the cognitive / mental-model layer only.*
