ANSI C compiler targeting Z80/CP/M
Project description
uc80 - ANSI C Compiler for Z80
A C compiler targeting the Z80 processor and CP/M operating system. Produces assembly compatible with the um80 assembler and linker toolchain.
Installation
pip install uc80
Or from source:
pip install -e .
Requires the um80 assembler/linker toolchain:
pip install um80
Quick Start
# Compile, assemble, and link a C program
uc80 hello.c -o hello.mac
um80 hello.mac -o hello.rel
ul80 hello.rel lib/libc.lib lib/runtime.lib -o hello.com
Best Optimization (Whole-Program)
For smallest binaries, compile all .c files in a single invocation.
This enables whole-program optimizations that are not possible when
compiling files separately:
# Single-file (best optimization - all optimizations enabled by default)
uc80 main.c utils.c -o program.mac
um80 program.mac -o program.rel
ul80 program.rel lib/libc.lib lib/runtime.lib -o program.com
Default optimizations (all enabled unless disabled):
- Whole-program mode: Dead function elimination across all files
- Shared storage: Non-recursive functions use static allocation instead of stack frames
- Function inlining: Small functions expanded at call sites
- Constant propagation: Interprocedural constant folding
- AST optimization: Expression simplification, strength reduction
- Assembly DCE: Dead code elimination at assembly level
- Peephole optimization: Pattern-based instruction replacement
- Printf auto-detection: Scans format strings to link only needed handlers;
rewrites
printf("...\n")toputs("...")when no format specifiers are used - Embedded runtime: Runtime functions included as source, DCE removes unused ones
Printf Control
The compiler auto-detects which printf format specifiers your program uses and links only the needed handlers. You can also control this explicitly:
# Command line
uc80 program.c --printf int # %d %u %x %o %s %c %p only
uc80 program.c --printf int --printf long # add %ld %lu %lx
uc80 program.c --printf float # add %f
# In source code
#pragma printf int
#pragma printf long
Separate Compilation
When compiling files separately for separate linking, use --no-whole-program:
uc80 --no-whole-program module.c -o module.mac
Binary Size
uc80 produces the smallest known binaries for Z80/CP/M among current compilers.
Tested against z88dk (SDCC backend, -SO3 --max-allocs-per-node10000)
on the Fujitsu compiler-test-suite:
| Metric | Result |
|---|---|
| uc80 smaller | 47/47 tests (100%) |
| Aggregate size ratio | 46% (uc80 is less than half the size) |
| Total uc80 | 170,496 bytes |
| Total z88dk | 369,644 bytes |
| Minimal binary | 128 bytes (vs 5,172 for z88dk) |
Sample sizes (bytes):
| Program | uc80 | z88dk | Ratio |
|---|---|---|---|
| hello world (puts) | 256 | 5,172 | 5% |
| printf %d | 4,608 | 7,696 | 60% |
| integer math | 5,248 | 7,948 | 66% |
| long arithmetic | 5,632 | 7,793 | 72% |
Test Results
Tested against multiple external test suites:
| Suite | Pass Rate | Notes |
|---|---|---|
| c-testsuite | 218/220 | 1 timeout, 1 _Generic |
| Fujitsu compiler-test-suite 0003 | 371/374 | |
| Fujitsu 0010 | 59/75 | 9 int16, 4 bitfield, 1 float, 2 timeout |
| Fujitsu 0011 | 291/334 | 14 int16, 16 bitfield, 5 large struct |
| Fujitsu 0012 | 3/9 | all bitfield |
| SDCC regression tests | 488/523 | 6 sdcc ext, 8 float math, 5 libc |
Most non-passing tests are due to platform differences, not bugs:
- int16: Z80 has 16-bit int, tests assume 32-bit
- bitfield: Bitfield layout/packing not yet implemented
- large struct: Struct-by-value in complex expressions
- sdcc ext: SDCC-specific language extensions
- float math: Edge cases in transcendental functions
Features
- ANSI C (C11/C23) with most standard features
- Z80 code generation with peephole optimization
- IEEE 754 single-precision float
- 16-bit int, 32-bit long, 64-bit long long
- Full preprocessor (#include, #define, #if, #pragma, etc.)
- Modular library with selective linking
- Whole-program optimization
- CP/M target with embedded crt0
Related Projects
| Project | Description | Link |
|---|---|---|
| um80 | MACRO-80 compatible assembler/linker | github / pypi |
| uplm80 | PL/M-80 compiler for Z80 | github / pypi |
| cpmemu | CP/M emulator for testing | github |
| upeepz80 | Z80 peephole optimizer | github / pypi |
| uada80 | Ada compiler for Z80 | github / pypi |
License
GPL-3.0-or-later. See LICENSE.
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 uc80-0.1.0.tar.gz.
File metadata
- Download URL: uc80-0.1.0.tar.gz
- Upload date:
- Size: 447.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3d15ee94d8a218da1c945c4ac576f92ccb1d9d6de60432efd2047ed5d99cf7e
|
|
| MD5 |
3b45385d40b6461a7fe98a84633ef5be
|
|
| BLAKE2b-256 |
f86b04e6fadbed741aebce33ad23f8fbfca63be1d8d00109f9a8fb725163cc6d
|
Provenance
The following attestation bundles were made for uc80-0.1.0.tar.gz:
Publisher:
publish.yml on avwohl/uc80
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uc80-0.1.0.tar.gz -
Subject digest:
f3d15ee94d8a218da1c945c4ac576f92ccb1d9d6de60432efd2047ed5d99cf7e - Sigstore transparency entry: 1093278372
- Sigstore integration time:
-
Permalink:
avwohl/uc80@9f7e0646b2eba9128f10199d58befcbb0ee512a8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/avwohl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9f7e0646b2eba9128f10199d58befcbb0ee512a8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file uc80-0.1.0-py3-none-any.whl.
File metadata
- Download URL: uc80-0.1.0-py3-none-any.whl
- Upload date:
- Size: 540.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d92935bf9dc9aa17057cc7ee7f82193379cbf3f3f97af355c8d6c422c2ab468
|
|
| MD5 |
43fe73cb245bf1ca9db8ac3ac0fea810
|
|
| BLAKE2b-256 |
0089c878af7c2e35972725b68a549a150a4db04e04169703fb5658d801b67031
|
Provenance
The following attestation bundles were made for uc80-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on avwohl/uc80
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uc80-0.1.0-py3-none-any.whl -
Subject digest:
9d92935bf9dc9aa17057cc7ee7f82193379cbf3f3f97af355c8d6c422c2ab468 - Sigstore transparency entry: 1093278390
- Sigstore integration time:
-
Permalink:
avwohl/uc80@9f7e0646b2eba9128f10199d58befcbb0ee512a8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/avwohl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9f7e0646b2eba9128f10199d58befcbb0ee512a8 -
Trigger Event:
release
-
Statement type: