NAUG Ch6 — Introduction to the OS

Holmes & Dickens, The New Advanced User Guide, pp.107-125. Defines the MOS API surface: vectored entry points, indirection vectors, OSBYTE / OSWORD generic protocol, zero-page and page-two workspace allocation.

This is the contract the MOS exposes to user code. The wiki’s zero-page and os-workspace close the memory/vdu-workspace stub that was left over from the earlier Ch13 ingest.

Key facts captured

  • All OS calls take their primary parameter in A. Secondary in X, Y. If more is needed, X+Y form a 16-bit pointer to a parameter block.
  • Vectored calls JMP-indirect through a 2-byte vector in page 2 (e.g. OSWRCH JMP (&20E)). Vector contents differ per machine. Intercepting a vector lets you wedge into the OS path.
  • Non-vectored calls (NVWRCH &FFCB, NVRDCH &FFC8, etc.) are faster (no indirection) but not available across the Tube.
  • All OS calls preserve the interrupt status (though interrupts may be enabled during the call — relevant for IRQ handlers that mustn’t call OS).
  • Decimal flag must be CLEAR before any OS call (per Ch3 §3.2 — see 6502).

Vector & entry-point table (NAUG §6.1 p102)

RoutineAddressVectorFunction
(User)USERV &200User vector (catches unknown OSWORD &E0-&FF)
(BRK)BRKV &202BRK handler
(IRQ)IRQ1V &204Primary IRQ vector
(IRQ)IRQ2V &206Unrecognised IRQ vector
OSCLI&FFF7CLIV &208Command line interpreter
OSBYTE&FFF4BYTEV &20AOSBYTE dispatcher
OSWORD&FFF1WORDV &20COSWORD dispatcher
OSWRCH&FFEEWRCHV &20EWrite char to output
OSNEWL&FFE7Write LF+CR
OSASCI&FFE3Write char (&D → LF+CR)
OSRDCH&FFE0RDCHV &210Read char from input
OSFILE&FFDDFILEV &212Load/save file
OSARGS&FFDAARGSV &214File arguments
OSBGET&FFD7BGETV &216Get byte from file
OSBPUT&FFD4BPUTV &218Put byte to file
OSGBPB&FFD1GBPBV &21AMulti-byte file I/O
OSFIND&FFCEFINDV &21COpen/close file
(FSC)FSCV &21EFiling system control
(Event)EVNTV &220Event dispatch
(Print)UPTV &222User print
(Econet)NETV &224Econet
(VDU)VDUV &226Unrecognised VDU command
(Key)KEYV &228Keyboard
(Buf)INSV &22AInsert into buffer
(Buf)REMV &22CRemove from buffer
(Buf)CNPV &22ECount/purge buffer
(Spare)IND1V &230Spare
(Spare)IND2V &232Spare
(Spare)IND3V &234Spare
NVWRCH&FFCBNon-vectored OSWRCH
NVRDCH&FFC8Non-vectored OSRDCH
GSREAD&FFC5Read char from string
GSINIT&FFC2String input init
OSEVEN&FFBFGenerate event
OSRDSC&FFB9Read byte from screen / paged ROM (formerly “OSRDRM”)
OSWRSC&FFB3Write byte to screen

OSBYTE convention (§6.3.1)

  • A = call number.
  • X, Y = parameters per call.
  • On exit: A preserved, X/Y may return values.
  • For OSBYTEs &A6-&FF: <NEW>=(<OLD> AND Y) EOR X; old value returned in X. Read: X=0, Y=&FF. Write: X=value, Y=0.
  • Unknown OSBYTE → paged ROM service call &07 with A/X/Y in zp &EF/&F0/&F1.

OSWORD convention (§6.3.2)

  • A = call number.
  • X+Y = parameter block address (LSB+MSB).
  • Block layout per call; results written back to the same block.
  • Unknown OSWORD with A=&E0-&FF → USERV (&200).
  • Other unknown OSWORD → paged ROM service call &08, A/X/Y in &EF/&F0/&F1.
  • DFS 0.90 bug: that DFS version intercepts any unknown OSWORD ≥ &80 and treats it as OSBYTE &7F. Avoid that range unless you know DFS 0.90 isn’t present.

Zero page allocation (§6.6.1)

The most performance-critical resource on the BBC: page 0. NAUG splits it as:

RangeOwner
&00-&6FLanguage workspace (BASIC has most of it)
&70-&8FUser zero page (32 bytes — safe to use)
&90-&9FEconet workspace
&A0-&A7NMI workspace
&A8-&AFOS temporary workspace
&B0-&BFFS temporary workspace
&C0-&CFFiling system workspace
&D0-&E1VDU workspace (see zero-page)
&E2-onwardsOS / CFS / FS / OSBYTE/OSWORD parameter storage
&EFOSBYTE/OSWORD A value (during call)
&F0OSBYTE/OSWORD X value
&F1OSBYTE/OSWORD Y value
&FCAccumulator save during IRQ
&FFEscape flag (bit 7 only)

Detail in zero-page.

Page 2 — OS variables and vectors (§6.6.2)

  • &200-&235 — Operating-system vectors (table above).
  • &236-&28F — OS variables addressable via OSBYTE &A6-&FF.
  • &290-&29F*TV settings, TIME values (dual-clock for atomicity), interval timer.
  • &2A0-onwards — Paged ROM table, INKEY countdown, ADC results, event enable flags, key rollover, buffer pointers, CFS state, OSFILE control blocks.

Detail in os-workspace.

OSHWM — where user RAM starts

  • OSBYTE &83 — Read OSHWM (low byte in X, high byte in Y).
  • OSBYTE &B3 — R/W primary OSHWM (top of OS RAM ignoring font state). On Master this OSBYTE doubles as paged-ROM 100Hz polling semaphore.
  • OSBYTE &B4 — R/W current OSHWM (may differ from primary if font is exploded).

OSHWM is the MSB of a 16-bit address always on a page boundary. On Model B with DFS, typically &19 (= &1900). After exploding fonts up to OSHWM+&600.

Filed into

  • zero-page — Full zp allocation with user/MOS regions and MOS-bypass notes.
  • os-workspace — Page 1, page 2, page 3 workspace consolidated (closes the earlier memory/vdu-workspace stub).
  • calls — Master OS entry-point reference (replaces stubs in os/osbyte.md / os/osword.md).
  • Updates: memory-map now links to zero-page and os-workspace pages.

Open follow-ups

  • DFS 0.90 OSWORD interception bug detail — only Model B with that specific DFS revision. Sidelined.
  • Master-specific OSHWM 100Hz semaphore use → covered when Ch17 ingested.
  • Filing-system OS calls (OSFILE..OSFIND) — details in Ch16 (pending).

This wiki is curated by Claude following the LLM-Wiki methodology — a human curates source documents, the LLM compiles structured cross-linked markdown. Content may contain errors, omissions, or stale claims. For authoritative information refer to the original source documents in the bbc-documents GitHub archive.