Ada compiler targeting Z80 processor
Project description
uada80 - Ada Compiler for Z80/CP/M
An Ada compiler targeting the Z80 processor and CP/M 2.2 operating system, aiming for ACATS (Ada Conformity Assessment Test Suite) compliance.
Project Status
🔧 Alpha - Core compiler functionality implemented
Overview
uada80 is a compiler for the Ada programming language that generates code for the Z80 8-bit microprocessor running CP/M 2.2. The project aims to support a substantial subset of Ada 2012 and pass the ACATS conformance tests.
Target Platforms: CP/M 2.2 and MP/M II on Z80
- CP/M 2.2:
.comexecutables, single-threaded, programs load at 0x0100 - MP/M II:
.prlrelocatable executables, preemptive multitasking via OS primitives - Access to BDOS for file I/O and console operations
- Approximately 57K TPA on typical 64K system
Goals
- Compile Ada source code to Z80 assembly/machine code
- Generate CP/M .COM executables
- Pass ACATS test suite (or as many tests as feasible for Z80/CP/M)
- Generate efficient code suitable for CP/M systems
- Provide clear error messages and diagnostics
Inspiration
This project builds on experience from uplm80, a PL/M-80 compiler for Z80, reusing proven optimization techniques.
Features
Phase 1 (MVP) ✅
- Project structure
- Lexer and parser
- Basic types: Integer, Boolean, Character
- Procedures and functions
- Control flow: if, case, loop, for
- Arrays and records
- Z80 code generation
Phase 2 (Expanded) ✅
- Packages
- Enumeration types
- Access types (pointers)
- Derived types
- Unconstrained arrays
- AST optimization
Phase 3 (ACATS Compliance) 🔧
- Generics
- Exception handling
- Full attribute support
- Representation clauses
- Standard library (adapted for Z80)
- ACATS test validation
Architecture
Ada Source → Lexer → Parser → AST → Semantic Analysis → Optimizer → Code Gen → Z80 Assembly
See docs/ARCHITECTURE.md for detailed design documentation.
Building
Requirements
- Python 3.10 or later
- um80_and_friends - Z80 assembler and linker (
um80,ul80) - cpmemu - CP/M emulator for running compiled programs
Installation
# Clone the repository
git clone https://github.com/avwohl/uada80.git
cd uada80
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install in development mode
pip install -e ".[dev]"
# Install assembler/linker
pip install um80
Running Tests
pytest tests/ -v -o addopts=""
Usage
# Compile Ada to Z80 assembly
python -m uada80 hello.ada -o hello.asm
# Assemble and link
um80 -o hello.rel hello.asm
ul80 -o hello.com hello.rel -L runtime/ -l libada.lib
# Run on CP/M emulator
cpmemu --z80 hello.com
Example Programs
Hello World
with Ada.Text_IO;
procedure Hello is
begin
Ada.Text_IO.Put_Line("Hello from Ada on Z80!");
end Hello;
Fibonacci
procedure Fibonacci is
A, B, Temp : Integer;
N : Integer := 10;
begin
A := 0;
B := 1;
for I in 1 .. N loop
Temp := A + B;
A := B;
B := Temp;
end loop;
end Fibonacci;
See learn-ada-z80 for 99 example programs covering basics through tasking, generics, and applications.
Ada Tasking on MP/M II
Ada tasking (tasks, entries, rendezvous, protected types) runs on MP/M II using OS-native primitives for preemptive multitasking. On CP/M 2.2 (single-user), the runtime provides cooperative tasking stubs.
How It Works
Ada tasks become MP/M II subprocesses sharing one memory bank. The OS handles preemptive scheduling, and all inter-task communication uses BDOS queue operations:
| Ada Construct | MP/M II Primitive |
|---|---|
| Task creation | P_CREATE (BDOS 144) |
| Entry call | Q_WRITE (BDOS 139) - blocking send to queue |
| Accept statement | Q_READ (BDOS 137) - blocking receive from queue |
| Select/else | Q_CREAD (BDOS 138) - conditional (non-blocking) read |
| Protected object | MX queue (mutual exclusion) |
| Delay | P_DELAY (BDOS 141) |
| Abort | P_ABORT (BDOS 157) |
Building for MP/M II
# Compile Ada to assembly
python -m uada80 program.ada -o program.asm
# Assemble
um80 -o program.rel program.asm
# Link as PRL (relocatable for MP/M II)
ul80 --prl -p 0 -o program.prl program.rel -L runtime/ -l libada_mpm.lib
# Or link as COM (also works under MP/M)
ul80 -o program.com program.rel -L runtime/ -l libada_mpm.lib
Running on the MP/M II Emulator
The mpm2 emulator provides a full MP/M II environment with SSH terminal access:
# Start the emulator (up to 4 concurrent consoles)
mpm2_emu --no-auth -p 127.0.0.1:2222 -d A:disks/mpm2_system_work.img
# Connect via SSH
ssh -p 2222 user@localhost
# Upload and run
sftp -P 2222 user@localhost
put program.prl /A.0/PROGRAM.PRL
Runtime Libraries
Two runtime libraries are provided:
libada.lib- CP/M 2.2 runtime with cooperative tasking stubslibada_mpm.lib- MP/M II runtime with OS-native preemptive tasking
Rebuild after changes:
cd runtime && make clean && make
Documentation
Compiler Documentation
- docs/ARCHITECTURE.md - Compiler architecture and design
- docs/AST_DESIGN.md - Abstract syntax tree structure
- docs/OPTIMIZATION_ANALYSIS.md - Optimization strategies
- docs/LANGUAGE_SUBSET.md - Supported Ada language features
CP/M Target Platform
- docs/CPM_RUNTIME.md - Complete Ada/CP/M runtime specification
- docs/CPM_QUICK_REFERENCE.md - CP/M quick reference for developers
- docs/cpm22_bdos_calls.pdf - BDOS system call reference
- docs/cpm22_bios_calls.pdf - BIOS hardware interface
- docs/cpm22_memory_layout.pdf - CP/M memory organization
Ada Language Specifications
- specs/ - Ada language specifications and ACATS tests
Testing
ACATS End-to-End Execution
The ACATS 4.2 test suite is included in tests/acats/. Tests are compiled to Z80 assembly, assembled with um80, linked with ul80, and executed on cpmemu.
579 ACATS tests pass end-to-end (compile + assemble + link + execute on cpmemu):
$ pytest tests/test_acats_execution.py -o addopts=""
===== 257 failed, 579 passed, 624 skipped in 5197s =====
| Result | Count | Description |
|---|---|---|
| Passed | 579 | Compiled, ran on cpmemu, output contains PASSED |
| Failed | 257 | Compiled and ran but produced wrong results (codegen bugs) |
| Skipped | 624 | Compile/link/timeout failures (multi-file deps, missing features) |
ACATS Front-End
All 5,787 legal ACATS files pass parsing and semantic analysis:
$ pytest tests/test_acats.py -o addopts=""
======================= 5,787 passed in 248s =======================
learn-ada-z80 Programs
The learn-ada-z80 companion project has 99 example programs. 98 of 99 compile to Z80 assembly (full pipeline: parse, semantic analysis, lowering, code generation). One program fails due to a codegen bug with negative array bounds.
Execution Tests
End-to-end execution tests (compile + assemble + link + run on cpmemu) are in tests/test_execution.py:
pytest tests/test_execution.py -v -o addopts=""
Limitations
Due to the Z80's 8-bit architecture and limited resources:
- Integer sizes limited to 8-bit and 16-bit (32-bit via library)
- Software floating-point only (IEEE 754 double via
float64.mac) - Reduced standard library
- Tasking requires MP/M II (CP/M 2.2 provides stubs only)
- Limited heap (small memory space)
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Run the test suite
- Submit a pull request
License
This project is licensed under the GNU General Public License v2.0 - see LICENSE for details.
References
Related Projects
- 80un - Unpacker for CP/M compression and archive formats (LBR, ARC, squeeze, crunch, CrLZH)
- cpmdroid - Z80/CP/M emulator for Android with RomWBW HBIOS compatibility and VT100 terminal
- cpmemu - CP/M 2.2 emulator with Z80/8080 CPU emulation and BDOS/BIOS translation to Unix filesystem
- ioscpm - Z80/CP/M emulator for iOS and macOS with RomWBW HBIOS compatibility
- learn-ada-z80 - Ada programming examples for the uada80 compiler targeting Z80/CP/M
- mbasic - Modern MBASIC 5.21 Interpreter & Compilers
- mbasic2025 - MBASIC 5.21 source code reconstruction - byte-for-byte match with original binary
- mbasicc - C++ implementation of MBASIC 5.21
- mbasicc_web - WebAssembly MBASIC 5.21
- mpm2 - MP/M II multi-user CP/M emulator with SSH terminal access and SFTP file transfer
- romwbw_emu - Hardware-level Z80 emulator for RomWBW with 512KB ROM + 512KB RAM banking and HBIOS support
- scelbal - SCELBAL BASIC interpreter - 8008 to 8080 translation
- uc80 - ANSI C compiler targeting Z80 processor and CP/M 2.2 operating system
- ucow - Unix/Linux Cowgol to Z80 compiler
- um80_and_friends - Microsoft MACRO-80 compatible toolchain for Linux: assembler, linker, librarian, disassembler
- upeepz80 - Universal peephole optimizer for Z80 compilers
- uplm80 - PL/M-80 compiler targeting Intel 8080 and Zilog Z80 assembly language
- z80cpmw - Z80 CP/M emulator for Windows (RomWBW)
See Also
- GNAT - For production Ada development, use GNAT or other mature Ada compilers
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file uada80-0.4.0.tar.gz.
File metadata
- Download URL: uada80-0.4.0.tar.gz
- Upload date:
- Size: 627.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0fb1d704647fab86c24921000cb737afbe21112fd0884a9b7ca984ed62d71017
|
|
| MD5 |
b5bd9fe0a11cb0c09813268e92cc9870
|
|
| BLAKE2b-256 |
d9886179258df75068f3af4c8561dcbec11ba16268c99ebc99e38525ed6af11a
|
Provenance
The following attestation bundles were made for uada80-0.4.0.tar.gz:
Publisher:
publish.yml on avwohl/uada80
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uada80-0.4.0.tar.gz -
Subject digest:
0fb1d704647fab86c24921000cb737afbe21112fd0884a9b7ca984ed62d71017 - Sigstore transparency entry: 1484847976
- Sigstore integration time:
-
Permalink:
avwohl/uada80@19d6095f388601d5f0a51ad079add2006b2c55b6 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/avwohl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@19d6095f388601d5f0a51ad079add2006b2c55b6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file uada80-0.4.0-py3-none-any.whl.
File metadata
- Download URL: uada80-0.4.0-py3-none-any.whl
- Upload date:
- Size: 529.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd31a663ffb29103da3ce3def13db8f04127aa30ecaa7b804eaed02b0de7bbb9
|
|
| MD5 |
9ed1ef14aadaa81c54e51d281b1b8bd8
|
|
| BLAKE2b-256 |
e5dc30fa88603f86d34bb355d2c1113a8db206c8c38f53ae97bb227f9aaa842e
|
Provenance
The following attestation bundles were made for uada80-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on avwohl/uada80
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uada80-0.4.0-py3-none-any.whl -
Subject digest:
fd31a663ffb29103da3ce3def13db8f04127aa30ecaa7b804eaed02b0de7bbb9 - Sigstore transparency entry: 1484847989
- Sigstore integration time:
-
Permalink:
avwohl/uada80@19d6095f388601d5f0a51ad079add2006b2c55b6 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/avwohl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@19d6095f388601d5f0a51ad079add2006b2c55b6 -
Trigger Event:
release
-
Statement type: