The toolchain¶
To compile, assemble, link, and run CP/M apps with the DCC C Compiler toolchain, you need two things: the DCC C Compiler tools
(dcc, dccmake, dccpeep, dccrtlstrip, plus DCCRTL.MAC, m80.com, and l80.com) and the ntvcm CP/M 2.2 emulator to run CP/M binaries, including m80.com, l80.com, and the resulting programs.
You build these tools once. After that, use them from any CP/M app project.
Setup flow:
- Install the host prerequisites for Windows, macOS, or Linux.
- Clone the DCC C Compiler (
dcc) andntvcmrepositories. - Build the DCC C Compiler host tools with
pwsh ./scripts/build-dcc.ps1. - Build the ntvcm emulator.
- Add the DCC C Compiler and ntvcm directories to your
PATH. - Verify the setup with a sample CP/M program.
Install prerequisites¶
Install the native compiler tools for your host platform before cloning and building DCC C Compiler or ntvcm.
-
Install Visual Studio Build Tools with the C++ workload. Install with
winget:winget install --id Microsoft.VisualStudio.BuildTools -e --override "--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --wait --norestart"You can also use the Visual Studio Installer and select Desktop development with C++. The Windows build uses the Microsoft C/C++ compiler tools from that installation.
-
Install PowerShell 7 (
pwsh) from the Microsoft PowerShell install guide, then verify it is available:pwsh --version
-
Install the Xcode Command Line Tools:
xcode-select --installThis provides the clang and C++ compiler tools used by the macOS build scripts.
-
Install PowerShell 7 (
pwsh) with Homebrew or the Microsoft PowerShell install guide, then verify it is available:brew install --cask powershell pwsh --version
-
Install gcc, g++, make, and the usual build tools:
sudo apt install build-essential -
Install PowerShell 7 (
pwsh) using the package instructions for your Ubuntu release in the Microsoft PowerShell install guide, then verify it is available:pwsh --version
-
Install gcc, g++, make, and the usual build tools:
sudo apt install build-essential -
Install an ARM64 build of PowerShell 7 (
pwsh). If the package flow for your Ubuntu release is available, use the Microsoft PowerShell install guide. If not, use the officiallinux-arm64tarball from the PowerShell release page. To find the latest available version, check the PowerShell releases page or query the GitHub release metadata:curl -fsSL https://api.github.com/repos/PowerShell/PowerShell/releases/latest \ | sed -n 's/.*"tag_name": "v\([^"]*\)".*/\1/p'For a user-local install, set
versionto that release:version=7.6.3 install_dir="$HOME/.local/share/powershell/$version" archive="/tmp/powershell-${version}-linux-arm64.tar.gz" mkdir -p "$install_dir" "$HOME/.local/bin" curl -fL \ "https://github.com/PowerShell/PowerShell/releases/download/v${version}/powershell-${version}-linux-arm64.tar.gz" \ -o "$archive" tar -xzf "$archive" -C "$install_dir" chmod +x "$install_dir/pwsh" ln -sfn "$install_dir/pwsh" "$HOME/.local/bin/pwsh"Make sure
~/.local/binis on yourPATH, then verify both the version and architecture:export PATH="$HOME/.local/bin:$PATH" pwsh --version file "$(readlink -f "$HOME/.local/bin/pwsh")"The
fileoutput should reportARM aarch64.
-
Install Visual Studio Build Tools with the C++ workload and native ARM64 compiler tools. Install with
winget:winget install --id Microsoft.VisualStudio.BuildTools -e --override "--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.ARM64 --includeRecommended --quiet --wait --norestart"You can also use the Visual Studio Installer and select Desktop development with C++, then add the MSVC ARM64/ARM64EC build tools component. The DCC C Compiler Windows build scripts use the native ARM64 MSVC environment (
vcvarsarm64.bat) when they run on Windows ARM64. -
Verify that the ARM64 MSVC tools were installed:
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" $installPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.ARM64 -property installationPath Test-Path "$installPath\VC\Auxiliary\Build\vcvarsarm64.bat"The final command should print
True. -
Install PowerShell 7 (
pwsh) from the Microsoft PowerShell install guide, then verify it is available:pwsh --version
Clone the repositories¶
# Clone DCC C Compiler
git clone https://github.com/davidly/dcc.git
# Clone the ntvcm z80 emulator
git clone https://github.com/davidly/ntvcm.git
Build DCC C Compiler¶
The cross-platform PowerShell build script is in the scripts directory. It
builds dcc, dccpeep, and dccrtlstrip, using MSVC on Windows, clang on
macOS, and gcc on Linux by default:
pwsh ./scripts/build-dcc.ps1
Build ntvcm¶
ntvcm is a C++ project. Build it from its own directory.
Open a Developer PowerShell or Developer Command Prompt so the Microsoft
C/C++ compiler (cl) is on your PATH, then run the Windows build script:
cd ntvcm
.\m.bat
Produces ntvcm.exe.
Open a terminal where the Xcode Command Line Tools are available, then run the macOS build script:
cd ntvcm
chmod +x mmac.sh
./mmac.sh
Produces the ntvcm executable.
Open a terminal where g++ is available, then run the Linux build script:
cd ntvcm
chmod +x m.sh
./m.sh
Produces the ntvcm executable.
Open a terminal where g++ is available, then run the Linux build script:
cd ntvcm
chmod +x m.sh
./m.sh
Produces the ntvcm executable.
Open a Developer PowerShell or Developer Command Prompt for ARM64 so the
Microsoft C/C++ compiler (cl) is on your PATH, then run the Windows
build script:
cd ntvcm
.\m.bat
Produces ntvcm.exe.
Set up your environment¶
Build scripts live in the scripts directory:
dcc-ma— installed package command for building one app on Windows, macOS, and Linuxscripts/ma.sh— source-checkout implementation for Linux/macOS without PowerShellscripts/ma.ps1— source-checkout implementation for Windows PowerShell 5.1 or PowerShell 7+scripts/runall.ps1— builds and verifies the test suite
Run the single-app shell helper directly on Linux/macOS, or run the PowerShell
scripts from your operating-system terminal or the VS Code terminal by changing
to the DCC C Compiler checkout, starting pwsh, and running ./scripts/ma.ps1 or
./scripts/runall.ps1.
They resolve each tool the same way: they use an environment variable if you set
one, otherwise they look for the tool on your PATH. The relevant tools are:
dcc— compilerdccmake— build pipeline helperdccpeep— peephole optimizerdccrtlstrip— runtime stripperntvcm— CP/M emulatorm80/l80— assembler and linker
Recommended setup, especially when building apps in a project outside the DCC C Compiler
repo, is to add the directories containing the built dcc and ntvcm
binaries to your PATH. The DCC C Compiler directory also provides dccpeep,
dccrtlstrip, m80.com, l80.com, and DCCRTL.MAC, so no per-tool variables
are needed.
-
Add the DCC C Compiler and ntvcm directories to
PATHfor the current PowerShell session:$env:PATH += ";C:\path\to\dcc;C:\path\to\ntvcm" -
To make that permanent for your Windows user account, update the user
PATHand then open a new terminal:$userPath = [Environment]::GetEnvironmentVariable("Path", "User") [Environment]::SetEnvironmentVariable("Path", "$userPath;C:\path\to\dcc;C:\path\to\ntvcm", "User") -
Replace
C:\path\to\dccandC:\path\to\ntvcmwith the actual directories. With this on yourPATH, the scripts finddcc,dccpeep,dccrtlstrip, andntvcmautomatically.
To pin specific binaries instead (for example, when juggling multiple
DCC C Compiler builds), set the environment variables to explicit paths and only
put ntvcm on PATH:
```powershell
$env:PATH += ";C:\path\to\ntvcm"
$env:DCC = "C:\path\to\dcc\dcc.exe"
$env:DCCPEEP = "C:\path\to\dcc\dccpeep.exe"
$env:DCCRTLSTRIP = "C:\path\to\dcc\dccrtlstrip.exe"
```
-
Add the DCC C Compiler and ntvcm directories to
PATHfor the current shell session:export PATH="$PATH:/path/to/dcc:/path/to/ntvcm" -
To make that permanent for the default zsh shell, append the same setting to
~/.zshrc, then open a new terminal or reload the file:printf '\nexport PATH="$PATH:/path/to/dcc:/path/to/ntvcm"\n' >> ~/.zshrc source ~/.zshrc -
Replace
/path/to/dccand/path/to/ntvcmwith the actual directories (e.g.~/GitHub/dccand~/GitHub/ntvcm). With this on yourPATH, the scripts finddcc,dccpeep,dccrtlstrip, andntvcmautomatically.
To pin specific binaries instead (for example, when juggling multiple
DCC C Compiler builds), set the environment variables to explicit paths and only
put ntvcm on PATH:
```bash
export PATH="$PATH:/path/to/ntvcm"
export DCC=/path/to/dcc/dcc
export DCCPEEP=/path/to/dcc/dccpeep
export DCCRTLSTRIP=/path/to/dcc/dccrtlstrip
```
-
Add the DCC C Compiler and ntvcm directories to
PATHfor the current shell session:export PATH="$PATH:/path/to/dcc:/path/to/ntvcm" -
To make that permanent for bash, append the same setting to
~/.bashrc, then open a new terminal or reload the file:printf '\nexport PATH="$PATH:/path/to/dcc:/path/to/ntvcm"\n' >> ~/.bashrc source ~/.bashrc -
Replace
/path/to/dccand/path/to/ntvcmwith the actual directories (e.g.~/GitHub/dccand~/GitHub/ntvcm). With this on yourPATH, the scripts finddcc,dccpeep,dccrtlstrip, andntvcmautomatically.
To pin specific binaries instead (for example, when juggling multiple
DCC C Compiler builds), set the environment variables to explicit paths and only
put ntvcm on PATH:
```bash
export PATH="$PATH:/path/to/ntvcm"
export DCC=/path/to/dcc/dcc
export DCCPEEP=/path/to/dcc/dccpeep
export DCCRTLSTRIP=/path/to/dcc/dccrtlstrip
```
-
Add the DCC C Compiler and ntvcm directories to
PATHfor the current shell session:export PATH="$PATH:/path/to/dcc:/path/to/ntvcm" -
To make that permanent for bash, append the same setting to
~/.bashrc, then open a new terminal or reload the file:printf '\nexport PATH="$PATH:/path/to/dcc:/path/to/ntvcm"\n' >> ~/.bashrc source ~/.bashrc -
Replace
/path/to/dccand/path/to/ntvcmwith the actual directories (e.g.~/GitHub/dccand~/GitHub/ntvcm). With this on yourPATH, the scripts finddcc,dccpeep,dccrtlstrip, andntvcmautomatically.
To pin specific binaries instead (for example, when juggling multiple
DCC C Compiler builds), set the environment variables to explicit paths and only
put ntvcm on PATH:
```bash
export PATH="$PATH:/path/to/ntvcm"
export DCC=/path/to/dcc/dcc
export DCCPEEP=/path/to/dcc/dccpeep
export DCCRTLSTRIP=/path/to/dcc/dccrtlstrip
```
-
Add the DCC C Compiler and ntvcm directories to
PATHfor the current PowerShell session:$env:PATH += ";C:\path\to\dcc;C:\path\to\ntvcm" -
To make that permanent for your Windows user account, update the user
PATHand then open a new terminal:$userPath = [Environment]::GetEnvironmentVariable("Path", "User") [Environment]::SetEnvironmentVariable("Path", "$userPath;C:\path\to\dcc;C:\path\to\ntvcm", "User") -
Replace
C:\path\to\dccandC:\path\to\ntvcmwith the actual directories. With this on yourPATH, the scripts finddcc,dccpeep,dccrtlstrip, andntvcmautomatically.
To pin specific binaries instead (for example, when juggling multiple
DCC C Compiler builds), set the environment variables to explicit paths and only
put ntvcm on PATH:
```powershell
$env:PATH += ";C:\path\to\ntvcm"
$env:DCC = "C:\path\to\dcc\dcc.exe"
$env:DCCPEEP = "C:\path\to\dcc\dccpeep.exe"
$env:DCCRTLSTRIP = "C:\path\to\dcc\dccrtlstrip.exe"
```
Verify the setup¶
With the tools on your PATH, build and run one of the DCC C Compiler repo's sample tests
to confirm everything is wired up. From your operating-system terminal or the VS
Code terminal, change to the DCC C Compiler checkout, start PowerShell, build
tests/tstr.c, then run the generated .COM file under ntvcm:
cd /path/to/dcc
pwsh
./scripts/ma.ps1 tstr -Mode fast # compiles tests/tstr.c -> TSTR.COM
ntvcm TSTR.COM # runs it under the emulator
The DCC C Compiler repo's tests/ programs are suitable samples for scratch projects, but
day-to-day work does not need to happen inside the DCC C Compiler repo. The tools build
CP/M apps from wherever your sources live. Once that works, move on to
Building and linking for the day-to-day workflow.