docs: Write initial documentation for access-director and command-drivers

This commit is contained in:
Rachel 2025-04-20 17:01:01 -07:00
parent f5aff7f4e1
commit 72fbcf58e6
8 changed files with 530 additions and 0 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
# Build artifacts
build/
*.nds
*.1
# Developer conveniences
testdir/

View File

@ -73,9 +73,27 @@ Developers and early-adopters can build the project from source:
./build/nitrorom
```
Optionally, distributable manual-pages can be generated from the plain-text
files in `docs/`:
```sh
ninja -C build docs
```
This requires setting up the project with the `manuals` option set to `true`,
which must be specified when configuring the build:
```sh
meson setup -Dmanuals=true build
```
The generation targets use [`asciidoctor`][repology-asciidoctor] to convert the
`.adoc` files into manual pages.
[getting-meson]: https://mesonbuild.com/Getting-meson.html
[repology-meson]: https://repology.org/project/meson/versions
[repology-libpng]: https://repology.org/project/libpng/versions
[repology-asciidoctor]: https://repology.org/project/asciidoctor/versions
## Usage

25
docs/meson.build Normal file
View File

@ -0,0 +1,25 @@
man_1_adoc_files = [
'nitrorom.adoc',
'nitrorom-list.adoc',
'nitrorom-pack.adoc',
]
asciidoctor_exe = find_program('asciidoctor')
man_1 = []
foreach man_1_adoc : man_1_adoc_files
man_1_out = man_1_adoc.replace('.adoc', '.1')
man_1 += custom_target(
input: files(man_1_adoc),
output: man_1_out,
command: [
asciidoctor_exe,
'-b', 'manpage',
'-a', 'manversion=' + meson.project_version(),
'-o', '@OUTPUT@',
'@INPUT@',
],
)
endforeach
alias_target('docs', man_1)

40
docs/nitrorom-list.adoc Normal file
View File

@ -0,0 +1,40 @@
nitrorom-list (1)
=================
:doctype: manpage
:manmanual: NitroROM Manual
:mansource: NitroROM {manversion}
:man-linkstyle: pass:[blue R < >]
NAME
----
nitrorom-list - List the components of a Nintendo DS ROM
SYNOPSIS
--------
[verse]
'nitrorom list' <INPUT.NDS>
DESCRIPTION
-----------
Generate a listing of the constituent members of an input ROM file. The listing
will be emitted to the standard-output stream in a comma-separated format. Each
record in the output adheres to the following `printf`-style format:
------
ROM Start,ROM End,Size,Padding,Component
ROM Start - 0x%08X
ROM End - 0x%08X
Size - 0x%08X
Padding - 0x%04X
Component - %s
------
No program-options are available for this command. No validation is performed on
the input ROM-file, and it is treated as-is.

371
docs/nitrorom-pack.adoc Normal file
View File

@ -0,0 +1,371 @@
nitrorom-pack (1)
=================
:doctype: manpage
:manmanual: NitroROM Manual
:mansource: NitroROM {manversion}
:man-linkstyle: pass:[blue R < >]
NAME
----
nitrorom-pack - Produce a Nintendo DS ROM from sources
SYNOPSIS
--------
[verse]
'nitrorom pack' [OPTION]... <CONFIG.INI> <FILESYSTEM.CSV>
DESCRIPTION
-----------
Construct a Nintendo DS ROM-file from the contents of the input specification
files. The output ROM-file will be packaged using a strategy similar to that
used by the tooling which shipped with the original proprietary SDK. Thus, given
a set of binary-identical input files and an identical ordering of those input
files, this program should produce a binary-identical ROM-file to an existing
retail copy.
For details on the expected content of input specification files, refer to
<<CONFIG.INI>> and <<FILESYS.CSV>>.
OPTIONS
-------
`-D <key=val>`::
`--define=<key=val>`::
Define a key-value pair to be used while parsing program configuration. Keys
identified during the parse-run will be substituted in-place for matching
values from these definitions, if any such match exists. If no match exists,
then the program will exit with an appropriate error message. Keys specified
must be unique.
`-C <dir>`::
`--directory=<dir>`::
Change to directory _<dir>_ before loading any constituent file-data. This
will not affect the loading of input specification files, which will be
opened according to the working directory in which the program is run.
`-o <file>`::
`--output=<file>`::
Write a packaged output ROM to _<file>_. Defaults to `rom.nds`.
`--dry-run`::
Do not create an output ROM; instead, emit intermediate artifacts computed
during packing which would be built into the ROM. For details on the files
generated by this option, refer to <<DRY-RUN_MODE>>.
`--verbose`::
Emit verbose program logs during execution. These logs are written to the
standard-error stream to separate them from any other logging statements
which may be written to the standard-output stream.
EXAMPLES
--------
`nitrorom pack -C build config.ini filesys.csv`::
Reads the contents of _./config.ini_ and _./filesys.csv_ to build an output
ROM. Filepaths referenced in _./config.ini_ and _./filesys.csv_ will be
implicitly prefixed with _./build/_. An output ROM _./rom.nds_ will be created.
`nitrorom pack -C build --output myrom.nds config.ini filesys.csv`::
Identical to the above, but the output ROM will be created as _./myrom.nds_.
`nitrorom pack -DARM7_STATIC=myarm7.sbin -C build config.ini filesys.csv`::
Replace the variable-substitution token _${ARM7_STATIC}_ with _myarm7.sbin_
while processing configuration.
`nitrorom pack -C build --dry-run config.ini filesys.csv`::
Do not generate an output ROM, but instead emit dry-run artifacts to the
directory _./build_.
`nitrorom pack -C build --dry-run --verbose config.ini filesys.csv`::
Emit verbose logs detailing the packing strategy while reading configuration
files. These verbose logs are prefixed with a colon-delimited string which
details the stage of the packing process; e.g., _rompacker:configuration:banner:_
will precede a message emitted while parsing the _banner_ section of _./config.ini_.
[[CONFIG.INI]]
CONFIG.INI
----------
This file details important meta-properties for the output ROM's structure and
critical files to be used by the system's coprocessors.
Syntax Overview
~~~~~~~~~~~~~~~
The contents of this file are parsed as a flavour of _.ini_:
- Comments are permitted on standalone lines and recognized by a leading hash
(#) or semicolon (;). Comments are _not_ permitted in-line.
- The file consists of sections and key-value pairs. A section begins with the
name of the section in square brackets ([ and ]) and continues until the
beginning of the next section.
- All key-value pairs belong to a section.
- A key-value pair is separated into a key and a value around an equals sign
(=).
- The keys recognized by each section are strictly-defined.
- Values of the form `${VARIABLE}` will be replaced with corresponding values
from the variable-store specified by command-line arguments.
- White-space which leads or trails either the key or value is ignored.
- White-space _within_ values is permitted, provided that it follows a character
which is _not_ white-space and is not a new-line (which would terminate the
key-value pair).
- Blank lines (those which contain only white-space) are ignored.
Value Types
~~~~~~~~~~~
Values read from the input file are strongly-typed.
`boolean`::
A simple flag value. The literal values “true”, “yes”, and “on” will be read
as a “truthy” value; “false”, “no”, and “off” will be read as a “falsy”
value. Any other specified value is invalid.
`number`::
A literal number, either in base-10 or base-16. If the number must be given
as base-16, then it must be prefixed with “0x” or “0X”. Both lowercase and
uppercase alphabetic digits are accepted for base-16 numbers. Digit
separators of any kind (\_, ,, ., etc.) are _not_ permitted.
`string`::
A literal string. No additional validation is performed inherently, though
individual keys are free to enforce their own specific value-validation.
`header` Section
~~~~~~~~~~~~~~~~
This section is described by the name “header”. Keys in this section generally
specify metadata which is only relevant to the header of the output ROM-file.
`template` -> `string`, filepath::
Specify the path to a file which should be loaded as an initial state for
the output ROM-file's header. This may be useful if you have a pre-computed
header that should not be changed or modified, or if you have identified
byte-data within a retail ROM's header that must be maintained to produce an
output which satisfies which satisfies binary-matching (e.g., for a
decompilation project) or which is not configurable via other means within
this file.
`title` -> `string`, max length: 12::
The 12-character ASCII title string as stored in the output ROM header. Note
that this does _not_ specify the title which is displayed on the system
boot-menu. Some emulators, however, may show this title string in their
window decorations.
`serial` -> `string`, max length: 4::
The 4-character ASCII serial code associated with the output ROM. This value
uniquely identifies the game's ROM software and release language.
Functionally, this value serves no purpose and is purely informational.
`maker` -> `string`, max length: 2::
The 2-character ASCII maker code associated with the output ROM.
Historically, the value given here was assigned to a developer as part of
their publication-agreement with Nintendo. Functionally, this value serves
no purpose and is purely informational.
`revision` -> `number`, base-10, max value: 255::
The revision number of the ROM-file. Historically, some retail releases
produced further revisions which may have corrected issues identified after
the first edition was submitted for publication.
`secure-crc` -> `number`, base-16, max value: 0xFFFF::
An override value to be specified as the CRC-16 checksum of the output ROM's
secure area. The secure area consists largely of system-critical code for,
e.g., reading data from the inserted game card.
`rom` Section
~~~~~~~~~~~~~
This section is described by the name “rom”. Keys in this section define
attributes about the output ROM-file's structure or control interactions between
the ROM-file and the hardware.
`storage-type` -> `string`, allowed values: “MROM”, “PROM”::
Either “MROM” (for Masked Read-Only Memory) or “PROM” (for Programmable
Read-Only Memory). The specified storage-type has a number of implications
which will not be summarized here; in practice, this value controls various
clock-timings for card-access by the hardware and the functional size-limit
for an output ROM-file: “MROM” ROM-files are limited to 64MB of capacity,
whereas “PROM” ROM-files are limited to 2GB of total ROM space.
Generally, the storage-type used by a retail ROM-file can be identified
by interpreting offset `0x006E..0x006F` of the file as a 16-bit integer in
little-endian order: a value of `0x051E` represents “MROM”, while a value of
`0x0D7E` represents “PROM”.
`fill-tail` -> `boolean`::
If set to a truthy-value, then the output ROM-file should be filled to its
maximum capacity with the configured padding value (see “fill-with”). The
maximum capacity is computed according to the consumed storage space of the
output ROM-file, rounded up to the next power-of-2.
`fill-with` -> `number`, base-16, max value: 0xFF::
This value will be used to align member-files and ROM sections to offset-
boundaries divisible by `0x200`. If “fill-tail” is set to a truthy-value,
then this value will also be used to fill any remaining space in the output
ROM-file up to its determined maximum capacity.
`banner` Section
~~~~~~~~~~~~~~~~
This section is described by the name “banner”. Keys in this section define data
usable by the system for display to an end-user via the boot menu.
`version` -> `number`, allowed values: 1, 2, 3::
Specify the version of the banner-encoding to be used. This value controls
the languages in which the title-string is provided, and all versions are
backwards-compatible with previous versions. All banners will provide a
title-string for the Japanese, English, French, German, Italian, and Spanish
languages; version 2 banners will additionally provide a title-string for
the Chinese language, and version 3 banners will further provide a title-
string for the Korean language.
`icon` -> `string`, filepath::
Specify the path to an indexed, 16-color PNG to be used for displaying an
icon on the system boot menu. This key acts as a wrapper around `icon4bpp`
and `iconpal` for end-users that do not wish to pre-compute the requisite
files for those keys as part of their packaging workflow.
`icon4bpp` -> `string`, filepath::
Specify the path to a pre-computed 4-bit-per-pixel tileset to be used by an
icon on the system boot menu. Individual tiles should be computed from the
indexed-PNG format by consuming 4 pixel-pairs from the row-origin, then
iterating to the next column and repeating 8 total times. The output
pixel-pairs must have their ordering inverted -- that is, the right-most
pixel of the pair will comprise the most-significant nybble, and the
left-most pixel will comprise the least-significant nybble.
`iconpal` -> `string`, filepath::
Specify the path to a pre-computed 15-bit-color RGB palette to be used by an
icon on the system boot menu. Each color-value in the palette must be
formatted with 5-bit values for each of the Red, Green, and Blue channels.
The Red channel will comprise bits 0 through 4, the Green channel will
comprise bits 5 through 9, the Blue channel will comprise bits 10 through
14, and bit 15 will be discarded.
`title` -> `string`, UTF-8 encoded, Basic Multilingual Plane::
`subtitle` -> `string`, UTF-8 encoded, Basic Multilingual Plane::
`developer` -> `string`, UTF-8 encoded, Basic Multilingual Plane::
Specify title-string components for the output ROM-file. These components
are copied for use by all languages in the output, and they must be
specified in the order “title” -> “subtitle” -> “developer”. The “subtitle”
component is considered optional. Individual components accept the same set
of characters from plane 0 of the Unicode standard (the “Basic Multilingual
Plane”), which defines encodings for characters in most major world
languages.
`arm9` and `arm7` Sections
~~~~~~~~~~~~~~~~~~~~~~~~~~
These two sections, despite their differing names, are sisters which support an
identical set of keys. These sections are kept separate from one another to
denote to which coprocessor each key-value pair belongs: the ARM946E-S (commonly
called the “main” coprocessor) or the ARM7TDMI (commonly called the “sub”
coprocessor).
`static-binary` -> `string`, filepath::
Specify the path to a file which will be loaded and treated by the hardware
as code for the corresponding coprocessor that should always be present
within RAM at runtime.
`definitions` -> `string`, filepath::
Specify the path to a file which will be interpreted by this program as a
set of “definitions” relevant to the coprocessor. The terminology used here
and the collection of values therein are both loosely defined, and this file
should be produced by some aspect of your build system. This program expects
this file to have the following structure:
--------
struct definitions_t {
uint32_t load_addr; // RAM address for the static code-binary.
uint32_t entry; // RAM address for the coprocessor's entry-point.
uint32_t load_size; // Size of the static code-binary.
uint32_t load_cb; // RAM address of an on-load callback routine.
char *overlays[]; // Null-terminated filepaths for overlay binaries.
};
--------
`overlay-table` -> `string`, filepath::
Specify the path to a file which will be loaded and treated by the hardware
as a list of data-values for use by the coprocessor when loading overlays.
This file should be produced by some aspect of your build system, whether
when unpacking an existing ROM-file or by a program-linker. Individual
records within this table must adhere to the following structure:
--------
struct overlay_t {
uint32_t id;
uint32_t load_addr;
uint32_t load_size;
uint32_t bss_size;
uint32_t static_init_head_addr;
uint32_t static_init_tail_addr;
uint32_t filesys_id;
uint32_t _padding;
};
--------
[[FILESYS.CSV]]
FILESYS.CSV
-----------
The structure of the output ROM's filesystem is computed from this input file,
which contains newline-delimited records of comma-delimited fields (a typical
CSV table-file). This program expects that this input file:
1. contains a header record, which acts only as an informant to a human reader
and is otherwise ignored by the program;
2. specifies one record for each filesystem member in the output ROM, ordered
according to order in which they appear in a forward linear scan of the ROM;
3. specifies two fields for each record: the first is a path to a local file
which contains the filesystem member's data (the “source path”), and the
second is a path to the member in the output ROM's filesystem (the “target
path”);
4. specifies a source path to a local file that is accessible to the program;
5. specifies a Unix-like absolute target path.
To illustrate, consider the following record from a hypothetical input file:
--------
filesys/data/UTF16.txt,/data/UTF16.txt
--------
This record declares the following to the program:
1. there is a file on-disk at the path “filesys/data/UTF16.txt”;
2. the contents of this file at this path must be packed into the ROM; and
3. the contents of this file shall be accessible in the output ROM-file from the
virtual filesystem path “/data/UTF16.txt”.
[[DRY-RUN_MODE]]
DRY-RUN MODE
------------
Running the program in this mode will suppress the final output of a ROM-file.
It can be used, thus, to act as a validator for the input files above. However,
during program execution, some virtual files are generated for packaging into
the output ROM-file; in dry-run mode, these virtual files will be dumped to real
files on-disk in the working directory (potentially modified by the `-C` option)
for inspection / debugging:
1. `header.sbin` - The computed ROM header, which contains critical information
for executing software on the hardware. This header file contains offsets at
which important sections can be found, e.g., the location of static binaries,
coprocessor overlay tables, and the filesystem structure.
2. `banner.sbin` - A collection of data relevant to the system's boot menu which
should be displayed to an end-user: the ROM's software title, any sub-title,
the developer, and a small graphics-set defining a 32x32 icon.
3. `fntb.sbin` - A binary structure which defines the ROM's internal filesystem
layout.
4. `fatb.sbin` - A table of ROM offsets to the head and tail of each member-file
present in the output ROM. This table includes offsets both for coprocessor
overlays and filesystem entries.

65
docs/nitrorom.adoc Normal file
View File

@ -0,0 +1,65 @@
nitrorom (1)
============
:doctype: manpage
:manmanual: NitroROM Manual
:mansource: NitroROM {manversion}
:man-linkstyle: pass:[blue R < >]
NAME
----
nitrorom - Interface with Nintendo DS ROM images
SYNOPSIS
--------
[verse]
'nitrorom' [OPTION]... [COMMAND] [ARGUMENT]...
DESCRIPTION
-----------
NitroROM is a program for interfacing with Nintendo DS ROM-files in a variety of
ways. Its primary aims are to provide a reusable tool-suite for developers,
modders, hackers, and reverse-engineering researchers. This tool-suite is
sub-divided into a set of commands which act as programs unto themselves; the
top-level executable acts merely as an access-director to these programs.
For details on each of the commands listed below, refer to their distinct manual
page.
OPTIONS
-------
`-h`::
`--help`::
View the help-text for the access-director, which provides a summary for
basic usage.
`-v`::
`--version`::
Display the NitroROM suite-version and exit.
COMMANDS
--------
`list`::
Generate a listing of the constituent members of an input ROM-file. The
output listing will be emitted to standard-output in comma-separated format.
`pack`::
Construct a Nintendo DS ROM-file from the contents of the input specification
files.
REPORTING BUGS
--------------
Report bugs to the project's issue page <lhearachel/nitrorom.git[1]>. You will
need a GitHub account to create a new issue.
NOTES
-----
1. lhearachel/nitrorom.git
https://github.com/lhearachel/nitrorom

View File

@ -70,6 +70,9 @@ nitrorom_exe = executable(
if not meson.is_subproject()
subdir('tests')
if get_option('manuals')
subdir('docs')
endif
else
meson.override_find_program('nitrorom', nitrorom_exe)
endif

View File

@ -4,3 +4,10 @@ option(
value: true,
description: 'Force native compilation, even in a cross-compilation setup',
)
option(
'manuals',
type: 'boolean',
value: false,
description: 'Generate manual pages from documentation using Asciidoctor. Ignored by subprojects.',
)