* build.sh: compile as `quartus_sh --flow compile <project> -c <revision>`
(the .qpf is the project, each .qsf a revision) - matching the Jenkins CI.
coreMZ has revisions coreMZ_E115/E75[_emuMZ|_SoftCPU]; CPLDs have one
revision == project. Validated: CPLD builds 0 errors.
* docker/QuartusPrime/Dockerfile.{13.0.1,13.1} - self-contained Web-Edition
images (from the MZ80A ones) for the MAX7000 CPLDs and the SW-700 v1.2
Cyclone III FPGA. Dockerfile.17.1 - Quartus 17.1 **Lite** (free, no licence
- the Jenkins CI uses the licensed Standard edition) for the SW-700 v1.3 /
Fusion Cyclone IV EP4CE115/EP4CE75, installed under xvfb with libglib2.0-0.
* setup_tranZPUter.sh + Windows .ps1/.cmd - install Docker + Java, clone
--recurse-submodules (pulls TZFS/zSoft/ZPU transparently), build the three
Quartus images, then build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
95 lines
6.1 KiB
Bash
Executable File
95 lines
6.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#########################################################################################################
|
|
## tranZPUter SW - Build Environment Setup (Linux / macOS)
|
|
## Copyright (c) 2019-2026 Philip Smart <philip.smart@net2net.org>. GPL v3. See license.txt.
|
|
##
|
|
## Prepares everything to build the tranZPUter SW loadable outputs (CPLD .pof, FPGA .sof/.jic, and the
|
|
## software: zOS, TZFS, monitor ROMs, CP/M). Three Quartus versions are needed and each runs inside a
|
|
## self-contained Docker image using the free Web/Lite Edition (no licence file):
|
|
## tzpu-quartus:13.0.1 - MAX7000 CPLDs tzpu-quartus:13.1 - Cyclone III (SW-700 v1.2)
|
|
## tzpu-quartus:17.1 - Cyclone IV (SW-700 v1.3 / Fusion)
|
|
## Java is used for the GLASS Z80 assembler (TZFS/ROMs/CP/M). The zOS/TZFS/ZPU sources come in as git
|
|
## submodules, so the clone pulls everything - the user needs to know nothing about them.
|
|
##
|
|
## Self-contained: copy just this file and run it; it clones the repo (with submodules) if needed.
|
|
## Usage: chmod +x setup_tranZPUter.sh && ./setup_tranZPUter.sh
|
|
## Env: TZPU_REPO_URL, TZPU_DIR (existing checkout), TZPU_ASSUME_YES=1 (non-interactive).
|
|
#########################################################################################################
|
|
|
|
set -uo pipefail
|
|
|
|
TZPU_REPO_URL="${TZPU_REPO_URL:-https://git.eaw.app/eaw/tranZPUter.git}"
|
|
IMG_CPLD="${TZPU_QUARTUS_CPLD_IMAGE:-tzpu-quartus:13.0.1}"
|
|
IMG_C3="${TZPU_QUARTUS_C3_IMAGE:-tzpu-quartus:13.1}"
|
|
IMG_C4="${TZPU_QUARTUS_C4_IMAGE:-tzpu-quartus:17.1}"
|
|
|
|
RED='\033[0;31m'; GRN='\033[0;32m'; YEL='\033[1;33m'; CYN='\033[0;36m'; NC='\033[0m'
|
|
info(){ echo -e "${CYN}[INFO]${NC} $*"; } ; ok(){ echo -e "${GRN}[OK]${NC} $*"; }
|
|
warn(){ echo -e "${YEL}[WARN]${NC} $*" >&2; } ; fail(){ echo -e "${RED}[FAIL]${NC} $*" >&2; exit 1; }
|
|
has(){ command -v "$1" >/dev/null 2>&1; }
|
|
ask(){ if [ "${TZPU_ASSUME_YES:-0}" = "1" ]; then return 0; fi; read -r -p "$1 [Y/n] " a; [ -z "$a" ] || [ "$a" = y ] || [ "$a" = Y ]; }
|
|
|
|
detect_os(){
|
|
if [ "$(uname)" = Darwin ]; then OS=macos; OS_NAME="macOS $(sw_vers -productVersion 2>/dev/null)"
|
|
elif [ -f /etc/os-release ]; then . /etc/os-release; OS="$ID"; OS_NAME="$PRETTY_NAME"
|
|
else OS=unknown; OS_NAME=Unknown; fi; ok "OS: ${OS_NAME}"
|
|
}
|
|
pkg_install(){ [ $# -eq 0 ] && return 0; case "$OS" in
|
|
debian|ubuntu|raspbian|linuxmint|pop) sudo apt-get update && sudo apt-get install -y "$@";;
|
|
fedora|rhel|centos|rocky|almalinux) sudo dnf install -y "$@";;
|
|
arch|manjaro|endeavouros) sudo pacman -S --needed "$@";;
|
|
macos) brew install "$@" || warn "brew issues; continuing.";;
|
|
*) warn "Install manually: $*";; esac; }
|
|
|
|
ensure_base(){
|
|
info "Checking base tools (git, curl, java)..."
|
|
local need=(); has git||need+=(git); { has curl||has wget; }||need+=(curl)
|
|
has java||{ case "$OS" in debian|ubuntu|raspbian|linuxmint|pop) need+=(default-jre);; macos) need+=(openjdk);; *) need+=(java);; esac; }
|
|
[ ${#need[@]} -gt 0 ] && { [ "$OS" = macos ] && ! has brew && fail "Homebrew required (https://brew.sh)."; ask "Install ${need[*]}?" && pkg_install "${need[@]}" || warn "ensure they are present."; }
|
|
has java && ok "Java: $(java -version 2>&1 | head -1)" || warn "Java missing - the TZFS/ROM/CPM (GLASS) build needs it."
|
|
}
|
|
ensure_docker(){
|
|
has docker || { [ "$OS" = macos ] && fail "Install Docker Desktop, start it, then re-run." || { ask "Install docker.io?" && pkg_install docker.io || fail "Docker required."; }; }
|
|
docker info >/dev/null 2>&1 || fail "Docker installed but not running - start it and re-run."; ok "Docker available."
|
|
}
|
|
resolve_root(){
|
|
if [ -n "${TZPU_DIR:-}" ]; then PROJ="${TZPU_DIR%/}"
|
|
elif [ -f ./build.sh ] && [ -d ./CPLD ] && [ -d ./FPGA ]; then PROJ="$(pwd)"
|
|
else
|
|
PROJ="${HOME}/tranZPUter"
|
|
if [ ! -d "${PROJ}/.git" ]; then info "Cloning ${TZPU_REPO_URL} (with submodules) into ${PROJ}..."
|
|
git clone --recurse-submodules "${TZPU_REPO_URL}" "${PROJ}" || fail "git clone failed."
|
|
else info "Updating ${PROJ} + submodules."; ( cd "${PROJ}" && git pull --ff-only || true; git submodule update --init --recursive || true ); fi
|
|
fi
|
|
[ -f "${PROJ}/build.sh" ] || fail "${PROJ} is not a tranZPUter checkout."
|
|
# Make sure the submodules (TZFS, zSoft, zpu) are present even for an existing checkout.
|
|
( cd "${PROJ}" && git submodule update --init --recursive 2>/dev/null || true )
|
|
ok "Checkout: ${PROJ}"
|
|
}
|
|
build_image(){ # $1=Dockerfile $2=tag $3=name
|
|
docker image inspect "$2" >/dev/null 2>&1 && { ok "$3 image ($2) already built."; return; }
|
|
info "Building the $3 Quartus image ($2) - large download + install (20-45 min)..."
|
|
docker build -f "${PROJ}/docker/QuartusPrime/$1" -t "$2" "${PROJ}/docker/QuartusPrime" || fail "Failed to build the $3 image."
|
|
ok "$3 image built ($2)."
|
|
}
|
|
|
|
echo ""; echo "==========================================================================="
|
|
echo " tranZPUter SW - Build Environment Setup (Linux / macOS)"
|
|
echo "==========================================================================="
|
|
detect_os; ensure_base; resolve_root; ensure_docker
|
|
build_image Dockerfile.13.0.1 "${IMG_CPLD}" "CPLD (Quartus 13.0.1)"
|
|
build_image Dockerfile.13.1 "${IMG_C3}" "FPGA SW-700 v1.2 (Quartus 13.1)"
|
|
build_image Dockerfile.17.1 "${IMG_C4}" "FPGA SW-700 v1.3 / Fusion (Quartus 17.1)"
|
|
|
|
echo ""
|
|
if ask "Build the default set now (SW-700 v1.3 CPLD + FPGA + software)?"; then
|
|
( cd "${PROJ}" && ./build.sh -t all ) && ok "Build complete - loadable outputs in build/output/." || warn "Build reported errors - see build/logs/."
|
|
fi
|
|
echo ""; echo "==========================================================================="
|
|
echo " Ready. Build with:"
|
|
echo " cd ${PROJ} && ./build.sh -t all # cpld + fpga + software (SW-700 v1.3)"
|
|
echo " ./build.sh -t fpga -M MZ80A -D E115 -C SoftCPU # one specific FPGA bitstream"
|
|
echo " ./build.sh -t cpld | -t software | -h"
|
|
echo " Loadable outputs are collected under build/output/ (.pof, .sof, .jic, ROMs)."
|
|
echo "==========================================================================="
|