Skip to content

Commit bdf7e5b

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 bdf7e5b

File tree

4 files changed

+994
-36
lines changed

4 files changed

+994
-36
lines changed

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

0 commit comments

Comments
 (0)