1. Introduction
This guide covers the software side of the FV-1 platform: writing SpinASM programs, assembling them into EEPROM files and loading them onto a pedal.
SpinASM for VS Code is a Visual Studio Code extension for .spn source files on Windows, macOS and Linux. It adds syntax highlighting, completion, live diagnostics and resource tracking, and drives the open-source asfv1 assembler to build your programs.
The workflow has three stages, and you can stop after any of them:
- Write a
.spnprogram, with the editor catching mistakes as you type. - Assemble it into a file for one of the EEPROM’s eight program slots, or into a complete EEPROM image.
- Program the EEPROM directly from VS Code with a compatible programmer.
Only the last stage needs hardware, so you can learn the language and build programs with nothing on the bench.
2. Install and Configure
You need two pieces: the extension for editing, and asfv1 to turn your source into code the FV-1 can run.
| Item | Needed for |
|---|---|
| Visual Studio Code 1.95 or newer | Running the extension |
| SpinASM for VS Code | Editing, compiling and programming |
Python 3 and asfv1 |
Compiling programs and EEPROM images |
| A compatible programmer (optional) | Writing the EEPROM from VS Code |
Install the extension
- Open the Extensions view (
Ctrl+Shift+X, orCmd+Shift+Xon macOS). - Search for
@id:ygn-effects.vscode-spinasmand install SpinASM for VS Code from YGN Effects. - Open any
.spnfile. The language indicator in the lower-right corner should read SpinASM.
A warning that the compiler path isn’t configured is expected at this point; you’ll set it once asfv1 is installed.
Install asfv1
asfv1 is a Python package. Install it for your user account, then check that your terminal can run it.
Windows (PowerShell):
- Check for Python with
py --version. If the command is missing, install Python 3 from python.org and open a new PowerShell window. -
Install the assembler:
py -m pip install --user asfv1 - Check that it runs:
Get-Command asfv1.exe. If it’s found, you’re done. If not,pipprinted a warning naming the PythonScriptsfolder that holdsasfv1.exe; note that full path for the next step.
macOS and Linux (terminal):
- Check for Python and
pipwithpython3 -m pip --version. If it’s missing, install Python 3 from python.org on macOS, or your distribution’spython3andpython3-pippackages on Linux. -
Install the assembler:
python3 -m pip install --user asfv1 - Check that it runs:
command -v asfv1. If nothing is printed, it was installed outside yourPATH: look in thebinfolder of the location printed bypython3 -m site --user-baseand note the full path toasfv1.
Tip: On some Linux distributions
pipstops with anexternally-managed-environmenterror. Installpipxfrom your package manager and runpipx install asfv1instead.
Configure the compiler path
- Open Settings (
Ctrl+,, orCmd+,on macOS) and search forSpinASM. - In
spinasm.compiler.path, enterasfv1if your terminal found it by name, or the full path you noted otherwise. Don’t add quotation marks, even if the path contains spaces. - Leave
spinasm.compiler.argsat its default,["-s"].
The first compile in section 5 confirms that VS Code can launch the assembler.
Caution: The
-sargument makesasfv1read the literals1and2the way SpinASM does. Removing it changes the meaning of existing SpinASM source, so keep it unless you have a specific reason not to.
3. Understand the Project Layout
An FV-1 EEPROM holds eight programs. The extension maps those slots to folders named bank_0 to bank_7: the folder decides which slot a program goes into, so the file name is free to describe the effect.
my-fv1-project/
├── bank_0/
│ └── chorus.spn
├── bank_1/
│ └── delay.spn
├── bank_2/
│ └── reverb.spn
├── bank_3/ … bank_7/
└── output/
├── bank_0.hex
├── bank_1.hex
├── bank_2.hex
└── output.bin
Compiled files land in output: one bank_N.hex per program, and output.bin when you build a complete EEPROM image. The folder starts empty and fills as you compile.
Create a new project
- Open an empty folder in VS Code (File > Open Folder).
- Run SpinASM: Create Project from the Command Palette (
Ctrl+Shift+P, orCmd+Shift+Pon macOS).
The command creates the eight bank folders, the output folder and a starter program.spn in each bank. It doesn’t need the compiler, and it leaves existing folders and files alone. Rename each starter file after the effect you plan to put there, and delete it from any bank you want to leave empty.
Open an existing project
Open the folder that contains the bank_N folders, not an individual bank. Missing bank folders, and folders without a .spn file, count as empty banks.
One program per bank
Keep a single .spn file in each bank folder. If a bank holds several, the extension builds the first one in alphabetical order and flags the bank as ambiguous, which may not be the program you meant. Keep alternate versions and experiments outside the bank_N folders.
Read the bank status
The status bar shows the state of all eight banks:
| Symbol | Meaning |
|---|---|
- |
Empty bank |
✗ |
Source not compiled yet |
✓ |
Compiled output is up to date |
⚠ |
Source changed since the last compile |
Click the indicator (or run SpinASM: Show Bank Status) for the detailed list. Selecting a bank opens its source and offers to compile it if its output is missing or out of date.
4. Work with SpinASM Files
Each .spn file is one FV-1 program. Everything in this section works without a compiler or programmer, so it’s the place to study existing effects or sketch new ones.
Create a program
Create a .spn file inside the bank folder you want, for example bank_0/passthrough.spn, and enter a first program. This one sends the left input straight to the left output:
; Left-channel passthrough
rdax ADCL, 1.0
wrax DACL, 0.0
Save it, and the bank indicator shows ✗: the source exists but hasn’t been compiled yet.
Completion and snippets
As you type, the extension suggests instructions, registers, condition flags and the symbols declared in the current file, each with its signature and a short description. Pick a suggestion, then press Tab to move between its operands. If the list doesn’t open on its own, press Ctrl+Space (on macOS, use your Trigger Suggest shortcut, as Ctrl+Space often switches input source).
Every instruction has a snippet, and a few larger ones cover common structures:
| Prefix | Inserts |
|---|---|
fxstart |
A mono effect skeleton with one-time initialisation, ADC input and DAC output |
skprun |
A run-once initialisation block using the RUN condition |
adcsetup |
Reads of both ADC inputs |
dacwrite |
Writes to both DAC outputs |
allpass |
An all-pass delay section using RDA and WRAP |
lpf |
A first-order low-pass filter using RDFX and WRAX |
Inspect instructions and symbols
Hover over an instruction, register or flag to see its signature and purpose. Hovering also works on your own symbols: EQU constants and register aliases, MEM delay-memory blocks and jump labels. Press F12 (or Ctrl+Click, Cmd+Click on macOS) on one of them to jump to its definition in the same file.
Live diagnostics
The extension checks the file shortly after you stop typing and every time you save. Problems are underlined in the editor and listed in the Problems view (Ctrl+Shift+M, or Cmd+Shift+M on macOS), where selecting one jumps to its line. The checks catch:
- malformed
EQUandMEMdeclarations - unknown instructions, and duplicate or undefined symbols
- missing operands or commas
- coefficients outside their valid range
- programs over the instruction or delay-memory limits
These checks give you quick feedback, but asfv1 has the final word: its warnings and errors appear in the same Problems view when you compile.
Watch resource usage
An FV-1 program has three hard limits: 32 registers, 128 instructions and 32,768 samples of delay memory. The R, I and M values in the status bar track them for the file you’re editing (M is rounded), and turn to a warning or critical state as you approach a limit. Click them (or run SpinASM: Show Resource Usage) to see every register alias, the remaining instructions and each MEM block.
Note that this indicator answers a different question from the bank indicator: it tells you whether the current program fits, while the bank indicator tells you whether the project’s outputs are up to date.
5. Compile Programs and EEPROM Images
Compiling (or assembling) turns your source into the 32-bit instructions the FV-1 runs. There are two kinds of output:
bank_N.hex: one program in Intel HEX format, addressed to its slot. This is what the programmer uploads.output.bin: a raw 4 KB image of the whole EEPROM, for other programming tools or manufacturing.
Save your changes before compiling: the extension refuses to build a program whose editor has unsaved changes, so it never compiles a version you aren’t looking at.
Compile the current program
- Open the
.spnfile and save it. - Run SpinASM: Compile current program, click the checkmark button in the editor title or press
Ctrl+Alt+B.
When the success message appears, output/bank_N.hex exists and the bank indicator shows ✓. If the compile fails, the SpinASM output channel opens with asfv1’s message, and the error is also underlined in the source.
Tip: Keep the SpinASM output channel (View > Output, then SpinASM) open while you’re learning. Seeing which line produces which
asfv1message teaches you the assembler’s rules quickly.
Compile the whole project
Run SpinASM: Compile all programs to build every populated bank in order, skipping empty ones. It stops at the first bank that fails, so fix that source and run it again.
Build a complete EEPROM image
Run SpinASM: Compile all programs to .bin when another tool needs the whole EEPROM as one file. The extension compiles each populated bank into its 512-byte slot, fills empty slots with 0x00 and writes the 4 KB result to output/output.bin. It doesn’t create or refresh the individual .hex files.
Caution:
output.bincovers all eight slots, empty ones included. Writing it with another tool replaces every program on the EEPROM.
6. Program an EEPROM
With a program compiling cleanly, you can write it to the EEPROM on your target board straight from VS Code. Two programmer designs are supported, and both use the same commands:
- the YGN FV-1 EEPROM Programmer: see FV-1 Programmer Flashing and Setup
- a 3.3 V Arduino Pro Mini with a USB-to-serial adapter: see Arduino Pro Mini FV-1 Programmer Setup
Finish your programmer’s setup guide first; it covers the wiring and power. This section covers the VS Code side.
Connect and check the hardware
- Connect the programmer to the target board as its setup guide shows, and power the board. Both programmers run from the target’s 3.3 V supply.
- Connect the programmer to your computer and open your project in VS Code.
- Run SpinASM: Auto-Detect Programmer. It probes your serial ports and saves the first one that answers. If it finds nothing, or you have several serial devices connected, use SpinASM: Select Serial Port… instead.
- Run SpinASM: Check Hardware Connection. It checks the whole chain (compiler, programmer and EEPROM) and reports Compiler and Programmer are connected and ready! when everything answers.
The serial port is saved as a machine setting, so it stays out of your project files.
Caution: Keep 5 V power and 5 V serial logic away from the programming connection. The EEPROM, the programming header and the Arduino Pro Mini all work at 3.3 V.
Compile, upload and verify one bank
For everyday work, use Compile & Upload current program: it rebuilds the source, writes only that program’s 512-byte slot and checks the result.
- Open the
.spnfile and save it. - Run SpinASM: Compile & Upload current program, click the lightning-bolt button in the editor title or press
Ctrl+Alt+U. - Keep the board powered and connected until the success message appears.
After writing, the extension reads the 512 bytes back and compares them with the compiled program, so a success message means the data on the EEPROM is verified. The other seven slots are left untouched, which lets you iterate on one effect without rebuilding the rest.
Other banks and upload-only commands
Compile & Upload Specific Bank… lets you pick a bank without opening its source, and Compile & Upload all programs rebuilds, writes and verifies every populated bank. Empty banks are skipped, so their contents on the EEPROM stay as they were.
The Upload commands skip compiling and send the existing .hex files. Before uploading, they check each bank’s output: if it’s missing or older than its source, you’re offered Compile & Upload instead (or Upload Anyway, when an older output exists and you really want the previous version).
Compile, upload and hardware commands run one at a time. If you start one while another is running, it waits for the first to finish.
7. Command Reference
Type SpinASM in the Command Palette to list the commands. Current-program commands appear only while a .spn editor is active.
Project and status
| Command | What it does |
|---|---|
| Create Project | Adds bank_0 to bank_7, a starter program.spn in each and output to the open folder. Keeps existing files. |
| Show Bank Status | Lists the eight banks with their state, including ambiguous banks. Selecting one opens its source and offers to compile it. |
| Show Resource Usage | Registers, instructions and delay memory used by the active .spn file. |
| Show Configuration | Shows the compiler path, serial port and baud rate, with a button to open the settings. Doesn’t test them. |
| Check Hardware Connection | Tests the compiler, the programmer’s response and the EEPROM. Needs the hardware connected. |
Programmer selection
| Command | What it does |
|---|---|
| Auto-Detect Programmer | Probes the serial ports at the configured baud rate and saves the first one that answers. Doesn’t check the EEPROM. |
| Select Serial Port… | Lists serial ports with their manufacturer and USB IDs, and saves your choice. Doesn’t test it. |
Compile
| Command | Output |
|---|---|
| Compile current program | bank_N.hex for the active or selected file |
| Compile Specific Bank… | bank_N.hex for the bank you pick |
| Compile all programs | bank_N.hex for every populated bank; stops at the first failure |
| Compile all programs to .bin | output.bin only, with empty slots filled with 0x00 |
Upload
All uploads write the selected 512-byte slots and verify them by read-back. Empty banks are skipped.
| Command | What it does |
|---|---|
| Compile & Upload current program | Rebuilds and uploads the active or selected program |
| Compile & Upload Specific Bank… | Rebuilds and uploads the bank you pick |
| Compile & Upload all programs | Rebuilds and uploads every populated bank |
| Upload current program | Uploads the existing .hex; offers to compile it first if it’s missing or out of date |
| Upload Specific Bank… | Same, for the bank you pick |
| Upload all programs | Same, for every populated bank |
Buttons, menus and shortcuts
| Where | Actions |
|---|---|
| Editor title | Compile current program, Compile & Upload current program |
Editor and Explorer context menus on a .spn file |
Compile, Compile & Upload, Upload current program |
| Bank status indicator | Show Bank Status |
| Resource indicator | Show Resource Usage |
Ctrl+Alt+B |
Compile current program |
Ctrl+Alt+U |
Compile & Upload current program |
Menu actions apply to the file you clicked; Command Palette and shortcut actions apply to the active editor.
8. Settings Reference
Search for SpinASM in Settings to see all seven options. Set the compiler path and serial port at the User level, as they belong to the machine rather than the project.
| Setting | Default | What it changes |
|---|---|---|
spinasm.compiler.path |
Empty | The asfv1 command: a bare name found on your PATH, such as asfv1, or a full path. No quotation marks. Needed to compile, not to upload existing output. |
spinasm.compiler.args |
["-s"] |
Arguments passed to asfv1 before the file names. -s gives SpinASM-compatible handling of the literals 1 and 2. |
spinasm.programmer.serialPort |
Empty | Port used for uploads and hardware checks, for example COM3, /dev/cu.usbserial-* or /dev/ttyUSB0. Set by auto-detect or manual selection. |
spinasm.programmer.baudRate |
57600 |
Serial speed. Must match the programmer firmware; leave it at 57600 with the supplied firmware. |
spinasm.editor.compileOnSave |
false |
Compiles a bank’s .hex whenever you save its source in the editor. Doesn’t build output.bin or upload. |
spinasm.statusBar.enabled |
true |
Shows the eight-bank indicator. The resource indicator stays visible either way. |
spinasm.logging.verbose |
false |
Adds every serial message to the SpinASM output channel. Turn it on only while diagnosing programmer problems. |
Caution: Changing the baud rate in VS Code doesn’t change the programmer’s firmware. If the two don’t match, they can’t communicate.
9. Troubleshooting
Start from the exact message VS Code shows. The SpinASM output channel (View > Output, then SpinASM) has the full log of every operation.
The file isn’t recognised as SpinASM
No highlighting, completion or status indicators. Check that the file name ends in .spn and that the language indicator in the lower-right corner reads SpinASM (click it to change it). For project commands, open the folder containing the bank_N folders, not a single file.
Compiler not set or not found
Compiler path is not set in Settings or Compiler "…" not found or not executable. Run Get-Command asfv1.exe (Windows) or command -v asfv1 (macOS and Linux). If it prints a path, put asfv1 or that path in spinasm.compiler.path. If it prints nothing, find the executable as described in Install asfv1 and enter its full path.
Unsaved changes
… has unsaved changes. Save it before compiling. Save the file (or File > Save All) and run the command again.
The file isn’t a project program
Current file is not a valid project program or Program at index N does not exist. The file must sit in a folder named exactly bank_0 to bank_7 (lower case matters on Linux), directly inside the folder open in VS Code.
The wrong file builds
Bank Status reports a bank as ambiguous. The bank holds more than one .spn file, and the extension builds the first alphabetically. Move the extra files out of the bank folder.
An upload finds no output
No output file found for bank N or Unable to open file. The bank’s .hex is missing or unreadable. Use the matching Compile & Upload command, which builds a fresh output before uploading.
Compilation fails
Compilation failed for program N. Select the error in the Problems view to jump to the line, and read the full asfv1 message in the output channel. Typical causes are an undefined symbol, a malformed operand, a missing comma or a program over the FV-1’s limits. A failed compile is never a programmer problem, so fix it before touching the hardware.
No programmer detected
No serial ports detected, Could not auto-detect programmer or Programmer did not respond.
- Check that the target board is powered; the programmer runs from its 3.3 V supply.
- Use a USB cable that carries data, not a charge-only cable.
- Close serial terminals and flashing tools that may hold the port open.
- Check that
spinasm.programmer.baudRateis57600with the supplied firmware. - On Linux, your account may need access to serial devices, usually through the
dialoutgroup or a udev rule. Sign out and back in after changing groups.
The EEPROM doesn’t respond
EEPROM is not ready or EEPROM isn't responding. The programmer answers but can’t reach the EEPROM. Keep the board powered, check the SDA, SCL, FV-1 RESET, 3.3 V and GND connections, make sure no 5 V source is connected and secure or shorten loose jumper wires. Then run Check Hardware Connection again.
Verification fails
Data verification failed. At least one byte read back differs from what was written, so treat the bank as not programmed. Power-cycle the board, check the SDA, SCL and ground connections and the stability of the board’s power, then run Check Hardware Connection and the Compile & Upload command again. If it keeps failing, inspect the EEPROM and the target board.
Reporting a bug
If a problem persists, open an issue in the YGN FV-1 platform repository with:
- your operating system, VS Code version and extension version
- the command you ran and the exact error message
- the relevant SpinASM output, captured with
spinasm.logging.verboseenabled if the problem involves the programmer (check it for paths or port names you’d rather not share) - the source needed to reproduce the problem
Found an Issue?
Help improve this documentation by reporting errors or suggesting improvements.