Autonomous troubleshooting workflow for Amiberry bugs. Use this when investigating, reproducing, or fixing bugs in Amiberry, especially renderer or input regressions, HiDPI or SDL3 logical-presentation bugs, Vulkan capability or swapchain failures, or general crash and behavior regressions. Provides a complete edit-build-run-test-fix cycle using the Amiberry MCP server tools for process management, IPC control, screenshot analysis, log monitoring, and crash detection.
Debug and fix Amiberry bugs through iterative edit-build-run-test-fix cycles with minimal user interaction.
$ARGUMENTS
Amiberry source is at the current working directory (or a nearby amiberry/ directory).
The MCP server (amiberry-mcp-server) provides tools for runtime control.
Determine the platform before building:
cmakecmake (use wsl -e prefix if on Windows host)# Configure (first time or after CMake changes)
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DUSE_IPC_SOCKET=ON
# Build (subsequent changes)
cmake --build build -j$(nproc)
wsl -e bash -c "cd ~/amiberry && cmake --build build -j$(nproc)"
# Use the helper script (sets PATH for CLion's cmake/ninja/mingw, VCPKG_ROOT)
powershell -ExecutionPolicy Bypass -File "build_and_run.ps1"
# Or manually:
$env:VCPKG_ROOT = "D:\Github\vcpkg"
cmake --preset windows-debug
cd out/build/windows-debug
ninja -j12
# Run with logging enabled
.\amiberry.exe --log
Windows build notes:
out/build/windows-debug (or windows-release)amiberry.exe before rebuild if "permission denied"write_log() is silent unless --log flag or write_logfile config is set$env: variables get stripped in bash inline commands; use .ps1 files with -FileGrep to find related functions, variables, error messagesGlob to find relevant source filesLaunch Amiberry with appropriate config:
launch_and_wait_for_ipc to start Amiberry and wait for IPC readinessA500, A1200, etc.) or config file as neededVerify it's running:
health_check to confirm process + IPC + emulation statusSet up the reproduction scenario:
runtime_load_config to load specific configurationsruntime_insert_floppy to insert disk imagessend_key to navigate menus or trigger actionsruntime_set_config to change specific optionsObserve the behavior:
runtime_screenshot_view to see what's on screentail_log to monitor log outputruntime_get_fps to check performanceruntime_get_cpu_regs / runtime_get_custom_regs for hardware stateIf it crashes:
get_crash_info to detect the crash and analyze signals + log patternsget_process_info for exit code and signal detailsBefore editing, decide whether the bug is in a shared subsystem or only one renderer/input path.
SDL_RenderCoordinatesFromWindow() or SDL_ConvertEventToRenderCoordinates(). Do not pre-scale and then ask SDL to scale again.SDL_EVENT_MOUSE_MOTION is fixed, stylus/tablet input often remains offset.SDL_Renderer, logical presentation, viewport, pen/mouse conversionkill_amiberrycmake --build build -j$(nproc)
Restart with same config: Use restart_amiberry or launch_and_wait_for_ipc
Run the same reproduction steps from Phase 2
Check results:
runtime_screenshot_view - does the screen look correct?tail_log - are there still errors/warnings?get_crash_info - did it crash again?health_check - is everything still running?If NOT fixed: Go back to Phase 3 with new hypothesis
If fixed: Clean up and report findings
supportedCompositeAlphaTRANSFER_DST_BITSummarize:
| Tool | Purpose |
|---|---|
check_process_alive | Is Amiberry running? Returns PID + exit code |
get_process_info | Detailed info: PID, status, signal, crash detection |
kill_amiberry | Force kill (SIGTERM then SIGKILL) |
wait_for_exit | Block until process exits (with timeout) |
restart_amiberry | Kill + relaunch with same command |
| Tool | Purpose |
|---|---|
launch_and_wait_for_ipc | Launch with logging, wait for IPC ready |
health_check | Combined: process + IPC ping + status + FPS |
| Tool | Purpose |
|---|---|
runtime_screenshot_view | Screenshot returned as image data |
tail_log | New log lines since last read |
wait_for_log_pattern | Wait for regex in log (with timeout) |
get_crash_info | Process signals + log crash pattern scanning |
| Tool | Purpose |
|---|---|
pause_emulation / resume_emulation | Pause/resume |
reset_emulation | Soft or hard reset |
frame_advance | Step N frames when paused |
runtime_set_config / runtime_get_config | Change/query config at runtime |
runtime_load_config | Load a .uae config file |
| Tool | Purpose |
|---|---|
runtime_get_cpu_regs | All CPU registers (D0-D7, A0-A7, PC, SR) |
runtime_get_custom_regs | Custom chip registers (DMACON, INTENA, etc.) |
runtime_read_memory | Read Amiga memory (1/2/4 bytes) |
runtime_write_memory | Write Amiga memory |
runtime_disassemble | Disassemble at address |
runtime_set_breakpoint / runtime_clear_breakpoint | Breakpoints |
runtime_debug_activate / runtime_debug_step | Debugger control |
runtime_debug_step_over | Step over JSR/BSR |
runtime_get_copper_state / runtime_get_blitter_state | Hardware state |
| Tool | Purpose |
|---|---|
runtime_insert_floppy / runtime_eject_floppy | Floppy management |
runtime_insert_cd / runtime_eject_cd | CD management |
send_key | Send keyboard input (Amiga keycodes) |
runtime_set_display_mode | Window/fullscreen/fullwindow |
runtime_set_ntsc | PAL/NTSC switching |
| Key | Code | Key | Code |
|---|---|---|---|
| Return | 0x44 | Space | 0x40 |
| Escape | 0x45 | Backspace | 0x41 |
| Up | 0x4C | Down | 0x4D |
| Left | 0x4F | Right | 0x4E |
| F1-F10 | 0x50-0x59 | Help | 0x5F |
| Left Amiga | 0x66 | Right Amiga | 0x67 |
| A-Z | 0x20,0x35,0x33,0x22,0x12,0x23,0x24,0x25,0x17,0x26,0x27,0x28,0x37,0x36,0x18,0x19,0x10,0x13,0x21,0x14,0x16,0x34,0x11,0x32,0x15,0x31 |
To send a keypress, call send_key twice: once with state=1 (press), then state=0 (release).
| Directory | Contents |
|---|---|
src/ | Core emulation (UAE-derived) |
src/osdep/ | Platform abstraction (Linux/macOS/Android/Windows) |
src/osdep/imgui/ | GUI panels (Dear ImGui) |
src/include/ | Headers and interfaces |
src/osdep/amiberry_ipc_socket.cpp | IPC socket implementation |
src/osdep/amiberry_gfx.cpp | Graphics/display |
src/osdep/amiberry_input.cpp | Input handling |
src/osdep/amiberry.cpp | Core platform layer |
src/osdep/macos_bookmarks.h/.mm | macOS security-scoped bookmarks (App Store) |
~/Library/Application Support/Amiberry (contains a space).download_file() properly quotes paths in curl/wget commands via popen().create_missing_amiberry_folders() uses std::filesystem::copy() instead of system("cp -R ...").build/Amiberry.app stores resources (controllers, data, roms, whdboot) under Resources/.--log (handled automatically by launch_and_wait_for_ipc) for log outputtail_log frequently to catch errors earlypause_emulation + runtime_screenshot_view gives a stable frameruntime_set_config to change CPU speed or floppy speedget_crash_info tells you a lot: SIGSEGV = null pointer/bad memory, SIGABRT = assertion/abort, SIGBUS = alignment-DCMAKE_BUILD_TYPE=Debug) for better crash infokill_amiberry + launch_and_wait_for_ipc between eachOn-screen D-pad acts like a mouse instead of joystick: Two possible causes:
SDL_MOUSEBUTTONDOWN/SDL_MOUSEMOTION from touch events by default. Fix: filter event.button.which == SDL_TOUCH_MOUSEID / event.motion.which == SDL_TOUCH_MOUSEID in mouse event handlers when on-screen joystick is active (done in amiberry.cpp).on_screen_joystick_set_enabled(true), but check changed_prefs.jports[1].id to verify.On-screen joystick not appearing in Input dropdown: The virtual device is only registered when currprefs.onscreen_joystick is enabled. Check this preference first. Then verify registration in init_joystick() (input_platform_internal_host.h): num_joystick < MAX_INPUT_DEVICES and osj_device_index is set. The device appears as "On-Screen Joystick" in the joystick device list.
Input injection debugging: Use --log flag. The on-screen joystick logs "On-Screen Joystick registered as JOY%d" at startup. Use setjoystickstate()/setjoybuttonstate() (proper device API); avoid send_input_event() which bypasses port mode configuration.
Port mode mismatch: If port 1 mode is not JSEM_MODE_JOYSTICK, D-pad input may behave as mouse. The auto-assignment sets changed_prefs.jports[1].mode = JSEM_MODE_JOYSTICK and calls inputdevice_config_change().
jit_abort() → uae_reset() permanently setting quit_program, which blocks pixel drawing in waitqueue(). Fixed in src/jit/x86/compemu_x86.h.-DDEBUG) enable assert() in tinyxml2. This can cause crashes with debugger attached but not in normal execution. Not a real bug.std::filesystem::copy() directly. File symlinks have try-catch fallback.close() → closesocket(), ioctl() → ioctlsocket(), errno → WSAGetLastError(). Check src/slirp/ for patterns.write_log() returns early if neither --log nor write_logfile is enabled. Always pass --log when debugging.data/ directory (fonts, icons) is missing from the runtime working directory, ImGui's AddFontFromFileTTF asserts and crashes in debug builds (exit code 3). Fix: main_window.cpp checks std::filesystem::exists(font_path) before loading. Deployment fix: copy data/ from source tree to working directory.msvcrt.dll which doesn't support "ccs=UTF-8" fopen mode (errno=22). Fixed with plain "w"/"rt"/"wt" modes under #ifdef AMIBERRY in cfgfile.cpp and ini.cpp.hd.cpp was missing hardfile_testrdb() call after HDF file selection, causing geometry to stay at 32,1,2 instead of auto-detecting RDB (0,0,0). Fixed in commit c2b5c053.