Skip to content

Commit acc6bff

Browse files
committed
added script to generate a clean CP/M disk with applications
- patch for cpmtools to be able to handle the Ceda disk format - updated diskdefs to be compliant with the cpmtools patch - updated gitignore with temporary directories
1 parent 35c57d4 commit acc6bff

4 files changed

Lines changed: 999 additions & 36 deletions

File tree

.gitignore

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
1-
build
1+
build/
2+
disks/
3+
cpmtools/
4+
.vscode/
5+
6+
*.bin
7+
*.com
8+
*.COM
9+
*.o
10+
*.lis
11+
*.def
12+
*.map
13+
*.sym
14+
*.bak

diskdefs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,13 @@
11
# Image exported from HxCFloppyEmulator with 9216 bytes as boot area (1st track
22
# head 0 and 1, with different format size).
33
diskdef sanco
4-
# Disk properties
5-
seclen 1024
6-
# 79 tracks double sided (1st track excluded)
7-
tracks 158
8-
# 5 sectors per track
9-
sectrk 5
10-
# Blocksize from CPM-BIOS
11-
blocksize 4096
12-
# Maxdir from CPM-BIOS
13-
maxdir 128
14-
# Why skew 2? I don't know
15-
skew 2
16-
# No boot track
17-
boottrk 0
18-
# Skip boot area
19-
offset 9216
20-
os 2.2
21-
end
22-
23-
# Image exported as before, but without boot area
24-
diskdef sanco-no-boot
25-
seclen 1024
26-
tracks 158
27-
sectrk 5
28-
blocksize 4096
29-
maxdir 128
30-
skew 2
31-
boottrk 0
32-
bootsec 0
33-
os 2.2
34-
end
35-
36-
# Image exported as before, but with tweaked boot area: added +1024bytes as
37-
# padding to make first track like the others (256 * 16 + 1024 = 1024 * 5)
38-
diskdef sanco-uniformed
394
seclen 1024
405
tracks 160
416
sectrk 5
427
blocksize 4096
438
maxdir 128
449
skew 2
4510
boottrk 2
11+
boottrkgeometry 256,16
4612
os 2.2
4713
end

makedisk.sh

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#!/bin/bash
2+
3+
# -----------------------------------------------------------------------------
4+
# SANCO CP/M 2.2 Disk Image Builder
5+
#
6+
# This script automates the process of:
7+
# - Preparing patched version of cpmtools for this platform
8+
# - Generating the boot track
9+
# - Patching SLF80037.COM (autoexec.bat) for a given locale
10+
# - Building final CP/M disk images with applications
11+
#
12+
# It creates three disk images by default: us, fr, it.
13+
# -----------------------------------------------------------------------------
14+
15+
set -euo pipefail
16+
IFS=$'\n\t'
17+
18+
# -----------------------------------------------------------------------------
19+
# Globals and constants
20+
# -----------------------------------------------------------------------------
21+
SCRIPT_DIR=$(dirname `realpath $0`) # Base directory where the script is run
22+
TMPFILES=() # Track temp files for cleanup
23+
CPMTOOLS_PREFIX="" # Set by prepare_cpmtools()
24+
25+
# Applications to be copied into the CP/M disk
26+
# CORE = code that has been reversed and can be assembled from source
27+
CORE_APPS=(COPY8003.COM FUNK00.COM PAR8003.COM SG8003.COM TRX62.COM)
28+
# EXTRA = all additional software that is not yet reversed (in this repo) or
29+
# we don't want to reverse
30+
# Applications from Digital Research
31+
EXTRA_APPS=(ASM.COM DDT.COM DUMP.COM LOAD.COM PIP.COM STAT.COM SUBMIT.COM XSUB.COM)
32+
# Useful applications not from Digital Research
33+
EXTRA_APPS+=(ED.COM MBASIC.COM)
34+
# Specific applications for Ceda/Sanco that we have not yet reversed
35+
EXTRA_APPS+=(RCX62.COM TERM80.COM FMT8003.COM CONFIG80.COM)
36+
37+
# -----------------------------------------------------------------------------
38+
# Helpers
39+
# -----------------------------------------------------------------------------
40+
41+
# Clean up temporary files on exit
42+
cleanup() {
43+
if [[ ${#TMPFILES[@]} -gt 0 ]]; then
44+
rm -rf -- "${TMPFILES[@]}"
45+
fi
46+
}
47+
trap cleanup EXIT
48+
49+
# Allocate a new temporary file or directory and track it for later cleanup
50+
# Return: sets TMP with the generated temporary path
51+
new_tmp() {
52+
TMP=$(mktemp "$@")
53+
TMPFILES+=("$TMP")
54+
}
55+
56+
# Simple logger for progress messages
57+
log() {
58+
echo -e "==> $*" >&2
59+
}
60+
61+
# Validate the locale to avoid invalid filenames or missing resources
62+
validate_locale() {
63+
case "$1" in
64+
us|fr|it) ;;
65+
*) echo "Invalid locale: $1" >&2; exit 1;;
66+
esac
67+
}
68+
69+
# -----------------------------------------------------------------------------
70+
# Prepare cpmtools (clone, patch, build)
71+
# -----------------------------------------------------------------------------
72+
prepare_cpmtools() {
73+
if [[ ! -d cpmtools ]]; then
74+
log "Cloning cpmtools repository..."
75+
git clone https://github.com/lipro-cpm4l/cpmtools.git
76+
fi
77+
78+
pushd cpmtools > /dev/null
79+
80+
if [[ ! -f .patched ]]; then
81+
log "Applying local patch to cpmtools..."
82+
git reset --hard # ensure clean tree before patch
83+
git apply ../patch/0001-feat-added-capability-to-handle-images-with-multiple.patch
84+
touch .patched
85+
fi
86+
87+
if [[ ! -f mkfs.cpm ]]; then
88+
log "Building cpmtools..."
89+
./configure
90+
make -j"$(nproc)" all
91+
touch .built
92+
fi
93+
94+
popd > /dev/null
95+
96+
# Set the base path for the patched version of cpmtools
97+
CPMTOOLS_PREFIX="$SCRIPT_DIR/cpmtools/"
98+
}
99+
100+
# -----------------------------------------------------------------------------
101+
# Generate boot track from CPM components
102+
# Return: sets BOOTTRACK variable pointing to the temporary boot track file
103+
# that will be copied into the final disk image
104+
# -----------------------------------------------------------------------------
105+
genboottrack() {
106+
log "Generating boot track..."
107+
local boottrack
108+
new_tmp
109+
boottrack=$TMP
110+
111+
make -C cpm build/cpm_bios.bin build/cpm_loader.bin > /dev/null
112+
113+
# Manually cut-and-paste parts of the CP/M components to assemble the boot track
114+
# See README.md for more info about the boot track format
115+
dd conv=notrunc oflag=append status=none bs=256 if=cpm/build/cpm_loader.bin of="$boottrack"
116+
dd conv=notrunc oflag=append status=none skip=3072 bs=1 count=512 if=cpm/cpm_bdos.bin of="$boottrack"
117+
dd conv=notrunc oflag=append status=none bs=256 count=13 if=cpm/build/cpm_bios.bin of="$boottrack"
118+
dd conv=notrunc oflag=append status=none bs=1024 count=2 if=cpm/cpm_ccp.bin of="$boottrack"
119+
dd conv=notrunc oflag=append status=none bs=1024 count=3 if=cpm/cpm_bdos.bin of="$boottrack"
120+
121+
BOOTTRACK="$boottrack"
122+
}
123+
124+
# -----------------------------------------------------------------------------
125+
# Patch SLF80037.COM with keyboard map + locale string
126+
# Return: sets SLF variable pointing to the temporary SLF80037.COM file that
127+
# will be copied into the final disk image
128+
# -----------------------------------------------------------------------------
129+
patchslf() {
130+
local locale=$1
131+
log "Patching SLF80037.COM for locale=$locale..."
132+
local slf80037
133+
new_tmp
134+
slf80037=$TMP
135+
136+
make -C applications build/SLF80037.COM > /dev/null
137+
cp applications/build/SLF80037.COM "$slf80037"
138+
139+
# Patch keyboard layout
140+
dd conv=notrunc bs=1 seek=7424 status=none \
141+
if="applications/localization/keymap_${locale}.bin" of="$slf80037"
142+
143+
# Patch 2-letter locale string at offset 303
144+
echo -n "$locale" | dd conv=notrunc,ucase bs=1 count=2 seek=303 status=none of="$slf80037"
145+
146+
SLF="$slf80037"
147+
}
148+
149+
# -----------------------------------------------------------------------------
150+
# Build one disk image for the given locale
151+
# -----------------------------------------------------------------------------
152+
makedisk() {
153+
local locale=$1
154+
validate_locale "$locale"
155+
local filename="disks/SANCO-CPM22_${locale}.bin"
156+
157+
log "Building disk image: $filename"
158+
159+
mkdir -p "$(dirname "$filename")"
160+
rm -f "$filename"
161+
162+
# Generate boot track
163+
genboottrack
164+
"$CPMTOOLS_PREFIX"mkfs.cpm -f sanco -b "$BOOTTRACK" "$filename"
165+
166+
# Patch SLF80037.COM "autoexec" with the requested locale file
167+
patchslf "$locale"
168+
"$CPMTOOLS_PREFIX"cpmcp -f sanco "$filename" "$SLF" 0:SLF80037.COM
169+
170+
# Add core applications
171+
log "Adding core applications..."
172+
make -C applications assemble > /dev/null
173+
for comfile in "${CORE_APPS[@]}"; do
174+
"$CPMTOOLS_PREFIX"cpmcp -f sanco "$filename" "applications/build/$comfile" 0:
175+
done
176+
177+
# Add extra applications copied from reference image
178+
log "Adding extra applications..."
179+
local apptmp
180+
new_tmp -d
181+
apptmp=$TMP
182+
for comfile in "${EXTRA_APPS[@]}"; do
183+
"$CPMTOOLS_PREFIX"cpmcp -f sanco SANCO8003_CPM_2.2fr.bin 0:"$comfile" "$apptmp/$comfile"
184+
"$CPMTOOLS_PREFIX"cpmcp -f sanco "$filename" "$apptmp/$comfile" 0:
185+
done
186+
}
187+
188+
# -----------------------------------------------------------------------------
189+
# Main
190+
# -----------------------------------------------------------------------------
191+
prepare_cpmtools
192+
193+
for loc in us fr it; do
194+
makedisk "$loc"
195+
done
196+
197+
log "All disk images were successfully built!"

0 commit comments

Comments
 (0)