Getting Started
This web application is designed to assemble SpinASM source code into machine instructions for the FV-1 DSP chip. Generated machine code may be saved locally for later use, or sent to a Sandbox FV1 hardware target to hear the results.
- Enter SpinASM source code into the editor area, or select a file or example. Press the Assemble button to verify and assemble the code into a HEX file
- Press the Download HEX to save the resulting HEX file to your local Downloads folder. Check the Build Results for success or error messages.
- Download Binary and Download C Headers output the assembled data in alternate format for use with more advanced applications and are not used with Sandbox FV1 hardware
- When satisfied with your source code, press the Save Source... button to download a local copy.
Simulator
The TEST DRIVE tab runs your assembled program through a software FV-1 so you can hear it without hardware.
- Press Assemble, open the TEST DRIVE tab, then press Play. Ctrl+P (Alt+P on Windows) plays and stops from anywhere, including the editor, and opens the tab as it starts.
- Choose a Source: a test tone, noise, a one-second click train, an audio file from your computer, or live input from a microphone or interface. Audio files of any sample rate are resampled to the simulator's clock when loaded.
- The Clock section sets the crystal the simulated chip runs on. Crystal lists the standard parts from 8.192 kHz to 64 kHz; the Rate slider sweeps anything from 4 kHz to 48 kHz and reads Custom when it lands between two named parts. Both are live - the slider can be dragged while a program plays, and CC60 does the same from a MIDI controller. The line underneath gives the two things that follow from the crystal: how much delay time the fixed memory buys you, and where the audio band ends.
- The POT0-POT2 sliders correspond to the three knobs on the Sandbox hardware. A program can name them: put a tag in a comment, like ; #POT0 Delay time, and the labels follow it as you type. Tags are read from the comment part of a line, so they never collide with code, and hovering a renamed pot still shows which one it is.
- The Indicators lamps follow REG30 and REG31. Brightness is the register read as S1.23 - 0 is off, 1.0 is full - and a negative value is off rather than rectified, so a bipolar LFO lights the lamp for half of each cycle unless the program folds it first with sof 0.5, 0.5. The scale is linear on purpose: a program that wants a curve is two instructions from the curve it wants. Name them with ; #LED1 Tempo, as with the pots. Nothing on the FV-1 reserves REG30 or REG31, so a program parking scratch there will light a lamp by accident.
- With Reset on assemble ticked, every successful build is loaded straight into the simulator, so you can edit and re-assemble while it plays.
- Bypass compares against the dry signal, and Reset clears the simulated delay memory.
The simulator models the 24-bit accumulator saturation and the 14-bit companded delay memory that give the FV-1 its character. LFO rates and depths follow the equations in Spin's application note AN-0001. The fractional interpolation inside CHO is approximated, so chorus and flange sound correct but are not sample-identical to hardware. Confirm on the pedal before shipping a design.
Your program is unchanged by the Crystal setting - it still runs 128 instructions per sample - but every delay and LFO sweep scales with the clock, and the fixed delay memory buys you proportionally less time. Halve the clock and every delay lasts twice as long, every LFO sweeps at half the speed, and the audio band ends an octave lower.
The core is clocked separately from the audio graph rather than by it, which is what lets the clock move without stopping anything: sweep the Rate slider mid-program and delay memory keeps its contents, the input keeps playing, and a reverb tail carries across the change instead of being cut off. The conversion between the two clocks band-limits the core's input and output to its own Nyquist, the way the converters on either side of a real FV-1 do, so a low crystal sounds dark rather than aliased.
MIDI Control
The simulator can be played from a MIDI controller plugged into your computer. Press Enable MIDI in the TEST DRIVE tab, allow the browser's prompt, then choose an Input and Channel. The dot and the line beside the button show the last message that was accepted, which is the quickest way to tell whether a controller is reaching the page at all.
- CC50, CC51 and CC52 sweep POT0, POT1 and POT2.
- CC60 sweeps the clock across the same 4 kHz to 48 kHz the Rate slider covers - 0 is 4 kHz, 127 is 48 kHz, and the stock 32.768 kHz is around 83. It changes the crystal while the program runs, so an expression pedal on CC60 stretches every delay and sweep in the program without interrupting it.
- CC102 switches the effect: 0-63 bypasses, 64-127 engages.
Nothing here responds to MIDI beat clock. CC60 is the crystal, not tempo sync: the FV-1 has no tempo to lock to, and on hardware changing it means changing the part. A control change with no control behind it is accepted and does nothing. MIDI otherwise moves the same controls the sliders do, at the full 128 steps a control change carries, so a program cannot tell the difference between a fader and a mouse. The chosen input and channel are remembered, and a controller unplugged and plugged back in is picked up again on its own.
Web MIDI needs Chrome, Edge or Firefox - Safari does not implement it. Note that the Sandbox pedal itself has no MIDI input; this drives the simulator only.
Watching the Program Run
The simulator can be watched as well as heard. Both of these live in the Registers section of the TEST DRIVE tab.
- Open register viewer opens a second window showing ACC, the audio in and out, the pots, the LFOs and REG0-REG31 as the program runs - each as its S.23 value and the 24-bit word behind it. Registers are named after the EQU lines in your source, so REG5 reads as REG5 feedback. It is a real window: drag it to a second display and leave it there while you edit.
- Click a register name in the viewer to plot it over time. The Window menu sets how much time the plot covers, from 64 ms to 16 s. An audio-rate signal shows as its envelope and an LFO as its shape, so a sweep that is too fast, an envelope follower that never settles, or a feedback path ringing up are all visible at a glance.
- ACC trace in editor writes the accumulator after every instruction at the end of its line, live, while the program plays. A SKP line says taken when it jumped, the lines it jumped over say skipped, and a line whose result had to be clamped shows clip with the share of recent samples on which that happened - a line pinned at 100% is saturating, one at 2% is catching peaks. The FV-1 runs every instruction every sample, so one pass is a complete trace and there is nothing to step through to see it.
- The trace belongs to the build the simulator is running. Edit the source and it disappears until you assemble again, rather than drifting onto the wrong lines.
Halting and Stepping
The Debug section of the TEST DRIVE tab stops the simulator where it stands and lets you step it one instruction at a time. Breakpoints only fire while the simulator is running, so assemble and press Play first.
- Halt freezes the core at the end of the current sample. The panel shows where it stopped, a ▶ in the editor's margin marks the next instruction, and every line above it shows the accumulator value it just produced; lines below show … because they have not run yet this sample. If the register viewer is open it shows the halted state too.
- Step runs one instruction. Sample runs the rest of this pass and stops at the top of the next one. Run to line carries on until that line is next, across samples if it has to. Stepping off the last instruction lands on end of sample; one more step starts the next.
- Resume (the Halt button, renamed) carries on from wherever the stepping got to. While halted the output is silent and the input is held at the sample it halted on, so stepping through a delay tail shows what the program does with that one input value rather than continuing the tone.
- Reset, or re-assembling with Reset on assemble ticked, clears a halt: the core that was being stepped no longer exists.
Breakpoints are conditions rather than places. Every instruction runs every sample, so a breakpoint on a line by itself halts on the very next sample - a fraction of a millisecond after you set it. That is fine when the point is to step through the program from there; for anything else, give it a condition. Two ways to set one:
- Click the margin just left of a line number. A red dot appears and the line halts on the next sample. Click again to remove it.
- Use the form under Breakpoints for something more specific. Pick a kind, fill in the fields, press Add:
- Line with first run halts only on sample 0, before skp run has started skipping - the way to inspect initialisation code such as a wlds. With on sample # it halts on exactly that sample: 32768 is one second in at the stock crystal.
- Clip halts the first time a line's result is clamped. Leave the line blank for any line.
- SKP halts when a branch goes the way you name, taken or not taken.
- ACC and Register halt when the value crosses a threshold - DACL > 0.9, REG5 < -0.5. They fire when the condition becomes true, not while it stays true, so a register sitting above its threshold does not halt again on the instruction after every resume. Registers are listed with their EQU names.
Each breakpoint in the list has a checkbox to leave it set but quiet, and ✕ to remove it. Click one to jump to its line. A breakpoint on a line with no instruction - a comment, a blank line, an EQU - is shown greyed until a build gives that line one. Breakpoints follow their lines as you edit above them, and are matched to the build again on every assemble.
Extended Instruction Set
This program carries #extended, which turns on an instruction set beyond the FV-1's own - the same instruction set with the constraints that made sense in silicon in 1999 lifted. An FV-1 does not implement any of it, so an extended build is not a program the Sandbox pedal can run. Delete the line and the extra instructions become errors again, which is the point: without it, this assembler produces exactly the bytes it always did.
- Delay memory is 65536 words rather than 32768 - two seconds at the standard crystal instead of one - and MEM may allocate all of it.
- POT3, POT4 and POT5 join the three the FV-1 has. The simulator shows sliders for them as soon as the source carries the pragma - you need the slider while you are writing the program that reads it, not after - and CC53, CC54 and CC55 sweep them.
- RMPAX reads ADDR_PTR as ACC[22:7] instead of ACC[23:8], keeping the accumulator's sign out of the address so wrax addr_ptr / rmpax sweeps the whole tank with no seam. Plain RMPA still works, and still reaches only the low 32K.
- RAND loads a register with a uniform random sample - rand reg0, 0.002 is a dither, rand reg0, 1.0 is full scale - without spending four or five instructions on an LFSR.
- SIN2, SIN3, RMP2 and RMP3 double the LFOs, with their eight registers at 0x08-0x0f.
- A program may be 256 instructions rather than 128. The FV-1 runs all 128 every sample whether they are used or not, so on the chip the length is the time budget; off it a skip skips and the padding is never reached, so what is left of 128 is a container. The image only grows if the program does - 128 instructions or fewer still assemble to the same 512 bytes - and a skip still reaches 63 instructions, which is now less than a quarter of a program.
The EXTENDED section of the instruction reference has the detail, and appears alongside this one. The simulator runs all of it, so an extended program can be auditioned here before it goes anywhere near hardware - but Download to Hardware will ask before writing one to a Sandbox pedal, since what is in that pedal is an FV-1.
Connecting to Hardware
Connect your Sandbox FV1 pedal to your computer using a suitable USB cable. A new removable drive labeled SANDBOX-FV1 should appear.
- Open the Hardware Options section to Select Output Directory button to specify the path to your Sandbox FV1 (typically /SANDBOX-FV1).
- Use the Filename / Toggle Position buttons to select the destination slot on your hardware device
- Press the Download to Hardware button to save your algorithm to the Sandbox FV1 hardware unit
Troubleshooting
Errors and warnings will appear in the Build Results window and are often helpful for troubleshooting. Scroll up to the top to see previous messages
- Error information not helpful - use Editor Options - Show full build results to see more detailed info
- File transfer problems - ensure proper directory permissions
- Assembly errors - check syntax and register usage
- Connection issues - verify USB cable and folder selection
What do these Options do?
These are some settings that change various editor settings
Editor Options
- Select Project Folder: Choose path to save HEX, binary, header, and source files
- Large editor window: Expands editor text area to show more instructions
- Theme: Use light, dark, or system color theme
- Show editor mini-map: Show a small navigation map in editor
- Show full build results: Show complete debug information in Build Results window
Hardware Options
- Select Output Directory: Specify the folder location of your Sandbox FV hardware (typically /SANDBOX-FV1)
- Filename / Toggle Position: Select the destination slot on your hardware device