Loop 2.1
Operator's Field Guide
30 named techniques for the manual flow computer — Volume I: Single Machine
Designed by Shea Gunther · New Gloucester, Maine · 2026
loop2.computer
"The operator is the program. These are the moves."
Introduction
How to Use This Guide

This is a recipe book. Each entry is a named technique — a reusable move with a clear purpose, a defined set of components, and step-by-step instructions for executing it on the machine. Techniques are the vocabulary of Loop 2.1. Knowing them by name lets you think in terms of composition rather than individual button presses.

Every recipe follows the same structure: a one-line description, the components it uses, setup requirements, steps, par estimate, and a note covering alternatives or gotchas. Par estimates assume 24 Hz and competent but not superhuman execution. They're targets, not guarantees.

The guide is organized into six sections — Injection & Loading, Bus Routing, ALU Operations, Memory, Pattern Matcher, and Threshold Gate & Counters. Techniques within each section are ordered roughly from simple to complex. If you're looking for something specific, the table of contents lists every recipe with its component tags.

This is Volume I: single-machine techniques only. Networked operations — Bus H/I routing, P2P word transfer, chain operations — will be covered in a separate volume.

Architecture constants you'll need
BPW = 17 bits per word (1 marker + 16 data). BUS_N = 24 bits (bus transit time: 24 ticks per word at position 0). Loop capacities: Working 18 words, ALU 24 words, Memory 24 words, Big 48 words. Recommended clock: 24 Hz.
Contents
I — Injection & Loading
01Clean Single InjectInject channel 02Sequential Multi-InjectInject channel 03Zero-Pulse ConstructionInject · Gate 04RNG FloodInject channel · RNG
II — Bus Routing
05Single Value TransferBus A–D · Gate 06Non-Destructive ReadBus · Gate · Destructive toggle 07Stream RoutingBus A–D · Gate 08Loop EchoBus · same source & dest 09Cross-Loop HoldTwo buses · Two loops
III — ALU Operations
10Two-Register ComputationALU · Bus · Gate 11Running AccumulatorALU · Auto-Writeback 12Auto-Writeback CounterALU · Auto-Writeback 13Running MaximumALU · Comparator · Working Scratch 14Conditional SwapALU · Comparator 15Absolute DifferenceALU · Comparator 16Binary MultiplicationALU · loop iteration 17Scratch Register HoldWorking Scratch · ALU
IV — Memory
18Sequential StoreMemory · Bus · Auto-Increment 19Address-Keyed StoreMemory · Addr-Read mode 20Destructive RecallMemory · Destructive mode 21Batch RecallMemory · Batch Write All 22Memory Snapshot Save & LoadMemory · Files · Bus File Save
V — Pattern Matcher
23Exact Value EjectPM1 · Big Loop 24Bit-Field FilterPM1 · Bus · Big Loop 25Rewrite in PlacePM1 rewrite mode 26PM Cascade — Two-Stage FilterPM1 + PM2 27Match CountPM1 match counter · Big Loop
VI — Threshold Gate & Counters
28Minimum ExtractionTG1 · Big Loop 29Range GateTG1 + TG2 · Big Loop 30Counter as DataCounter · Bus · ALU
Section I
Injection & Loading
01
Clean Single Inject
Load one value into the Working loop without collision artifacts.
Inject
Components
Inject channel
Par
17 ticks · 1 op
Setup
Machine running
  1. 1
    Set the inject value. Type decimal directly — no binary conversion needed.
  2. 2
    Press INJECT. The 17-bit word enters the inject channel (INJ_N = 17 slots) and shifts into the Working loop's write head over 17 ticks.
  3. 3
    Wait for the INJECT LED in the control bar to go dark before injecting again. The LED indicates bits still in the channel.
Why it matters
The inject channel is exactly BPW = 17 bits long. If you inject a second value before the first clears, the second word's marker bit collides with the first word's trailing data bits. The result is a corrupted value in the loop with no error message. The LED is your only guard. When in doubt, wait an extra tick or two.
02
Sequential Multi-Inject
Load N values into the Working loop in sequence with correct spacing.
Inject
Components
Inject channel
Par
17n + gap ticks · n ops
Setup
Machine running · loop has room
  1. 1
    Check that the Working loop has room for all N values. Working holds 18 words max. At 17 bits each, a full loop is 306 bits. Leave space — circulating values pack tightly.
  2. 2
    Set first value, press INJECT, wait for INJECT LED to go dark.
  3. 3
    Repeat for each subsequent value. The natural gap from LED-wait provides sufficient spacing between words.
Timing note
At 24 Hz, 17 ticks takes about 0.7 seconds. For large N at high clock rates, you can inject faster by watching the canvas instead of the LED — once the trailing dark bits of the previous word have cleared the write head, the channel is free. With practice, experienced operators can inject at one-per-second cadence without collision.
03
Zero-Pulse Construction
Build a specific value bit by bit using timed zero injections and loop pause.
Inject Gate
Components
Inject · Gate · Loop pause
Par
~17 × (1-bits) ticks
Difficulty
Advanced · precise timing

The inject channel fires a marker bit followed by 16 data bits. By injecting a zero-value word and pausing the Working loop at the exact moment a specific data-bit position exits the inject channel, you allow only that one bit position to land in the loop. Repeat for each 1-bit in your target value.

  1. 1
    Identify the bit positions you need to set. Example: value 420 = 0000000110100100. 1-bits at positions b8, b7, b5, b2 (counting from b0 = LSB). That's four pulses.
  2. 2
    Set inject value to 0. Press INJECT. The zero word begins entering the Working loop.
  3. 3
    Count ticks as the word shifts in. Marker arrives at tick 1. Bit D15 at tick 2, D14 at tick 3 … D0 at tick 17. At the exact tick for the bit you want to set, PAUSE the Working loop. This freezes that bit position at the write head while the rest of the inject channel clears.
  4. 4
    The channel finishes draining (ticks pass in the channel but nothing lands in the paused loop). Resume the loop. That bit position now holds a 1.
  5. 5
    Repeat steps 2–4 for each remaining 1-bit. Each pass adds one bit to the value accumulating in Working.
When to use this
Almost never in practice — injecting the value directly is vastly faster. Zero-pulse construction exists as a technique demonstration: it proves you understand how the inject channel works at the bit level. It's used in Challenge Problem D ("Building Numbers from Nothing") as a learning exercise.
04
RNG Flood
Fill a loop with random values for testing or challenge setup.
Inject RNG
Components
Inject channel · RNG button
Par
17n ticks · n ops
Setup
Machine running
  1. 1
    Press the RNG button next to the inject value field. This loads a random 16-bit value (0–65535) into the inject field without injecting it.
  2. 2
    Press INJECT. Wait for the LED.
  3. 3
    Repeat until the loop is filled to the desired density.
RNG implementation
The RNG is a linear feedback shift register (LFSR) — deterministic from its seed, not truly random. The same sequence will repeat if the seed is the same. For testing scenarios where you need genuinely varied data across multiple sessions, re-seed by injecting a manually chosen value first. The LFSR's output distribution is even across the 0–65535 range over a full period.
Section II
Bus Routing
05
Single Value Transfer
Move one value from one loop to another via a bus.
Bus Gate
Components
Any Bus A–D · Gate
Par
24 + circ ticks · 3 ops
Setup
Source loop has a value
  1. 1
    Set the bus Source to the source loop, Destination to the target loop.
  2. 2
    Turn the bus on.
  3. 3
    Watch the source loop canvas. When your value reaches the gate position (G dot), press OPEN GATE. The gate closes automatically after the word exits.
  4. 4
    The word traverses the bus (BUS_N = 24 ticks) and enters the destination loop's write head. Turn the bus off when done to prevent stray bits.
Bus transit time
A word takes exactly 24 ticks to traverse the bus from gate to write head regardless of clock rate. At 24 Hz that's one second. At 8 Hz it's three. Plan accordingly when timing matters — the value is unavailable to the source loop during transit.
06
Non-Destructive Read
Copy a value to another loop while keeping it in the source.
Bus Gate
Components
Bus · Gate · Destructive off
Par
24 + circ ticks · 3 ops
Setup
Destructive toggle OFF
  1. 1
    Confirm the Destructive toggle on the source loop's gate is OFF. This is the default — the gate ejects a copy and the original continues circulating.
  2. 2
    Execute a Single Value Transfer (recipe 05). The value leaves the source loop via the gate but immediately re-enters from the bus bits still in the loop — net effect: the source loop retains its value.
Destructive mode
With Destructive ON, the gate physically removes the word from the loop — it exits and is gone. Use destructive mode when you want to move a value (not copy it), or when you're deliberately consuming data from a loop one word at a time. For the Memory loop, destructive mode zeroes the slot after the writeback completes.
07
Stream Routing
Route multiple values in sequence from one loop to another.
Bus Gate
Components
Bus A–D · Gate
Par
41n ticks · n ops
Setup
Bus on · destination loop has room
  1. 1
    Configure and enable the bus (source → destination).
  2. 2
    For each value: watch the source loop, open the gate as each word approaches the G dot. The 41-tick cadence — approximately one full loop revolution at 24 Hz — gives you one gate-open per word comfortably.
  3. 3
    After the last word, turn the bus off to prevent the circulating values from re-entering the gate.
Destination capacity
Check that the destination loop has capacity before starting. Routing 12 values into a Working loop (18-word capacity) that already holds 8 values will overflow — older values get overwritten by the write head. The Big loop (48 words) is the natural staging area when you need to hold a large dataset before processing.
08
Loop Echo
Route a loop back into itself to refresh values at the write head position.
Bus
Components
Bus (same src & dst)
Par
N/A — continuous
Use case
Bus E output mirroring

Set a bus source and destination to the same loop. Values that exit via the gate travel across the bus and re-enter at the write head. The effect: values are not lost when they exit the gate, but they do travel the 24-tick bus delay before re-entering. This creates a brief gap in the loop where the value is in transit.

When this is useful
The primary use case is monitoring Bus E outbound while preserving values in Working: set Bus A source = Working, dest = Working (echo), then also configure Bus E outbound from Working. Values exit the gate, go to Bus E for challenge evaluation, and simultaneously echo back into Working. The challenge module receives the answer and the operator keeps their data. Requires careful gate timing — two bus outputs from one gate open.
09
Cross-Loop Hold
Park a value in a second loop while working in the first, then retrieve it.
Bus Two loops
Components
Two buses · Two loops
Par
48 ticks round-trip · 6 ops
Alternative
Working Scratch (recipe 17)
  1. 1
    Route value from source loop to a second loop via Bus A (one gate open).
  2. 2
    The value circulates in the second loop while you work in the first.
  3. 3
    When needed: configure Bus B (source = second loop, dest = first loop), open gate to retrieve.
Working Scratch is usually better
The Working Scratch registers (recipe 17) are a faster and simpler alternative to cross-loop hold for temporary value storage during ALU operations. Use cross-loop hold when you need to park a full dataset (not a single value) or when you're working with loops that don't connect to Working Scratch.
Section III
ALU Operations
10
Two-Register Computation
Load two values into ALU registers and compute a result.
ALU Bus
Components
ALU · Bus A · Gate
Par
~120 ticks · 6 ops
Setup
Values in Working or ALU loop
  1. 1
    Set Bus A: source = Working, dest = ALU. Enable bus.
  2. 2
    In the ALU panel, set capture route to A. Open gate — first value crosses to ALU loop, passes R head, loads into Reg A.
  3. 3
    Set capture route to B. Open gate — second value crosses, loads into Reg B.
  4. 4
    Result is computed instantly. Press SEND TO LOOP to write the result into the ALU loop for further use.
The ALU is combinational
The ALU recomputes its result the instant any register changes. There is no execute button, no clock cycle for the operation. Set the operation before or after loading registers — it doesn't matter. The result is always the current operation applied to the current register values.
11
Running Accumulator
Accumulate a running total across a stream of values.
ALU Auto-Writeback
Components
ALU · Bus · Auto-Writeback
Par
77n + 5 ticks · 3n + 4 ops
Setup
Op = ADD · Reg A or B = 0 initially
  1. 1
    Set ALU op to ADD. Load 0 into Reg A (inject 0 and capture, or the registers start at null — the first captured value becomes the initial total automatically).
  2. 2
    Enable AUTO-SEND: ON. Now the result writes back to the ALU loop whenever it changes.
  3. 3
    Set capture route to A. As each successive value passes the ALU R head, it loads into Reg A. With ADD and auto-writeback, the previous result is in the loop and will recapture into Reg A or B on the next pass — route the first total to Reg B by adjusting the route mid-accumulation.
  4. 4
    The cleanest approach: set Reg A = Op A source, Reg B = running total source. Each new value goes to A; the current total is in B. After each ADD, the new total writes back to the ALU loop, recaptures into B, and A is ready for the next value.
Watch for overflow
16-bit addition wraps at 65535. If your sum exceeds this, the carry flag lights but the result silently wraps. Check the C (carry) flag on each addition if overflow is a concern. The 12-bit mode toggle masks the top 4 bits and caps at 4095 — useful if your values are known to be small.
12
Auto-Writeback Counter
Build a self-incrementing counter that runs at the clock rate.
ALU Auto-Writeback
Components
ALU · Auto-Writeback
Par
N/A — runs continuously
Setup
ALU loop has a value · Op = INC
  1. 1
    Inject a starting value into the ALU loop (or use 0).
  2. 2
    Set capture route to A. The value loads into Reg A as it passes the R head.
  3. 3
    Set ALU op to INC.
  4. 4
    Enable AUTO-SEND: ON. The result (starting value + 1) writes back to the ALU loop, recaptures into Reg A, increments again. The loop now counts upward at every R-head pass.
This is powerful
Change the op to DEC for a countdown. Change to SHL (shift left) for a doubling sequence: 1, 2, 4, 8, 16… Change to ADD with a constant in Reg B for counting by any interval. The auto-writeback counter is one of the most expressive single-setup configurations on the machine — it turns the ALU loop into a programmable number generator with no further operator action required.
13
Running Maximum
Track the largest value in a stream using the comparator.
ALU Comparator
Components
ALU · Bus · Comparator
Par
82n + 41 ticks · 3n + 4 ops
Setup
Values in ALU loop · Op = SUB
  1. 1
    Route values to ALU loop. Capture first value into Reg B (current maximum candidate). Set op to SUB (A − B). Set Reg A as the source for each incoming value.
  2. 2
    Capture next value into Reg A. Check the GT flag on the comparator: if A > B (GT lit), the new value is larger — press B ← A to copy Reg A into Reg B.
  3. 3
    If GT is not lit, B remains the maximum. Capture next value into A and repeat.
  4. 4
    After all values: Reg B holds the maximum. Send to loop or route out.
Comparator flags are live
The comparator continuously computes all six flags (GT, LT, EQ, GTE, LTE, NEQ) against the current Reg A and Reg B values. You read the flags, decide whether to update B, and move on. No explicit "compare" step — the comparison is already done the moment A loads.
14
Conditional Swap
Replace the current maximum/minimum only when a new value beats it.
ALU Comparator
Components
ALU · Comparator flags
Par
~60 ticks · 2 ops per value
Builds on
Running Maximum (recipe 13)

The core of Running Maximum, extracted as a standalone technique because it appears in many contexts. Load a candidate into Reg A, check a comparator flag, execute one of two actions based on the flag state. The decision is yours — the flag is just information.

  1. 1
    Hold the current champion in Reg B. Load candidate into Reg A.
  2. 2
    Read the relevant flag (GT for max, LT for min, EQ for duplicate detection).
  3. 3
    If flag condition met: copy A → B (press the B←A button). If not: do nothing, B stays.
Variations
Use LT flag to track the minimum instead of maximum. Use EQ flag to detect duplicate values. Use NEQ to route only novel (unseen) values. The flag system is simple but combining flags with register swaps produces surprisingly expressive conditional logic without any branching infrastructure.
15
Absolute Difference
Compute |A − B| without signed arithmetic.
ALU Comparator
Components
ALU · Comparator
Par
~80 ticks · 5 ops
Use case
Running Delta challenge · distance
  1. 1
    Load both values into Reg A and Reg B. Set op to SUB.
  2. 2
    Check the S (sign) flag. If S is lit, the result is negative (A < B).
  3. 3
    If S is not lit: result is the absolute difference. Send to loop.
  4. 4
    If S is lit: send the result to the loop and re-capture it into Reg A, then set op to NEG. The result is now the positive absolute difference. Send to loop.
Why two cases
Loop 2.1 values are unsigned (0–65535). Subtraction that would go negative wraps around via two's complement. The S flag catches this — it lights when bit 15 of the result is 1, indicating the result wrapped. NEG (two's complement negation) converts it back to the positive distance. For the Running Delta challenge (recipe 30 in the challenge guide) you execute this pattern once per consecutive pair.
16
Binary Multiplication
Multiply two values using repeated addition.
ALU Loop iteration
Components
ALU · loop · Working Scratch
Par
36(m−1) + 82 ticks · 3m + 5 ops
m = min(a, b)
  1. 1
    Identify which operand is smaller — use it as the repeat count to minimize iterations. Call the smaller value m and the larger value n.
  2. 2
    Load n into Reg A and Reg B. Set op to ADD.
  3. 3
    Send result to loop, recapture into Reg A. Now Reg A = 2n, Reg B = n. This is the result after 1 iteration. Send and recapture m−1 times total.
  4. 4
    After m−1 sends, Reg A holds n × m. Send to loop for use.
SHL shortcut for powers of 2
If your multiplier is a power of 2, use SHL (shift left) instead of repeated addition. SHL doubles the value in one operation. Multiply by 8: SHL three times. Multiply by 6: SHL twice (×4), then ADD the original value twice. Hybrid approaches combining SHL and ADD can significantly reduce iteration count for non-power-of-2 multipliers.
17
Scratch Register Hold
Park up to four values in Working Scratch during an ALU operation.
Working Scratch ALU
Components
Working Scratch · Working loop
Par
0 ticks overhead · 2 ops per slot
Capacity
4 slots (0–3)
  1. 1
    Press CAPTURE: ON in the Working Scratch panel. The next complete word that passes the Working R head is captured into slot 0. Capture auto-advances to slot 1, then 2, then 3, cycling back to 0.
  2. 2
    The word remains circulating in Working — capture is non-destructive. Multiple words can be captured in sequence as they circulate past.
  3. 3
    To retrieve: press →W next to the slot. The value enters a 17-tick writeback pipeline into Working's write head.
Scratch vs cross-loop hold
Working Scratch is faster and requires fewer setup steps than cross-loop hold (recipe 09). Use it whenever you need to temporarily hold 1–4 Working loop values during a computation. Its limitation: values in scratch are copies — if the Working loop value changes, scratch doesn't update automatically.
Section IV
Memory
18
Sequential Store
Store a stream of values into consecutive memory slots using auto-increment.
Memory Auto-Increment
Components
Memory · Bus · Auto-Inc
Par
41n + 24 ticks · n+2 ops
Setup
Memory loop running
  1. 1
    Set the starting address on the Memory address selector. Enable TURN AUTO-INC ON. Enable ENABLE WRITE TO SLOTS.
  2. 2
    Route values from your source loop to the Memory loop via Bus B (or any bus). Each word that passes the Memory R head is written to the current address and the address advances to the next slot.
  3. 3
    After all values are stored, disable Write to Slots to prevent subsequent loop circulation from overwriting slots.
Auto-increment wraps at 16
After filling slot 15, auto-increment wraps back to slot 0. If your stream is longer than 16 − startAddress values, earlier slots will be overwritten. For a full 16-slot store, start from slot 0.
19
Address-Keyed Store
Use the top 4 bits of each arriving word to determine its destination slot.
Memory Addr-Read
Components
Memory · Addr-Read mode
Par
41n ticks · n+2 ops
Prerequisite
Values pre-encoded with address
  1. 1
    Enable ADDR-READ: ON and ENABLE WRITE TO SLOTS on the Memory panel.
  2. 2
    Route pre-encoded values into the Memory loop. Each arriving word's top 4 bits (b15–b12) are decoded as a 4-bit address (0–15), overriding the manual address selector. The word is written to that slot, full 16-bit value intact.
How to encode addresses into values
To store value V into slot S, the encoded word is (S << 12) | (V & 0x0FFF). This sacrifices the top 4 bits of the data range — maximum stored value is 4095 (0x0FFF). Use Addr-Read mode when you want non-sequential writes (slot 7, then slot 2, then slot 14) or when values are arriving already-encoded from a previous computation.
20
Destructive Recall
Read a memory slot, use its value, and automatically clear the slot.
Memory Destructive
Components
Memory · SEND TO LOOP
Par
17 ticks · 2 ops
Setup
TURN DESTRUCT ON
  1. 1
    Enable TURN DESTRUCT ON in the Memory panel.
  2. 2
    Press SEND TO LOOP next to the target slot. The value enters the 17-tick writeback pipeline and the slot is cleared (set to null) when the pipeline completes.
When to use it
Destructive recall is useful when you're consuming values from memory rather than reading them — building a sorted output stream, for example, where each extracted value should not be reused. Also useful for guaranteed-once semantics: a value in a destructive-read slot will be consumed exactly once.
21
Batch Recall
Stream all 16 memory slots into the Memory loop in slot order.
Memory Batch Write All
Components
Memory · Batch Write All
Par
272 ticks · 1 op
Output
Always 16 words
  1. 1
    Press BATCH WRITE ALL. All 16 slots stream into the Memory loop in order (slot 0 first, slot 15 last). Empty (null) slots write a zero word — marker=1, data=0 — to preserve position information in the stream.
  2. 2
    The stream is 16 × 17 = 272 bits. At 24 Hz, approximately 11 seconds from start to finish. Watch the log for each slot's transmission.
The null-to-zero behavior
Empty slots produce marker=1, data=0 words rather than being skipped. This means slot 7's value will always be the 8th word in the stream regardless of how many earlier slots are populated. Position is preserved. On the receiving side (Write to Slots + Auto-Increment), a zero word writes 0 to the corresponding slot — null and zero are indistinguishable after a batch recall cycle. This is an accepted tradeoff.
22
Memory Snapshot Save & Load
Persist the full 16-slot memory state to a .L21 file and restore it later.
Memory Files
Components
Files panel · Bus · FILE SAVE dst
Par (save)
272 ticks · 2 ops
Par (load)
272 ticks · 3 ops
  1. 1
    Open the Files panel. Press NEW FILE, enter a name, press SAVE. The system arms and displays: "Ready — send Batch Write All to FILE SAVE on Bus A, B, C, or D."
  2. 2
    Set any bus destination to File Save. Press BATCH WRITE ALL. All 16 words stream to the Files system and the snapshot is saved automatically.
  1. 1
    Enable Write to Slots and Auto-Increment (starting at slot 0) on the Memory panel. Ensure the Memory loop is running.
  2. 2
    Select the file in the Files panel. Press LOAD. The 16 words stream through the Memory loop's writeback pipeline into consecutive slots. The load pauses if the loop pauses — no bits are lost.
Persistence across sessions
.L21 files are stored in browser localStorage and survive between sessions on the same browser. Use EXPORT .l21x to archive your full /local folder to a real computer file. The .l21x format is plain text and can be opened, read, and edited in any text editor.
Section V
Pattern Matcher
23
Exact Value Eject
Eject a specific value from the Big Loop when it passes PM1.
PM1 Big Loop
Components
PM1 · Big Loop · Bus A
Par
circ + 1 ticks · 3 ops
Setup
Value in Big Loop
  1. 1
    Set PM1 mask to 1111111111111111 (all 16 bits). Set PM1 match to the exact value you want to eject (all 16 bits).
  2. 2
    Enable PM1. Enable EJECT: DESTRUCTIVE to remove the value from the loop, or EJECT: COPY to keep it circulating while also outputting a copy.
  3. 3
    Set Bus A source to PM (PM1 bridge). The ejected value exits onto Bus A. Route to your desired destination.
PM1 eject position
PM1 fires at bit index 359 on the Big Loop. There is a small cooldown after each eject to prevent the same word from triggering multiple times as it passes. With COPY mode, the value continues circulating and will re-trigger PM1 on the next pass — disable PM1 after ejecting if you only want one copy.
24
Bit-Field Filter
Route only values matching a bit pattern — odd, top-bit-set, divisible by 4, etc.
PM1 Big Loop Bus
Components
PM1 · Big Loop · Bus source = PM
Par
41n + 18m ticks · n+m ops
m = match count
Common PM1 configurations
Odd values (b0 = 1): Mask = 0000000000000001, Match = 0000000000000001
Even values (b0 = 0): Mask = 0000000000000001, Match = 0000000000000000
Top bit set (≥ 32768): Mask = 1000000000000000, Match = 1000000000000000
Divisible by 4 (b1,b0 = 00): Mask = 0000000000000011, Match = 0000000000000000
  1. 1
    Route your stream into the Big Loop.
  2. 2
    Configure PM1 mask and match bits for your condition. Enable PM1 with EJECT: DESTRUCTIVE.
  3. 3
    Set Bus A source to PM. Route matching values to your destination as they eject. Non-matching values continue circulating in the Big Loop.
Mask vs Match
The mask controls which bits are checked. The match controls what those bits must equal. Only bits where mask=1 are compared — bits where mask=0 are ignored regardless of their value in the word. This lets you check any subset of the 16 data bits independently.
25
Rewrite in Place
Modify specific bits of matching values without ejecting them from the loop.
PM1 Rewrite mode
Components
PM1 rewrite mode · Big Loop
Par
n × circ ticks · 2 ops
Eject mode
COPY (not destructive)
  1. 1
    Configure PM1 mask and match for your condition.
  2. 2
    Set the Change Mask to indicate which bits to rewrite (1 = change this bit, 0 = leave it).
  3. 3
    Set the Change Value to what those bits should become.
  4. 4
    Enable PM1 with EJECT: COPY. When a matching word passes, its selected bits are rewritten in place — the modified word continues in the loop at the same position. No ejection, no routing needed.
Example — clear the top bit of all values ≥ 32768
Mask = 1000000000000000, Match = 1000000000000000 (top bit set). Change Mask = 1000000000000000, Change Value = 0000000000000000. Every value ≥ 32768 has its top bit cleared in place. One full loop revolution processes all values — no bus routing, no ALU involvement.
26
PM Cascade — Two-Stage Filter
Use PM1 and PM2 in sequence to split a stream into three groups.
PM1 PM2 Big Loop
Components
PM1 + PM2 · Big Loop · Two buses
Groups
PM1 match · PM2 match · Neither
Eject order
PM1 at idx 359, PM2 at idx 342

PM1 is at bit index 359 on the Big Loop; PM2 is 17 bits downstream at index 342. Words pass PM1 first, then PM2. PM2 only sees words that PM1 did not eject (or that PM1 passed through in COPY mode).

  1. 1
    Configure PM1 to match Group A. Enable with EJECT: DESTRUCTIVE. Set Bus A source = PM (PM1 bridge). Group A values eject here.
  2. 2
    Configure PM2 to match Group B. Enable with EJECT: DESTRUCTIVE. Set Bus B source = PM2. Group B values eject here after passing PM1 without matching.
  3. 3
    Values matching neither condition continue circulating — Group C stays in the Big Loop.
PM2 has additional outputs
PM2 has separate bridge outputs for matched and rejected values (pm2.bridge and pm2.rejectBridge). Set Bus source to PM2 Match or PM2 Reject to route those streams independently. This gives you four potential output streams from a two-PM cascade.
27
Match Count
Count how many values in a stream satisfy a bit condition.
PM1 Match counter
Components
PM1 match counter · Big Loop · Bus
Par
41n + 544 + 41 ticks · n+8 ops
544t = counter eject latency
  1. 1
    Configure PM1 for your condition. Enable PM1. Enable the PM1 MATCH COUNTER. The counter increments every time PM1 fires.
  2. 2
    Route your stream through the Big Loop. Let all values pass PM1. No bus routing needed — you only care about the count, not the matched values themselves.
  3. 3
    After all values have circulated: press the PM1 counter eject button. The count value enters the Big Loop as a word and circulates to the R head.
  4. 4
    Route the count word to your destination (Bus E for challenge output, Bus B to Memory, etc.).
The 544-tick eject latency
The counter ejects into the Big Loop, and the Big Loop is 48 words × 17 bits = 816 bits. The ejected count word circulates approximately one-third of the loop (from eject point to R head) before it's readable — roughly 544 bits at the Big Loop's circulation rate. At 24 Hz that's about 22 seconds. Plan for it.
Section VI
Threshold Gate & Counters
28
Minimum Extraction
Extract the smallest value in a loop using the Threshold Gate in ≤ mode.
TG1 Big Loop
Components
TG1 · Big Loop · Bus
Par
~circ × n ticks per pass
Use case
Sort Values challenge core op
  1. 1
    Set TG1 threshold to a value you believe is larger than the minimum in the loop. Set TG1 mode to (less than or equal). Enable TG1 with EJECT: DESTRUCTIVE.
  2. 2
    Let the Big Loop circulate one full revolution. The first value ≤ threshold ejects. If no value ejects, lower the threshold and try again.
  3. 3
    To find the true minimum: start with a high threshold, extract the first matching value, lower the threshold to that value, and repeat. The extracted values come out in ascending order.
Iterative minimum sort
This is the foundational operation for sorting via the Threshold Gate. Each iteration extracts the current minimum and removes it from the loop, so the next iteration's minimum is the next-smallest remaining value. For n values, you do n extractions — the Sort Values challenge is exactly this loop, run n times, with each extracted value routed to Bus E outbound.
29
Range Gate
Pass only values within a specific range using two Threshold Gates in series.
TG1 TG2 Big Loop
Components
TG1 + TG2 · Big Loop
Eject order
TG1 at idx 325, TG2 at idx 308
Passes through
lo ≤ value ≤ hi
  1. 1
    Set TG1 threshold = lower bound (lo). Set TG1 mode to < (less than). Enable TG1 EJECT: DESTRUCTIVE. Values below lo eject here — they're out of range and consumed.
  2. 2
    Set TG2 threshold = upper bound (hi). Set TG2 mode to > (greater than). Enable TG2 EJECT: DESTRUCTIVE. Values above hi eject here — also out of range and consumed.
  3. 3
    Values that pass both gates (≥ lo and ≤ hi) continue circulating. Route them via a PM or bus from there.
You can also set TG threshold via bus
Bus destinations include TG1·Thresh and TG2·Thresh. Route a value from Working or ALU loop to a TG threshold destination to set it dynamically. This lets you change the gate thresholds during operation — useful when the range itself is computed from the data rather than known in advance.
30
Counter as Data
Eject a loop counter's value into the loop as a usable word.
Counter Bus ALU
Components
Counter · Bus Ctr·W/A/M/B dst
Par
17 ticks · 2 ops
Use case
Count-based routing decisions
  1. 1
    Configure a counter trigger on the desired loop (Word Written, Bit Written, or Full Cycle). Let it accumulate during normal operation.
  2. 2
    To read the counter value: press the counter eject button. The current count enters the loop as a 17-bit word via a 17-tick writeback pipeline.
  3. 3
    Alternatively: set a bus destination to Ctr·W (Working counter), Ctr·A (ALU), etc. Route a value from any loop into the counter destination — this loads the counter with that value rather than incrementing it. Useful for initializing a counter to a specific starting point.
Counters are six digits
The loop counters track up to 999,999 events before rolling over. For measuring word counts in a session, this is effectively unlimited. The Op Count (operator action counter) is separate and can be linked to Op Count Halt — when the count reaches its target, the machine stops automatically. This enables timed sessions and repeatable benchmarks without manual intervention.