Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ jobs:
uses: actions/checkout@v3
- name: Build and test of CP/M components
run: |
cd cpm
make assemble
make tests
- name: Build and test of CP/M applications
Expand Down
15 changes: 14 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
build
build/
disks/
cpmtools/
.vscode/

*.bin
*.com
*.COM
*.o
*.lis
*.def
*.map
*.sym
*.bak
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,19 @@ To better handle the disassmbley and analysis of the CP/M components, each one w
At the moment, only the loader and the BIOS are disassemblied.
To build them, just run

cd cpm
make assemble

To check the asm file consistency, run

cd cpm
make test

### Handle CP/M file system

The CP/M file system onto the `SANCO8003_CPM_2.2fr.bin` image may be accessed using the [cpmtools](http://www.moria.de/~michael/cpmtools/).
An appropriate disk definition file is needed (`diskdefs`), which is included in this repository.
Some of the applications, in particular the ones that are implemented for the Sanco computers, can be found dissassembled and commented in [applications](applications/README.md) folder.

#### Print the content of the disk

Expand Down
4 changes: 2 additions & 2 deletions applications/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
- [FMT8003.COM](https://github.com/BayoDev/Sanco_8000/blob/main/CP-M/DISASSEMBLY/FMT8003_disassembly.z80): disk format utility;
- [FUNK00.COM](FUNK00.COM.asm): keymap configuration;
- [PAR8003.COM](PAR8003.COM.asm): configure diskette units;
- REV.COM: delete files, **disassembly in progress**;
- [REV.COM](REV.COM): delete files;
- [RCX62.COM](https://github.com/BayoDev/Sanco_8000/blob/main/CP-M/DISASSEMBLY/RCX62_disassembly.z80): receive data from serial port;
- [SG8003.COM](SG8003.COM.asm): boot sector copier, used to change the boot program
- [SLF80037.COM](SLF80037.COM.asm): bootstrap application;
- [TERM80.COM](https://github.com/BayoDev/Sanco_8000/blob/main/CP-M/DISASSEMBLY/TERM80_disassembly.z80): serial terminal;
- TRX62.COM: send data through serial port, **disassembly in progress**;
- [TRX62.COM](TRX62.COM): send data through serial port;

## CP/M system tools and applications

Expand Down
2 changes: 1 addition & 1 deletion applications/SLF80037.COM.asm
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ shortcuts_str: ;[2080]
;; The system ROM code starts back here, same as before
romjunk1:
DB $3F,$FE,$FF,$C8,$06,$14,$3A,$B8,$FF,$FE,$03,$28,$02,$06
DB $40,$C5,$3A,$31,$2E,$31,$31,$39,$00,$C4,$ED,$4B,$B9,$FF
DB $40,$C5,$CD,$07,$C4,$0E,$4D,$CD,$00,$C4,$ED,$4B,$B9,$FF
DB $CD,$00,$C4,$3A,$B8,$FF,$4F,$CD,$00,$C4,$0E,$05,$3A,$B8
DB $FF,$FE,$03,$28,$02,$0E

Expand Down
3 changes: 3 additions & 0 deletions applications/localization/keymap_fr.bin
Git LFS file not shown
3 changes: 3 additions & 0 deletions applications/localization/keymap_it.bin
Git LFS file not shown
3 changes: 3 additions & 0 deletions applications/localization/keymap_us.bin
Git LFS file not shown
2 changes: 1 addition & 1 deletion applications/md5sum.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
22d027c28acc59b775c8a826194d9fc7 build/FUNK00.COM
2a75591c8b454c74df433ab1b58a47fd build/PAR8003.COM
5c6f140b44c03539fea2e30eab1bb138 build/PAR8003.relocated
8c0541188297d176ffa06d4cae53591f build/SLF80037.COM
88139c49cfba7e7cc6d7db12319702e2 build/SLF80037.COM
b022bb2d88531e11fd4f6fc4c89f31ed build/SLF80037.relocated
2b5ea330d652f8da9cc47b3038dadbf9 build/COPY8003.COM
8924c5c5c9f22f56f06dc1f913a091a4 build/SG8003.COM
Expand Down
2 changes: 1 addition & 1 deletion Makefile → cpm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ assemble: $(BIN)
build/%.bin: %.asm
$(QUIET) mkdir -p `dirname $@`
$(ECHO) ' ASM $<'
$(QUIET) zcc +z80 -subtype=none -o $@ $<
$(QUIET) z80asm -b -o$@ $<

%.chk: build/%.bin
$(ECHO) ' SUM $<'
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
36 changes: 1 addition & 35 deletions diskdefs
Original file line number Diff line number Diff line change
@@ -1,47 +1,13 @@
# Image exported from HxCFloppyEmulator with 9216 bytes as boot area (1st track
# head 0 and 1, with different format size).
diskdef sanco
# Disk properties
seclen 1024
# 79 tracks double sided (1st track excluded)
tracks 158
# 5 sectors per track
sectrk 5
# Blocksize from CPM-BIOS
blocksize 4096
# Maxdir from CPM-BIOS
maxdir 128
# Why skew 2? I don't know
skew 2
# No boot track
boottrk 0
# Skip boot area
offset 9216
os 2.2
end

# Image exported as before, but without boot area
diskdef sanco-no-boot
seclen 1024
tracks 158
sectrk 5
blocksize 4096
maxdir 128
skew 2
boottrk 0
bootsec 0
os 2.2
end

# Image exported as before, but with tweaked boot area: added +1024bytes as
# padding to make first track like the others (256 * 16 + 1024 = 1024 * 5)
diskdef sanco-uniformed
seclen 1024
tracks 160
sectrk 5
blocksize 4096
maxdir 128
skew 2
boottrk 2
boottrkgeometry 256,16
os 2.2
end
210 changes: 210 additions & 0 deletions makedisk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
#!/bin/bash

# -----------------------------------------------------------------------------
# SANCO CP/M 2.2 Disk Image Builder
#
# This script automates the process of:
# - Preparing patched version of cpmtools for this platform
# - Generating the boot track
# - Patching SLF80037.COM (autoexec.bat) for a given locale
# - Building final CP/M disk images with applications
#
# It creates three disk images by default: us, fr, it.
# -----------------------------------------------------------------------------

set -euo pipefail
IFS=$'\n\t'

# -----------------------------------------------------------------------------
# Globals and constants
# -----------------------------------------------------------------------------
SCRIPT_DIR=$(dirname `realpath $0`) # Base directory where the script is run
TMPFILES=() # Track temp files for cleanup
CPMTOOLS_PREFIX="" # Set by prepare_cpmtools()

# Applications to be copied into the CP/M disk
# CORE = code that has been reversed and can be assembled from source
CORE_APPS=(COPY8003.COM FUNK00.COM PAR8003.COM SG8003.COM TRX62.COM)
# EXTRA = all additional software that is not yet reversed (in this repo) or
# we don't want to reverse
# Applications from Digital Research
EXTRA_APPS=(ASM.COM DDT.COM DUMP.COM LOAD.COM PIP.COM STAT.COM SUBMIT.COM XSUB.COM)
# Useful applications not from Digital Research
EXTRA_APPS+=(ED.COM MBASIC.COM)
# Specific applications for Ceda/Sanco that we have not yet reversed
EXTRA_APPS+=(RCX62.COM TERM80.COM FMT8003.COM CONFIG80.COM)

# -----------------------------------------------------------------------------
# Helpers
# -----------------------------------------------------------------------------

# Clean up temporary files on exit
cleanup() {
if [[ ${#TMPFILES[@]} -gt 0 ]]; then
rm -rf -- "${TMPFILES[@]}"
fi
}
trap cleanup EXIT

# Allocate a new temporary file or directory and track it for later cleanup
# Return: sets TMP with the generated temporary path
new_tmp() {
TMP=$(mktemp "$@")
TMPFILES+=("$TMP")
}

# Simple logger for progress messages
log() {
echo -e "==> $*" >&2
}

# Validate the locale to avoid invalid filenames or missing resources
validate_locale() {
case "$1" in
us|fr|it) ;;
*) echo "Invalid locale: $1" >&2; exit 1;;
esac
}

# -----------------------------------------------------------------------------
# Prepare cpmtools (clone, patch, build)
# -----------------------------------------------------------------------------
prepare_cpmtools() {
if [[ ! -d cpmtools ]]; then
log "Cloning cpmtools repository..."
git clone -b cpm4l/cpmtools-2.21 https://github.com/lipro-cpm4l/cpmtools.git
fi

pushd cpmtools > /dev/null

if [[ ! -f .patched ]]; then
log "Applying local patch to cpmtools..."
git reset --hard # ensure clean tree before patch
git apply ../patch/0001-feat-added-capability-to-handle-images-with-multiple.patch
touch .patched
fi

if [[ ! -f mkfs.cpm ]]; then
log "Building cpmtools..."
./configure
make -j"$(nproc)" all
touch .built
fi

popd > /dev/null

# Set the base path for the patched version of cpmtools
CPMTOOLS_PREFIX="$SCRIPT_DIR/cpmtools/"
}

# -----------------------------------------------------------------------------
# Generate boot track from CPM components
# Return: sets BOOTTRACK variable pointing to the temporary boot track file
# that will be copied into the final disk image
# -----------------------------------------------------------------------------
genboottrack() {
log "Generating boot track..."
local boottrack
new_tmp
boottrack=$TMP

make -C cpm build/cpm_bios.bin build/cpm_loader.bin > /dev/null

# Manually cut-and-paste parts of the CP/M components to assemble the boot track
# See README.md for more info about the boot track format
dd conv=notrunc oflag=append status=none bs=256 if=cpm/build/cpm_loader.bin of="$boottrack"
dd conv=notrunc oflag=append status=none skip=3072 bs=1 count=512 if=cpm/cpm_bdos.bin of="$boottrack"
dd conv=notrunc oflag=append status=none bs=256 count=13 if=cpm/build/cpm_bios.bin of="$boottrack"
dd conv=notrunc oflag=append status=none bs=1024 count=2 if=cpm/cpm_ccp.bin of="$boottrack"
dd conv=notrunc oflag=append status=none bs=1024 count=3 if=cpm/cpm_bdos.bin of="$boottrack"

BOOTTRACK="$boottrack"
}

# -----------------------------------------------------------------------------
# Patch SLF80037.COM with keyboard map + locale string
# Return: sets SLF variable pointing to the temporary SLF80037.COM file that
# will be copied into the final disk image
# -----------------------------------------------------------------------------
patchslf() {
local locale=$1
log "Patching SLF80037.COM for locale=$locale..."
local slf80037

new_tmp
slf80037=$TMP

make -C applications build/SLF80037.COM > /dev/null
cp applications/build/SLF80037.COM "$slf80037"

if [[ $locale != "" ]]; then
# Patch keyboard layout
dd conv=notrunc bs=1 seek=7424 status=none \
if="applications/localization/keymap_${locale}.bin" of="$slf80037"

# Patch 2-letter locale string at offset 303
echo -n "$locale" | dd conv=notrunc,ucase bs=1 count=2 seek=303 status=none of="$slf80037"
fi

SLF="$slf80037"
}

# -----------------------------------------------------------------------------
# Build one disk image for the given locale
# -----------------------------------------------------------------------------
makedisk() {
local locale=$1
local filename="disks"
if [[ $locale != "" ]]; then
validate_locale "$locale"
filename="$filename/SANCO-CPM22_${locale}.bin"
else
filename="$filename/SANCO-CPM22.bin"
fi


log "Building disk image: $filename"

mkdir -p "$(dirname "$filename")"
rm -f "$filename"

# Generate boot track
genboottrack
"$CPMTOOLS_PREFIX"mkfs.cpm -f sanco -b "$BOOTTRACK" "$filename"

# Patch SLF80037.COM "autoexec" with the requested locale file
patchslf "$locale"
"$CPMTOOLS_PREFIX"cpmcp -f sanco "$filename" "$SLF" 0:SLF80037.COM

# Add core applications
log "Adding core applications..."
make -C applications assemble > /dev/null
for comfile in "${CORE_APPS[@]}"; do
"$CPMTOOLS_PREFIX"cpmcp -f sanco "$filename" "applications/build/$comfile" 0:
done

# Add extra applications copied from reference image
log "Adding extra applications..."
local apptmp
new_tmp -d
apptmp=$TMP
for comfile in "${EXTRA_APPS[@]}"; do
"$CPMTOOLS_PREFIX"cpmcp -f sanco SANCO8003_CPM_2.2fr.bin 0:"$comfile" "$apptmp/$comfile"
"$CPMTOOLS_PREFIX"cpmcp -f sanco "$filename" "$apptmp/$comfile" 0:
done
}

# -----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------
prepare_cpmtools

# Generate original image
makedisk ""

# Generate localized images
for loc in us fr it; do
makedisk "$loc"
done

log "All disk images were successfully built!"
Loading