# Oracle — the hand-written TinySafeBoot assembly `tsb-fixedbaud.asm` is the reference implementation this port is measured against: the **native-UART, fixed-baud** TinySafeBoot bootloader, hand-written in AVR assembly. It is the size-and-feature bar for the port's `tsb_asm` tier. - **Source**: (`firmware_ASM/latest_stable_release/20200727-fixedbaud/main.asm`), the Seed Robotics fixed-baud fork of Julien Thomas' TinySafeBoot. - **License**: GPLv3 (see the header in the file). It is vendored here **only as a reference oracle** — it is not compiled, linked, or distributed as part of the MIT-licensed port. Mere aggregation. ## Why this variant The user chose the fixed-baud, hardware-UART variant deliberately: it is the one whose feature set the port must match. It fits the **complete** TSB feature set into the 512-byte ATmega boot section: | Feature | Oracle routine | |---|---| | Watchdog-reset bail straight to the app | `RESET` (WDRF check) | | One-wire half-duplex (RX/TX shorted): RXEN/TXEN toggled per direction, TX turnaround guard | `SetRX` / `SetTX` / `TransmitByte` | | Activation timeout read from the config page, with a lockout-proof minimum | `WRX1To` (uses `utimeoutH`) | | 3×`@` activation knock | `ActCharRcvd` | | Password gate; wrong byte hangs (still draining the UART) | `CheckPassword` | | Emergency erase on password `\0` + double-confirm — wipes flash, EEPROM and the config page | `EmergencyErase` | | Device-info block (16 bytes) | `SendDeviceInfo` / `DEVICEINFO` | | App-flash read/write (`f`/`F`), EEPROM read/write (`e`/`E`), config read/write (`c`/`C`) | `CheckCommands` | ## Assembled size (the bar) Assembled for the ATmega328P with `avra`: ``` avra -I /usr/share/avra tsb-fixedbaud.asm # after uncommenting .include "m328Pdef.inc" # Code : 250 words (500 bytes) — the whole loader, all features, in the 512 B section ``` **500 bytes with every feature** — the proof that ≤512 B and full feature parity are simultaneously reachable. The port's four tiers reach it from the other side, and the gradient between them is the cost of the mechanisms each is allowed: | tier | bytes | section | what it is allowed | |---|---|---|---| | oracle | 500 | 512 B | hand-written assembly, the reference | | `tsb_asm` | 512 | 512 B | C++ on libavr, two routines in asm | | `tsb_tricks` | 528 | 1 KB | no asm; global register variables | | `tsb_policy` | 630 | 1 KB | pureboot's rules: no asm, no register variables | | `tsb_pure` | 776 | 1 KB | idiomatic libavr throughout | The two routines `tsb_asm` keeps are the ones whose remaining cost is the calling convention itself: the bounded rx and the page-store loop. It fills its section exactly, with the same one-bit-time turn-around guard the oracle spends six bytes on - every tier implements the whole feature set, which is what makes the column a gradient rather than four different loaders. The oracle targets 20 MHz / 33333 baud; the port targets 16 MHz / 115200 baud (what the simavr protocol test drives). Baud and geometry differ, code size and feature set do not.