Releases: oisee/minz
v0.24.0 — VIR Zero Bugs, Default Backend
VIR Zero Bugs — Default Backend
VIR has zero known bugs. Now the default backend for MinZ.
Pipeline (нерушимый)
Function → Table(83.6M) → Z3 → Islands → PBQP fallback
O(1) sec sec ms (safety net)
What's New
- VIR is default (
--vir=true,--liris legacy) - PBQP fallback in CodegenModule — automatic splice when VIR fails
- F→A flag materialization — bridge-level SBC A,A for ClassFlag returns
- 500 GPU-proven peephole rules — table-driven, expandable
- 500 GPU-optimal arithmetic — 254 mul + 246 div inline sequences
- Island decomposition prototype — recursive split at liveness bottlenecks
- Per-block fallback removed — all failures → PBQP (no broken code paths)
- Frill on CP/M — 3/3 ML-style demos running on Z80 (81-498 bytes)
- C23 on Z80 — #embed, _BitInt(N), constexpr, 619 asserts
Books & Articles
- Frill Language Guide (epub/pdf)
- Frill on Z80 Article — ML on ZX Spectrum
- C23 on Z80 Book — 13/13 C23 features
- VIR Zero Bugs Report
- Birthday Sprint Report
Research Papers
- Paper A: 83.6M exhaustive GPU regalloc table
- Paper B: Cross-function merging (210T savings, 36%)
- Paper C: Compositional regalloc from solved atoms
- Paper D: Constant multiply superoptimization
- Paper E: Bounded-type GPU iterator fusion
Numbers
| Metric | Value |
|---|---|
| VIR E2E tests | 12/14 PASS (2 = MIR2 bugs, not VIR) |
| Nanz corpus | 41/44 |
| ABAP corpus | 27/27 ✅ |
| C99 corpus | 18/19 |
| Frill on Z80 | 3/3 ✅ |
| GPU arithmetic | 500 sequences |
| GPU peephole | 500 rules |
| Exhaustive table | 83.6M entries |
| VIR bugs | ZERO |
The register allocator with zero bugs and 83.6 million proofs.
🤖 Built with Claude Code across 5 AI-assisted sessions communicating via dedelulu.
v0.23.0 — Birthday Marathon Release
v0.23.0 — Birthday Marathon Release 🎂
12 breakthroughs across 3 sessions. The birthday sprint that wouldn't stop.
@error — Z80-Native Error Propagation + ? Enforcement
- Layer 1:
@error(N)→SCF / LD A, N / RET.@propagate→RET C(1 byte!) - Layer 2: Functions ending with
?are fallible — compiler requires@check/@propagateafter every?-call. Forget it → compile error. - Zero parser/AST/semantic changes. Pure metafunction + parser enforcement.
C99/C11/C17/C23 Standards Sprint
- 5 new libc headers:
stdbool.h,assert.h,ctype.h(17 inline funcs),stdalign.h,stdnoreturn.h - C23 keywords:
bool/true/falsewithout#includeneeded __STDC_VERSION__ = 201710L— C17 conformance- Array designated initializers:
uint8_t arr[5] = {[2] = 42, [4] = 99} - 350/350 C89 corpus asserts pass + 5 new
examples/c/programs - C Standards Roadmap — full C99→C23 feature matrix
MZA: INCBIN Directive
INCBIN "file.bin"— binary data embedding (sprites, fonts, GPU tables)- Optional offset + length:
INCBIN "data.bin", 128, 256
VIR Backend: Zero Test Failures
- 12/14 E2E tests PASS, 0 FAIL — 45 commits in one sprint
- 83.6M exhaustive regalloc table (≤6v complete)
- 164 GPU-optimal constant multiplies inline (4-20x speedup)
- Param constraints across all CFG blocks (one-line fix for clamp bug!)
- Edge-move emission, block param PHI, VIR_STRICT safety net
By the Numbers
| Metric | Value |
|---|---|
| Nanz examples | 35/35 (100%) |
| C89 corpus asserts | 350/350 |
| VIR E2E tests | 12/14 PASS, 0 FAIL |
| VIR functions | 645/645 (100%) |
| GPU regalloc entries | 83.6M (≤6v) |
| Optimal mul sequences | 164 |
| New libc headers | 5 |
| New examples | 6 (5 C + 1 Nanz) |
Files Changed
minzc/pkg/nanz/parse.go—?lexer +enforceFallibleCalls()minzc/pkg/c89/c89.go— C17/C23 predefined macrosminzc/pkg/c89/lower.go—lowerArrayInit()for designated initminzc/pkg/c89/libc/— 5 new headersminzc/pkg/hir/lower.go— array Initial pre-populationminzc/pkg/z80asm/directives.go— INCBIN handlerminzc/pkg/z80asm/parser.go— INCBIN directive recognitiondocs/C_Standards_Roadmap.md— full C99→C23 roadmapexamples/c/— 5 new C99/C11/C23 test programsexamples/nanz/15_error_enforcement.nanz—?enforcement demo
v0.21.4 — Nanz Language Book v5
Nanz Language Book v5 — 21 chapters, 2818 lines
New chapters (v4.1 → v5)
| Ch | Topic | Highlights |
|---|---|---|
| 16 | Enums & Type Aliases | Dot syntax, auto-increment + explicit values, structural aliases |
| 17 | Module System | 4 import styles (unqualified, qualified, alias, glob), HIR merging |
| 18 | Strings & Text Output | SString/LString/CString, triple-quote, #{expr} interpolation, StringPool |
| 19 | Pipe/Trans Pipelines | Named reusable pipelines, use composition, DJNZ fusion, ` |
| 20 | @derive Metaprogramming | @derive_eq, @derive_debug, @derive_sizeof, MetaRuntime introspection |
| 21 | Cross-Language Imports | Import .lanz and .plm modules from Nanz — three languages, one pipeline |
Also in this release
- 9 new showcase examples (ex20–ex28), all E2E verified
- BUG-008 RCA (IX/IY codegen conflicts) + ADR-0020 (instruction constraints) + ADR-0021 (banked memory)
- 6/8 MinZ-only feature gaps closed in Nanz
- Circular import detection, module-not-found errors
- Native Go metafunctions generating Lanz S-expressions at compile time
Downloads
- PDF — Nanz_Language_Book_v5.pdf (180K)
- EPUB — Nanz_Language_Book_v5.epub (57K)
- LaTeX — Nanz_Language_Book_v5.tex (164K)
v0.21.2: mzn native compiler + Nanz Language Book v4
Highlights
mznnative compiler —mzn file.nanzcompiles Nanz to AMD64 via C99 or QBEexpr as typecast syntax —x as u16alongsideu16(x)- Nanz Language Book v4 — 14 chapters, 36 pages. New: signed comparison, PreallocCoalesce, trivial inliner, 6502 backend,
@smc,mzn - MinZ vs Nanz Feature Gap Analysis — enums, @error, imports, strings: what's missing and how to close each gap
Toolchain Binaries (macOS arm64)
minz-toolchain-darwin-arm64.tar.gz — all 11 tools:
| Tool | Description |
|---|---|
mz |
MinZ Compiler (Nanz/MinZ/PL/M-80 → Z80) |
mzn |
Native compiler (Nanz → AMD64 via C99/QBE) |
mza |
Z80 Assembler |
mze |
Z80 Emulator (1335/1335 FUSE tests) |
mzx |
ZX Spectrum emulator (T-state accurate) |
mzd |
Z80 Disassembler |
mzlsp |
Language Server Protocol |
mzv |
MIR2 VM runner |
mzrun |
DZRP remote runner |
mztap |
TAP file loader |
mzr |
Interactive REPL |
Documentation
- Nanz_Language_Book_v4.pdf (36 pages) / .epub / .tex
- MinZ_vs_Nanz_Feature_Gap.pdf / .epub
v0.20.1 — Profiler: Stack Tracking + Memory Snapshots
What's New in v0.20.1
Profiler: Stack Push/Pop Heatmaps
- Per-byte stack tracking via SP-delta detection after each instruction
stack_push/stack_popcounters show exactly which addresses are used as stackstack_depthmeta field: lowest SP seen (deepest stack usage)- Signed int16 delta handles uint16 wraparound; ignores
LD SP,nnre-initialization
Profiler: Memory Snapshot at Export
- Captures full 64KB memory state when profile is exported
mem_snapshotfield: byte values at all hot addresses (exec/read/write/stack)- Correlate "most-read address" with "what's actually there" in one JSON
Example profile output
{
"meta": {"total_instrs": 33, "stack_depth": "FFFE"},
"exec": {"0100": 1, "0103": 1, ...},
"read": {"0100": 5, "FFFE": 2, ...},
"stack_push": {"FFFE": 1, "FFFF": 1},
"stack_pop": {"FFFE": 1, "FFFF": 1},
"mem_snapshot": {"0100": "3E", "FFFE": "00", ...}
}Changes
- Both MZE and MZX profilers updated
Memory()accessor on RemogattoZ80 for snapshot capture- MZX: stack tracking in both
RunFrame()andRunFrameFast()paths
Full diff: v0.20.0...v0.20.1
v0.20.0 — MIR Backend Tests, VSCode Tooling, Stderr Port
What's New in v0.20.0
Emulator: Stderr Port & Exit Codes
- Stderr port $25:
OUT ($25), Asends bytes to host stderr (when--console-ioactive) - DI+HALT exit code: A register value becomes the process exit code
- Port $23 (stdin/stdout) unchanged; $25 is write-only, odd (safe from ZX ULA conflicts)
MIR Backend Test Suite
- 11 handcrafted
.mirprograms exercising arithmetic, logic, branches, loops, variables, strings - Go test harness: parse → codegen → assemble → emulate → verify output
- 9/11 passing (2 known backend bugs: loop_while, accumulator)
- T-state benchmarking support
VSCode Extension v0.6.0
- MIR syntax highlighting — TextMate grammar for
.mirfiles (functions, registers, instructions, labels) - Compile & Run works for both
.minzand.mirfiles - Target selection — choose cpm/zxspectrum/msx/cpc from Quick Pick
- LSP server (
mzlsp), SLD debugging, DeZog integration
Register Allocator Overhaul
- 7.8x iterator speedup (207T → 26T per element)
- Physical register allocation for iterator hot paths
Iterator Chain Fusion
- Fusion optimizer inlines ≤8-instruction callbacks into DJNZ loops
- 11/11 E2E tests pass (hex-verified)
- BareDJNZ hint + peephole rule 48
Documentation
- Honest assessment report (#025) with code-verified numbers
- MIR language compatibility analysis (53 portable opcodes, PL/M 9/10 compatibility)
- Comprehensive ecosystem status review (#024)
Full changelog
39 commits since v0.19.3 — see compare
v0.19.1 — MZA Bracket Syntax, Beeper Fixes
What's New
MZA Assembler: Bracket Indirection Syntax
[addr]accepted alongside(addr)for all indirection forms- Register indirect:
LD A, [HL],LD [BC], A - Memory indirect:
LD HL, [$8000],LD [$9000], A - Indexed:
LD A, [IX+5],LD [IY+3], B - I/O:
IN A, [C],OUT [C], B - Mismatched brackets (
[HL),(HL]) are correctly rejected - Follows sjasmplus
--syntax=abfconvention, always enabled — no flag needed - 28 new test cases covering all forms + mismatch rejection
MZX Beeper Audio Fixes
- Fix beeper silence bug —
BEEPcommand now produces sound - Fix 50Hz click — fade out at active→silent transitions
- Fix periodic click — always produce samples in silent frames
Binaries
All platforms include: mz (compiler), mza (assembler), mze (emulator), mzd (disassembler), mzr (REPL), mzrun (DZRP runner), mzv (VM), mztap (TAP loader).
macOS builds also include mzx (ZX Spectrum graphical emulator). Linux/Windows mzx requires building from source with CGO.
Full Changelog: v0.19.0...v0.19.1
v0.19.0 — MZX Emulator, Covox, PSG Capture, All Platforms
What's New
MZX ZX Spectrum Emulator
- T-state accurate ULA with proper border rendering
- AY-3-8912 sound with ring buffer for jitter-free playback
- Covox Speech Thing (DAC on port $FB) with per-T-state recording
- AY PSG auto-capture —
--psg file.psg/--psg file.psg2(compact bitmask format) - 128K SNA snapshots, .TAP and .TRD/.SCL disk loading
- TR-DOS simulation with full dispatch table
- Pentagon 128K model with corrected border timing
- Screenshots (F5 or
--screenshot), frame dumps (--dump-frames) - BASIC automation:
--type,--execfor scripted testing --load/--set/--runflags for raw binary loading and CPU state control--trd-runflag to run BASIC programs from TR-DOS disk images
Toolchain Improvements
- Z80 emulator: 1335/1335 FUSE tests pass (100% instruction coverage)
- Table-driven assembler: All Z80 instructions via pattern matching
- IDA-like disassembler: Analysis engine with cross-references
- ABI file format: Load/export for ROM integration
- Execution profiler and trace output
Bug Fixes
- AY data write port mask corrected ($BFFD instead of $7FFD)
- Default model changed to 128K
- 48K protected from accidental paging port writes
- Beeper clicking and keyboard mapping fixes
Binaries — MZX on ALL platforms!
| Platform | Tools |
|---|---|
| macOS arm64 | minzc, mza, mzd, mze, mztap, mzx |
| macOS x86-64 | minzc, mza, mzd, mze, mztap, mzx |
| Linux x86-64 | minzc, mza, mzd, mze, mztap, mzx |
| Linux arm64 (RPi) | minzc, mza, mzd, mze, mztap, mzx |
| Windows x86-64 | minzc, mza, mzd, mze, mztap, mzx |
| Windows arm64 | minzc, mza, mzd, mze, mztap, mzx |
Checksums
See SHA256SUMS.txt in the release assets.
v0.18.0 - MZX Spectrum Emulator, Profiler & Full Toolchain
Highlights
MZX: T-State Accurate ZX Spectrum Emulator (NEW)
A complete ZX Spectrum emulator built into the MinZ toolchain, featuring:
- T-state accurate ULA with proper border rendering and contention
- AY-3-8912 sound chip emulation
- 128K / Pentagon models with bank switching
- .tap / .trd / .scl format loading (tape and TR-DOS disk)
- .sna snapshot load/save (48K and 128K)
- BASIC tokenizer and console capture (
--exec,--type,--console) - Frame dump system (
--dump-frames,--dump-keyframes,--screenshot) - Raw binary loading (
--load FILE@ADDR,--set PC=8000,SP=FFFF,DI) - Headless mode for automated testing and CI
- Beeper + AY audio with per-channel enable/disable
- ZX Spectrum 48K ROM included (Amstrad free distribution)
Execution Profiler & Trace
--profile FILE.json— execution/memory/IO heatmaps (sparse JSON)--trace FILE.jsonl— basic-block execution trace (JSONL)--trace-frames START:END— frame range filtering- Zero overhead when disabled (nil pointer check)
DI+HALT Detection
--warn-on-halt— warns when CPU executes HALT with interrupts disabled
MZD: IDA-Like Disassembler (NEW)
- Recursive descent analysis engine
- Cross-reference tracking, code vs data classification
MZA: Table-Driven Assembler Rewrite
- Old encoder fully removed, replaced with
instruction_table.go+pattern_matcher.go - 1335/1335 FUSE Z80 test suite passes
Participle Parser
- Tree-sitter replaced with pure Go Participle-based parser
- Eliminates OOM issues on large files
Language Features
- Operator overloading (
+,==,*with type dispatch) - UFCS method syntax (
obj.method()) - Auto-derivation for comparison operators
- Multi-parameter loop reroll optimization
- String intent detection in peephole optimizer
Build System
make allbuilds 9 tools: mz, mza, mze, mzv, mzr, mzrun, mztap, mzd, mzxmake install-userinstalls to~/.local/bin/- Linux/WSL build fixes
Full Changelog
v0.16.4 - GLSL Shader Library: Shaders on Z80!
MinZ v0.16.4 - GLSL Shader Library
Codename: "Shaders on Z80"
What's New
Complete GLSL-style shader library bringing modern graphics programming to vintage Z80 hardware!
New Library: stdlib/glsl/
| Module | Purpose |
|---|---|
fp.minz |
8.8 Fixed-point math with Z80 assembly |
trig.minz |
Trigonometry with 65-entry lookup tables |
vec.minz |
vec2/vec3/vec4 GLSL-style vectors |
sdf.minz |
Signed Distance Functions |
raymarch.minz |
Raymarching framework |
dither.minz |
Floyd-Steinberg & Bayer dithering |
Working Demo: glsl_sphere_demo.minz
A 410-line raymarched sphere demo that compiles to 4,384 lines of optimized Z80 assembly!
Features:
- 15-step raymarching with DJNZ optimization
- Fixed-point lighting and fog
- Bayer 4x4 dithering
- Surface normal calculation
Compilation Stats
| Metric | Value |
|---|---|
| Source lines | 410 |
| MIR instructions | 986 |
| Z80 assembly lines | 4,384 |
| DJNZ loops | 4 |
| True SMC calls | 30 |
| Inlined functions | 95 |
Inspiration
Massive thanks to DeanTheCoder and the ZXSpeculator project for proving sophisticated 3D graphics are possible on Z80. The OneSmallStep lunar raymarcher directly inspired this library.
"Shaders on Z80 - because we can."