{"id":51971134,"url":"https://github.com/gingerbeardman/snes-memory-maps","last_synced_at":"2026-07-29T22:30:43.935Z","repository":{"id":368895964,"uuid":"1287266288","full_name":"gingerbeardman/snes-memory-maps","owner":"gingerbeardman","description":"Generate SNES memory maps as SVG and/or CSV, with lots of options","archived":false,"fork":false,"pushed_at":"2026-07-02T19:22:21.000Z","size":60,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-09T19:27:27.909Z","etag":null,"topics":["data-visualisation","memory-map","sfc","snes","treemap"],"latest_commit_sha":null,"homepage":"https://www.gingerbeardman.com/apps/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gingerbeardman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-02T14:27:07.000Z","updated_at":"2026-07-04T07:34:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gingerbeardman/snes-memory-maps","commit_stats":null,"previous_names":["gingerbeardman/snes-memory-maps"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gingerbeardman/snes-memory-maps","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fsnes-memory-maps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fsnes-memory-maps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fsnes-memory-maps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fsnes-memory-maps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gingerbeardman","download_url":"https://codeload.github.com/gingerbeardman/snes-memory-maps/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gingerbeardman%2Fsnes-memory-maps/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36052204,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-29T02:00:04.910Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-visualisation","memory-map","sfc","snes","treemap"],"created_at":"2026-07-29T22:30:43.423Z","updated_at":"2026-07-29T22:30:43.927Z","avatar_url":"https://github.com/gingerbeardman.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SNES Memory Maps\n\nGenerate zoomable SVG maps of SNES ROM and WRAM from linker map files, with\noptional machine-readable CSV output.\n\nSupports [llvm-mos](https://github.com/llvm-mos/llvm-mos) (ld.lld),\n[vbcc65816](http://www.compilers.de/vbcc.html) (vlink), [cc65](https://cc65.github.io/)\n(ca65/ld65), [wla-dx](https://github.com/vhelin/wla-dx), and\n[asar](https://github.com/RPGHacker/asar); the input format is auto-detected.\nLinker maps carry exact sizes; assembler symbol files (wla-dx, asar) carry only\naddresses, so their sizes are inferred (see below).\n\nThe repository provides two command-line scripts:\n\n- `rommap.py` creates a physical-bank ROM treemap.\n- `rammap.py` creates an address-preserving WRAM overview with low-WRAM and\n  direct-page zooms.\n\nBoth are thin entry points to `snesmap.py`, the shared engine that does the map\nparsing, layout, and rendering; they simply preset ROM or RAM mode. Keeping one\nengine means the ~95% of logic the two maps share lives in a single place, while\nyou still get the two commands you'd expect. (`snesmap.py` is not meant to be run\ndirectly.)\n\nAll three use only the Python 3 standard library. Their SVG output supports\nlight and dark colour schemes, browser zooming, and per-allocation tooltips.\n\n## Examples\n\n### ROM\n\n![Example SNES ROM map](examples/rommap.svg)\n\n### RAM\n\n![Example SNES RAM map](examples/rammap.svg)\n\n## Quick start\n\nRun the scripts from the directory containing your linker script:\n\n```sh\npython3 /path/to/rommap.py build/game.map \\\n  --linker-script game.ld \\\n  -o build/rommap\n\npython3 /path/to/rammap.py build/game.map \\\n  -o build/rammap\n```\n\nEach command writes an SVG by default:\n\n```text\nbuild/rommap.svg\nbuild/rammap.svg\n```\n\nPass `--csv` to also write the machine-readable CSV (`build/rommap.csv`,\n`build/rammap.csv`).\n\nThe format is auto-detected. Override detection with `--format`, one of `lld`,\n`vlink`, `ca65`, `wla`, or `asar`.\n\n## ROM map\n\nThe ROM map displays sixteen physical 32 KiB banks in SNES reading order. Bank\nheaders show allocated bytes and a right-aligned percentage. Symbol rectangles\nare proportional within each bank; transparent rectangles are free space.\n\nFor llvm-mos/ld.lld builds, ROM region names, origins, and capacities come from\nthe linker script's `MEMORY` block. Regions below `$00:8000` and WRAM banks\n`$7E/$7F` are excluded.\n\nThe RAM script derives its fixed WRAM ranges directly and does not require a\nlinker script.\n\nThe existing `rom_bank_fixed` convention is recognised: its contents are shown\nin every `code_bank_*` physical bank. Other linker-region names have no special\nmeaning.\n\n## RAM map\n\nThe RAM map separates static linker allocation from runtime usage:\n\n- A true-scale overview displays the full 128 KiB WRAM.\n- A magnified panel displays `$7E:0100–1FFF`.\n- A second magnified panel displays the default direct page,\n  `$7E:0000–00FF` with `D=$0000`.\n- Allocation order and address gaps are preserved.\n\nRAM colours identify initialized `.data`, zero-filled `.bss`, `.noinit`,\nhardware stack reservation, compiler direct-page registers, and other\nallocations. Unallocated space is transparent by default.\n\nWhen present in an ld.lld map, `__rcN` and `__stack` linker symbols are used to\naccount for compiler direct-page registers and the page-$01 hardware stack.\nDynamic stack and heap high-water usage cannot be inferred from a static linker\nmap.\n\n## Display options\n\nOptions apply independently to either script:\n\n```sh\n--checkerboard\n--colour-key                 # alias: --color-key\n--coloured-percentages       # alias: --colored-percentages\n```\n\n- `--checkerboard` uses a Photoshop-style pattern for free space.\n- `--colour-key` adds the colour legend.\n- `--coloured-percentages` shows 75–89.9% in amber and 90%+ in red.\n\nAll three are off by default.\n\nUse `--compiler \"toolchain name\"` to override the compiler/linker label embedded\nin the SVG footer.\n\nUse `--delimiter` to change the field separator used throughout the SVG — headers,\ntooltips, captions, and the footer (e.g. `$00 / 31,333 B / 95.6% full`). It is\nspace-padded, and the default is a bullet (`·`), e.g. `--delimiter \"/\"`.\n\n## Supported linker maps\n\n- llvm-mos/ld.lld map output, with ROM regions read from a GNU-style `MEMORY`\n  block.\n- vbcc65816/vlink section mappings.\n- vlink LoROM, plus the vlink HiROM address projection used by `vlink-hi`.\n- cc65 ca65/ld65: the `ld65 --mapfile` **Segment list** for exact per-segment\n  sizes. Optionally pass your cc65 linker config (the same `.cfg` you build with,\n  `cl65 -C` / `ld65 -C`) as `--linker-script` to name the ROM regions; without it\n  the map falls back to physical banks.\n- wla-dx / asar symbol files (`wlalink` `.sym`, `asar --symbols=wla|nocash`):\n  label→address only, so LoROM physical banks are assumed and sizes are\n  **inferred** from label gaps (the last label in a bank runs to the bank end).\n  Trailing free space inside a bank is therefore invisible; the footer marks\n  these maps `(approx sizes)`.\n\nSee [docs/linker-map-support.md](docs/linker-map-support.md) for assumptions and\nknown limitations.\n\n## Development\n\nRun the test suite:\n\n```sh\npython3 -m unittest discover -s tests -v\n```\n\nThe tests invoke both scripts against small checked-in fixtures for each\nsupported format (ld.lld, vlink, ca65/ld65, wla-dx, and asar) and validate their\nCSV and SVG output.\n\n## Acknowledgements\n\nThe physical-bank ROM view was inspired by Pin Eight's\n[Homebrew ROM maps and treemaps](https://pineight.com/retrotainment/home_treemaps.html).\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgingerbeardman%2Fsnes-memory-maps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgingerbeardman%2Fsnes-memory-maps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgingerbeardman%2Fsnes-memory-maps/lists"}