Conventions & methodology
How to read these notes, and how they were produced.
Suggested reading order
- Overview — the four pillars and the system through-line.
- Subsystem map — see the whole API surface at once.
- Substrate: Memory map → Paging → The bcall mechanism → Interrupts.
- Pick a core subsystem (Floating-point, VAT, Tokenizer/TI-BASIC, Display…), then its feature deep-dive (
sub-*). - Glossary for any unfamiliar term.
Address notation
pp:addr— flash pagepp(00–3F), logical addressaddr. Banked pages run in the4000–7FFFwindow, so e.g._PutSat01:5C39means page 1, address0x5C39. Example:3D:6745.ram:addr— page 0 (the always-mapped kernel) and the RAM window; Ghidra keeps page 0 in itsramspace, soram:229E≡00:229E.- Ghidra’s overlay space writes flash addresses as
page_pp:addr(e.g.page_38:4000); the wiki normalizes these to the shortpp:addrform, sopage_38:4000is written38:4000. - A bare
0x….(no page) is a RAM data address or an unpaged value (e.g.flags0x89F0, the bcall-ID ranges0x4xxx/0x8xxx, a page number like0x3B). - bcall ID ≠ address. A bcall has an ID (the 2-byte word after
rst 28h, e.g._FindSym=42F4h) and a body address (00:0E65). The ID indexes the jump table; it is not where the code lives.
Confidence flags
Every non-obvious claim is tagged:
| Flag | Meaning |
|---|---|
| [confirmed] | Directly observed in the disassembly/decompiler of this ROM. |
| [standard] | Matches the publicly-documented TI-83+/84+ architecture and is consistent with the disassembly, but not every byte was traced. |
| [hypothesis] | Inferred / not yet verified — treat with caution. |
Some early deep-dive docs use shorthand [C]/[H]/[I] ≈ [confirmed]/[standard]/[hypothesis]; read them against this three-tier scheme.
Function naming
_CamelCase— an official TI bcall/equate name (fromti83plus.inc, the full 2007 TI-83 Plus SDK equates file, or the TI SDK), e.g._FindSym,_FPAdd. High confidence.snake_case— a name inferred during this RE from a routine’s behavior (which named routines it calls, which RAM/ports it touches), e.g.findsym_scan,fp_normalize. Accurate in aggregate; any single low-level helper name is a best-effort guess.
Math notation
Formulas are written in LaTeX and rendered by KaTeX (offline, client-side): $…$ for inline math and $$…$$ for display. Algorithms render as pseudocode blocks and data/control-flow diagrams as Mermaid.
How this RE was produced
- The Ghidra database is rebuilt from the ROM by
tools/build.sh(a 10-stage headless pipeline). It loads all 64 flash pages (page 0 + overlays at4000), then resolves and names routines from the main OS bcall table. - bcall table resolution. The main jump table page was found by scoring all 64 flash pages: for each candidate, count how many of the known bcall IDs produce a valid
(addr, page)entry. Page 0x3B scored highest for the0x4xxxtable — more known bcall IDs resolve to a valid(addr, page)entry there than on any other page — and is confirmed by the documented RST shortcuts (all six matched) and by every entry resolving and live-confirming once 0x3B is applied.0x8xxxbcall IDs index a retail boot table on page3F(with the USB boot entries on retail page2F). Thisrom.binis a BootFree image — page3Fcarries the BootFree prefix3E 3F D3 06 …and page2Fis blank (allFF) — so these0x8xxxbody targets do not resolve and are left unnamed (tools/bcalls8x_targets.txthas no body rows); only their SDK equate names are known. - Decompiler caveats. Ghidra’s Z80 decompiler mis-renders some idioms —
SET b,(IY+d)flag ops, theCALL cross_page_jump(ram:2B09) trampolines, and register-passed arguments on banked pages. Where the decompiler is unreliable the notes are grounded in the raw disassembly (and several deep-dives used a small custom Z80 decoder over the ROM to verify addresses byte-exactly). - Parallel multi-agent passes. The feature deep-dives (
sub-*) and the final 100%-naming pass were produced by multiple agents working on isolated copies of the database, each owning a disjoint set of pages, then merged.
See the repository README.md for the exact build pipeline and tooling.