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.3.0.tar.gz (460.2 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.3.0-py3-none-any.whl (553.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for uc80-0.3.0.tar.gz
Algorithm Hash digest
SHA256 9c90e2edf5d51045ecefae61b6ca2f6d6503fd7066243c7d9c893fdd638481e9
MD5 b0debbfe127ff212411ff5e8a00c0d0b
BLAKE2b-256 7f8129df2fee05232a0d254f45643d03bc519d2c37b5dbd1fa5dfaecd8f48831

See more details on using hashes here.

Provenance

The following attestation bundles were made for uc80-0.3.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.3.0-py3-none-any.whl.

File metadata

  • Download URL: uc80-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 553.3 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e9086ccba77437e10b3840a8fb8c59077a0f44b333b2621f32b2fee1afc7e730
MD5 2a4f3d0a8f39826a0bdc14d39965d0f1
BLAKE2b-256 f76f7a1b7c6c038fc3b6dcd0f4208206976d52234be99bc01ee95c07dda68f19

See more details on using hashes here.

Provenance

The following attestation bundles were made for uc80-0.3.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