| | {{infobox |
| | | title = ALB FASM16 backend |
| | | target_flag = `-t fasm16` |
| | | produces = 16-bit x86 assembly (`use16`) |
| | | output = .COM · MZ .EXE · boot sector (`org 7C00h`) |
| | | runs_on = Real-mode DOS, emulators, bare metal |
| | | emitter_unit = `Emit_Native_FASM16` (emit_native_fasm16.adb) |
| | | status = Tiny profile, growing; `--build` supported |
| | }} |
| | |
| | The **ALB FASM16 backend** compiles [[AdaLogic BASIC]] down to **16-bit x86 assembly** — real-mode code in 8086 mindset, where a word is 16 bits, an address is a segment:offset pair, and the operating system is interrupt `21h`. It is the backend that lets a modern typed BASIC produce programs a 1983 PC could run. |
| | |
| | ```alb One-liner |
| | albt demo.alb -t fasm16 --build |
| | → fasm16_demo/demo.asm → fasm.exe → demo.exe (MZ format by default) |
| | ``` |
| | |
| | ## Three output formats |
| | |
| | The emitter's `FASM16_Output_Format` chooses what kind of 16-bit artifact comes out: |
| | |
| | | Format | Emitted header | What it is | |
| | | --- | --- | --- | |
| | | **MZ .EXE** | `format MZ` · `entry main:start` · `stack 100h` | Relocatable DOS executable — the CLI default | |
| | | **.COM** | `format binary` · `org 100h` | Flat single-segment program — `--fasm16-com` | |
| | | **Boot** | `format binary` · `org 7C00h` | A **boot sector** — code the BIOS loads and runs | |
| | |
| | Yes — an ALB program can, in principle, be emitted as something that boots a machine before any operating system exists. That is what "the low-level floor beneath it all" means in practice. |
| | |
| | ```note From the source itself |
| | The emitter's own banner is honest about its station: *"FASM remains the full ALB native profile… FASM16 starts as a tiny 8086 profile."* It is a seed backend that keeps growing — features it cannot yet lower emit a `; FASM16 UNSUPPORTED: <feature>` marker in the output instead of silently producing wrong code. |
| | ``` |
| | |
| | ## The DOS contract |
| | |
| | A 16-bit program talks to DOS through software interrupts, and the emitted code does it plainly: |
| | |
| | ```text |
| | mov dx, ALB16_Newline |
| | mov ah, 09h ; print $-terminated string |
| | int 21h |
| | ``` |
| | |
| | - `AH=09h` prints a `$`-terminated string — so every literal is stored with the DOS `$` delimiter |
| | - `AH=02h` writes a single character |
| | - `AH=0Ah` reads a buffered line into `ALB16_Input_Buffer` (`db 126, 0, 127 dup(0)` — the classic DOS input structure: max, count, payload) |
| | - Errors are the same `$`-strings: `'ALB16 RUNTIME ERROR: divide or MOD by zero'` |
| | |
| | Because a .COM program begins executing at offset `100h` while static storage sits before the code, binary formats emit `jmp start` first — the program leaps over its own data to reach its first instruction, exactly as hand-written .COM programs do. |
| | |
| | ## 16-bit everything |
| | |
| | Everything gets narrower — and the compiler makes it work: |
| | |
| | - **U16-native** — the machine word is 16 bits; `dw` is the workhorse |
| | - **U32 by pairing** — 32-bit values live as Hi/Lo word pairs (`ALB16_U32_DividendLo/Hi`, `QuotLo/Hi`, `RemLo/Hi`) with multiword division done in software |
| | - **Returns in DX:AX** — inline ASM expressions document the convention in the emitted comment: *"result must be returned in DX:AX (or AX for 16-bit values)"* |
| | - **PURE shrinks** — the exact rational type packs into 4 bytes on this profile: `PURE.den equ 0 · PURE.num equ 2 · sizeof.PURE equ 4` |
| | - **Strings pool** — a fixed 4 KiB pool (`ALB16_Str_Max equ 4096`, safe limit 3840, results capped at 255) |
| | |
| | ## The runtime that fits in a corner |
| | |
| | Even tiny gets the same architecture — scaled: |
| | |
| | - **Dumptruck GC** — `ALB16_GC_Grid`, 1025 nodes × 6 bytes (`Alive · Refs · Child1 · Child2`), with `CLAIM/DROP/BIND/SWEEP` — a mark-and-release memory manager in real mode |
| | - **Prolog knowledge base** — `ALB16_KB`: 1024 fact slots × 13 bytes, hash-keyed (`HashLo/HashHi · ArgLo/ArgHi · ValLo/ValHi · Active`), so ASSERT/QUERY/RETRACT work even in 64 KiB |
| | - **Safety traps** — divide-by-zero, bounds, and range checks print an error and halt, same contract as the 64-bit backend |
| | - **Random** — a seeded 16/32-bit generator (`ALB16_Rnd_SeedLo/Hi`) |
| | - **Temporal variables** — history rings survive the transition to 16 bits: `ALB_TEMP_<name>_history rb N` plus a head cursor |
| | |
| | And the same `if used … end if` discipline as the [[ALB FASM backend]] wraps every routine — the assembler deletes whatever the program doesn't call, which matters enormously when a .COM file is supposed to stay small. |
| | |
| | ## Reversible blocks on 16 bits |
| | |
| | The **reversible state forge** made the trip too: `Emit_Rev_Add/Sub/Xor/Rol/Ror/Swap/Not/Neg` all exist on this backend, operating on 16-bit registers — reversible computation is a language-level feature, not a word-size luxury. |
| | |
| | ## Under the hood |
| | |
| | `Emit_Native_FASM16` (~6,500 lines of SPARK-annotated Ada) implements the same `Emit_*` call surface as every other backend — same front end, same AST, different floor. The two-buffer pattern (`Buffer_Global` / `Buffer_Main`) returns, and `Emit_Profile_Banner` stamps the tiny-profile banner at the top of every file. |
| | |
| | ```tip Try it |
| | `albt demo.alb -t fasm16 --build` assembles straight to an .EXE when fasm is installed. `--fasm16-com` produces a .COM instead — run either in DOSBox or on real hardware, if you're feeling 1983. |
| | ``` |
| | |
| | ## See also |
| | |
| | - [[ALB FASM backend]] — the 64-bit sibling |
| | - [[ALB C backend]] — the portable sibling |
| | - [[AdaLogic BASIC]] — the language |
| | - [[Z3]] · [[Manchester Baby]] — machines from an era this backend could nearly touch |
| | - [[History of Programming]] · [[History of Language]] |
| | |
| + | ## References |
| + | |
| + | 1. ALB Handbook — alb-lang.org/handbook — the language reference for all backends. |
| + | 2. ALB Technology page — alb-lang.org/technology — the sixteen-backend matrix. |
| + | 3. ALB source — github.com/rockyoliver454/AdaLogic-BASIC-ALB-Programming-Language — the emitter sources are Apache 2.0. |
| + | |
| | [[Category:Backends]] |
| | [[Category:AdaLogic BASIC]] |
| | |