# Memory modes Sprinter's CPU address space is four 16 KB windows. ESTEX DSS allocates RAM pages by program size — programs ≤ 16 KB get only **one** page, so the "default" Spectrum-style "code in W1, data in W2" layout silently fails for small programs. This is why `sprinter-cc` has explicit memory modes. ## The five modes | Mode | Code at | Data at | Banks in | Use when | |---|---|---|---|---| | `tiny` (default) | W2 (0x8100+) | chained after code | — | code + data ≤ 14 KB | | `small` | W1 (0x4100+) | chained after code | — | code + data ≤ 30 KB | | `big` | W2 (0x8100+) | chained after code | **W1** (0x4000) | tiny + extra banked modules | | `huge` | W1 (0x4100+) | W2 (0x8000+) | **W3** (0xC000) | small + extra banked modules | | `manual` | user-specified | user-specified | user-specified | special cases | ## Choosing Start with **`tiny`**. If `sprinter-cc` says "_CODE too big" or the program mysteriously fails to start, jump straight to `small`. If you have a large code base (>32 KB total) and want to keep most of it out of the always-resident window, use `huge` and split modules into banks with `--bank N=mod.c`. `big` is the same idea but with banks in W1 instead of W3 — useful when you need W3 for hardware (graphics, mapped memory). ## Stack and heap The stack starts at `0xBFFE` (top of W2) and grows down. The heap starts right after BSS and grows up. By default they share W2 with about 1.2 KB reserved for the stack and the rest for the heap. `--stack-size N` reserves more (or less) for the stack at the cost of heap. ## What's actually under the hood Every mode picks a different `runtime/crt0_*.s`: * `tiny`: `crt0.s` — SP = 0xBFFE, parse argv, call main. * `small`: `crt0_small.s` — read port 0xC2 to see if DSS gave W2. If not, allocate one page via ESTEX `$3D` and map it via `$3A SETWIN2` *before* switching the stack — BIOS calls need the stack in W2, ESTEX calls don't. * `big`: `crt0_banked.s` with `BANK_W1=1` prepended — banks live at `0x{N}4000` and trampolines use port `0xA2`. * `huge`: `crt0_banked.s` (default `BANK_W1=0`) — banks at `0x{N}C000` via port `0xE2`. Also includes the small-mode W2 auto-allocate. For `manual` see `sprinter-cc --memory-manual SPEC` syntax in `sprinter_cc.md`.