Skip to content

Latest commit

 

History

332 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CP/M-86 & MS-DOS Cross Development Environment


Overview

This project regroups a simple method to create a cross development environment for CP/M‑86. It happens that all DOS based tools can also be used for building DOS programs. This project was developed for myself in a nerdy spirit and for a lot of fun. Just sharing without any guarantees.

Language Compilers / Interpreters
C Aztec C 3.4 (K&R), Aztec C 4.2 (almost ANSI), DR C 1.11 (ansi2kr integrated), Microsoft C 5.1
Assembler SCP ASM, RASM‑86, ASM‑86 1.1, ASM‑86 3.2, MASM 1.1, MASM 5.10, NASM 3.02, CP/M‑80 ASM
Basic DR CBASIC 2.0, DR Personal Basic 1.2, MS Basic 5.21/5.22/5.28, TDL BASIC 3.05
Pascal Pascal MT+ 3.3, Turbo Pascal 3.02, PolyPascal‑86 3.11
Fortran‑77 DR Fortran‑77 4.0
COBOL Micro Focus Level II COBOL V2.1
PL/M‑86 Intel PL/M‑86 3.30
PL/I DR PL/I‑86 1.0
Lisp XLISP 1.1

Thanks

  • dmsc (https://github.com/dmsc) for the emu2 emulator, without which this project would not be nearly as pleasant to use.
  • johnsonjh (https://github.com/johnsonjh) for the emu2‑cpm86 fork, the hexcom rewrite, and portability/build fixes contributed to this project.

Where to find CP/M-86?

The source for CP/M‑86 doc, sources and binaries is http://www.cpm.z80.de.

A cleaned‑up distribution and kernel is available at https://github.com/tsupplis/cpm86-kernel. This distribution is working well in virtual environments, patched with all known patches, 'y2k' friendly (it contains the version of tod which sources are in this project) and AT friendly.

Key tools for CP/M-86 development

Compilers and language tools

Tool Version Description
Aztec C 4.2/4.10d Almost‑ANSI C89; c86.lib patched & improved, d11.lib for DOS 1.1
Aztec C 3.4/3.40a K&R/Legacy/"C86" C; c86.lib patched, patched preprocessor, otherwise as‑is
DR C 1.11 CP/M‑86 C compiler; passes drc860drc862, runtime clearl/clears.l86
MSC 5.1 Microsoft C compiler for DOS;
DR Fortran‑77 4.0 CP/M‑86; compiler f77.cmd+codegen.cmd, runtime f32s/l.obj, 8087.sim
Pascal MT+ 3.3 CP/M‑86; compiler mt+86.cmd, linker linkmt.cmd, assembler asmt86.cmd
Turbo Pascal 3.02 Last CP/M‑86 Borland release; compiler turbo.cmd, installer tinst.cmd
PolyPascal‑86 3.11 Integrated editor+compiler; small/BCD/8087 variants (ppas, ppbs, pp87)
DR CBASIC 2.0 (CP/M‑86) / 2.1 (DOS) Compiled BASIC; compiler cb86.exe, linker link86.exe
M2CBASIC 1.4 MS BASIC → CBASIC source converter; translator + runtime libs
DR Personal Basic 1.2 Interactive CP/M‑86 BASIC interpreter
MS Basic 5.22 (CP/M‑86) / 5.28 (DOS) Interpreted; patched binaries included
MS Basic 5.21 (CP/M‑80) / 4.51 "Old Basic" Run via tnylpo
TDL BASIC 3.05 Z‑80 CP/M‑80 BASIC; run via tnylpo
Intel PL/M‑86 3.30 Compiler plm86.exe, assembler asm86.exe, linker, librarian, locator
DR PL/I‑86 1.0 CP/M‑86; compiler pli.cmd, runtime plilib.l86, DIO sources
XLISP 1.1 Public‑domain Lisp interpreter; built from source with Aztec C 4.2
Micro Focus COBOL Level II V2.1 CP/M‑86; compiler cobol.cmd, runtime run.cmd

Assemblers

Tool Version Description
RASM‑86 / LINK‑86 / LIB‑86 XREF-86 1.4a / 2.02 / 1.3 / 1.1 DR DOS assembler toolchain
ASM‑86 + GENCMD 1.1 DR assembler; CP/M‑80 and CP/M‑86 versions
XLT86 1.3 DR 8080/8085 → 8086 translator; xlt86.com + overlays; run via tnylpo
TRANS 2.21A SCP/Microsoft Z80 to 8086 Translator; runs via emu2
MASM / LINK / ASM / LIB / EXE2BIN / HEX2BIN 1.1 and 5.10 / 3.65 / 2.44a / 3.10 / 2.4 / — Microsoft DOS assembler toolchain; masm patched for emu2 (https://github.com/tsupplis/pcdos11-hacking)
NASM 3.02+ Netwide assembler (native)
Intel ASM‑86 3.2 Part of Intel PL/M‑86 toolchain (asm86.exe)

Emulators and utilities

Tool Version Description
emu2‑cpm86 v2026.09‑C DOS/CP/M‑86 emulator (fork of emu2 with CP/M‑86 support)
tnylpo CP/M‑80 emulator; used for asm86.com, gencmd.com, XLT86, MS Basic 80
upx 5.2.1 Executable packer
lzexe (and utilities) 0.91‑ecm Executable packer
pc 1.1.2 Programmers calculator
crc Enhanced IBM PC‑DOS CRC.EXE‑compatible 32‑bit CRC utility
ARC86 / LU86 1.0 / 4.05 CP/M‑86 archive and library utilities for .ARC and .LBR files

License Considerations

No guarantees are made for any component. Use each at your own risk subject to the conditions below.

Component License / Status Reference
MS‑DOS tools (DOS 1.1, ASN, TRANS, MASM, LINK, Basic 86, MSC 5.1) MIT license LICENSE
Aztec C Freeware (conditions apply) aztecmuseum.ca
DR tools (RASM‑86, ASM‑86, CBASIC, DR C, Fortran‑77, Pascal MT+, Personal Basic, PL/I‑86, XLT86) DR/Caldera open‑source license license · faq
M2CBASIC (Comeau) Unclear ⚠️ m2cbasic.zip
Turbo Pascal 3.01A (Borland) Freely usable, not open source RC750 image
emu2 / emu2‑cpm86 GPL‑2.0 emu2 · emu2‑cpm86
tnylpo BSD‑3‑Clause LICENSE
pc MIT LICENSE
crc MIT‑0 LICENSE
lzexe / unlzexe / comtoexe / infoexe MIT LICENSE
NASM BSD‑2‑Clause nasm.us
hexcom.c (Jeffrey H. Johnson) MIT‑0 source
ansi2kr (Masaki Oba) BSD‑2‑Clause nabeta.tk
ARC86 (Reimer Mellin; CP/M‑86 port by D. J. Weatherall) Public domain source; private non-commercial use only for the CP/M‑86 modifications 86arkive.zip (stored in src/freetools)
LU86 (Paul J. Homchick) Unclear ⚠️ 86arkive.zip (stored in src/freetools)
XLISP 1.1 (David Betz) Public domain cpm86‑ports
PL/I Object Fixer GPL‑3.0 ccpm objfix
Intel PL/M‑86 3.30 Unclear ⚠️ PLM8086Tools.zip (stored in src/inteltools)
PolyPascal‑86 V3.11 (PolyData MicroCenter A/S) Unclear ⚠️
Micro Focus Level II COBOL V2.1 Unclear ⚠️
TDL BASIC 3.05 (Technical Design Labs) Unclear ⚠️

Prerequisites

Install any missing prerequisites with your favorite package manager.

Status Prerequisites
Required · C/C++ toolchain (C99/C++14): GCC or Clang · curl · CMake · dos2unix · git · GNU Coreutils · Gzip · GNU Make · GNU patch · Screen · tar · Wget · Info‑ZIP Unzip · ncurses · XZ Utils
Optional Docker, Podman, or equivalent (for containerized builds)

Script Mapping

When several tools can perform the same job, use the highest tier available:

  1. Native (native) — compiled for the host OS, no emulation overhead.
  2. DOS.exe/.com binary run under emu2.
  3. CP/M‑86.cmd binary run under emu2.
  4. CP/M‑80.com binary run under tnylpo — legacy fallback only.

For example, cpm86_asm86 (CP/M‑86, tier 3) is preferred over cpm_asm86 (CP/M‑80, tier 4), and cmdinfo (native, tier 1) is preferred over any DOS wrapper.

All the tools are wrapped in the bin directory for direct usage:

Category Tool Program Description
Assembler cpm_asm86 asm86.com DR assembler (CP/M‑80 tool)
Assembler cpm_gencmd gencmd.com DR H86 converter (CP/M‑80 tool)
Assembler cpm_xlt86 xlt86.com DR 8080→8086 translator (CP/M‑80, via tnylpo)
Assembler pcdev_trans trans.com SCP/Microsoft Z80 to 8086 Translator (DOS, via emu2)
Assembler cpm86_asm86 asm86.cmd DR assembler (CP/M‑86, via emu2, not working yet)
Assembler cpm86_gencmd gencmd.cmd DR H86 converter (CP/M‑86 via emu2, not working yet)
Assembler nasm (native) Netwide assembler
Assembler pcdev_asm asm.com Microsoft/86‑DOS assembler
Assembler pcdev_masm masm.exe Microsoft assembler
Assembler pcdev_masm11 masm11.exe Legacy Microsoft assembler
Assembler pcdev_rasm86 rasm86.exe DR assembler
Assembler pcdev_xref86 xref86.exe DR cross referencer
Assembler cpm_asm80 asm80.com DR 8008 assembler (CP/M‑80 tool) to support xlt86
Linkers / Librarians bin2cmd (native) CMD converter (native)
Linkers / Librarians exe2cmd (native) EXE to CMD converter (native)
Linkers / Librarians hexcom (native) HEX to COM translation
Linkers / Librarians pcdev_bin2cmd obsolete alias for bin2cmd
Linkers / Librarians pcdev_exe2bin exe2bin.exe Microsoft EXE converter
Linkers / Librarians pcdev_exe2cmd obsolete alias for exe2cmd
Linkers / Librarians pcdev_hex2bin hex2bin.com Microsoft HEX converter
Linkers / Librarians pcdev_lib86 lib86.exe DR librarian
Linkers / Librarians pcdev_link link.exe Microsoft linker
Linkers / Librarians pcdev_lib lib.exe Microsoft librarian
Linkers / Librarians pcdev_link86 linkcmd.exe DR linker for CP/M‑86 (alias)
Linkers / Librarians pcdev_linkcmd linkcmd.exe DR linker for CP/M‑86
Linkers / Librarians pcdev_linkexe linkexe.exe DR linker for DOS
Debuggers cpm86_ddt86 ddt86.cmd DDT‑86 debugger for CP/M‑86
Debuggers cpm86_sid86 sid86.cmd SID‑86 symbolic debugger/disassembler for CP/M‑86
Debuggers pcdev_sid86 sid86.exe SID‑86 symbolic debugger/disassembler for DOS; support is WIP
Debuggers pcdev_debug debug.com Microsoft DOS debugger; support is WIP
Debuggers pcdev_edebug edebug.com Microsoft DOS debugger by ECM; support is WIP
Debuggers pcdev_ldebug edebug.com Advanced DOS debugger by ECM
Basic cpm_mbasic mbasic.com Microsoft Basic 5.21 (8080 CP/M‑80, via tnylpo)
Basic cpm_obasic obasic.com Microsoft Basic 4.51 (8080 CP/M‑80, via tnylpo)
Basic cpm_tdlbasic tdlbasic.com TDL BASIC 3.05 (Z‑80 CP/M‑80, via tnylpo)
Basic cpm86_basic basic.cmd DR Personal Basic 1.2 (via cpm86)
Basic cpm86_mbasic mbasic86.cmd Microsoft Basic 5.22 (CP/M‑86, via emu2)
Basic drcbcpm_bc cb86.exe DR CBASIC compiler for CP/M‑86
Basic drcbcpm_link link86.exe DR CBASIC linker for CP/M‑86
Basic drcbdos_bc cb86.exe DR CBASIC compiler for DOS
Basic drcbdos_link linkexe.exe DR CBASIC linker for DOS
Basic m2cb_cvt m2cbasic.cmd M2CBASIC 1.4 MBASIC to CBASIC converter
Basic pcdev_mbasic mbasic86.com Microsoft Basic 5.28 (DOS, via emu2)
C ansi2kr (native) ANSI C to K&R C converter (native)
C aztec34_as as.exe Aztec assembler (v3.4)
C aztec34_cc cc.exe Aztec K&R C compiler (v3.4)
C aztec34_hex86 hex86.exe Aztec C H86 generator (v3.4)
C aztec34_lib lb.exe Aztec C lib (v3.4)
C aztec34_link ln.exe Aztec C linker (v3.4)
C aztec34_obd obd.exe Aztec C object dump (v3.4)
C aztec34_obj obj.exe Aztec C object lister (v3.4)
C aztec34_ord ord.exe Aztec C library ordering helper (v3.4)
C aztec34_sqz sqz.exe Aztec C object optimizer (v3.4)
C aztec42_as as.exe Aztec assembler (v4.2)
C aztec42_cc cc.exe Aztec ANSI C compiler (v4.2)
C aztec42_hex86 hex86.exe Aztec C H86 generator (v4.2)
C aztec42_lib lb.exe Aztec C lib (v4.2)
C aztec42_link ln.exe Aztec C linker (v4.2)
C aztec42_obd obd.exe Aztec C object dump (v4.2)
C aztec42_obj obj.exe Aztec C object lister (v4.2)
C aztec42_ord ord.exe Aztec C library ordering helper (v4.2)
C aztec42_sqz sqz.exe Aztec C object optimizer (v4.2)
C drccpm_cc drc860+861.cmd DR C 1.11 compiler (two‑pass)
C drccpm_link linkcmd.exe DR C 1.11 linker
C msc5_cl cl.exe Microsoft C 5.1 compiler (CL 5.10)
C msc5_lib lib.exe Microsoft C 5.1 librarian (LIB 3.10)
C msc5_link link.exe Microsoft C 5.1 linker (LINK 5.10a, patched)
COBOL mfcobol_cc cobol.cmd Micro Focus Level II COBOL compiler (CP/M‑86)
COBOL mfcobol_run run.cmd Micro Focus Level II COBOL runtime (CP/M‑86)
Emulation cpm86 cpm86.exe CP/M‑86 emulator (via emu2+dos)
Emulation emu2 (native) x86 DOS/CP/M‑86 emulator
Emulation tnylpo (native) CP/M‑80 emulator
Fortran drfcpm_fc f77.cmd DR Fortran‑77 4.0 compiler
Fortran drfcpm_link linkcmd.exe DR Fortran‑77 4.0 linker
Lisp cpm86_xlisp xlisp.cmd XLISP 1.1 interpreter (built from source)
Pascal cpm86_turbo turbo.cmd Turbo Pascal 3.01 (CP/M‑86)
Pascal drpmtcpm_asm asmt86.cmd Pascal MT+ 3.3 assembler
Pascal drpmtcpm_link linkmt.cmd Pascal MT+ 3.3 linker
Pascal drpmtcpm_pc mt+86.cmd Pascal MT+ 3.3 compiler
Pascal ppcpm_pp87 pp87.cmd PolyPascal‑86 V3.11 8087 FPU variant (CP/M‑86)
Pascal ppcpm_ppas ppas.cmd PolyPascal‑86 V3.11 compiler+editor (CP/M‑86)
Pascal ppcpm_ppbs ppbs.cmd PolyPascal‑86 V3.11 BCD business variant (CP/M‑86)
Pascal ppdos_pp87 pp87.com PolyPascal‑86 V3.11 8087 FPU variant (DOS)
Pascal ppdos_ppas ppas.com PolyPascal‑86 V3.11 compiler+editor (DOS)
Pascal ppdos_ppbs ppbs.com PolyPascal‑86 V3.11 BCD business variant (DOS)
PL/I drplicpm_link linkcmd.exe DR PL/I‑86 1.0 linker
PL/I drplicpm_pc pli.cmd DR PL/I‑86 1.0 compiler
PL/I drpli_objfix (native) PL/I Object Compatibility Fix for DR Linker
PL/M intel_asm86 asm86.exe Intel ASM‑86 assembler V3.2
PL/M intel_lib86 lib86.exe Intel librarian
PL/M intel_link link.exe Intel/Microsoft linker
PL/M intel_link86 link86.exe Intel linker
PL/M intel_loc86 loc86.exe Intel locator
PL/M intel_oh86 oh86.exe Intel object to hex converter
PL/M intel_plm86 plm86.exe Intel PL/M‑86 3.30 compiler
Misc cmdinfo (native) CMD info tool (native)
Misc doscat (native) Truncate files beyond ^Z
Misc tnylpo‑convert (native) converts text files to and from the CP/M format
Misc crc (native) Enhanced IBM PC‑DOS CRC.EXE‑compatible 32‑bit CRC utility
Misc pcdev_cmdinfo obsolete alias for cmdinfo
Misc cpm_arc86 arc86.cmd ARC86 archive utility for CP/M‑86 .ARC files
Misc cpm_lu86 lu86.cmd LU86 library utility for CP/M‑86 .LBR files
Misc upx (native) Executable packer for DOS and CP/M‑86 binaries
Misc pcdev_exepack exepack.exe Microsoft EXEPACK 4.06b executable packer (patched)
Misc pcdev_lzexe lzexe.exe LZEXE executable packer for DOS EXE files (ecm fork)
Misc pcdev_unlzexe unlzexe.exe Unpacker for DOS LZEXE packed executables (ecm fork)
Misc pcdev_comtoexe comtoexe.exe Converts DOS COM files to EXE format (ecm fork)
Misc pcdev_infoexe infoexe.exe Display information about a DOS EXE file (ecm fork)

Fetching the tools

The development environment can be assembled by using the following steps:

./fetch_tools
export PATH="$(pwd -P)"/bin
Component Source
Aztec C 4.2 AztecC86.zip
Aztec C 3.4 az8634b.zip
RASM‑86, LINK‑86, LIB‑86 tools86.zip (stored in src/drtools)
ASM‑86 + GENCMD (CP/M‑80) mpm862sr.zip (stored in src/drtools)
XLT86 1.3 xlt86.zip (stored in src/drpackages/xlt86)
ASM‑86 + GENCMD (CP/M‑86) cpm86‑kernel (GitHub)
DR C 1.11 + extra headers drc_86.zip · drc86111.zip (stored in src/drpackages/drc86cpm)
DR Fortran‑77 4.0 f77‑86.zip (stored in src/drpackages/drf77cpm)
Turbo Pascal 3.02 (CP/M‑86) RC750 image (stored in src/turbo)
PolyPascal‑86 3.11 PolyPascal (GitHub)
Pascal MT+ 3.3 mt8633cp.zip (stored in src/drpackages/drpmtcpm)
DR CBASIC 2.0/2.1 + libs cbasic86.zip · cb86toys.zip (stored in src/drpackages/cb86cpm, src/drpackages/cb86dos)
M2CBASIC 1.4 m2cbasic.zip
DR Personal Basic 1.2 datamuseum.dk (stored in src/drtools/basic.cmd)
MS Basic 5.21 (CP/M‑80) repository (local copy)
MASM, LINK, ASM, EXE2BIN, HEX2BIN, MS Basic 86/80 MS‑DOS (GitHub) + repository
cmdtools (cmdinfo, bin2cmd, exe2cmd) cpm86‑cmdtools (GitHub, built natively)
NASM nasm.us snapshots
UPX UPX releases (GitHub)
lzexe (and utilities) lzexe (pushbx.org, fork of the original
emu2‑cpm86 emu2‑cpm86 (GitLab, fork of emu2)
tnylpo tnylpo (GitLab)
Intel PL/M‑86 3.30 tools PLM8086Tools.zip (stored in src/inteltools)
DR PL/I‑86 1.0 pli86.zip (stored in src/drpackages/drplicpm)
MSC 5.1 MS‑DOS (GitHub, stored in src/mspackages/msc51)
ARC86 / LU86 86arkive.zip (stored in src/freetools)
XLISP 1.1 cpm86‑ports (GitHub, built from source with aztec42)
Micro Focus Level II COBOL LII‑COBOL‑CPM86.zip
TDL BASIC 3.05 (CP/M‑80) Nutting_ICE.zip

Clearing the directory is achieved by:

./clear_tools

Platform notes

Tested platforms
  • The build has been tested on IBM AIX (7.2 TL5+), GNU/Linux, NetBSD, FreeBSD, OpenBSD, OpenIndiana (illumos), and Solaris (11.4 SRU 81+). No special build steps (other than installing the appropriate prerequisites) are required most platforms.

  • See special build instructions below for IBM AIX and Solaris.

Solaris and OpenIndiana
  • On both Solaris 11.4 SRU 81+ and current OpenIndiana (illumos) systems, you must have GNU tar available as gtar and also provide your own dos2unix in the PATH. Invoke fetch_tools as follows:
    env PATH="/path/to/dos2unix:$(getconf PATH):$PATH" CC=gcc CXX=g++ ./fetch_tools
    Replace /path/to/dos2unix with the actual path where you built the software.
IBM AIX notes
  • On IBM AIX you must invoke fetch_tools as:

    env CC=gcc-13 CXX=g++-13 ./fetch_tools

    (If you have a version of GCC later than 13, adjust your invocations accordingly.)

    1. It is known that UPX 5.2.1 initially fails to build. As a workaround:

      cd archive/upx
      rm -rf build/release
    2. Edit the src/work.cpp file and (around line 159) change:

      // POSIX.1-2008
      times[0] = st->st_atim;
      times[1] = st->st_mtim;

      to this:

      times[0].tv_sec  = st->st_atim.tv_sec;
      times[0].tv_nsec = st->st_atim.tv_nsec;
      times[1].tv_sec  = st->st_mtim.tv_sec;
      times[1].tv_nsec = st->st_mtim.tv_nsec;
    3. Edit the src/util/xspan.h file and (around line 33) change:

      #ifndef WITH_XSPAN
      #define WITH_XSPAN 2
      #endif

      to this:

      #undef WITH_XSPAN
      #define WITH_XSPAN 1
    4. Edit the src/check/dt_xspan.cpp file and (around line 29), after the #include "../conf.h" line, delete all lines until the end of the file.

    5. Then rebuild UPX using the following command:

      sh -xc 'export PATH="/opt/freeware/bin:$PATH" && env OBJECT_MODE=64 CC="gcc-13 -maix64 -Wl,-b64 -D_ALL_SOURCE" CXX="g++-13 -maix64 -Wl,-b64 -D_ALL_SOURCE" gmake -j $(nproc) VERBOSE=1'
      cd ../..

    Once the steps above successfully complete, run env CC=gcc-13 CXX=g++-13 ./fetch_tool again the build will run to completion.

Download archive / offline rebuilds

Every file downloaded by fetch_tools (the Aztec, DR, CB86 and NASM archives, but not the git checkouts) is cached under archive/ instead of being deleted.

This keeps the build environment reproducible even if an upstream disappears:

  • If a download fails, fetch_tools falls back to the cached copy in archive/.
  • Set ARCHIVE_FIRST=1 to rebuild entirely from archive/ without touching the network (e.g. offline, or to pin exact versions):
    env ARCHIVE_FIRST=1 ./fetch_tools
  • clear_tools will not remove the archive/, so a cleared tree can always be rebuilt from the local cache.

Testing

The cpm86 tool is a cpm86 emulator for dos pulled with Aztec C. We have reverse engineered it and patch it to fix a few bugs and add some new features. It should not be relied on fully as some bugs surely remain, but it can be experimented with and works for many programs. For build tools DOS/CP/M‑80 emulations and DOS/CP/M‑80 cross compilations are far better options and proper emulation of CP/M‑86 is the best option for testing; PCE is a very good choice (http://www.hampa.ch/pce/).

Note that the enhanced cpm86 emulator supports padding records with EOF instead of NULL which may make working with text files easier, but because this behavior does not match real CP/M‑86, it's disabled by default and only enabled if you set CPM86_EOF=1, for example:

env CPM86_EOF=1 cpm86 program.cmd

This may be a next step:

  • automating pce, cpmtools
  • bootable/up‑to‑date CP/M‑86 floppy ...

Docker image

A Dockerfile is provided for this environment.

To build the container, from the repository root, run:

docker build --progress=plain --rm=true -t cpm86:latest -f docker/Dockerfile .

to use the created image, just ensure that the local path where the compilation happens is mounted properly:

docker run -it --rm -h cpm86 -v "$(pwd -P)":/work -w /work cpm86 pcdev_rasm86 helloa.a86
docker run -it --rm -h cpm86 -v "$(pwd -P)":/work -w /work cpm86 aztec34_cc helloc.c

The only difference on the command line happens with ;

pcdev_masm hellod \;

... becomes ...

docker run -it --rm -h cpm86 -v "$(pwd -P)":/work -w /work cpm86 pcdev_masm hellod '\\;'

Using the tools

Finally, a simple Makefile with a sample c, assembler for rasm86, assembler for asm86 is provided:

./test_crossdev

Basic Programs

VariantCommands
DR CBASIC (compiled, CP/M‑86)
drcbcpm_bc hellor.bas
drcbcpm_link hellor.cmd=hellor.o
cmdinfo hellor.cmd
MS BASIC → CBASIC (convert + compile)
m2cb_cvt hellomsb.bas
mv hellomsb.cb hellocvt.cb
drcbcpm_bc hellocvt.cb
drcbcpm_link hellocvt
cmdinfo hellocvt.cmd
MS Basic 5.22 (interpreted, CP/M‑86)
cpm86_mbasic hellomsb.bas
MS Basic 5.28 (interpreted, DOS)
pcdev_mbasic hellomsb.bas
MS Basic 5.21 (CP/M‑80, via tnylpo)
cpm_mbasic hellomsb.bas
MS Basic 4.51 "Old Basic" (CP/M‑80, via tnylpo)
cpm_obasic hellomsb.bas
TDL BASIC 3.05 (Z‑80 CP/M‑80, via tnylpo)
cpm_tdlbasic hellomsb.bas
DR Personal Basic 1.2 (interactive)
cpm86_basic

C Programs

aztec42 is the preferred compiler — it supports almost‑ANSI syntax and its runtime and CP/M‑86 library are actively improved. Use aztec34 only when strict K&R compatibility is required or for legacy builds.

drccpm_cc is the DR C 1.11 compiler for CP/M‑86. It runs two passes internally: drc860.cmd (preprocessor) produces ctemp.tok, then drc861.cmd (code generator) consumes it. When -r is given, a third pass (drc862.cmd) merges the listing and disassembly into a <source>.ili interlist file. Temp files are cleaned up via a trap regardless of success or failure. The DR C runtime libraries (clearl.l86, clears.l86) and link86.cmd are all staged in share/drc86cpm/. The redundant DISK3 tools (rasm86.cmd, lib86.cmd, xref86.cmd) are not staged.

drccpm_link and drfcpm_link are thin wrappers around link86.cmd - they set drive A to the current working directory (so .obj files are found there) and drive D to the tool share directory (so runtime libraries are found there). Link options are passed explicitly by the caller using the LINK‑86 [option] syntax. The following option(s) are recognized:

Option Description
$LD Search drive D for .l86 runtime libraries

This is not necessary with the wrappers.

VariantCommands
Aztec C 4.2 (preferred, almost‑ANSI)
aztec42_cc helloc.c
aztec42_sqz helloc.o
aztec42_link -o helloc.cmd helloc.o -lc86
cmdinfo helloc.cmd
Aztec C 3.4 (K&R legacy)
aztec34_cc helloc.c
aztec34_sqz helloc.o
aztec34_link -o helloc.cmd helloc.o -lc86
cmdinfo helloc.cmd
DR C 1.11 (K&R)
drccpm_cc -ohellodrc.obj hellodrc.c
drccpm_link 'hellodrc.cmd=hellodrc.obj'
cmdinfo hellodrc.cmd
DR C 1.11 (ANSI mode)
drccpm_cc -e -ohelloans.obj helloans.c
drccpm_link 'helloans.cmd=helloans.obj'
cmdinfo helloans.cmd
Microsoft C 5.1 (DOS)
msc5_cl -c hellomsc.obj hellomsc.c
msc5_link hellomsc.obj \;
emu2 hellomsc.exe

C runtime startup

aztec34_link/aztec42_link automatically prepend the matching C runtime startup object, so the $begin ‑> Croot_ ‑> main ‑> exit entry/exit code is always present. The startup is selected from the C library you link against:

Library Target / Model Startup
‑lc86 CP/M‑86 small begin86.o
‑lc / ‑lclc MS‑DOS small sbegin.o
‑lcl / ‑lcld MS‑DOS large lbegin.o

These startup objects are produced from the C libraries by fetch_tools (src/fetch/cross_aztec_startups). Without this, Aztec's single‑pass ln only pulls the startup from the library on demand, so a program that references no libc symbol — e.g. int main(void){ return 0; } — would link with no startup and crash on exit, and a program that references the startup indirectly (e.g. exit()) could fail to link (Undefined symbol: _exit_) unless the library was ordered with ord or passed twice (‑lc86 ‑lc86). Prepending the startup as a command‑line object fixes all of these cases, so neither ord nor a doubled library is needed. To restore the old behavior set AZTEC_NOSTARTUP=1, or force a specific startup with AZTEC_STARTUP=<obj‑in‑lib>.

Assembler Programs

VariantCommands
RASM‑86
pcdev_rasm86 helloa.a86 '$' pz sz
pcdev_linkcmd helloa '[$sz]'
cmdinfo helloa.cmd
ASM‑86 (CP/M‑86)
cpm_asm86 hellob.a86
cpm_gencmd hellob.h86
cmdinfo hellob.cmd
MASM
pcdev_masm hellod \;
pcdev_link hellod \;
pcdev_exe2bin hellod.exe
bin2cmd hellod.bin hellod.cmd
cmdinfo hellod.cmd
NASM
nasm hellon.asm -fbin -o hellon.bin
bin2cmd hellon.bin hellon.cmd
cmdinfo hellon.cmd
XLT86 (8080→8086) + ASM‑86Pass basename without extension. XLT86 translates CALL 5 to INT 224 (0E0h). "Number of Errors: 1" for ORG 100h is expected and harmless.
cpm_xlt86 hello80
cpm86_asm86 hello80.a86
cpm86_gencmd hello80.h86
cmdinfo hello80.cmd

Misc Languages

LanguageCommands
PolyPascal‑86 V3.11 (CP/M‑86) Interactive editor+compiler. Standard (ppas), BCD (ppbs), 8087 (pp87) variants.
ppcpm_ppas
The editor opens first. Use COMPILE then RUN. PPAS.HLP and PPAS.ERM found automatically on drive D.
Pascal MT+ 3.3 (CP/M‑86)
drpmtcpm_pc hellomt
drpmtcpm_link hellomt.cmd=hellomt,p:paslib/s
cmdinfo hellomt.cmd
DR Fortran‑77 4.0 (CP/M‑86, small model) Both compiler passes (f77.cmd + codegen.cmd) run internally; .cil/.cym intermediates cleaned up automatically.
drfcpm_fc hellof.f77
drfcpm_link 'hellof.cmd=hellof'
cmdinfo hellof.cmd
Micro Focus Level II COBOL V2.1 (CP/M‑86) Compiles .cbl to bytecode .int; runtime executes it.
mfcobol_cc hellocbl.cbl
mfcobol_run hellocbl.int
The cobol overlay is staged automatically and cleaned up on exit.
Intel PL/M‑86 3.30
intel_asm86 scd.a86
intel_plm86 hellop.plm debug 'optimize(3)'
pcdev_linkcmd hellop=scd,hellop '[data[ori[0]]'
cmdinfo hellop.cmd
DR PL/I‑86 1.0 (CP/M‑86)
drplicpm_pc hellopi
drplicpm_link 'hellopi.cmd=hellopi'
cmdinfo hellopi.cmd
XLISP 1.1 (CP/M‑86) Interactive by default. Pass a .lsp file to load and run it; use (exit) to terminate without waiting for input.
cpm86_xlisp hello.lsp
For an interactive session:
cpm86_xlisp
Drive D = tool dir (contains xlisp.cmd), drive C = CWD, so .lsp files are found automatically.

About

CP/M-86 cross development environment

Topics

Resources

Stars

31 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages