Microsoft MACRO-80 compatible assembler toolchain for Linux
Project description
um80 - Microsoft MACRO-80 Compatible Toolchain for Linux
A complete Unix/Linux implementation of Microsoft's classic CP/M development tools from the 1980s:
- um80 - MACRO-80 compatible assembler for 8080/Z80
- ul80 - LINK-80 compatible linker
- ulib80 - LIB-80 compatible library manager
- ucref80 - Cross-reference utility
- ud80 - 8080/Z80 disassembler for CP/M .COM files
- ux80 - 8080 to Z80 assembly source translator
These tools can assemble, link, and manage 8080/Z80 assembly code to produce CP/M-compatible .COM executables on modern Linux systems.
Installation
From PyPI (recommended)
pip install um80
From source
git clone https://github.com/um80/um80_and_friends.git
cd um80_and_friends
pip install -e .
Quick Start
Assemble a source file
um80 program.mac # Creates program.rel
um80 -o output.rel program.mac # Specify output name
um80 -l listing.prn program.mac # Generate listing file
um80 -g program.mac # Export all symbols as PUBLIC (for debug)
um80 -t program.mac # Truncate symbols to 8 chars (M80 compat)
um80 -e ".z80" program.mac # Execute code before source (set Z80 mode)
um80 --pre macros.mac program.mac # Include file before source
Link object files
ul80 program.rel # Creates program.com
ul80 -o output.com a.rel b.rel # Link multiple files
ul80 -s program.rel # Generate symbol file (.sym)
ul80 -S symbols.sym program.rel # Specify symbol file name
ul80 -p E000 program.rel # Set origin address (hex)
ul80 --prl program.rel # Output MP/M .PRL format
Disassemble a COM file
ud80 program.com # Creates program.mac
ud80 -z program.com # Z80 mode
ud80 -e 0200 program.com # Add entry point at 0200h
ud80 -d 0500-05FF program.com # Mark range as data
Create/manage libraries
ulib80 -c mylib.lib a.rel b.rel # Create library
ulib80 -l mylib.lib # List contents
ulib80 -p mylib.lib # Show public symbols
ulib80 -x mylib.lib module # Extract module
ulib80 -a mylib.lib new.rel # Add module
ulib80 -d mylib.lib module # Delete module
Generate cross-reference
ucref80 program.mac # Print to stdout
ucref80 -o xref.txt *.mac # Output to file
Translate 8080 to Z80 assembly
ux80 program.mac # Creates program_z80.mac
ux80 -o output.mac program.mac # Specify output name
Tools Reference
um80 - Assembler
Microsoft MACRO-80 compatible assembler supporting:
- 8080 and Z80 instruction sets
- Macros with parameters (MACRO/ENDM)
- Repeat blocks (REPT, IRP, IRPC)
- Conditional assembly (IF/ELSE/ENDIF, IFDEF, etc.)
- Segments (CSEG, DSEG, ASEG, COMMON)
- PUBLIC/EXTRN for module linking
- Include files
- All standard directives (ORG, EQU, SET, DB, DW, DS, etc.)
Command-Line Pre-Execution (-e and --pre)
Code can be injected before the main source file using -e (inline code) and --pre (include file). Both options can be repeated and are processed in the order specified:
# Set Z80 mode from command line
um80 -e ".z80" program.mac
# Multiple statements using ! separator (DRI notation)
um80 -e ".z80!DEBUG equ 1!BUFSIZE equ 256" program.mac
# Include a file of macros before the main source
um80 --pre stdmacros.mac program.mac
# Combine both, processed left to right
um80 -e ".z80" --pre macros.mac -e "MYVAL equ 42" program.mac
This is useful for:
- Switching CPU mode (
.z80or.8080) without modifying source files - Defining conditional assembly symbols (
DEBUG equ 1) - Including project-wide macro libraries
See man um80 for full documentation, or refer to the original Microsoft M80 Manual.
ul80 - Linker
LINK-80 compatible linker that:
- Links multiple .REL relocatable object files
- Resolves external references
- Produces CP/M .COM executables
- Supports COMMON blocks
- Can output Intel HEX format
- Can output MP/M .PRL (Page Relocatable) format
- Provides
__END__symbol for dynamic memory allocation
Predefined Symbols
The linker provides a predefined __END__ symbol that points to the first free byte after all linked segments (code + data + common blocks). This is useful for implementing heap allocation:
EXTRN __END__ ; Import linker symbol
START: LXI H,__END__ ; Load end of program
SHLD HEAP ; Initialize heap pointer
...
DSEG
HEAP: DW 0 ; Heap pointer
See man ul80 for full documentation, or refer to the original Microsoft L80 Manual.
ulib80 - Library Manager
LIB-80 compatible library manager for:
- Creating .LIB library archives
- Listing library contents and public symbols
- Adding/removing/extracting modules
See man ulib80 for full documentation, or refer to the original Microsoft CREF/LIB Manual.
ucref80 - Cross-Reference
Generates cross-reference listings showing:
- Symbol definitions
- Symbol references by file and line
- PUBLIC and EXTRN declarations
See man ucref80 for full documentation.
ud80 - Disassembler
8080/Z80 disassembler that:
- Disassembles CP/M .COM files to .MAC source
- Produces output compatible with um80
- Supports both 8080 and Z80 instruction sets
- Allows marking data ranges and entry points
- Generates re-assemblable source code
See man ud80 for full documentation (no Microsoft equivalent exists).
ux80 - 8080 to Z80 Translator
Source-to-source translator that converts Intel 8080 assembly to Zilog Z80 assembly:
- Translates all 8080 instructions to equivalent Z80 mnemonics
- Preserves all comments, labels, and formatting
- Produces byte-identical output when assembled
- Automatically adds
.Z80directive to output - Handles all assembler directives (passes them through unchanged)
Translation examples:
| 8080 | Z80 |
|---|---|
MOV A,B |
LD A,B |
MVI A,42H |
LD A,42H |
LXI H,1234H |
LD HL,1234H |
LDA addr |
LD A,(addr) |
LHLD addr |
LD HL,(addr) |
LDAX B |
LD A,(BC) |
INR A |
INC A |
INX H |
INC HL |
DAD D |
ADD HL,DE |
ADD B |
ADD B |
ADI 10 |
ADD 10 |
JMP addr |
JP addr |
JNZ addr |
JP NZ,addr |
CALL addr |
CALL addr |
CNZ addr |
CALL NZ,addr |
RET / RNZ |
RET / RET NZ |
RLC |
RLCA |
CMA |
CPL |
HLT |
HALT |
PCHL |
JP (HL) |
XCHG |
EX DE,HL |
IN port |
IN A,(port) |
OUT port |
OUT (port),A |
PSW |
AF |
M (memory) |
(HL) |
See man ux80 for full documentation.
File Formats
| Extension | Description |
|---|---|
| .MAC | Assembly source (MACRO-80 format) |
| .REL | Relocatable object file |
| .COM | CP/M executable |
| .PRL | MP/M Page Relocatable executable |
| .LIB | Library archive |
| .PRN | Assembly listing |
| .SYM | Symbol file |
Compatibility Notes
These tools aim for compatibility with the original Microsoft tools while running on modern Unix/Linux systems:
- Source files use Unix line endings (LF), but CR/LF is also accepted
- File names are case-insensitive for symbols (converted to uppercase)
- Default origin is 0100h (standard CP/M load address)
- Output files are binary-compatible with original CP/M tools
Extended Symbol Names
The original Microsoft REL format limits symbol names to 8 characters. um80/ul80 extend this to support symbols up to 255 characters, which is essential for:
- External references with offsets (e.g.,
MEMSEGTBL+2stays intact instead of truncating toMEMSEGTB) - Long descriptive symbol names in modern code
- Compatibility with source code written for other assemblers
Use -t or --truncate to disable this extension for strict M80 compatibility.
See docs/EXTENSIONS.md for technical details on the extended REL format.
DRI Extensions
um80 supports several Digital Research (DRI) assembly syntax extensions commonly found in CP/M and MP/M source code. These extensions are compatible with DRI's ASM, MAC, and RMAC assemblers.
Multi-Statement Lines (! separator)
Multiple instructions can be placed on a single line, separated by !:
PUSH H! PUSH D! PUSH B ; Save registers
POP B! POP D! POP H ; Restore registers
MOV A,B! ORA A! RZ ; Test and return if zero
LOW and HIGH Operators
Extract the low or high byte of a 16-bit value using function-call syntax:
MVI L,LOW(BUFFER) ; Load low byte of address
MVI H,HIGH(BUFFER) ; Load high byte of address
MVI A,LOW(1234H) ; A = 34H
MVI B,HIGH(1234H) ; B = 12H
Both LOW(expr) and HIGH(expr) syntax (with parentheses) and LOW expr / HIGH expr syntax (with space) are supported.
Digit Separators in Numbers ($)
The $ character can be used as a visual separator within numeric literals for readability:
MVI A,1111$0000B ; Binary with separator
LXI H,1$0000H ; Hex: 10000H
MVI B,1$000D ; Decimal: 1000
The $ characters are ignored during parsing and do not affect the numeric value.
Register Aliases via EQU
Symbols can be defined with EQU to represent registers, then used in place of register names:
; Define register aliases using register names
UR EQU B ; UR is an alias for register B
LR EQU C ; LR is an alias for register C
MR EQU E ; MR is an alias for register E
KR EQU H ; KR is an alias for register H (or HL for pairs)
; Use aliases in instructions
MVI MR,0 ; Same as MVI E,0
MOV A,UR ; Same as MOV A,B
INR LR ; Same as INR C
LXI KR,0 ; Same as LXI H,0 (H maps to HL for pairs)
For register pair instructions, single register aliases are automatically promoted:
- B or C → BC
- D or E → DE
- H or L → HL
PUSH A / POP A
DRI assemblers allowed PUSH A and POP A as synonyms for PUSH PSW and POP PSW:
PUSH A ; Same as PUSH PSW (push A and flags)
POP A ; Same as POP PSW (pop A and flags)
Register number assignments (when using numeric values):
| Number | 8-bit Register | 16-bit Pair |
|---|---|---|
| 0 | B | BC |
| 1 | C | DE |
| 2 | D | HL |
| 3 | E | SP |
| 4 | H | - |
| 5 | L | - |
| 6 | M (memory) | - |
| 7 | A | - |
External Symbol Aliases (EQU external+offset)
Symbols can be defined as aliases to external symbols with an optional offset, then exported as PUBLIC:
; In library module - define entry points
EXTRN ADD10 ; External symbol from another module
PUBLIC ADD10_SKIP ; Export the alias
; Define alias: ADD10_SKIP is ADD10+2 (skip first instruction)
ADD10_SKIP EQU ADD10+2
This is useful for:
- Defining alternate entry points into routines (skipping initialization code)
- Creating symbolic offsets into data structures defined in other modules
- Porting code from assemblers that support this feature (like z88dk)
The alias is resolved at link time:
; In main module - use both symbols
EXTRN ADD10
EXTRN ADD10_SKIP
START: CALL ADD10 ; Call full routine
CALL ADD10_SKIP ; Call at offset (skips first 2 bytes)
For more details on these extensions and compatibility notes, see docs/EXTENSIONS.md.
Documentation
- Man pages:
man um80,man ul80,man ulib80,man ucref80,man ud80,man ux80 - Original Microsoft manuals in
docs/external/:m80.pdf- MACRO-80 assemblerl80.pdf- LINK-80 linkercref_lib.pdf- CREF and LIB-808080asm.pdf- 8080 assembly reference
Example Workflow
# Assemble source files
um80 -o main.rel main.mac
um80 -o util.rel util.mac
# Create a library
ulib80 -c mylib.lib helper.rel support.rel
# Link everything together
ul80 -o program.com main.rel util.rel mylib.lib
# Run in CP/M emulator
cpm program.com
Installing Man Pages
After pip installation, install the man pages manually:
# Find where the package is installed
PKGDIR=$(python3 -c "import um80; print(um80.__path__[0])")
# Copy man pages to system location (requires sudo)
sudo cp "$PKGDIR/../docs/man/"*.1 /usr/local/share/man/man1/
sudo mandb
Or view them directly:
man docs/man/um80.1
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
- uc80 - ANSI C compiler targeting Z80 processor and CP/M 2.2 operating system
- ucow - Unix/Linux Cowgol to Z80 compiler
- 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)
Project details
Release history Release notifications | RSS feed
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 um80-0.3.37.tar.gz.
File metadata
- Download URL: um80-0.3.37.tar.gz
- Upload date:
- Size: 119.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 |
ddc30da5f0eaadb336908769bf182dc4bcf6dee3d1d1a868727ce0349a2a2116
|
|
| MD5 |
421d3a8f22ea62209b65a6191040363f
|
|
| BLAKE2b-256 |
2f2e21a6ca6f2e49e7396178fcb08ff7fa42404fcc56a261ae6b8ed40b7c185a
|
Provenance
The following attestation bundles were made for um80-0.3.37.tar.gz:
Publisher:
publish.yml on avwohl/um80_and_friends
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
um80-0.3.37.tar.gz -
Subject digest:
ddc30da5f0eaadb336908769bf182dc4bcf6dee3d1d1a868727ce0349a2a2116 - Sigstore transparency entry: 1194661876
- Sigstore integration time:
-
Permalink:
avwohl/um80_and_friends@67697e41ca22c5fa7f33932009e1a0a5b90a340c -
Branch / Tag:
refs/tags/v0.3.37 - Owner: https://github.com/avwohl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@67697e41ca22c5fa7f33932009e1a0a5b90a340c -
Trigger Event:
release
-
Statement type:
File details
Details for the file um80-0.3.37-py3-none-any.whl.
File metadata
- Download URL: um80-0.3.37-py3-none-any.whl
- Upload date:
- Size: 89.5 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 |
5acf809b6276d99b26336e533f67389c9a71511ce1d1ebef703a91e234bb844f
|
|
| MD5 |
b0d52d94e982c6755372d863e4b2433a
|
|
| BLAKE2b-256 |
9dd69a0aa4d8dcd801f415f09bd17cf6925813c915cd9558a032073805a77863
|
Provenance
The following attestation bundles were made for um80-0.3.37-py3-none-any.whl:
Publisher:
publish.yml on avwohl/um80_and_friends
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
um80-0.3.37-py3-none-any.whl -
Subject digest:
5acf809b6276d99b26336e533f67389c9a71511ce1d1ebef703a91e234bb844f - Sigstore transparency entry: 1194661877
- Sigstore integration time:
-
Permalink:
avwohl/um80_and_friends@67697e41ca22c5fa7f33932009e1a0a5b90a340c -
Branch / Tag:
refs/tags/v0.3.37 - Owner: https://github.com/avwohl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@67697e41ca22c5fa7f33932009e1a0a5b90a340c -
Trigger Event:
release
-
Statement type: