This is a Tier-1-graded worksheet. Submit this filled worksheet only. The paper graph-paper exercise in the cognitive-tools supplement is the deeper hand-work artifact; today is the calibration that confirms your paper decode against the live visualizer.
Purpose
The SPK-101 cognitive-tools supplement (Tool 3) gave you the formula and a paper-and-pencil exercise: 8x8 grid, 4 colors, 16 bytes, decode by hand. Today's worksheet drives the Bitplane Decomposer (/workbench/static/bitplane-decomposer.html) to verify your hand decode against the live tool's step-through.
The decomposer's three side-by-side 8x8 grids show: Plane A bits (low bit of each pixel's color index), Plane B bits (high bit), and the output 4-color tile. Step through the 64 pixels one at a time; the math callout shows Color = (PlaneB << 1) | PlaneA worked out for the active cell. The tool also exposes an editable 16-byte input table, so you can author your own tile and watch the output update.
The pedagogical claim of the cognitive-tools supplement is that the byte layout is the picture: every visual pattern in an NES sprite reduces to a 16-byte arrangement, and once you can read those bytes you can edit them. The pedagogical claim of Jon's 2026-05-11 younger-learner feedback (which produced the resolved-MSB-first formula Color = (PlaneB << 1) | PlaneA) is that the formula has a definite digit-order that has to be drilled until it becomes automatic.
The deeper purpose: this worksheet builds the byte-level fluency you carry into Week 4 ROM hacking (where you find tile bytes in a real ROM dump with xxd) and Week 5 cross-platform comparisons (where Game Boy and SNES use related but distinct encodings).
Learning Objectives
By the end of this worksheet, you will be able to:
- Hand-decode a single row of an 8x8 NES tile from two 1-byte planes, using
Color = (PlaneB << 1) | PlaneAMSB-first, and verify against the visualizer (Apply; Tool 3 supplement). - Tally palette-index usage per row of an 8x8 tile, identifying which of the 4 colors dominate the picture (Analyze; Week 4 ROM hacking foundation).
- Author a 16-byte tile from scratch that uses all 4 palette indices and verify the resulting picture in the visualizer (Create; the byte-level edit skill Week 4 graded labs require).
- Explain the two-plane layout in terms of what hardware constraint it serves and what visual constraint 2 bits per pixel imposes (Evaluate; the NES PPU's design tradeoff).
- Articulate one observation about the visualizer that the paper exercise alone could not surface, in 3-5 sentences (Evaluate; visualizer-vs-paper distinction).
Equipment Checklist
- Modern web browser (Chromium-family preferred)
- Visualizer URL open:
https://virtuscyberacademy.org/workbench/static/bitplane-decomposer.html - Cognitive-tools supplement Tool 3 open in a second tab
- Paper notebook for predictions (do NOT step the visualizer before you predict)
- 4-color pencil set or 4 markers (one per palette index)
- SPK-101 Weeks 1-3 reading complete
Step-by-Step Procedure
This worksheet takes ~60 minutes. Plan one sitting.
Stage 1 - Load the visualizer and study the mario-M example
- Step 1. Open the visualizer at the URL above. The default loaded example is
mario-m(letter M; one color). Confirm you see three 8x8 grids labeledPlane A,Plane B,Output 8x8 tile, a 4-color palette legend below the output, and Start / Step / Step all / Reset buttons. - Step 2. Read the 16-byte input table at the bottom. For the mario-m example, all 8 Plane B bytes are
0x00and the Plane A bytes encode the letter M. Without stepping, transcribe the Plane A bytes from the input table onto your paper notebook (row 0 through row 7). - Step 3. Hand-decode row 0 of the mario-m tile before clicking Start. For each of 8 pixels in row 0, apply the formula
Color = (PlaneB << 1) | PlaneAwith the Plane A bit from your transcription and Plane B = 0. Write the predicted color indices in Table A row 0.
Stage 2 - Step through the mario-m visualizer
- Step 4. Click Start. The active highlight appears on pixel (0, 0). Read the math callout: it should say
Color = (0 << 1) | 0 = 0 (palette index 0)if the Plane A row 0 byte's bit 7 is 0. Confirm against your Table A row 0 prediction for col 0. - Step 5. Click Step seven more times to walk all 8 cells of row 0. After each Step, fill the observation column in Table A. Mark match / miss per cell.
- Step 6. Click Step all to fast-forward through the remaining 56 pixels. The output grid should now show the letter M in palette color 1 (red) on a palette-0 (black) background. Status pill should read
Done.
Stage 3 - Switch to the diamond example
- Step 7. Select
diamondfrom the example dropdown. The visualizer reloads with a new 16-byte tile that uses all 4 palette indices. - Step 8. Click Step all to decode the entire tile.
- Step 9. For each row of the output grid, tally how many pixels of each palette index appear. Fill Table B. The diamond pattern should have a recognizable shape: outer pixels black (color 0), a ring of blue (color 3), a layer of green (color 2), and a red interior (color 1).
Stage 4 - Author your own tile
- Step 10. Click Reset. Plan a small tile on paper that uses ALL FOUR palette indices (0, 1, 2, 3). It does not have to be a recognizable picture; a 2x2 block of each color is fine. Sketch it on graph paper first.
- Step 11. Translate your sketch into 16 bytes. For each pixel of color c, the bit pair is
(planeA bit, planeB bit) = (c & 1, (c >> 1) & 1). Compute the 8 Plane A bytes (each MSB-first across 8 pixels of a row) and the 8 Plane B bytes. Fill Table C column "Authored bytes". - Step 12. Edit the 16 hex inputs in the visualizer to match your bytes. Click Step all and confirm the output tile matches your sketch. Fill the verification column in Table C.
Stage 5 - Reflection
Answer the 4 reflection prompts below in 2-4 sentences each.
Data Entry Tables
Table A - Mario-M Row 0 Per-Cell Decode (Steps 3-5; PREDICT before stepping)
Plane A row 0 byte for the mario-m example is 0x42 = 0100 0010 (MSB on the left = col 0). Plane B row 0 byte is 0x00.
| Col | Plane A bit | Plane B bit | Predicted color (= (B<<1)|A) | Observed color (visualizer) | Match | |:---:|:---:|:---:|:---:|:---:|:---:| | 0 | 0 | 0 | _____ | _____ | [ ] | | 1 | 1 | 0 | _____ | _____ | [ ] | | 2 | 0 | 0 | _____ | _____ | [ ] | | 3 | 0 | 0 | _____ | _____ | [ ] | | 4 | 0 | 0 | _____ | _____ | [ ] | | 5 | 0 | 0 | _____ | _____ | [ ] | | 6 | 1 | 0 | _____ | _____ | [ ] | | 7 | 0 | 0 | _____ | _____ | [ ] |
All 8 predictions filled BEFORE stepping? [ ] Yes [ ] No (re-do honestly)
Table B - Diamond Example Per-Row Palette Usage (Step 9)
For each of the 8 rows, count how many cells are color 0, color 1, color 2, color 3. The row totals must add to 8.
| Row | Color 0 (black) | Color 1 (red) | Color 2 (green) | Color 3 (blue) | Row total |
|---|---|---|---|---|---|
| 0 | _____ | _____ | _____ | _____ | = 8 |
| 1 | _____ | _____ | _____ | _____ | = 8 |
| 2 | _____ | _____ | _____ | _____ | = 8 |
| 3 | _____ | _____ | _____ | _____ | = 8 |
| 4 | _____ | _____ | _____ | _____ | = 8 |
| 5 | _____ | _____ | _____ | _____ | = 8 |
| 6 | _____ | _____ | _____ | _____ | = 8 |
| 7 | _____ | _____ | _____ | _____ | = 8 |
| Column totals (all 64 pixels) | _____ | _____ | _____ | _____ | = 64 |
Table C - Custom 4-Color Tile (Steps 10-12)
| Row | Authored Plane A byte | Authored Plane B byte | Output matches sketch? |
|---|---|---|---|
| 0 | 0x____ | 0x____ | [ ] |
| 1 | 0x____ | 0x____ | [ ] |
| 2 | 0x____ | 0x____ | [ ] |
| 3 | 0x____ | 0x____ | [ ] |
| 4 | 0x____ | 0x____ | [ ] |
| 5 | 0x____ | 0x____ | [ ] |
| 6 | 0x____ | 0x____ | [ ] |
| 7 | 0x____ | 0x____ | [ ] |
Confirm all 4 palette indices appear in your custom tile (verify in the output grid):
- Color 0 appears
- Color 1 appears
- Color 2 appears
- Color 3 appears
Reflection Prompts
Answer in 2-4 sentences each.
1. Why is an NES sprite encoded as 2 separate planes of 8 bytes (16 bytes total) rather than 1 plane of 16 bytes where each pair of bits is one pixel? (Hint: the PPU reads bytes one at a time from its pattern-table memory. If the two bits of each pixel were adjacent, drawing a single row would require reading 2 bytes per row. With the two-plane layout, the PPU reads 1 byte from each plane and can XOR or shift them together to render a row. The hardware tradeoff is the answer.)
2. What visual constraint does the 2-bit-per-pixel limit impose, and how does the NES sidestep it for full-screen graphics? (Hint: 2 bits = 4 colors per tile. A full NES screen has hundreds of tiles, but each tile is still capped at 4 colors. Forward pointer to Week 5: how do attribute tables let different tiles share different 4-color palettes from a larger palette bank? You do not have to answer the forward pointer in full; naming the mechanism is enough.)
3. Jon's 2026-05-11 younger-learner feedback produced the resolved formula Color = (PlaneB << 1) | PlaneA MSB-first. Why MSB-first and not LSB-first? (Hint: the leftmost pixel on the screen corresponds to bit 7 of each plane byte. Reading the byte left-to-right matches reading the row of pixels left-to-right. LSB-first would mirror the picture.)
4. The brief's headline question. What did the visualizer show that the paper graph-paper exercise alone could not? (Hint: the paper exercise gives you the final colored grid, but the visualizer animates the decode one pixel at a time. A good answer names a specific dynamic property the animation surfaced - the active-highlight in all three grids simultaneously, the math callout's running computation, or the byte-level edit feedback loop that lets you author Table C in real time.)
Submission Checklist
- This worksheet, with Tables A, B, C filled
- All 4 Reflection Prompts answered
- Table A predictions filled BEFORE stepping the visualizer
- Custom tile (Table C) uses all 4 palette indices
- Toolchain Diary entry for the Bitplane Decomposer added
Pass/Fail Self-Evidence (Tier 1 of the rubric)
Every gate must be checked.
- Gate 1. Table A predictions filled before observations.
- Gate 2. Table A row 0 matches the canonical decode: the 8 cells should be
0,1,0,0,0,0,1,0(corresponding to the letter M's row 0 . X . . . . X . pattern in color 1). - Gate 3. Table B column totals (across all 64 pixels) add to 64.
- Gate 4. Table C output tile in the visualizer uses all 4 palette indices (verify the 4 checkboxes).
- Gate 5. Reflection 4 names a specific dynamic property the visualizer surfaced.
If any gate is unchecked, do not submit yet.
Common Pitfalls
The five most common first-attempt failures:
- Stepped before predicting. Table A asks for predictions. Stepping first and back-filling loses the calibration value the worksheet builds. If you stepped first, redo with a different example or with custom-edited bytes.
- Confused MSB-first with LSB-first. Bit 7 of the Plane A byte is the leftmost pixel (col 0). Bit 0 is the rightmost pixel (col 7). If your decode is mirrored, you read LSB-first by mistake.
- Mixed up Plane A and Plane B. Plane A is the low bit of the color index; Plane B is the high bit. Color 1 has Plane A = 1 and Plane B = 0. Color 2 has Plane A = 0 and Plane B = 1. Color 3 has both = 1. Color 0 has both = 0.
- Custom tile in Table C does not actually use all 4 colors. Re-verify the 4 checkboxes after editing. If color 3 is missing, find a pixel where you want it, then set both that pixel's bit positions to 1 in their respective bytes.
- Mis-counted Table B totals. Each row total is 8 (8 pixels per row); the column totals are 64 (64 pixels in an 8x8 tile). If your row totals do not add to 8, recount that row.
Forward Pointer
SPK-101 Week 4 ROM Hacking labs ask you to find sprite-tile bytes in a real NES ROM dump using xxd. The byte-level fluency you build today is the foundation for that lab; you will be looking for 16-byte patterns that match what you authored in Table C.
SPK-101 Week 5 (Game Boy + SNES) introduces variant bitplane formats. Game Boy uses the same 2-plane layout but with a different memory order. SNES uses up to 8 bitplanes (16 colors / 256 colors per tile). The same decode formula generalizes; today's worksheet is the simplest case.
SPK-101 Week 6 Capstone asks you to ship a small palette-swap ROM hack. The byte-edit feedback loop you used to author Table C is the same loop you will use to edit real ROM bytes, except the hex editor is xxd and the verification is a NES emulator instead of the academy visualizer.
Beyond SPK-101: the same byte-level decoding skill transfers to RE-011 Week 3 (ELF byte-layout cards) and CSA-101 Ch 4 (RV32I-Lite instruction encoding). The visualizer is one of the first places students see "the byte layout is the picture, and once you can read the bytes you can edit them."
LAB WORKSHEET COMPLETE - SPK-101 lab-bitplane-decomposer v1.0; Tier-1 worksheet-completion (first numbered worksheet in worksheets/spk-101/); 3 data tables (A row-0 per-cell decode of mario-m predict-then-verify; B diamond per-row palette tally; C authored custom 4-color tile bytes) + 4 reflection prompts (why 2 planes not 1; 2-bit-per-pixel constraint + attribute-table forward pointer; MSB-first rationale; visualizer-vs-paper headline) + 5 Tier-1 gates + 5 common pitfalls + forward pointer to Week 4 ROM hacking + Week 5 cross-platform + Week 6 capstone + RE-011 Week 3 cross-track; references Tool 3 supplement and Jon's 2026-05-11 younger-learner feedback; em-dash + blacklist clean per editor-guide.