amiga-bootcamp/13_toolchain/sasc.md
2026-04-26 14:46:18 -04:00

4.8 KiB

← Home · Toolchain

SAS/C 6.x — Compiler Reference

Overview

SAS/C (originally Lattice C) was the dominant commercial C compiler for AmigaOS from the mid-1980s through the mid-1990s. Version 6.58 is the final release. It produces highly optimized 68k code with deep AmigaOS integration, including pragma-based system calls, SAS-specific debug formats, and a built-in profiler.

Most existing Amiga source code and documentation assumes SAS/C conventions. Understanding its idioms is essential for working with legacy codebases.


Key Features

Feature Description
Register args Automatic register parameter passing for small functions
Pragmas #pragma libcall for direct library LVO calls — no stub library needed
Small data model A4-relative addressing for global variables (faster, smaller code)
Large data model Absolute addressing for globals (no 64 KB limit)
Profiler Built-in sprof function-level profiler
Debug format SAS stabs (=APS tag in HUNK_DEBUG)
Global optimizer lc -O with peephole, dead code elimination, CSE
Code generation 68000 through 68060 + 68881/68882 FPU
Integrated linker blink — faster than generic linkers, understands Amiga hunks

Pragma Format

Pragmas tell the compiler how to call AmigaOS library functions directly via JSR through the library base, with arguments in specific registers:

/* dos_pragmas.h — generated from FD files: */
#pragma libcall DOSBase Open 1e 2102
/*                            ^^  ^^^^
                              LVO  register encoding

   LVO $1E = -30 (decimal) = offset in jump table
   Register encoding: read RIGHT to LEFT:
     2 = D2 (not used here)
     0 = D0 (return value)
     1 = D1 (first arg)
     2 = D2 (second arg)
   Last digit = number of arguments */

#pragma libcall DOSBase Close 24 101
/* LVO -$24 (-36), 1 arg in D1, returns in D0 */

#pragma libcall DOSBase Read 2a 32103
/* LVO -$2A (-42), 3 args: D1=fh, D2=buffer, D3=length */

Register Encoding

Digit Register Digit Register
0 D0 8 (unused)
1 D1 9 A0
2 D2 A A1
3 D3 B A2
4 D4 C A3
5 D5 D A4
6 D6 E A5
7 D7 F (unused)

The rightmost digit is always the result register, next digit is number of args, then args are listed left-to-right.


Compilation Workflow

Source (.c) → lc (compile) → Object (.o) → blink (link) → Executable
# Compile a single file:
lc -v -O -b0 main.c

# Link:
blink main.o util.o TO myapp LIB lib:sc.lib lib:amiga.lib

# Compile + link in one step:
lc -v -O -b0 -j73 main.c util.c LINK TO myapp

Compiler Flags

Flag Meaning
-v Verbose output
-O Enable global optimizer
-b0 Small data model (A4-relative, max 64 KB globals)
-b1 Large data model (absolute addressing)
-j30 Generate 68030 code
-j40 Generate 68040 code
-j73 Generate 68020 + 68881 FPU code
-d0 No debug info
-d2 Full debug info (SAS stabs)
-r Generate resident/reentrant code
-L Disable auto-open of amiga.lib
-w Suppress warnings
-E Preprocess only
Flag Meaning
TO name Output file name
LIB libs Link libraries
DEBUG Include debug hunks
STRIPDEBUG Remove debug hunks
SMALLCODE PC-relative addressing
SMALLDATA A4-relative data
MAP file Generate link map
NODEBUG Omit all debug info

SAS/C-Specific Idioms

/* Register parameters: */
ULONG __asm MyFunc(register __d0 ULONG arg1,
                   register __a0 APTR arg2);

/* Interrupt-safe function: */
void __interrupt __saveds MyInterrupt(void);

/* Resident code: */
LONG __saveds __asm LibOpen(register __a6 struct Library *base);

/* __saveds: saves/restores A4 (small data base) on entry/exit */
/* __interrupt: preserves all registers */
/* __asm: use register calling convention */

Differences from GCC

Feature SAS/C GCC (m68k-amigaos)
Register args register __d0 ULONG x ULONG x __asm("d0")
Small data base A4 (automatic with -b0) -fbaserel (A4)
Library pragmas #pragma libcall Inline asm stubs in <inline/lib.h>
Startup cres.o (resident) / c.o (standard) libnix or ixemul
String constants Pooled by default -fmerge-constants

References

  • SAS/C 6.x User Manual and Reference Manual
  • NDK39 pragma files: NDK_3.9/Include/pragmas/
  • See also: pragmas.md — pragma/inline mechanism in depth
  • See also: gcc_amiga.md — GCC cross-compiler (modern alternative)