Getting Started with Amiga C Programming

A beginner's orientation to Amiga C development, distilled from Amiga C for Beginners (Data Becker/Abacus, 1990). This article covers the fundamentals that the other wiki articles assume you already know.

The three Amiga C compilers

Compiler Notes
SAS/C (formerly Lattice C) The professional standard. Used by the NDK. See SAS/C Compiler Reference.
Manx Aztec C Older alternative, popular in the 1.x era.
DICE C Public domain option.

For all new code, use SAS/C — it's what every example and the NDK itself targets.

Compilation workflow (beginner view)

source.c → [editor: ED or your preferred editor]
         → sc source.c              (compile to object .o)
         → slink c.o source.o lib:sc.lib lib:amiga.lib  (link)
         → executable

Or one-step:
         → sc link source.c          (compile + link)

The absolute minimum Amiga program

#include <exec/types.h>
#include <clib/exec_protos.h>
#include <stdio.h>

extern struct ExecBase *SysBase;

int main(void)
{
    struct Library *DOSBase;
    DOSBase = OpenLibrary("dos.library", 37);
    if (!DOSBase) return 20;

    printf("Hello, Amiga!\n");

    CloseLibrary(DOSBase);
    return 0;
}

Three rules for every program: 1. Open every library with a version number check. 2. Always check if OpenLibrary() returned NULL. 3. Close every library you opened, in reverse order.

First Intuition window

struct Window *win = OpenWindowTags(NULL,
    WA_Left, 50, WA_Top, 50,
    WA_Width, 300, WA_Height, 100,
    WA_Title, (ULONG)"My First Window",
    WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET,
    WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY,
    TAG_DONE);

if (win) {
    struct IntuiMessage *msg;
    BOOL done = FALSE;
    while (!done) {
        WaitPort(win->UserPort);
        while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) {
            if (msg->Class == IDCMP_CLOSEWINDOW) done = TRUE;
            if (msg->Class == IDCMP_VANILLAKEY && msg->Code == 27) done = TRUE;
            ReplyMsg((struct Message *)msg);
        }
    }
    CloseWindow(win);
}

See Intuition Windows, Screens, and the Event Loop for the full IDCMP event reference.

First graphics

struct RastPort *rp = win->RPort;

/* Draw text */
SetAPen(rp, 1);                /* foreground pen */
Move(rp, 20, 30);              /* text position */
Text(rp, "Hello!", 6);         /* draw text */

/* Draw a filled rectangle */
SetAPen(rp, 2);
RectFill(rp, 10, 10, 100, 50);

/* Draw a line */
SetAPen(rp, 1);
Move(rp, 10, 10);
Draw(rp, 100, 50);

Memory — the most common beginner mistake

The single most important concept: chip memory vs fast memory.

/* WRONG — may allocate fast memory, hardware can't see it */
UBYTE *screen = AllocMem(320 * 200, NULL);

/* RIGHT — MEMF_CHIP for anything hardware touches */
UBYTE *screen = AllocMem(320 * 200, MEMF_CHIP | MEMF_CLEAR);

/* Always free with the same size */
FreeMem(screen, 320 * 200);

When you MUST use MEMF_CHIP: - Screen bitmaps, display memory - Sprite data - Audio samples - Copper lists - Anything accessed by custom-chip DMA

When MEMF_FAST (or no flag) is fine: - Program code - Application data structures - Text strings - File buffers

The 7 rules for Amiga programming

  1. Always check return valuesOpenLibrary(), AllocMem(), OpenWindow(), everything can fail.
  2. Always close/free what you open/allocate — in reverse order.
  3. Use MEMF_CHIP for hardware-accessible memory.
  4. Never call dos.library from interrupt handlers or tasks — use processes.
  5. Always ReplyMsg() every message you GetMsg().
  6. Never Forbid() or Disable() for synchronization — use semaphores.
  7. Always use the OS API — never bang hardware registers directly.

For the full philosophy behind these rules, see AmigaOS Programming Philosophy.

See Also


Sources: Schaun Wu, "Amiga C for Beginners" (Data Becker/Abacus, 1990). Raw: raw/amiga-c-beginners/beginners-c-extract.md; raw/tutorials/amiga-c-beginners-full.md Updated: 2026-08-09 Updated: 2026-08-04