diff --git a/.gitignore b/.gitignore index 81fdeba6..36fbca2f 100755 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ templates *.exe /public/generated/placeholders/*.svg _site.backup/ +*/__pycache__/* diff --git a/codex/skills/retroreversing-contributing/SKILL.md b/codex/skills/retroreversing-contributing/SKILL.md new file mode 100644 index 00000000..95bcaa23 --- /dev/null +++ b/codex/skills/retroreversing-contributing/SKILL.md @@ -0,0 +1,73 @@ +## RetroReversing Contributing (Repo Skill) +Use this skill whenever you create or edit content in the `retroReversing` repo (Markdown pages/posts, `_includes`, or related site content). The goal is to keep changes consistent with `CONTRIBUTING.md`. + +### Non-negotiables +* Target audience is technical: assume programming literacy, don't assume reverse-engineering literacy. +* Prefer linking to high-quality sources over duplicating other sites' content; still provide a short summary so the page reads coherently without clicking out. +* Reference sources for technical claims and dates; Wikipedia only as a last resort. + +### Workflow (content edits) +1) Decide fit: does this belong on RetroReversing (retro game dev + reverse engineering / digital archaeology; ~1980–2015)? +2) Choose location + frontmatter: + * Follow the "standard shape" from `CONTRIBUTING.md` (use modern minimal frontmatter; don't clone old pages blindly). + * `title` must not contain colons. + * `permalink` must not end with a trailing `/`. + * `tags`/`recommend` values must be valid and used appropriately (`recommend` can be omitted and will fall back to `tags`). +3) Write like a technical handbook (not a blog post): + * Short paragraphs, short sentences, encourage hands-on experimentation. + * Present terminology first, then explain/justify. + * Sections should be readable non-linearly (don't rely on strict reading order). +4) Apply Markdown/structure rules: + * Don't bold headings; don't put emojis or backticks in headings. + * Use `---` before major section jumps, and when jumping back up the heading hierarchy. + * No blank line between `---` and the next heading. + * No blank line between a heading and its first paragraph. + * Lists: never use numbered lists; use `*` bullets; always introduce a list with a sentence ending in `:`, with no blank line before the list. + * Tables: always introduce with a sentence; keep formatting compact (no padded spacing; don't start rows with `|`). + * Table of contents: don't write your own; the site generates it at runtime from headings. +5) Character hygiene: + * Use straight quotes (`"`), not smart quotes (`“`). + * Use `-` hyphen, not em dashes (`—`). + * Avoid non-standard keyboard characters. +6) Glossaries (when acronym-heavy): + * Add a glossary near the top. + * Add explicit anchors like `` so in-page links are stable. + * Link the first meaningful mention per section, not every occurrence. +7) Links and references: + * Use footnotes for citations under an H1 `# References` at the end. + * If a footnote is at sentence end: put it before the period (`text [^1].`). + * For external "standalone" links (own paragraph/line), use the include: + * `link-to-other-site.html` with `title`, `url`, `description`. + * For links to other RetroReversing pages, prefer: + * `{% raw %}{% include_cached link-to-other-post.html post="/permalink" %}{% endraw %}` +8) Code examples: + * Use TypeScript when it's runnable interactively in-browser; otherwise use Python for local scripts. + * Use fenced code blocks with a language tag; use `nasm` for assembly highlighting. + * Mermaid diagrams: use sparingly; keep labels short; bold the first line in nodes when there's a title + explanation. + +### Preferred Site Components (use instead of ad-hoc HTML) +* External "standalone" link blocks: `link-to-other-site.html`. +* Internal links to RetroReversing pages: `link-to-other-post.html` via `{% raw %}{% include_cached ... %}{% endraw %}`. +* Folder listings / nested trees: `connected-folder-tree.html` rather than raw HTML or bullet dumps. +* Source-file callouts: `source-code-card.html` / `source-code-card-grid.html` when actually showing real file contents/symbols. + * The `functions`, `variables`, and `lines` fields must be exact numeric counts from the file. + * Omit the card if you can't provide exact counts yet. +* Tabs: prefer the `rr-tabs` pattern shown in `CONTRIBUTING.md` when comparing variants (e.g., C vs ASM). + +### Images +* Prefer linking externally hosted box-art (e.g. MobyGames) for "section about a specific game" figures when appropriate. +* Lazy loading: use `` (optionally with a placeholder `src`). +* Lightbox: images with `postImage` are auto-wrapped; for custom galleries, wrap in ``. + +### Visual readability helpers +* Emoji callout under heading (not in the heading): add `
...
` on the line after the heading. + +### Workflow (_includes edits) +* Prefer Liquid comments (`{% comment %}...{% endcomment %}`) over HTML comments to avoid shipping docs into generated pages. + +### Spelling +* Use cspell blocks when needed: + * `` / `` + +### Reminder +* `CONTRIBUTING.md` is the source of truth for edge-cases and newer patterns; consult it if unsure. diff --git a/pages/consoles/gameboy/Mrdo.md b/pages/consoles/gameboy/Mrdo.md index 2124ed74..d65b90d3 100644 --- a/pages/consoles/gameboy/Mrdo.md +++ b/pages/consoles/gameboy/Mrdo.md @@ -5,8 +5,9 @@ tags: - games - sourcecode title: Mr Do! Source Code (Game Boy) -category: gameboy -youtube: "qLtNkZ1GHh0" +category: +- gameboy +- sourcecode image: /public/games/MrDoGameboy.jpg permalink: /mrdo breadcrumbs: @@ -16,10 +17,8 @@ breadcrumbs: url: /gameboy - name: Mr Do! Source Code (Game Boy) url: # -recommend: -- gameboy editlink: /consoles/gameboy/Mrdo.md -updatedAt: '2026-04-14' +updatedAt: '2026-04-19' --- # Introduction @@ -76,6 +75,8 @@ If you are new to Game Boy reverse engineering terminology, this quick glossary *
**VRAM** - Video RAM (`$8000-$9FFF`) containing tile graphics and background/window tilemaps [^3]. * **WRAM** - Work RAM (`$C000-$DFFF`) used for variables, buffers, and scratch space [^3]. * **HRAM** - High RAM (`$FF80-$FFFE`) used here to run short routines (including the DMA trigger) without being blocked during OAM DMA [^3]. +* **MBC1** - A Game Boy cartridge mapper that enables ROM bank switching (writes to `$2000-$3FFF` select the active `ROMX` bank) [^3]. +* **ROM0 / ROMX** - The fixed 16 KiB window at `$0000-$3FFF` (ROM0) and the switchable 16 KiB window at `$4000-$7FFF` (ROMX) [^3]. --- # Code overview @@ -911,15 +912,11 @@ We have written a best-effort converter that keeps the original `mrdo.asm` untou What it does: * converts `EQU`/`DEFB`/`DEFW`/`DEFS`, turns `HEX` into `db $..`, and maps each `ORG` to an explicit `SECTION`. * **Heuristic bank split** - The converter includes a pragmatic split so the output links as a simple ROM-only build: `ORG $800` becomes fixed ROMX bank 1 code, and the `SCENE1`+ data block is placed back into ROM0 at `$0800`. -* **Retail-style profile** - The converter also supports a `--profile retail-mbc1` mode that attempts to produce a 64 KiB `MBC1`-style image by placing a handful of large asset blocks into banks that match signature hits in the retail ROM. * **Main limitation** - The original toolchain could pre-initialize RAM, but RGBDS cannot, so WRAM/HRAM sections in the output are primarily for symbol addresses (you still need real init/copy code for a working rebuild). * **Interrupt vector stubs** - The converter injects `reti` stubs at `$0040/$0048/$0050/$0058/$0060` because the release enables interrupts (`IE=1` then `EI`) but does not define handlers in the vector table. Without this, a rebuild will often crash or "flash" as soon as VBlank fires [^3]. One thing to keep in mind is that this converted build is not trying to match the retail ROM layout. -The retail Mr Do! ROM is a banked `MBC1` cartridge and is effectively a 64 KiB-class image (4 x 16 KiB banks), while the current converter is set up to link a minimal 2-bank layout so you can explore the code paths quickly. -To produce a ROM image that matches retail size and banking, you will need to: -* split the file into multiple `ROMX` banks (and use a MBC header / `rgbfix` flags that match the chosen banking model) and -* reconcile which content belongs in which bank by comparing against a known-good retail ROM (checksums + bank contents). +The retail Mr Do! ROM is a banked `MBC1` cartridge and is effectively a 64 KiB-class image (4 x 16 KiB banks), while the direct conversion build is a minimal 32 KiB `ROM ONLY` image so you can explore code and data quickly. ### Installing RGBDS @@ -928,7 +925,7 @@ If you want to run the `rgbasm`/`rgblink` sanity-check commands locally, install * **Linux** - Install via your distro package manager, or use the official release tarball + `install.sh` [^9]. * **Windows** - Use WSL and follow the Linux instructions, or use the official `.zip` release and add it to your `PATH` [^10]. -To generate a converted file: +To generate a converted file we have a script [convert-mrdo-to-rgbds.py](https://gist.github.com/RetroGameDeveloper/bfecf7c09eea56398f4bc66d25d4d5ee#file-convert-mrdo-to-rgbds-py): ```bash python3 scripts/convert-mrdo-to-rgbds.py mrdo.asm build/mrdo.rgbds.asm ``` @@ -948,88 +945,65 @@ It supports three useful comparisons: * **Coverage scan** - a fast sliding-window scan that estimates how much of the rebuilt ROM appears verbatim in the retail ROM (useful for data/graphics blocks that should match exactly). * **Signature search from a map** - take a `rgblink -m` map from the rebuilt ROM and search for `N`-byte sequences inside the retail ROM to find where specific labels land. -For a retail-like 64 KiB build attempt: -```bash -python3 scripts/convert-mrdo-to-rgbds.py mrdo.asm build/mrdo.retail.rgbds.asm --profile retail-mbc1 -rgbasm -o build/mrdo.retail.o build/mrdo.retail.rgbds.asm -rgblink -m build/mrdo.retail.map -n build/mrdo.retail.sym -o build/mrdo.retail.gb build/mrdo.retail.o -rgbfix -v -p 0xFF -m MBC1 -t "MR.DO!" build/mrdo.retail.gb -``` - -Then compare it against your retail ROM: +Then compare the direct conversion build against your retail ROM: ```bash python3 scripts/compare-gb-roms.py \ - --rebuilt build/mrdo.retail.gb \ + --rebuilt build/mrdo.gb \ --original build/mrdo_original.gb \ - --map build/mrdo.retail.map \ + --map build/mrdo.map \ --scan-map \ - --sig-len 128 \ + --sig-len 32 \ --window 256 \ --strings ``` --- #### Current repo comparison results -This repository already includes a known-good retail ROM at `build/mrdo_original.gb`, plus two rebuild outputs (`build/mrdo.gb` and `build/mrdo.retail.gb`). -As of `2026-04-12`, the headline results are: +This repository already includes a known-good retail ROM at `build/mrdo_original.gb`, plus the direct conversion build at `build/mrdo.gb`. +As of `2026-04-19`, the headline results are: ROM | Size | Title | Cart type | SHA256 ---|---|---|---|--- `build/mrdo_original.gb` | 64 KiB | `MR.DO!` | `MBC1` | `c19f7ec9ff29fa438d7ef189f81711dcaedaa55c86b192d6d9020f5f7dc22702` -`build/mrdo.retail.gb` | 64 KiB | `MR.DO!` | `MBC1` | `d6e4a52072e4c6d4d1a34bd126617ce4340150cd351ddeafdcc7d842bbb6e4f3` `build/mrdo.gb` | 32 KiB | `MRDO!` | `ROM ONLY` | `bb824ead872abaf5055be48c42c01873bbda749afb400353682bea9bfc565fda` -Both 64 KiB images use the same visible header identity (title `MR.DO!`, cartridge type `MBC1`, ROM size code `0x01`). -However, neither rebuilt image matches the retail binary byte-for-byte: -* **No exact bank matches** - none of the 16 KiB banks in `build/mrdo.retail.gb` are identical to any bank in `build/mrdo_original.gb`. -* **High verbatim data coverage** - a 256-byte sliding window scan finds `49600/65536` bytes (75.7%) from `build/mrdo.retail.gb` somewhere in the retail ROM. -* **Explore build coverage is lower** - the ROM-only explore build (`build/mrdo.gb`) still finds `17024/32768` bytes (52.0%) somewhere in the retail ROM, which is a useful sanity check that many assets are shared even when the overall layout differs. +The direct conversion build does not match the retail binary byte-for-byte (it is a different size and layout), but it still contains many verbatim data/code blocks: +* **Window coverage** - at a 256-byte window size, `17024/32768` bytes (52.0%) from `build/mrdo.gb` appear verbatim somewhere in the retail ROM. +* **Offset equality is low** - only `1731/32768` bytes (5.28%) are identical at the same file offsets because the retail image is banked and laid out differently. * **Different build lineage strings** - text like `"CLONE"` / `"TWINS"` / `"REMIX"` appears in the source-derived builds but does not appear in the retail ROM, which is a quick way to confirm you are not comparing a simple re-link. -If you use `--scan-map` with a longer signature length (128 bytes), you do start getting "anchor" hits for a handful of large `HEX` blocks and assets. -These are useful when tightening the bank-placement heuristic for a more retail-like layout: - -Symbol | Rebuilt bank:addr | Retail hit bank:addr ----|---|--- -`CBADS` | `bank3:$4C00` | `bank1:4C00`, `bank3:4C00` -`CHEADS` | `bank2:$4D60` | `bank2:4D60` -`CHRTABLE` | `bank0:$0400` | `bank0:0400` -`CICONS` | `bank2:$4B20` | `bank2:4B20` -`CLOGO` | `bank2:$4080` | `bank2:4080` -`CMRDO` | `bank3:$4000` | `bank3:4000` -`CMRSDO` | `bank3:$4300` | `bank3:4300` -`CSTAR` | `bank2:$47F0` | `bank2:47F0` -`LOGO` | `bank0:$0E3B` | `bank0:0E3B` - -These numbers can look contradictory at first glance (for example: a symbol can have a 128-byte signature hit, while still sitting inside a "no 256-byte window match" region). -That is simply an artifact of the window size: 128-byte runs can match without any 256-byte run matching. - --- -#### Header-level differences -The retail ROM's banking/layout is not described by the header block embedded in the released `mrdo.asm`. -For example, the source's `ORG $100` header declares `ROM ONLY` and a ROM size code of `0`, while the retail ROM is a 64 KiB `MBC1` image. +#### Build completeness sanity check +Because the direct conversion output is only 32 KiB, it is reasonable to ask whether code went missing during conversion/linking. +To make that question testable, we have a small audit script: +[audit-mrdo-build-completeness.py](https://gist.github.com/RetroGameDeveloper/bfecf7c09eea56398f4bc66d25d4d5ee#file-audit-mrdo-build-completeness-py) -In this repository, the retail-style converter can splice the exact `$0100-$014F` header bytes from `build/mrdo_original.gb` into the rebuilt image so the header matches retail byte-for-byte. -This is useful for isolating layout and bank-placement differences from header/metadata differences. -If you run `rgbfix -v` afterwards, RGBDS will recalculate and overwrite the checksum fields (`$014D` and `$014E-$014F`), so the rebuilt header will no longer be byte-identical to retail even if the title/logo fields match. +```bash +python3 scripts/audit-mrdo-build-completeness.py +``` + +At the moment, it reports: +* every ROM-side "procedure-style" label from the released source snapshot is present in `build/mrdo.map`. +* none of those labels were accidentally assembled into a RAM region (they all land in `ROM0` or `ROMX`). --- -#### Offset-aligned similarity vs relocated similarity -There are two different "closeness" metrics that are both useful: -* **Offset-aligned equality** - how many bytes are identical at the same file offsets. -* **Window coverage** - how much of the rebuild appears verbatim *somewhere* in the retail ROM, even if it moved. +#### Retail bank switching hotspots +The direct conversion build is a `ROM ONLY` image and does not contain any cartridge bank switch writes. +The retail ROM does, and you can locate the most obvious sites by scanning for `LD (a16),A` stores into the `0x2000-0x3FFF` mapper register range: -For the current retail-style rebuild, only `16278/65536` bytes (24.8%) are identical at the same offsets, because large blocks have moved between banks and within banks. -By contrast, the 256-byte window coverage scan finds 75.7% of rebuilt bytes occurring verbatim somewhere in retail (and 77.9% at a 128-byte window). +```bash +python3 scripts/scan-gb-mbc1-bankswitch-sites.py --rom build/mrdo_original.gb --markdown --max 30 +``` -Per-bank offset-aligned equality looks like this: +In the current retail ROM, the most common pattern is `ld a,imm; ld [$2004],a` (still inside the standard MBC1 ROM bank select range). +That gives you a concrete place to start debugging retail-only behaviour: +* set a write watchpoint on `$2004` and log which bank numbers are selected before/after big asset loads, menu code, or level setup. +* compare those call sites against the direct conversion build (which never switches banks) to identify code/data that only exists in banked form in retail. -Bank | Equal bytes at same offsets | Notes ----|---|--- -bank0 | `1496/16384` (9.1%) | Header is identical, but ROM0 tables are still in flux -bank1 | `1080/16384` (6.6%) | Bank 1 still differs heavily (code + tables) -bank2 | `5560/16384` (33.9%) | Many assets line up at the same offsets -bank3 | `8142/16384` (49.7%) | Largest "same-offset" overlap in this build +--- +#### Header-level differences +The retail ROM's banking/layout is not described by the header block embedded in the released `mrdo.asm`. +For example, the source's `ORG $100` header declares `ROM ONLY` and a ROM size code of `0`, while the retail ROM is a 64 KiB `MBC1` image. --- #### Why the banking/layout differs @@ -1057,13 +1031,17 @@ Treat the `ORG $100` header block in `mrdo.asm` as "what this particular source --- #### What is in the "no 256-byte match" regions -The 256-byte window scan flags a few large regions where **no 256-byte chunk** matches anywhere in the retail ROM. -To make those regions actionable, here are the notable map labels that live inside them: - -* `bank1:4000..bank1:56DE` - tables + core code, including `DMATRANS`, `SYSETUP`, and `START`. -* `bank2:4EC0..bank2:56FF` - large graphics blocks `CBIGMRDO` and `CBIGAPPLES`. -* `bank3:4C00..bank3:609F` - a large asset + menu cluster starting at `CBADS`, plus `MENU`/`SLOGO`/`OPTIONS` and friends. -* `bank0:0000..bank0:03FF` - boot/interrupt-area differences (the converter emits minimal `reti` stubs rather than retail handlers). +The 256-byte window scan flags a few large regions where **no 256-byte chunk** from the direct conversion build appears anywhere in the retail ROM. +Those regions are interesting because they are strong candidates for: +* toolchain-generated tables that never existed in the source snapshot, +* later bugfix/content additions, +* code/data that is present in the released source but gets rearranged enough that 256-byte windows no longer line up. + +In the current `build/mrdo_original.gb` vs `build/mrdo.gb` comparison, the largest retail-only regions (window=256) start at: +* `bank1:4600..bank1:7FFF` - text/tables-heavy region. +* `bank0:0608..bank0:3FFF` - a large ROM0 region with many strings/tables. +* `bank2:4EC0..bank2:7FFF` - a large bank 2 region. +* `bank3:4600..bank3:6FFF` - a large bank 3 region. If you see: * **No exact bank matches** - that is normal when the layout does not match byte-for-byte. @@ -1073,312 +1051,316 @@ If you see: --- ### Rebuilt procedure map This table lists every procedure-style label detected in the converted RGBDS output, along with its rebuilt `bank:addr` location, so you can set breakpoints quickly: -The retail columns are intentionally conservative and are only filled when a 32-byte signature from that label matches verbatim at a single location inside `build/mrdo_original.gb`. +The retail columns are best-effort and are only filled when the mapper script can place the routine at a single retail offset using byte-signature matching against `build/mrdo_original.gb`. +The `Retail match` column gives a rough confidence level: +* `entry` - the routine entrypoint bytes match retail (high confidence). +* `in-body` - the entrypoint is inferred from multiple in-body signature matches (use as a hint, not proof). +* `unverified` - the row was previously filled but could not be re-verified by the current mapper settings. -Procedure | Rebuilt bank:addr | Retail bank:addr | Retail file offset ----|---|---|--- -`MULTIE` | `00:06A4` | | -`MULTID` | `00:06A9` | | -`MENU` | `00:363C` | | -`SLOGO` | `00:3661` | | -`RESETST` | `00:366F` | | -`LOGOLOOP` | `00:3699` | | -`WORKMENU` | `00:36B5` | | -`EXITMENU` | `00:36D6` | | -`OPTIONS` | `00:36E2` | | -`NEXTUP` | `00:36FD` | | -`NEXTMENU` | `00:3702` | | -`NOGAME` | `00:370A` | | -`NEWSEL` | `00:3715` | | -`NOSEL` | `00:3723` | | -`UPMENU` | `00:3732` | | -`HANDYMAN` | `00:3743` | | -`SOUNDOPT` | `00:375D` | | -`DWMENU` | `00:3765` | | -`LOGOPULSE` | `00:377B` | | -`FADE` | `00:37D0` | | -`LOGOON` | `00:37E0` | | -`LOGON` | `00:37EB` | | -`NOMOV` | `00:37FE` | | -`BARREL` | `00:3803` | | -`BARON` | `00:3810` | | -`RASTARS` | `00:3823` | | -`RASTAR` | `00:3832` | | -`STARFALL` | `00:3845` | | -`ANIHEAD` | `00:3872` | | -`MENUOBJ` | `00:3894` | | -`WORKSTAR` | `00:38AC` | | -`STAROFF` | `00:38B7` | | -`NOBOW` | `00:38E4` | | -`DUMP3BY3` | `00:38F8` | | -`SHOWRESULTS` | `00:395F` | | -`SETBIG` | `00:3989` | | -`RESLOOP` | `00:39B5` | | -`APLM` | `00:39CE` | | -`WORKWELL` | `00:3A1A` | | -`EMOVE` | `00:3A30` | | -`UPWELLY` | `00:3A3A` | | -`UPWELL` | `00:3A3F` | | -`ALLWAIT` | `00:3A47` | | -`ALLMOVE` | `00:3A51` | | -`DODIMOVE` | `00:3A58` | | -`DUMPBIG` | `00:3A7E` | | -`DUMPBG` | `00:3A93` | | -`SHOWAVERAGES` | `00:3AA2` | | -`PUTAVER` | `00:3ABF` | | -`AVELOOP` | `00:3B10` | | -`RESETBOARD` | `00:3B29` | | -`RESETB` | `00:3B2E` | | -`BOARDLINED` | `00:3B41` | | -`BOARDLINE` | `00:3B61` | | -`PUTSCORE` | `00:3B73` | | -`TOTOTAL` | `00:3B9C` | | -`UPTOTAL` | `00:3BA1` | | -`DIGITADD` | `00:3BA6` | | -`DUMPENDOBJ` | `00:3BB8` | `00:35F6` | `0x35F6` -`DUMP2BY2SEQU` | `00:3BBD` | `00:35FB` | `0x35FB` -`CHECKHIGH` | `00:3BE9` | | -`CHECKLINE` | `00:3BEE` | | -`CHECKCHR` | `00:3BF4` | | -`NEXTLINE` | `00:3BFF` | | -`ISBIG` | `00:3C08` | | -`SHUNTLINE` | `00:3C11` | | -`PUTDIG` | `00:3C20` | | -`PRHIGHSCORES` | `00:3C39` | | -`PRHIGHS` | `00:3C41` | | -`PRHGH` | `00:3C85` | | -`DMATRANS` | `01:40E9` | | -`DMAL` | `01:40EF` | | -`SYSETUP` | `01:40F4` | | -`RESETV` | `01:4101` | | -`TOINTRAM` | `01:4114` | | -`GAMESETUP` | `01:4122` | | -`LEVELSETUP` | `01:4141` | | -`ISMISTER` | `01:4165` | | -`RESETSP` | `01:4198` | | -`SETAPPLES` | `01:41AB` | | -`RESETEX` | `01:41BD` | | -`SETET` | `01:420E` | | -`START` | `01:4219` | | -`MAINLOOP` | `01:4228` | | -`EXITLEVEL` | `01:426A` | | -`NOMAPR` | `01:4288` | | -`NOLEVR` | `01:42A4` | | -`WAITISH` | `01:42AA` | | -`WINHOW` | `01:42B2` | | -`EXTRALIFE` | `01:42BE` | | -`SETEXTRA` | `01:42C8` | | -`RESETET` | `01:42D3` | | -`PAUSEGAME` | `01:42DE` | | -`NOSTRT` | `01:42F3` | | -`WAITNOK` | `01:4303` | | -`SPLITSCREEN` | `01:430A` | | -`PRAPPLES` | `01:434C` | | -`PRALOOP` | `01:4352` | | -`APPLEPIE` | `01:437F` | | -`APLOOP` | `01:4388` | | -`WORKAPPLE` | `01:439A` | | -`NOAPPLE` | `01:43AD` | | -`NOLFALL` | `01:43B0` | | -`GOSPLIT` | `01:43B2` | | -`APPLEWAIT` | `01:43BA` | | -`APPLEJIG` | `01:43D5` | | -`APPLEFALL` | `01:43E4` | | -`LEEV0` | `01:4419` | | -`LEEV1` | `01:442B` | | -`FLOUT` | `01:442D` | | -`HLOUT` | `01:443E` | | -`REPBACK` | `01:4440` | | -`STOPAFALL` | `01:444B` | | -`APPLESPLIT` | `01:4455` | | -`NOASPL` | `01:4461` | | -`LEEV2` | `01:4493` | | -`LEEV3` | `01:44A5` | | -`BRINGON` | `01:44BE` | | -`GETDINO` | `01:44D2` | | -`GETSP` | `01:44D8` | | -`GETAPPLE` | `01:44E3` | | -`GETAP` | `01:44E9` | `00:1BE4` | `0x1BE4` -`FLAGS` | `01:44F4` | `00:1BEF` | `0x1BEF` -`NOT3` | `01:451B` | | -`COLLISIONS` | `01:451F` | | -`BALLCP` | `01:4522` | | -`BALLCPL` | `01:4535` | | -`NBALLCP` | `01:4551` | | -`MRDOCATCH` | `01:455A` | | -`GHOSTDIE` | `01:4563` | | -`NOTLASTG` | `01:4574` | | -`EXDIE` | `01:4582` | | -`GAPPLE` | `01:45D6` | | -`GOAPPLE` | `01:45DF` | | -`GOBALLBANG` | `01:45FE` | | -`BALLSCORE` | `01:4606` | | -`DUFKILL` | `01:462B` | | -`EATCHERRY` | `01:462D` | | -`NOCHSEQU` | `01:4651` | | -`RESCHSEQU` | `01:4656` | | -`EATWALL` | `01:4668` | | -`EATFOOD` | `01:4675` | | -`GETLET` | `01:46A0` | | -`GOTLET` | `01:46AB` | | -`ISOUT` | `01:46D1` | | -`PUTGHST` | `01:46D8` | | -`SETGHST` | `01:46E1` | | -`DECODE` | `01:46F5` | | -`NOGODEL` | `01:4700` | | -`NODECBON` | `01:470A` | | -`DECODER` | `01:4734` | | -`ISSLOW` | `01:4749` | | -`NOSLOW` | `01:4751` | | -`INVALIDX` | `01:4776` | | -`NEWMOVE` | `01:4790` | | -`NOWRAP` | `01:479D` | | -`NOSCROLL` | `01:47C4` | | -`INVALID` | `01:47DD` | | -`DOBALL` | `01:47E7` | | -`BADDIES` | `01:480E` | | -`BADLOOP` | `01:4813` | | -`WORKBADDIE` | `01:4835` | | -`NOBAD` | `01:4847` | | -`CIRCLE` | `01:484C` | `00:216A` | `0x216A` -`MOVEBADF` | `01:4876` | | -`MOVEBAD` | `01:487B` | | -`FINDEXITS` | `01:4889` | | -`NOUP` | `01:48A4` | | -`NORT` | `01:48B0` | | -`NODW` | `01:48C7` | | -`NOLF` | `01:48D3` | | -`WORKEXITS` | `01:48D6` | | -`CHANGEDIR` | `01:48EA` | | -`FINDEX` | `01:48F4` | | -`GOEXIT` | `01:4902` | | -`DINODE` | `01:4907` | | -`DINO` | `01:4909` | | -`DINOMOVE` | `01:491A` | | -`DINOEAT` | `01:492A` | | -`DINOPUSH` | `01:492C` | | -`EXDANCE` | `01:492E` | | -`NOEXFL` | `01:4941` | | -`UPTYPE` | `01:4973` | | -`EXUP` | `01:4979` | | -`EXEAT` | `01:4985` | | -`EXWALK` | `01:4987` | | -`EXMOVE` | `01:4998` | | -`EXOUT` | `01:49A1` | | -`GHOST` | `01:49A3` | | -`GHOSTMOVE` | `01:49B4` | | -`GHOSTR` | `01:49C0` | | -`GHOSTEAT` | `01:49C7` | | -`CARRYBALL` | `01:49C9` | | -`THROWBALL` | `01:49EE` | | -`CDEL0` | `01:49F8` | | -`ISCHN` | `01:4A06` | | -`NOCHWL` | `01:4A16` | | -`BCHECK` | `01:4A24` | | -`NRNDB` | `01:4A3A` | | -`NOBHIT` | `01:4A3D` | | -`NOCHN` | `01:4A41` | | -`OUTBALL` | `01:4A50` | | -`GOINBALL` | `01:4A7D` | | -`INBALL` | `01:4A87` | | -`INBALL0` | `01:4A91` | | -`INBALL1` | `01:4A9B` | | -`POINTS` | `01:4AC3` | | -`DUMPOBJ` | `01:4ACF` | | -`MPLEX` | `01:4AEE` | | -`DUMPL` | `01:4B14` | | -`DUMP2BY1` | `01:4B29` | `00:283A` | `0x283A` -`DUMP1BY1` | `01:4B4F` | | -`DUMP2BY2` | `01:4B73` | `00:2884` | `0x2884` -`DUMP2BY2S` | `01:4B86` | `00:2897` | `0x2897` -`MRDOCHEW` | `01:4BCA` | | -`GOCHEW` | `01:4BE1` | | -`CHEWS` | `01:4BF2` | | -`CHEWUP` | `01:4C14` | | -`CHU0` | `01:4C21` | | -`CHU1` | `01:4C32` | | -`CHU2` | `01:4C49` | | -`CHU3` | `01:4C5A` | | -`CHEWRT` | `01:4C61` | | -`CHR0` | `01:4C6E` | | -`CHR1` | `01:4C7F` | | -`CHR2` | `01:4C96` | | -`CHR3` | `01:4CA7` | | -`CHEWDW` | `01:4CAE` | | -`CHD0` | `01:4CBB` | | -`CHD1` | `01:4CCC` | | -`CHD2` | `01:4CE3` | | -`CHD3` | `01:4CF4` | | -`CHEWLT` | `01:4CFB` | | -`CHL0` | `01:4D0A` | | -`CHL1` | `01:4D1B` | | -`CHL2` | `01:4D32` | | -`CHL3` | `01:4D43` | | -`CHRDUMPER` | `01:4D4A` | | -`CDUMP` | `01:4D59` | | -`PRSCORE` | `01:4D64` | | -`SCOREADD` | `01:4D81` | | -`UPSCORE` | `01:4D97` | | -`NOSCRP` | `01:4DA3` | | -`CLOCK` | `01:4DA5` | | -`UPCLOCK` | `01:4DC0` | | -`STATUS` | `01:4DC5` | | -`STATSP` | `01:4DDE` | | -`PUTSSP` | `01:4DF4` | | -`ONSTAT` | `01:4E1A` | | -`DRAWMAP` | `01:4E22` | | -`FILLMAP` | `01:4E28` | | -`FILLBYTE` | `01:4E3F` | | -`PUTFOOD` | `01:4E76` | | -`DRAWBLOCK` | `01:4E91` | | -`DRWBLOCK` | `01:4EA1` | | -`DOTUNNEL` | `01:4EB9` | | -`DRAWREP` | `01:4ED2` | | -`ENDTUNNEL` | `01:4EE6` | | -`PUTCHERRY` | `01:4EEF` | | -`PUTAPPLE` | `01:4F1F` | | -`COPYMAP` | `01:4F41` | | -`COPYM` | `01:4F4A` | | -`COPYLETTER` | `01:4F53` | | -`PUTLINE` | `01:4F80` | `00:2CFB` | `0x2CFB` -`KEYS` | `01:4FB6` | | -`PIXAD` | `01:4FED` | `00:2D63` | `0x2D63` -`GETMAPHI` | `01:5004` | | -`GETMAPLODE` | `01:501B` | | -`GETMAPLO` | `01:502D` | | -`GETBYTEHI` | `01:503F` | `00:2DCC` | `0x2DCC` -`GETBYTELO` | `01:504D` | | -`LOWAD` | `01:5059` | | -`WAITSC` | `01:5070` | | -`RESETOBJ` | `01:5078` | | -`RESETOB` | `01:5087` | | -`RESETO` | `01:508B` | | -`RAND` | `01:5097` | | -`PRINTEXT` | `01:50B1` | `00:2E45` | `0x2E45` -`TEXTL` | `01:50B9` | `00:2E4D` | `0x2E4D` -`PRINTSHAPE` | `01:50C1` | | -`YROWS` | `01:50C5` | | -`XROWS` | `01:50C7` | | -`DIVIDE` | `01:50DA` | | -`DIVE` | `01:50DE` | | -`CREATESET` | `01:50E6` | | -`CLEARSET` | `01:50FB` | | -`SHUNT` | `01:5106` | | -`DISPBIN` | `01:510F` | | -`DOBIN` | `01:5114` | `00:2EDA` | `0x2EDA` -`ISNONE` | `01:511B` | `00:2EE1` | `0x2EE1` -`CLEARSTAT` | `01:5120` | `00:2EE6` | `0x2EE6` -`CLR` | `01:512B` | | -`HEXBYTE` | `01:5134` | | -`HEXWORD` | `01:5139` | | -`PRHEX` | `01:5143` | | -`PRDEC` | `01:5158` | | -`PRDECDIGITS` | `01:5160` | | -`PRDEC1` | `01:516B` | | +Procedure | Rebuilt bank:addr | Retail bank:addr | Retail file offset | Retail match +---|---|---|---|--- +`MULTIE` | `00:06A4` | | | +`MULTID` | `00:06A9` | | | +`MENU` | `00:363C` | | | +`SLOGO` | `00:3661` | | | +`RESETST` | `00:366F` | | | +`LOGOLOOP` | `00:3699` | | | +`WORKMENU` | `00:36B5` | | | +`EXITMENU` | `00:36D6` | | | +`OPTIONS` | `00:36E2` | | | +`NEXTUP` | `00:36FD` | | | +`NEXTMENU` | `00:3702` | | | +`NOGAME` | `00:370A` | | | +`NEWSEL` | `00:3715` | | | +`NOSEL` | `00:3723` | | | +`UPMENU` | `00:3732` | | | +`HANDYMAN` | `00:3743` | | | +`SOUNDOPT` | `00:375D` | | | +`DWMENU` | `00:3765` | | | +`LOGOPULSE` | `00:377B` | | | +`FADE` | `00:37D0` | | | +`LOGOON` | `00:37E0` | | | +`LOGON` | `00:37EB` | | | +`NOMOV` | `00:37FE` | | | +`BARREL` | `00:3803` | | | +`BARON` | `00:3810` | | | +`RASTARS` | `00:3823` | | | +`RASTAR` | `00:3832` | | | +`STARFALL` | `00:3845` | `00:31D5` | `0x31D5` | in-body +`ANIHEAD` | `00:3872` | `00:3202` | `0x3202` | in-body +`MENUOBJ` | `00:3894` | | | +`WORKSTAR` | `00:38AC` | | | +`STAROFF` | `00:38B7` | | | +`NOBOW` | `00:38E4` | | | +`DUMP3BY3` | `00:38F8` | | | +`SHOWRESULTS` | `00:395F` | | | +`SETBIG` | `00:3989` | `00:32DA` | `0x32DA` | in-body +`RESLOOP` | `00:39B5` | | | +`APLM` | `00:39CE` | | | +`WORKWELL` | `00:3A1A` | | | +`EMOVE` | `00:3A30` | | | +`UPWELLY` | `00:3A3A` | | | +`UPWELL` | `00:3A3F` | | | +`ALLWAIT` | `00:3A47` | | | +`ALLMOVE` | `00:3A51` | | | +`DODIMOVE` | `00:3A58` | | | +`DUMPBIG` | `00:3A7E` | `00:33CD` | `0x33CD` | entry +`DUMPBG` | `00:3A93` | | | +`SHOWAVERAGES` | `00:3AA2` | | | +`PUTAVER` | `00:3ABF` | | | +`AVELOOP` | `00:3B10` | | | +`RESETBOARD` | `00:3B29` | | | +`RESETB` | `00:3B2E` | | | +`BOARDLINED` | `00:3B41` | | | +`BOARDLINE` | `00:3B61` | | | +`PUTSCORE` | `00:3B73` | `00:35A0` | `0x35A0` | in-body +`TOTOTAL` | `00:3B9C` | | | +`UPTOTAL` | `00:3BA1` | | | +`DIGITADD` | `00:3BA6` | | | +`DUMPENDOBJ` | `00:3BB8` | `00:35F6` | `0x35F6` | unverified +`DUMP2BY2SEQU` | `00:3BBD` | `00:35FB` | `0x35FB` | entry +`CHECKHIGH` | `00:3BE9` | | | +`CHECKLINE` | `00:3BEE` | | | +`CHECKCHR` | `00:3BF4` | | | +`NEXTLINE` | `00:3BFF` | | | +`ISBIG` | `00:3C08` | | | +`SHUNTLINE` | `00:3C11` | | | +`PUTDIG` | `00:3C20` | | | +`PRHIGHSCORES` | `00:3C39` | | | +`PRHIGHS` | `00:3C41` | | | +`PRHGH` | `00:3C85` | | | +`DMATRANS` | `01:40E9` | | | +`DMAL` | `01:40EF` | | | +`SYSETUP` | `01:40F4` | | | +`RESETV` | `01:4101` | | | +`TOINTRAM` | `01:4114` | | | +`GAMESETUP` | `01:4122` | | | +`LEVELSETUP` | `01:4141` | | | +`ISMISTER` | `01:4165` | | | +`RESETSP` | `01:4198` | | | +`SETAPPLES` | `01:41AB` | | | +`RESETEX` | `01:41BD` | | | +`SETET` | `01:420E` | | | +`START` | `01:4219` | | | +`MAINLOOP` | `01:4228` | | | +`EXITLEVEL` | `01:426A` | | | +`NOMAPR` | `01:4288` | | | +`NOLEVR` | `01:42A4` | | | +`WAITISH` | `01:42AA` | | | +`WINHOW` | `01:42B2` | | | +`EXTRALIFE` | `01:42BE` | | | +`SETEXTRA` | `01:42C8` | | | +`RESETET` | `01:42D3` | | | +`PAUSEGAME` | `01:42DE` | | | +`NOSTRT` | `01:42F3` | | | +`WAITNOK` | `01:4303` | | | +`SPLITSCREEN` | `01:430A` | | | +`PRAPPLES` | `01:434C` | | | +`PRALOOP` | `01:4352` | | | +`APPLEPIE` | `01:437F` | | | +`APLOOP` | `01:4388` | | | +`WORKAPPLE` | `01:439A` | | | +`NOAPPLE` | `01:43AD` | | | +`NOLFALL` | `01:43B0` | | | +`GOSPLIT` | `01:43B2` | | | +`APPLEWAIT` | `01:43BA` | | | +`APPLEJIG` | `01:43D5` | | | +`APPLEFALL` | `01:43E4` | | | +`LEEV0` | `01:4419` | | | +`LEEV1` | `01:442B` | | | +`FLOUT` | `01:442D` | | | +`HLOUT` | `01:443E` | | | +`REPBACK` | `01:4440` | | | +`STOPAFALL` | `01:444B` | | | +`APPLESPLIT` | `01:4455` | | | +`NOASPL` | `01:4461` | | | +`LEEV2` | `01:4493` | | | +`LEEV3` | `01:44A5` | `00:1ABA` | `0x1ABA` | entry +`BRINGON` | `01:44BE` | | | +`GETDINO` | `01:44D2` | | | +`GETSP` | `01:44D8` | | | +`GETAPPLE` | `01:44E3` | | | +`GETAP` | `01:44E9` | `00:1BE4` | `0x1BE4` | unverified +`FLAGS` | `01:44F4` | `00:1BEF` | `0x1BEF` | entry +`NOT3` | `01:451B` | | | +`COLLISIONS` | `01:451F` | | | +`BALLCP` | `01:4522` | `00:1F9D` | `0x1F9D` | in-body +`BALLCPL` | `01:4535` | `00:1FB0` | `0x1FB0` | in-body +`NBALLCP` | `01:4551` | | | +`MRDOCATCH` | `01:455A` | | | +`GHOSTDIE` | `01:4563` | | | +`NOTLASTG` | `01:4574` | | | +`EXDIE` | `01:4582` | | | +`GAPPLE` | `01:45D6` | | | +`GOAPPLE` | `01:45DF` | | | +`GOBALLBANG` | `01:45FE` | | | +`BALLSCORE` | `01:4606` | | | +`DUFKILL` | `01:462B` | | | +`EATCHERRY` | `01:462D` | | | +`NOCHSEQU` | `01:4651` | | | +`RESCHSEQU` | `01:4656` | | | +`EATWALL` | `01:4668` | | | +`EATFOOD` | `01:4675` | | | +`GETLET` | `01:46A0` | | | +`GOTLET` | `01:46AB` | | | +`ISOUT` | `01:46D1` | | | +`PUTGHST` | `01:46D8` | | | +`SETGHST` | `01:46E1` | | | +`DECODE` | `01:46F5` | | | +`NOGODEL` | `01:4700` | | | +`NODECBON` | `01:470A` | | | +`DECODER` | `01:4734` | | | +`ISSLOW` | `01:4749` | | | +`NOSLOW` | `01:4751` | | | +`INVALIDX` | `01:4776` | | | +`NEWMOVE` | `01:4790` | | | +`NOWRAP` | `01:479D` | | | +`NOSCROLL` | `01:47C4` | | | +`INVALID` | `01:47DD` | | | +`DOBALL` | `01:47E7` | | | +`BADDIES` | `01:480E` | | | +`BADLOOP` | `01:4813` | | | +`WORKBADDIE` | `01:4835` | `00:2153` | `0x2153` | entry +`NOBAD` | `01:4847` | | | +`CIRCLE` | `01:484C` | `00:216A` | `0x216A` | unverified +`MOVEBADF` | `01:4876` | | | +`MOVEBAD` | `01:487B` | | | +`FINDEXITS` | `01:4889` | | | +`NOUP` | `01:48A4` | | | +`NORT` | `01:48B0` | | | +`NODW` | `01:48C7` | | | +`NOLF` | `01:48D3` | | | +`WORKEXITS` | `01:48D6` | | | +`CHANGEDIR` | `01:48EA` | | | +`FINDEX` | `01:48F4` | | | +`GOEXIT` | `01:4902` | | | +`DINODE` | `01:4907` | | | +`DINO` | `01:4909` | | | +`DINOMOVE` | `01:491A` | | | +`DINOEAT` | `01:492A` | | | +`DINOPUSH` | `01:492C` | | | +`EXDANCE` | `01:492E` | | | +`NOEXFL` | `01:4941` | | | +`UPTYPE` | `01:4973` | | | +`EXUP` | `01:4979` | | | +`EXEAT` | `01:4985` | | | +`EXWALK` | `01:4987` | | | +`EXMOVE` | `01:4998` | | | +`EXOUT` | `01:49A1` | | | +`GHOST` | `01:49A3` | | | +`GHOSTMOVE` | `01:49B4` | | | +`GHOSTR` | `01:49C0` | | | +`GHOSTEAT` | `01:49C7` | | | +`CARRYBALL` | `01:49C9` | | | +`THROWBALL` | `01:49EE` | | | +`CDEL0` | `01:49F8` | | | +`ISCHN` | `01:4A06` | | | +`NOCHWL` | `01:4A16` | | | +`BCHECK` | `01:4A24` | | | +`NRNDB` | `01:4A3A` | | | +`NOBHIT` | `01:4A3D` | | | +`NOCHN` | `01:4A41` | | | +`OUTBALL` | `01:4A50` | | | +`GOINBALL` | `01:4A7D` | | | +`INBALL` | `01:4A87` | | | +`INBALL0` | `01:4A91` | | | +`INBALL1` | `01:4A9B` | | | +`POINTS` | `01:4AC3` | | | +`DUMPOBJ` | `01:4ACF` | `00:27C2` | `0x27C2` | in-body +`MPLEX` | `01:4AEE` | | | +`DUMPL` | `01:4B14` | | | +`DUMP2BY1` | `01:4B29` | `00:283A` | `0x283A` | entry +`DUMP1BY1` | `01:4B4F` | `00:2861` | `0x2861` | in-body +`DUMP2BY2` | `01:4B73` | `00:2884` | `0x2884` | entry +`DUMP2BY2S` | `01:4B86` | `00:2897` | `0x2897` | in-body +`MRDOCHEW` | `01:4BCA` | | | +`GOCHEW` | `01:4BE1` | | | +`CHEWS` | `01:4BF2` | | | +`CHEWUP` | `01:4C14` | | | +`CHU0` | `01:4C21` | | | +`CHU1` | `01:4C32` | | | +`CHU2` | `01:4C49` | | | +`CHU3` | `01:4C5A` | | | +`CHEWRT` | `01:4C61` | | | +`CHR0` | `01:4C6E` | | | +`CHR1` | `01:4C7F` | | | +`CHR2` | `01:4C96` | | | +`CHR3` | `01:4CA7` | | | +`CHEWDW` | `01:4CAE` | | | +`CHD0` | `01:4CBB` | | | +`CHD1` | `01:4CCC` | | | +`CHD2` | `01:4CE3` | | | +`CHD3` | `01:4CF4` | | | +`CHEWLT` | `01:4CFB` | | | +`CHL0` | `01:4D0A` | | | +`CHL1` | `01:4D1B` | | | +`CHL2` | `01:4D32` | | | +`CHL3` | `01:4D43` | | | +`CHRDUMPER` | `01:4D4A` | | | +`CDUMP` | `01:4D59` | | | +`PRSCORE` | `01:4D64` | | | +`SCOREADD` | `01:4D81` | | | +`UPSCORE` | `01:4D97` | | | +`NOSCRP` | `01:4DA3` | | | +`CLOCK` | `01:4DA5` | | | +`UPCLOCK` | `01:4DC0` | | | +`STATUS` | `01:4DC5` | | | +`STATSP` | `01:4DDE` | | | +`PUTSSP` | `01:4DF4` | `00:2B44` | `0x2B44` | in-body +`ONSTAT` | `01:4E1A` | | | +`DRAWMAP` | `01:4E22` | | | +`FILLMAP` | `01:4E28` | | | +`FILLBYTE` | `01:4E3F` | | | +`PUTFOOD` | `01:4E76` | | | +`DRAWBLOCK` | `01:4E91` | | | +`DRWBLOCK` | `01:4EA1` | `00:2C17` | `0x2C17` | in-body +`DOTUNNEL` | `01:4EB9` | | | +`DRAWREP` | `01:4ED2` | | | +`ENDTUNNEL` | `01:4EE6` | | | +`PUTCHERRY` | `01:4EEF` | | | +`PUTAPPLE` | `01:4F1F` | | | +`COPYMAP` | `01:4F41` | | | +`COPYM` | `01:4F4A` | | | +`COPYLETTER` | `01:4F53` | | | +`PUTLINE` | `01:4F80` | `00:2CFB` | `0x2CFB` | entry +`KEYS` | `01:4FB6` | | | +`PIXAD` | `01:4FED` | `00:2D63` | `0x2D63` | entry +`GETMAPHI` | `01:5004` | `00:2D7A` | `0x2D7A` | entry +`GETMAPLODE` | `01:501B` | `00:2DBA` | `0x2DBA` | entry +`GETMAPLO` | `01:502D` | `00:2DA8` | `0x2DA8` | entry +`GETBYTEHI` | `01:503F` | `00:2DCC` | `0x2DCC` | unverified +`GETBYTELO` | `01:504D` | | | +`LOWAD` | `01:5059` | `00:2DE6` | `0x2DE6` | in-body +`WAITSC` | `01:5070` | | | +`RESETOBJ` | `01:5078` | | | +`RESETOB` | `01:5087` | | | +`RESETO` | `01:508B` | | | +`RAND` | `01:5097` | | | +`PRINTEXT` | `01:50B1` | `00:2E45` | `0x2E45` | unverified +`TEXTL` | `01:50B9` | `00:2E4D` | `0x2E4D` | unverified +`PRINTSHAPE` | `01:50C1` | | | +`YROWS` | `01:50C5` | | | +`XROWS` | `01:50C7` | `00:2E5B` | `0x2E5B` | entry +`DIVIDE` | `01:50DA` | | | +`DIVE` | `01:50DE` | | | +`CREATESET` | `01:50E6` | | | +`CLEARSET` | `01:50FB` | | | +`SHUNT` | `01:5106` | | | +`DISPBIN` | `01:510F` | | | +`DOBIN` | `01:5114` | `00:2EDA` | `0x2EDA` | unverified +`ISNONE` | `01:511B` | `00:2EE1` | `0x2EE1` | unverified +`CLEARSTAT` | `01:5120` | `00:2EE6` | `0x2EE6` | unverified +`CLR` | `01:512B` | | | +`HEXBYTE` | `01:5134` | | | +`HEXWORD` | `01:5139` | | | +`PRHEX` | `01:5143` | | | +`PRDEC` | `01:5158` | | | +`PRDECDIGITS` | `01:5160` | | | +`PRDEC1` | `01:516B` | | | --- ### Retail offsets for known verbatim code blocks -If you want to map the retail ROM quickly, these labels have a unique 32-byte verbatim signature match inside `build/mrdo_original.gb` (found by scanning `build/mrdo.retail.map` against the retail binary): +If you want to map the retail ROM quickly, these labels have a unique 32-byte verbatim signature match inside `build/mrdo_original.gb` (found by scanning `build/mrdo.map` against the retail binary): Label | Retail bank:addr | Retail file offset ---|---|--- diff --git a/pages/consoles/gamecube/iQueGamecube.md b/pages/consoles/gamecube/iQueGamecube.md index bf0ab23c..3f0f1986 100644 --- a/pages/consoles/gamecube/iQueGamecube.md +++ b/pages/consoles/gamecube/iQueGamecube.md @@ -17,7 +17,6 @@ breadcrumbs: url: # redirect_from: - /ique - - /ique-gamecube/ recommend: - gamecube - sdk diff --git a/public/css/code.css b/public/css/code.css index 7cb53d2c..9670000a 100644 --- a/public/css/code.css +++ b/public/css/code.css @@ -7,6 +7,11 @@ margin-bottom: 0 } +.gist { + max-height: 50vw !important; + overflow: scroll !important; +} + .gist .gist-file { font-family: Menlo, Monaco, "Courier New", monospace !important } diff --git a/public/css/post.css b/public/css/post.css index cc6f3702..76f8c64e 100644 --- a/public/css/post.css +++ b/public/css/post.css @@ -28,13 +28,23 @@ @media (max-width: 768px) { .post h1 { font-size: 20px; - margin-left: unset! important; + margin-left: unset !important; + } + .post { + /* On Phone don't have the text touching the side */ + margin-left: 1vw; } /* Youtube videos should be full width on phone */ .post iframe { width: 100vw !important; - margin-left: -20px !important; + margin-left: -5px !important; + } + + .post table { + display: block !important; + max-width: 100vw !important; + overflow: scroll; } } diff --git a/scripts/install-codex-skill.sh b/scripts/install-codex-skill.sh new file mode 100755 index 00000000..13dd938e --- /dev/null +++ b/scripts/install-codex-skill.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +src_dir="$repo_root/codex/skills/retroreversing-contributing" + +codex_home="${CODEX_HOME:-$HOME/.codex}" +dest_dir="$codex_home/skills/retroreversing-contributing" + +if [[ ! -d "$src_dir" ]]; then + echo "Skill source directory not found: $src_dir" >&2 + exit 1 +fi + +mkdir -p "$dest_dir" + +if command -v rsync >/dev/null 2>&1; then + rsync -a --delete "$src_dir/" "$dest_dir/" +else + rm -rf "$dest_dir" + mkdir -p "$dest_dir" + cp -R "$src_dir/"* "$dest_dir/" +fi + +echo "Installed Codex skill to: $dest_dir" + diff --git a/sitemap.xml b/sitemap.xml index bb6f5eb3..6a7c01c3 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -6,6 +6,9 @@ layout: none xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"> {% assign all_pages = site.pages | sort: 'updatedAt' | reverse %} {% for post in all_pages %} + {% if post.redirect_to %} + {% continue %} + {% endif %} https://www.retroreversing.com{{ post.url }} {{ post.updatedAt }}