https://github.com/gingerbeardman/snes-memory-maps
Generate SNES memory maps as SVG and/or CSV, with lots of options
https://github.com/gingerbeardman/snes-memory-maps
data-visualisation memory-map sfc snes treemap
Last synced: 10 days ago
JSON representation
Generate SNES memory maps as SVG and/or CSV, with lots of options
- Host: GitHub
- URL: https://github.com/gingerbeardman/snes-memory-maps
- Owner: gingerbeardman
- License: mit
- Created: 2026-07-02T14:27:07.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-07-02T19:22:21.000Z (about 1 month ago)
- Last Synced: 2026-07-09T19:27:27.909Z (30 days ago)
- Topics: data-visualisation, memory-map, sfc, snes, treemap
- Language: Python
- Homepage: https://www.gingerbeardman.com/apps/
- Size: 58.6 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# SNES Memory Maps
Generate zoomable SVG maps of SNES ROM and WRAM from linker map files, with
optional machine-readable CSV output.
Supports [llvm-mos](https://github.com/llvm-mos/llvm-mos) (ld.lld),
[vbcc65816](http://www.compilers.de/vbcc.html) (vlink), [cc65](https://cc65.github.io/)
(ca65/ld65), [wla-dx](https://github.com/vhelin/wla-dx), and
[asar](https://github.com/RPGHacker/asar); the input format is auto-detected.
Linker maps carry exact sizes; assembler symbol files (wla-dx, asar) carry only
addresses, so their sizes are inferred (see below).
The repository provides two command-line scripts:
- `rommap.py` creates a physical-bank ROM treemap.
- `rammap.py` creates an address-preserving WRAM overview with low-WRAM and
direct-page zooms.
Both are thin entry points to `snesmap.py`, the shared engine that does the map
parsing, layout, and rendering; they simply preset ROM or RAM mode. Keeping one
engine means the ~95% of logic the two maps share lives in a single place, while
you still get the two commands you'd expect. (`snesmap.py` is not meant to be run
directly.)
All three use only the Python 3 standard library. Their SVG output supports
light and dark colour schemes, browser zooming, and per-allocation tooltips.
## Examples
### ROM

### RAM

## Quick start
Run the scripts from the directory containing your linker script:
```sh
python3 /path/to/rommap.py build/game.map \
--linker-script game.ld \
-o build/rommap
python3 /path/to/rammap.py build/game.map \
-o build/rammap
```
Each command writes an SVG by default:
```text
build/rommap.svg
build/rammap.svg
```
Pass `--csv` to also write the machine-readable CSV (`build/rommap.csv`,
`build/rammap.csv`).
The format is auto-detected. Override detection with `--format`, one of `lld`,
`vlink`, `ca65`, `wla`, or `asar`.
## ROM map
The ROM map displays sixteen physical 32 KiB banks in SNES reading order. Bank
headers show allocated bytes and a right-aligned percentage. Symbol rectangles
are proportional within each bank; transparent rectangles are free space.
For llvm-mos/ld.lld builds, ROM region names, origins, and capacities come from
the linker script's `MEMORY` block. Regions below `$00:8000` and WRAM banks
`$7E/$7F` are excluded.
The RAM script derives its fixed WRAM ranges directly and does not require a
linker script.
The existing `rom_bank_fixed` convention is recognised: its contents are shown
in every `code_bank_*` physical bank. Other linker-region names have no special
meaning.
## RAM map
The RAM map separates static linker allocation from runtime usage:
- A true-scale overview displays the full 128 KiB WRAM.
- A magnified panel displays `$7E:0100–1FFF`.
- A second magnified panel displays the default direct page,
`$7E:0000–00FF` with `D=$0000`.
- Allocation order and address gaps are preserved.
RAM colours identify initialized `.data`, zero-filled `.bss`, `.noinit`,
hardware stack reservation, compiler direct-page registers, and other
allocations. Unallocated space is transparent by default.
When present in an ld.lld map, `__rcN` and `__stack` linker symbols are used to
account for compiler direct-page registers and the page-$01 hardware stack.
Dynamic stack and heap high-water usage cannot be inferred from a static linker
map.
## Display options
Options apply independently to either script:
```sh
--checkerboard
--colour-key # alias: --color-key
--coloured-percentages # alias: --colored-percentages
```
- `--checkerboard` uses a Photoshop-style pattern for free space.
- `--colour-key` adds the colour legend.
- `--coloured-percentages` shows 75–89.9% in amber and 90%+ in red.
All three are off by default.
Use `--compiler "toolchain name"` to override the compiler/linker label embedded
in the SVG footer.
Use `--delimiter` to change the field separator used throughout the SVG — headers,
tooltips, captions, and the footer (e.g. `$00 / 31,333 B / 95.6% full`). It is
space-padded, and the default is a bullet (`·`), e.g. `--delimiter "/"`.
## Supported linker maps
- llvm-mos/ld.lld map output, with ROM regions read from a GNU-style `MEMORY`
block.
- vbcc65816/vlink section mappings.
- vlink LoROM, plus the vlink HiROM address projection used by `vlink-hi`.
- cc65 ca65/ld65: the `ld65 --mapfile` **Segment list** for exact per-segment
sizes. Optionally pass your cc65 linker config (the same `.cfg` you build with,
`cl65 -C` / `ld65 -C`) as `--linker-script` to name the ROM regions; without it
the map falls back to physical banks.
- wla-dx / asar symbol files (`wlalink` `.sym`, `asar --symbols=wla|nocash`):
label→address only, so LoROM physical banks are assumed and sizes are
**inferred** from label gaps (the last label in a bank runs to the bank end).
Trailing free space inside a bank is therefore invisible; the footer marks
these maps `(approx sizes)`.
See [docs/linker-map-support.md](docs/linker-map-support.md) for assumptions and
known limitations.
## Development
Run the test suite:
```sh
python3 -m unittest discover -s tests -v
```
The tests invoke both scripts against small checked-in fixtures for each
supported format (ld.lld, vlink, ca65/ld65, wla-dx, and asar) and validate their
CSV and SVG output.
## Acknowledgements
The physical-bank ROM view was inspired by Pin Eight's
[Homebrew ROM maps and treemaps](https://pineight.com/retrotainment/home_treemaps.html).
## License
MIT. See [LICENSE](LICENSE).