RISC OS Build EnvironmentROBE

Appendix41Appendix G: CMHG File Format

Overview

The CMHG file format, also used by CMunge, is a small domain-specific language for defining the interfaces and structure of a RISC OS relocatable module. CMunge processes these description files to generate the assembly-language veneers that bridge the RISC OS kernel environment with C or C++ module code.

This appendix preserves the main reference material for the format so that the build-environment guide can explain module workflows without having to repeat every directive inline. The same source format is used by the original CMHG tool and by the newer riscos-cmunge wrapper around CMunge, although CMunge adds extra directives and target support.

Directive reference

Syntax rules

The CMHG and CMunge parsers follow these basic rules:

  • Logical lines: the file is a sequence of logical lines.
  • Comments: start with a semicolon (;) and extend to the end of the physical line. Comments are removed before parsing.
  • Directives: keywords followed by a colon (:). Keywords are case-insensitive and consist of alphabetic characters and minus signs.
  • Line continuation: a physical line ending with a comma (,) continues onto the next physical line.
  • Strings: enclosed in double quotes. Adjacent quoted strings are concatenated before processing.
  • Numbers: unsigned decimal by default, or hexadecimal with & or 0x.
  • Arguments: lists may be separated by commas or spaces. Commas are required when splitting lists across lines.

Integer evaluation

CMHG strips surrounding parentheses from integer values so that values taken from C-style headers through #include directives can be used directly.

CMunge also supports simple additive expressions such as (&800 + 1). No other arithmetic operations are supported in the format itself.

Module identification

title-string

Defines the module's internal name, as shown by *Modules. It should normally be a single word and is best kept below about 16 characters.

title-string: MyModule

help-string

Defines the descriptive string shown by *Help Modules. The usual form is:

ModuleTitle VersionNumber Comment

The version number should normally be written as d.dd.

help-string: MyModule 1.00 (06 Apr 2026) Copyright 2026

date-string

CMunge extension. Supplies an explicit build date string when the date is not intended to be derived only from the help string.

date-string: 06 Apr 2026

Core module handlers

initialisation-code

Names the C function called when the module is initialised or reinitialised.

C prototype: _kernel_oserror *init(const char *tail, int podule_base, void *pw);

Return NULL for success, or a pointer to an error block to abort initialisation. Finalisation code is not called if initialisation fails.

finalisation-code

Names the C function called when the module is being killed, just before the C library is shut down.

C prototype: _kernel_oserror *final(int fatal, int podule, void *pw);

Return NULL to allow termination, or an error pointer to refuse it.

service-call-handler

Names the C function that handles service calls. It may be followed by a list of service numbers to filter, which is usually preferable to receiving every service call.

C prototype: void *service(int number, _kernel_swi_regs *r, void *pw);

module-is-runnable

Declares that the module may be run as an application, so that the C main function can be entered in user mode.

C prototype: int main(int argc, char *argv[]);

module-is-not-reentrant

Declares that the module is not reentrant and must not be entered again while already running.

module-is-c-plus-plus

CMunge extension for modules containing C++ code built with the supported C++ toolchain arrangements.

module-is-initialised-early

CMunge extension for modules that must be initialised early in the boot sequence, mainly for ROM use.

SWI interface

swi-chunk-base-number

Supplies the base SWI number for the module chunk of 64 SWIs. The X bit must not be set in this value.

Two concrete rules follow from the chunk being 64 entries wide: the base number must be a multiple of 64 (its low 6 bits must be zero), and it must not have bit 17 (&20000, the "X bit") set. Allocated chunk ranges are &0-&3FFC0 for operating-system use, &40000-&7FFC0 for operating-system extensions, &80000-&BFFC0 for third-party applications, and &C0000-&FFFC0 for user applications; any chunk used in a distributed module must be registered.

swi-handler-code

Names the central dispatcher for SWIs in the chunk.

C prototype: _kernel_oserror *swi_handler(int number, _kernel_swi_regs *r, void *pw);

number is the 0 to 63 offset within the chunk.

swi-decoding-table

Defines the SWI prefix and the decoding names:

swi-decoding-table: MyMod, Get, Set, Reset/MyResetHandler

The first entry is the SWI prefix. Each later entry names one SWI and may optionally route that SWI to a specific handler with /<handler>.

swi-decoding-code

Provides custom name-to-number and number-to-name translation code. Both the older single-function interface and the newer two-function interface are supported.

Command interface

command-keyword-table

Defines the module's * command table. The first parameter is the name of the central command handler function, or - if every command uses its own handler or explicitly has no handler.

C prototype for the default handler: _kernel_oserror *command(const char *arg_string, int argc, int number, void *pw);

Each command entry may use sub-keywords such as:

KeywordDescription
min-argsMinimum argument count.
max-argsMaximum argument count.
gstrans-mapBitmap selecting arguments to GSTrans.
fs-commandMarks a filing-system command.
internationalUses tokenised help or syntax messages.
add-syntaxAppends syntax to the help text.
configureMarks a *Configure or *Status command.
statusEquivalent to configure.
helpHandler participates in help generation.
invalid-syntaxSyntax error text or token.
help-textHelp text or token.
handlerSpecific C function for this command.
no-handlerHelp-only command entry.

Veneers and callbacks

generic-veneers

Defines general callback veneers using the form EntryName[/HandlerName](...). Optional parameters include private-word: and carry-capable:.

vector-handlers

Defines veneers for claimable RISC OS vectors such as TickerV. The generated C header exports an extern void name(void) symbol whose address should be passed to OS_Claim or similar interfaces.

C prototype: int handler(_kernel_swi_regs *r, void *pw);

irq-handlers

Obsolete alias for vector-handlers: both CMHG and CMunge continue to accept it, mapped internally to the same handling, so existing CMHG files using it do not need to be changed to keep working. New descriptions should use vector-handlers directly.

vector-traps

CMunge extension for advanced vector chaining where the remainder of the vector chain must be callable explicitly from the handler.

event-handler

Defines an event veneer. Only one entry may appear in a single directive, but the directive may be repeated. Event-number filtering is supported and is recommended for performance.

C prototype: int handler(_kernel_swi_regs *r, void *pw);

Error management

error-chunk-base-number / error-base

CMunge extension that defines the module's base error number. The value is also exported as ERROR_BASE in the generated header.

The example value below is illustrative only. A real module distributed outside this project should have its error base registered with the RISC OS Open allocation service rather than chosen arbitrarily, the same as a SWI chunk; see the allocating-resources skill for the registration process.

error-chunk-base-number: &12345

error-identifiers

CMunge extension for defining named error constants that are exported to the C header.

Other directives

library-initialisation-code

Overrides the C library initialisation symbol. The replacement routine must be written in assembly and must still call the normal _clib_initialisemodule.

library-enter-code

Overrides the module entry symbol normally provided by the C library support code.

international-help-file

Embeds a literal path to the Messages file used for internationalised help and syntax text.

Worked example

Minimal module description

This compact example shows the main structure of a CMHG or CMunge description file for a simple module.

; CMunge description for a sample module
title-string: SampleMod
help-string:  Sample 1.00 (06 Apr 2026)

initialisation-code: mod_init
finalisation-code:   mod_final

swi-chunk-base-number: &58B00
swi-handler-code:      mod_swi
swi-decoding-table:    Sample, Get, Set

command-keyword-table: mod_command
  MyCmd(min-args: 0, max-args: 1, help-text: "Usage: *MyCmd [<arg>]")

generic-veneers: callback/callback_handler(private-word: r1)

riscos-cmunge, the tool behind both the CMHG and CMunge descriptions, has no separate check-only or dry-run mode. A mistake in a hand-written description file is therefore only caught when CMunge fails to produce the expected header, or when the resulting build fails to link, not by any earlier validation step.