Atari ST track
Step 9 ยท Atari ST

Test and debug.

Embedded debugging is mostly about restoring the thing you take for granted everywhere else: being able to see what your program is doing. Deploying got easy in Booster v2.3.0. Seeing inside a running microfirmware did not, and this is how you get it back.

Printf, but over a wire

The C half prints diagnostics with DPRINTF. There is no console attached to a microcontroller, so that output goes out of the serial port, and you need something at the other end of it.

That something is the Raspberry Pi Debug Probe , wired to the board's UART pins: TX, RX, ground. Once connected, open the serial port on your computer and your DPRINTF lines appear as your app runs. Its documentation covers the wiring and the UART bridge.

This is the single biggest quality-of-life change in the whole track.

Without it you are inferring behaviour from what appears on the Atari's screen. With it you have a log. If you have been putting off buying the probe, this is the step where it pays for itself.

Remember to build with debug rather than release while you are working. That is the second argument to build.sh, and it is what keeps the diagnostics in.

The probe and the Wi-Fi deploy API solve different problems, and they work together well. Deploy over Wi-Fi so you never unplug anything, and keep the probe attached the whole time for the log. See DEPLOY-API.md for the deploy side.

Stepping through code in VS Code

The templates ship a .vscode/ directory with a launch.json set up for Cortex-Debug, which drives the probe through OpenOCD. With the extension installed in step 3 and the probe connected, you get real breakpoints, stepping and variable inspection on the microcontroller.

This is where the two environment variables step 3 told you to skip finally matter. Set them now:

needed by the debugger
ARM_GDB_PATH        # your ARM toolchain, for arm-none-eabi-gdb
PICO_OPENOCD_PATH   # OpenOCD's tcl directory

If the debugger fails to launch, these are the first thing to check. The error messages are not helpful about it. Raspberry Pi's C/C++ SDK guide is where both the toolchain and OpenOCD come from, so it is the place to go if either is missing.

Debugging changes timing.

Halting at a breakpoint stops the microcontroller answering the Atari's bus reads. The Atari does not pause politely and wait, so expect the host machine to misbehave while you are stopped. This is normal, and it is why DPRINTF logging is often more useful than breakpoints for anything involving the emulation path.

Without a probe

You can still make progress, just more slowly:

  • Put state on the Atari's screen. Crude, but it is a display you already control.
  • Bisect by building. Comment out half of what you added, rebuild, reload. Slow, but it always converges.
  • The SELECT button on the board is a physical input you can read, useful as a manual trigger when you cannot type.
  • Hold SHIFT at boot to skip straight to GEMDOS. This is your way back when a build hangs the machine.

When the screen stays black

Work down this list in order. It is roughly sorted by how often each one is the answer.

Check Why
Does the unmodified template still run? Reflash the step 6 build. If that fails too, the problem is the board or Booster rather than your code, and you have just saved yourself hours.
Are you blocking in the main loop? Anything that stops chandler_loop() stops the Atari being answered. A machine that appears frozen is usually this.
Did the deploy actually happen? picotool or curl reporting success and the board running your new code are two different claims. Add a DPRINTF at startup and look for it.
Is the Atari-side code over budget? userfw.s has 6 KB. Overrunning it produces failures that look nothing like a size problem.
Is the microSD card present and readable? Code that assumes a mounted filesystem fails early and silently when it is not there.
Is Booster still installed? Flashing certain images over it will replace it. Reinstall from step 4, and check troubleshooting and the FAQ for symptoms that are not about your code.

Where emulators fit

Hatari and STEEM emulate the Atari ST. They do not emulate the SidecarTridge board, so they cannot run your microfirmware. What they are good for is Atari-side logic you can exercise independently: screen layout, keyboard handling, anything that does not depend on the board answering.

Treat them as a fast side-loop for a narrow class of problem, not as a development environment. Everything that matters still has to be tested on hardware.

Debugging is where an assistant needs the most context, not the least.

"It does not work" gets you guesses. Give it the shape of the system and the evidence:

Prompt
My SidecarTridge microfirmware <what it does wrong> on real hardware.

What I changed since it last worked:
<the diff, or a description>

DPRINTF output over the debug probe:
<paste it, including where it stops>

Already ruled out:
- the unmodified template still runs correctly
- <anything else you have checked>

Remember the main loop must never block, the Atari side has 6 KB and
cannot use Atari RAM, and commands are polled rather than interrupt
driven. Which of my changes is most likely responsible, and what should
I instrument next?

The "already ruled out" section is what stops it re-suggesting things you have done.