Expand documentation suite: 30+ articles enriched with diagrams, code examples, and hardware details

Graphics: text_fonts (bitmap layout, styles), sprites (DMA, multiplexing), gfx_base (chipset detection), rastport (draw modes, clipping), ham_ehb (mermaid fixes), display_modes (HAM palettes)

Devices: scsi (per-model interfaces, Gayle limits, CD-ROM, native vs vendor drivers), console (ANSI sequences, CON:/RAW:), parallel (CIA registers, pinout), timer (resource exhaustion), gameport (quadrature, XOR state)

Libraries: workbench (WBStartup, AppWindow/Icon/MenuItem), rexxsyslib (ARexx port hosting, command parsing), diskfont (font directory, colour fonts), keymap (rawkey codes, dead keys), locale (catalogue system, date formatting), layers (ClipRect, refresh types), utility (TagItem chains), icon (DiskObject, ToolTypes), iffparse (IFF structure, ByteRun1), expansion (Zorro AutoConfig)

Networking: tcp_ip_stacks (major rewrite - Amiga vs Unix architecture, SANA-II pipeline, PPP/SLIP dial-up, Ethernet cards, MiSTer), bsdsocket (pure API ref), sana2 (buffer hooks, driver requirements), protocols (all code examples). Deduplicated overlap between the three files.

Toolchain: debugging (Enforcer patterns, SnoopDOS, GDB remote, kprintf checklist), sasc (pragma encoding, __saveds idioms), stormc (NEW - StormC IDE, C++, PowerPC)

References: error_codes (DOS, Exec, trackdisk, Intuition error tables)
Driver development: rtg_driver (Native driver analysis, P96 tuning)

All 22 README indexes updated. Root README synced with stormc.md entry.
This commit is contained in:
Ilia Sharin 2026-04-23 21:37:26 -04:00
parent 0ded078134
commit f61c26b542
38 changed files with 6402 additions and 1065 deletions

View file

@ -4,7 +4,9 @@
## Overview
SAS/C (originally Lattice C) was the dominant commercial C compiler for AmigaOS. Version 6.58 is the final release. It produces optimised 68k code with full AmigaOS integration, including pragma-based system calls and SAS-specific debug formats.
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 optimised 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.
---
@ -12,52 +14,143 @@ SAS/C (originally Lattice C) was the dominant commercial C compiler for AmigaOS.
| Feature | Description |
|---|---|
| Register args | Automatic register parameter passing |
| Pragmas | `#pragma libcall` for direct library LVO calls |
| Small data | A4-relative addressing for globals |
| Profiling | Built-in `sprof` profiler |
| Debug format | SAS stabs (`=APS` tag in HUNK_DEBUG) |
| Optimizer | Global optimizer (`lc -O`) with peephole |
| **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:
```c
/* dos_pragmas.h — generated from FD files: */
#pragma libcall DOSBase Open 1e 2102
/* ^^ ^^ ^^^^
name LVO reg-encoding
reg-encoding: 2=D2, 1=D1, 0=result in D0, 2 args */
/* ^^ ^^^^
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: digits map to registers (1=D0, 2=D1, ... 9=A0, A=A1, etc.)
### 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
## Compilation Workflow
```
lc -v -O -b0 -j73 hello.c ; compile
blink hello.o TO hello LIB lib:sc.lib lib:amiga.lib ; link
Source (.c) → lc (compile) → Object (.o) → blink (link) → Executable
```
```bash
# 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 |
| `-O` | Optimise |
| `-b0` | Small data model (A4-relative) |
| `-b1` | Large data model |
| `-j73` | Generate 68020/68881 code |
| `-v` | Verbose output |
| `-O` | Enable global optimiser |
| `-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 |
| `-d2` | Full debug info (SAS stabs) |
| `-r` | Generate resident/reentrant code |
| `-L` | Disable auto-open of amiga.lib |
| `-w` | Suppress warnings |
| `-E` | Preprocess only |
### Linker Flags (blink)
| 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
```c
/* 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
- SAS/C 6.x User Manual and Reference Manual
- NDK39 pragma files: `NDK_3.9/Include/pragmas/`
- See also: [pragmas.md](pragmas.md) — pragma/inline mechanism in depth
- See also: [gcc_amiga.md](gcc_amiga.md) — GCC cross-compiler (modern alternative)