Add global build script and VERSION file
Add build.sh for building all FusionX components: Z80 assembly ROMs, TZFS ROMs, CP/M variants, kernel modules, user-space apps, and CPLD bitstreams. Supports selective builds via --asm/--tzfs/--cpm/--drivers/ --cpld flags. Updated rebuilt binaries from build verification. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
440
build.sh
Executable file
440
build.sh
Executable file
@@ -0,0 +1,440 @@
|
||||
#!/bin/bash
|
||||
#########################################################################################################
|
||||
##
|
||||
## Name: build.sh
|
||||
## Created: March 2026
|
||||
## Author(s): Philip Smart
|
||||
## Description: FusionX global build script
|
||||
## Builds all software components for the FusionX tranZPUter board:
|
||||
## - Z80 assembly ROMs (monitor, MS BASIC, CP/M, TZFS)
|
||||
## - Linux kernel modules (z80drv, ttymzdrv) for each target machine
|
||||
## - User-space applications (sharpbiter, k64fcpu, z80ctrl)
|
||||
## - SPI tools (mspi_main)
|
||||
## - CPLD bitstreams for each target machine (requires Quartus Docker)
|
||||
##
|
||||
## Credits:
|
||||
## Copyright: (c) 2019-2026 Philip Smart <philip.smart@net2net.org>
|
||||
##
|
||||
## History: March 2026 - Initial global build script.
|
||||
##
|
||||
#########################################################################################################
|
||||
## This source file is free software: you can redistribute it and#or modify
|
||||
## it under the terms of the GNU General Public License as published
|
||||
## by the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This source file is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#########################################################################################################
|
||||
|
||||
set -e
|
||||
|
||||
# Root directory of the FusionX project.
|
||||
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Directories.
|
||||
SOFTDIR="${ROOT_DIR}/software"
|
||||
ASMDIR="${SOFTDIR}/asm"
|
||||
INCDIR="${ASMDIR}/include"
|
||||
TMPDIR="${SOFTDIR}/tmp"
|
||||
ROMDIR="${SOFTDIR}/roms"
|
||||
TOOLDIR="${SOFTDIR}/tools"
|
||||
CPLDDIR="${ROOT_DIR}/CPLD/v1.0"
|
||||
DRVDIR="${SOFTDIR}/FusionX/src/z80drv"
|
||||
TTYDIR="${SOFTDIR}/FusionX/src/ttymz"
|
||||
SPIDIR="${SOFTDIR}/FusionX/src/spitools"
|
||||
BINDIR="${SOFTDIR}/FusionX/bin"
|
||||
MODDIR="${SOFTDIR}/FusionX/modules"
|
||||
|
||||
# Tools.
|
||||
ASM_JAR="${TOOLDIR}/glass-0.5.1.jar"
|
||||
CROSS_PREFIX="arm-linux-gnueabihf-"
|
||||
|
||||
# Build targets.
|
||||
SOFTWARE_TARGETS="MZ80A MZ700 MZ2000"
|
||||
CPLD_TARGETS="MZ80A MZ700 MZ2000 PCW8256"
|
||||
|
||||
# Assembly build lists.
|
||||
BUILDROMLIST="mz2000_mon_1z001m mz2000_ipl_original mz2000_ipl_tzpu mz2000_ipl_fusionx mz800_1z_013b mz800_9z_504m mz800_iocs mz80afi monitor_sa1510 monitor_80c_sa1510 monitor_1z-013a monitor_80c_1z-013a monitor_1z-013a-km monitor_80c_1z-013a-km mz80b_ipl"
|
||||
BUILDMZFLIST="5z009-1b sa-5510_tzfs msbasic_mz80a msbasic_mz700 msbasic_tz40 msbasic_tz80 sharpmz-test"
|
||||
BUILDTZFSROMLIST="tzfs"
|
||||
BUILDTZFSMZFLIST="testtz"
|
||||
CPMVERSIONS="mz700_80c:0 mz80a_80c:1 mz80a_std:2"
|
||||
|
||||
# Counters for summary.
|
||||
PASS=0
|
||||
FAIL=0
|
||||
SKIP=0
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Helper functions.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
log_info() { echo "==> $*"; }
|
||||
log_ok() { echo " [OK] $*"; PASS=$((PASS + 1)); }
|
||||
log_fail() { echo " [FAIL] $*"; FAIL=$((FAIL + 1)); }
|
||||
log_skip() { echo " [SKIP] $*"; SKIP=$((SKIP + 1)); }
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Build all or selected FusionX components."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --all Build everything (default)"
|
||||
echo " --asm Build Z80 assembly ROMs only"
|
||||
echo " --tzfs Build TZFS ROM only"
|
||||
echo " --cpm Build CP/M only"
|
||||
echo " --drivers Build kernel modules and user-space apps only"
|
||||
echo " --spi Build SPI tools only"
|
||||
echo " --cpld Build CPLD bitstreams only (requires Quartus Docker)"
|
||||
echo " --clean Clean all build artifacts"
|
||||
echo " --help Show this help"
|
||||
echo ""
|
||||
echo "Software targets: ${SOFTWARE_TARGETS}"
|
||||
echo "CPLD targets: ${CPLD_TARGETS}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build Z80 Assembly ROMs and MZF files.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_asm_roms() {
|
||||
log_info "Building Z80 Assembly ROMs and MZF files..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble Z80 ROMs"
|
||||
return
|
||||
fi
|
||||
if [ ! -f "${ASM_JAR}" ]; then
|
||||
log_skip "GLASS assembler not found at ${ASM_JAR}"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
for f in ${BUILDROMLIST} ${BUILDMZFLIST}; do
|
||||
SRCNAME="${f}"
|
||||
ASMNAME="${f}.asm"
|
||||
OBJNAME="${f}.obj"
|
||||
SYMNAME="${f}.sym"
|
||||
ROMNAME="${f}.rom"
|
||||
MZFNAME="${f}.mzf"
|
||||
|
||||
# MS BASIC variant handling.
|
||||
case "${SRCNAME}" in
|
||||
msbasic_mz80a)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 0" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_mz700)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 1" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_tz40)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 2" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_tz80)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 3" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
esac
|
||||
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${ASMNAME}" "${TMPDIR}/${OBJNAME}" "${TMPDIR}/${SYMNAME}" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
if echo "${BUILDROMLIST}" | grep -qw "${SRCNAME}"; then
|
||||
cp "${TMPDIR}/${OBJNAME}" "${ROMDIR}/${ROMNAME}"
|
||||
log_ok "ROM: ${ROMNAME}"
|
||||
else
|
||||
cp "${TMPDIR}/${OBJNAME}" "${ROMDIR}/${MZFNAME}"
|
||||
log_ok "MZF: ${MZFNAME}"
|
||||
fi
|
||||
else
|
||||
log_fail "${SRCNAME}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Composite MZ-800 ROM.
|
||||
if [ -f "${ROMDIR}/mz800_1z_013b.rom" ] && [ -f "${ROMDIR}/mz800_cgrom.ori" ] && \
|
||||
[ -f "${ROMDIR}/mz800_9z_504m.rom" ] && [ -f "${ROMDIR}/mz800_iocs.rom" ]; then
|
||||
cat "${ROMDIR}/mz800_1z_013b.rom" "${ROMDIR}/mz800_cgrom.ori" \
|
||||
"${ROMDIR}/mz800_9z_504m.rom" "${ROMDIR}/mz800_iocs.rom" > "${ROMDIR}/mz800_ipl.rom"
|
||||
log_ok "ROM: mz800_ipl.rom (composite)"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build TZFS ROM for each machine+board combination.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_tzfs() {
|
||||
log_info "Building TZFS ROMs..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble TZFS"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
local DEFSFILE="${INCDIR}/tzfs_definitions.asm"
|
||||
local MACHINES="MZ80A MZ700 MZ2000"
|
||||
|
||||
for machine in ${MACHINES}; do
|
||||
# Set machine target in definitions.
|
||||
for m in MZ80A MZ700 MZ1500 MZ2000; do
|
||||
local val=0
|
||||
[ "${m}" = "${machine}" ] && val=1
|
||||
sed -i "s/^BUILD_${m}\s\+EQU\s\+[01]/BUILD_${m} EQU ${val}/" "${DEFSFILE}"
|
||||
done
|
||||
|
||||
# Set board to FusionX.
|
||||
sed -i "s/^BUILD_FUSIONX\s\+EQU\s\+[01]/BUILD_FUSIONX EQU 1/" "${DEFSFILE}"
|
||||
sed -i "s/^BUILD_PICOZ80\s\+EQU\s\+[01]/BUILD_PICOZ80 EQU 0/" "${DEFSFILE}"
|
||||
|
||||
for f in ${BUILDTZFSROMLIST} ${BUILDTZFSMZFLIST}; do
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${f}.asm" "${TMPDIR}/${f}.obj" "${TMPDIR}/${f}.sym" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
local lower_machine=$(echo "${machine}" | tr '[:upper:]' '[:lower:]')
|
||||
if echo "${BUILDTZFSROMLIST}" | grep -qw "${f}"; then
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}_${lower_machine}_fusionx.rom"
|
||||
log_ok "TZFS ROM: ${f}_${lower_machine}_fusionx.rom"
|
||||
else
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}_${lower_machine}_fusionx.mzf"
|
||||
log_ok "TZFS MZF: ${f}_${lower_machine}_fusionx.mzf"
|
||||
fi
|
||||
else
|
||||
log_fail "TZFS: ${f} (${machine})"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build CP/M for each version.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_cpm() {
|
||||
log_info "Building CP/M variants..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble CP/M"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
for ver in ${CPMVERSIONS}; do
|
||||
local FILEEXT=$(echo "${ver}" | cut -d: -f1)
|
||||
local BUILDVER=$(echo "${ver}" | cut -d: -f2)
|
||||
echo "BUILD_VERSION EQU ${BUILDVER}" > "${INCDIR}/cpm_buildversion.asm"
|
||||
|
||||
local all_ok=true
|
||||
for f in cbios cpm22; do
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${f}.asm" "${TMPDIR}/${f}.obj" "${TMPDIR}/${f}.sym" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}.bin"
|
||||
else
|
||||
log_fail "CP/M: ${f} (${FILEEXT})"
|
||||
all_ok=false
|
||||
fi
|
||||
done
|
||||
|
||||
if ${all_ok}; then
|
||||
cat "${ROMDIR}/cpm22.bin" "${ROMDIR}/cbios.bin" > "${ROMDIR}/cpm223_${FILEEXT}.bin"
|
||||
log_ok "CP/M: cpm223_${FILEEXT}.bin"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build kernel modules and user-space applications for each target machine.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_drivers() {
|
||||
log_info "Building kernel modules and user-space applications..."
|
||||
|
||||
if ! command -v ${CROSS_PREFIX}gcc &>/dev/null; then
|
||||
log_skip "ARM cross-compiler (${CROSS_PREFIX}gcc) not found"
|
||||
return
|
||||
fi
|
||||
|
||||
local KERNEL_DIR="${SOFTDIR}/linux/kernel"
|
||||
if [ ! -f "${KERNEL_DIR}/Makefile" ]; then
|
||||
log_skip "Kernel source tree not found at ${KERNEL_DIR}"
|
||||
return
|
||||
fi
|
||||
|
||||
for target in ${SOFTWARE_TARGETS}; do
|
||||
log_info " Target: ${target}"
|
||||
|
||||
# Build z80drv kernel module + user-space tools.
|
||||
# Must cd into directory because Makefile uses $(PWD) for kernel path.
|
||||
if [ -f "${DRVDIR}/Makefile" ]; then
|
||||
if (cd "${DRVDIR}" && make "${target}" 2>&1); then
|
||||
(cd "${DRVDIR}" && make install 2>&1) || true
|
||||
log_ok "z80drv + apps (${target})"
|
||||
else
|
||||
log_fail "z80drv (${target})"
|
||||
fi
|
||||
(cd "${DRVDIR}" && make clean 2>&1) || true
|
||||
fi
|
||||
|
||||
# Build ttymzdrv kernel module.
|
||||
if [ -f "${TTYDIR}/Makefile" ]; then
|
||||
if (cd "${TTYDIR}" && make "${target}" 2>&1); then
|
||||
(cd "${TTYDIR}" && make install 2>&1) || true
|
||||
log_ok "ttymzdrv (${target})"
|
||||
else
|
||||
log_fail "ttymzdrv (${target})"
|
||||
fi
|
||||
(cd "${TTYDIR}" && make clean 2>&1) || true
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build SPI tools.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_spi() {
|
||||
log_info "Building SPI tools..."
|
||||
|
||||
if ! command -v ${CROSS_PREFIX}gcc &>/dev/null; then
|
||||
log_skip "ARM cross-compiler (${CROSS_PREFIX}gcc) not found"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f "${SPIDIR}/Makefile" ]; then
|
||||
if (cd "${SPIDIR}" && make all 2>&1); then
|
||||
log_ok "SPI tools (mspi_main)"
|
||||
else
|
||||
log_fail "SPI tools"
|
||||
fi
|
||||
else
|
||||
log_skip "SPI tools Makefile not found"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build CPLD bitstreams for each target machine.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_cpld() {
|
||||
log_info "Building CPLD bitstreams..."
|
||||
|
||||
if ! command -v quartus_sh &>/dev/null; then
|
||||
log_skip "Quartus not found in PATH (use Quartus Docker: qp130)"
|
||||
return
|
||||
fi
|
||||
|
||||
for target in ${CPLD_TARGETS}; do
|
||||
local BUILDDIR="${CPLDDIR}/${target}/build"
|
||||
local PROJECT="tzpuFusionX_${target}"
|
||||
|
||||
if [ ! -f "${BUILDDIR}/${PROJECT}.qpf" ]; then
|
||||
log_skip "CPLD: No Quartus project for ${target}"
|
||||
continue
|
||||
fi
|
||||
|
||||
log_info " Compiling CPLD: ${target}"
|
||||
if (cd "${BUILDDIR}" && quartus_sh --flow compile "${PROJECT}" 2>&1); then
|
||||
if [ -f "${BUILDDIR}/output_files/${PROJECT}.pof" ]; then
|
||||
log_ok "CPLD: ${PROJECT}.pof"
|
||||
else
|
||||
log_fail "CPLD: ${target} (no .pof output)"
|
||||
fi
|
||||
else
|
||||
log_fail "CPLD: ${target}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Clean all build artifacts.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
do_clean() {
|
||||
log_info "Cleaning build artifacts..."
|
||||
|
||||
# Assembly temporaries.
|
||||
rm -f "${TMPDIR}"/*.obj "${TMPDIR}"/*.sym 2>/dev/null
|
||||
|
||||
# Driver build artifacts.
|
||||
if [ -f "${DRVDIR}/Makefile" ]; then
|
||||
(cd "${DRVDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
if [ -f "${TTYDIR}/Makefile" ]; then
|
||||
(cd "${TTYDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
if [ -f "${SPIDIR}/Makefile" ]; then
|
||||
(cd "${SPIDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
|
||||
log_ok "Clean complete"
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Main.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
BUILD_ASM=false
|
||||
BUILD_TZFS=false
|
||||
BUILD_CPM=false
|
||||
BUILD_DRIVERS=false
|
||||
BUILD_SPI=false
|
||||
BUILD_CPLD=false
|
||||
BUILD_ALL=false
|
||||
DO_CLEAN=false
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
BUILD_ALL=true
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--all) BUILD_ALL=true ;;
|
||||
--asm) BUILD_ASM=true ;;
|
||||
--tzfs) BUILD_TZFS=true ;;
|
||||
--cpm) BUILD_CPM=true ;;
|
||||
--drivers) BUILD_DRIVERS=true ;;
|
||||
--spi) BUILD_SPI=true ;;
|
||||
--cpld) BUILD_CPLD=true ;;
|
||||
--clean) DO_CLEAN=true ;;
|
||||
--help|-h) usage ;;
|
||||
*) echo "Unknown option: $1"; usage ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
echo "========================================"
|
||||
echo " FusionX Build System"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
if ${DO_CLEAN}; then
|
||||
do_clean
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ${BUILD_ALL} || ${BUILD_ASM}; then build_asm_roms; fi
|
||||
if ${BUILD_ALL} || ${BUILD_TZFS}; then build_tzfs; fi
|
||||
if ${BUILD_ALL} || ${BUILD_CPM}; then build_cpm; fi
|
||||
if ${BUILD_ALL} || ${BUILD_DRIVERS}; then build_drivers; fi
|
||||
if ${BUILD_ALL} || ${BUILD_SPI}; then build_spi; fi
|
||||
if ${BUILD_ALL} || ${BUILD_CPLD}; then build_cpld; fi
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " Build Summary"
|
||||
echo " Passed: ${PASS} Failed: ${FAIL} Skipped: ${SKIP}"
|
||||
echo "========================================"
|
||||
|
||||
if [ ${FAIL} -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
BIN
software/FusionX/bin/k64fcpu
vendored
BIN
software/FusionX/bin/k64fcpu
vendored
Binary file not shown.
BIN
software/FusionX/bin/sharpbiter
vendored
BIN
software/FusionX/bin/sharpbiter
vendored
Binary file not shown.
BIN
software/FusionX/bin/z80ctrl
vendored
BIN
software/FusionX/bin/z80ctrl
vendored
Binary file not shown.
BIN
software/FusionX/modules/z80drv.ko
vendored
BIN
software/FusionX/modules/z80drv.ko
vendored
Binary file not shown.
Reference in New Issue
Block a user