Skip to main content

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") to puts("...") 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

Configurable Integer Sizes

By default int is 16 bits (natural Z80 word width). Code that assumes 32-bit int can be compiled with a CLI override — no source changes:

uc80 program.c --int=32 -o program.mac     # 32-bit int
uc80 program.c --long=64 -o program.mac    # 64-bit long

The bundled headers (<limits.h>, <stdint.h>, <stddef.h>, <inttypes.h>) derive their typedefs and limit macros from compiler-supplied __SIZEOF_*__ and __*_MAX__ macros, so the same header files work under every config. Codegen routes arithmetic, printf/scanf format dispatch, and sizeof through the selected widths automatically.

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 220/220 full pass
c-testsuite --int=32 219/220 00200 (long-long shift) overflows 64K TPA
c-testsuite --int=32 --long=64 218/220 same as above + marginal timeout
Fujitsu compiler-test-suite 0003 371/374
Fujitsu 0010 58/75 9 int16, 1 float, 2 timeout
Fujitsu 0011 287/335 14 int16, 5 large struct
Fujitsu 0012 4/9 4 int16/long long, 1 static DCE
SDCC regression tests 514/523 3 fail, 4 sdcc ext, 2 multi-file link

Remaining non-passing tests are environmental, not codegen bugs:

  • sdcc ext: SDCC-specific extensions (__asm, #pragma save/restore)
  • multi-file: tests that require separate compilation units
  • float precision: ACOSF/TANF near asymptotes (single-precision IEEE 754 limit)
  • malloc OOM: SDCC test asserts malloc(2000) == NULL; we have plenty of TPA
  • 00200: 67KB binary exceeds 64KB CP/M TPA

Features

  • ANSI C (C11/C23) with most standard features
  • Z80 code generation with peephole optimization
  • IEEE 754 single-precision float
  • Configurable integer sizes (--int=16|32, --long=32|64); default is 16-bit int, 32-bit long, 64-bit long long
  • Structs, unions, bitfields, enums
  • Full preprocessor (#include, #define, #if, #pragma, etc.)
  • Modular library with selective linking
  • Whole-program optimization
  • CP/M target with embedded crt0

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
  • uada80 - Ada compiler targeting Z80 processor and CP/M 2.2 operating system
  • uc386 - C23 compiler targeting Intel 386 (x86-32) and MS-DOS; sibling backend sharing the uc_core frontend
  • uc_core - Shared C23 frontend and AST optimizer used by uc80 and uc386
  • ucow - Unix/Linux Cowgol to Z80 compiler
  • um80_and_friends - Microsoft MACRO-80 compatible toolchain for Linux: assembler, linker, librarian, disassembler
  • upeepz80 - Z80 peephole optimizer
  • uplm80 - PL/M-80 compiler targeting Intel 8080 and Zilog Z80 assembly language
  • z80cpmw - Z80 CP/M emulator for Windows (RomWBW)

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

uc80-0.4.0.tar.gz (462.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uc80-0.4.0-py3-none-any.whl (555.2 kB view details)

Uploaded Python 3

File details

Details for the file uc80-0.4.0.tar.gz.

File metadata

  • Download URL: uc80-0.4.0.tar.gz
  • Upload date:
  • Size: 462.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for uc80-0.4.0.tar.gz
Algorithm Hash digest
SHA256 7591d56c66088f5cdfa47526876ee8400523df1844dcf53c6ed2af1af6ccc6cb
MD5 0135e342cbf193475a4b34811ea87dc7
BLAKE2b-256 2dcbb43c402de37753a9254981078555a5626cf9db7132d0b657fb489ab75215

See more details on using hashes here.

Provenance

The following attestation bundles were made for uc80-0.4.0.tar.gz:

Publisher: publish.yml on avwohl/uc80

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uc80-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: uc80-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 555.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for uc80-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 556daa9e238ee985db0e5ec89abf4ac433488de9fec0901701f7096cb749fe0b
MD5 78d36ace3b6eaf46a3ffd5d36313b0af
BLAKE2b-256 ee5520091a5582447ea6926c2cc6d78a587fd3474d6577392fd6cd750d4a478a

See more details on using hashes here.

Provenance

The following attestation bundles were made for uc80-0.4.0-py3-none-any.whl:

Publisher: publish.yml on avwohl/uc80

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page