SAS/C System Library Reference

The "SAS/C Development System: System Library Reference" is a ~700-page reference to the system libraries available to SAS/C 6.58 programs. Ch.1–6 cover concepts and overview; Ch.7 (~500 pp) is the C library reference; Ch.8 is the C++ library reference. Source: SAS/C System Library Reference, Version 6.50 (1993).

This article summarizes Ch.1–6 — the conceptual material that the average AmigaOS programmer needs to know. The function-by-function reference is in Part VII.

What libraries are available

AmigaOS provides a layered set of libraries:

+----------------------------------+
|  Application code                  |
+----------------------------------+
|  dos.library  intuition.library    |   ← user-facing OS layer
|  graphics.library  layers.library |   ← display layer
+----------------------------------+
|  exec.library  utility.library     |   ← low-level support
|  expansion.library  icon.library   |
+----------------------------------+
|  ROM Kernel (exec is the basis)   |
+----------------------------------+

Each library is opened with OpenLibrary() and closed with CloseLibrary(). Calls go through the library's jump table, which sits at a known offset from the library base.

Commodore (built-in) libraries

Ch.2 documents the system libraries that ship with AmigaOS 3.x:

Library Header Purpose
exec.library <exec/exec.h> Tasks, memory, lists, ports, interrupts
dos.library <dos/dos.h> Files, directories, processes, commands
intuition.library <intuition/intuition.h> Windows, screens, events, gadgets, menus
graphics.library <graphics/graphics.h> RastPort, BitMap, blitter, drawing primitives
layers.library <layers/layers.h> Layered rendering, clipping
utility.library <utility/utility.h> TagItems, Hooks, date/time math, names
commodities.library <commodities/commodities.h> Input event brokers (HotKey, Exchange, etc.)
asl.library <asl/asl.h> Standard requesters (file, font, screen mode)
datatypes.library <datatypes/datatypes.h> Multi-format data objects
iffparse.library <iffparse/iffparse.h> IFF file parsing
diskfont.library <diskfont/diskfont.h> Disk-based font loading
keymap.library <keymap/keymap.h> Keyboard mapping
rexxsyslib.library <rexx/rexxio.h> ARexx system services
icon.library <icon/icon.h> Workbench icon I/O
expansion.library <expansion/expansion.h> Expansion board management
wb.library <workbench/workbench.h> Workbench apps
locale.library <locale/locale.h> Internationalization
mathieeedoubbas.library <mathieeedoubbas.h> IEEE double-precision math
mathtrans.library <mathtrans.h> IEEE transcendentals (sin, cos, exp, log)
mathffp.library <mathffp.h> FFP (Fast Floating Point) math
mathieeesingbas.library <mathieeesingtrans.h> IEEE single-precision
audio.device <audio/audio.h> Audio output (technically a device)
battclock.resource <resources/battclock.h> Battery-backed clock
carddisk.resource <resources/carddisk.h> PCMCIA card services
cia.resource <resources/cia.h> CIA chip timers and I/O
clipboard.device <devices/clipboard.h> Shared clipboard
console.device <devices/console.h> Console handler
gameport.device <devices/gameport.h> Joystick/mouse input
input.device <devices/input.h> Keyboard/mouse raw events
keyboard.device <devices/keyboard.h> Keyboard translation
parallel.device <devices/parallel.h> Parallel port
potgo.resource <resources/potgo.h> Potentiometer (audio channels as analog in)
printer.device <devices/printer.h> Printer driver
serial.device <devices/serial.h> Serial port
timer.device <devices/timer.h> Microsecond timer
trackdisk.device <devices/trackdisk.h> Floppy/IDE storage
ramdrive.device <devices/ramdrive.h> RAM disk
scsidisk.device <devices/scsidisk.h> SCSI storage

SAS/C specific libraries

Ch.3 documents the libraries that ship with the SAS/C compiler itself:

Library Header Purpose
sc.lib (linker-level) C runtime (printf, malloc, etc.)
amiga.lib (linker-level) NDK stub functions for low-level ops
Amiga.lib (linker-level) Aztec compatibility stubs
debug.lib (linker-level) CodeProbe runtime support

These are not opened at runtime via OpenLibrary(). They are static link libraries that resolve to code that gets included in the executable. The runtime support is part of c.o (the startup module) — see SAS/C Startup Modules.

Header file structure

Ch.4 documents the NDK header layout. The convention:

NDK_3.2/Include/
├── include_h/         # public headers
│   ├── exec/
│   │   ├── exec.h
│   │   ├── execbase.h
│   │   ├── ports.h
│   │   └── ...
│   ├── dos/
│   ├── intuition/
│   ├── graphics/
│   ├── ...
│   └── utility/
├── inline/            # compiler-inline functions (SAS/C)
│   ├── exec.h
│   ├── dos.h
│   ├── ...
├── proto/              # pragma libcall declarations
│   ├── exec.h
│   ├── dos.h
│   ├── ...
├── pragmas/            # prama-only files
│   ├── exec_pragmas.h
│   ├── dos_pragmas.h
│   └── ...
├── clib/               # C function prototypes
│   ├── dos_protos.h
│   ├── exec_protos.h
│   └── ...
└── ...

Your program typically includes just <proto/exec.h>, <proto/dos.h>, etc. — these pull in everything needed.

Header conventions

  • xxx_base.h — defines the library base (e.g., extern struct ExecBase *SysBase;)
  • xxx.h — function declarations and macros for using the library
  • proto/xxx.h — full set of #pragma libcall declarations (called from <xxx.h>)
  • inline/xxx.h — inline implementations where possible
  • clib/xxx_protos.h — C-style prototypes, used when <proto/xxx.h> is unavailable

#include <proto/dos.h> pulls in all of these automatically.

Calling library functions

The standard pattern:

#include <proto/dos.h>
#include <proto/exec.h>

void do_something(void)
{
    /* dos.library is already opened by c.o (if you used `sc link`) */
    BPTR lock = Lock("SYS:Prefs", ACCESS_READ);
    if (lock) {
        /* do work */
        UnLock(lock);
    } else {
        LONG err = IoErr();
        /* handle err */
    }
}

The compiler emits the right jump-table call for each function. The mechanism is detailed in SAS/C Compilation and Linking.

Manually opening a library

If you wrote your own startup and didn't include c.o, you must open libraries yourself:

struct DosLibrary *DOSBase;

int my_main(void)
{
    DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37);
    if (!DOSBase) {
        return RETURN_FAIL;
    }

    /* Now you can call dos.library functions */
    BPTR lock = Lock("SYS:", ACCESS_READ);

    /* ... */
    UnLock(lock);
    CloseLibrary((struct Library *)DOSBase);
    return RETURN_OK;
}

The base pointer (DOSBase) is set up by OpenLibrary() and used implicitly by every #pragma libcall declaration.

Advanced library techniques

Ch.5 covers:

Library base patching

The library base is normally fixed for the process. But:

  • For shared libraries you ship: each consumer process gets its own base. The library code is shared; the base is per-process.
  • For system libraries: the base is allocated by exec.library when the library is loaded and never moves.

Sub-libraries

Some libraries open other libraries internally. For example, dos.library opens exec.library. Application code typically doesn't need to manage this — it just calls OpenLibrary() directly.

Library versioning

When opening a library, you specify a minimum version:

DOSBase = OpenLibrary("dos.library", 37);  /* require V37 or newer */

OpenLibrary() fails if the library is older. The OSERR_NORTGBITMAP errors and other 3.2-specific functions need V47 or newer.

Resident tag lists

exec.library maintains a list of resident modules. The first NDK header to read when you suspect a library isn't loaded is <exec/resident.h>.

Predefined data

Ch.6 lists the data that is automatically initialized by the SAS/C startup:

Name Type Set by
SysBase struct ExecBase * exec.library (always)
DOSBase struct DosLibrary * dos.library (by c.o)
IntuitionBase struct IntuitionBase * intuition.library (auto by proto)
GfxBase struct GfxBase * graphics.library (auto)
LayersBase struct LayersBase * layers.library (auto)
UtilityBase struct UtilityBase * utility.library (auto)
argc, argv int, char ** Startup (Shell)
WBench struct WBench * (opaque) Startup (Workbench)
_ProgramName char * Startup (the file name)
_stack long Stack size in bytes

You can also declare your own auto-opened library base:

#include <proto/my_lib.h>
struct MyLibBase *MyLibBase;   /* auto-opened by proto/my_lib.h */

The proto/my_lib.h macro machinery generates the OpenLibrary() call before main() and the CloseLibrary() call after.

Custom predefined data

For data that needs initialization outside the C constructor order, use __autoinit:

__autoinit void init_my_thing(void)
{
    /* runs before main() */
}

And to extend the default library set, add your own to the startup:

/* In a file linked with the program */
__autoinit void open_my_libs(void)
{
    MyLibBase = (APTR)OpenLibrary("my.library", 0);
    if (!MyLibBase) {
        /* library not available — fail */
        exit(RETURN_FAIL);
    }
}

__autoexit void close_my_libs(void)
{
    if (MyLibBase) {
        CloseLibrary(MyLibBase);
    }
}

Practical library usage patterns

Lazy opening

For optional features, open the library at use time and close it when done:

void do_optional_thing(void)
{
    struct Library *base = OpenLibrary("optional.library", 0);
    if (base) {
        /* call functions via base */
        CloseLibrary(base);
    }
    /* silently skip if not available */
}

Caching the base

For libraries you use many times, cache the base globally:

static struct Library *cached_base = NULL;

struct Library *get_mylib_base(void)
{
    if (!cached_base) {
        cached_base = OpenLibrary("mylib.library", 0);
    }
    return cached_base;
}

The base never moves for a given process, so caching is safe.

See Also


Sources: SAS Institute Inc., "SAS/C Development System — System Library Reference" Ch.1–6, Version 6.50 (1993). Raw: raw/sasc/sasc-syslib-extract.md Updated: 2026-10-02