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:
| Keyword | Description |
|---|---|
| min-args | Minimum argument count. |
| max-args | Maximum argument count. |
| gstrans-map | Bitmap selecting arguments to GSTrans. |
| fs-command | Marks a filing-system command. |
| international | Uses tokenised help or syntax messages. |
| add-syntax | Appends syntax to the help text. |
| configure | Marks a *Configure or *Status command. |
| status | Equivalent to configure. |
| help | Handler participates in help generation. |
| invalid-syntax | Syntax error text or token. |
| help-text | Help text or token. |
| handler | Specific C function for this command. |
| no-handler | Help-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.