Atari ST track
Step 6 ยท Atari ST

Your first build.

Compile the template without changing a single line, put it on the board, and watch it run. This is the step that proves your whole toolchain works, while the code is still known-good.

Build it

From the root of your cloned repository:

Terminal
./build.sh pico_w debug 44444444-4444-4444-8444-444444444444

The three arguments are:

Argument Meaning
pico_w The target board. The Pico W is the only supported one, so this argument does not really vary.
debug Build type. Debug keeps the diagnostics you will want in step 9. release is for publishing.
44444444-...-444444444444 The app's UUID. See below, this particular one is special.

The first build is slow, because it is compiling the Pico SDK and pulling the Docker image that assembles the 68000 half. Later builds are much faster.

About that UUID

Every microfirmware is identified by a UUID, not by its name. Booster uses it to decide which settings sector belongs to which app, and the store uses it to tell releases of the same app apart from different apps.

44444444-4444-4444-8444-444444444444 is the shared development UUID. Everyone uses it while building, which is fine because it never leaves your desk.

It is also the reason step 4 put the device on the Development channel. That UUID is the DEV APP slot, and the slot only exists on Development. Build with it while the device is on Stable or Testing and there is nowhere for the result to go.

Never publish anything built with the development UUID.

Two published apps sharing a UUID collide. They fight over the same settings sector, and the catalogue cannot tell them apart. Step 10 has you generate a real UUIDv4 of your own for the release build. Until then, the development UUID is exactly right.

What you get

build.sh wipes dist/ and rebuilds it, so what is in there is always the current build and nothing else:

File What it is
<uuid>-<version>.uf2 The firmware image. This is what goes on the board. The version comes from version.txt at the repository root.
<uuid>.json The app's descriptor, built from desc/app.json with the UUID, version and checksum filled in. Step 10 is about this file.
rp.uf2.md5sum The checksum, as md5sum wrote it. The hash itself is already copied into the descriptor, so this is a byproduct rather than something you publish.

Note the version in the .uf2 filename. It catches people out when they go looking for <uuid>.uf2 and find nothing.

Put it on the board

Two ways. Take the Wi-Fi one if you turned on developer mode in step 4, because you are about to do this a few hundred times and the difference adds up.

Over Wi-Fi, Booster v2.3.0 and later

Two curl calls. The board stays plugged into the Atari, nothing gets unplugged, and the app launches by itself.

upload
UF2=dist/44444444-4444-4444-8444-444444444444-$(cat version.txt).uf2

curl --fail --data-binary @"$UF2" \
     -H "Content-Type: application/octet-stream" \
     "http://sidecart.local/dev_upload.cgi"
launch
curl --fail "http://sidecart.local/mngr_launchapp.cgi?uuid=44444444-4444-4444-8444-444444444444"

If sidecart.local does not resolve on your network, use the device's IP address instead. The booster repository documents a make deploy target that runs both calls, and takes DEVICE=192.168.1.50 to override the host. Full details in DEPLOY-API.md .

This only answers while the device is on the Development channel with the DEV APP installed, which is what the red DEVELOPMENT MODE banner tells you. A refused curl almost always means the channel was switched or the DEV APP was removed.

Over USB with picotool

Always works, needs no network, and needs no developer mode. It also means physically getting at the Pico W every time.

Terminal
picotool load dist/*.uf2

If picotool is not behaving, its repository documents the flags, and Raspberry Pi's Pico-series page covers BOOTSEL mode.

Then power-cycle the Atari, press ESC at boot to reach the app selector, and launch your app. The device still has to be on the Development channel, because that is where the development UUID's slot lives. USB changes how the build gets across, not where it lands.

Either way, the template's demo should now run on the Atari. The user guide explains the selector in full.

This is the moment the whole track turns on.

From here, everything you do is a variation of: change code, run build.sh, deploy, look. Over Wi-Fi that is two commands and a few seconds. Get the loop comfortable now, because it is the rest of the work.

If it did not work

Almost every first-build failure is one of four things, and all four are environment problems rather than code problems. That is exactly why you ran the template unmodified.

What you see Almost certainly
Missing headers, or a complaint about the SDK An environment variable is unset in this shell, or the submodules were never initialised. Back to step 3 and step 5.
Something about Docker, or the Atari half not building Docker is not running, or the image did not resolve. See the stcmd fix in step 3.
Builds fine, but picotool cannot find the device The Pico W is not in a state that accepts a load. Reconnect it, holding BOOTSEL if needed.
The deploy curl is refused or times out Developer mode is off, or the host is wrong. Check the red DEVELOPMENT MODE banner, then try the device's IP address instead of sidecart.local.
Loads fine, but the app never appears on the Atari Booster is not installed. See step 4. Hold SHIFT while booting to get back to GEMDOS, then work through troubleshooting .
Give your assistant the whole failure, not a summary.

Build failures here are long and mostly noise, with one real line in the middle. Paste the lot: the command, the full output, and what you have already checked.

Prompt
Building a SidecarTridge microfirmware for the Atari ST from the official
template. The C half targets a Raspberry Pi Pico W via the Pico SDK; the
68000 half is assembled inside a Docker container.

Command:
  ./build.sh pico_w debug 44444444-4444-4444-8444-444444444444

Full output:
<paste everything>

I have already confirmed: <env vars set / submodules initialised / Docker
running, whichever are true>.

Which line is the real error, and what do I do about it?