Chipgrid / Documentation / Reference

Timing and logic

Clocks, beats, sequences, chance and arithmetic: the operators that make the numbers and the bangs everything else uses.

C clock

Counts ticks and writes the count below.

Counts ticks. Writes (tick ÷ rate) mod mod below: 1C4 counts 0 1 2 3 0 1 2 3… Feed it into a sequence S to walk through a melody.

CellRoleWhat it takes
leftratedivides the tick count
rightmodhow many values / how many ticks
belowoutoutput, written every tick

History. Old games ran their music from a counter tied to the screen: 50 refreshes a second in Europe (PAL), 60 in the US and Japan (NTSC). Tempo was “how many frames per row” — that is why the same game plays faster on an American console.

Example

# CLOCK - example #
.
...2C8
.1D2.SCDEFGABb
...P4.12

Open in Chipgrid ↗

2C8 counts 0 1 2 … 7, one step every 2 ticks, and writes the count below. That number is the index of the sequence S: it walks through the 8 notes. D2 plays P every 2 ticks, so each step is heard once: a rising scale.

Try this

  • Change the 8 into 4: only the first 4 notes loop.
  • Change the rate 2 into 4: each note is played twice.
  • Try 3 for the modulo: an odd loop of 3 over a beat of 4.

D beat

Writes a bang * below every N ticks.

Writes a bang * below every rate × mod ticks. D4 = every 4 ticks = every beat (a tick is a sixteenth note). D8 every two beats, 3D3 every 9 — out of step.

CellRoleWhat it takes
leftratedivides the tick count
rightmodhow many values / how many ticks
belowoutoutput, written every tick

History. A tick is a 1/16 note: 4 ticks a beat. Trackers (Soundtracker 1987, FamiTracker, LSDJ on the Game Boy) count the same way, one row per sixteenth.

Example

# BEAT - example #
.
...D4....D6
....B3C2o.N530

Open in Chipgrid ↗

D4 writes a bang every 4 ticks (every beat) next to a triangle kick. D6 bangs every 6 ticks next to a noise snare. They meet again every 12 ticks: a polyrhythm, 3 against 2.

Try this

  • Change 6 into 8: kick on every beat, snare every 2 beats — a straight rock beat.
  • Type a rate on the left: 2D4 bangs every 2 × 4 = 8 ticks.
  • Try D5 or D7 for rhythms that never sit still.

S sequence

Picks the step chosen by its index (left) and writes it below.

A sequence: the cells to its right (up to 16, until an empty cell) are the steps. The index on its left chooses which step is written below. Steps can be notes (CEGA), numbers, or bangs: *000*000 is a drum pattern (0 = rest).

CellRoleWhat it takes
leftindexwhich step to output
right, until an empty cellstepsup to 16: notes, numbers or bangs
belowoutoutput, written every tick

History. This is a tracker pattern turned sideways. Composers like Koji Kondo or Rob Hubbard wrote music as columns of note codes, one row per tick.

Example

# SEQUENCE - example #
.
.1Cg
...S*0*0*0*0*0*0*0*0
..J.N010
...S0000*0000000*000
..J.N530
...S000000*000000*0*
....N421

Open in Chipgrid ↗

One clock 1Cg counts 0–15 (a bar of 16 ticks). Three sequences read it — the Js pass the count down. Their steps are bangs * and rests 0: a drum pattern on a 16-step grid, like a drum machine. Each one plays a different noise.

Try this

  • Move the *s in a row: the rhythm changes on the next bar.
  • A sequence can hold notes too: SCEGA in front of a voice’s note input.
  • Cut a pattern short (end it with an empty cell): it loops on fewer steps.

R random

Writes a random number below, every tick.

Writes a random value between min and max below, every tick. Put it on the index of a sequence to pick random notes from a scale.

CellRoleWhat it takes
leftminlowest value
rightmaxhighest value
belowoutoutput, written every tick

History. Consoles had no randomness chip. Games used the same trick as the noise channel — a shift register — or read the frame counter at the moment you pressed a button.

Example

# RANDOM - example #
.
...0R4
.1D2.SCDEGA
...P5.12
.
....0Rn
....X.c3
.
.T3

Open in Chipgrid ↗

0R4 writes a random number from 0 to 4 every tick. It is the index of a sequence holding a pentatonic scale (C D E G A): the notes are random, but never wrong. Below, a second R gives a random x to a pixel X: it jumps along a line.

Try this

  • Change the max 4 into 2: only C, D, E.
  • Replace the scale by your own notes, e.g. SCdFGa (a minor-ish scale).
  • Change the pixel’s max n into 8: it stays on the left.

A add

Writes a + b below.

Adds a + b and writes it below (in base 36). Use it to transpose: a note index + 7 is a fifth up.

CellRoleWhat it takes
leftafirst number
rightbsecond number
belowoutoutput, written every tick

History. The 6502 processor in the NES, C64 and Apple II spent its life doing ADC (add with carry) on single bytes — 8 bits, 0 to 255. That’s what “8-bit” means.

Example

# ADD - example #
.
...2C4
.....S0247
...D2.A3
....P4.12

Open in Chipgrid ↗

The sequence holds a short melody as semitones above C: 0 2 4 7 (C D E G). A adds 3 to each one before it reaches P: the same tune, 3 semitones higher (D# F G A#). That is transposing.

Try this

  • Change 3 into 0, 1 or 2 while it plays: the tune keeps its shape and moves as a block.
  • Careful: a sum above 10 is written as a letter (b, c…), and in a note input a–g are note names (c = C#). Keep sums up to 10, or transpose by octaves on the octave input.

J jump

Copies the cell above to the cell below.

Copies the cell above to the cell below. Use a column of Js to share one clock between several sequences (see the Drums chapter).

CellRoleWhat it takes
aboveincell to copy
belowoutoutput, written every tick

Example

# JUMP - example #
.
...2C8
.1D2.SCEGEAGED
...P4.12
.....J
...Xv.4
.
.M05

Open in Chipgrid ↗

The melody note goes into P. J copies the same note one cell further down, into the y of a pixel X on the right edge (x = v = 31). M05 scrolls the picture left: each note leaves a dot at its height — a piano roll.

Try this

  • Stack two Js to carry a value two cells down.
  • Change the melody: the drawing follows.

W wave

Writes a smooth wave (a sine) below: 0 → max → 0, one cycle every rate×4 ticks.

A wave: writes a sine below, swinging smoothly 0 → max → 0, one cycle every rate × 4 ticks (4W = once a bar). phase shifts it: two waves a quarter apart (9) draw a circle. Feed it into a coordinate for motion that slows at the edges.

CellRoleWhat it takes
leftratedivides the tick count
rightmaxhighest value
2nd rightphasewhere in the cycle it starts (0–35 = a full cycle)
belowoutoutput, written every tick

History. Demos never computed sines live: the 6502 had no multiplication. They read them from a sine table — 256 precomputed bytes — and walked through it with a counter. Bouncing logos, copper bars, scrollers: all sine tables.

Example

# WAVE - example #
.
...4Wn
..Xv.6
.
.M05

Open in Chipgrid ↗

4Wn swings smoothly from 0 up to 23 (n) and back, one cycle every 16 ticks. It feeds the y of a pixel on the right edge, and M05 scrolls left: the screen draws a sine wave, like an oscilloscope.

Try this

  • Rate 2: twice as fast. Rate 8: slow and wide.
  • Max 8: a small wave at the top.
  • Add a phase on the right: 4Wn9 starts a quarter later.

Y send

Sends the value on its left to the cell dx right, dy down.

Sends the value on its left to a cell dx to the right and dy down. Use it when an input can’t be fed from just above — for example the y of an X whose x is already fed by a wave.

CellRoleWhat it takes
leftvaluewhat to send
rightdxhow many cells to the right
2nd rightdyhow many cells down
dx right, dy downoutput · targetthe cell it writes into

History. This is a store to an address: the 6502’s STA instruction wrote a byte anywhere in memory — including the video chip’s registers.

Example

# SEND - example #
.
....3Wn
......Y23
.
......1Cw
......X..4
.
.T1

Open in Chipgrid ↗

The pixel X takes its x from a clock just above it. Its y input is two cells to the right — nothing can reach it from above. So the wave 3Wn goes into Y23, which sends it 2 cells right and 3 down, straight into that y. The dot traces a sine.

Try this

  • Hover the cell Y writes into: it is marked as its target.
  • Change Y23 into Y33: the wave lands in the colour input instead.

I listen

Listens to a chip channel: writes its volume (0–f) below.

Listens to one of the chip’s four channels and writes its current volume (0–f) below: 0 pulse 1, 1 pulse 2, 2 triangle, 3 noise. Feed it into a width, a radius or a colour and the picture follows the music.

CellRoleWhat it takes
rightchannel0 pulse 1 · 1 pulse 2 · 2 triangle · 3 noise
belowoutoutput, written every tick

History. Programs could read the sound chip back: the C64’s SID let you read voice 3’s envelope, and demos used it to make the picture pulse with the music.

Example

# LISTEN - example #
.
...2C8
.1D2.SCEGEAGED
...P4.12
.
.....I0
..Qgc.3
.
.T5

Open in Chipgrid ↗

The melody plays on pulse 1. I0 listens to that channel and writes its volume (0–f) below, into the radius of a ring. Each note starts loud and fades, so the ring jumps out and shrinks with every note.

Try this

  • Change I0 into I3 (noise): nothing, no noise is playing. Add one!
  • Make the notes longer (P4.14): slower breathing.

! tempo

Sets the tempo from the three digits on its right: !150 = 150 BPM.

Sets the tempo every tick while the program plays. The three cells on its right read like a number: !150 = 150 BPM, from 40 to 999. Any of them can be fed from above, so a wave or a sequence can move the tempo. With no digits, it does nothing. While a ! is playing it overrides the BPM box. There is only one tempo: with several !, the last one you typed or edited holds it, and the others are dimmed. Delete it and the previous one takes over. With a gate, ?! changes the tempo on a bang.

CellRoleWhat it takes
righthundredsfirst digit of the BPM
2nd righttenssecond digit of the BPM
3rd rightunitsthird digit of the BPM

Example

# TEMPO - example #
.
..8Wi
.!1.0
.
.1D4
.
..B2C2

Open in Chipgrid ↗

A slow wave W writes into the tens digit of !1.0, so the tempo swings between 100 and 280 BPM. The kick below speeds up and slows down with it.

Try this

  • Remove the W and type a digit in its place: a fixed tempo.
  • Change the 1 into 5: 500 BPM and up.

? gate

Gate: the operator on its right runs only when a bang touches the gate. Red = it can do nothing there.

A gate. The operator on its right stops running by itself and runs only when a bang touches the gate, from the left, above or below. ?X draws on the beat, ?V changes palette at a new section, ?! changes tempo on cue, ?T fades on the snare. Voices, F and K fire on a bang at the gate, as if it touched them. A gate shown in red can do nothing: movers, ; and operators with an input on their left, like C or D.

Example

# GATE - example #
.
.1D40Rv
...?X.c7
.
.T2

Open in Chipgrid ↗

1D4 bangs every 4 ticks and the bang touches the gate. X behind it draws only then, at a random x, so the dots land on the beat.

Try this

  • Delete the ?: X draws every tick again.
  • Put a gate before T2: the picture fades only on a bang.

@ send

Sends its left value, or a bang, over a named link. Uppercase = shared with the room.

Sends over a named link: a wire with no cable, so code can sit anywhere on the grid. It sends the value on its left, or a bang if a bang is on its left, above or below. & with the same name receives it. A lowercase name is yours alone. An uppercase name is shared with the whole room in multiplayer: one player sends on B, and whoever wants it listens. A bang arrives in the same tick; a value reaches a sound in the same tick and other operators in the next one.

CellRoleWhat it takes
leftvaluewhat to send
rightnamelowercase = yours · uppercase = shared with the room

Example

# SEND - example #
.
.1D4
...@k
.
.
..&k
...P4C24

Open in Chipgrid ↗

The bang under D goes into @k, and &k writes it out below itself, right next to the voice. No cable: move the bottom part anywhere and it still plays.

Try this

  • Add a second &k somewhere else, with its own voice.
  • In multiplayer, use K instead of k: everyone can listen.

& receive

Receives from a named link and writes it below.

Receives what an @ sends under the same name and writes it below: the last value sent, or a bang for one tick. Several & can listen to one name.

CellRoleWhat it takes
rightnamelowercase = yours · uppercase = shared with the room
belowoutoutput, written every tick

Example

# RECEIVE - example #
.
.2C4
...@n
.
...&n
.D2.SCEGA
..P4.24

Open in Chipgrid ↗

This time the link carries a value: the clock’s count travels from @n to &n and walks the sequence below.

Try this

  • Change the 2 in 2C4: the melody speeds up, from far away.

; swell

Jumps to its peak on a bang, then falls back: wire it in and things pulse.

A swell. A bang sets it to peak (15 if empty), then it falls by one every fall ticks and writes its value below. Wire it into a size, a colour or an amount and things pulse with the music: the kick makes the ring jump, and it shrinks back by itself.

CellRoleWhat it takes
rightpeakwhere a bang sets it (empty = 15)
2nd rightfallticks between two steps down
belowoutoutput, written every tick

Example

# SWELL - example #
.
..1D8
....;f1
.Qgc.7
.
.T41

Open in Chipgrid ↗

Each bang sets ; to f (15), then it falls by 1 every tick. Its value is the radius of the ring, so the ring jumps and shrinks back.

Try this

  • Change the fall 1 into 3: a slower swell.

, eye

Looks at one block of the picture and writes its colour, or a bang, below.

An eye: it looks at one block of the picture, at x, y, and writes below what it sees: the colour there, or nothing. With lit 1, it writes a bang if anything is drawn there. So the picture can play the music: draw bars, sweep an eye over them, and each bar is a note. It reads the layer it is on, so a scan line on another layer doesn’t disturb it.

CellRoleWhat it takes
rightx0–31 blocks (×5 pixels)
2nd righty0–23 blocks
3rd rightlit1 = a bang if something is there
belowoutoutput, written every tick

Example

# EYE - example #
.
.H0841
.
.1Cw
.,.81
..P5C02

Open in Chipgrid ↗

A bar is drawn from x = 0, 4 blocks wide, and the clock sweeps the eye along the row. While it passes over the bar, it writes a bang, and the voice plays. The picture is the score.

Try this

  • Change the width of the bar: a longer note pattern.
Esc