AmigaOS 3.2 — What Changed for Developers (V40 → V47)

This article captures the developer-facing delta from AmigaOS 3.1 / NDK 3.1 (V39/V40) — the baseline the rest of this wiki documents — to AmigaOS 3.2 (NDK 3.2 Release 1, V47, 2021). AmigaOS 3.2 is the Hyperion Entertainment continuation of the OS. The lineage is: the 3.1.4 project (V45, 2016-2018) → the 3.2 project (V46/V47, 2019-2021).

The NDK 3.2 ReadMe-NDK.txt notes: "more than seventeen years after the last AmigaOS 68k NDK," and "tools, examples, and other components from previous NDKs are not needlessly duplicated here" — so the 3.1 NDK and the 3.2 NDK are complementary, not a superset/replace relationship. This article covers what materially changed for someone writing or porting Amiga software.

Version numbers at a glance

Version Meaning
V33-V36 Kickstart 1.2-2.0
V37 AmigaOS 2.0 (this wiki's getting-started baseline)
V39 AmigaOS 3.0 ("AA", Advanced Amiga)
V40 AmigaOS 3.1 (NDK 3.1 — the original wiki baseline)
V45 AmigaOS 3.1.4 project (2016-2018)
V46/V47 AmigaOS 3.2 project (2019-2021); V47.1 ships on the CD ($VER: AmigaOS 3.2 CD-ROM Release 47.1)
V50 Reserved API slots; some functions implemented early in V47

If your code does runtime version checks, the relevant thresholds are V45 (3.1.4 behavior changes) and V47 (3.2). Always check Library->lib_Version, and note that V50 functions exist in the V47 jump table as reserved slots — test for their presence, do not assume.

exec.library — features removed, pools fixed

The biggest exec changes are removals, not additions. Code that touched these private/unfinished APIs will hit a recoverable alert under 3.2:

  • Task trees removed. "These functions were never fully functional and were incomplete." Any use ends in a recoverable alert and returns zero.
  • AVL trees removed. ROM space is precious; high-level data structures belong in a separate library. Any use ends in a recoverable alert and returns zero.
  • Memory pools reverted to the V40 puddle-based scheme (Allocate() on puddles) — "just without the V40 bugs." Released puddles bubble to the top immediately.

Other exec notes: coldstart now detects a 68060 FPU and suppresses the bogus FPU-present report (the 68060.library owns that role). ROMWack is back in place of the SAD debug kernel. On 68040+, ExitIntr does an extra custom-register access to suppress spurious interrupts.

See exec.library Reference for the V40 baseline; the SAD section there is superseded — Status: Outdated — ROMWack replaced SAD in V46.37.

dos.library — finally-correct features and V50 additions

Several V40 promises are fulfilled in 3.2, plus genuinely new functions:

  • NP_Error / NP_CloseError finally work, "unlike V40, which claimed to support it, but in fact did not." For V40 compatibility, NP_Error defaults to NULL (not Open("NIL:",...)) and NP_CloseError to FALSE (not TRUE).
  • System() gains SYS_CmdStream (command input as a stream), SYS_Async (now works with NULL command — a replacement for NewCLI), and SYS_InName/SYS_CmdName/SYS_OutName (open streams in the shell's context). NP_Name is now honored (V40 ignored it, always naming the process "Background CLI").
  • CliInitNewCli() and CliInit() are obsolete — both now dead-end alert. Shell startup uses CliInitRun() exclusively.
  • The *Printf family is buffered (permanently enabled in V47.23). On an A3000 030@25MHz, throughput for medium strings improved by up to ~3.9x over the byte-at-a-time BCPL implementation.
  • Default stack sizes raised for CON:, RAW:, PRT:, SER:, PAR:, RAM: and the FFS.

V50 functions (implemented in V47 for OS 4.x jump-table parity)

The following functions occupy slots reserved for V50 in the dos.library jump table. They were already implemented in V47 (the 3.2 release), so code that needs them can be written today. Multiple other V50 slots are reserved. Each link below points to the autodoc entry in dos.library Reference.

Function Signature Purpose Autodoc
PutErrStr() LONG PutErrStr(STRPTR str) Write a string to the calling process's error stream (pr_CES), falling back to standard output (pr_COS). Returns 0 on success, ENDSTREAMCH on failure. link
GetCurrentDir() BPTR GetCurrentDir(void) Return a lock on the calling process's current directory (the actual pr_CurrentDir value). Use this when you need the lock itself; use GetCurrentDirName() when you want the path string. link
GetCurrentDirName() BOOL GetCurrentDirName(STRPTR buf, LONG len) Copy the current directory's path string into buf. Truncates silently if too short (still returns DOSTRUE). Pair with SetCurrentDirName() for the symmetric write side. link
ErrorOutput() BPTR ErrorOutput(void) Return the calling process's error-output stream (pr_CES), or pr_COS if no error stream is set. Shell commands should use this for diagnostics. link
SelectErrorOutput() BPTR SelectErrorOutput(BPTR newfile) Replace the error-output stream and return the previous one. Pass ZERO to query without changing. Per-process; does not propagate to children. link
VolumeRequestHook() LONG VolumeRequestHook(UBYTE *volume) Hook called by dos.library before showing "please insert volume" requesters. Return DOSTRUE to let the requester appear; DOSFALSE to suppress it (as if the user pressed Cancel). Intended for patching by assign-wedge code, not for direct calls. link
DoShellMethodTagList() APTR DoShellMethodTagList(ULONG method, struct TagItem *tags) Internal entry point used by the Shell itself to dispatch to its own services. Not generally useful to applications, but reserved in the V50 jump table. link

See DOS Error Reporting for the full treatment of PutErrStr, ErrorOutput/SelectErrorOutput, VolumeRequestHook, and related helpers.

intuition.library — iconify, scrollwheel, hotkeys, richer DrawInfo

3.2 substantially modernizes the GUI without breaking the classic event loop:

  • Iconify gadget is first-class. Request WA_IconifyGadget,TRUE (WA_Dummy + 0x60). Pressing it delivers IDCMP_WindowClose with msg->Code = 1 (hide only) rather than 0 (close). MultiView implements this protocol.

  • ShowWindow() / HideWindow() are reimplemented (V50-derived) and run through the input event handler to avoid races. ShowWindow() takes a second arg — the window to show in front of: pass NULL to put the window behind other same-type windows (BACKDROP), pass WINDOW_FRONTMOST to bring it to the front, or pass another window's struct Window * to position the target directly behind it. HideWindow() takes only the target window. Neither call acts immediately — the change is applied the next time Intuition processes an input event (10-60 Hz).

  • Native scrollwheel support at the OS level (V47.26). Shift-click the zoom gadget = maximize. Ctrl+left/right in string gadgets jumps to line ends.
  • GA_Underscore / GA_ActivateKey (backported from OS4) give gadgets and EasyRequest buttons keyboard hotkeys. MIF_SHIFTCOMMSEQ (0x0800) enables Shift+Amiga-key menu shortcuts.
  • SA_OpenBorder lets windows drag partly off-screen (requires layers V45; ON for Workbench, OFF elsewhere).
  • DrawInfo is now version 3. DRI_VERSION is 3 (was 2 for V39). One new pen, BARCONTOURPEN (0x000C), brings NUMDRIPENS to 13 (0x000D), and a new dri_Screen backpointer appears. BARCONTOURPEN colors the left/top edges of the screen bar and menus. Code that hard-codes NUMDRIPENS must be updated.
  • New OSERR_NORTGBITMAP (10) from OpenScreen when a tagged RTG bitmap allocation fails. New sysiclass images: MENUSUB (the proper submenu arrow, replacing the ASCII 187 "»" GadTools used), plus FRAME_PROPBORDER, FRAME_PROPKNOB, FRAME_DISPLAY. New FRAMEF_MINIMAL flag for IM_FRAMEBOX.
  • Mutually-exclusive menu items render as radio buttons, not checkmarks. Configurable sizing-gadget aspect (18×14 / 18×16 / 18×18 / 18×20) for square-pixel high-res screens.
  • IntuitionControlA() is a new multi-purpose entry point; jump-table slots were reserved to match the OS 4.x intuition.library layout.
  • Screen bitmaps now allocate via the tagged AllocBitMap() (V39 AllocBitMap + tags), with the ModeID placed on the tag list, falling back to the legacy allocator on failure.

graphics.library, layers.library, gadtools.library

  • graphics: GetDisplayInfo()/SetDisplayInfo() now reach private/extended display-info elements. A BestModeID() cast bug (lower 16 bits of a tag address used — false negatives at 64K boundaries) is fixed. ClearRectRegion() no longer mangles regions with >1 RegionRectangle.
  • layers (V50 functions present in V47): four layer-management entry points reserved in the V50 jump table are already usable from V47. Superbitmap code simplified; newlayer() pre-allocates cliprects to avoid races.

  • LayerOccluded() — returns TRUE if any part of the given layer is covered by another layer of the same LayerInfo, FALSE if the layer is fully visible. Lock the LayerInfo before calling or the result is undefined.

  • HideLayer() — move a layer behind the bottommost layer and make all its cliprects invisible. For LAYERSMART layers, copy the layer's contents to the back layer before hiding. Available since V45.
  • ShowLayer() — make a previously hidden layer visible again. Available since V45.
  • SetLayerInfoBounds() — define the clipping bounds that all layers of a LayerInfo are confined to. Useful for restricting rendering to a sub-region. Available since V45.
  • gadtools: new NG_GRIDLAYOUT flag; new GTVI_MinFontWidth/GTVI_MinFontHeight; read-only GTLV_Total/GTLV_Visible; GTMX_ScaledSpacing; GTSC_Arrows accepts -1 ("square"). Submenus use the Intuition MENUSUB image (requires intuition ≥47.8) instead of the ASCII 187 glyph. FrameIClass gains FRAME_CONTEXT for bevel boxes.

utility.library — 64-bit math done right, length-limited strings

  • The 64-bit math routines return in proper register order (low 32 bits in d0, high 32 bits in d1). Added SDiv64/UDiv64. 68020 and 68060 specialized versions exist; the 68060 versions are not auto-enabled because exec does not identify the 68060 (the 68060.library does). The 68020-only build of utility is retired.
  • New V47 functions: VSNPrintf() (length-limited formatting), Strncpy(), Strncat(). VSNPrintf() was realigned to the OS 4.x LVO/register order — recompile code using it; the original V47 LVO survives as a wrapper for now.

locale.library — much faster, much stricter

  • FormatString() rewritten (permanently enabled V47.21). Because locale patches exec/RawDoFmt, this speeds up all formatted output; on an A3000 030@25MHz short-string RawDoFmt() is up to 5.06x faster. The number-conversion buffer shrank to 100 chars (from 200); %s is no longer capped at 65535 chars.
  • GetCatalogStr() uses a sorted lookup table + binary search for catalogs with ≥128 entries (a non-recursive qsort() avoids pulling in the SAS/C runtime).
  • Catalog loading is hardened: it validates the STRS, language, and version chunks and string bounds, and rejects malformed catalogs. FormatString() positional args (%5$s) are limited to 128.
  • GetCatalogStr() deliberately preserves the V38-V40 D1/A0/A1 register configuration because software (e.g. TurboCalc 3.5) depends on it.

Devices

  • timer.device / trackdisk.device add NSCMD_QUERY. trackdisk makes TD_ADDCHANGEINT/TD_REMCHANGEINT safe and adds a CPU-based MFM encoder plus TDInitBuffer()/TDU_* tags for 32-bit chip memory.

NDK 3.2 later releases (R2, R3, R4)

The tree above documents the R1 baseline (13.04.2021). Hyperion shipped three updates — R2 (31.05.2021), R3 (22.06.2021) and R4 (06.02.2022). R4 is the significant one for developers: its autodocs "for the first time in 35 years contain documentation on bugs and features never covered in detail before in the RKM text or in the AutoDocs" (8 libraries: amiga_lib, audio, commodities, dos, exec, graphics, locale, wb). R4 also adds two developer-doc articles, full trackfile.device/DAControl source, vbcc inline-header support, and Include_I/lvo/. See NDK 3.2 R2/R3/R4 Release Notes.

New R4 developer knowledge documented separately:

  • Interface Header Files — how clib/proto/pragmas/pragma/inline and amiga.lib stub code bridge C to register-based OS calls.
  • exec Memory Pools — the puddle/threshold scheme, sizing, and the show_memory_pool_insights() diagnostic.
  • trackfile.device — the ADF-backed virtual-floppy driver (full source in R4).

Third-party GUI: MUI

The 3.2 era also brought the third major GUI toolkit into scope. MUI — Magic User Interface (Stefan Stuntz, 1992-97, v3.8 dev archive) is the dominant third-party BOOPSI GUI system, distinct from both GadTools and ReAction: it provides a fully automatic layout engine and a declarative notification mechanism where the main loop is just a Wait().

New subsystems in NDK 3.2 (separate articles)

These did not exist in NDK 3.1 and have their own articles:

  • ReAction GUI Toolkit — BOOPSI-based gadget classes opened as libraries; the Examples/ tree ships ~40 demos.
  • mmu.library — Thomas Richter's hardware-independent MMU API (basis for MuForce and the virtual-memory memory.library).
  • Roadshow bsdsocket TCP/IP — Olaf Barthel's TCP/IP stack; SANA-II evolved to R4/R5.

See Also


Sources: Hyperion Entertainment / AmigaOS Team, NDK 3.2 ReleaseNotes (exec, dos, intuition, graphics, layers, gadtools, utility, locale, trackdisk, timer), 2016-2021; NDK 3.2 ReadMe-NDK.txt. Raw: raw/architecture/os-3.2-release-notes.md Updated: 2026-08-04