Imported from mirq/ami-wordle-mui (
AGENTS.md). Install upstream withnpx skills add mirq/ami-wordle-mui. Copyright stays with the author.
Agent Development Guidelines for llm-amiwordle-mui
This document provides essential information for AI coding agents working on this Amiga MUI application codebase.
Project Overview
Project Type: Classic Amiga OS application using MUI (Magic User Interface) Language: C (cross-compiled for Motorola 68000) Target Platform: Amiga OS 3.1 and 3.2 Compiler: m68k-amiga-elf-gcc with aggressive optimization (-Ofast, -flto, -fwhole-program) Build System: GNU Make
This is a template/example project demonstrating MUI GUI programming on classic Amiga using modern development tools (VSCode + cross-compiler).
Build Commands
Primary Build Commands
# Build the project (default target)
make -j4
# Clean build artifacts
make clean
# Build output locations
# - obj/*.o - Object files
# - obj/*.d - Dependency files
# - out/a.elf - ELF executable
# - out/a.exe - Amiga Hunk format executable (final)
# - out/a.s - Disassembly listing
# - out/a.map - Linker map
VSCode Integration
# From VSCode command palette (Ctrl+P):
task compile # Runs make -j4
task clean # Runs make clean
# Debug/Run:
F5 # Compile and launch in WinUAE/FS-UAE emulator
Testing
No formal test framework: This is an example project without automated tests.
Testing approach: Manual testing via VSCode debugger with WinUAE/FS-UAE emulator.
Debug configurations (in .vscode/launch.json):
- Amiga 500 (OS 3.1)
- Amiga 1200 (OS 3.2)
- Amiga 4000
To test changes: Press F5 to compile and launch in the emulator.
Code Style Guidelines
File Organization
Root directory structure:
├── main.c # Main entry point with MUI example
├── misc.c # Variadic wrapper functions (REQUIRED)
├── *.c # Demo programs (Bevels, Buttons, CheckBox, Requester)
├── l_option.h # Build-time configuration flags
├── Makefile # Build configuration
├── libs/ # Static libraries (clib2)
└── .vscode/ # IDE configuration
Imports and Headers
CRITICAL: All includes of intuition.h and muimaster.h MUST be wrapped:
#define NO_INLINE_STDARG
#include <proto/intuition.h>
#undef NO_INLINE_STDARG
Include order (follow this pattern):
#include "l_option.h" // Project config (always first)
#include <proto/exec.h> // Exec library
#define NO_INLINE_STDARG
#include <proto/intuition.h> // Intuition library
#undef NO_INLINE_STDARG
#include <proto/window.h> // Other proto includes
#define NO_INLINE_STDARG
#include <proto/muimaster.h> // MUI library
#undef NO_INLINE_STDARG
#include <proto/utility.h> // Other libraries
#include <clib/alib_protos.h> // C library prototypes
#if OPTION_USE_CLIB2
#include <stdlib_headers.h> // clib2 headers (conditional)
#endif
Use proto includes, NOT pragma includes:
// CORRECT:
#include <proto/label.h>
#include <proto/layout.h>
// WRONG:
#include <pragmas/label_pragmas.h>
#include <pragmas/layout_pragmas.h>
Naming Conventions
- Functions:
camelCase(MUI style) orlowercase_underscore(C standard) - Demo entry points:
main_*prefix (e.g.,main_bevels,main_buttons) - Library bases: Suffix with
Base(e.g.,IntuitionBase,DOSBase,MUIMasterBase) - Constants/Macros:
UPPERCASE_UNDERSCORE(e.g.,TAG_DONE,MUI_LIB_VERSION) - Local variables:
camelCaseorlowercase - Struct members: Follow Amiga SDK conventions (
ti_Tag,ti_Data)
Formatting
- Indentation: Tabs (equivalent to 4 spaces)
- Brace style: K&R style (opening brace on same line for functions)
- Line length: No strict limit, but keep reasonable (~100-120 chars)
- Comments: Both C-style
/* */and C++-style//are acceptable
Types and Type Safety
Use Amiga-specific types:
ULONG, LONG, UWORD, WORD, UBYTE, BYTE // Sized integers
APTR, STRPTR // Pointers
BOOL, TRUE, FALSE // Boolean values
Tag, struct TagItem // Tag lists
Library base declarations:
// CRITICAL: All library bases must be externally_visible for -fwhole-program
__attribute__((externally_visible)) struct ExecBase *SysBase;
__attribute__((externally_visible)) struct IntuitionBase *IntuitionBase = NULL;
__attribute__((externally_visible)) struct Library *MUIMasterBase = NULL;
Conditional types (OS 3.1 vs 3.2):
#if OPTION_AMIGA_OS32
__attribute__((externally_visible)) struct Library *UtilityBase = NULL;
#else
__attribute__((externally_visible)) struct UtilityBase *UtilityBase = NULL;
#endif
Error Handling
Library opening pattern:
if ((MUIMasterBase = OpenLibrary("muimaster.library", MUI_LIB_VERSION))) {
// Use library
CloseLibrary(MUIMasterBase);
} else {
// Handle error (print message, exit gracefully)
}
Memory allocation checking:
if ((tagItem = (struct TagItem *)AllocVec(cnt * sizeof(struct TagItem), MEMF_ANY))) {
// Use memory
FreeVec(tagItem);
}
Always clean up resources: Amiga OS has no garbage collection. Close libraries, free memory, dispose objects.
Conditional Compilation
Use l_option.h for build-time configuration:
// In l_option.h:
#define OPTION_USE_CLIB2 0 // 0 = disabled, 1 = enabled
#define OPTION_AMIGA_OS32 0 // 0 = OS 3.1, 1 = OS 3.2
// In source files:
#if OPTION_AMIGA_OS32
// OS 3.2 specific code (ReAction gadgets)
#endif
#if OPTION_USE_CLIB2
// clib2 library initialization
#endif
Variadic Functions (CRITICAL)
NEVER use inline variadic functions from headers. Always use wrappers from misc.c:
// CORRECT (use misc.c functions):
Object *obj = NewObject(...);
SetAttrs(obj, ...);
Object *mui_obj = MUI_NewObject(MUIC_Window, ...);
// WRONG (will cause optimization issues):
// Using inline functions from proto/intuition.h directly
Available misc.c functions:
NewObject,SetAttrs,GetAttrOpenWindowTags,OpenScreenTagsMUI_NewObject,MUI_MakeObject,MUI_RequestDoMethod,DoSuperMethod,DoSuperMethodA
clib2 Library Usage
When OPTION_USE_CLIB2 is enabled:
-
Main program structure must follow main.c skeleton:
- Custom
_start()function - Manual constructor/destructor calls
setjmp/longjmpbased exit handling
- Custom
-
Static library linking (in Makefile):
# For Amiga-style paths (RAM:, DH0:)
static_libs := -lc -lm -ldebug -lnet -lunix -lc -lm -lamiga
# For UNIX-style paths (/RAM/, /DH0/)
static_libs := -lm -ldebug -lnet -lunix -lc -lm -lamiga
-
Requirements:
- Stack size: 16384 bytes minimum (for libunix)
- SetPatch must be run in startup-sequence
- bsdsocket.library required (for libnet)
- PIPE: device required for pipe functions (OS 3.1)
-
DO NOT mix libnet functions with native bsdsocket.library inline functions
Common Pitfalls
- Forgetting NO_INLINE_STDARG wrapper → Compilation errors
- Using inline variadic functions instead of misc.c → Runtime crashes
- Missing externally_visible attribute → Linker errors with -fwhole-program
- Not closing libraries/freeing memory → Resource leaks
- Using wrong SDKDIR in Makefile → Include errors (sys-include vs ndk-include)
- Forgetting to clean before switching OS versions → Strange build errors
Making Changes
- When adding new source files: Update Makefile if needed (auto-detected via wildcards)
- When switching OS versions:
- Update l_option.h flags
- Update Makefile SDKDIR path
- Run
make cleanbefore rebuilding
- When opening new libraries: Add library base declarations with
externally_visible - When adding variadic function calls: Check if wrapper exists in misc.c, add if needed
Reference Documentation
- README.txt: Comprehensive setup and usage guide
- MUI Developer Wiki: https://github.com/amiga-mui/muidev/wiki
- clib2: https://github.com/jyoberle/clib2
- vscode-amiga-debug: https://github.com/jyoberle/vscode-amiga-debug
- YouTube tutorials: Linked in README.txt
Notes for Agents
- This is a template project, not production code
- Focus on correctness over performance (compiler handles optimization)
- Always test in emulator after making changes (press F5)
- Respect Amiga SDK conventions and naming patterns
- The code demonstrates modern C cross-compilation for retro hardware