diff --git a/.gitignore b/.gitignore index 83ce18e..2f89fa0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ NDK .version-stamp tools/kickstart/workdir_*/ tools/kickstart/out/ +docs/internal/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a1919b7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "extern/ptable"] + path = extern/ptable + url = https://github.com/pulchart/amigaos-ptable diff --git a/Makefile b/Makefile index 7e3d344..747370b 100644 --- a/Makefile +++ b/Makefile @@ -6,22 +6,22 @@ # Release version: YYYYMMDD package date + optional in-progress suffix # (-dev, -rc1, ...). Empty suffix for a final release. -RELEASE_DATE = 20260614 -VERSION_SUFFIX = +RELEASE_DATE = 20260710 +VERSION_SUFFIX = -dev # compactflash.device version -CFD_MAJOR = 1 -CFD_MINOR = 44 -CFD_VERSION_SUFFIX = -CFD_DATE = 04.06.2026 - -# ptable.library version; bumped only on library-ABI changes: -# - additive LVOs bump REVISION -# - breaking changes bump MAJOR -PLIB_MAJOR = 1 -PLIB_MINOR = 1 -PLIB_VERSION_SUFFIX = -PLIB_DATE = 07.06.2026 +# 2.0: DOS-time automount of FAT MBR/GPT cards (per-unit MountAgent) on top +# of the shared partition.resource architecture (ptable.library v2). +CFD_MAJOR = 2 +CFD_MINOR = 0 +CFD_VERSION_SUFFIX = -dev +CFD_DATE = 10.07.2026 + +# compactflash.automount version (optional boot/automount module) +AUTOMOUNT_MAJOR = 2 +AUTOMOUNT_MINOR = 0 +AUTOMOUNT_VERSION_SUFFIX = -dev +AUTOMOUNT_DATE = 10.07.2026 # Tool-specific versions (MAJOR/MINOR + optional in-progress suffix, # same shape as CFD_* and PLIB_* above) @@ -46,10 +46,16 @@ VERSION = $(RELEASE_DATE)$(VERSION_SUFFIX) DATE = $(shell echo "$(RELEASE_DATE)" | sed 's/\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\3.\2.\1/') CFD_VERSION = $(CFD_MAJOR).$(CFD_MINOR)$(CFD_VERSION_SUFFIX) VERSION_INC = src/cfd_version.i +AUTOMOUNT_VERSION = $(AUTOMOUNT_MAJOR).$(AUTOMOUNT_MINOR)$(AUTOMOUNT_VERSION_SUFFIX) +AUTOMOUNT_VERSION_INC = src/cfd_automount_version.i -# ptable.library version include (auto-generated like cfd_version.i) -PLIB_VERSION = $(PLIB_MAJOR).$(PLIB_MINOR)$(PLIB_VERSION_SUFFIX) -PLIB_VERSION_INC = src/lib/ptable_version.i +# ptable.library version/date read from the submodule build stamp +PLIB_VERSION = $(firstword $(shell cat $(PTABLE_VERSION_FILE) 2>/dev/null)) +PLIB_DATE = $(word 2,$(shell cat $(PTABLE_VERSION_FILE) 2>/dev/null)) + +# lsptres version/date read from the ptable build stamp. +LSPTRES_VERSION = $(firstword $(shell cat $(PTABLE_LSPTRES_VERSION_FILE) 2>/dev/null)) +LSPTRES_DATE = $(word 2,$(shell cat $(PTABLE_LSPTRES_VERSION_FILE) 2>/dev/null)) # Tool versions (derived) CFINFO_VERSION = $(CFINFO_MAJOR).$(CFINFO_MINOR)$(CFINFO_VERSION_SUFFIX) @@ -57,10 +63,12 @@ PCMCIASPEED_VERSION = $(PCMCIASPEED_MAJOR).$(PCMCIASPEED_MINOR)$(PCMCIASPEED_VER PCMCIACHECK_VERSION = $(PCMCIACHECK_MAJOR).$(PCMCIACHECK_MINOR)$(PCMCIACHECK_VERSION_SUFFIX) # Component table driving TOOLS_ALL and the README/dist auto-gen blocks. -COMPONENTS = CFD PLIB CFINFO PCMCIASPEED PCMCIACHECK +COMPONENTS = CFD AUTOMOUNT PLIB CFINFO PCMCIASPEED PCMCIACHECK LSPTRES CFD_NAME = compactflash.device CFD_KIND = device +AUTOMOUNT_NAME = compactflash.automount +AUTOMOUNT_KIND = module PLIB_NAME = ptable.library PLIB_KIND = library CFINFO_NAME = CFInfo @@ -69,6 +77,8 @@ PCMCIASPEED_NAME = pcmciaspeed PCMCIASPEED_KIND = tool PCMCIACHECK_NAME = pcmciacheck PCMCIACHECK_KIND = tool +LSPTRES_NAME = lsptres +LSPTRES_KIND = tool # "PREFIX|name|version|date" per component, fed to tools/components.sh # (the README.md block and the cfd.readme list both render from this). @@ -76,8 +86,10 @@ COMPONENT_ARGS = $(foreach c,$(COMPONENTS),'$(c)|$($(c)_NAME)|$($(c)_VERSION)|$( # Flavor x CPU fan-out for assembled artifacts (device, library). FLAVORS = full/68020 small/68020 full/68000 small/68000 +# compactflash.automount (KIND=module) ships in libs/ like the library. _subdir_device = devs _subdir_library = libs +_subdir_module = libs # Per-component "name:target:version:date" entries; device/library fan out over $(FLAVORS). define _artifact_entries @@ -137,11 +149,20 @@ VASM = $(VASM_HOME)/bin/vasmm68k_mot VBCC = $(VBCC_HOME)/bin/vc LHA = lha EXPECTED_VASM_VERSION = 2.0e +MD2GUIDE = tools/md2guide.py # Flags # VASMFLAGS is the base set shared by all tiers; per-tier CPU flag # (-m68020 / -m68000) is appended in the individual build rules. -VASMFLAGS = -Fhunkexe -nosym $(DEFINITIONS) +# ptable.library submodule (override PTABLE= to point elsewhere, e.g. a local +# checkout). +PTABLE ?= extern/ptable +PTABLE_SRC = $(PTABLE)/src +PTABLE_VERSION_FILE = $(PTABLE)/dist/ptable.version +PTABLE_LSPTRES_VERSION_FILE = $(PTABLE)/dist/lsptres.version + +# -I $(PTABLE_SRC) lets the driver resolve the submodule's ptable_pub.i. +VASMFLAGS = -Fhunkexe -nosym $(DEFINITIONS) -I $(PTABLE_SRC) VBCCFLAGS = +aos68k -O2 -c99 -INDK/Include_H # CPU tier flags @@ -164,21 +185,13 @@ OUTDIR_C = $(OUTDIR)/c SOURCE = $(SRCDIR)/cfd.s # Extra sources pulled in via "include" from cfd.s. Listed here so # a change to them triggers a rebuild of the driver targets below. -SOURCE_DEPS = $(LIBSRC)/ptable_pub.i \ +SOURCE_DEPS = $(PTABLE_SRC)/ptable_pub.i \ $(LIBSRC)/umul32.i \ $(LIBSRC)/log2.i \ $(LIBSRC)/udivmod32.i \ $(LIBSRC)/raw_debug.i -# Files: ptable.library -LIB_SOURCE = $(LIBSRC)/ptable_lib.s -# Extra sources pulled in via "include" from ptable_lib.s. Listed here -# so a change to any of them triggers a rebuild of the library targets. -LIB_SOURCE_DEPS = $(LIBSRC)/ptable_boot.s $(LIBSRC)/ptable_fs.s \ - $(LIBSRC)/ptable_hunk.s $(LIBSRC)/ptable_dosdiag.i \ - $(LIBSRC)/ptable_pub.i \ - $(LIBSRC)/umul32.i $(LIBSRC)/log2.i \ - $(LIBSRC)/raw_debug.i +# ptable.library is built by the $(PTABLE) submodule, not assembled here. # Per-flavor / per-cpu output drawers. # @@ -226,6 +239,20 @@ SOURCE_PCMCIASPEED = $(SRCDIR)/pcmciaspeed.c TARGET_PCMCIASPEED = $(OUTDIR_C)/pcmciaspeed SOURCE_PCMCIACHECK = $(SRCDIR)/pcmciacheck.c TARGET_PCMCIACHECK = $(OUTDIR_C)/pcmciacheck +# lsptres binary + guide are built by the $(PTABLE) submodule and copied +# from its dist/, so every release ships the ptable-built bytes. +TARGET_LSPTRES = $(OUTDIR_C)/lsptres + +# compactflash.automount: optional boot/automount bringup module (cold-boot +# autoboot + after-DOS device open), split out of compactflash.device. Shipped +# in libs/ per tier (full = boot serial, small = none); 68000-safe so the same +# binary runs on every CPU. Load only when autoboot/automount is wanted. +SOURCE_AUTOMOUNT = $(SRCDIR)/cfd_automount.s +AUTOMOUNT_TARGETS = \ + $(OUTDIR)/full/68020/libs/compactflash.automount \ + $(OUTDIR)/full/68000/libs/compactflash.automount \ + $(OUTDIR)/small/68020/libs/compactflash.automount \ + $(OUTDIR)/small/68000/libs/compactflash.automount # Files: Release RELEASE_NAME = cfd.v$(VERSION) @@ -239,7 +266,7 @@ README_INFO = dist/cfd.readme.info # ============================================================ # Default target - build all driver tiers, library, and tools -all: check-vasm version-readme $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) +all: check-vasm version-readme $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(AUTOMOUNT_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) $(TARGET_LSPTRES) # Generate version include file (always check, only update if changed) # Uses a stamp file to track the current version string @@ -268,26 +295,37 @@ $(VERSION_INC): $(VERSION_STAMP) $(Q)echo " endc" >> $@ $(Q)echo " endm" >> $@ -# ptable.library version include - regenerated whenever the library -# version macros above change (the stamp file already tracks the -# device VERSION; library version is bound to it because both are -# released as one archive). -$(PLIB_VERSION_INC): $(VERSION_STAMP) - $(Q)echo " VERSION ptable.library $(PLIB_VERSION)" +# compactflash.automount version include (own component version, stamp-tracked) +# Regenerated only when the Makefile (which holds the version/date) changes. +$(AUTOMOUNT_VERSION_INC): Makefile + $(Q)echo " VERSION compactflash.automount $(AUTOMOUNT_VERSION)" $(Q)echo "; Auto-generated by Makefile" > $@ - $(Q)echo "LIB_VERSION = $(PLIB_MAJOR)" >> $@ - $(Q)echo "LIB_REVISION = $(PLIB_MINOR)" >> $@ - $(Q)echo "LIB_VERSION_STRING macro" >> $@ - $(Q)echo " ifd __68020__" >> $@ - $(Q)echo " dc.b \"ptable.library $(PLIB_VERSION) ($(PLIB_DATE)) [68020]\"" >> $@ - $(Q)echo " else" >> $@ - $(Q)echo " dc.b \"ptable.library $(PLIB_VERSION) ($(PLIB_DATE)) [68000]\"" >> $@ - $(Q)echo " endc" >> $@ + $(Q)echo "FILE_VERSION = $(AUTOMOUNT_MAJOR)" >> $@ + $(Q)echo "FILE_REVISION = $(AUTOMOUNT_MINOR)" >> $@ + $(Q)echo "VERSION_STRING macro" >> $@ + $(Q)echo " dc.b \"compactflash.automount $(AUTOMOUNT_VERSION) ($(AUTOMOUNT_DATE))\"" >> $@ $(Q)echo " endm" >> $@ +# Build ptable.library in the submodule (produces all four tiers, lsptres, +# the guides, and the dist/*.version stamps that PLIB_*/LSPTRES_* read). +# Everything ptable-owned is copied from that build, never rebuilt here. +# MD2GUIDE/NDK are passed as absolute paths: the submodule's own relative +# defaults do not resolve from inside extern/ptable. +# Depends on the submodule Makefile: a pin bump or version/date change +# there must refresh the stamps, or changes.md keeps old component rows. +$(PTABLE_VERSION_FILE): $(PTABLE)/Makefile + $(Q)test -f $(PTABLE_SRC)/ptable_lib.s || { \ + echo "ERROR: ptable submodule missing at $(PTABLE)."; \ + echo " git submodule update --init, or build with PTABLE="; \ + exit 1; } + $(Q)$(MAKE) -C $(PTABLE) all guides MD2GUIDE=$(abspath $(MD2GUIDE)) NDK=$(abspath NDK) + # Rewrite the topmost release-notes header and the COMPONENTS block in # docs/changes.md from current Makefile vars. Add new release headers by hand. -version-readme: +# Depends on the submodule version stamp: PLIB_*/LSPTRES_* expand lazily +# from $(PTABLE)/dist/*.version, so stamping before that build exists +# writes empty "component ()" rows into changes.md. +version-readme: $(PTABLE_VERSION_FILE) $(Q)sed -i '0,/^## [0-9]\{8\}[^[:space:]]*/s/^## [0-9]\{8\}[^[:space:]]*/## $(VERSION)/' docs/changes.md $(Q)block="_Components in this release_:\n\n$$(sh tools/components.sh md $(COMPONENT_ARGS))"; \ awk -v block="$$block" ' \ @@ -309,14 +347,12 @@ $(DEVICE_TARGETS): $(OUTDIR)/%/devs/compactflash.device: $(SOURCE) $(SOURCE_DEPS $(Q)$(VASM) $(VASMFLAGS) $(VASMCPU_$(cpu)) $(DEBUG_$(flav)) -o $@ $< $(Q)echo " $$(stat -c%s $@) bytes, md5:$$(md5sum $@ | cut -c1-8)" -# ptable.library: dist///libs/ptable.library -$(LIBRARY_TARGETS): $(OUTDIR)/%/libs/ptable.library: $(LIB_SOURCE) $(LIB_SOURCE_DEPS) $(PLIB_VERSION_INC) - $(eval flav := $(word 1,$(subst /, ,$*))) - $(eval cpu := $(word 2,$(subst /, ,$*))) +# ptable.library: copied from the submodule build (dist///ptable.library) +# into our install tree at dist///libs/ptable.library. +$(LIBRARY_TARGETS): $(OUTDIR)/%/libs/ptable.library: $(PTABLE_VERSION_FILE) $(Q)mkdir -p $(@D) - $(Q)echo " VASM $@ [$(flav), $(cpu)]" - $(Q)$(VASM) $(VASMFLAGS) $(VASMCPU_$(cpu)) $(DEBUG_$(flav)) -o $@ $< - $(Q)echo " $$(stat -c%s $@) bytes, md5:$$(md5sum $@ | cut -c1-8)" + $(Q)cp $(PTABLE)/dist/$*/ptable.library $@ + $(Q)echo " PTABLE $@ [$*] (md5:$$(md5sum $@ | cut -c1-8))" # Per-tier convenience phonies (subsets of DEVICE_TARGETS / LIBRARY_TARGETS) full: check-vasm $(TARGET_FULL) @@ -331,24 +367,30 @@ library-full-000: check-vasm $(LIB_FULL_000) library-small-000: check-vasm $(LIB_SMALL_000) # Tools only target -tools: $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) +tools: $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) $(TARGET_LSPTRES) # Generate AmigaGuide documentation from Markdown GUIDE_OUTPUT_DIR = dist/docs GUIDE_CFD = $(GUIDE_OUTPUT_DIR)/cfd.guide +GUIDE_AUTOMOUNT = $(GUIDE_OUTPUT_DIR)/automount.guide GUIDE_CHANGES = $(GUIDE_OUTPUT_DIR)/changes.guide GUIDE_CFINFO = $(GUIDE_OUTPUT_DIR)/CFInfo.guide GUIDE_SPEED = $(GUIDE_OUTPUT_DIR)/pcmciaspeed.guide GUIDE_CHECK = $(GUIDE_OUTPUT_DIR)/pcmciacheck.guide -MD2GUIDE = tools/md2guide.py +GUIDE_LSPTRES = $(GUIDE_OUTPUT_DIR)/lsptres.guide -guide guides: $(GUIDE_CFD) $(GUIDE_CHANGES) $(GUIDE_CFINFO) $(GUIDE_SPEED) $(GUIDE_CHECK) +guide guides: $(GUIDE_CFD) $(GUIDE_AUTOMOUNT) $(GUIDE_CHANGES) $(GUIDE_CFINFO) $(GUIDE_SPEED) $(GUIDE_CHECK) $(GUIDE_LSPTRES) $(GUIDE_CFD): README.md $(MD2GUIDE) $(Q)mkdir -p $(GUIDE_OUTPUT_DIR) $(Q)echo " GUIDE $@" $(Q)$(MD2GUIDE) README.md $@ --version $(CFD_VERSION) --date $(CFD_DATE) --title "compactflash.device" --ver-title "compactflash.device guide" +$(GUIDE_AUTOMOUNT): docs/automount.md $(MD2GUIDE) + $(Q)mkdir -p $(GUIDE_OUTPUT_DIR) + $(Q)echo " GUIDE $@" + $(Q)$(MD2GUIDE) docs/automount.md $@ --version $(CFD_VERSION) --date $(CFD_DATE) --title "compactflash.device" --ver-title "automount guide" + $(GUIDE_CHANGES): docs/changes.md $(MD2GUIDE) $(Q)mkdir -p $(GUIDE_OUTPUT_DIR) $(Q)echo " GUIDE $@" @@ -369,27 +411,43 @@ $(GUIDE_CHECK): docs/pcmciacheck.md $(MD2GUIDE) $(Q)echo " GUIDE $@" $(Q)$(MD2GUIDE) docs/pcmciacheck.md $@ --version $(PCMCIACHECK_VERSION) --date $(PCMCIACHECK_DATE) --ver-title "pcmciacheck guide" -# CFInfo utility (requires vbcc) +# lsptres.guide: copied from the submodule build, not generated here. +$(GUIDE_LSPTRES): $(PTABLE_VERSION_FILE) + $(Q)mkdir -p $(GUIDE_OUTPUT_DIR) + $(Q)cp $(PTABLE)/dist/docs/lsptres.guide $@ + $(Q)echo " PTABLE $@" + $(TARGET_CFINFO): $(SOURCE_CFINFO) $(Q)mkdir -p $(OUTDIR_C) $(Q)echo " VBCC $(TARGET_CFINFO)" $(Q)VBCC=$(VBCC_HOME) PATH=$(VBCC_HOME)/bin:$$PATH $(VBCC) +aos68k -O2 -c99 -INDK/Include_H -DVERSION='"$(CFINFO_VERSION)"' -DDATE='"$(CFINFO_DATE)"' -o $(TARGET_CFINFO) $< $(Q)echo " $$(stat -c%s $(TARGET_CFINFO)) bytes, md5:$$(md5sum $(TARGET_CFINFO) | cut -c1-8)" -# pcmciaspeed utility (requires vbcc) $(TARGET_PCMCIASPEED): $(SOURCE_PCMCIASPEED) $(Q)mkdir -p $(OUTDIR_C) $(Q)echo " VBCC $(TARGET_PCMCIASPEED)" $(Q)VBCC=$(VBCC_HOME) PATH=$(VBCC_HOME)/bin:$$PATH $(VBCC) +aos68k -O2 -c99 -INDK/Include_H -DVERSION='"$(PCMCIASPEED_VERSION)"' -DDATE='"$(PCMCIASPEED_DATE)"' -o $(TARGET_PCMCIASPEED) $< $(Q)echo " $$(stat -c%s $(TARGET_PCMCIASPEED)) bytes, md5:$$(md5sum $(TARGET_PCMCIASPEED) | cut -c1-8)" -# pcmciacheck utility (requires vbcc) $(TARGET_PCMCIACHECK): $(SOURCE_PCMCIACHECK) $(Q)mkdir -p $(OUTDIR_C) $(Q)echo " VBCC $(TARGET_PCMCIACHECK)" $(Q)VBCC=$(VBCC_HOME) PATH=$(VBCC_HOME)/bin:$$PATH $(VBCC) +aos68k -O2 -c99 -INDK/Include_H -DVERSION='"$(PCMCIACHECK_VERSION)"' -DDATE='"$(PCMCIACHECK_DATE)"' -o $(TARGET_PCMCIACHECK) $< $(Q)echo " $$(stat -c%s $(TARGET_PCMCIACHECK)) bytes, md5:$$(md5sum $(TARGET_PCMCIACHECK) | cut -c1-8)" +# lsptres: copied from the submodule build (dist/c/lsptres), not compiled here. +$(TARGET_LSPTRES): $(PTABLE_VERSION_FILE) + $(Q)mkdir -p $(OUTDIR_C) + $(Q)cp $(PTABLE)/dist/c/lsptres $@ + $(Q)echo " PTABLE $@ (md5:$$(md5sum $@ | cut -c1-8))" + +$(AUTOMOUNT_TARGETS): $(OUTDIR)/%/libs/compactflash.automount: $(SOURCE_AUTOMOUNT) $(SRCDIR)/cfd_pub.i $(AUTOMOUNT_VERSION_INC) $(PTABLE_SRC)/ptable_pub.i + $(eval flav := $(word 1,$(subst /, ,$*))) + $(Q)mkdir -p $(@D) + $(Q)echo " VASM $@ [$(flav), automount]" + $(Q)$(VASM) $(VASMFLAGS) $(VASMCPU_68000) $(DEBUG_$(flav)) -o $@ $< + $(Q)echo " $$(stat -c%s $@) bytes, md5:$$(md5sum $@ | cut -c1-8)" + # ============================================================ # Release targets # ============================================================ @@ -399,7 +457,7 @@ $(TARGET_PCMCIACHECK): $(SOURCE_PCMCIACHECK) COMPONENT_VERSIONS_NL = $(shell sh tools/components.sh plain $(COMPONENT_ARGS)) # Generate readme from template -$(README_NAME): $(README_TEMPLATE) $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) +$(README_NAME): $(README_TEMPLATE) $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(AUTOMOUNT_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) $(TARGET_LSPTRES) @echo "Generating $(README_NAME) from template..." @tool_checksums=""; \ for tool_info in $(TOOLS_ALL); do \ @@ -425,7 +483,7 @@ $(README_NAME): $(README_TEMPLATE) $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET readme: $(README_NAME) # Create Aminet-compatible LHA release -release: check-vasm version-readme $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(README_NAME) guides check-lha +release: check-vasm version-readme $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(AUTOMOUNT_TARGETS) $(README_NAME) guides check-lha @echo "Creating Aminet release: $(ARCHIVE_NAME)" @echo "==================================" $(eval STAGING := $(shell mktemp -d)) @@ -433,8 +491,8 @@ release: check-vasm version-readme $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(README @echo "Copying files..." @# Per-flavor binary trees (cfd/full//{devs,libs}/) @cp -r dist/full dist/small "$(STAGING)/cfd/" - @# Flavor-shared assets (tools, mountlist, docs, images) - @cp -r dist/c dist/Storage dist/docs dist/images "$(STAGING)/cfd/" + @# Flavor-shared assets (tools, mountlist, example config, docs, images) + @cp -r dist/c dist/Storage dist/ENVARC dist/docs dist/images "$(STAGING)/cfd/" @# Top-level icons paired with the top-level drawers/files above. @# (devs.info / libs.info are reused per-flavor below, not at @# the cfd/ root - there are no top-level devs/ or libs/ drawers.) @@ -500,8 +558,8 @@ check-lha: # ============================================================ # Show checksums for all built artifacts -checksums: $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) - @for target in $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK); do \ +checksums: $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) $(TARGET_LSPTRES) + @for target in $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) $(TARGET_LSPTRES); do \ if [ -f "$$target" ]; then \ echo "=== $${target} ==="; \ ls -l "$$target"; \ @@ -514,7 +572,8 @@ checksums: $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIA # Clean build artifacts clean: - rm -f $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) $(VERSION_INC) $(PLIB_VERSION_INC) $(VERSION_STAMP) + rm -f $(DRIVER_TARGETS) $(LIBRARY_TARGETS) $(AUTOMOUNT_TARGETS) $(TARGET_CFINFO) $(TARGET_PCMCIASPEED) $(TARGET_PCMCIACHECK) $(TARGET_LSPTRES) $(VERSION_INC) $(VERSION_STAMP) $(AUTOMOUNT_VERSION_INC) + $(Q)[ ! -f $(PTABLE_SRC)/ptable_lib.s ] || $(MAKE) -C $(PTABLE) clean $(Q)for d in $(OUTDIR)/full $(OUTDIR)/small ; do \ [ ! -d $$d ] || find $$d -depth -type d -empty -delete ; \ done @@ -577,6 +636,7 @@ help: @echo " $(TARGET_CFINFO) - card info utility" @echo " $(TARGET_PCMCIASPEED) - pcmcia speed/timing benchmark utility" @echo " $(TARGET_PCMCIACHECK) - pcmcia check utility" + @echo " $(TARGET_LSPTRES) - partition.resource lister" @echo " $(README_NAME) - Aminet readme" @echo " $(ARCHIVE_NAME) - Aminet release archive" @echo "" diff --git a/README.md b/README.md index 22c7d0d..81c1e44 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ See [docs/changes.md](docs/changes.md) for release news and history. ## Documentation Included +- [docs/automount.md](docs/automount.md) - autoboot, automount, and ENV:cfd.prefs configuration. - [docs/changes.md](docs/changes.md) - release notes and original CFD history. - [docs/CFInfo.md](docs/CFInfo.md) - CFInfo card information utility documentation. - [docs/pcmciaspeed.md](docs/pcmciaspeed.md) - PCMCIA timing benchmark documentation. @@ -48,7 +49,7 @@ The archive ships two flavours (`full` / `small`) and two CPU tiers (`68020+` / | full | 68000+ | full/68000/devs/compactflash.device | ~11.3 KB | | small | 68000+ | small/68000/devs/compactflash.device | ~8.0 KB | -Companion `ptable.library` binaries live next to the device in the same flavour/CPU tree (`//libs/ptable.library`). +Companion libraries live next to the device in the same flavour/CPU tree under `//libs/`: `ptable.library` (partition scan/mount) and the optional `compactflash.automount` (boot/automount bringup, only needed for autoboot or automount). Pick the tier that matches your CPU, then pick the full or small flavour: - Use the **full** version if you want serial debug output (`Flags = 8`) @@ -69,97 +70,35 @@ The inner `devs/` and `libs/` drawers map directly onto `SYS:Devs/` and `SYS:Lib Have fat95 installed on your system. Mount the drive by double-clicking `Storage/DOSDrivers/CF0`. +Inserted cards automount by default (with the optional `compactflash.automount` module active). To tune it, or disable it with `AUTOMOUNT 0`, copy the example config to `ENVARC:` (and `ENV:`): +``` +Copy cfd/ENVARC/cfd.prefs to ENVARC:cfd.prefs +Copy cfd/ENVARC/cfd.prefs to ENV:cfd.prefs +``` +See [docs/automount.md](docs/automount.md) for all keys and the optional `compactflash.automount` module. + For OS 3.5+: ``` Copy def_CF0.info sys:prefs/env-archive/sys Copy def_CF0.info env:sys ``` -## Autoboot / Automount (ROM-resident) - -At Kickstart cold start `compactflash.device` opens `ptable.library`, which walks the RDB on the inserted card, registers any filesystem handlers stored in the RDB into `FileSystem.resource`, and publishes each partition via `AddBootNode` (bootable) or `AddDosNode` (mountable only). - -*ROM-resident requirement* - -`ptable.library` is **optional** for the driver. Without it, `compactflash.device` still works fully as a mount-only device via `DEVS:DOSDrivers/CF0` as example. It is **required** for autoboot and automount. To activate, both compactflash.device and ptable.library must be flashed into a ROM image. - -*Building your own ROM* - -A scripted Capitoline-based ROM builder for creating a 1 MB AmigaOS 3.2.3 / 3.1 / 2.05 Kickstart with `compactflash.device` + `ptable.library` embedded lives in the companion [amigaos-kickstart-builder](https://github.com/pulchart/amigaos-kickstart-builder) repo. - -*Partition handling* - -How each RDB partition is handled at boot: - -| RDB partition flag | BootPri | Result | -|--------------------|---------|--------| -| normal | ≥ 0 | bootable: appears in Early Startup boot device list | -| normal | < 0 | non-bootable: mounted as a DOS volume | -| NOMOUNT (bit 1 set) | any | skipped entirely: not mounted, not in DOS list | - -BootPri is stored in the RDB partition environment and controls boot order. +## Autoboot / Automount -*Boot order* +`compactflash.device` can boot straight from an RDB-partitioned CF card (ROM-resident only) and automount inserted cards at DOS time (RDB, MBR, GPT, and flat whole-disk FAT). Both are driven by `ptable.library` plus the optional `compactflash.automount` module; without them the device still works as a plain mount-only device. -The driver starts during Kickstart boot after the internal IDE is ready. The relevant modules in boot order are: +Automount is **on by default everywhere** (ROM-resident and file-based alike); disable it with `AUTOMOUNT 0` in `ENV:cfd.prefs` (see the example config above). Removing a card fully unmounts all supported filesystems by default; `UNMOUNT ` restricts it and `UNMOUNT NONE` keeps the handlers. The resident driver re-reads that file on every card insert and removal. -| Module | Role | -|--------|------| -| `card.resource` | PCMCIA slot initialised | -| `trackdisk.device` | floppy | -| `carddisk.device` | Kickstart built-in PCMCIA handler | -| `scsi.device` | internal IDE initialised | -| **`compactflash.boot`** | **CF card check + partition scan**. It opens `ptable.library`. `ptable.library` walks the RDB, registers any filesystem handlers it finds, and publishes each partition via `AddBootNode` (bootable) or `AddDosNode` (mountable only). | -| `strap` | boot menu / Workbench start | +The per-filesystem config keys (`UNMOUNT`, `FLAGS_`, `CONTROL_`) recognise exactly five filesystem names and no others: `DOS`, `FFS`, `SFS`, `PFS`, `FAT`. Any other name is silently ignored. See [docs/automount.md](docs/automount.md) for the full config reference. -The driver runs after the internal IDE is initialised, so it does not interfere with it. If the IDE stalls at boot (e.g. no drive connected), CF autoboot will not trigger either. - -*Cold-boot timing* - -The boot stub starts with a **no-card pre-gate**: a single read of the Gayle tells it whether a CF card is in the slot. If the slot is empty, the stub returns immediately. - -If a card IS present, the driver tolerates slow cards/adapters by polling for up to ~1.8 s in total (1 s for card-detect stabilisation, ~400 ms each for the two CIS tuple reads). Stable cards complete the first iteration of each loop, so a healthy card pays no measurable delay. +`compactflash.automount` provides the boot/automount bringup: in a ROM it gives cold-boot autoboot and opens the device after DOS so the automount agent runs; on disk you get the same run-time automount (hot-swap) by adding it to your startup-sequence with: +``` +LoadModule LIBS:compactflash.automount LIBS:ptable.library DEVS:compactflash.device +``` -*Boot debug output* +The full reference (the `ENV:cfd.prefs` keys, deployment matrix, removable-media model, cold-boot details and serial-debug output) lives in [docs/automount.md](docs/automount.md) (`automount.guide`). -`ptable.library` opens the device with `Flags=0`. Serial debug output at cold boot comes from a `full` build only and is unconditional, not gated by the mountlist `Flags = 8` setting. Two components emit output: `compactflash.device` uses the `[CFD] boot:` prefix, and `ptable.library` uses `[RDB]`: - -``` -[CFD] boot: open ptable.library ... -[CFD] boot: ptable.library not preloaded, InitResident()... -[CFD] boot: BootScanRDB(compactflash.device,0) -[RDB] scan -[RDB] found RDSK -[RDB] +fs PFS v20.0 -[RDB] skip SDH10 -[RDB] skip SDH11 -[RDB] +boot SDH0 -[RDB] +dos SDH1 -[RDB] +dos SDH2 -[RDB] done -``` - -| Line | Meaning | -|------|---------| -| `[CFD] boot: open ptable.library ...` | device opened ptable.library | -| `[CFD] boot: ptable.library not preloaded, InitResident()...` | library was not yet in memory; loaded from ROM via `InitResident()` | -| `[CFD] boot: BootScanRDB(compactflash.device,0)` | device hands off RDB scan to ptable.library for unit 0 | -| `[RDB] scan` | ptable.library begins scanning for the RDB | -| `[RDB] found RDSK` | RDB block located on the card | -| `[RDB] +fs PFS v20.0` | filesystem handler loaded from RDB (DosType + version) | -| `[RDB] skip SDH10` | partition skipped (NOMOUNT flag set in RDB) | -| `[RDB] +boot SDH0` | bootable partition registered via `AddBootNode` | -| `[RDB] +dos SDH1` | mountable-only partition registered via `AddDosNode` | -| `[RDB] done` | RDB scan complete | - -*Expansion board entry* - -`ptable.library` registers a synthetic expansion board entry so the Kickstart Early Startup boot menu sees the device. The entry is visible in expansion-board inspection tools (e.g. `ShowConfig`) as a board with the following identifiers: - -| Field | Value | -|-------|-------| -| Vendor ID | `65535 ($FFFF)` (as 'no vendor') | -| Product ID | `1` | +To build a Kickstart ROM with `compactflash.device` + `ptable.library` embedded, see the companion [amigaos-kickstart-builder](https://github.com/pulchart/amigaos-kickstart-builder) repo. ## Hardware Notes @@ -231,22 +170,22 @@ Use a adapter `DB-25 Female to DB-9 Male`, the adapter uses Straight-Through con Once the hardware is connected, monitor the serial port (e.g., `screen /dev/ttyUSB0 9600`, `minicom -b 9600 -o -D /dev/ttyUSB0`, `putty`) on remote computer to see online initialization process. -Cold boot (ROM-resident `ptable.library`, RDB-partitioned card): +Cold boot (ROM-resident `compactflash.automount` + `ptable.library`, RDB-partitioned card). The `[CFD] boot:` lines come from `compactflash.automount`, the `[PT]` lines from `ptable.library`: ``` -[CFD] boot: open ptable.library v1... +[CFD] boot: open ptable.library ... [CFD] boot: ptable.library not preloaded, InitResident()... -[CFD] boot: BootScanRDB(compactflash.device,0) -[RDB] scan -[RDB] found RDSK -[RDB] +fs PFS v20.0 -[RDB] +boot SDH0 -[RDB] +dos SDH1 -[RDB] done +[CFD] boot: BootScanPartitions(compactflash.device,0) +[PT] cold boot: scanning for partitions +[PT] RDB partition table +[PT] + filesystem handler PFS v20.0 +[PT] + boot SDH0 +[PT] + mount SDH1 +[PT] cold boot done, partitions registered: 2 ``` Card identification (hot-plug): ``` -[CFD] compactflash.device 1.42 (02.05.2026) [68020] +[CFD] compactflash.device 2.0-dev (10.07.2026) [68020] [CFD] Card inserted [CFD] Identifying card... [CFD] Reset @@ -256,7 +195,7 @@ Card identification (hot-plug): [CFD] Voltage: 5V [CFD] CIS gate [CFD] ..DEVICE: type=0x0D speed=400ns size=0x00000800 -[CFD] ..FUNCID: 0x04 +[CFD] ..FUNCEXT: link=0x02, type=0x01, ifc=0x01 [CFD] ..RESULT: accept [CFD] ..CONFIG: addr=0x00000200 (or: [CFD] ..CONFIG: default (0x200)) @@ -289,8 +228,25 @@ W248: 0000 0000 0000 0000 0000 0000 0000 0000 [CFD] ..done, multi RW: 256 [CFD] Card identified OK [CFD] Notify clients +[MW] config: read=-1 auto=1 flags=0 +[MW] scanning compactflash.device:0 for partitions +[PT] scanning for partitions +[PT] MBR partition table +[PT] partitions found: 1 +[MW] scan done, partitions known: 1 +[MW] mounting new partitions +[PT] mounting partitions +[PT] mounted CFa0 +[MW] mounted volumes: 1 [CFD] Card removed +[MW] config: read=-1 auto=1 flags=0 +[MW] card removed +[PT] card removed, media absent +[PT] unmounting partitions +[PT] unmounted CFa0 +[MW] entries detached: 1 ``` +The `[MW]` lines come from the automount mount worker (they appear when `compactflash.automount` is active), the `[PT]` lines from `ptable.library`. `read=-1` means no `ENV:cfd.prefs` is set, so the defaults apply (`auto=1`). #### Capturing serial output without a null-modem cable @@ -560,7 +516,7 @@ The driver auto-detects the transfer mode during card initialization by testing | BYTE (alt2) | 8-bit byte access via alternate register. Rarely used fallback mode. | | MMAP | Memory mapped word access. Direct memory transfer (requires PCMCIA memory mapping). | -Most CF cards work with WORD mode. The driver tests write/read patterns during initialization and falls back to BYTE modes if 16-bit access fails. The selected mode is shown in serial debug output as `[CFD] Transfer: WORD` or similar. +Most CF cards work with WORD mode. The driver tests write/read patterns during initialization and falls back to BYTE modes if 16-bit access fails. The selected mode is shown in serial debug output as `[CFD] ..done, transfer mode: WORD`. ## Tools diff --git a/dist.readme.in b/dist.readme.in index c0917fe..7cfb61c 100644 --- a/dist.readme.in +++ b/dist.readme.in @@ -5,7 +5,7 @@ Type: driver/media Version: @VERSION@ Requires: AmigaOS 2.0+, PCMCIA slot, CF-to-PCMCIA or SD-to-CF adapter Architecture: m68k-amigaos -Replaces: driver/media/cfd.v20260609.lha +Replaces: driver/media/cfd.v20260614.lha Kurz: CompactFlash PCMCIA Treiber fuer A600/1200 PCMCIA CompactFlash driver and supporting tools for Amiga 600/1200. Fork of driver/media/CFD133.lha. @@ -17,8 +17,21 @@ COMPONENTS IN THIS RELEASE CHANGES IN @DATE@ ===================== -Documentation-only update (no binaries changed). Release notes and -original CFD history are included in docs/changes.guide. +compactflash.device: + +* Automount: hotplugged cards mount automatically at DOS time (on by + default; disable with AUTOMOUNT 0 in the new ENV:cfd.prefs config + file). Removing a card unmounts all supported filesystems by default. + Boot and automount bringup is split into a separate + compactflash.automount module. See automount.guide. + +ptable.library: + +* Unified partition scanning: one scanner parses RDB, MBR, GPT, and + whole-disk FAT and publishes every partition into a shared + partition.resource, now used by both compactflash.device and fat95 + instead of each carrying its own. The new lsptres tool lists the + resource. Library: https://github.com/pulchart/amigaos-ptable FEATURES ======== @@ -26,6 +39,8 @@ FEATURES * TD64 and SCSI emulation support * Works with fat95 filesystem for FAT32 support, not excluding Amiga native (ffs, sfs, pfs) filesystems +* Scans and automounts RDB, MBR, GPT, and flat (whole-disk FAT) partition + tables via ptable.library * Serial debug output for troubleshooting (Flags = 8) * Transfer speeds up to 2.2 MB/s read, 1.9 MB/s write (in multi-sector mode if firmware supports it or with Flags = 16 override) @@ -44,16 +59,23 @@ The archive ships two flavours (full / small) and two CPU tiers, each as a sysroot ready to drop onto SYS:. 68020+ (A1200 stock, 68020+): - full/68020/devs/compactflash.device debug-capable - small/68020/devs/compactflash.device no debug code - full/68020/libs/ptable.library debug-capable - small/68020/libs/ptable.library no debug code + full/68020/devs/compactflash.device debug-capable + small/68020/devs/compactflash.device no debug code + full/68020/libs/ptable.library debug-capable + small/68020/libs/ptable.library no debug code + full/68020/libs/compactflash.automount optional, debug-capable + small/68020/libs/compactflash.automount optional, no debug code 68000 (stock A600, 68000+): - full/68000/devs/compactflash.device debug-capable - small/68000/devs/compactflash.device no debug code - full/68000/libs/ptable.library debug-capable - small/68000/libs/ptable.library no debug code + full/68000/devs/compactflash.device debug-capable + small/68000/devs/compactflash.device no debug code + full/68000/libs/ptable.library debug-capable + small/68000/libs/ptable.library no debug code + full/68000/libs/compactflash.automount optional, debug-capable + small/68000/libs/compactflash.automount optional, no debug code + + compactflash.automount is the optional boot/automount bringup module; + install it only if you want autoboot or automount (see AUTOBOOT/AUTOMOUNT). Choose based on your needs: - Use the full flavour if you need serial debug output (Flags = 8) @@ -68,6 +90,13 @@ Steps for normal mount-only use (no autoboot): 3. Have fat95 installed on your system 4. Mount the drive by double-clicking Storage/DOSDrivers/CF0 +Inserted cards automount by default. To tune it, or disable it with +AUTOMOUNT 0, copy the example config: + Copy ENVARC/cfd.prefs to ENVARC:cfd.prefs + Copy ENVARC/cfd.prefs to ENV:cfd.prefs +The resident driver re-reads cfd.prefs on every card insert and +removal. See automount.guide for all keys. + For autoboot, see the AUTOBOOT section below. For OS 3.5+: @@ -76,21 +105,40 @@ For OS 3.5+: AUTOBOOT/AUTOMOUNT ================== -Autoboot is now provided by a separate ptable.library shipped under -//libs/. At Kickstart cold start the compactflash.device -opens ptable.library and asks it to walk the RDB on the inserted card, -load any filesystem handlers carried in into FileSystem.resource, -and publish each partition via AddBootNode (bootable) or AddDosNode -(non-bootable). - -Both the compactflash.device and the ptable.library MUST be ROM-resident -for this to work. A disk-only ptable.library install is silently ignored. -The device driver still works as a normal mount-only device. - -On cold boot the driver tolerates slow cards and adapters by polling -for up to ~1.8s. When a card is present and stable the delay is zero. - -More details can be found in fat95's guide and GitHub project page. +Boot/automount is provided by ptable.library plus the optional +compactflash.automount module (both shipped under //libs/). +The plain compactflash.device on its own is a normal mount-only device. + +compactflash.automount carries two parts: + - cold-boot autoboot: at Kickstart cold start it walks the RDB on the + card, loads filesystem handlers into FileSystem.resource, and + publishes each partition via AddBootNode (bootable) / AddDosNode. + This needs compactflash.device + compactflash.automount + ptable.library + ROM-resident; a disk-only install is silently ignored. + - after-DOS bringup: it opens the device once DOS is up so the + card-detect interrupt and the automount agent start. + +Automount is ON by default everywhere. Disable it with AUTOMOUNT 0 in +ENV:cfd.prefs (copy ENVARC/cfd.prefs as shown in INSTALLATION). On +removal all supported filesystems are fully unmounted by default; +UNMOUNT restricts this, UNMOUNT NONE keeps the handlers. The +resident driver re-reads cfd.prefs on every card insert and removal. + +On disk (no ROM), you get the same run-time automount (hot-swap) by +adding to your user-startup-sequence: + LoadModule LIBS:compactflash.automount LIBS:ptable.library DEVS:compactflash.device +(plus L:fat95). LoadModule cannot provide cold-boot autoboot; that needs +a real ROM. + +The per-filesystem config keys (UNMOUNT, FLAGS_, CONTROL_) +recognise exactly five filesystem names and no others: DOS, FFS, SFS, +PFS, FAT. Any other name is silently ignored. + +FAT partitions still need fat95 loaded so its filesystem code is +registered. On cold boot the driver tolerates slow cards by polling for +up to ~1.8s; with a stable card the delay is zero. + +More details are in automount.guide. MOUNT FLAGS =========== @@ -111,7 +159,7 @@ With Flags = 8, connect serial cable and monitor at 9600 baud. The first line is a version banner that identifies the driver version and CPU tier ([68020] or [68000]): - [CFD] compactflash.device 1.42 (03.05.2026) [68020] + [CFD] compactflash.device 2.0-dev (10.07.2026) [68020] [CFD] Card inserted [CFD] Identifying card... [CFD] Reset @@ -156,19 +204,19 @@ line is a version banner that identifies the driver version and CPU tier [CFD] Notify clients [CFD] Card removed -Serial debug output at cold boot comes from a full build only and is unconditional, +Serial debug output at cold boot comes from a full build only and is unconditional, not gated by the mountlist Flags=8 setting. Two components emit output: -compactflash.device uses the [CFD] boot: prefix, and ptable.library uses [RDB]. +compactflash.automount uses the [CFD] boot: prefix, and ptable.library uses [PT]. Note that ptable.library opens the device with Flags=0, so the per-card identify log ([CFD] Reset, [CFD] CIS gate, etc.) is not printed during autoboot. [CFD] boot: open ptable.library ... [CFD] boot: ptable.library not preloaded, InitResident()... - [CFD] boot: BootScanRDB(compactflash.device,0) - [RDB] scan - [RDB] no RDB - [RDB] done + [CFD] boot: BootScanPartitions(compactflash.device,0) + [PT] cold boot: scanning for partitions + [PT] no partition table (not RDB/MBR/GPT/FAT) + [PT] cold boot done, partitions registered: 0 ENFORCE MULTI MODE (FLAG 16) @@ -272,19 +320,26 @@ cfd/small/68020/devs/compactflash.device - 68020+, no debug code cfd/full/68000/devs/compactflash.device - 68000+, debug-capable (serial output with Flags=8) cfd/small/68000/devs/compactflash.device - 68000+, no debug code -ptable.library (optional) enables autoboot and automount from RDB-partitioned cards; - must be ROM-resident to work, disk-only install has no effect: +ptable.library (optional) - partition scanner/automounter (RDB/MBR/GPT/FAT): cfd/full/68020/libs/ptable.library - 68020+, debug-capable (serial output always on at boot) cfd/small/68020/libs/ptable.library - 68020+, no debug code cfd/full/68000/libs/ptable.library - 68000+, debug-capable (serial output always on at boot) cfd/small/68000/libs/ptable.library - 68000+, no debug code +compactflash.automount (optional) - boot/automount bringup; install for autoboot (ROM) + or DOS-time automount (ROM, or on disk via LoadModule): +cfd/full/68020/libs/compactflash.automount - debug-capable (serial output always on at boot) +cfd/small/68020/libs/compactflash.automount - no debug code +cfd/full/68000/libs/compactflash.automount - debug-capable (serial output always on at boot) +cfd/small/68000/libs/compactflash.automount - no debug code + cfd/c/CFInfo - Card information utility (displays model, size, capabilities) cfd/c/pcmciacheck - PCMCIA check utility cfd/c/pcmciaspeed - Speed test utility cfd/Storage/DOSDrivers/CF0 - Mountlist entry (with flags documentation) cfd/Storage/DOSDrivers/CF0.info - Mountlist Workbench icon +cfd/ENVARC/cfd.prefs - Example config (copy to ENVARC:cfd.prefs to automount) cfd/docs/cfd.guide - Main documentation cfd/docs/changes.guide - Release notes and original CFD history diff --git a/dist/ENVARC/cfd.prefs b/dist/ENVARC/cfd.prefs new file mode 100644 index 0000000..95da688 --- /dev/null +++ b/dist/ENVARC/cfd.prefs @@ -0,0 +1,4 @@ +; compactflash.device config. copy to ENVARC:cfd.prefs (see automount.guide). +AUTOMOUNT 1 +FLAGS 0 +CONTROL_FAT -d-D+q diff --git a/dist/c/lsptres b/dist/c/lsptres new file mode 100755 index 0000000..966825d --- /dev/null +++ b/dist/c/lsptres @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6442cdb2d7153d23ff92491aa09000d279683f06c020be74ef517fa0daf70da +size 10524 diff --git a/dist/docs/automount.guide b/dist/docs/automount.guide new file mode 100644 index 0000000..55ae7cc --- /dev/null +++ b/dist/docs/automount.guide @@ -0,0 +1,477 @@ +@database "compactflash.device" +@$VER: automount guide 2.0-dev (10.07.2026) +@author "Generated by md2guide.py v1.6 (14.06.2026)" +@(c) "See LICENSE" +@font topaz.font 8 +@help Main +@index Index + +@node Main "Table of Contents" + +@{b}compactflash.device@{ub} + + @{"compactflash.device automount and configuration" link compactflash_device_automount_and_configuration} + @{"What automount does" link What_automount_does} + @{"Filesystem handlers" link Filesystem_handlers} + @{"Modules and deployment" link Modules_and_deployment} + @{"On-disk automount via LoadModule" link On_disk_automount_via_LoadModule} + @{"Building your own ROM" link Building_your_own_ROM} + @{"ENV:cfd.prefs reference" link ENV_cfd_prefs_reference} + @{"Example" link Example} + @{"Removable-media model" link Removable_media_model} + @{"Cold-boot autoboot details (ROM-resident)" link Cold_boot_autoboot_details__ROM_resident_} + @{"Serial debug at cold boot" link Serial_debug_at_cold_boot} + @{"Inspecting with lsptres" link Inspecting_with_lsptres} + @{"Troubleshooting" link Troubleshooting} + +@endnode + +@node Index "Index" +@{b}Index@{ub} + +@{b}B@{ub} + @{"Building your own ROM" link Building_your_own_ROM} +@{b}C@{ub} + @{"Cold-boot autoboot details (ROM-resident)" link Cold_boot_autoboot_details__ROM_resident_} + @{"compactflash.device automount and configuration" link compactflash_device_automount_and_configuration} +@{b}E@{ub} + @{"ENV:cfd.prefs reference" link ENV_cfd_prefs_reference} + @{"Example" link Example} +@{b}F@{ub} + @{"Filesystem handlers" link Filesystem_handlers} +@{b}I@{ub} + @{"Inspecting with lsptres" link Inspecting_with_lsptres} +@{b}M@{ub} + @{"Modules and deployment" link Modules_and_deployment} +@{b}O@{ub} + @{"On-disk automount via LoadModule" link On_disk_automount_via_LoadModule} +@{b}R@{ub} + @{"Removable-media model" link Removable_media_model} +@{b}S@{ub} + @{"Serial debug at cold boot" link Serial_debug_at_cold_boot} +@{b}T@{ub} + @{"Troubleshooting" link Troubleshooting} +@{b}W@{ub} + @{"What automount does" link What_automount_does} + +@endnode + +@node compactflash_device_automount_and_configuration "compactflash.device automount and configuration" +@{b}@{u}compactflash.device automount and configuration@{uu}@{ub} + +This guide covers autoboot and automount for @{fg shine}compactflash.device@{fg text} , and +the @{fg shine}ENV:cfd.prefs@{fg text} configuration file. The partition scanning and +mounting itself is done by @{fg shine}ptable.library@{fg text} (see its own @{fg shine}ptable.guide@{fg text} for +the library internals); this document is the user-facing reference. + +---------------------------------------- +@{"<< Prev" link Main} @{"Contents" link Main} @{"Next >>" link What_automount_does} + +@endnode + +@node What_automount_does "What automount does" +@{b}What automount does@{ub} + +@{fg shine}compactflash.device@{fg text} reconciles @{fg shine}partition.resource@{fg text} against the inserted +card and (optionally) mounts its partitions. There are two stages: + + * Cold-boot autoboot (ROM-resident only): at Kickstart cold start, before DOS + exists, the driver opens @{fg shine}ptable.library@{fg text} , which walks the RDB on the card, + loads any filesystem handlers stored in the RDB, and registers each partition + as either bootable (appears in the Early Startup boot menu) or mountable-only. + This is what lets you boot straight from an RDB-partitioned CF card. + * DOS-time (runtime) hotplug: after the machine is up, inserting a card scans it + (RDB, MBR, GPT, or whole-disk flat) and publishes each partition into + @{fg shine}partition.resource@{fg text} ; if automount is enabled the partitions are then mounted. + Removing a card marks them absent (keep the filesystem handler) or unmounts + (dismount filesystem handler) them, per the configured policy. + +@{fg shine}ptable.library@{fg text} is required for both. Without it the device still works +as a plain mount-only device (mount partitions yourself via +@{fg shine}DEVS:DOSDrivers/@{fg text} ), but autoboot and automount are unavailable. + +---------------------------------------- +@{"<< Prev" link compactflash_device_automount_and_configuration} @{"Contents" link Main} @{"Next >>" link Filesystem_handlers} + +@endnode + +@node Filesystem_handlers "Filesystem handlers" +@{b}Filesystem handlers@{ub} + +Automount mounts a partition only when a handler for its filesystem is +already present in the system. It never loads a filesystem handler from +@{fg shine}L:@{fg text} by itself, so a handler file sitting unused in @{fg shine}L:@{fg text} does not count. +When no handler is available for a partition's filesystem, the partition +is still scanned and listed by @{fg shine}lsptres@{fg text} , but stays @{fg shine}P---@{fg text} (present, not +mounted); it is never falsely shown mounted. This applies to every +filesystem the same way: FFS, SFS, PFS, FAT and any other. + +A handler becomes available in one of these ways: + + * Stored in the card's RDB (typical for native FFS, SFS and PFS partitions): + @{fg shine}ptable.library@{fg text} loads it straight from the RDB, both at cold boot and on a + DOS-time insert, so an RDB card needs nothing extra. + * Built into the Kickstart ROM (for example pfs3aio, or fat95 in a custom ROM): + registered by the handler's own startup at boot. + * Made resident from disk with @{fg shine}LoadModule@{fg text} (for example adding @{fg shine}L:fat95@{fg text} to your + @{fg shine}LoadModule@{fg text} line): becoming resident runs the handler's startup, which + registers it. + * Loaded on demand when you mount a matching DOSDriver by hand: mounting one + fat95 DOSDriver, for instance, loads fat95 from @{fg shine}L:@{fg text} and registers its shared + FAT code, after which automount binds every other FAT partition to it. + +FAT cards are the case that needs attention: MBR, GPT and whole-disk +(flat) FAT cards carry no handler in their partition table, so fat95 +must be provided by the ROM, @{fg shine}LoadModule@{fg text} , or a mounted fat95 DOSDriver. +Native FFS/SFS/PFS partitions on an RDB card carry their handler in the +RDB, so they mount with no extra step. + +---------------------------------------- +@{"<< Prev" link What_automount_does} @{"Contents" link Main} @{"Next >>" link Modules_and_deployment} + +@endnode + +@node Modules_and_deployment "Modules and deployment" +@{b}Modules and deployment@{ub} +@{i}Subsections:@{ui} + @{" On-disk automount via LoadModule " link On_disk_automount_via_LoadModule} + @{" Building your own ROM " link Building_your_own_ROM} + +There are three modules, and boot/automount is opt-in by whether you +include the third: + + * @{fg shine}compactflash.device@{fg text} : the I/O driver. On its own it is a plain mount-only + device. + * @{fg shine}ptable.library@{fg text} : the partition scanner and automounter (RDB, MBR, GPT, flat + FAT). + * @{fg shine}compactflash.automount@{fg text} : optional boot/automount bringup. It carries two + romtags: a cold-boot one (scans the card's RDB and registers partitions for + autoboot, ROM only) and an after-DOS one (opens the device once DOS is up, + which starts the card-detect interrupt and the automount agent). Include it + only when you want autoboot or automount. + +Typical setups: + +--- Table --- + 1. Goal + 2. Modules + 3. Cold-boot autoboot + + 1. ROM autoboot + 2. @{fg shine}compactflash.device@{fg text} + @{fg shine}compactflash.automount@{fg text} + @{fg shine}ptable.library@{fg text} in Kickstart + 3. available + + 1. Resident/on-disk, no automount + 2. @{fg shine}compactflash.device@{fg text} + @{fg shine}ptable.library@{fg text} (no automount module) + 3. no + + 1. On-disk automount + 2. @{fg shine}LoadModule LIBS:compactflash.automount LIBS:ptable.library DEVS:compactflash.device@{fg text} (+ @{fg shine}L:fat95@{fg text}) + 3. no + +--- End Table --- + +@{fg shine}AUTOMOUNT@{fg text} defaults @{b}on everywhere@{ub} (ROM-resident and on-disk alike). +Disable it with @{fg shine}AUTOMOUNT 0@{fg text} in @{fg shine}ENV:cfd.prefs@{fg text} ; the resident driver +re-reads that file on every card insert, so the setting takes effect +without a rebuild. An explicit @{fg shine}AUTOMOUNT 0@{fg text} / @{fg shine}1@{fg text} always takes precedence +over the default. An example config is shipped as @{fg shine}ENVARC/cfd.prefs@{fg text} (copy +it to @{fg shine}ENVARC:cfd.prefs@{fg text} and @{fg shine}ENV:cfd.prefs@{fg text} ). + +One caveat for ROM-resident systems: the after-DOS bringup runs before +the startup-sequence assigns @{fg shine}ENV:@{fg text} , so @{fg shine}cfd.prefs@{fg text} is not yet readable at +that point and the built-in defaults apply. A card already in the slot +at cold boot therefore auto-mounts once even when @{fg shine}ENVARC:cfd.prefs@{fg text} says +@{fg shine}AUTOMOUNT 0@{fg text} ; the setting takes effect as soon as @{fg shine}ENV:@{fg text} exists (the next +insert or removal re-reads it). Cold-boot RDB @{i}autoboot@{ui} is unaffected, it +does not depend on @{fg shine}AUTOMOUNT@{fg text} . + +Other notes: + + * Even with automount off, an inserted card is still scanned and published to + @{fg shine}partition.resource@{fg text} , so @{fg shine}lsptres@{fg text} lists the partitions; they are just not + mounted. + * When you mount a device-dostype DOSDriver by hand (e.g. @{fg shine}CFAUX@{fg text} ), it serves its + own partition. Automount pauses on each pass so that handler can claim its + partition first, then reuses it (shown as @{fg shine}CFa0>CFAUX@{fg text} ) and mounts only the + other partitions, rather than starting a second handler on the same one. + +---------------------------------------- +@{"<< Prev" link Filesystem_handlers} @{"Contents" link Main} @{"Next >>" link On_disk_automount_via_LoadModule} + +@endnode + +@node On_disk_automount_via_LoadModule "On-disk automount via LoadModule" +@{i}On-disk automount via LoadModule@{ui} + +@{fg shine}LoadModule@{fg text} (AmigaOS 3.x) makes on-disk modules resident and reboots. It +activates only the @{i}first@{ui} romtag of each file, which is why +boot/automount lives in its own module: @{fg shine}compactflash.automount@{fg text} 's first +romtag is the after-DOS one, so @{fg shine}LoadModule@{fg text} runs it. It opens the device +once DOS is up, bringing up the card-detect interrupt and the automount +agent; from then on hotplug works as in a disk install. Put +@{fg shine}compactflash.automount@{fg text} (and @{fg shine}ptable.library@{fg text} ) in @{fg shine}LIBS:@{fg text} and add to +@{fg shine}user-startup-sequence@{fg text} : + +@{fg highlight} + LoadModule LIBS:compactflash.automount LIBS:ptable.library DEVS:compactflash.device L:fat95 +@{fg text} + +This does not give cold-boot RDB autoboot (booting straight off a CF +card): that runs before DOS and needs @{fg shine}compactflash.device@{fg text} + +@{fg shine}compactflash.automount@{fg text} + @{fg shine}ptable.library@{fg text} in a real Kickstart ROM (see the +companion kickstart-builder). @{fg shine}LoadModule@{fg text} cannot provide it. + +---------------------------------------- +@{"<< Prev" link Modules_and_deployment} @{"Contents" link Main} @{"Next >>" link Building_your_own_ROM} + +@endnode + +@node Building_your_own_ROM "Building your own ROM" +@{i}Building your own ROM@{ui} + +A scripted Capitoline-based ROM builder for a 1 MB AmigaOS 3.2.3 / 3.1 / +2.05 Kickstart with @{fg shine}compactflash.device@{fg text} + @{fg shine}ptable.library@{fg text} embedded lives +in the companion amigaos-kickstart-builder +(https://github.com/pulchart/amigaos-kickstart-builder) repo. + +---------------------------------------- +@{"<< Prev" link On_disk_automount_via_LoadModule} @{"Contents" link Main} @{"Next >>" link ENV_cfd_prefs_reference} + +@endnode + +@node ENV_cfd_prefs_reference "ENV:cfd.prefs reference" +@{b}ENV:cfd.prefs reference@{ub} +@{i}Subsections:@{ui} + @{" Example " link Example} + +Configuration is read from @{fg shine}ENV:cfd.prefs@{fg text} at mount time. Write +@{fg shine}ENVARC:cfd.prefs@{fg text} too if you want it to survive a reboot. The driver +re-reads the file on every card insert and every card removal, so a +change takes effect the next time you insert or remove a card, with no +reboot or rebuild needed. It reads the live @{fg shine}ENV:@{fg text} copy, so update +@{fg shine}ENV:cfd.prefs@{fg text} for a change to apply now; editing only @{fg shine}ENVARC:cfd.prefs@{fg text} +does not take effect until the next reboot copies it into @{fg shine}ENV:@{fg text} . Because +removal is re-read too, a changed @{fg shine}UNMOUNT@{fg text} applies to the very next card +you pull. The format is one key per line, the value following the key +after whitespace; keys are matched case-sensitively as whole words (so +@{fg shine}FLAGS@{fg text} does not match inside @{fg shine}FLAGS_DOS@{fg text} ). A missing key keeps its +default. + +There is no comment syntax: put only the keys you want set. A @{fg shine};@{fg text} +-prefixed line such as @{fg shine}; FLAGS 0@{fg text} is still parsed as @{fg shine}FLAGS 0@{fg text} (the parser +finds the keyword anywhere in the file). Free-text notes are safe only +if they avoid the uppercase key words. An example you can copy is +shipped as @{fg shine}ENVARC/cfd.prefs@{fg text} . + + @{b}Key@{ub} @{b}Value@{ub} @{b}Default@{ub} @{b}Meaning@{ub} + ------------ ------- -------------- ------------------- + @{fg shine}AUTOMOUNT@{fg text} @{fg shine}0@{fg text} or @{fg shine}1@{fg text} on Mount partitions on + insert. + @{fg shine}FLAGS@{fg text} decimal @{fg shine}0@{fg text} Mount flags applied + to every mount. See + the bit table + below. + @{fg shine}CONTROL@{fg text} string none Mount CONTROL + string applied to + every mount. + @{fg shine}UNMOUNT@{fg text} names all Filesystems to + fully unmount on + removal (see + "Removable-media + model"). Any subset + of + @{fg shine}DOS FFS SFS PFS FAT@{fg text} + ; a key with no + recognized names + (e.g. @{fg shine}UNMOUNT NONE@{fg text} + ) keeps every + handler. + @{fg shine}FLAGS_@{fg text} decimal global @{fg shine}FLAGS@{fg text} Per-filesystem + override of @{fg shine}FLAGS@{fg text} . + @{fg shine}@{fg text} is one of + @{fg shine}DOS FFS SFS PFS FAT@{fg text} + . + @{fg shine}CONTROL_@{fg text} string global @{fg shine}CONTROL@{fg text} Per-filesystem + override of @{fg shine}CONTROL@{fg text} + . + +@{fg shine}FLAGS@{fg text} bits (see also the README "Mount Flags" section for the full +description): + + @{b}Bit value@{ub} @{b}Effect@{ub} + --------- -------------------------------- + 8 serial debug output (full build) + 16 enforce ATA multi-sector mode + +The filesystem names understood in @{fg shine}UNMOUNT@{fg text} , @{fg shine}FLAGS_@{fg text} and @{fg shine}CONTROL_@{fg text} +are exactly these five, and no others: @{fg shine}DOS@{fg text} , @{fg shine}FFS@{fg text} , @{fg shine}SFS@{fg text} , @{fg shine}PFS@{fg text} , @{fg shine}FAT@{fg text} . Any +other name ( @{fg shine}NTFS@{fg text} , @{fg shine}EXT2@{fg text} , @{fg shine}PDS@{fg text} , ...) is not recognised and is silently +ignored, taking no effect. In particular @{fg shine}PDS@{fg text} is not a valid name: PFS3's +@{fg shine}PDS\x@{fg text} DosType is already covered by the @{fg shine}PFS@{fg text} name, so use @{fg shine}PFS@{fg text} for it. + +A per-filesystem key applies to partitions whose DosType high three +bytes match: @{fg shine}DOS@{fg text} = @{fg shine}DOS\x@{fg text} , @{fg shine}FFS@{fg text} = @{fg shine}DOS\x@{fg text} fast-filesystem, @{fg shine}PFS@{fg text} = @{fg shine}PFS\x@{fg text} (and +the @{fg shine}PDS\x@{fg text} alias), @{fg shine}SFS@{fg text} = @{fg shine}SFS\x@{fg text} , @{fg shine}FAT@{fg text} = @{fg shine}FAT\x@{fg text} . Use the per-FS overrides +when, for example, you want serial debug only on FAT mounts. + +Tip for hot-plugged FAT cards: @{fg shine}CONTROL_FAT "+q"@{fg text} enables fat95's quiet +option, so no error requesters ("please reinsert" / read / write +windows) can pop up when a card is pulled with pending writes; errors +are returned to the calling program instead. See the fat95 documentation +for the full option list. + +---------------------------------------- +@{"<< Prev" link Building_your_own_ROM} @{"Contents" link Main} @{"Next >>" link Example} + +@endnode + +@node Example "Example" +@{i}Example@{ui} + +@{fg highlight} + AUTOMOUNT 1 + FLAGS 0 + UNMOUNT FAT + CONTROL_FAT +q +@{fg text} + +This keeps automount on (the default, listed for clarity), restricts the +removal policy so only FAT volumes are fully unmounted when the card is +pulled (PFS and others keep their handler, see below), and passes the @{fg shine}+q@{fg text} +(quiet) option to FAT (fat95) mounts only. Note that a CONTROL string is +only meaningful for filesystems that parse one. + +---------------------------------------- +@{"<< Prev" link ENV_cfd_prefs_reference} @{"Contents" link Main} @{"Next >>" link Removable_media_model} + +@endnode + +@node Removable_media_model "Removable-media model" +@{b}Removable-media model@{ub} + + * Insert: the card is scanned and its partitions are published to + @{fg shine}partition.resource@{fg text} (always, even when automount is off). With automount on, + partitions that are not yet mounted are mounted. + * Remove, default (no @{fg shine}UNMOUNT@{fg text} key): every partition is fully unmounted (handler + stopped, DOS node removed, memory freed). Its @{fg shine}partition.resource@{fg text} line is kept + and shown absent, so the partition is still listed; reinserting the card + mounts it fresh. + * Remove, @{fg shine}UNMOUNT @{fg text} : only partitions of the listed filesystems are unmounted + as above. A filesystem not listed is marked absent instead: its DOS node and + handler are kept in memory, and reinserting the same card reattaches it + without re-initialising the handler (the native AmigaOS removable-media + behaviour). @{fg shine}UNMOUNT NONE@{fg text} (no recognized names) keeps every handler. + +Either way the partition stays visible in @{fg shine}lsptres@{fg text} (shown absent) while +the card is out, and is re-confirmed or re-published on reinsert. + +@{fg shine}AUTOMOUNT@{fg text} gates only the mount step; it does not unmount. Changing +@{fg shine}AUTOMOUNT 1@{fg text} to @{fg shine}0@{fg text} does not unmount volumes already mounted. To clear +them, pull the card (the default removal policy unmounts them) or +reboot. + +---------------------------------------- +@{"<< Prev" link Example} @{"Contents" link Main} @{"Next >>" link Cold_boot_autoboot_details__ROM_resident_} + +@endnode + +@node Cold_boot_autoboot_details__ROM_resident_ "Cold-boot autoboot details (ROM-resident)" +@{b}Cold-boot autoboot details (ROM-resident)@{ub} +@{i}Subsections:@{ui} + @{" Serial debug at cold boot " link Serial_debug_at_cold_boot} + +How each RDB partition is handled at cold boot: + + @{b}RDB partition flag@{ub} @{b}BootPri@{ub} @{b}Result@{ub} + ------------------- ------- ------------------------- + normal >= 0 bootable: appears in the + Early Startup boot device + list + normal < 0 non-bootable: mounted as + a DOS volume + NOMOUNT (bit 1 set) any skipped: not mounted, not + in the DOS list + +BootPri is stored in the RDB partition environment and controls boot +order. + +The driver's cold-boot autoboot runs late in Kickstart's resident init, +after the internal IDE ( @{fg shine}scsi.device@{fg text} ) has started. Because that init is +sequential, if the IDE stalls at boot (for example no drive connected), +CF autoboot never gets its turn and does not trigger either. The boot +stub first does a single Gayle read to check for a card; an empty slot +returns immediately. With a card present it tolerates slow cards by +polling up to about 1.8 s total; a healthy card adds no measurable +delay. + +@{fg shine}ptable.library@{fg text} also registers a synthetic expansion board (Vendor ID +@{fg shine}65535 ($FFFF)@{fg text} , Product ID @{fg shine}1@{fg text} ) so the Early Startup boot menu sees the +device; it shows up in tools like @{fg shine}ShowConfig@{fg text} . + +---------------------------------------- +@{"<< Prev" link Removable_media_model} @{"Contents" link Main} @{"Next >>" link Serial_debug_at_cold_boot} + +@endnode + +@node Serial_debug_at_cold_boot "Serial debug at cold boot" +@{i}Serial debug at cold boot@{ui} + +A @{fg shine}full@{fg text} build emits unconditional serial output at cold boot (9600 baud), +regardless of the mountlist @{fg shine}Flags@{fg text} setting. @{fg shine}compactflash.device@{fg text} uses the +@{fg shine}[CFD] boot:@{fg text} prefix and @{fg shine}ptable.library@{fg text} uses @{fg shine}[PT]@{fg text} : + +@{fg highlight} + [CFD] boot: open ptable.library ... + [CFD] boot: BootScanPartitions(compactflash.device,0) + [PT] cold boot: scanning for partitions + [PT] RDB partition table + [PT] + filesystem handler PFS v20.0 + [PT] - skip SDH10 + [PT] + boot SDH0 + [PT] + mount SDH1 + [PT] + mount SDH2 + [PT] cold boot done, partitions registered: 3 +@{fg text} + +---------------------------------------- +@{"<< Prev" link Cold_boot_autoboot_details__ROM_resident_} @{"Contents" link Main} @{"Next >>" link Inspecting_with_lsptres} + +@endnode + +@node Inspecting_with_lsptres "Inspecting with lsptres" +@{b}Inspecting with lsptres@{ub} + +@{fg shine}lsptres@{fg text} lists @{fg shine}partition.resource@{fg text} , which reflects the last-seen card +whether or not partitions are mounted. The @{fg shine}Flags@{fg text} column first char is @{fg shine}P@{fg text} +present, @{fg shine}I@{fg text} invalid, or @{fg shine}-@{fg text} absent. @{fg shine}I@{fg text} means the slot is still mounted (its +handler and DOS node are kept in memory), but the card currently in the +slot has no such partition, typically after a card swap; it shows as +@{fg shine}I--M@{fg text} and returns to @{fg shine}P@{fg text} when the original card is reinserted. A slot with +no card in the drive at all reads @{fg shine}-@{fg text} , so a kept mount whose media is +simply gone shows @{fg shine}---M@{fg text} . The remaining chars are @{fg shine}B@{fg text} bootable, @{fg shine}N@{fg text} nomount, +@{fg shine}M@{fg text} mounted. @{fg shine}MFlg@{fg text} is the resolved mount flags and @{fg shine}Ctrl@{fg text} the resolved +CONTROL string. A mounted volume shows as @{fg shine}scanname>dosname@{fg text} when its real +DOS name differs from the scanned name. + +---------------------------------------- +@{"<< Prev" link Serial_debug_at_cold_boot} @{"Contents" link Main} @{"Next >>" link Troubleshooting} + +@endnode + +@node Troubleshooting "Troubleshooting" +@{b}Troubleshooting@{ub} + + * Nothing automounts: check that @{fg shine}ENV:cfd.prefs@{fg text} does not say @{fg shine}AUTOMOUNT 0@{fg text} (the + default is on), and that @{fg shine}ptable.library@{fg text} is reachable (ROM-resident, or in + @{fg shine}LIBS:@{fg text} for DOS-time mounts). + * File-based, card present but nothing happens: the driver is not loaded until + something opens it. Add a @{fg shine}DEVS:DOSDrivers/CF0@{fg text} entry so it loads at boot. + * Partitions listed in @{fg shine}lsptres@{fg text} but not mounted: automount is off, or they are a + non-FAT filesystem with no handler available. + * Want serial trace of a DOS-time mount: set @{fg shine}FLAGS 8@{fg text} (full build). + +---------------------------------------- +@{"<< Prev" link Inspecting_with_lsptres} @{"Contents" link Main} + +@endnode diff --git a/dist/docs/cfd.guide b/dist/docs/cfd.guide index 9ee4226..9f5669c 100644 --- a/dist/docs/cfd.guide +++ b/dist/docs/cfd.guide @@ -1,5 +1,5 @@ @database "compactflash.device" -@$VER: compactflash.device guide 1.44 (04.06.2026) +@$VER: compactflash.device guide 2.0-dev (10.07.2026) @author "Generated by md2guide.py v1.6 (14.06.2026)" @(c) "See LICENSE" @font topaz.font 8 @@ -16,7 +16,7 @@ @{"Documentation Included" link Documentation_Included} @{"System Requirements" link System_Requirements} @{"Installation" link Installation} - @{"Autoboot / Automount (ROM-resident)" link Autoboot___Automount__ROM_resident_} + @{"Autoboot / Automount" link Autoboot___Automount} @{"Hardware Notes" link Hardware_Notes} @{"Mount Flags" link Mount_Flags} @{"Debug via serial line (Flag 8)" link Debug_via_serial_line__Flag_8_} @@ -55,7 +55,7 @@ @{b}A@{ub} @{"After (v1.41-dev)" link After__v1_41_dev_} @{"ATAPI status" link ATAPI_status} - @{"Autoboot / Automount (ROM-resident)" link Autoboot___Automount__ROM_resident_} + @{"Autoboot / Automount" link Autoboot___Automount} @{b}B@{ub} @{"Before (through v1.40)" link Before__through_v1_40_} @{"Build Options" link Build_Options} @@ -166,6 +166,7 @@ See @{" docs/changes.guide " link "changes.guide/Main"} for release news and h @node Documentation_Included "Documentation Included" @{b}Documentation Included@{ub} + * @{" docs/automount.guide " link "automount.guide/Main"} - autoboot, automount, and ENV:cfd.prefs configuration. * @{" docs/changes.guide " link "changes.guide/Main"} - release notes and original CFD history. * @{" docs/CFInfo.guide " link "CFInfo.guide/Main"} - CFInfo card information utility documentation. * @{" docs/pcmciaspeed.guide " link "pcmciaspeed.guide/Main"} - PCMCIA timing benchmark documentation. @@ -204,8 +205,10 @@ The flavour is encoded in the path: full 68000+ full/68000/devs/compactflash.device ~11.3 KB small 68000+ small/68000/devs/compactflash.device ~8.0 KB -Companion @{fg shine}ptable.library@{fg text} binaries live next to the device in the same -flavour/CPU tree ( @{fg shine}//libs/ptable.library@{fg text} ). +Companion libraries live next to the device in the same flavour/CPU tree +under @{fg shine}//libs/@{fg text} : @{fg shine}ptable.library@{fg text} (partition scan/mount) and +the optional @{fg shine}compactflash.automount@{fg text} (boot/automount bringup, only needed +for autoboot or automount). Pick the tier that matches your CPU, then pick the full or small flavour: @@ -230,6 +233,15 @@ device and @{fg shine}ptable.library@{fg text} at once. Have fat95 installed on your system. Mount the drive by double-clicking @{fg shine}Storage/DOSDrivers/CF0@{fg text} . +Inserted cards automount by default (with the optional +@{fg shine}compactflash.automount@{fg text} module active). To tune it, or disable it with +@{fg shine}AUTOMOUNT 0@{fg text} , copy the example config to @{fg shine}ENVARC:@{fg text} (and @{fg shine}ENV:@{fg text} ): +@{fg highlight} + Copy cfd/ENVARC/cfd.prefs to ENVARC:cfd.prefs + Copy cfd/ENVARC/cfd.prefs to ENV:cfd.prefs +@{fg text} +See @{" docs/automount.guide " link "automount.guide/Main"} for all keys and the optional @{fg shine}compactflash.automount@{fg text} module. + For OS 3.5+: @{fg highlight} Copy def_CF0.info sys:prefs/env-archive/sys @@ -237,156 +249,46 @@ For OS 3.5+: @{fg text} ---------------------------------------- -@{"<< Prev" link System_Requirements} @{"Contents" link Main} @{"Next >>" link Autoboot___Automount__ROM_resident_} +@{"<< Prev" link System_Requirements} @{"Contents" link Main} @{"Next >>" link Autoboot___Automount} @endnode -@node Autoboot___Automount__ROM_resident_ "Autoboot / Automount (ROM-resident)" -@{b}Autoboot / Automount (ROM-resident)@{ub} - -At Kickstart cold start @{fg shine}compactflash.device@{fg text} opens @{fg shine}ptable.library@{fg text} , which -walks the RDB on the inserted card, registers any filesystem handlers -stored in the RDB into @{fg shine}FileSystem.resource@{fg text} , and publishes each -partition via @{fg shine}AddBootNode@{fg text} (bootable) or @{fg shine}AddDosNode@{fg text} (mountable only). - -@{i}ROM-resident requirement@{ui} - -@{fg shine}ptable.library@{fg text} is @{b}optional@{ub} for the driver. Without it, -@{fg shine}compactflash.device@{fg text} still works fully as a mount-only device via -@{fg shine}DEVS:DOSDrivers/CF0@{fg text} as example. It is @{b}required@{ub} for autoboot and -automount. To activate, both compactflash.device and ptable.library must -be flashed into a ROM image. - -@{i}Building your own ROM@{ui} - -A scripted Capitoline-based ROM builder for creating a 1 MB AmigaOS -3.2.3 / 3.1 / 2.05 Kickstart with @{fg shine}compactflash.device@{fg text} + @{fg shine}ptable.library@{fg text} -embedded lives in the companion amigaos-kickstart-builder -(https://github.com/pulchart/amigaos-kickstart-builder) repo. - -@{i}Partition handling@{ui} - -How each RDB partition is handled at boot: - - @{b}RDB partition flag@{ub} @{b}BootPri@{ub} @{b}Result@{ub} - ------------------- ------- ------------------------- - normal >= 0 bootable: appears in - Early Startup boot device - list - normal < 0 non-bootable: mounted as - a DOS volume - NOMOUNT (bit 1 set) any skipped entirely: not - mounted, not in DOS list - -BootPri is stored in the RDB partition environment and controls boot -order. - -@{i}Boot order@{ui} - -The driver starts during Kickstart boot after the internal IDE is ready. -The relevant modules in boot order are: - - @{b}Module@{ub} @{b}Role@{ub} - ----------------- ------------------------------------- - @{fg shine}card.resource@{fg text} PCMCIA slot initialised - @{fg shine}trackdisk.device@{fg text} floppy - @{fg shine}carddisk.device@{fg text} Kickstart built-in PCMCIA handler - @{fg shine}scsi.device@{fg text} internal IDE initialised - @{b}@{fg shine}compactflash.boot@{fg text}@{ub} @{b}CF card check + partition scan@{ub} . It - opens @{fg shine}ptable.library@{fg text} . @{fg shine}ptable.library@{fg text} - walks the RDB, registers any - filesystem handlers it finds, and - publishes each partition via - @{fg shine}AddBootNode@{fg text} (bootable) or @{fg shine}AddDosNode@{fg text} - (mountable only). - @{fg shine}strap@{fg text} boot menu / Workbench start - -The driver runs after the internal IDE is initialised, so it does not -interfere with it. If the IDE stalls at boot (e.g. no drive connected), -CF autoboot will not trigger either. - -@{i}Cold-boot timing@{ui} - -The boot stub starts with a @{b}no-card pre-gate@{ub} : a single read of the -Gayle tells it whether a CF card is in the slot. If the slot is empty, -the stub returns immediately. - -If a card IS present, the driver tolerates slow cards/adapters by -polling for up to ~1.8 s in total (1 s for card-detect stabilisation, -~400 ms each for the two CIS tuple reads). Stable cards complete the -first iteration of each loop, so a healthy card pays no measurable -delay. - -@{i}Boot debug output@{ui} - -@{fg shine}ptable.library@{fg text} opens the device with @{fg shine}Flags=0@{fg text} . Serial debug output at -cold boot comes from a @{fg shine}full@{fg text} build only and is unconditional, not gated -by the mountlist @{fg shine}Flags = 8@{fg text} setting. Two components emit output: -@{fg shine}compactflash.device@{fg text} uses the @{fg shine}[CFD] boot:@{fg text} prefix, and @{fg shine}ptable.library@{fg text} uses -@{fg shine}[RDB]@{fg text} : +@node Autoboot___Automount "Autoboot / Automount" +@{b}Autoboot / Automount@{ub} + +@{fg shine}compactflash.device@{fg text} can boot straight from an RDB-partitioned CF card +(ROM-resident only) and automount inserted cards at DOS time (RDB, MBR, +GPT, and flat whole-disk FAT). Both are driven by @{fg shine}ptable.library@{fg text} plus +the optional @{fg shine}compactflash.automount@{fg text} module; without them the device +still works as a plain mount-only device. + +Automount is @{b}on by default everywhere@{ub} (ROM-resident and file-based +alike); disable it with @{fg shine}AUTOMOUNT 0@{fg text} in @{fg shine}ENV:cfd.prefs@{fg text} (see the example +config above). Removing a card fully unmounts all supported filesystems +by default; @{fg shine}UNMOUNT @{fg text} restricts it and @{fg shine}UNMOUNT NONE@{fg text} keeps the +handlers. The resident driver re-reads that file on every card insert +and removal. + +The per-filesystem config keys ( @{fg shine}UNMOUNT@{fg text} , @{fg shine}FLAGS_@{fg text} , @{fg shine}CONTROL_@{fg text} ) +recognise exactly five filesystem names and no others: @{fg shine}DOS@{fg text} , @{fg shine}FFS@{fg text} , @{fg shine}SFS@{fg text} , +@{fg shine}PFS@{fg text} , @{fg shine}FAT@{fg text} . Any other name is silently ignored. See @{" docs/automount.guide " link "automount.guide/Main"} for the full config +reference. +@{fg shine}compactflash.automount@{fg text} provides the boot/automount bringup: in a ROM it +gives cold-boot autoboot and opens the device after DOS so the automount +agent runs; on disk you get the same run-time automount (hot-swap) by +adding it to your startup-sequence with: @{fg highlight} - [CFD] boot: open ptable.library ... - [CFD] boot: ptable.library not preloaded, InitResident()... - [CFD] boot: BootScanRDB(compactflash.device,0) - [RDB] scan - [RDB] found RDSK - [RDB] +fs PFS v20.0 - [RDB] skip SDH10 - [RDB] skip SDH11 - [RDB] +boot SDH0 - [RDB] +dos SDH1 - [RDB] +dos SDH2 - [RDB] done + LoadModule LIBS:compactflash.automount LIBS:ptable.library DEVS:compactflash.device @{fg text} ---- Table --- - 1. Line - 2. Meaning - - 1. @{fg shine}[CFD] boot: open ptable.library ...@{fg text} - 2. device opened ptable.library - - 1. @{fg shine}[CFD] boot: ptable.library not preloaded, InitResident()...@{fg text} - 2. library was not yet in memory; loaded from ROM via @{fg shine}InitResident()@{fg text} +The full reference (the @{fg shine}ENV:cfd.prefs@{fg text} keys, deployment matrix, +removable-media model, cold-boot details and serial-debug output) lives +in @{" docs/automount.guide " link "automount.guide/Main"} ( @{fg shine}automount.guide@{fg text} ). - 1. @{fg shine}[CFD] boot: BootScanRDB(compactflash.device,0)@{fg text} - 2. device hands off RDB scan to ptable.library for unit 0 - - 1. @{fg shine}[RDB] scan@{fg text} - 2. ptable.library begins scanning for the RDB - - 1. @{fg shine}[RDB] found RDSK@{fg text} - 2. RDB block located on the card - - 1. @{fg shine}[RDB] +fs PFS v20.0@{fg text} - 2. filesystem handler loaded from RDB (DosType + version) - - 1. @{fg shine}[RDB] skip SDH10@{fg text} - 2. partition skipped (NOMOUNT flag set in RDB) - - 1. @{fg shine}[RDB] +boot SDH0@{fg text} - 2. bootable partition registered via @{fg shine}AddBootNode@{fg text} - - 1. @{fg shine}[RDB] +dos SDH1@{fg text} - 2. mountable-only partition registered via @{fg shine}AddDosNode@{fg text} - - 1. @{fg shine}[RDB] done@{fg text} - 2. RDB scan complete - ---- End Table --- - -@{i}Expansion board entry@{ui} - -@{fg shine}ptable.library@{fg text} registers a synthetic expansion board entry so the -Kickstart Early Startup boot menu sees the device. The entry is visible -in expansion-board inspection tools (e.g. @{fg shine}ShowConfig@{fg text} ) as a board with -the following identifiers: - - @{b}Field@{ub} @{b}Value@{ub} - ---------- ------------------------------ - Vendor ID @{fg shine}65535 ($FFFF)@{fg text} (as 'no vendor') - Product ID @{fg shine}1@{fg text} +To build a Kickstart ROM with @{fg shine}compactflash.device@{fg text} + @{fg shine}ptable.library@{fg text} +embedded, see the companion amigaos-kickstart-builder +(https://github.com/pulchart/amigaos-kickstart-builder) repo. ---------------------------------------- @{"<< Prev" link Installation} @{"Contents" link Main} @{"Next >>" link Hardware_Notes} @@ -419,7 +321,7 @@ In conjunction with fat95 v3.09+, cfd can use CF card's built-in erase function if available. ---------------------------------------- -@{"<< Prev" link Autoboot___Automount__ROM_resident_} @{"Contents" link Main} @{"Next >>" link Mount_Flags} +@{"<< Prev" link Autoboot___Automount} @{"Contents" link Main} @{"Next >>" link Mount_Flags} @endnode @@ -516,22 +418,24 @@ Once the hardware is connected, monitor the serial port (e.g., @{fg shine}screen /dev/ttyUSB0 9600@{fg text} , @{fg shine}minicom -b 9600 -o -D /dev/ttyUSB0@{fg text} , @{fg shine}putty@{fg text} ) on remote computer to see online initialization process. -Cold boot (ROM-resident @{fg shine}ptable.library@{fg text}, RDB-partitioned card): +Cold boot (ROM-resident @{fg shine}compactflash.automount@{fg text} + @{fg shine}ptable.library@{fg text} , +RDB-partitioned card). The @{fg shine}[CFD] boot:@{fg text} lines come from +@{fg shine}compactflash.automount@{fg text} , the @{fg shine}[PT]@{fg text} lines from @{fg shine}ptable.library@{fg text} : @{fg highlight} - [CFD] boot: open ptable.library v1... + [CFD] boot: open ptable.library ... [CFD] boot: ptable.library not preloaded, InitResident()... - [CFD] boot: BootScanRDB(compactflash.device,0) - [RDB] scan - [RDB] found RDSK - [RDB] +fs PFS v20.0 - [RDB] +boot SDH0 - [RDB] +dos SDH1 - [RDB] done + [CFD] boot: BootScanPartitions(compactflash.device,0) + [PT] cold boot: scanning for partitions + [PT] RDB partition table + [PT] + filesystem handler PFS v20.0 + [PT] + boot SDH0 + [PT] + mount SDH1 + [PT] cold boot done, partitions registered: 2 @{fg text} Card identification (hot-plug): @{fg highlight} - [CFD] compactflash.device 1.42 (02.05.2026) [68020] + [CFD] compactflash.device 2.0-dev (10.07.2026) [68020] [CFD] Card inserted [CFD] Identifying card... [CFD] Reset @@ -541,7 +445,7 @@ Card identification (hot-plug): [CFD] Voltage: 5V [CFD] CIS gate [CFD] ..DEVICE: type=0x0D speed=400ns size=0x00000800 - [CFD] ..FUNCID: 0x04 + [CFD] ..FUNCEXT: link=0x02, type=0x01, ifc=0x01 [CFD] ..RESULT: accept [CFD] ..CONFIG: addr=0x00000200 (or: [CFD] ..CONFIG: default (0x200)) @@ -574,8 +478,27 @@ Card identification (hot-plug): [CFD] ..done, multi RW: 256 [CFD] Card identified OK [CFD] Notify clients + [MW] config: read=-1 auto=1 flags=0 + [MW] scanning compactflash.device:0 for partitions + [PT] scanning for partitions + [PT] MBR partition table + [PT] partitions found: 1 + [MW] scan done, partitions known: 1 + [MW] mounting new partitions + [PT] mounting partitions + [PT] mounted CFa0 + [MW] mounted volumes: 1 [CFD] Card removed + [MW] config: read=-1 auto=1 flags=0 + [MW] card removed + [PT] card removed, media absent + [PT] unmounting partitions + [PT] unmounted CFa0 + [MW] entries detached: 1 @{fg text} +The @{fg shine}[MW]@{fg text} lines come from the automount mount worker (they appear when +@{fg shine}compactflash.automount@{fg text} is active), the @{fg shine}[PT]@{fg text} lines from @{fg shine}ptable.library@{fg text} . +@{fg shine}read=-1@{fg text} means no @{fg shine}ENV:cfd.prefs@{fg text} is set, so the defaults apply ( @{fg shine}auto=1@{fg text} ). @{b}Capturing serial output without a null-modem cable@{ub} @@ -1197,7 +1120,7 @@ testing which PCMCIA access methods work reliably: Most CF cards work with WORD mode. The driver tests write/read patterns during initialization and falls back to BYTE modes if 16-bit access fails. The selected mode is shown in serial debug output as -@{fg shine}[CFD] Transfer: WORD@{fg text} or similar. +@{fg shine}[CFD] ..done, transfer mode: WORD@{fg text} . ---------------------------------------- @{"<< Prev" link Speed_Test_Results} @{"Contents" link Main} @{"Next >>" link Tools} diff --git a/dist/docs/changes.guide b/dist/docs/changes.guide index d03eb7e..a02ef7b 100644 --- a/dist/docs/changes.guide +++ b/dist/docs/changes.guide @@ -1,5 +1,5 @@ @database "compactflash.device release notes" -@$VER: compactflash.device release notes guide 20260614 (14.06.2026) +@$VER: compactflash.device release notes guide 20260710-dev (10.07.2026) @author "Generated by md2guide.py v1.6 (14.06.2026)" @(c) "See LICENSE" @font topaz.font 8 @@ -10,6 +10,7 @@ @{b}compactflash.device release notes@{ub} + @{"20260710-dev" link 20260710_dev} @{"20260614" link 20260614} @{"20260609" link 20260609} @{"v1.43 (19.05.2026)" link v1_43__19_05_2026_} @@ -31,6 +32,7 @@ @{"20260609" link 20260609} @{"20260614" link 20260614} + @{"20260710-dev" link 20260710_dev} @{b}O@{ub} @{"Original CFD History Through v1.33" link Original_CFD_History_Through_v1_33} @{b}V@{ub} @@ -47,6 +49,39 @@ @endnode +@node 20260710_dev "20260710-dev" +@{b}20260710-dev@{ub} + +@{i}Components in this release@{ui}: + + * @{fg shine}compactflash.device 2.0-dev (10.07.2026)@{fg text} @{i}(new)@{ui} + * @{fg shine}compactflash.automount 2.0-dev (10.07.2026)@{fg text} @{i}(new)@{ui} + * @{fg shine}ptable.library 2.0-dev (10.07.2026)@{fg text} @{i}(new)@{ui} + * @{fg shine}CFInfo 1.37 (11.01.2026)@{fg text} + * @{fg shine}pcmciaspeed 1.36 (02.01.2026)@{fg text} + * @{fg shine}pcmciacheck 1.39 (22.05.2026)@{fg text} + * @{fg shine}lsptres 1.0-dev (10.07.2026)@{fg text} @{i}(new)@{ui} + +@{b}CompactFlash Driver@{ub} + + * @{b}Automount.@{ub} Hotplugged cards mount automatically at DOS time, on by default; + disable with @{fg shine}AUTOMOUNT 0@{fg text} in the new @{fg shine}ENV:cfd.prefs@{fg text} config file. Removing a card + fully unmounts all supported filesystems by default ( @{fg shine}UNMOUNT @{fg text} + restricts it, @{fg shine}UNMOUNT NONE@{fg text} keeps the handlers). Boot and automount bringup is + split into a separate @{fg shine}compactflash.automount@{fg text} module. See @{" automount.guide " link "automount.guide/Main"} . + +@{b}Partition Table library@{ub} + + * @{b}Unified partition scanning.@{ub} One scanner parses RDB, MBR, GPT, and flat + (whole-disk) partition tables and publishes every partition into a shared + @{fg shine}partition.resource@{fg text} , now used by both @{fg shine}compactflash.device@{fg text} and @{fg shine}fat95@{fg text} instead of + each carrying its own. The new @{fg shine}lsptres@{fg text} tool lists the resource. See @{" ptable.guide " link "ptable.guide/Main"} and @{" lsptres.guide " link "lsptres.guide/Main"} . + +---------------------------------------- +@{"<< Prev" link Main} @{"Contents" link Main} @{"Next >>" link 20260614} + +@endnode + @node 20260614 "20260614" @{b}20260614@{ub} @@ -64,7 +99,7 @@ Documentation-only update (no binaries changed). Release notes and original CFD history are included in @{" docs/changes.guide " link "changes.guide/Main"} document. ---------------------------------------- -@{"<< Prev" link Main} @{"Contents" link Main} @{"Next >>" link 20260609} +@{"<< Prev" link 20260710_dev} @{"Contents" link Main} @{"Next >>" link 20260609} @endnode diff --git a/dist/docs/lsptres.guide b/dist/docs/lsptres.guide new file mode 100644 index 0000000..82cbb4b --- /dev/null +++ b/dist/docs/lsptres.guide @@ -0,0 +1,253 @@ +@database "lsptres" +@$VER: lsptres guide 1.0-dev (10.07.2026) +@author "Generated by md2guide.py v1.6 (14.06.2026)" +@(c) "See LICENSE" +@font topaz.font 8 +@help Main +@index Index + +@node Main "Table of Contents" + +@{b}lsptres@{ub} + + @{"lsptres - partition.resource lister" link lsptres___partition_resource_lister} + @{"Usage" link Usage} + @{"Columns" link Columns} + @{"Examples" link Examples} + @{"A GPT card with three FAT partitions, mounted" link A_GPT_card_with_three_FAT_partitions__mounted} + @{"A single MBR partition reattached over a 3-partition GPT card (the `I` flag)" link A_single_MBR_partition_reattached_over_a_3_partition_GPT_card__the__I__flag_} + @{"An RDB card with PFS partitions" link An_RDB_card_with_PFS_partitions} + @{"Verbose" link Verbose} + @{"See also" link See_also} + +@endnode + +@node Index "Index" +@{b}Index@{ub} + +@{b}A@{ub} + @{"A GPT card with three FAT partitions, mounted" link A_GPT_card_with_three_FAT_partitions__mounted} + @{"A single MBR partition reattached over a 3-partition GPT card (the `I` flag)" link A_single_MBR_partition_reattached_over_a_3_partition_GPT_card__the__I__flag_} + @{"An RDB card with PFS partitions" link An_RDB_card_with_PFS_partitions} +@{b}C@{ub} + @{"Columns" link Columns} +@{b}E@{ub} + @{"Examples" link Examples} +@{b}L@{ub} + @{"lsptres - partition.resource lister" link lsptres___partition_resource_lister} +@{b}S@{ub} + @{"See also" link See_also} +@{b}U@{ub} + @{"Usage" link Usage} +@{b}V@{ub} + @{"Verbose" link Verbose} + +@endnode + +@node lsptres___partition_resource_lister "lsptres - partition.resource lister" +@{b}@{u}lsptres - partition.resource lister@{uu}@{ub} + +@{fg shine}lsptres@{fg text} lists @{fg shine}partition.resource@{fg text} : every partition that @{fg shine}ptable.library@{fg text} +has discovered and published, whether registered at cold boot or scanned +when a card was hotplugged. It reports the partition scheme it came from +(RDB, MBR, GPT or a partition-table-less "flat" superfloppy), the +DosType, mount state, and the mount Flags / CONTROL string resolved for +it. It is the companion to fat95's @{fg shine}lsfsres@{fg text} , which lists +@{fg shine}FileSystem.resource@{fg text} . + +@{b}Use cases@{ub}: + * Confirm a hotplugged card's partitions were scanned and mounted. + * See which partitions are mounted, and under what DOS name. + * Check the mount Flags and CONTROL string the partition was mounted with - + whether resolved by cfd's automount from @{fg shine}ENV:cfd.prefs@{fg text} (the @{fg shine}FLAGS@{fg text} / @{fg shine}CONTROL@{fg text} + knobs), or supplied by a handler that mounted it from a static mountlist. + +---------------------------------------- +@{"<< Prev" link Main} @{"Contents" link Main} @{"Next >>" link Usage} + +@endnode + +@node Usage "Usage" +@{b}Usage@{ub} + +@{fg highlight} + lsptres ; default columns + lsptres VERBOSE ; also show CMD / Start / Blocks / Size (V works too) + lsptres >SER: ; forward output over the serial line +@{fg text} + +@{fg shine}lsptres@{fg text} reads the live resource. If nothing has been scanned yet, or +@{fg shine}ptable.library@{fg text} v2 is not resident, it prints +@{fg shine}partition.resource not present@{fg text} and exits. + +---------------------------------------- +@{"<< Prev" link lsptres___partition_resource_lister} @{"Contents" link Main} @{"Next >>" link Columns} + +@endnode + +@node Columns "Columns" +@{b}Columns@{ub} + + @{b}Column@{ub} @{b}Meaning@{ub} + ------- -------------------------------------- + Name Partition name. Shown as @{fg shine}name>dosname@{fg text} + when the partition is mounted under a + different DOS name (e.g. @{fg shine}MFMa0>MS0@{fg text} ). + Device Device serving the partition (e.g. + @{fg shine}compactflash.device@{fg text} , truncated to + fit). + Unit Device unit number. + Part Partition index within the card + (0-based). + Src Partition scheme: @{fg shine}MBR@{fg text} , @{fg shine}GPT@{fg text} , @{fg shine}RDB@{fg text} , or + @{fg shine}FLT@{fg text} (flat / superfloppy). + Pri Boot priority. + DosType The DosType as hex (e.g. @{fg shine}0x46415400@{fg text}). + Text The DosType as four-character text; + non-printable bytes (e.g. a trailing + @{fg shine}\0@{fg text} ) show as @{fg shine}.@{fg text} . + Flags First char: @{fg shine}P@{fg text} present, @{fg shine}I@{fg text} invalid (a + card is in but has no partition for + this mounted slot), @{fg shine}-@{fg text} absent. Then @{fg shine}B@{fg text} + bootable, @{fg shine}N@{fg text} nomount, @{fg shine}M@{fg text} mounted; @{fg shine}-@{fg text} for + an absent bit. + MFlg Mount Flags the partition was mounted + with: cfd's automount resolves these + from @{fg shine}cfd.prefs@{fg text} ( @{fg shine}FLAGS@{fg text} ), or a handler + that mounts it statically records the + value it opened the device with. + Ctrl CONTROL string the partition was + mounted with: from @{fg shine}cfd.prefs@{fg text} ( @{fg shine}CONTROL@{fg text} + ) on the automount path, or recorded + by a handler mounting statically. + +Verbose (@{fg shine}VERBOSE@{fg text} / @{fg shine}V@{fg text}) appends: + + @{b}Column@{ub} @{b}Meaning@{ub} + ------ --------------------------------- + CMD Read command used for the device: + @{fg shine}NSCMD@{fg text} , @{fg shine}TD64@{fg text} , @{fg shine}SCSI@{fg text} or @{fg shine}CMD@{fg text} . + Start Start block (LBA). + Blocks Block count. + Size Size in MB. + +---------------------------------------- +@{"<< Prev" link Usage} @{"Contents" link Main} @{"Next >>" link Examples} + +@endnode + +@node Examples "Examples" +@{b}Examples@{ub} +@{i}Subsections:@{ui} + @{" A GPT card with three FAT partitions, mounted " link A_GPT_card_with_three_FAT_partitions__mounted} + @{" A single MBR partition reattached over a 3-partition GPT card (the `I` flag) " link A_single_MBR_partition_reattached_over_a_3_partition_GPT_card__the__I__flag_} + @{" An RDB card with PFS partitions " link An_RDB_card_with_PFS_partitions} + @{" Verbose " link Verbose} + +---------------------------------------- +@{"<< Prev" link Columns} @{"Contents" link Main} @{"Next >>" link A_GPT_card_with_three_FAT_partitions__mounted} + +@endnode + +@node A_GPT_card_with_three_FAT_partitions__mounted "A GPT card with three FAT partitions, mounted" +@{i}A GPT card with three FAT partitions, mounted@{ui} + +The card was inserted at runtime; @{fg shine}cfd.prefs@{fg text} set @{fg shine}CONTROL_FAT -d-D@{fg text} , so +that value appears in the Ctrl column and applies to every FAT mount. + +@{fg highlight} + Name Device Unit Part Src Pri DosType Text Flags MFlg Ctrl + ------------ ------------- ---- ---- --- --- ---------- ---- ----- ----- ---------- + CFa0 compactflash. 0 0 GPT 0 0x46415400 FAT. P--M 0 -d-D + CFa1 compactflash. 0 1 GPT 0 0x46415400 FAT. P--M 0 -d-D + CFa2 compactflash. 0 2 GPT 0 0x46415400 FAT. P--M 0 -d-D +@{fg text} + +The @{fg shine}P--M@{fg text} flags read: present, mounted (not bootable, not nomount). The +Text of @{fg shine}0x46415400@{fg text} is @{fg shine}FAT.@{fg text} (the trailing @{fg shine}\0@{fg text} prints as @{fg shine}.@{fg text} ). + +---------------------------------------- +@{"<< Prev" link Examples} @{"Contents" link Main} @{"Next >>" link A_single_MBR_partition_reattached_over_a_3_partition_GPT_card__the__I__flag_} + +@endnode + +@node A_single_MBR_partition_reattached_over_a_3_partition_GPT_card__the__I__flag_ "A single MBR partition reattached over a 3-partition GPT card (the `I` flag)" +@{i}A single MBR partition reattached over a 3-partition GPT card (the `I` flag)@{ui} + +Starting from the three-FAT GPT card above (all @{fg shine}P--M@{fg text} ), that card was +removed and a single-partition MBR card inserted in its place. The scan +re-matches the new card's one partition to the @{fg shine}CFa0@{fg text} slot - note its Src +flips @{fg shine}GPT@{fg text} -> @{fg shine}MBR@{fg text} , the fresh card's scheme. The @{fg shine}CFa1@{fg text} and @{fg shine}CFa2@{fg text} handlers +were never unmounted, and the MBR card has no partition for them, so +those slots go @{fg shine}I@{fg text} (invalid): the present bit clears while mounted stays. + +@{fg highlight} + Name Device Unit Part Src Pri DosType Text Flags MFlg Ctrl + ------------ ------------- ---- ---- --- --- ---------- ---- ----- ----- ---------- + CFa0 compactflash. 0 0 MBR 0 0x46415400 FAT. P--M 0 -d-D + CFa1 compactflash. 0 1 GPT 0 0x46415400 FAT. I--M 0 -d-D + CFa2 compactflash. 0 2 GPT 0 0x46415400 FAT. I--M 0 -d-D +@{fg text} + +@{fg shine}CFa0@{fg text} re-mounted cleanly as @{fg shine}P--M@{fg text} with the new card's @{fg shine}MBR@{fg text} scheme. @{fg shine}CFa1@{fg text} / +@{fg shine}CFa2@{fg text} read @{fg shine}I--M@{fg text} - invalid but still mounted: the handlers hold the +mounts, and their Src stays @{fg shine}GPT@{fg text} (the removed card's value) since nothing +refreshed them. Contrast a card pulled with no replacement: those slots +read @{fg shine}---M@{fg text} (leading @{fg shine}-@{fg text} ), plain absent rather than invalid. + +---------------------------------------- +@{"<< Prev" link A_GPT_card_with_three_FAT_partitions__mounted} @{"Contents" link Main} @{"Next >>" link An_RDB_card_with_PFS_partitions} + +@endnode + +@node An_RDB_card_with_PFS_partitions "An RDB card with PFS partitions" +@{i}An RDB card with PFS partitions@{ui} + +@{fg highlight} + Name Device Unit Part Src Pri DosType Text Flags MFlg Ctrl + ------------ ------------- ---- ---- --- --- ---------- ---- ----- ----- ---------- + SDH10 compactflash. 0 0 RDB 0 0x4D414300 MAC. P-N- 0 + SDH11 compactflash. 0 1 RDB 0 0x4D414300 MAC. P-N- 0 + SDH0 compactflash. 0 2 RDB 0 0x50465303 PFS. PB-M 0 + SDH1 compactflash. 0 3 RDB 0 0x50465303 PFS. P--M 0 + SDH2 compactflash. 0 4 RDB 0 0x50465303 PFS. P--M 0 +@{fg text} + +@{fg shine}SDH0@{fg text} is bootable ( @{fg shine}B@{fg text} ). @{fg shine}SDH10@{fg text} and @{fg shine}SDH11@{fg text} are marked nomount ( @{fg shine}N@{fg text} ) in +their RDB entries, so they are published but not mounted (no @{fg shine}M@{fg text} ). RDB +partitions carry no @{fg shine}cfd.prefs@{fg text} Flags / CONTROL, so MFlg is @{fg shine}0@{fg text} and Ctrl is +empty. + +---------------------------------------- +@{"<< Prev" link A_single_MBR_partition_reattached_over_a_3_partition_GPT_card__the__I__flag_} @{"Contents" link Main} @{"Next >>" link Verbose} + +@endnode + +@node Verbose "Verbose" +@{i}Verbose@{ui} + +@{fg highlight} + Name Device Unit Part Src Pri DosType Text Flags MFlg Ctrl CMD Start Blocks Size + ------------ ------------- ---- ---- --- --- ---------- ---- ----- ----- ---------- ----- ------- -------- ------ + CFa0 compactflash. 0 0 GPT 0 0x46415400 FAT. P--M 0 -d-D NSCMD 2048 4194304 2048M +@{fg text} + +---------------------------------------- +@{"<< Prev" link An_RDB_card_with_PFS_partitions} @{"Contents" link Main} @{"Next >>" link See_also} + +@endnode + +@node See_also "See also" +@{b}See also@{ub} + + * @{fg shine}cfd.prefs@{fg text} (the @{fg shine}FLAGS@{fg text} / @{fg shine}CONTROL@{fg text} knobs, global and @{fg shine}_@{fg text} per-filesystem) + supplies the MFlg / Ctrl values for partitions cfd automounts; statically + mounted partitions show the values their handler opened the device with + instead. + * @{fg shine}lsfsres@{fg text} (fat95) lists @{fg shine}FileSystem.resource@{fg text} : the handlers, where @{fg shine}lsptres@{fg text} lists + the partitions they mount. + +---------------------------------------- +@{"<< Prev" link Verbose} @{"Contents" link Main} + +@endnode diff --git a/dist/full/68000/devs/compactflash.device b/dist/full/68000/devs/compactflash.device index 2de95bf..27b0954 100644 Binary files a/dist/full/68000/devs/compactflash.device and b/dist/full/68000/devs/compactflash.device differ diff --git a/dist/full/68000/libs/compactflash.automount b/dist/full/68000/libs/compactflash.automount new file mode 100644 index 0000000..0118332 Binary files /dev/null and b/dist/full/68000/libs/compactflash.automount differ diff --git a/dist/full/68000/libs/ptable.library b/dist/full/68000/libs/ptable.library index e590294..77fa2ed 100644 Binary files a/dist/full/68000/libs/ptable.library and b/dist/full/68000/libs/ptable.library differ diff --git a/dist/full/68020/devs/compactflash.device b/dist/full/68020/devs/compactflash.device index ba161d2..e5da051 100644 Binary files a/dist/full/68020/devs/compactflash.device and b/dist/full/68020/devs/compactflash.device differ diff --git a/dist/full/68020/libs/compactflash.automount b/dist/full/68020/libs/compactflash.automount new file mode 100644 index 0000000..0118332 Binary files /dev/null and b/dist/full/68020/libs/compactflash.automount differ diff --git a/dist/full/68020/libs/ptable.library b/dist/full/68020/libs/ptable.library index 6d9972f..de01d3c 100644 Binary files a/dist/full/68020/libs/ptable.library and b/dist/full/68020/libs/ptable.library differ diff --git a/dist/small/68000/devs/compactflash.device b/dist/small/68000/devs/compactflash.device index 2df4f7c..b63ee51 100644 Binary files a/dist/small/68000/devs/compactflash.device and b/dist/small/68000/devs/compactflash.device differ diff --git a/dist/small/68000/libs/compactflash.automount b/dist/small/68000/libs/compactflash.automount new file mode 100644 index 0000000..1893927 Binary files /dev/null and b/dist/small/68000/libs/compactflash.automount differ diff --git a/dist/small/68000/libs/ptable.library b/dist/small/68000/libs/ptable.library index 2f7adba..f4b55ad 100644 Binary files a/dist/small/68000/libs/ptable.library and b/dist/small/68000/libs/ptable.library differ diff --git a/dist/small/68020/devs/compactflash.device b/dist/small/68020/devs/compactflash.device index 18a88c8..df1cda4 100644 Binary files a/dist/small/68020/devs/compactflash.device and b/dist/small/68020/devs/compactflash.device differ diff --git a/dist/small/68020/libs/compactflash.automount b/dist/small/68020/libs/compactflash.automount new file mode 100644 index 0000000..1893927 Binary files /dev/null and b/dist/small/68020/libs/compactflash.automount differ diff --git a/dist/small/68020/libs/ptable.library b/dist/small/68020/libs/ptable.library index 11db829..2043210 100644 Binary files a/dist/small/68020/libs/ptable.library and b/dist/small/68020/libs/ptable.library differ diff --git a/docs/automount.md b/docs/automount.md new file mode 100644 index 0000000..0510d97 --- /dev/null +++ b/docs/automount.md @@ -0,0 +1,157 @@ +# compactflash.device automount and configuration + +This guide covers autoboot and automount for `compactflash.device`, and the `ENV:cfd.prefs` configuration file. The partition scanning and mounting itself is done by `ptable.library` (see its own `ptable.guide` for the library internals); this document is the user-facing reference. + +## What automount does + +`compactflash.device` reconciles `partition.resource` against the inserted card and (optionally) mounts its partitions. There are two stages: + +- Cold-boot autoboot (ROM-resident only): at Kickstart cold start, before DOS exists, the driver opens `ptable.library`, which walks the RDB on the card, loads any filesystem handlers stored in the RDB, and registers each partition as either bootable (appears in the Early Startup boot menu) or mountable-only. This is what lets you boot straight from an RDB-partitioned CF card. +- DOS-time (runtime) hotplug: after the machine is up, inserting a card scans it (RDB, MBR, GPT, or whole-disk flat) and publishes each partition into `partition.resource`; if automount is enabled the partitions are then mounted. Removing a card marks them absent (keep the filesystem handler) or unmounts (dismount filesystem handler) them, per the configured policy. + +`ptable.library` is required for both. Without it the device still works as a plain mount-only device (mount partitions yourself via `DEVS:DOSDrivers/`), but autoboot and automount are unavailable. + +## Filesystem handlers + +Automount mounts a partition only when a handler for its filesystem is already present in the system. It never loads a filesystem handler from `L:` by itself, so a handler file sitting unused in `L:` does not count. When no handler is available for a partition's filesystem, the partition is still scanned and listed by `lsptres`, but stays `P---` (present, not mounted); it is never falsely shown mounted. This applies to every filesystem the same way: FFS, SFS, PFS, FAT and any other. + +A handler becomes available in one of these ways: + +- Stored in the card's RDB (typical for native FFS, SFS and PFS partitions): `ptable.library` loads it straight from the RDB, both at cold boot and on a DOS-time insert, so an RDB card needs nothing extra. +- Built into the Kickstart ROM (for example pfs3aio, or fat95 in a custom ROM): registered by the handler's own startup at boot. +- Made resident from disk with `LoadModule` (for example adding `L:fat95` to your `LoadModule` line): becoming resident runs the handler's startup, which registers it. +- Loaded on demand when you mount a matching DOSDriver by hand: mounting one fat95 DOSDriver, for instance, loads fat95 from `L:` and registers its shared FAT code, after which automount binds every other FAT partition to it. + +FAT cards are the case that needs attention: MBR, GPT and whole-disk (flat) FAT cards carry no handler in their partition table, so fat95 must be provided by the ROM, `LoadModule`, or a mounted fat95 DOSDriver. Native FFS/SFS/PFS partitions on an RDB card carry their handler in the RDB, so they mount with no extra step. + +## Modules and deployment + +There are three modules, and boot/automount is opt-in by whether you include the third: + +- `compactflash.device`: the I/O driver. On its own it is a plain mount-only device. +- `ptable.library`: the partition scanner and automounter (RDB, MBR, GPT, flat FAT). +- `compactflash.automount`: optional boot/automount bringup. It carries two romtags: a cold-boot one (scans the card's RDB and registers partitions for autoboot, ROM only) and an after-DOS one (opens the device once DOS is up, which starts the card-detect interrupt and the automount agent). Include it only when you want autoboot or automount. + +Typical setups: + +| Goal | Modules | Cold-boot autoboot | +|---|---|---| +| ROM autoboot | `compactflash.device` + `compactflash.automount` + `ptable.library` in Kickstart | available | +| Resident/on-disk, no automount | `compactflash.device` + `ptable.library` (no automount module) | no | +| On-disk automount | `LoadModule LIBS:compactflash.automount LIBS:ptable.library DEVS:compactflash.device` (+ `L:fat95`) | no | + +`AUTOMOUNT` defaults **on everywhere** (ROM-resident and on-disk alike). Disable it with `AUTOMOUNT 0` in `ENV:cfd.prefs`; the resident driver re-reads that file on every card insert, so the setting takes effect without a rebuild. An explicit `AUTOMOUNT 0`/`1` always takes precedence over the default. An example config is shipped as `ENVARC/cfd.prefs` (copy it to `ENVARC:cfd.prefs` and `ENV:cfd.prefs`). + +One caveat for ROM-resident systems: the after-DOS bringup runs before the startup-sequence assigns `ENV:`, so `cfd.prefs` is not yet readable at that point and the built-in defaults apply. A card already in the slot at cold boot therefore auto-mounts once even when `ENVARC:cfd.prefs` says `AUTOMOUNT 0`; the setting takes effect as soon as `ENV:` exists (the next insert or removal re-reads it). Cold-boot RDB *autoboot* is unaffected, it does not depend on `AUTOMOUNT`. + +Other notes: + +- Even with automount off, an inserted card is still scanned and published to `partition.resource`, so `lsptres` lists the partitions; they are just not mounted. +- When you mount a device-dostype DOSDriver by hand (e.g. `CFAUX`), it serves its own partition. Automount pauses on each pass so that handler can claim its partition first, then reuses it (shown as `CFa0>CFAUX`) and mounts only the other partitions, rather than starting a second handler on the same one. + +### On-disk automount via LoadModule + +`LoadModule` (AmigaOS 3.x) makes on-disk modules resident and reboots. It activates only the *first* romtag of each file, which is why boot/automount lives in its own module: `compactflash.automount`'s first romtag is the after-DOS one, so `LoadModule` runs it. It opens the device once DOS is up, bringing up the card-detect interrupt and the automount agent; from then on hotplug works as in a disk install. Put `compactflash.automount` (and `ptable.library`) in `LIBS:` and add to `user-startup-sequence`: + +``` +LoadModule LIBS:compactflash.automount LIBS:ptable.library DEVS:compactflash.device L:fat95 +``` + +This does not give cold-boot RDB autoboot (booting straight off a CF card): that runs before DOS and needs `compactflash.device` + `compactflash.automount` + `ptable.library` in a real Kickstart ROM (see the companion kickstart-builder). `LoadModule` cannot provide it. + +### Building your own ROM + +A scripted Capitoline-based ROM builder for a 1 MB AmigaOS 3.2.3 / 3.1 / 2.05 Kickstart with `compactflash.device` + `ptable.library` embedded lives in the companion [amigaos-kickstart-builder](https://github.com/pulchart/amigaos-kickstart-builder) repo. + +## ENV:cfd.prefs reference + +Configuration is read from `ENV:cfd.prefs` at mount time. Write `ENVARC:cfd.prefs` too if you want it to survive a reboot. The driver re-reads the file on every card insert and every card removal, so a change takes effect the next time you insert or remove a card, with no reboot or rebuild needed. It reads the live `ENV:` copy, so update `ENV:cfd.prefs` for a change to apply now; editing only `ENVARC:cfd.prefs` does not take effect until the next reboot copies it into `ENV:`. Because removal is re-read too, a changed `UNMOUNT` applies to the very next card you pull. The format is one key per line, the value following the key after whitespace; keys are matched case-sensitively as whole words (so `FLAGS` does not match inside `FLAGS_DOS`). A missing key keeps its default. + +There is no comment syntax: put only the keys you want set. A `;`-prefixed line such as `; FLAGS 0` is still parsed as `FLAGS 0` (the parser finds the keyword anywhere in the file). Free-text notes are safe only if they avoid the uppercase key words. An example you can copy is shipped as `ENVARC/cfd.prefs`. + +| Key | Value | Default | Meaning | +|---|---|---|---| +| `AUTOMOUNT` | `0` or `1` | on | Mount partitions on insert. | +| `FLAGS` | decimal | `0` | Mount flags applied to every mount. See the bit table below. | +| `CONTROL` | string | none | Mount CONTROL string applied to every mount. | +| `UNMOUNT` | names | all | Filesystems to fully unmount on removal (see "Removable-media model"). Any subset of `DOS FFS SFS PFS FAT`; a key with no recognized names (e.g. `UNMOUNT NONE`) keeps every handler. | +| `FLAGS_` | decimal | global `FLAGS` | Per-filesystem override of `FLAGS`. `` is one of `DOS FFS SFS PFS FAT`. | +| `CONTROL_` | string | global `CONTROL` | Per-filesystem override of `CONTROL`. | + +`FLAGS` bits (see also the README "Mount Flags" section for the full description): + +| Bit value | Effect | +|---|---| +| 8 | serial debug output (full build) | +| 16 | enforce ATA multi-sector mode | + +The filesystem names understood in `UNMOUNT`, `FLAGS_` and `CONTROL_` are exactly these five, and no others: `DOS`, `FFS`, `SFS`, `PFS`, `FAT`. Any other name (`NTFS`, `EXT2`, `PDS`, ...) is not recognised and is silently ignored, taking no effect. In particular `PDS` is not a valid name: PFS3's `PDS\x` DosType is already covered by the `PFS` name, so use `PFS` for it. + +A per-filesystem key applies to partitions whose DosType high three bytes match: `DOS` = `DOS\x`, `FFS` = `DOS\x` fast-filesystem, `PFS` = `PFS\x` (and the `PDS\x` alias), `SFS` = `SFS\x`, `FAT` = `FAT\x`. Use the per-FS overrides when, for example, you want serial debug only on FAT mounts. + +Tip for hot-plugged FAT cards: `CONTROL_FAT "+q"` enables fat95's quiet option, so no error requesters ("please reinsert" / read / write windows) can pop up when a card is pulled with pending writes; errors are returned to the calling program instead. See the fat95 documentation for the full option list. + +### Example + +``` +AUTOMOUNT 1 +FLAGS 0 +UNMOUNT FAT +CONTROL_FAT +q +``` + +This keeps automount on (the default, listed for clarity), restricts the removal policy so only FAT volumes are fully unmounted when the card is pulled (PFS and others keep their handler, see below), and passes the `+q` (quiet) option to FAT (fat95) mounts only. Note that a CONTROL string is only meaningful for filesystems that parse one. + +## Removable-media model + +- Insert: the card is scanned and its partitions are published to `partition.resource` (always, even when automount is off). With automount on, partitions that are not yet mounted are mounted. +- Remove, default (no `UNMOUNT` key): every partition is fully unmounted (handler stopped, DOS node removed, memory freed). Its `partition.resource` line is kept and shown absent, so the partition is still listed; reinserting the card mounts it fresh. +- Remove, `UNMOUNT `: only partitions of the listed filesystems are unmounted as above. A filesystem not listed is marked absent instead: its DOS node and handler are kept in memory, and reinserting the same card reattaches it without re-initialising the handler (the native AmigaOS removable-media behaviour). `UNMOUNT NONE` (no recognized names) keeps every handler. + +Either way the partition stays visible in `lsptres` (shown absent) while the card is out, and is re-confirmed or re-published on reinsert. + +`AUTOMOUNT` gates only the mount step; it does not unmount. Changing `AUTOMOUNT 1` to `0` does not unmount volumes already mounted. To clear them, pull the card (the default removal policy unmounts them) or reboot. + +## Cold-boot autoboot details (ROM-resident) + +How each RDB partition is handled at cold boot: + +| RDB partition flag | BootPri | Result | +|---|---|---| +| normal | >= 0 | bootable: appears in the Early Startup boot device list | +| normal | < 0 | non-bootable: mounted as a DOS volume | +| NOMOUNT (bit 1 set) | any | skipped: not mounted, not in the DOS list | + +BootPri is stored in the RDB partition environment and controls boot order. + +The driver's cold-boot autoboot runs late in Kickstart's resident init, after the internal IDE (`scsi.device`) has started. Because that init is sequential, if the IDE stalls at boot (for example no drive connected), CF autoboot never gets its turn and does not trigger either. The boot stub first does a single Gayle read to check for a card; an empty slot returns immediately. With a card present it tolerates slow cards by polling up to about 1.8 s total; a healthy card adds no measurable delay. + +`ptable.library` also registers a synthetic expansion board (Vendor ID `65535 ($FFFF)`, Product ID `1`) so the Early Startup boot menu sees the device; it shows up in tools like `ShowConfig`. + +### Serial debug at cold boot + +A `full` build emits unconditional serial output at cold boot (9600 baud), regardless of the mountlist `Flags` setting. `compactflash.device` uses the `[CFD] boot:` prefix and `ptable.library` uses `[PT]`: + +``` +[CFD] boot: open ptable.library ... +[CFD] boot: BootScanPartitions(compactflash.device,0) +[PT] cold boot: scanning for partitions +[PT] RDB partition table +[PT] + filesystem handler PFS v20.0 +[PT] - skip SDH10 +[PT] + boot SDH0 +[PT] + mount SDH1 +[PT] + mount SDH2 +[PT] cold boot done, partitions registered: 3 +``` + +## Inspecting with lsptres + +`lsptres` lists `partition.resource`, which reflects the last-seen card whether or not partitions are mounted. The `Flags` column first char is `P` present, `I` invalid, or `-` absent. `I` means the slot is still mounted (its handler and DOS node are kept in memory), but the card currently in the slot has no such partition, typically after a card swap; it shows as `I--M` and returns to `P` when the original card is reinserted. A slot with no card in the drive at all reads `-`, so a kept mount whose media is simply gone shows `---M`. The remaining chars are `B` bootable, `N` nomount, `M` mounted. `MFlg` is the resolved mount flags and `Ctrl` the resolved CONTROL string. A mounted volume shows as `scanname>dosname` when its real DOS name differs from the scanned name. + +## Troubleshooting + +- Nothing automounts: check that `ENV:cfd.prefs` does not say `AUTOMOUNT 0` (the default is on), and that `ptable.library` is reachable (ROM-resident, or in `LIBS:` for DOS-time mounts). +- File-based, card present but nothing happens: the driver is not loaded until something opens it. Add a `DEVS:DOSDrivers/CF0` entry so it loads at boot. +- Partitions listed in `lsptres` but not mounted: automount is off, or they are a non-FAT filesystem with no handler available. +- Want serial trace of a DOS-time mount: set `FLAGS 8` (full build). diff --git a/docs/changes.md b/docs/changes.md index ec0a80a..13d182e 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,14 +1,34 @@ -## 20260614 +## 20260710-dev _Components in this release_: +- `compactflash.device 2.0-dev (10.07.2026)` _(new)_ +- `compactflash.automount 2.0-dev (10.07.2026)` _(new)_ +- `ptable.library 2.0-dev (10.07.2026)` _(new)_ +- `CFInfo 1.37 (11.01.2026)` +- `pcmciaspeed 1.36 (02.01.2026)` +- `pcmciacheck 1.39 (22.05.2026)` +- `lsptres 1.0-dev (10.07.2026)` _(new)_ + + +##### CompactFlash Driver + +- **Automount.** Hotplugged cards mount automatically at DOS time, on by default; disable with `AUTOMOUNT 0` in the new `ENV:cfd.prefs` config file. Removing a card fully unmounts all supported filesystems by default (`UNMOUNT ` restricts it, `UNMOUNT NONE` keeps the handlers). Boot and automount bringup is split into a separate `compactflash.automount` module. See [automount.md](automount.md). + +##### Partition Table library + +- **Unified partition scanning.** One scanner parses RDB, MBR, GPT, and flat (whole-disk) partition tables and publishes every partition into a shared `partition.resource`, now used by both `compactflash.device` and `fat95` instead of each carrying its own. The new `lsptres` tool lists the resource. See [ptable.md](https://github.com/pulchart/amigaos-ptable/blob/HEAD/docs/ptable.md) and [lsptres.md](https://github.com/pulchart/amigaos-ptable/blob/HEAD/docs/lsptres.md). + +## 20260614 + +_Components in this release_: + - `compactflash.device 1.44 (04.06.2026)` - `ptable.library 1.1 (07.06.2026)` - `CFInfo 1.37 (11.01.2026)` - `pcmciaspeed 1.36 (02.01.2026)` - `pcmciacheck 1.39 (22.05.2026)` - ##### Packaging diff --git a/extern/ptable b/extern/ptable new file mode 160000 index 0000000..67d537e --- /dev/null +++ b/extern/ptable @@ -0,0 +1 @@ +Subproject commit 67d537edd73be41176d36126ff80afba44165e69 diff --git a/src/cfd.s b/src/cfd.s index 36436ce..9fbd140 100644 --- a/src/cfd.s +++ b/src/cfd.s @@ -9,7 +9,7 @@ ; ; This tool 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 +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; ; You should have received a copy of the GNU Lesser General Public @@ -62,7 +62,8 @@ ; --- Includes --- include "cfd_version.i" include "cfd_debug.i" - include "lib/ptable_pub.i" + include "ptable_pub.i" ;from the ptable submodule (-I extern/ptable/src) + include "cfd_pub.i" ;CFD/CFU offsets shared with compactflash.automount ;--- from exec.library ------------------------------------- @@ -133,6 +134,12 @@ OpenResource = -498 TypeOfMem = -534 OpenLibrary = -552 CopyMem = -624 + +;-- dos.library (worker reads the config var) +DosGetVar = -906 +Delay = -198 ;dos.library +GVF_GLOBAL_ONLY = $100 +GVF_BINARY_VAR = $400 CacheClearE = -642 CacheControl = -648 RawPutChar = -516 @@ -560,16 +567,21 @@ CFD_ExecBase = 36 ;exec.library base pointer CFD_DosBase = 40 ;dos.library base pointer CFD_CardBase = 44 ;card.resource base pointer CFD_SegList = 48 ;segment list for expunge -CFD_Unit = 52 ;pointer to CFU (single unit) -; CFD extension for autoboot cooperation with ptable.library. Always +;CFD_Unit = 52 -> cfd_pub.i (shared with compactflash.automount) +; CFD extension for autoboot cooperation with ptable.library. Always ; present so the build is autoboot-capable in ROM without any -; compile-time toggle. When ptable.library is not loaded the slot +; compile-time toggle. When ptable.library is not loaded the slot ; stays zero (CFD allocation is MEMF_CLEAR). ; ; offset size field ; 56 1 CFD_BootDone one-shot re-entry guard set by the ; RTF_COLDSTART stub at end of scan -CFD_BootDone = 56 +; 57 1 CFD_DosReady set by the RTF_AFTERDOS hook when +; System-Startup reports DOS functional +; (step 13, see NDK system-startup.doc); +; the MountAgent defers all work until set +;CFD_BootDone = 56 -> cfd_pub.i (shared with compactflash.automount) +;CFD_DosReady = 57 -> cfd_pub.i (shared with compactflash.automount) CFD_Sizeof = 60 ;--------------------------------------------------------------------------- @@ -722,7 +734,16 @@ CFU_WriteBlockFn = 972 ;bound write-block handler (longword) ; Written alongside CFU_IOPtr at probe time. CFU_DataPort = 976 ;PCMCIA I/O base + 8 (longword) -CFU_Sizeof = 980 +;--- DOS-time automount agent (per unit) --- +; A small Exec task spawned at unit startup. The unit task signals it +; on card insert/remove (after NotifyClients); the agent reconciles the +; partition.resource via ptable.library v2 (Scan/Mount/Unmount) outside +; the Forbid window that NotifyClients runs under. +;CFU_MountAgent = 980 -> cfd_pub.i (shared with compactflash.automount) +;CFU_MountSig = 984 -> cfd_pub.i (shared with compactflash.automount) +CFU_MountDone = 988 ;worker-done signal mask (agent's bit) + +CFU_Sizeof = 992 ;CFU_Flags @@ -739,8 +760,8 @@ Start: s_resident: dc.w RTC_MATCHWORD dc.l s_resident - dc.l s_resident_boot ;EndSkip: continue ROM scan into the - ;cold-start stub Resident below. + dc.l s_codeend ;EndSkip: end of this module (boot/automount + ;bringup lives in compactflash.automount) dc.b RTF_AUTOINIT dc.b FILE_VERSION dc.b NT_DEVICE @@ -2303,6 +2324,8 @@ _t_1: move.l CFU_KillTask(a3),a1 CALLSAME Signal + bsr _SpawnMountAgent ;DOS-time automount worker (best-effort) + ;- - card already inserted? - - - - - - - - - - - - - - - - ; Poll CCDET for up to 1s on cold boot: GAYLE VCC and the ; PCMCIA card-detect line may not be electrically stable @@ -2463,7 +2486,7 @@ _t_do: ; handler not in) ; ; The ATAPI build flag (default 0) compiles in or out the -; ATAPI handler at _t_iatapi. -atapi releases ATAPI cards +; ATAPI handler at _t_iatapi. -atapi releases ATAPI cards ; classified by IDENTIFY so a dedicated ATAPI driver can ; claim them; +atapi routes ATAPI cards through the handler. ;=========================================================== @@ -2540,9 +2563,9 @@ _t_i2: ; CIS gate report DBGMSG dbg_cis_scan - ; Read CISTPL_DEVICE. On cold boot the card sometimes hasn't + ; Read CISTPL_DEVICE. On cold boot the card sometimes hasn't ; finished populating its attribute memory yet and returns an - ; all-zero "NULL/hole" tuple (type=0x00). Retry up to 10 times + ; all-zero "NULL/hole" tuple (type=0x00). Retry up to 10 times ; (~400ms) before giving up and falling through to FUNCID. moveq.l #10,d2 _t_dev_retry: @@ -2634,8 +2657,8 @@ _t_cis_gate_accept: ;-- Require CISTPL_FUNCEXT to declare IDE ---------------------- ; After DEVICE/FUNCID tentatively accept, demand a well-formed ; FUNCEXT (0x22) with TPLFE_TYPE=1 (Disk Interface) and - ; Interface=1 (IDE). Absent, malformed, or non-IDE rejects - ; the card before IDENTIFY. Retry the read up to 10 times to + ; Interface=1 (IDE). Absent, malformed, or non-IDE rejects + ; the card before IDENTIFY. Retry the read up to 10 times to ; tolerate CIS attribute-memory read instability on hardware ; like A1200 + ACA1234 (mirrors the CISTPL_CONFIG retry). moveq.l #10,d6 ;FUNCEXT retry counter @@ -2715,7 +2738,7 @@ _t_cis_gate_end: ; Try to locate CISTPL_CONFIG tuple for config register address. ; On cold boot the CIS attribute memory may parse OK structurally - ; but every byte still reads as zero, yielding addr=0. Retry the + ; but every byte still reads as zero, yielding addr=0. Retry the ; read up to 10 times before falling back to 0x200. ; Sets CFU_ConfigAddr and leaves a2 pointing at the CCR base. moveq.l #10,d3 @@ -2929,6 +2952,7 @@ _t_iok: DBGMSG dbg_id_ok DBGMSG dbg_notify bsr NotifyClients + bsr _MountAgentSignal ;wake automount agent (insert/no-disk) bra.w _t_check _t_identify_failed: @@ -2982,6 +3006,7 @@ _t_disown: clr.l (a0)+ dbf d0,.clr_loop bsr NotifyClients + bsr _MountAgentSignal ;wake automount agent (teardown) moveq.l #0,d0 lea CFU_CardHandle(a3),a1 CALLCARD ReleaseCard @@ -3022,6 +3047,864 @@ _t_end: sub.l a1,a1 JMPEXEC RemTask +;=========================================================== +; DOS-time automount agent +; +; Spawned per unit by _SpawnMountAgent at unit startup. Waits on +; CFU_MountSig; on each wake (the unit task signals it after +; NotifyClients on insert/remove) it reconciles partition.resource +; via ptable.library v2: +; card present -> ScanPartitions + MountPartitions +; card absent -> UnmountPartitions +; Both LVOs are idempotent, so a coalesced or stale wake is harmless. +; +; The agent is a bare Exec Task. The worker process reads ENV:ptable.prefs +; (AUTOMOUNT / FLAGS / UNMOUNT) and applies it. +;=========================================================== + +;-- _MountAgentSignal: wake the agent if it is up. a3=&Unit, a4=&Dev. +_MountAgentSignal: + movem.l d0/d1/a1/a6,-(sp) + move.l CFU_MountSig(a3),d0 + beq.s _masig_done + move.l CFU_MountAgent(a3),d1 + beq.s _masig_done + move.l d1,a1 + CALLEXEC Signal +_masig_done: + movem.l (sp)+,d0/d1/a1/a6 + rts + +;-- _SpawnMountAgent: create the agent task (best-effort). a3=&Unit, +; a4=&Dev. Mirrors NewUnit's task allocation (MemList + stack/Task + +; AddTask), minus the startup handshake. On failure CFU_MountAgent +; stays 0 and the device simply has no automount. +MA_STACK = 4096 + +; Settle (dos ticks, 50/s) the mount worker waits after scanning before it +; mounts, so a device-dostype handler that just opened us (and triggered this +; pass) can claim its partition via RegisterPartition first - the worker then +; reuses it instead of double-mounting. +MOUNT_SETTLE_TICKS = 50 + +_SpawnMountAgent: + movem.l d2-d3/a2,-(sp) + moveq.l #MA_STACK>>8,d3 + lsl.l #8,d3 ;d3 = agent stack size + moveq.l #24,d0 + move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d0,d2 ;&MemList + beq.w _sma_out + move.l d0,a1 + move.w #1,14(a1) ;ml_NumEntries = 1 + moveq.l #TC_Sizeof,d0 + add.l d3,d0 + move.l d0,20(a1) ;me_Length = Task + stack + move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 + CALLEXEC AllocMem + move.l d2,a1 + move.l d0,16(a1) ;me_Addr = stack base + beq.w _sma_freeml + move.l d0,a2 ;&stack + add.l d3,a2 ;&Task (top of stack) + lea MAgentName(pc),a0 + move.l a0,LN_Name(a2) + move.b #NT_TASK,LN_Type(a2) + move.l a2,TC_SPUpper(a2) + move.l d0,TC_SPLower(a2) + move.l a2,TC_SPReg(a2) ;initial SP = top of stack + lea TC_MemEntry(a2),a0 + INITLIST a0 + lea TC_MemEntry(a2),a0 + move.l d2,a1 + CALLEXEC AddHead ;MemList -> task (RemTask frees it) + move.l a3,TC_UserData(a2) ;&Unit + move.l a2,CFU_MountAgent(a3) + move.l a3,-(sp) ;preserve &Unit across AddTask + move.l a2,a1 + lea _MountAgentEntry(pc),a2 + sub.l a3,a3 ;finalPC = 0 + CALLEXEC AddTask + move.l (sp)+,a3 + DBGMSG dbg_ma_spawn + bra.s _sma_out +_sma_freeml: + moveq.l #24,d0 + move.l d2,a1 + CALLEXEC FreeMem +_sma_out: + movem.l (sp)+,d2-d3/a2 + rts + +;-- dos.library pieces for the worker-process launch. AddDosNode with +; ADNF_STARTPROC, LockDosList/RemDosEntry and ACTION_DIE are process- +; only DOS calls; running them from the bare agent task made dos read +; Process fields past the end of the Task struct (first hardware test: +; garbage-pointer storm + guru 8000 0003). The agent therefore only +; catches events; the DOS work runs in a short-lived worker process. +; CreateNewProc is documented callable from a task (dos autodoc) when +; nothing needs inheriting; every inheritable tag is given explicitly. +DOS_CreateNewProc = -498 + +NP_Dummy = $80000000+1000 +NP_Seglist = NP_Dummy+1 +NP_FreeSeglist = NP_Dummy+2 +NP_Input = NP_Dummy+4 +NP_Output = NP_Dummy+5 +NP_CloseInput = NP_Dummy+6 +NP_CloseOutput = NP_Dummy+7 +NP_CurrentDir = NP_Dummy+10 +NP_StackSize = NP_Dummy+11 +NP_Name = NP_Dummy+12 +NP_Priority = NP_Dummy+13 +NP_WindowPtr = NP_Dummy+15 +NP_CopyVars = NP_Dummy+17 + +MW_TAGBYTES = 26*4 ;13 TagItem pairs incl TAG_DONE + +;-- _MountAgentEntry: the agent task body. +; a3=&Unit, a4=&Dev, d5=wake mask, d4=done mask, d7=dos base. +; Pure event catcher: waits for the unit task's Signal, makes sure +; dos.library is up, then runs one CF.MountWork process and waits for +; its done-Signal (serialises workers; coalesced events just rerun). +_MountAgentEntry: + move.l (_AbsExecBase).w,a6 + sub.l a1,a1 + jsr FindTask(a6) + move.l d0,a0 + move.l TC_UserData(a0),a3 ;&Unit + move.l CFU_Device(a3),a4 ;&Dev (for CALLEXEC) + moveq.l #0,d4 + moveq.l #0,d5 + moveq.l #0,d7 +;-- allocate the wake + worker-done signals in this task + moveq.l #-1,d0 + CALLEXEC AllocSignal + cmp.b #-1,d0 + beq.w _ma_die + bset d0,d5 ;d5 = wake mask + moveq.l #-1,d0 + CALLEXEC AllocSignal + cmp.b #-1,d0 + beq.w _ma_die + bset d0,d4 ;d4 = done mask + move.l d4,CFU_MountDone(a3) + move.l d5,CFU_MountSig(a3) ;publish last: signals valid now + +;-- Disk-loaded driver: CFD_BootDone == 0 means RTF_COLDSTART / +; RTF_AFTERDOS never ran, so mark DOS ready here (DOS is up at +; disk-load time). ROM builds (== 1) keep the AFTERDOS gate. + tst.b CFD_BootDone(a4) + bne.s _ma_loop + move.b #1,CFD_DosReady(a4) +;-- file-based load: no AFTERDOS hook to kick us, and the unit task's +; startup card-detect signalled before our wake signal existed (lost). +; Self-signal so the first loop reconciles a card already in the slot. + bsr _MountAgentSignal + +_ma_loop: + move.l d5,d0 + CALLEXEC Wait + ifd DEBUG + move.l CFU_DriveSize(a3),d0 + bne.s _ma_wk_in + DBGMSG dbg_ma_wake_out + bra.s _ma_wk_done +_ma_wk_in: + DBGMSG dbg_ma_wake_in +_ma_wk_done: + endc +;-- Defer everything until System-Startup reports DOS functional (the +; RTF_AFTERDOS hook sets CFD_DosReady and re-signals us, so deferred +; events are reprocessed). The agent must never call dos.library +; while System-Startup is still building it: the first hardware test +; raced it (CreateNewProc into a half-built DOS, wild jump to PC=8). + tst.b CFD_DosReady(a4) + beq.w _ma_loop + bsr _ma_dos_open ;d7 = DOSBase (opened once, kept) + DBGMSG dbg_ma_dos + tst.l d7 + beq.w _ma_loop ;cannot happen post-AFTERDOS; be safe +;-- launch the worker process (tag list built on the stack; the seglist +; BPTR must be computed at runtime, so no static table) + moveq.l #0,d1 + move.l d1,-(sp) ;TAG_DONE data (unread) + move.l d1,-(sp) ;TAG_DONE + move.l d1,-(sp) ;NP_CopyVars = FALSE + move.l #NP_CopyVars,-(sp) + moveq.l #-1,d0 + move.l d0,-(sp) ;NP_WindowPtr = -1 (no requesters) + move.l #NP_WindowPtr,-(sp) + move.l d1,-(sp) ;NP_CurrentDir = 0 + move.l #NP_CurrentDir,-(sp) + move.l d1,-(sp) ;NP_CloseOutput = FALSE + move.l #NP_CloseOutput,-(sp) + move.l d1,-(sp) ;NP_CloseInput = FALSE + move.l #NP_CloseInput,-(sp) + move.l d1,-(sp) ;NP_Output = 0 + move.l #NP_Output,-(sp) + move.l d1,-(sp) ;NP_Input = 0 + move.l #NP_Input,-(sp) + move.l #8192,-(sp) ;NP_StackSize + move.l #NP_StackSize,-(sp) + move.l d1,-(sp) ;NP_Priority = 0 + move.l #NP_Priority,-(sp) + pea MWorkName(pc) ;NP_Name + move.l #NP_Name,-(sp) + move.l d1,-(sp) ;NP_FreeSeglist = FALSE (ROM seglist!) + move.l #NP_FreeSeglist,-(sp) + lea _ma_fakeseg(pc),a0 + move.l a0,d0 + lsr.l #2,d0 + move.l d0,-(sp) ;NP_Seglist = BPTR(fake ROM seglist) + move.l #NP_Seglist,-(sp) + move.l sp,d1 ;d1 = tag list + move.l d7,a6 + jsr DOS_CreateNewProc(a6) + lea MW_TAGBYTES(sp),sp + tst.l d0 + bne.s _ma_worker_ok + DBGMSG dbg_ma_run_fail + bra.w _ma_loop ;no memory: retry on next event +_ma_worker_ok: +;-- wait for the worker to finish (one at a time) + move.l d4,d0 + CALLEXEC Wait + bra.w _ma_loop + +;-- _ma_dos_open: d7 = DOSBase, opened once and kept. Only called +; after CFD_DosReady, so a single OpenLibrary suffices (no polling). +_ma_dos_open: + movem.l d0/a1,-(sp) + tst.l d7 + bne.s _mado_done ;already open + moveq.l #36,d0 + lea MAgentDosName(pc),a1 + CALLEXEC OpenLibrary + move.l d0,d7 +_mado_done: + movem.l (sp)+,d0/a1 + rts + +;-- _ma_die: setup failed; clear identity and remove self. +_ma_die: + clr.l CFU_MountSig(a3) + clr.l CFU_MountDone(a3) + clr.l CFU_MountAgent(a3) + tst.l d5 + beq.s _ma_die_2 + move.l d5,d0 + LOG2 + CALLEXEC FreeSignal +_ma_die_2: + tst.l d4 + beq.s _ma_die_rt + move.l d4,d0 + LOG2 + CALLEXEC FreeSignal +_ma_die_rt: + sub.l a1,a1 + JMPEXEC RemTask + +;-- Fake seglist for NP_Seglist: BPTR -> the next-BPTR longword; DOS +; starts execution 4 bytes after it. Lives in ROM, never freed +; (NP_FreeSeglist = FALSE). + cnop 0,4 + dc.l 16 ;fake segment length (never freed) +_ma_fakeseg: + dc.l 0 ;next segment = none + jmp _MountWorkEntry(pc) + +;-- _MountWorkEntry: the worker, a real DOS process. Looks up the +; device by name (single unit), reconciles partition.resource against +; the live card state via ptable.library v2, signals the agent, exits. +_MountWorkEntry: + movem.l d2-d7/a2-a6,-(sp) + lea -CFG_SIZEOF(sp),sp ;config frame + move.l sp,a5 ;a5 = config frame base + move.l (_AbsExecBase).w,a6 + jsr Forbid(a6) + lea SB_DeviceList(a6),a0 + lea s_name(pc),a1 ;"compactflash.device" + jsr FindName(a6) + move.l d0,d2 + jsr Permit(a6) + tst.l d2 + beq.w _mw_out ;device gone: nothing to do + move.l d2,a4 ;&Dev (for CALLEXEC / DBGMSG) + move.l CFD_Unit(a4),d0 + beq.w _mw_out + move.l d0,a3 ;&Unit +;-- open ptable.library v2; without it there is nothing to reconcile + moveq.l #2,d0 + lea RdbLibName(pc),a1 ;"ptable.library" + CALLEXEC OpenLibrary + move.l d0,d6 + ifd DEBUG + bne.s _mw_haveLib + DBGMSG dbg_mw_pt_fail + bra.w _mw_done +_mw_haveLib: + DBGMSG dbg_mw_pt + else + beq.w _mw_done + endc + bsr _mwReadConfig ;ENV:cfd.prefs -> a5 frame + ifd DEBUG + move.w CFG_MountCfg+mc_Flags+2(a5),d0 ;global FLAGS -> gate so worker trace shows + or.w d0,CFU_OpenFlags(a3) + DBGMSG dbg_mw_cfg_b + move.l CFG_DbgRead(a5),d0 + DBGDEC + DBGMSG dbg_mw_cfg_am + moveq.l #0,d0 + move.b CFG_AutoMount(a5),d0 + DBGDEC + DBGMSG dbg_mw_cfg_fl + move.l CFG_MountCfg+mc_Flags(a5),d0 + DBGDEC + DBGNL + endc + tst.l CFU_DriveSize(a3) + beq.w _mw_unmount +;-- card present: always scan/publish so the partitions show in lsptres +; (partition.resource only, no DOS nodes); mount only if automount is on. + DBGMSG dbg_mw_scan_b + move.l d6,a6 + lea s_name(pc),a1 + moveq.l #0,d0 ;unit 0 (the only unit) + jsr _LVOScanPartitions(a6) + DBGMSG dbg_mw_scan_a + DBGDEC + DBGNL + tst.b CFG_AutoMount(a5) + beq.w _mw_close ;automount off: published for lsptres, not mounted +;-- settle: let an in-flight handler mount (a device-dostype DOSDriver that just +; opened us) register its partition before we mount, so MountPartitions reuses +; it (PEB_MOUNTED) instead of starting a second handler on the same partition. + moveq.l #0,d0 ;any version + lea MAgentDosName(pc),a1 + CALLEXEC OpenLibrary + tst.l d0 + beq.s _mw_settled + move.l d0,d2 ;d2 = DOSBase (preserved across Delay) + move.l d0,a6 + move.l #MOUNT_SETTLE_TICKS,d1 + jsr Delay(a6) + move.l d2,a1 + CALLEXEC CloseLibrary +_mw_settled: + DBGMSG dbg_mw_mnt_b + move.l d6,a6 + lea s_name(pc),a1 + moveq.l #0,d0 + lea CFG_MountCfg(a5),a0 ;MountCfg -> per-partition Flags/Control + jsr _LVOMountPartitions(a6) + DBGMSG dbg_mw_mnt_a + DBGDEC + DBGNL + bra.s _mw_close +_mw_unmount: +;-- card removed: empty UNMOUNT list -> MarkAbsent (keep node + handler); +; non-empty -> UnmountPartitions(prefixList) (unmount the listed filesystems). + DBGMSG dbg_mw_umnt_b + move.l d6,a6 + lea s_name(pc),a1 + moveq.l #0,d0 + lea CFG_Prefixes(a5),a0 + tst.l (a0) ;empty prefix list? + bne.s _mw_detach + jsr _LVOMarkAbsent(a6) + bra.s _mw_detach_dbg +_mw_detach: + jsr _LVOUnmountPartitions(a6) +_mw_detach_dbg: + DBGMSG dbg_mw_umnt_a + DBGDEC + DBGNL +_mw_close: + move.l d6,a1 + CALLEXEC CloseLibrary +_mw_done: +;-- wake the agent (it serialises on this) + move.l CFU_MountDone(a3),d0 + beq.s _mw_out + move.l CFU_MountAgent(a3),d1 + beq.s _mw_out + move.l d1,a1 + CALLEXEC Signal +_mw_out: + lea CFG_SIZEOF(sp),sp ;release config frame + movem.l (sp)+,d2-d7/a2-a6 + moveq.l #0,d0 + rts + +;=========================================================== +; _mwReadConfig: read ENV:cfd.prefs into the config frame via GetVar (global, +; binary so multi-line is read whole) and build a MountCfg. Line-oriented, +; exact whole-word keys: AUTOMOUNT / FLAGS / CONTROL / UNMOUNT (global) plus +; FLAGS_ / CONTROL_ per-dostype overrides. A missing var or key keeps +; the default (flags 0, no control). AUTOMOUNT defaults on everywhere (ROM and +; file-based alike); opt out with AUTOMOUNT 0 in cfd.prefs. UNMOUNT defaults to +; all supported filesystems; an UNMOUNT key with no recognized names (e.g. +; UNMOUNT NONE) keeps handlers on removal instead. +; In : a5 = config frame. Preserves a3/a4/a5/d6/d7. +;=========================================================== +CFG_BUFSZ = 256 +CFG_OVMAX = 6 ;max override rows +CFG_NCTL = 8 ;control-pool slots (global + per-FS) +CFG_CTLSZ = 32 ;bytes per control slot + +CFG_Buf = 0 ;config text buffer (0..255) +CFG_Prefixes = 256 ;UNMOUNT dostype list, 0-terminated (8 longs) +CFG_AutoMount = 288 ;byte (1 = automount on) +CFG_CtlNext = 289 ;byte (control slots used) +CFG_OvNext = 290 ;byte (override rows used) +CFG_DbgRead = 292 ;long GetVar result (-1 = var not defined) +CFG_MountCfg = 296 ;MountCfg (mc_Flags/mc_Control/mc_Overrides) +CFG_Overrides = 308 ;(CFG_OVMAX+1) override rows * ovr_Sizeof +CFG_Controls = 420 ;CFG_NCTL control C-string slots * CFG_CTLSZ +CFG_SIZEOF = 676 + +_mwReadConfig: + movem.l d0-d7/a0-a4/a6,-(sp) + move.b #1,CFG_AutoMount(a5) ;automount on by default everywhere; opt + ;out via AUTOMOUNT 0 in ENV:cfd.prefs + move.l #-1,CFG_DbgRead(a5) + clr.b CFG_CtlNext(a5) + clr.b CFG_OvNext(a5) + clr.l CFG_MountCfg+mc_Flags(a5) + clr.l CFG_MountCfg+mc_Control(a5) + clr.l CFG_MountCfg+mc_Overrides(a5) +;-- default UNMOUNT list: every um_table prefix (unmount all supported +; filesystems on removal). An explicit UNMOUNT key rebuilds the list; a key +; with no recognized names leaves it empty (keep handlers). 6 prefixes + +; terminator fit the 8-long CFG_Prefixes field. + lea CFG_Prefixes(a5),a0 + lea um_table(pc),a1 +_cfg_umdef: + move.l (a1)+,d0 ;name ptr (0 = end of table) + beq.s _cfg_umdef_done + move.l (a1)+,(a0)+ ;append the row's dostype prefix + bra.s _cfg_umdef +_cfg_umdef_done: + clr.l (a0) ;terminate prefix list + lea CFG_Overrides(a5),a0 + clr.l ovr_Prefix(a0) ;empty override table (terminator) + move.l (_AbsExecBase).w,a6 + moveq.l #36,d0 + lea MAgentDosName(pc),a1 ;"dos.library" + jsr OpenLibrary(a6) + tst.l d0 + beq.w _cfg_done ;no dos.library -> defaults + move.l d0,a2 ;a2 = DOSBase +;-- read the global env var whole (binary so newlines are kept) + move.l a2,a6 + lea s_cfgname(pc),a0 + move.l a0,d1 ;name = "cfd.prefs" (bare, no ENV:) + lea CFG_Buf(a5),a0 + move.l a0,d2 ;buffer + move.l #CFG_BUFSZ-1,d3 ;buffer size + move.l #GVF_GLOBAL_ONLY!GVF_BINARY_VAR,d4 + jsr DosGetVar(a6) + move.l d0,d3 ;d3 = length, or -1 if not defined + move.l d3,CFG_DbgRead(a5) + move.l a2,a1 + move.l (_AbsExecBase).w,a6 + jsr CloseLibrary(a6) + tst.l d3 + ble.w _cfg_done ;not defined / empty -> defaults + cmp.l #CFG_BUFSZ-1,d3 + bcs.s _cfg_term + move.l #CFG_BUFSZ-1,d3 +_cfg_term: + lea CFG_Buf(a5),a0 + clr.b 0(a0,d3.l) ;NUL-terminate +;-- AUTOMOUNT + lea CFG_Buf(a5),a0 + lea kw_automount(pc),a1 + bsr _cfgStr + tst.l d0 + beq.s _cfg_flags + move.l d0,a0 + bsr _cfgSkipSp + cmp.b #'0',(a0) + bne.s _cfg_am_on ;explicit non-0 value -> on (overrides default) + clr.b CFG_AutoMount(a5) ;AUTOMOUNT 0 -> off + bra.s _cfg_flags +_cfg_am_on: + move.b #1,CFG_AutoMount(a5) ;AUTOMOUNT 1 -> on +_cfg_flags: +;-- global FLAGS + lea CFG_Buf(a5),a0 + lea kw_flags(pc),a1 + bsr _cfgStr + tst.l d0 + beq.s _cfg_control + move.l d0,a0 + bsr _cfgSkipSp + bsr _cfgDec + move.l d0,CFG_MountCfg+mc_Flags(a5) +_cfg_control: +;-- global CONTROL + lea CFG_Buf(a5),a0 + lea kw_control(pc),a1 + bsr _cfgStr + tst.l d0 + beq.s _cfg_ovkw + move.l d0,a0 + bsr _cfgSkipSp + bsr _cfgCtl + move.l d0,CFG_MountCfg+mc_Control(a5) +_cfg_ovkw: +;-- per-FS overrides: {keyword, dostype-prefix, isControl} rows + lea ovkw_table(pc),a4 +_cfg_ovloop: + move.l (a4),d0 ;keyword (0 = end) + beq.s _cfg_unmount + move.l d0,a1 + lea CFG_Buf(a5),a0 + bsr _cfgStr + tst.l d0 + beq.s _cfg_ovnext + move.l d0,a0 ;a0 = value start + bsr _cfgSkipSp + move.l 4(a4),d0 ;prefix + bsr _cfgFindOrAddOv ;d1 = row (0 = table full) + tst.l d1 + beq.s _cfg_ovnext + move.l d1,a1 ;a1 = override row + tst.l 8(a4) ;isControl? + bne.s _cfg_ovctl + bsr _cfgDec ;FLAGS_ + move.l d0,ovr_Flags(a1) + move.b #1,ovr_HasFlags(a1) + bra.s _cfg_ovnext +_cfg_ovctl: + bsr _cfgCtl ;CONTROL_ + move.l d0,ovr_Control(a1) +_cfg_ovnext: + lea 12(a4),a4 ;next ovkw row (12 bytes) + bra.s _cfg_ovloop +_cfg_unmount: + lea CFG_Buf(a5),a0 + lea kw_unmount(pc),a1 + bsr _cfgStr + tst.l d0 + beq.s _cfg_done ;no UNMOUNT key -> keep default (unmount all) + lea CFG_Prefixes(a5),a2 ;output cursor + lea um_table(pc),a3 ;{name, dostype prefix} rows +_cfg_um_loop: + move.l (a3),d0 ;name pointer (0 = end of table) + beq.s _cfg_um_term + lea CFG_Buf(a5),a0 + move.l d0,a1 ;needle = FS name + bsr _cfgStr + tst.l d0 + beq.s _cfg_um_next + move.l 4(a3),(a2)+ ;name present -> append its dostype prefix +_cfg_um_next: + addq.l #8,a3 ;next row + bra.s _cfg_um_loop +_cfg_um_term: + clr.l (a2) ;terminate prefix list +_cfg_done: + movem.l (sp)+,d0-d7/a0-a4/a6 + rts + +;-- _cfgStr: find NUL-term needle (a1) as a WHOLE WORD in NUL-term haystack (a0). +; Word char = [A-Za-z0-9_]; the match must be bounded by non-word chars (or the +; buffer ends) on both sides, so FLAGS does not match inside FLAGS_DOS and a +; name DOS does not match inside FLAGS_DOS. +; Out: d0 = ptr just past the match, or 0. Preserves d2-d3/a2-a4. +_cfgStr: + movem.l d2-d3/a2-a4,-(sp) + move.l a1,a3 ;needle start + move.l a0,a4 ;haystack start +_cs_outer: + tst.b (a0) + beq.s _cs_no ;haystack end -> no match + cmp.l a0,a4 + beq.s _cs_try ;at start -> prev boundary ok + move.l a0,a2 + subq.l #1,a2 + move.b (a2),d2 + bsr _cfgWordCh + tst.b d0 + bne.s _cs_adv ;prev is word char -> not a word start +_cs_try: + move.l a0,a2 ;haystack cursor + move.l a3,a1 ;needle cursor +_cs_inner: + move.b (a1)+,d3 + beq.s _cs_chksfx ;needle end -> check suffix boundary + move.b (a2)+,d2 + beq.s _cs_no ;haystack ended mid-needle + cmp.b d3,d2 + beq.s _cs_inner + bra.s _cs_adv ;mismatch +_cs_chksfx: + move.b (a2),d2 ;char just past match + bsr _cfgWordCh + tst.b d0 + bne.s _cs_adv ;suffix is word char -> not whole word + move.l a2,d0 ;whole-word match + bra.s _cs_ret +_cs_adv: + addq.l #1,a0 + bra.s _cs_outer +_cs_no: + moveq.l #0,d0 +_cs_ret: + movem.l (sp)+,d2-d3/a2-a4 + rts + +;-- _cfgWordCh: d2.b char -> d0.b = 1 if [A-Za-z0-9_] else 0. +_cfgWordCh: + moveq.l #1,d0 + cmp.b #'0',d2 + bcs.s _cwc_a + cmp.b #'9',d2 + bls.s _cwc_ret +_cwc_a: + cmp.b #'A',d2 + bcs.s _cwc_b + cmp.b #'Z',d2 + bls.s _cwc_ret +_cwc_b: + cmp.b #'a',d2 + bcs.s _cwc_c + cmp.b #'z',d2 + bls.s _cwc_ret +_cwc_c: + cmp.b #'_',d2 + beq.s _cwc_ret + moveq.l #0,d0 +_cwc_ret: + rts + +;-- _cfgSkipSp: advance a0 past spaces, tabs and '='. Clobbers d0. +_cfgSkipSp: + move.b (a0),d0 + cmp.b #' ',d0 + beq.s _csk_adv + cmp.b #9,d0 + beq.s _csk_adv + cmp.b #'=',d0 + beq.s _csk_adv + rts +_csk_adv: + addq.l #1,a0 + bra.s _cfgSkipSp + +;-- _cfgDec: parse unsigned decimal at a0 -> d0. Advances a0; preserves a1-a4. +_cfgDec: + movem.l d1-d2,-(sp) + moveq.l #0,d1 +_cfgdec_l: + moveq.l #0,d0 + move.b (a0)+,d0 + sub.b #'0',d0 + bcs.s _cfgdec_e + cmp.b #9,d0 + bhi.s _cfgdec_e + move.l d1,d2 + lsl.l #3,d1 + add.l d2,d1 + add.l d2,d1 ;d1 = d1*10 + add.l d0,d1 + bra.s _cfgdec_l +_cfgdec_e: + move.l d1,d0 + movem.l (sp)+,d1-d2 + rts + +;-- _cfgCtl: copy the CONTROL value at a0 (optionally "quoted") into the next +; control-pool slot. Out: d0 = slot addr, or 0 (empty / pool full). +; Preserves a1-a4/d1-d4. +_cfgCtl: + movem.l d1-d4/a1-a2,-(sp) + moveq.l #0,d1 + move.b CFG_CtlNext(a5),d1 + cmp.b #CFG_NCTL,d1 + bhs.s _cfgctl_none + move.l d1,d4 + lsl.l #5,d4 ;*CFG_CTLSZ (32) + lea CFG_Controls(a5),a1 + add.l d4,a1 ;a1 = slot base + move.l a1,a2 ;a2 = dest cursor + moveq.l #CFG_CTLSZ-1,d3 + moveq.l #0,d2 ;quote flag + cmp.b #'"',(a0) + bne.s _cfgctl_cp + addq.l #1,a0 + moveq.l #1,d2 +_cfgctl_cp: + move.b (a0)+,d1 + beq.s _cfgctl_end + tst.b d2 + bne.s _cfgctl_q + cmp.b #' ',d1 ;ws-delimited: stop at space/ctrl + bls.s _cfgctl_end + cmp.b #',',d1 + beq.s _cfgctl_end + bra.s _cfgctl_put +_cfgctl_q: + cmp.b #'"',d1 ;closing quote + beq.s _cfgctl_end +_cfgctl_put: + tst.l d3 + beq.s _cfgctl_end + move.b d1,(a2)+ + subq.l #1,d3 + bra.s _cfgctl_cp +_cfgctl_end: + clr.b (a2) ;NUL-terminate slot + tst.b (a1) + beq.s _cfgctl_none ;empty -> no slot consumed + addq.b #1,CFG_CtlNext(a5) + move.l a1,d0 + movem.l (sp)+,d1-d4/a1-a2 + rts +_cfgctl_none: + moveq.l #0,d0 + movem.l (sp)+,d1-d4/a1-a2 + rts + +;-- _cfgFindOrAddOv: find the override row for prefix d0, else append one. +; Out: d1 = row addr, or 0 if table full. Preserves a0/d0/a2-a4. +_cfgFindOrAddOv: + movem.l d2/a1-a2,-(sp) + lea CFG_Overrides(a5),a1 +_cfoa_scan: + move.l ovr_Prefix(a1),d2 + beq.s _cfoa_add + cmp.l d2,d0 + beq.s _cfoa_hit + lea ovr_Sizeof(a1),a1 + bra.s _cfoa_scan +_cfoa_add: + moveq.l #0,d2 + move.b CFG_OvNext(a5),d2 + cmp.b #CFG_OVMAX,d2 + bhs.s _cfoa_full + addq.b #1,CFG_OvNext(a5) + move.l d0,ovr_Prefix(a1) + clr.l ovr_Flags(a1) + clr.b ovr_HasFlags(a1) + clr.l ovr_Control(a1) + lea ovr_Sizeof(a1),a2 + clr.l ovr_Prefix(a2) ;new terminator + lea CFG_Overrides(a5),a2 + move.l a2,CFG_MountCfg+mc_Overrides(a5) +_cfoa_hit: + move.l a1,d1 + movem.l (sp)+,d2/a1-a2 + rts +_cfoa_full: + moveq.l #0,d1 + movem.l (sp)+,d2/a1-a2 + rts + +s_cfgname: dc.b "cfd.prefs",0 +kw_automount: dc.b "AUTOMOUNT",0 +kw_flags: dc.b "FLAGS",0 +kw_control: dc.b "CONTROL",0 +kw_unmount: dc.b "UNMOUNT",0 +kw_flags_dos: dc.b "FLAGS_DOS",0 +kw_flags_ffs: dc.b "FLAGS_FFS",0 +kw_flags_sfs: dc.b "FLAGS_SFS",0 +kw_flags_pfs: dc.b "FLAGS_PFS",0 +kw_flags_fat: dc.b "FLAGS_FAT",0 +kw_ctl_dos: dc.b "CONTROL_DOS",0 +kw_ctl_ffs: dc.b "CONTROL_FFS",0 +kw_ctl_sfs: dc.b "CONTROL_SFS",0 +kw_ctl_pfs: dc.b "CONTROL_PFS",0 +kw_ctl_fat: dc.b "CONTROL_FAT",0 +nm_pfs: dc.b "PFS",0 +nm_dos: dc.b "DOS",0 +nm_ffs: dc.b "FFS",0 +nm_sfs: dc.b "SFS",0 +nm_fat: dc.b "FAT",0 + even + +;-- UNMOUNT name -> dostype-prefix table. Each row: name C-string, prefix +; (pe_DosType high 3 bytes). A name may have several rows; add a filesystem +; by adding a row. 0 terminates. +um_table: + dc.l nm_pfs,$50465300 ;PFS -> 'PFS' + dc.l nm_pfs,$50445300 ;PFS -> 'PDS' (pfs3 alternate) + dc.l nm_dos,$444F5300 ;DOS -> 'DOS' + dc.l nm_ffs,$444F5300 ;FFS -> 'DOS' + dc.l nm_sfs,$53465300 ;SFS -> 'SFS' + dc.l nm_fat,$46415400 ;FAT -> 'FAT' + dc.l 0 + +;-- per-FS override keyword table. Each row: keyword, dostype prefix, +; isControl (0 = FLAGS_, 1 = CONTROL_). PFS has two rows (PFS + PDS). +; 0 terminates. +ovkw_table: + dc.l kw_flags_dos,$444F5300,0 + dc.l kw_flags_ffs,$444F5300,0 + dc.l kw_flags_sfs,$53465300,0 + dc.l kw_flags_pfs,$50465300,0 + dc.l kw_flags_pfs,$50445300,0 + dc.l kw_flags_fat,$46415400,0 + dc.l kw_ctl_dos,$444F5300,1 + dc.l kw_ctl_ffs,$444F5300,1 + dc.l kw_ctl_sfs,$53465300,1 + dc.l kw_ctl_pfs,$50465300,1 + dc.l kw_ctl_pfs,$50445300,1 + dc.l kw_ctl_fat,$46415400,1 + dc.l 0 + +MAgentName: + dc.b "CF.MountAgent",0 +MWorkName: + dc.b "CF.MountWork",0 +MAgentDosName: + dc.b "dos.library",0 +RdbLibName: + dc.b "ptable.library",0 + even + + ifd DEBUG +dbg_ma_spawn: + dc.b "[MA] automount agent ready (unit 0)",13,10,0 +dbg_ma_wake_in: + dc.b "[MA] unit 0: card present, automounting",13,10,0 +dbg_ma_wake_out: + dc.b "[MA] unit 0: card removed",13,10,0 +dbg_ma_dos: + dc.b "[MA] unit 0: DOS ready, starting worker",13,10,0 +dbg_ma_run_fail: + dc.b "[MA] unit 0: ERROR could not start mount worker",13,10,0 +dbg_mw_pt: + dc.b "[MW] using ptable.library",13,10,0 +dbg_mw_pt_fail: + dc.b "[MW] ERROR ptable.library unavailable",13,10,0 +dbg_mw_scan_b: + dc.b "[MW] scanning compactflash.device:0 for partitions",13,10,0 +dbg_mw_scan_a: + dc.b "[MW] scan done, partitions known: ",0 +dbg_mw_mnt_b: + dc.b "[MW] mounting new partitions",13,10,0 +dbg_mw_mnt_a: + dc.b "[MW] mounted volumes: ",0 +dbg_mw_umnt_b: + dc.b "[MW] card removed",13,10,0 +dbg_mw_umnt_a: + dc.b "[MW] entries detached: ",0 +dbg_mw_cfg_b: + dc.b "[MW] config: read=",0 +dbg_mw_cfg_am: + dc.b " auto=",0 +dbg_mw_cfg_fl: + dc.b " flags=",0 + even + endc + ;--- a Hack: cfd first ------------------------------------- _CfdFirst: @@ -3198,7 +4081,7 @@ _wc_end: ; IS_Code is called with a6=SysBase, a1=IS_Data. ; ; Trust contract: callers are responsible for calling TD_REMCHANGEINT -; before their IS_Code memory is freed. We only reject NULL IO_Data / +; before their IS_Code memory is freed. We only reject NULL IO_Data / ; NULL IS_Code defensively (cheap, catches accidental zero init) and ; otherwise dispatch directly to the registered server. NotifyClients: @@ -3806,7 +4689,7 @@ _ri_fail: ; 2. Wait for DRQ, retry up to 32 times for slow adapters ; 3. If DRQ never sets, fall back to IDENTIFY PACKET DEVICE ; ($A1) as a final attempt to elicit any response from the -; card. See _gid_check_retry for the rationale. +; card. See _gid_check_retry for the rationale. ; 4. Read 512-byte identify data ; 5. Parse device type and set unit parameters ; @@ -5671,215 +6554,6 @@ ap_time: ap_end: rts endc - - -;--- ROM AUTOBOOT STUB ------------------------------------- -; RTF_COLDSTART stub, always present. Only when both -; compactflash.device and ptable.library are ROM-resident -; ignored by ramlib at DOS time. -; -; Remus appends module binaries to the Kickstart image but -; does not add them to the KickTag list, so Exec's InitCode -; pass skips them. Recover by calling FindResident + -; InitResident explicitly for both the device and the -; library before use. -; -; Sequence: -; 1. Find/init compactflash.device if not yet in DeviceList. -; 2. Exit early if CFD_BootDone already set (2nd cold-start pass). -; 3. Find/init ptable.library; if absent (disk-only install) -; exit silently - device still works, autoboot unavailable. -; 4. BootScanRDB("compactflash.device", 0). -; 5. Set CFD_BootDone, CloseLibrary, return. - - cnop 0,2 -s_resident_boot: - dc.w RTC_MATCHWORD - dc.l s_resident_boot - dc.l s_codeend - dc.b $01 ;RTF_COLDSTART (no AUTOINIT) - dc.b FILE_VERSION - dc.b 0 ;NT_UNKNOWN - dc.b PRI_CFD_BOOT ;see ptable_pub.i for priority rationale - dc.l s_boot_name - dc.l s_idstring - dc.l s_bootstub - -s_boot_name: - dc.b "compactflash.boot",0 -RdbLibName: - dc.b "ptable.library",0 - even - - ifd DEBUG -dbg_bs_no_card: - dc.b "[CFD] boot: no PCMCIA card -> skip autoboot",13,10,0 -dbg_bs_open: - dc.b "[CFD] boot: open ptable.library ...",13,10,0 -dbg_bs_preload: - dc.b "[CFD] boot: ptable.library already resident",13,10,0 -dbg_bs_initres: - dc.b "[CFD] boot: ptable.library not preloaded, InitResident()...",13,10,0 -dbg_bs_noires: - dc.b "[CFD] boot: ptable.library not in ROM list - skip autoboot",13,10,0 -dbg_bs_initfail: - dc.b "[CFD] boot: ptable.library InitResident failed",13,10,0 -dbg_bs_scan: - dc.b "[CFD] boot: BootScanRDB(compactflash.device,0)",13,10,0 - even - endc - -;-- Boot-stub-local DEBUG/non-DEBUG branch helpers. -; -; DBG_BNE_MSG msg, target -- DEBUG: tst d0; on NZ print msg and -; unconditionally bra target. -; non-DEBUG: tst d0; bne target. -; (Use on the success / "proceed" leg.) -; DBG_BEQ_MSG msg, target -- dual; prints on Z and jumps. -; (Use on the failure / "give up" leg.) -; -; Both fold the tst.l d0 inside themselves so the 3 OpenLibrary / -; FindResident / re-OpenLibrary call sites stay one line each. - ifd DEBUG -DBG_BNE_MSG macro - tst.l d0 - beq.s .bsdbg_skip\@ - lea \1(pc),a0 - bsr _bootDebug - bra.w \2 -.bsdbg_skip\@: - endm -DBG_BEQ_MSG macro - tst.l d0 - bne.s .bsdbg_skip\@ - lea \1(pc),a0 - bsr _bootDebug - bra.w \2 -.bsdbg_skip\@: - endm - else -DBG_BNE_MSG macro - tst.l d0 - bne.w \2 - endm -DBG_BEQ_MSG macro - tst.l d0 - beq.w \2 - endm - endc - -s_bootstub: - movem.l d2-d7/a2-a6,-(sp) - move.l a6,a5 ;a5 = ExecBase - -;-- Probe DeviceList; InitResident if missing. - move.l a5,a6 - jsr Forbid(a6) - lea SB_DeviceList(a6),a0 - lea s_name(pc),a1 - jsr FindName(a6) - move.l d0,d7 - jsr Permit(a6) - - tst.l d7 - bne.s _bs_devPresent - lea s_resident(pc),a1 - sub.l a0,a0 - jsr InitResident(a6) -;-- re-find after init so we have the live &CFD - jsr Forbid(a6) - lea SB_DeviceList(a6),a0 - lea s_name(pc),a1 - jsr FindName(a6) - move.l d0,d7 - jsr Permit(a6) - tst.l d7 - beq.w _bs_done -;-- Hold the device open (OpenCnt=1) so a whole-machine takeover like -; WHDLoad, which flushes anything unused, leaves it alone. First init only. - move.l d7,a0 - addq.w #1,LIB_OpenCnt(a0) - -_bs_devPresent: -;-- 2nd-pass guard - move.l d7,a0 - tst.b CFD_BootDone(a0) - bne.w _bs_done - -;-- No-card pre-gate. Read live Gayle CCDET ($DA8000 bit 6, set = -; card present); when the slot is empty skip OpenDevice to avoid -; the unit-task hardware footprint (OwnCard, AddIntServer #5, -; timer.device) at cold-start. - btst.b #6,$00DA8000 - bne.s _bs_have_card - ifd DEBUG - lea dbg_bs_no_card(pc),a0 - bsr _bootDebug - endc - bra.w _bs_mark -_bs_have_card: - -;-- OpenLibrary "ptable.library", v1. - ifd DEBUG - lea dbg_bs_open(pc),a0 - bsr _bootDebug - endc - moveq.l #1,d0 - lea RdbLibName(pc),a1 - jsr OpenLibrary(a6) - DBG_BNE_MSG dbg_bs_preload,_bs_libOk - -;-- Remus didn't auto-init ptable.library; find and init it manually. -; If absent (disk-only install) FindResident returns NULL -> exit. - ifd DEBUG - lea dbg_bs_initres(pc),a0 - bsr _bootDebug - endc - lea RdbLibName(pc),a1 - jsr FindResident(a6) - DBG_BEQ_MSG dbg_bs_noires,_bs_mark - move.l d0,a1 ;a1 = &Resident - sub.l a0,a0 ;a0 = NULL (no SegList) - jsr InitResident(a6) - moveq.l #1,d0 - lea RdbLibName(pc),a1 - jsr OpenLibrary(a6) - DBG_BEQ_MSG dbg_bs_initfail,_bs_mark - -_bs_libOk: - move.l d0,a3 ;a3 = ptable.library base - -;-- Keep ptable.library in use so a memory-flush takeover (WHDLoad) won't -; expunge it once we close it below. - addq.w #1,LIB_OpenCnt(a3) - - ifd DEBUG - lea dbg_bs_scan(pc),a0 - bsr _bootDebug - endc - moveq.l #0,d0 ;unit 0 - lea s_name(pc),a1 ;deviceName = "compactflash.device" - move.l a3,a6 - jsr _LVOBootScanRDB(a6) - move.l a3,a1 - move.l a5,a6 - jsr CloseLibrary(a6) - -;-- Set the one-shot guard. d7 still holds &CFD from the -; _bs_devPresent / post-InitResident find above; every path that -; reaches here (including the DBG_BEQ_MSG -> _bs_mark jumps) has -; already validated d7, so no second Forbid+FindName is needed. -_bs_mark: - move.l d7,a0 - move.b #1,CFD_BootDone(a0) - -_bs_done: - moveq.l #0,d0 - movem.l (sp)+,d2-d7/a2-a6 - rts - - include "lib/raw_debug.i" - cnop 0,4 s_codeend: diff --git a/src/cfd_automount.s b/src/cfd_automount.s new file mode 100644 index 0000000..f8e0ddb --- /dev/null +++ b/src/cfd_automount.s @@ -0,0 +1,387 @@ +; compactflash.automount - boot / automount bringup for compactflash.device. +; +; Optional companion to compactflash.device. Load it only when you want +; autoboot (ROM) or automount. It carries two romtags: +; +; * compactflash.automount (RTF_AFTERDOS, FIRST): after DOS is functional, +; open compactflash.device unit 0 and hold it open, which starts the unit +; task, the card-detect interrupt and the automount agent. Listed first +; because LoadModule activates only a file's first romtag, so this one +; brings it up for a disk install. +; +; * compactflash.autoboot (RTF_COLDSTART, SECOND): at cold boot, scan the +; card's RDB and register its partitions (autoboot). Found by the linear +; ROM scan, so it runs from a flashed Kickstart; LoadModule ignores it +; (autoboot is pre-DOS, ROM only). +; +; The device itself contains no boot code; omit this module and you get a plain +; mount-only device. It reaches the device by name (FindName, OpenDevice) +; and with ptable.library by LVO; the only private coupling is the handful of +; CFD/CFU offsets in cfd_pub.i. + + include "cfd_pub.i" ;CFD_BootDone/DosReady/Unit, CFU_Mount* + include "ptable_pub.i" ;_LVOBootScanPartitions, PRI_CFD_BOOT + include "cfd_automount_version.i" ;FILE_VERSION, VERSION_STRING (Makefile-generated) + +_AbsExecBase = 4 + +; Exec LVOs +FindResident = -96 +InitResident = -102 +Forbid = -132 +Permit = -138 +AllocMem = -198 +FreeMem = -210 +FindName = -276 +Signal = -324 +CloseLibrary = -414 +OpenDevice = -444 +OpenLibrary = -552 +RawPutChar = -516 ;used by lib/raw_debug.i (DEBUG boot serial) + +; Exec base / structure offsets +SB_DeviceList = 350 +LIB_OpenCnt = 32 +LN_Type = 8 +MP_Flags = 14 +MP_MsgList = 20 +MP_Sizeof = 34 +MN_ReplyPort = 14 +MN_Length = 18 +IO_Sizeof = 56 + +NT_MSGPORT = 4 +NT_MESSAGE = 5 +NT_UNKNOWN = 0 +PA_IGNORE = 2 +MEMF_PUBLIC = 1 +MEMF_CLEAR = $10000 + +; Resident (romtag) +RTC_MATCHWORD = $4afc +RTF_COLDSTART = $01 +RTF_AFTERDOS = $04 +LF = 10 + +INITLIST macro + move.l \1,(\1) + addq.l #4,(\1) + clr.l 4(\1) + move.l \1,8(\1) + endm + +;-- Boot-stub-local DEBUG/non-DEBUG branch helpers (fold the tst.l d0 inside, so +; the OpenLibrary / FindResident call sites stay one line each). + ifd DEBUG +DBG_BNE_MSG macro + tst.l d0 + beq.s .bsdbg_skip\@ + lea \1(pc),a0 + bsr _bootDebug + bra.w \2 +.bsdbg_skip\@: + endm +DBG_BEQ_MSG macro + tst.l d0 + bne.s .bsdbg_skip\@ + lea \1(pc),a0 + bsr _bootDebug + bra.w \2 +.bsdbg_skip\@: + endm + else +DBG_BNE_MSG macro + tst.l d0 + bne.w \2 + endm +DBG_BEQ_MSG macro + tst.l d0 + beq.w \2 + endm + endc + + moveq.l #0,d0 ;defuse an accidental Shell invocation + rts + + cnop 0,2 +; AFTERDOS romtag (first), so LoadModule activates it. +s_automount_rt: + dc.w RTC_MATCHWORD + dc.l s_automount_rt + dc.l s_autoboot_rt ;EndSkip: continue ROM scan into the COLDSTART romtag + dc.b RTF_AFTERDOS + dc.b FILE_VERSION + dc.b NT_UNKNOWN + dc.b -100 ;AFTERDOS modules start at -100 (exec.doc) + dc.l automount_name + dc.l idstring + dc.l s_automount + +; COLDSTART romtag (second), reached by the ROM scan via EndSkip. +s_autoboot_rt: + dc.w RTC_MATCHWORD + dc.l s_autoboot_rt + dc.l endtag + dc.b RTF_COLDSTART + dc.b FILE_VERSION + dc.b NT_UNKNOWN + dc.b PRI_CFD_BOOT ;see ptable_pub.i for priority rationale + dc.l autoboot_name + dc.l idstring + dc.l s_autobootstub + +automount_name: + dc.b "compactflash.automount",0 +autoboot_name: + dc.b "compactflash.autoboot",0 +devname: + dc.b "compactflash.device",0 +RdbLibName: + dc.b "ptable.library",0 + dc.b "$VER: " ;tag for Version; rt_IdString points after it +idstring: + VERSION_STRING + dc.b LF,0 + even + + ifd DEBUG +dbg_bs_no_card: + dc.b "[CFD] boot: no PCMCIA card -> skip autoboot",13,10,0 +dbg_bs_open: + dc.b "[CFD] boot: open ptable.library ...",13,10,0 +dbg_bs_preload: + dc.b "[CFD] boot: ptable.library already resident",13,10,0 +dbg_bs_initres: + dc.b "[CFD] boot: ptable.library not preloaded, InitResident()...",13,10,0 +dbg_bs_noires: + dc.b "[CFD] boot: ptable.library not in ROM list - skip autoboot",13,10,0 +dbg_bs_initfail: + dc.b "[CFD] boot: ptable.library InitResident failed",13,10,0 +dbg_bs_scan: + dc.b "[CFD] boot: BootScanPartitions(compactflash.device,0)",13,10,0 + even + endc + +;=========================================================== +; _amFindInitDev: find compactflash.device in DeviceList, running its +; romtag init (found by resident name) first when a builder did not +; auto-init it. Shared by both romtag stubs. +; In : a6 = SysBase +; Out: d0 = &CFD (0 = device unavailable); +; d1 = 1 if this call InitResident'ed the device (first init) +; Clobbers d0/d1/a0/a1. +;=========================================================== +_amFindInitDev: + move.l d2,-(sp) + moveq.l #0,d2 ;d2 = did-init flag + bsr.s _afd_find + tst.l d0 + bne.s _afd_out + lea devname(pc),a1 + jsr FindResident(a6) + tst.l d0 + beq.s _afd_out ;no resident either -> d0 = 0 + move.l d0,a1 + sub.l a0,a0 + jsr InitResident(a6) + moveq.l #1,d2 + bsr.s _afd_find ;re-find after init -> live &CFD +_afd_out: + move.l d2,d1 + move.l (sp)+,d2 + rts +_afd_find: + jsr Forbid(a6) + lea SB_DeviceList(a6),a0 + lea devname(pc),a1 + jsr FindName(a6) + move.l d0,-(sp) ;FindName result across Permit + jsr Permit(a6) + move.l (sp)+,d0 + rts + +;=========================================================== +; RTF_AFTERDOS hook ("compactflash.automount") +; +; System-Startup initialises RTF_AFTERDOS modules after the boot volume and all +; remaining filesystems are started, before Startup-Sequence (NDK +; system-startup.doc), the OS-defined "DOS is fully functional" moment. Here: +; 1. ensure the device + unit task + card-detect interrupts + MountAgent exist +; (OpenDevice unit 0, held open for good), so a card inserted after a +; cardless boot mounts; +; 2. set CFD_DosReady; the MountAgent defers every event until then (it must +; not touch dos.library while System-Startup is still building it); +; 3. signal the agent so a deferred cold-boot insert is processed. +; a6 = SysBase. +;=========================================================== +s_automount: + movem.l d2/a2-a3/a6,-(sp) + +;-- find the device; InitResident it (by name) when it is not in DeviceList yet + bsr _amFindInitDev + tst.l d0 + beq.w _dr_out + move.l d0,a3 ;a3 = &CFD + tst.b CFD_DosReady(a3) ;idempotence guard + bne.w _dr_out + +;-- open unit 0 permanently. MsgPort + IOStdReq live in a one-shot public +; allocation (never freed): the device stays open, the port receives no +; messages and the request is never reused. + moveq.l #MP_Sizeof+IO_Sizeof,d0 + move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 + jsr AllocMem(a6) + tst.l d0 + beq.w _dr_out + move.l d0,a2 ;a2 = MsgPort; +MP_Sizeof = IOStdReq + move.b #NT_MSGPORT,LN_Type(a2) + move.b #PA_IGNORE,MP_Flags(a2) + lea MP_MsgList(a2),a0 + INITLIST a0 + lea MP_Sizeof(a2),a1 ;a1 = IOStdReq + move.b #NT_MESSAGE,LN_Type(a1) + move.w #IO_Sizeof,MN_Length(a1) + move.l a2,MN_ReplyPort(a1) + lea devname(pc),a0 + moveq.l #0,d0 ;unit 0 + moveq.l #0,d1 ;flags 0 (serial debug is opt-in via config FLAGS) + jsr OpenDevice(a6) + tst.l d0 + bne.s _dr_openfail + +;-- DOS is ready: unblock the agent and reprocess deferred events + move.b #1,CFD_DosReady(a3) + move.l CFD_Unit(a3),d0 + beq.s _dr_out + move.l d0,a0 + move.l CFU_MountSig(a0),d0 + beq.s _dr_out + move.l CFU_MountAgent(a0),d1 + beq.s _dr_out + move.l d1,a1 + jsr Signal(a6) + bra.s _dr_out + +_dr_openfail: + move.l a2,a1 + moveq.l #MP_Sizeof+IO_Sizeof,d0 + jsr FreeMem(a6) +_dr_out: + movem.l (sp)+,d2/a2-a3/a6 + moveq.l #0,d0 + rts + +;=========================================================== +; RTF_COLDSTART stub ("compactflash.autoboot") +; +; Runs at cold boot. Ensures the device and ptable.library are initialised +; (find by name; InitResident if a builder did not auto-init them), then scans +; the card's RDB and registers its partitions for autoboot. +; +; Sequence: +; 1. Find/init compactflash.device if not yet in DeviceList. +; 2. Exit early if CFD_BootDone already set (2nd cold-start pass). +; 3. Find/init ptable.library; if absent (disk-only install) exit silently +; (the device still works, only autoboot is unavailable). +; 4. BootScanPartitions("compactflash.device", 0). +; 5. Set CFD_BootDone, CloseLibrary, return. +; a6 = SysBase. +;=========================================================== +s_autobootstub: + movem.l d2-d7/a2-a6,-(sp) + move.l a6,a5 ;a5 = ExecBase + +;-- Probe DeviceList; InitResident (by name) if missing. + move.l a5,a6 + bsr _amFindInitDev + move.l d0,d7 + beq.w _bs_done + tst.l d1 + beq.s _bs_devPresent ;was already present -> no OpenCnt bump +;-- Hold the device open (OpenCnt=1) so a whole-machine takeover like +; WHDLoad, which flushes anything unused, leaves it alone. First init only. + move.l d7,a0 + addq.w #1,LIB_OpenCnt(a0) + +_bs_devPresent: +;-- 2nd-pass guard + move.l d7,a0 + tst.b CFD_BootDone(a0) + bne.w _bs_done + +;-- No-card pre-gate. Read live Gayle CCDET ($DA8000 bit 6, set = +; card present); when the slot is empty skip OpenDevice to avoid +; the unit-task hardware footprint (OwnCard, AddIntServer #5, +; timer.device) at cold-start. + btst.b #6,$00DA8000 + bne.s _bs_have_card + ifd DEBUG + lea dbg_bs_no_card(pc),a0 + bsr _bootDebug + endc + bra.w _bs_mark +_bs_have_card: + +;-- OpenLibrary "ptable.library", v2 (unified pipeline: BootScanPartitions). + ifd DEBUG + lea dbg_bs_open(pc),a0 + bsr _bootDebug + endc + moveq.l #2,d0 + lea RdbLibName(pc),a1 + jsr OpenLibrary(a6) + DBG_BNE_MSG dbg_bs_preload,_bs_libOk + +;-- ptable.library not yet initialised; find and init it manually. +; If absent (disk-only install) FindResident returns NULL, so exit. + ifd DEBUG + lea dbg_bs_initres(pc),a0 + bsr _bootDebug + endc + lea RdbLibName(pc),a1 + jsr FindResident(a6) + DBG_BEQ_MSG dbg_bs_noires,_bs_mark + move.l d0,a1 ;a1 = &Resident + sub.l a0,a0 ;a0 = NULL (no SegList) + jsr InitResident(a6) + moveq.l #2,d0 + lea RdbLibName(pc),a1 + jsr OpenLibrary(a6) + DBG_BEQ_MSG dbg_bs_initfail,_bs_mark + +_bs_libOk: + move.l d0,a3 ;a3 = ptable.library base + +;-- Keep ptable.library in use so a memory-flush takeover (WHDLoad) won't +; expunge it once we close it below. + addq.w #1,LIB_OpenCnt(a3) + + ifd DEBUG + lea dbg_bs_scan(pc),a0 + bsr _bootDebug + endc + moveq.l #0,d0 ;unit 0 + lea devname(pc),a1 ;deviceName = "compactflash.device" + move.l a3,a6 + jsr _LVOBootScanPartitions(a6) + move.l a3,a1 + move.l a5,a6 + jsr CloseLibrary(a6) + +;-- Set the one-shot guard. d7 still holds &CFD from the _bs_devPresent / +; post-InitResident find above; every path that reaches here has already +; validated d7, so no second Forbid+FindName is needed. +_bs_mark: + move.l d7,a0 + move.b #1,CFD_BootDone(a0) + +_bs_done: + moveq.l #0,d0 + movem.l (sp)+,d2-d7/a2-a6 + rts + + include "lib/raw_debug.i" + + cnop 0,4 +endtag: + end diff --git a/src/cfd_automount_version.i b/src/cfd_automount_version.i new file mode 100644 index 0000000..c42e103 --- /dev/null +++ b/src/cfd_automount_version.i @@ -0,0 +1,6 @@ +; Auto-generated by Makefile +FILE_VERSION = 2 +FILE_REVISION = 0 +VERSION_STRING macro + dc.b "compactflash.automount 2.0-dev (10.07.2026)" + endm diff --git a/src/cfd_debug.i b/src/cfd_debug.i index 8caa1a6..b8af26f 100644 --- a/src/cfd_debug.i +++ b/src/cfd_debug.i @@ -25,6 +25,10 @@ DBGNUM macro bsr _DebugHex endm +DBGDEC macro + bsr _DebugDecimal32 ;d0.l as unsigned decimal + endm + DBGNL macro bsr _DebugNewline endm @@ -76,6 +80,9 @@ DBGCHR macro DBGNUM macro endm +DBGDEC macro + endm + DBGNL macro endm diff --git a/src/cfd_pub.i b/src/cfd_pub.i new file mode 100644 index 0000000..c1a472b --- /dev/null +++ b/src/cfd_pub.i @@ -0,0 +1,16 @@ +;=========================================================== +; cfd_pub.i - device offsets shared between compactflash.device and the +; compactflash.automount bringup module. Single source of truth for the few CFD / +; CFU fields the boot/after-DOS code touches by name; the two binaries are built +; and versioned together. (cfd.s documents the full CFD/CFU layout; these live +; here so the automount module need not duplicate them.) +;=========================================================== + +; CompactFlashDevice (CFD) +CFD_Unit = 52 ;pointer to the (single) CFU +CFD_BootDone = 56 ;byte: RTF_COLDSTART one-shot guard +CFD_DosReady = 57 ;byte: set when DOS is functional (after-DOS) + +; CompactFlashUnit (CFU) +CFU_MountAgent = 980 ;MountAgent Task ptr (0 = none) +CFU_MountSig = 984 ;MountAgent wake signal mask (0 = not ready) diff --git a/src/cfd_version.i b/src/cfd_version.i index 3900a7a..ce2372f 100644 --- a/src/cfd_version.i +++ b/src/cfd_version.i @@ -1,10 +1,10 @@ ; Auto-generated by Makefile -FILE_VERSION = 1 -FILE_REVISION = 44 +FILE_VERSION = 2 +FILE_REVISION = 0 VERSION_STRING macro ifd __68020__ - dc.b "compactflash.device 1.44 (04.06.2026) [68020]" + dc.b "compactflash.device 2.0-dev (10.07.2026) [68020]" else - dc.b "compactflash.device 1.44 (04.06.2026) [68000]" + dc.b "compactflash.device 2.0-dev (10.07.2026) [68000]" endc endm diff --git a/src/lib/ptable_boot.s b/src/lib/ptable_boot.s deleted file mode 100644 index d344c5d..0000000 --- a/src/lib/ptable_boot.s +++ /dev/null @@ -1,1202 +0,0 @@ -;=========================================================== -; ptable_boot.s -- BootScanRDB body and helpers -; -; Device-agnostic: takes a device name and unit from the -; caller, opens that device, walks the RDB, and registers -; partitions via expansion.library. -; -; Register conventions inside this block: -; a4 = &BootCtx (allocated on entry, freed on exit) -; a5 = ExecBase (cached from RDBL_ExecBase(LibBase)) -; a6 is repeatedly loaded with ExecBase / ExpansionBase / -; DosBase / FileSystem.resource base before each jsr. -;=========================================================== - -;--- from expansion.library -------------------------------- -AddBootNode = -36 -AddConfigDev = -30 -AddDosNode = -150 - -;--- ConfigDev layout (libraries/configvars.i) ------------- -; Only the fields actually written by the synthetic ConfigDev -; below are defined here; full layout lives in NDK. -CD_NODE_TYPE = 8 -CD_NODE_NAME = 10 -CD_ER_TYPE = 16 -CD_ER_PRODUCT = 17 -CD_ER_MANUF = 20 -CD_ER_SERIAL = 22 -CD_ER_RESERVED0C = 28 -CD_BOARDADDR = 32 -CD_BOARDSIZE = 36 -CD_SIZEOF = 68 - -NT_CONFIGDEV = 20 -ERTF_DIAGVALID = $10 - -;--- from dos.library -------------------------------------- -DOS_Delay = -198 - -;--- Rigid Disk Block / Partition / FSHD / LSEG ------------ -; Only the fields actually read by the walkers below are -; defined; *_ID / *_ChkSum / *_SummedLongs are referred to by -; the RDSK/PART/FSHD/LSEG signature longs (RDSK_ID, ...). -RDB_LOCATION_LIMIT = 16 -RDB_BLOCK_BYTES = 512 - -rdb_SummedLongs = 4 -rdb_PartitionList = 28 -rdb_FileSysHeaderList = 32 - -RDSK_ID = $5244534B ;'RDSK' - -pb_Next = 16 -pb_Flags = 20 -pb_DriveName = 36 -pb_Environment = 128 - -PART_ID = $50415254 ;'PART' - -;-- pb_Flags bit numbers (used with btst) -PBFFB_BOOTABLE = 0 -PBFFB_NOMOUNT = 1 - -fhb_Next = 16 -fhb_DosType = 32 -fhb_Version = 36 -fhb_PatchFlags = 40 -fhb_Type = 44 -fhb_Task = 48 -fhb_Lock = 52 -fhb_Handler = 56 -fhb_StackSize = 60 -fhb_Priority = 64 -fhb_Startup = 68 -fhb_SegListBlocks = 72 -fhb_GlobalVec = 76 - -FSHD_ID = $46534844 ;'FSHD' - -lsb_Next = 16 -lsb_LoadData = 20 - -LSEG_ID = $4C534547 ;'LSEG' - -DE_BOOTPRI = 15 -DE_DOSTYPE = 16 -DE_BOOTBLOCKS = 19 - -fsr_Creator = 14 -fsr_FileSysEntries = 18 -fsr_Sizeof = 32 - -fse_DosType = 14 -fse_Version = 18 -fse_PatchFlags = 22 -fse_Type = 26 -fse_Task = 30 -fse_Lock = 34 -fse_Handler = 38 -fse_StackSize = 42 -fse_Priority = 46 -fse_Startup = 50 -fse_SegList = 54 -fse_GlobalVec = 58 -fse_Sizeof = 62 - -;--- AmigaDOS hunk format (used by rdb_hunk.s) ------------- -HUNK_UNIT = $000003E7 -HUNK_NAME = $000003E8 -HUNK_CODE = $000003E9 -HUNK_DATA = $000003EA -HUNK_BSS = $000003EB -HUNK_RELOC32 = $000003EC -HUNK_SYMBOL = $000003F0 -HUNK_DEBUG = $000003F1 -HUNK_END = $000003F2 -HUNK_HEADER = $000003F3 -HUNK_OVERLAY = $000003F5 -HUNK_BREAK = $000003F6 -HUNK_RELOC32SHORT = $000003FC - -;--- DeviceNode field offsets (for _bootPatchDNfromFSE) --- -dn_Type = 4 -dn_Task = 8 -dn_Lock = 12 -dn_Handler = 16 -dn_StackSize = 20 -dn_Priority = 24 -dn_Startup = 28 -dn_SegList = 32 -dn_GlobVec = 36 -dn_Name = 40 - -;=========================================================== -; BootCtx layout (one AllocMem on BootScanRDB entry): -; -; offset size field -; ------ ---- -------------------------------------------- -; 0 4 BC_ExecBase cached ExecBase -; 4 4 BC_ExpBase expansion.library base -; 8 4 BC_DosBase dos.library base (may be 0) -; 12 4 BC_Unit unit number passed by caller -; 16 4 BC_BlockBuf -> trailing 512B buffer -; 20 4 BC_FSResource FileSystem.resource (lazy) -; 24 1 BC_DevOpen 1 if OpenDevice succeeded -; 25 1 BC_SigOK 1 if reply-port signal alloc'd -; 26 1 BC_HaveNodes 1 if any AddBootNode/AddDosNode ran -; 27 1 BC_PartCount count of partitions registered -; 28 34 BC_DevMsgPort -; 62 56 BC_DevIOReq -; 118 2 (pad to long) -; 120 4 BC_ConfigDev synthetic ConfigDev (0 = none) -; 124 4 BC_DevName caller's device name string -; 128 4 BC_DevNameBSTR cached BSTR(BPTR) of BC_DevName -; for fssm_Device (0 = alloc failed, -; _bootAddOnePartition then skips) -; 132 512 block buffer (BC_BlockBuf points here) - -BC_ExecBase = 0 -BC_ExpBase = 4 -BC_DosBase = 8 -BC_Unit = 12 -BC_BlockBuf = 16 -BC_FSResource = 20 -BC_DevOpen = 24 -BC_SigOK = 25 -BC_HaveNodes = 26 -BC_PartCount = 27 -BC_DevMsgPort = 28 -BC_DevIOReq = 62 -BC_Pad2 = 118 -BC_ConfigDev = 120 -BC_DevName = 124 -BC_DevNameBSTR = 128 -BC_Sizeof = 132 - -BC_BUF_BYTES = 512 - -;--- DeviceNode blob layout (built by _bootAddOnePartition) --- -DN_FSSM_OFF = 44 -DN_ENVEC_OFF = 60 -DN_BSTR_OFF = 144 -DN_BLOB_SIZE = 176 - -;=========================================================== -; Constants: ROM strings used during scan -;=========================================================== -ExpansionName: - dc.b "expansion.library",0 -DosName: - dc.b "dos.library",0 -FileSysResName: - dc.b "FileSystem.resource",0 - even -;-- "ptable.library" is shared with the LN_Name string in -; ptable_lib.s; reuse s_libname(pc) for fsr_Creator and the -; FileSysEntry LN_Name (see ptable_fs.s). - -;--- Debug strings (only emitted in DEBUG builds) ---------- - ifd DEBUG -dbg_boot_start: - dc.b "[RDB] scan",CR,LF,0 -dbg_boot_no_card: - dc.b "[RDB] no card",CR,LF,0 -dbg_boot_no_rdb: - dc.b "[RDB] no RDB",CR,LF,0 -dbg_boot_fs_add: - dc.b "[RDB] +fs ",0 -dbg_boot_part_boot: - dc.b "[RDB] +boot ",0 -dbg_boot_part_dos: - dc.b "[RDB] +dos ",0 -dbg_boot_part_skip: - dc.b "[RDB] skip ",0 -dbg_boot_done: - dc.b "[RDB] done",CR,LF,0 -dbg_boot_exp_fail: - dc.b "[RDB] err: no exp.lib",CR,LF,0 -dbg_boot_no_mem: - dc.b "[RDB] err: no mem",CR,LF,0 -dbg_boot_opendev_err: - dc.b "[RDB] err: OpenDevice $",0 -dbg_boot_rdsk_found: - dc.b "[RDB] found RDSK",CR,LF,0 -dbg_boot_nl: - dc.b CR,LF,0 -dbg_hunk_badid: - dc.b "[RDB] hunk: bad id $",0 - endc - even - -;=========================================================== -; BootScanRDB -; -; Inputs: -; a1 = device name (NUL-terminated C-string) -; d0 = unit number -; a6 = LibBase -; -; Output: -; d0 = number of partitions registered (0 = no card / no RDB -; / allocation failure / etc.) -; -; Preserves d2-d7/a2-a5/a6 -;=========================================================== -BootScanRDB: - movem.l d2-d7/a2-a6,-(sp) - move.l a1,d6 ;d6 = device name - move.l d0,d5 ;d5 = unit - move.l RDBL_ExecBase(a6),a5 ;a5 = ExecBase - -;-- allocate BootCtx + 512B buffer in one shot - move.l #BC_Sizeof+BC_BUF_BYTES,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 - move.l a5,a6 - jsr AllocMem(a6) - tst.l d0 - bne.s bs_haveCtx - ifd DEBUG - lea dbg_boot_no_mem(pc),a0 - bsr _bootDebug - endc - moveq.l #0,d6 ;result count = 0 - bra.w bs_no_alloc -bs_haveCtx: - move.l d0,a4 ;a4 = &BootCtx - move.l a5,BC_ExecBase(a4) - move.l d6,BC_DevName(a4) ;d6 still holds devname - move.l d5,BC_Unit(a4) - lea BC_Sizeof(a4),a0 - move.l a0,BC_BlockBuf(a4) - move.b #-1,BC_SigOK(a4) ;sentinel: no signal allocated yet - -;-- Cache the device-name BSTR once per scan; reused for every -; partition's fssm_Device. On failure the slot stays 0 -; (BootCtx is MEMF_CLEAR) and _bootAddOnePartition skips. - move.l BC_DevName(a4),a0 - move.l a5,a6 - bsr _bootMakeExecBSTR - move.l d0,BC_DevNameBSTR(a4) - -;-- open expansion.library - moveq.l #0,d0 - lea ExpansionName(pc),a1 - move.l a5,a6 - jsr OpenLibrary(a6) - move.l d0,BC_ExpBase(a4) - bne.s bs_haveExp - ifd DEBUG - lea dbg_boot_exp_fail(pc),a0 - bsr _bootDebug - endc - bra.w bs_cleanup -bs_haveExp: - -;-- Synthesize a ConfigDev for the device. -; (The ConfigDev's CD_NODE_NAME points at the caller's device -; name string so strap renders the early-startup menu against -; the correct device. ER_TYPE = ERTF_DIAGVALID together with -; er_Reserved0c -> s_rdb_diag_rom drives the BootPoint flow: -; strap copies the DiagArea to RAM and calls da_BootPoint, -; which then runs FindResident("dos.library") + RT_INIT.) - move.l a5,a6 ;ExecBase - move.l #CD_SIZEOF,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 - jsr AllocMem(a6) - tst.l d0 - beq.w bs_no_cd - move.l d0,BC_ConfigDev(a4) - move.l d0,a2 - move.b #NT_CONFIGDEV,CD_NODE_TYPE(a2) - move.l BC_DevName(a4),CD_NODE_NAME(a2) - move.b #$C0|ERTF_DIAGVALID|4,CD_ER_TYPE(a2) ;Z-II, diag, 512KB - lea s_rdb_diag_rom(pc),a0 - move.l a0,CD_ER_RESERVED0C(a2) - move.b #1,CD_ER_PRODUCT(a2) - move.w #$FFFF,CD_ER_MANUF(a2) ;no vendor - move.l #$52444230,CD_ER_SERIAL(a2) ;'RDB0' - move.l #$00A00000,CD_BOARDADDR(a2) ;PCMCIA attributes base - move.l #$00080000,CD_BOARDSIZE(a2) ;512 KB -bs_no_cd: - -;-- open dos.library; used for Delay() only. OK to be NULL. - move.l a5,a6 - moveq.l #0,d0 - lea DosName(pc),a1 - jsr OpenLibrary(a6) - move.l d0,BC_DosBase(a4) - - ifd DEBUG - lea dbg_boot_start(pc),a0 - bsr _bootDebug - endc - -;-- open the requested unit, run the scan, close the unit. - bsr _bootOpenUnit - tst.l d0 - beq.s bs_close_unit - bsr _bootScanRdb -bs_close_unit: - bsr _bootCloseUnit ;idempotent: handles partial open - -;-- Register synthetic ConfigDev with strap (eb_CDevList) so the -; early-startup boot menu shows the device and the BootPoint -; fires when the user picks a bootable partition. Guarded: -; only call when at least one partition was registered. - tst.b BC_HaveNodes(a4) - beq.s bs_close - move.l BC_ConfigDev(a4),d0 - beq.s bs_close - move.l BC_ExpBase(a4),d0 - beq.s bs_close - move.l d0,a6 - move.l BC_ConfigDev(a4),a0 - jsr AddConfigDev(a6) - -bs_close: - move.l BC_ExecBase(a4),a6 - move.l BC_DosBase(a4),d0 - beq.s bs_close1 - move.l d0,a1 - jsr CloseLibrary(a6) -bs_close1: - move.l BC_ExpBase(a4),d0 - beq.s bs_cleanup - move.l d0,a1 - jsr CloseLibrary(a6) - -bs_cleanup: - ifd DEBUG - lea dbg_boot_done(pc),a0 - bsr _bootDebug - endc - moveq.l #0,d6 - move.b BC_PartCount(a4),d6 ;return value = partitions registered - move.l a4,a1 - move.l #BC_Sizeof+BC_BUF_BYTES,d0 - move.l BC_ExecBase(a4),a6 - jsr FreeMem(a6) - -bs_no_alloc: - move.l d6,d0 - movem.l (sp)+,d2-d7/a2-a6 - rts - -;=========================================================== -; _bootOpenUnit: OpenDevice + spin on TD_CHANGESTATE. -; -; Input: a4 = &BootCtx, a5 = ExecBase, BC_Unit / BC_DevName set -; Output: d0 = 1 on success (media present), 0 on failure -;=========================================================== -_bootOpenUnit: - move.l a5,a6 - -;-- MsgPort - sub.l a1,a1 - jsr FindTask(a6) - lea BC_DevMsgPort(a4),a2 - move.l d0,MP_SigTask(a2) - - moveq.l #-1,d0 - jsr AllocSignal(a6) - cmp.b #-1,d0 - bne.s _bou_sig_ok - bra.w _bou_fail -_bou_sig_ok: - move.b d0,MP_SigBit(a2) - move.b d0,BC_SigOK(a4) - move.b #NT_MSGPORT,LN_Type(a2) - clr.b MP_Flags(a2) ;PA_SIGNAL = 0 - lea MP_MsgList(a2),a0 - move.l a0,(a0) ;INITLIST inline - addq.l #4,(a0) - clr.l 4(a0) - move.l a0,8(a0) - -;-- IOStdReq - lea BC_DevIOReq(a4),a1 - move.b #NT_MESSAGE,LN_Type(a1) - move.w #IO_Sizeof,MN_Length(a1) - move.l a2,MN_ReplyPort(a1) - -;-- OpenDevice (caller-supplied name + unit) - move.l BC_DevName(a4),a0 - move.l BC_Unit(a4),d0 - ;moveq.l #9,d1 ;Flags=1|8: SocketOn + serial debug - moveq.l #0,d1 - jsr OpenDevice(a6) - tst.l d0 - beq.s _bou_od_ok - ifd DEBUG - move.l d0,-(sp) - lea dbg_boot_opendev_err(pc),a0 - bsr _bootDebug - move.l (sp)+,d0 - bsr _bootDebugHex8 - lea dbg_boot_nl(pc),a0 - bsr _bootDebug - endc - bra.w _bou_fail -_bou_od_ok: - move.b #1,BC_DevOpen(a4) - -;-- poll TD_CHANGESTATE up to 5s for slow card spin-up - moveq.l #50,d7 -_bou_poll: - lea BC_DevIOReq(a4),a1 - move.w #TD_CHANGESTATE,IO_Command(a1) - clr.l IO_Actual(a1) - clr.b IO_Error(a1) - jsr DoIO(a6) - tst.b BC_DevIOReq+IO_Error(a4) - bne.s _bou_delay - move.l BC_DevIOReq+IO_Actual(a4),d0 - beq.s _bou_ok ;IO_Actual=0 -> media present -_bou_delay: - bsr _bootDelay100ms - subq.w #1,d7 - bne.s _bou_poll - ifd DEBUG - lea dbg_boot_no_card(pc),a0 - bsr _bootDebug - endc - moveq.l #0,d0 - rts -_bou_ok: - moveq.l #1,d0 - rts -_bou_fail: - moveq.l #0,d0 - rts - -;=========================================================== -; _bootCloseUnit: CloseDevice + FreeSignal (idempotent) -;=========================================================== -_bootCloseUnit: - move.l BC_ExecBase(a4),a6 - tst.b BC_DevOpen(a4) - beq.s _bcu_sig - lea BC_DevIOReq(a4),a1 - jsr CloseDevice(a6) - clr.b BC_DevOpen(a4) -_bcu_sig: - move.b BC_SigOK(a4),d0 - cmp.b #-1,d0 - beq.s _bcu_end - ext.w d0 - ext.l d0 - jsr FreeSignal(a6) - move.b #-1,BC_SigOK(a4) -_bcu_end: - rts - -;=========================================================== -; _bootDelay100ms: sleep ~100 ms. Uses dos.library/Delay(5) -; if DosBase is open, otherwise a rough busy-wait (~350k -; simple insns is ~100ms on a 7 MHz 68000). -;=========================================================== -_bootDelay100ms: - move.l a6,-(sp) - move.l BC_DosBase(a4),d0 - beq.s _bd_busy - move.l d0,a6 - moveq.l #5,d1 ;50 Hz * 0.1s = 5 ticks - jsr DOS_Delay(a6) - move.l (sp)+,a6 - rts -_bd_busy: - move.l #150000,d0 -_bd_bl: subq.l #1,d0 - bne.s _bd_bl - move.l (sp)+,a6 - rts - -;=========================================================== -; _bootReadBlock: read one 512B block by 32-bit block#. -; -; Input: d0 = block# (0..16M), a4 = &BootCtx -; Output: d0 = 0 on success, nonzero (IO_Error) otherwise -; -; Wraps _bootReadBytes64 so reads survive partition starts -; that wrap past 4 GiB in 32-bit IO_Offset. -;=========================================================== -_bootReadBlock: - movem.l d1-d2/a1,-(sp) - moveq.l #0,d1 ;high32 = 0 (block# always small) - add.l d0,d0 ;*2 via add.l (faster than lsl.l #1) - lsl.l #8,d0 ;d0 = block * 512 (low32) - exg d0,d1 ;d0=high32=0, d1=low32 - move.l #RDB_BLOCK_BYTES,d2 - move.l BC_BlockBuf(a4),a1 - bsr _bootReadBytes64 - movem.l (sp)+,d1-d2/a1 - rts - -;=========================================================== -; _bootReadBytes64: NSCMD_TD_READ64 wrapper. -; (NSCMD reads bypass any CMD_READ partition-base intercept on the -; device, since we hand both halves of the 64-bit offset -; explicitly here.) -; -; Input : d0.l = high32, d1.l = low32, d2.l = bytes, -; a1 = destination, a4 = &BootCtx -; Output: d0 = 0 on success, nonzero IO_Error otherwise -;=========================================================== -_bootReadBytes64: - movem.l d1-d2/a0/a1/a6,-(sp) - move.l BC_ExecBase(a4),a6 - lea BC_DevIOReq(a4),a0 - move.w #NSCMD_TD_READ64,IO_Command(a0) - clr.b IO_Error(a0) - move.l d0,IO_Actual(a0) ;high 32 bits - move.l d1,IO_Offset(a0) ;low 32 bits - move.l d2,IO_Length(a0) - move.l a1,IO_Data(a0) - move.l a0,a1 - jsr DoIO(a6) - moveq.l #0,d0 - move.b BC_DevIOReq+IO_Error(a4),d0 - movem.l (sp)+,d1-d2/a0/a1/a6 - rts - -;=========================================================== -; _bootChecksum: sum of first d1 longs of buffer (a0). -; Returns d0 = 0 if checksum valid, nonzero otherwise. -;=========================================================== -_bootChecksum: - movem.l d2/a2,-(sp) - move.l a0,a2 - moveq.l #0,d0 - move.l d1,d2 - subq.l #1,d2 - bmi.s _bcs_end -_bcs_loop: - add.l (a2)+,d0 - dbra d2,_bcs_loop -_bcs_end: - movem.l (sp)+,d2/a2 - tst.l d0 - rts - -;=========================================================== -; _bootScanRdb: find RDSK, run FS-load + partition-add phases. -;=========================================================== -_bootScanRdb: -;-- find the RDB in the first 16 blocks - moveq.l #0,d6 ;d6 = current block index -_brdb_scan: - move.l d6,d0 - bsr _bootReadBlock - tst.l d0 - bne.s _brdb_next - move.l BC_BlockBuf(a4),a0 - cmpi.l #RDSK_ID,(a0) - bne.s _brdb_next - move.l rdb_SummedLongs(a0),d1 - cmp.l #128,d1 - bhi.s _brdb_next - bsr _bootChecksum - beq.s _brdb_found -_brdb_next: - addq.l #1,d6 - cmp.l #RDB_LOCATION_LIMIT,d6 - blo.w _brdb_scan - ifd DEBUG - lea dbg_boot_no_rdb(pc),a0 - bsr _bootDebug - endc - rts - -_brdb_found: - ifd DEBUG - lea dbg_boot_rdsk_found(pc),a0 - bsr _bootDebug - endc - move.l BC_BlockBuf(a4),a0 - move.l rdb_PartitionList(a0),d5 ;d5 = partition list head - move.l rdb_FileSysHeaderList(a0),d4 ;d4 = fshd list head - -;-- Phase 1: add filesystems carried in RDB. Hard cap at 16 hops -; so a corrupted multi-step fhb_Next cycle (A->B->A) cannot trap -; the cold-start path; the trivial 1-step self-loop is also -; caught by the cmp.l d3,d6 guard at the bottom of the loop. - move.l d4,d3 - moveq.l #16,d2 ;d2 = hop counter -_brdb_fs_loop: - move.l d3,d0 - addq.l #1,d0 ;-1 -> 0 (end sentinel) - beq.w _brdb_fs_done - subq.l #1,d2 ;walker hop counter - bmi.w _brdb_fs_done - move.l d3,d6 - move.l d3,d0 - bsr _bootReadBlock - tst.l d0 - bne.w _brdb_fs_done - move.l BC_BlockBuf(a4),a0 - cmpi.l #FSHD_ID,(a0) - bne.w _brdb_fs_done - move.l fhb_Next(a0),d3 - bsr _bootAddOneFileSys - cmp.l d3,d6 ;self-loop guard - beq.s _brdb_fs_done - bra.w _brdb_fs_loop -_brdb_fs_done: - -;-- Phase 2: add partitions. Hard cap at 128 hops (RDB allows up to -; ~127 partitions in practice); same rationale as the FSHD walker. - move.l d5,d3 - moveq.l #127,d2 ;d2 = hop counter (signed-fit moveq) -_brdb_part_loop: - move.l d3,d0 - addq.l #1,d0 - beq.s _brdb_pt_done - subq.l #1,d2 ;walker hop counter - bmi.s _brdb_pt_done - move.l d3,d6 - move.l d3,d0 - bsr _bootReadBlock - tst.l d0 - bne.s _brdb_pt_done - move.l BC_BlockBuf(a4),a0 - cmpi.l #PART_ID,(a0) - bne.s _brdb_pt_done - move.l pb_Next(a0),d3 - bsr _bootAddOnePartition - cmp.l d3,d6 - beq.s _brdb_pt_done - bra.s _brdb_part_loop -_brdb_pt_done: - rts - -;=========================================================== -; _bootAddOnePartition -; -; Input: BC_BlockBuf -> current PartitionBlock; a4 = &BootCtx -; Output: nothing (registers a DeviceNode via expansion.library -; when partition is mountable). -;=========================================================== -_bootAddOnePartition: - movem.l d2-d7/a2/a5,-(sp) - - move.l BC_BlockBuf(a4),a2 ;a2 = PartitionBlock - move.l BC_ExecBase(a4),a6 - -;-- NOMOUNT gate (pb_Flags bit PBFFB_NOMOUNT) - move.l pb_Flags(a2),d0 - btst #PBFFB_NOMOUNT,d0 - beq.s _bap_mountable - ifd DEBUG - lea dbg_boot_part_skip(pc),a0 - bsr _bootDebug - move.l BC_BlockBuf(a4),a0 - lea pb_DriveName(a0),a0 ;raw RDB name (no DN blob yet) - bsr _bootDebugBStr - endc - bra.w _bap_end -_bap_mountable: - -;-- The cached device-name BSTR is required for every FSSM; if the -; one-shot alloc in BootScanRDB failed there is no way to mount. - tst.l BC_DevNameBSTR(a4) - beq.w _bap_end - -;-- Validate DosEnvec TableSize before allocating the DN blob - move.l pb_Environment(a2),d2 ;d2 = envSize (TableSize) - cmp.l #DE_DOSTYPE,d2 ;need index 16 (DOSTYPE) in range - blo.w _bap_end - cmp.l #20,d2 - bhi.w _bap_end - -;-- Allocate DeviceNode blob (MEMF_REVERSE: high in RAM, away -; from low-heap fragmentation). Layout: -; [ 0..43 ] DeviceNode -; [ 44..59 ] FileSysStartupMsg -; [ 60..143] DosEnvec (TableSize <= 20 -> <= 84 bytes) -; [144..175] dn_Name BSTR - move.l #DN_BLOB_SIZE,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR+MEMF_REVERSE,d1 - jsr AllocMem(a6) - tst.l d0 - beq.w _bap_end - move.l d0,d7 ;d7 = DN byte addr - move.l d7,a5 ;a5 = DN - -;-- DeviceNode fields - move.l #-1,36(a5) ;dn_GlobVec - move.l #4000,20(a5) ;dn_StackSize - moveq.l #5,d0 - move.l d0,24(a5) ;dn_Priority - -;-- pb_DriveName BSTR -> DN_BSTR_OFF (early-startup menu only -; renders the partition name from a BSTR inside the DN's own -; allocation; separate-pool BSTRs render blank). - lea pb_DriveName(a2),a0 - lea DN_BSTR_OFF(a5),a1 - moveq.l #0,d3 - move.b (a0),d3 - addq.l #1,d3 -_bap_dn_cp: - move.b (a0)+,(a1)+ - subq.l #1,d3 - bne.s _bap_dn_cp - lea DN_BSTR_OFF(a5),a1 - move.l a1,d0 - lsr.l #2,d0 ;BPTR - move.l d0,40(a5) ;dn_Name - -;-- Uniquify the drive name against eb_MountList: -; append .1/.2/... when the name already exists, so two cards -; reusing RDB names don't clash in the early-startup menu). -; a4=&BootCtx, a5=DN blob. - bsr _bootDedupName - -;-- FileSysStartupMsg at DN_FSSM_OFF (fields written directly -; from BootCtx + DN; no scratch packet involved). - lea DN_FSSM_OFF(a5),a1 - move.l a1,d0 - lsr.l #2,d0 - move.l d0,28(a5) ;dn_Startup = BPTR(FSSM) - move.l BC_Unit(a4),(a1) ;fssm_Unit - move.l BC_DevNameBSTR(a4),4(a1) ;fssm_Device (cached BSTR) - lea DN_ENVEC_OFF(a5),a0 - move.l a0,d0 - lsr.l #2,d0 - move.l d0,8(a1) ;fssm_Environ = BPTR(envec) - -;-- Copy DosEnvec straight from pb_Environment(a2) into the DN -; blob's envec slot (one pass, no packet round-trip). - lea pb_Environment(a2),a1 ;a1 = source (TableSize + entries) - move.l d2,d3 ;d2 = envSize (already validated) - addq.l #1,d3 ;count = TableSize + 1 -_bap_envec_cp: - move.l (a1)+,(a0)+ - subq.l #1,d3 - bne.s _bap_envec_cp - -;-- Apply FileSysEntry patches BEFORE AddBootNode (FFS auto-attach -; in expansion.library otherwise replaces a custom handler such -; as PFS3 silently). - move.l BC_ExecBase(a4),a6 - move.l pb_Environment+DE_DOSTYPE*4(a2),d0 - bsr _bootFindFSEntry - tst.l d0 - beq.s _bap_fse_miss - move.l d0,a1 - move.l d7,a0 - bsr _bootPatchDNfromFSE -_bap_fse_miss: - -;-- Switch a6 back to expansion.library for the AddBootNode / -; AddDosNode call. - move.l BC_ExpBase(a4),a6 - - move.l pb_Flags(a2),d0 - btst #PBFFB_BOOTABLE,d0 - beq.w _bap_dosnode - -;---- AddBootNode - ifd DEBUG - lea dbg_boot_part_boot(pc),a0 - bsr _bootDebug - lea DN_BSTR_OFF(a5),a0 ;name as registered (post-dedup) - bsr _bootDebugBStr - endc - move.l pb_Environment+DE_BOOTPRI*4(a2),d0 - moveq.l #0,d1 ;flags=0: no ADNF_STARTPROC - move.l d7,a0 - move.l BC_ConfigDev(a4),a1 ;synthetic ConfigDev - jsr AddBootNode(a6) - move.b #1,BC_HaveNodes(a4) - addq.b #1,BC_PartCount(a4) - - bra.s _bap_end - -_bap_dosnode: - ifd DEBUG - lea dbg_boot_part_dos(pc),a0 - bsr _bootDebug - lea DN_BSTR_OFF(a5),a0 ;name as registered (post-dedup) - bsr _bootDebugBStr - endc - move.l pb_Environment+DE_BOOTPRI*4(a2),d0 - moveq.l #0,d1 - move.l d7,a0 - jsr AddDosNode(a6) - move.b #1,BC_HaveNodes(a4) - addq.b #1,BC_PartCount(a4) - -_bap_end: - movem.l (sp)+,d2-d7/a2/a5 - rts - -;=========================================================== -; _bootMakeExecBSTR: allocate and fill a BSTR copy of a -; NUL-terminated C string for FSSM use. ptable.library is -; device-agnostic so the caller-supplied name has to be -; converted to a BSTR at runtime. -; -; Called once per BootScanRDB invocation; the result is cached -; in BC_DevNameBSTR and shared across every partition's FSSM. -; -; Input : a0 = NUL-terminated C string, a4 = &BootCtx, -; a6 = ExecBase -; Output: d0 = BPTR (already >>2) to BSTR, or 0 on failure -; (Allocation is small and intentionally leaked: it must -; outlive BootCtx for FSSM consumers to keep using it. -; Total leak per scan is name_length + 4 bytes.) -;=========================================================== -_bootMakeExecBSTR: - movem.l d1-d3/a0-a2,-(sp) - move.l a0,a1 ;a1 = src - -;-- count length (clamped to 255 for BSTR) - moveq.l #0,d2 -_bmb_cnt: - tst.b (a1)+ - beq.s _bmb_cnt_done - addq.l #1,d2 - cmp.l #255,d2 - blo.s _bmb_cnt -_bmb_cnt_done: - -;-- alloc round_up(d2 + 1, 4) bytes; pad to longword for BSTR - move.l d2,d0 - addq.l #1,d0 ;include length byte - addq.l #3,d0 - and.l #~3,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 - jsr AllocMem(a6) - tst.l d0 - beq.s _bmb_fail - move.l d0,a1 ;a1 = BSTR base - move.b d2,(a1)+ ;length byte -;-- restore saved src ptr from stack: movem.l layout (low->high) is -;-- d1,d2,d3,a0,a1,a2, so the saved a0 lives at 12(sp), not (sp). - move.l 12(sp),a0 ;src ptr (saved a0) - move.l d2,d3 ;copy d2 chars - tst.l d3 - beq.s _bmb_done -_bmb_cp: - move.b (a0)+,(a1)+ - subq.l #1,d3 - bne.s _bmb_cp -_bmb_done: -;-- d0 already holds the BSTR base from AllocMem; turn it into a -;-- BPTR in place. movem.l restore touches d1-d3/a0-a2 only, so -;-- d0 carries the result through to the caller. - lsr.l #2,d0 ;BPTR - movem.l (sp)+,d1-d3/a0-a2 - rts -_bmb_fail: - movem.l (sp)+,d1-d3/a0-a2 - moveq.l #0,d0 - rts - -;=========================================================== -; _bootDedupName: ensure the candidate drive name (BSTR at -; DN_BSTR_OFF in the DN blob) is unique on expansion.library's -; eb_MountList. Mirrors commonly used rule by .device(s): -; if the name already exists, append ".n" (.1, .2, ...) and, if -; a name ending ".n" is also present, bump to ".n+1" and rescan -; from the top. -; -; Input : a4 = &BootCtx, a5 = DN blob (name BSTR at DN_BSTR_OFF) -; Output: BSTR at DN_BSTR_OFF mutated in place if a clash was hit -; Preserves a4/a5/a6/d7 (the caller relies on a5/d7). -;=========================================================== -_bootDedupName: - movem.l d0-d6/a0-a3,-(sp) - move.l BC_ExpBase(a4),a3 ;a3 = ExpansionBase - move.l a3,d0 - beq.s _bdn_ret ;no exp.lib -> nothing to check - - lea DN_BSTR_OFF(a5),a0 - moveq.l #0,d5 - move.b (a0),d5 ;d5 = original base char count - moveq.l #0,d4 ;d4 = suffix counter (0 = bare name) - -_bdn_retry: -;-- walk eb_MountList (LH at offset 74); entries are BootNodes. - lea 74(a3),a0 ;a0 = &eb_MountList - move.l (a0),a1 ;a1 = first node (lh_Head) -_bdn_walk: - move.l (a1),d0 ;ln_Succ - beq.s _bdn_unique ;tail sentinel -> name is unique - move.l 16(a1),a2 ;bn_DeviceNode - move.l a2,d0 - beq.s _bdn_next ;NULL device node - move.l 40(a2),d0 ;dn_Name (BPTR) - beq.s _bdn_next ;NULL name - lsl.l #2,d0 - move.l d0,a2 ;a2 = existing name BSTR - lea DN_BSTR_OFF(a5),a0 ;a0 = candidate BSTR - bsr _bootBStrEqualCI ;Z = equal - beq.s _bdn_dup -_bdn_next: - move.l (a1),a1 ;a1 = ln_Succ - bra.s _bdn_walk - -_bdn_dup: - cmp.l #9999,d4 ;defensive cap on suffix value - bhs.s _bdn_unique - addq.l #1,d4 - bsr _bootApplySuffix - bra.s _bdn_retry - -_bdn_unique: -_bdn_ret: - movem.l (sp)+,d0-d6/a0-a3 - rts - -;=========================================================== -; _bootApplySuffix: rewrite the name BSTR in place as -; ".". The base chars stay at DN_BSTR_OFF+1; the dot -; and digits are written strictly to their right, so the base -; prefix we re-read on each bump is never corrupted. If the -; result would exceed the 31-char the base is truncated (the -; suffix is kept, since it guarantees uniqueness). -; -; Input : a5 = DN blob, d4 = suffix value (>=1), d5 = base len -; Preserves all registers. -;=========================================================== -_bootApplySuffix: - movem.l d0-d3/a0-a2,-(sp) - lea -8(sp),sp ;8-byte digit scratch - move.l sp,a2 ;a2 = scratch base - move.l a2,a0 ;a0 = scratch write ptr - moveq.l #0,d1 ;digit count - move.l d4,d0 ;value to convert -_bas_div: - divu.w #10,d0 ;d0 = [rem:quot] - move.w d0,d2 ;d2.w = quotient - clr.w d0 - swap d0 ;d0.w = remainder - add.b #'0',d0 - move.b d0,(a0)+ ;store digit (least significant first) - addq.l #1,d1 - moveq.l #0,d0 - move.w d2,d0 ;d0 = quotient (zero-extended) - tst.w d0 - bne.s _bas_div - -;-- suffixLen = d1 + 1 (the dot); clamp kept base so total <= 31 - move.l d1,d3 - addq.l #1,d3 ;d3 = suffix length - move.l d5,d2 ;d2 = kept base length - move.l d2,d0 - add.l d3,d0 - cmp.l #31,d0 - bls.s _bas_fits - moveq.l #31,d2 - sub.l d3,d2 ;keptBase = 31 - suffixLen -_bas_fits: -;-- length byte - lea DN_BSTR_OFF(a5),a1 - move.l d2,d0 - add.l d3,d0 ;total length - move.b d0,(a1) -;-- '.' after the kept base - lea 1(a1),a1 - add.l d2,a1 - move.b #'.',(a1)+ -;-- digits, most significant first (scratch holds them reversed) - move.l a2,a0 - add.l d1,a0 ;a0 -> one past last stored digit -_bas_wr: - move.b -(a0),(a1)+ - cmp.l a2,a0 - bhi.s _bas_wr - - lea 8(sp),sp ;free scratch - movem.l (sp)+,d0-d3/a0-a2 - rts - -;=========================================================== -; _bootBStrEqualCI: case-insensitive compare of two BSTRs -; -; Input : a0 = BSTR A, a2 = BSTR B -; Output: d0 = 0 and Z set if equal; d0 = 1 and Z clear if not -; Preserves a0/a1/a2 and d1-d3. -;=========================================================== -_bootBStrEqualCI: - movem.l d1-d3/a0/a2,-(sp) - moveq.l #0,d1 - move.b (a0)+,d1 ;len A - moveq.l #0,d2 - move.b (a2)+,d2 ;len B - cmp.b d1,d2 - bne.s _bse_ne - tst.b d1 - beq.s _bse_eq ;both empty -_bse_loop: - move.b (a0)+,d2 - move.b (a2)+,d3 - cmp.b #'a',d2 - blo.s _bse_d2ok - cmp.b #'z',d2 - bhi.s _bse_d2ok - sub.b #$20,d2 ;to upper -_bse_d2ok: - cmp.b #'a',d3 - blo.s _bse_d3ok - cmp.b #'z',d3 - bhi.s _bse_d3ok - sub.b #$20,d3 -_bse_d3ok: - cmp.b d2,d3 - bne.s _bse_ne - subq.b #1,d1 - bne.s _bse_loop -_bse_eq: - movem.l (sp)+,d1-d3/a0/a2 - moveq.l #0,d0 ;0 = equal - tst.l d0 ;set Z - rts -_bse_ne: - movem.l (sp)+,d1-d3/a0/a2 - moveq.l #1,d0 ;nonzero = not equal - tst.l d0 ;clear Z - rts - -;=========================================================== -; Debug helpers (only assembled in DEBUG builds). -; All callable from BootScanRDB context (a4 = &BootCtx, -; a5 = ExecBase). Use (_AbsExecBase).w so they remain -; callable even when a6 has been temporarily clobbered. -;=========================================================== - ifd DEBUG - include "raw_debug.i" - -_bootDebugHex8: - movem.l d0-d3/a6,-(sp) - move.l (_AbsExecBase).w,a6 - move.l d0,d2 - moveq.l #7,d3 -_bdhx_lp: - rol.l #4,d2 - move.l d2,d0 - and.l #$f,d0 - cmp.b #10,d0 - blt.s _bdhx_dec - add.b #'A'-10,d0 - bra.s _bdhx_em -_bdhx_dec: - add.b #'0',d0 -_bdhx_em: - jsr RawPutChar(a6) - dbra d3,_bdhx_lp - movem.l (sp)+,d0-d3/a6 - rts - -_bootDebugDosType: - movem.l d0-d3/a0/a6,-(sp) - move.l (_AbsExecBase).w,a6 - move.l d0,d2 - moveq.l #3,d3 -_bddt_lp: - rol.l #8,d2 - move.l d2,d0 - and.l #$ff,d0 - tst.l d0 - bne.s _bddt_em - moveq.l #'.',d0 -_bddt_em: - jsr RawPutChar(a6) - dbra d3,_bddt_lp - movem.l (sp)+,d0-d3/a0/a6 - rts - -_bootDebugDecW: - movem.l d0-d5/a6,-(sp) - move.l (_AbsExecBase).w,a6 - and.l #$ffff,d0 - sub.l #8,sp - move.l sp,a0 - moveq.l #4,d3 -_bddw_fill: - move.l d0,d2 - divu #10,d2 - move.l d2,d1 - swap d1 - and.l #$ff,d1 - add.b #'0',d1 - move.b d1,0(a0,d3.l) - move.w d2,d0 - dbra d3,_bddw_fill - moveq.l #0,d3 -_bddw_skip: - cmp.b #4,d3 - bge.s _bddw_print - move.b 0(a0,d3.l),d0 - cmp.b #'0',d0 - bne.s _bddw_print - addq.l #1,d3 - bra.s _bddw_skip -_bddw_print: - move.b 0(a0,d3.l),d0 - and.l #$ff,d0 - jsr RawPutChar(a6) - addq.l #1,d3 - cmp.b #5,d3 - blt.s _bddw_print - add.l #8,sp - movem.l (sp)+,d0-d5/a6 - rts - -_bootDebugVersionNL: - movem.l d0-d2/a0/a6,-(sp) - move.l (_AbsExecBase).w,a6 - move.l d0,d2 - moveq.l #' ',d0 - jsr RawPutChar(a6) - moveq.l #'v',d0 - jsr RawPutChar(a6) - move.l d2,d0 - swap d0 - and.l #$ffff,d0 - bsr _bootDebugDecW - moveq.l #'.',d0 - move.l (_AbsExecBase).w,a6 - jsr RawPutChar(a6) - move.l d2,d0 - and.l #$ffff,d0 - bsr _bootDebugDecW - move.l (_AbsExecBase).w,a6 - moveq.l #13,d0 - jsr RawPutChar(a6) - moveq.l #10,d0 - jsr RawPutChar(a6) - movem.l (sp)+,d0-d2/a0/a6 - rts - -;-- Print a BSTR (length byte + chars) followed by CR/LF. -; a0 = BSTR pointer. Length is clamped to 31 so a garbage -; length byte in a raw RDB block can't run away. -; Callers: pb_DriveName (skip path, pre-blob) and the deduped -; name in the DN blob (DN_BSTR_OFF, +boot/+dos paths). -_bootDebugBStr: - movem.l d0/d3/a0/a6,-(sp) - move.l (_AbsExecBase).w,a6 - moveq.l #0,d3 - move.b (a0)+,d3 - cmp.w #31,d3 - bls.s _bdbs_ok - moveq.l #31,d3 -_bdbs_ok: - subq.l #1,d3 - bmi.s _bdbs_nl -_bdbs_lp: - moveq.l #0,d0 - move.b (a0)+,d0 - jsr RawPutChar(a6) - dbra d3,_bdbs_lp -_bdbs_nl: - moveq.l #13,d0 - jsr RawPutChar(a6) - moveq.l #10,d0 - jsr RawPutChar(a6) - movem.l (sp)+,d0/d3/a0/a6 - rts - endc ;DEBUG diff --git a/src/lib/ptable_dosdiag.i b/src/lib/ptable_dosdiag.i deleted file mode 100644 index 36ae0fd..0000000 --- a/src/lib/ptable_dosdiag.i +++ /dev/null @@ -1,35 +0,0 @@ -; ptable.library - DiagArea / BootPoint blob -; -; Standalone DiagArea hung off a synthetic ConfigDev's er_Reserved0c -; (ExpansionRom.DiagArea pointer) so the Kickstart strap (early-boot ROM -; code) boot menu renders the device as bootable and, when the user picks -; it, invokes the BootPoint to start dos.library. -; -; DAC_CONFIGTIME (bit 4) in da_Config is REQUIRED: strap's -; sChkBootPoint checks it and skips the BootPoint when it is -; clear. - -DAC_CONFIGTIME = $10 - - cnop 0,2 -s_rdb_diag_rom: - dc.b DAC_CONFIGTIME ;da_Config (bit 4 required) - dc.b 0 ;da_Flags - dc.w (s_rdb_diag_end-s_rdb_diag_rom) ;da_Size: bytes copied to RAM - dc.w 0 ;da_DiagPoint: none - dc.w (s_rdb_bootpoint-s_rdb_diag_rom) ;da_BootPoint offset -s_rdb_bootpoint: - ;-- a6 = ExecBase (passed by Kickstart strap); a2 = BootNode (passed but unused here) - lea s_rdb_dosname(pc),a1 - jsr FindResident(a6) - tst.l d0 - beq.s _srbp_end - movea.l d0,a0 - movea.l RT_INIT(a0),a0 ;dos.library Init vector - jsr (a0) ;DOS starts as tasks -_srbp_end: - rts -s_rdb_dosname: - dc.b "dos.library",0 - even -s_rdb_diag_end: diff --git a/src/lib/ptable_fs.s b/src/lib/ptable_fs.s deleted file mode 100644 index d004aba..0000000 --- a/src/lib/ptable_fs.s +++ /dev/null @@ -1,437 +0,0 @@ -;=========================================================== -; ptable_fs.s -- FileSystem.resource open/create/insert + FSE -; build helpers. -;=========================================================== - -;=========================================================== -; _bootAddOneFileSys -; Input: BC_BlockBuf -> current FileSysHeaderBlock; a4 = &BootCtx -; -; Reads the LSEG chain, concatenates the payload, then either -; relocates HUNK images via _bootRelocateHunks or wraps a -; pre-linked blob as a single-hunk SegList. Builds a -; FileSysEntry and inserts it into FileSys.resource. -;=========================================================== -_bootAddOneFileSys: - movem.l d2-d7/a2-a3,-(sp) - -;-- snapshot FSHD fields - move.l BC_BlockBuf(a4),a0 - move.l fhb_DosType(a0),d2 - move.l fhb_SegListBlocks(a0),d3 - -;-- validate LSEG head BEFORE any allocation - move.l d3,d0 - addq.l #1,d0 - beq.w _bao_end - -;-- duplicate FSHD (256 bytes) so we keep template fields after -; reading LSEG blocks (which clobber BC_BlockBuf) - moveq.l #0,d0 - move.w #256,d0 - move.l #MEMF_PUBLIC,d1 - move.l BC_ExecBase(a4),a6 - jsr AllocMem(a6) - tst.l d0 - beq.w _bao_end - move.l d0,a3 - move.l BC_BlockBuf(a4),a0 - move.l a3,a1 - move.l #256>>2,d0 -_bao_fshd_copy: - move.l (a0)+,(a1)+ - subq.l #1,d0 - bne.s _bao_fshd_copy - -;-- skip if a handler with this DosType already exists - move.l d2,d0 - bsr _bootFindFSEntry - tst.l d0 - beq.s _bao_no_dup - bra.w _bao_free_fshd -_bao_no_dup: - -;-- pass 1: count LSEG payload bytes - moveq.l #0,d4 - move.l d3,d5 -_bao_cnt_loop: - move.l d5,d0 - bsr _bootReadBlock - tst.l d0 - bne.w _bao_free_fshd - move.l BC_BlockBuf(a4),a0 - cmpi.l #LSEG_ID,(a0) - bne.w _bao_free_fshd - add.l #RDB_BLOCK_BYTES-lsb_LoadData,d4 - move.l lsb_Next(a0),d0 - move.l d0,d5 - addq.l #1,d0 - bne.s _bao_cnt_loop - - tst.l d4 - beq.w _bao_free_fshd - cmp.l #$100000,d4 ;cap at 1 MiB - bhi.w _bao_free_fshd - -;-- allocate SegList buffer (size + nextBPTR + payload + 0) - move.l d4,d0 - add.l #12,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 - move.l BC_ExecBase(a4),a6 - jsr AllocMem(a6) - tst.l d0 - beq.w _bao_free_fshd - move.l d0,a2 - - move.l d4,d0 - addq.l #8,d0 - move.l d0,(a2) - -;-- pass 2: copy LSEG payloads - lea 8(a2),a0 - move.l d3,d5 -_bao_cp_loop: - move.l d5,d0 - bsr _bootReadBlock - tst.l d0 - bne.w _bao_free_seg - move.l BC_BlockBuf(a4),a1 - cmpi.l #LSEG_ID,(a1) - bne.w _bao_free_seg - move.l lsb_Next(a1),d5 - lea lsb_LoadData(a1),a1 - move.l #(RDB_BLOCK_BYTES-lsb_LoadData)>>2,d0 -_bao_cp_words: - move.l (a1)+,(a0)+ - subq.l #1,d0 - bne.s _bao_cp_words - move.l d5,d0 - addq.l #1,d0 - bne.s _bao_cp_loop - -;-- HUNK image vs pre-linked - cmpi.l #HUNK_HEADER,8(a2) - bne.w _bao_not_hunk - -;-- HUNK: relocate via _bootRelocateHunks - move.l a2,-(sp) - lea 8(a2),a2 - bsr _bootRelocateHunks - move.l (sp)+,a2 - tst.l d0 - beq.w _bao_free_seg - move.l d0,d7 - move.l BC_ExecBase(a4),a6 - move.l a2,a1 - move.l d4,d0 - add.l #12,d0 - jsr FreeMem(a6) - sub.l a2,a2 - bra.w _bao_fse_build -_bao_not_hunk: - -;-- pre-linked: wrap concat buffer as single-hunk SegList - move.l a2,d0 - addq.l #4,d0 - lsr.l #2,d0 - move.l d0,d7 - -_bao_fse_build: -;-- I-cache flush before publishing the SegList - move.l BC_ExecBase(a4),a6 - jsr CacheClearU(a6) - -;-- Build a FileSysEntry; MEMF_REVERSE to keep it high. - moveq.l #fse_Sizeof,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR+MEMF_REVERSE,d1 - move.l BC_ExecBase(a4),a6 - jsr AllocMem(a6) - tst.l d0 - beq.w _bao_free_seg - move.l d0,a0 - - move.b #NT_UNKNOWN,LN_Type(a0) - move.l d7,d0 ;d7 = relocated SegList BPTR - bsr _bootFSName - move.l d0,LN_Name(a0) ;handler identity, or 0 -> unnamed - move.l d2,fse_DosType(a0) - - move.l fhb_Version(a3),fse_Version(a0) - move.l fhb_PatchFlags(a3),d5 - move.l d5,fse_PatchFlags(a0) - move.l fhb_Type(a3),fse_Type(a0) - move.l fhb_Task(a3),fse_Task(a0) - move.l fhb_Lock(a3),fse_Lock(a0) - move.l fhb_Handler(a3),fse_Handler(a0) - move.l fhb_StackSize(a3),fse_StackSize(a0) - move.l fhb_Priority(a3),fse_Priority(a0) - move.l fhb_Startup(a3),fse_Startup(a0) - move.l d7,fse_SegList(a0) - move.l fhb_GlobalVec(a3),fse_GlobalVec(a0) - -;-- ensure PatchFlags indicates SegList valid (bit 7 = $80) - or.l #$80,fse_PatchFlags(a0) - -;-- insert into FileSysResource - move.l a0,a2 - bsr _bootInsertFSEntry - - ifd DEBUG - movem.l d0-d1/a0-a1/a6,-(sp) - lea dbg_boot_fs_add(pc),a0 - bsr _bootDebug - move.l d2,d0 - bsr _bootDebugDosType - move.l fse_Version(a2),d0 - bsr _bootDebugVersionNL - movem.l (sp)+,d0-d1/a0-a1/a6 - endc - - bra.s _bao_free_fshd - -_bao_free_seg: - move.l a2,d0 - beq.s _bao_free_fshd - move.l BC_ExecBase(a4),a6 - move.l a2,a1 - move.l d4,d0 - add.l #12,d0 - jsr FreeMem(a6) -_bao_free_fshd: - move.l BC_ExecBase(a4),a6 - move.l a3,a1 - moveq.l #0,d0 - move.w #256,d0 - jsr FreeMem(a6) -_bao_end: - movem.l (sp)+,d2-d7/a2-a3 - rts - -;=========================================================== -; _bootFSName: derive a display name for a loaded FS handler by -; scanning its SegList. Pass A: first self-validating ROMTAG -; ($4AFC with RT_MATCHTAG == its own address) -> RT_IDSTRING, else -; RT_NAME. Pass B (if no ROMTAG): first "$VER:" cookie. Else 0. -; Input: d0 = SegList (BPTR) -; Output: d0 = APTR to a NUL-terminated name, or 0 (unnamed). -; Returned pointers alias into the SegList, which outlives the FSE. -; Preserves all other registers. -;=========================================================== -_bootFSName: - movem.l d1-d4/a0-a1,-(sp) - move.l d0,d4 ;d4 = SegList BPTR (kept for pass B) -;-- Pass A: ROMTAG RT_IDSTRING / RT_NAME - move.l d4,d1 -_bfn_rt_seg: - tst.l d1 - beq.w _bfn_ver - move.l d1,d0 - lsl.l #2,d0 - move.l d0,a0 ;a0 = seg (next-BPTR field) - move.l -4(a0),d2 - subq.l #8,d2 ;d2 = data length - move.l (a0),d1 ;d1 = next seg BPTR - addq.l #4,a0 ;a0 = data start (absolute addr) - move.l d2,d3 - sub.l #$16,d3 ;need a full romtag (0x16 bytes) - bmi.s _bfn_rt_seg -_bfn_rt_scan: - cmpi.w #$4AFC,(a0) - bne.s _bfn_rt_adv - move.l 2(a0),d0 ;RT_MATCHTAG - cmp.l a0,d0 ;self-pointer? -> genuine romtag - bne.s _bfn_rt_adv - move.l $12(a0),d0 ;RT_IDSTRING - bne.s _bfn_ret - move.l $0E(a0),d0 ;RT_NAME - bne.s _bfn_ret -_bfn_rt_adv: - addq.l #2,a0 - subq.l #2,d3 - bpl.s _bfn_rt_scan - bra.s _bfn_rt_seg -;-- Pass B: "$VER:" cookie -_bfn_ver: - move.l d4,d1 -_bfn_v_seg: - tst.l d1 - beq.s _bfn_none - move.l d1,d0 - lsl.l #2,d0 - move.l d0,a0 - move.l -4(a0),d2 - subq.l #8,d2 - move.l (a0),d1 - addq.l #4,a0 - move.l d2,d3 - subq.l #5,d3 - bmi.s _bfn_v_seg -_bfn_v_scan: - cmpi.b #'$',(a0) - bne.s _bfn_v_adv - cmpi.b #'V',1(a0) - bne.s _bfn_v_adv - cmpi.b #'E',2(a0) - bne.s _bfn_v_adv - cmpi.b #'R',3(a0) - bne.s _bfn_v_adv - cmpi.b #':',4(a0) - bne.s _bfn_v_adv - lea 5(a0),a0 ;skip "$VER:" -_bfn_v_sp: - cmpi.b #' ',(a0) ;skip following space(s) - bne.s _bfn_vhit - addq.l #1,a0 - bra.s _bfn_v_sp -_bfn_vhit: - move.l a0,d0 - bra.s _bfn_ret -_bfn_v_adv: - addq.l #1,a0 - subq.l #1,d3 - bpl.s _bfn_v_scan - bra.s _bfn_v_seg -_bfn_none: - moveq.l #0,d0 -_bfn_ret: - movem.l (sp)+,d1-d4/a0-a1 - rts - -;=========================================================== -; _bootFindFSEntry: look up FileSysEntry by DosType. -; Input: d0 = DosType -; Output: d0 = entry pointer or 0. -;=========================================================== -_bootFindFSEntry: - movem.l d2/a2,-(sp) - move.l d0,d2 - bsr _bootGetFSResource - tst.l d0 - beq.s _bff_none - move.l d0,a0 - lea fsr_FileSysEntries(a0),a0 - move.l (a0),a2 -_bff_loop: - move.l (a2),d0 - beq.s _bff_none - cmp.l fse_DosType(a2),d2 - beq.s _bff_hit - move.l d0,a2 - bra.s _bff_loop -_bff_hit: - move.l a2,d0 - bra.s _bff_end -_bff_none: - moveq.l #0,d0 -_bff_end: - movem.l (sp)+,d2/a2 - rts - -;=========================================================== -; _bootPatchDNfromFSE: apply FSE patches to a DeviceNode -; eagerly, BEFORE AddBootNode (otherwise AddBootNode's empty-DN -; auto-attach silently replaces a custom handler). -; -; Input : a0 = DeviceNode, a1 = FileSysEntry -; Trashes: d0, d1. -;=========================================================== -_bootPatchDNfromFSE: - move.l fse_PatchFlags(a1),d1 - btst #0,d1 - beq.s _pdf_no_type - move.l fse_Type(a1),dn_Type(a0) -_pdf_no_type: - btst #1,d1 - beq.s _pdf_no_task - move.l fse_Task(a1),dn_Task(a0) -_pdf_no_task: - btst #2,d1 - beq.s _pdf_no_lock - move.l fse_Lock(a1),dn_Lock(a0) -_pdf_no_lock: - btst #3,d1 - beq.s _pdf_no_handler - move.l fse_Handler(a1),dn_Handler(a0) -_pdf_no_handler: - btst #4,d1 - beq.s _pdf_no_stack - move.l fse_StackSize(a1),dn_StackSize(a0) -_pdf_no_stack: - btst #5,d1 - beq.s _pdf_no_pri - move.l fse_Priority(a1),dn_Priority(a0) -_pdf_no_pri: -;-- bit 6 (Startup) deliberately skipped (FSSM blob is ours) - btst #7,d1 - beq.s _pdf_no_seg - move.l fse_SegList(a1),dn_SegList(a0) -_pdf_no_seg: - btst #8,d1 - beq.s _pdf_no_gv - move.l fse_GlobalVec(a1),dn_GlobVec(a0) -_pdf_no_gv: - rts - -;=========================================================== -; _bootInsertFSEntry: Forbid + AddHead + Permit -; Input: a2 = FileSysEntry -;=========================================================== -_bootInsertFSEntry: - move.l a6,-(sp) - bsr _bootGetFSResource - tst.l d0 - beq.w _bie_end - move.l d0,a0 - lea fsr_FileSysEntries(a0),a0 - - move.l BC_ExecBase(a4),a6 - jsr Forbid(a6) - move.l a2,a1 - jsr AddHead(a6) - jsr Permit(a6) -_bie_end: - move.l (sp)+,a6 - rts - -;=========================================================== -; _bootGetFSResource: OpenResource(FileSystem.resource); if it -; does not exist yet, allocate + AddResource. Cache in -; BC_FSResource. -; Output: d0 = resource pointer (or 0 on alloc failure) -;=========================================================== -_bootGetFSResource: - move.l BC_FSResource(a4),d0 - bne.s _bfr_end - - move.l BC_ExecBase(a4),a6 - lea FileSysResName(pc),a1 - jsr OpenResource(a6) - tst.l d0 - bne.s _bfr_cache - -;-- create a new FileSysResource - moveq.l #fsr_Sizeof,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 - jsr AllocMem(a6) - tst.l d0 - beq.s _bfr_end - move.l d0,a0 - move.b #NT_RESOURCE,LN_Type(a0) - lea FileSysResName(pc),a1 - move.l a1,LN_Name(a0) - lea s_libname(pc),a1 - move.l a1,fsr_Creator(a0) - lea fsr_FileSysEntries(a0),a1 - move.l a1,(a1) - addq.l #4,(a1) - clr.l 4(a1) - move.l a1,8(a1) - - move.l a0,-(sp) - move.l a0,a1 - jsr AddResource(a6) - move.l (sp)+,d0 -_bfr_cache: - move.l d0,BC_FSResource(a4) -_bfr_end: - rts diff --git a/src/lib/ptable_hunk.s b/src/lib/ptable_hunk.s deleted file mode 100644 index d8d8bc5..0000000 --- a/src/lib/ptable_hunk.s +++ /dev/null @@ -1,401 +0,0 @@ -;=========================================================== -; ptable_hunk.s -- mini LoadSeg for cold-start use. -; -; Converts a concatenated HUNK executable (as found in the -; LSEG chain of an RDB FileSysHeader) into a relocated, chained -; SegList suitable for fse_SegList. Runs before dos.library -; is initialised so InternalLoadSeg is not callable. -; -; Supported hunk ids: -; HUNK_HEADER ($3F3): library-name list, table_size, first, -; last, per-hunk sizes. -; HUNK_CODE ($3E9): copy n longwords into current hunk. -; HUNK_DATA ($3EA): copy n longwords into current hunk. -; HUNK_BSS ($3EB): skip (memory MEMF_CLEAR already). -; HUNK_RELOC32 ($3EC): apply 32-bit absolute relocations. -; HUNK_RELOC32SHORT ($3FC): as RELOC32 but word-encoded. -; HUNK_SYMBOL ($3F0): skip symbol records until 0. -; HUNK_DEBUG ($3F1): skip n longwords. -; HUNK_NAME ($3E8): skip n longwords. -; HUNK_UNIT ($3E7): skip n longwords. -; HUNK_END ($3F2): advance to next hunk. -; -; Any other id logs "[RDB] hunk: bad id $xxxxxxxx" (DEBUG builds) -; then triggers full teardown (free per-hunk allocs, free scratch -; table, return 0). Caller leaves FileSystem.resource untouched in -; that case. -; -; Input : a2 = pointer to concatenated HUNK image (caller's -; concat buffer, payload starts at a2[0]). -; d4 = buffer size in bytes (used for bounds checks). -; a4 = &BootCtx (for ExecBase). -; Output: d0 = SegList BPTR on success, 0 on failure. -; Caller retains ownership of the input buffer. -; -; Clobbers: none visible to caller (movem saves d2-d7/a2-a6). -;=========================================================== -_bootRelocateHunks: - movem.l d2-d7/a2-a6,-(sp) - - move.l a2,a3 - add.l d4,a3 ;a3 = end-of-buffer (exclusive) - -;-- 1. verify HUNK_HEADER id - cmpa.l a3,a2 - bhs.w _brh_fail - cmpi.l #HUNK_HEADER,(a2) - bne.w _brh_fail - addq.l #4,a2 - -;-- 2. skip resident-library-name list: while (n=*a2++) skip n longs -_brh_lib_loop: - cmpa.l a3,a2 - bhs.w _brh_fail - move.l (a2)+,d0 - tst.l d0 - beq.s _brh_lib_done - lsl.l #2,d0 - add.l d0,a2 - cmpa.l a3,a2 - bhi.w _brh_fail - bra.s _brh_lib_loop -_brh_lib_done: - -;-- 3. table_size (ignored), first_hunk, last_hunk - lea 12(a2),a0 - cmpa.l a3,a0 - bhi.w _brh_fail - addq.l #4,a2 - move.l (a2)+,d2 ;first_hunk - move.l (a2)+,d3 ;last_hunk - -;-- 4. count = last - first + 1, clamp to [1..64] - move.l d3,d4 - sub.l d2,d4 - addq.l #1,d4 - tst.l d4 - ble.w _brh_fail - cmp.l #64,d4 - bhi.w _brh_fail - -;-- 5. allocate scratch pointer table - move.l d4,d0 - lsl.l #2,d0 - move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 - move.l BC_ExecBase(a4),a6 - jsr AllocMem(a6) - tst.l d0 - beq.w _brh_fail - move.l d0,a5 - -;-- 6. allocation pass: alloc each hunk - moveq.l #0,d5 -_brh_alloc_loop: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d6 - and.l #$3FFFFFFF,d6 - move.l d6,d0 - lsl.l #2,d0 - addq.l #8,d0 - cmp.l #$100000,d0 ;sanity: cap 1 MiB / hunk - bhi.w _brh_teardown - move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 - move.l BC_ExecBase(a4),a6 - jsr AllocMem(a6) - tst.l d0 - beq.w _brh_teardown - move.l d0,a0 - move.l d6,d1 - lsl.l #2,d1 - addq.l #8,d1 - move.l d1,(a0) ;alloc[0] = total bytes (for FreeMem) - clr.l 4(a0) - move.l d5,d0 - lsl.l #2,d0 - move.l a0,(a5,d0.l) - addq.l #1,d5 - cmp.l d4,d5 - blo.w _brh_alloc_loop - -;-- 7. chain segments via next-BPTRs - move.l d4,d7 - subq.l #1,d7 - ble.s _brh_chain_done - moveq.l #0,d5 -_brh_chain_loop: - move.l d5,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a0 - move.l d5,d0 - addq.l #1,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a1 - move.l a1,d0 - addq.l #4,d0 - lsr.l #2,d0 - move.l d0,4(a0) - addq.l #1,d5 - cmp.l d7,d5 - blo.s _brh_chain_loop -_brh_chain_done: - -;-- 8. walk hunk bodies - moveq.l #0,d5 -_brh_body_loop: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d0 - cmpi.l #HUNK_CODE,d0 - beq.w _brh_copy - cmpi.l #HUNK_DATA,d0 - beq.w _brh_copy - cmpi.l #HUNK_BSS,d0 - beq.w _brh_bss - cmpi.l #HUNK_RELOC32,d0 - beq.w _brh_reloc - cmpi.l #HUNK_RELOC32SHORT,d0 - beq.w _brh_reloc_short - cmpi.l #HUNK_SYMBOL,d0 - beq.w _brh_symbol - cmpi.l #HUNK_DEBUG,d0 - beq.w _brh_skip_n - cmpi.l #HUNK_NAME,d0 - beq.w _brh_skip_n - cmpi.l #HUNK_UNIT,d0 - beq.w _brh_skip_n - cmpi.l #HUNK_END,d0 - beq.w _brh_hunk_end - bra.w _brh_unknown - -_brh_copy: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d6 - and.l #$3FFFFFFF,d6 - move.l a2,d0 - move.l d6,d1 - lsl.l #2,d1 - add.l d1,d0 - cmp.l a3,d0 - bhi.w _brh_teardown - move.l d5,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a1 - ;-- verify body size fits the allocation: alloc stores - ; (header_d6*4 + 8) at offset 0; data area is alloc-8 bytes - move.l (a1),d0 - sub.l #8,d0 - cmp.l d1,d0 - blo.w _brh_teardown - addq.l #8,a1 - tst.l d6 - beq.s _brh_copy_done -_brh_copy_w: - move.l (a2)+,(a1)+ - subq.l #1,d6 - bne.s _brh_copy_w -_brh_copy_done: - bra.w _brh_body_loop - -_brh_bss: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d6 - and.l #$3FFFFFFF,d6 - ;-- verify body BSS size fits the allocation - move.l d5,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a1 - move.l (a1),d0 - sub.l #8,d0 - move.l d6,d1 - lsl.l #2,d1 - cmp.l d1,d0 - blo.w _brh_teardown - bra.w _brh_body_loop - -_brh_reloc: - move.l d5,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a0 - addq.l #8,a0 ;a0 = dst-hunk data base -_brh_reloc_outer: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d6 - tst.l d6 - beq.w _brh_body_loop - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d7 - sub.l d2,d7 - bmi.w _brh_teardown - cmp.l d4,d7 - bhs.w _brh_teardown - move.l d7,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a1 - addq.l #8,a1 -_brh_reloc_inner: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d0 - ;-- bounds-check relocation offset against dst hunk's data area; - ; alloc size header is at -8(a0), data ends at alloc_size-8 - ; bytes, max valid 4-byte write offset = alloc_size-12. - move.l -8(a0),d3 - sub.l #12,d3 - cmp.l d3,d0 - bhi.w _brh_teardown - move.l a1,d1 - add.l d1,(a0,d0.l) - subq.l #1,d6 - bne.s _brh_reloc_inner - bra.w _brh_reloc_outer - -;-- HUNK_RELOC32SHORT: identical fix-up to _brh_reloc but count, -; target-hunk and offset are UWORDs; the block is longword-padded -; after the terminating zero count. -_brh_reloc_short: - move.l d5,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a0 - addq.l #8,a0 ;a0 = dst-hunk data base -_brh_rs_outer: - cmpa.l a3,a2 - bhs.w _brh_teardown - moveq.l #0,d6 - move.w (a2)+,d6 ;count (UWORD); 0 -> end - tst.l d6 - beq.s _brh_rs_end - cmpa.l a3,a2 - bhs.w _brh_teardown - moveq.l #0,d7 - move.w (a2)+,d7 ;target hunk number (UWORD) - sub.l d2,d7 ;d2 = first_hunk - bmi.w _brh_teardown - cmp.l d4,d7 ;d4 = hunk count - bhs.w _brh_teardown - move.l d7,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a1 - addq.l #8,a1 ;a1 = target hunk data base -_brh_rs_inner: - cmpa.l a3,a2 - bhs.w _brh_teardown - moveq.l #0,d0 - move.w (a2)+,d0 ;offset (UWORD) - move.l -8(a0),d3 - sub.l #12,d3 - cmp.l d3,d0 - bhi.w _brh_teardown - move.l a1,d1 - add.l d1,(a0,d0.l) - subq.l #1,d6 - bne.s _brh_rs_inner - bra.s _brh_rs_outer -_brh_rs_end: - move.l a2,d0 ;align cursor up to longword - addq.l #3,d0 - and.l #$FFFFFFFC,d0 - move.l d0,a2 - bra.w _brh_body_loop - -;-- unrecognized hunk id: log it (DEBUG) and tear down so the -; load failure is visible rather than silent. -_brh_unknown: - ifd DEBUG - move.l d0,-(sp) ;preserve id across helpers - lea dbg_hunk_badid(pc),a0 - bsr _bootDebug - move.l (sp),d0 - bsr _bootDebugHex8 - lea dbg_boot_nl(pc),a0 - bsr _bootDebug - move.l (sp)+,d0 - endc - bra.w _brh_teardown - -_brh_symbol: -_brh_sym_loop: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d6 - tst.l d6 - beq.w _brh_body_loop - and.l #$00FFFFFF,d6 - addq.l #1,d6 - move.l d6,d0 - lsl.l #2,d0 - add.l d0,a2 - cmpa.l a3,a2 - bhi.w _brh_teardown - bra.s _brh_sym_loop - -_brh_skip_n: - cmpa.l a3,a2 - bhs.w _brh_teardown - move.l (a2)+,d6 - move.l d6,d0 - lsl.l #2,d0 - add.l d0,a2 - cmpa.l a3,a2 - bhi.w _brh_teardown - bra.w _brh_body_loop - -_brh_hunk_end: - addq.l #1,d5 - cmp.l d4,d5 - blo.w _brh_body_loop - -;-- success: result BPTR = (table[0] + 4) >> 2 - move.l (a5),a0 - move.l a0,d7 - addq.l #4,d7 - lsr.l #2,d7 - - move.l d4,d0 - lsl.l #2,d0 - move.l a5,a1 - move.l BC_ExecBase(a4),a6 - jsr FreeMem(a6) - -;-- I-cache flush after RELOC32 fixups (required on 68040/060). - move.l BC_ExecBase(a4),a6 - jsr CacheClearU(a6) - - move.l d7,d0 - movem.l (sp)+,d2-d7/a2-a6 - rts - -_brh_teardown: - moveq.l #0,d5 -_brh_td_loop: - cmp.l d4,d5 - bhs.s _brh_td_tbl - move.l d5,d0 - lsl.l #2,d0 - move.l (a5,d0.l),a1 - move.l a1,d0 - beq.s _brh_td_next - move.l (a1),d0 - move.l BC_ExecBase(a4),a6 - jsr FreeMem(a6) -_brh_td_next: - addq.l #1,d5 - bra.s _brh_td_loop -_brh_td_tbl: - move.l d4,d0 - lsl.l #2,d0 - move.l a5,a1 - move.l BC_ExecBase(a4),a6 - jsr FreeMem(a6) - moveq.l #0,d0 - movem.l (sp)+,d2-d7/a2-a6 - rts - -_brh_fail: - moveq.l #0,d0 - movem.l (sp)+,d2-d7/a2-a6 - rts diff --git a/src/lib/ptable_lib.s b/src/lib/ptable_lib.s deleted file mode 100644 index 6e586c7..0000000 --- a/src/lib/ptable_lib.s +++ /dev/null @@ -1,288 +0,0 @@ -; ptable.library - partition table scan and mount helper for AmigaOS -; Copyright (C) 2026 Jaroslav Pulchart -; -; This library is free software; you can redistribute it and/or -; modify it under the terms of the GNU Lesser General Public -; License as published by the Free Software Foundation; either -; version 2.1 of the License, or (at your option) any later version. -; -; This library 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 -; Lesser General Public License for more details. -; -; You should have received a copy of the GNU Lesser General Public -; License along with this library; if not, write to the Free Software -; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -;=========================================================================== -; ROLE -; -; ptable.library carries the cold-start RDB autoboot path: -; -; * Find RDSK on a block device, walk the partition list. -; * Load filesystem handlers carried in the RDB FSHD/LSEG -; blocks into FileSystem.resource (mini in-house LoadSeg). -; * Publish each partition via AddBootNode (bootable, with a -; synthetic ConfigDev + DiagArea/BootPoint that starts -; dos.library) or AddDosNode (non-bootable). -; -; INERT WHEN DISK-LOADED -; -; Like every Amiga library, ptable.library can be loaded from -; LIBS: at runtime via OpenLibrary. However, the only useful -; consumer (a device's RTF_COLDSTART stub) runs from -; Kickstart's ROM scan BEFORE ramlib starts, so a disk-loaded -; ptable.library will simply never have a caller. Functional -; autoboot therefore requires this library to be ROM-resident. -; -; BUILD VARIANTS -; -; Full build (DEBUG=1): includes serial debug output. -; Small build (no DEBUG): minimal binary size. -;=========================================================================== - -;--- Includes --- - include "ptable_version.i" - include "ptable_pub.i" - -;--- from exec.library ------------------------------------- - -_AbsExecBase = 4 - -;SysBase offsets (subset) -SB_DeviceList = 350 - -FindResident = -96 -InitResident = -102 -Forbid = -132 -Permit = -138 -FindName = -276 -AllocMem = -198 -FreeMem = -210 -AddHead = -240 -Remove = -252 -FindTask = -294 -AllocSignal = -330 -FreeSignal = -336 -CloseLibrary = -414 -OpenDevice = -444 -CloseDevice = -450 -DoIO = -456 -OpenResource = -498 -OpenLibrary = -552 -RawPutChar = -516 -AddResource = -486 -CacheClearU = -636 - -;struct Node -LN_Type = 8 -LN_Name = 10 -LN_Sizeof = 14 - -;LN_Type -NT_UNKNOWN = 0 -NT_TASK = 1 -NT_DEVICE = 3 -NT_MSGPORT = 4 -NT_MESSAGE = 5 -NT_RESOURCE = 8 -NT_LIBRARY = 9 - -;struct MsgPort -MP_Flags = 14 -MP_SigBit = 15 -MP_SigTask = 16 -MP_MsgList = 20 -MP_Sizeof = 34 - -;struct Message -MN_ReplyPort = 14 -MN_Length = 18 - -;memory types -MEMF_PUBLIC = 1 -MEMF_CLEAR = $10000 -MEMF_REVERSE = $40000 - -;struct Library -LIB_Node = 0 -LIB_Flags = 14 -LIB_NegSize = 16 -LIB_PosSize = 18 -LIB_Version = 20 -LIB_Revision = 22 -LIB_IdString = 24 -LIB_Sum = 28 -LIB_OpenCnt = 32 -LIB_Sizeof = 34 - -;LIB_Flags -LIBF_CHANGED = 2 -LIBF_SUMUSED = 4 -LIBF_DELEXP = 8 - -;struct Resident -RTC_MATCHWORD = $4afc -RT_INIT = $16 -RTF_AUTOINIT = $80 - -;trackdisk / IO command set (subset used by the boot path) -IO_Device = 20 -IO_Unit = 24 -IO_Command = 28 -IO_Flags = 30 -IO_Error = 31 -IO_Actual = 32 -IO_Length = 36 -IO_Data = 40 -IO_Offset = 44 -IO_Sizeof = 56 - -TD_CHANGESTATE = 14 -NSCMD_TD_READ64 = $c000 - -;CR/LF for debug strings -CR = 13 -LF = 10 - -;--- LibBase layout ---------------------------------------- -; The standard 34-byte exec library struct plus a couple of -; private slots used by the implementation. - -RDBL_ExecBase = LIB_Sizeof ;ExecBase pointer -RDBL_SegList = LIB_Sizeof+4 ;SegList for Expunge / FreeMem -RDBL_Sizeof = LIB_Sizeof+8 - -;=========================================================== -; Romtag + InitTable -; -; RTF_AUTOINIT here means Exec's MakeLibrary scaffolding does -; the entire setup for us: allocate RDBL_Sizeof bytes, copy -; the function offset table, call s_initfunc with d0 = new -; lib base / a0 = SegList / a6 = ExecBase, then AddLibrary. -;=========================================================== - -Start: - moveq.l #0,d0 - rts ;guard against shell invocation - - cnop 0,2 -s_resident: - dc.w RTC_MATCHWORD - dc.l s_resident - dc.l s_endcode - dc.b RTF_AUTOINIT - dc.b LIB_VERSION - dc.b NT_LIBRARY - dc.b PRI_PTABLE_LIB ;see ptable_pub.i for priority rationale - dc.l s_libname - dc.l s_libidstring - dc.l s_inittable - -s_libname: - dc.b "ptable.library",0 - dc.b "$VER: " -s_libidstring: - LIB_VERSION_STRING - dc.b LF,0 - even - -s_inittable: - dc.l RDBL_Sizeof - dc.l s_functable - dc.l 0 ;no InitStruct() table - dc.l s_initfunc - -s_functable: - dc.w -1 - dc.w Open-s_functable - dc.w Close-s_functable - dc.w Expunge-s_functable - dc.w Null-s_functable ;reserved - dc.w BootScanRDB-s_functable - dc.w -1 - -;--- s_initfunc: called by Exec.MakeLibrary scaffolding ---- -; d0 <- new LibBase -; a0 <- SegList (0 when ROM-resident) -; a6 <- ExecBase -; d0 -> LibBase or 0 -s_initfunc: - move.l d0,a1 ;a1 = LibBase - move.l a6,RDBL_ExecBase(a1) - move.l a0,RDBL_SegList(a1) - ;; LIB_Version is set up by MakeLibrary from the Resident's - ;; rt_Version, but rt_Version is only a byte; populate the - ;; full longword (major:minor) so consumers calling - ;; OpenLibrary("ptable.library", N) see a real revision. - move.l #LIB_VERSION<<16+LIB_REVISION,LIB_Version(a1) - move.l a1,d0 - rts - -;--- Open: a6 = LibBase -------------------------------------- -Open: - addq.w #1,LIB_OpenCnt(a6) - and.b #~LIBF_DELEXP,LIB_Flags(a6) - move.l a6,d0 - rts - -;--- Close: a6 = LibBase, returns SegList or 0 --------------- -Close: - moveq.l #0,d0 - subq.w #1,LIB_OpenCnt(a6) - bne.s cl_end - btst #3,LIB_Flags(a6) ;LIBF_DELEXP (bit 3 of LIB_Flags) - beq.s cl_end - bra.s Expunge -cl_end: - rts - -;--- Expunge: a6 = LibBase --------------------------------- -; Standard expunge: if the library is open, mark for delayed -; expunge and return 0; otherwise unlink, free our chunk, and -; return the SegList so ramlib can UnLoadSeg. -Expunge: - movem.l d2/a5-a6,-(sp) - move.l a6,a5 ;a5 = LibBase - move.l (_AbsExecBase).w,a6 - tst.w LIB_OpenCnt(a5) - beq.s ex_now - or.b #LIBF_DELEXP,LIB_Flags(a5) - moveq.l #0,d0 - bra.s ex_end -ex_now: - move.l RDBL_SegList(a5),d2 ;preserve SegList for return - move.l a5,a1 - jsr Remove(a6) ;unlink from library list - moveq.l #0,d0 - move.w LIB_NegSize(a5),d0 - move.l a5,a1 - sub.l d0,a1 - add.w LIB_PosSize(a5),d0 - jsr FreeMem(a6) - move.l d2,d0 -ex_end: - movem.l (sp)+,d2/a5-a6 - rts - -;--- Null: reserved LVO and various fall-through "do nothing" -Null: - moveq.l #0,d0 - rts - -;=========================================================== -; Boot-time bodies (BootScanRDB and helpers) -; -; All in a single source so the static branches below stay -; in range. -;=========================================================== - - include "ptable_boot.s" - include "ptable_fs.s" - include "ptable_hunk.s" - include "ptable_dosdiag.i" - - cnop 0,4 -s_endcode: - end diff --git a/src/lib/ptable_pub.i b/src/lib/ptable_pub.i deleted file mode 100644 index 9747822..0000000 --- a/src/lib/ptable_pub.i +++ /dev/null @@ -1,29 +0,0 @@ -; ptable.library — public interface -; -; Include in both ptable.library and any consumer device's RTF_COLDSTART stub. -; The stub opens ptable.library, calls BootScanRDB, then closes it (a6 = lib base). - -;--- LVOs (Exec convention: -6 per entry; Open/Close/Expunge/Reserved = -6..-24) --- - -; BootScanRDB(deviceName: a1, unit: d0) -> d0 = partitions registered, 0 on error -; Scans RDB on the named Exec device/unit, calls AddBootNode/AddDosNode for each -; partition, loads handler FSes into FileSysResource, and adds a synthetic ConfigDev -; (ERTF_DIAGVALID) so the Kickstart strap (early-boot menu) sees the device. - -_LVOBootScanRDB = -30 - -;--- Resident priorities (RT_PRI) for InitCode ordering ------------------- -; -; InitCode runs higher-priority residents first. Reference points (Hyperion -; 47.x): scsi.device runs at prio 10, Kickstart strap runs at prio -60. -; -; Cold-boot order: -; PRI_PTABLE_LIB ptable.library RTF_AUTOINIT must precede consumers -; PRI_CFD_DEVICE compactflash.device RTF_AUTOINIT AddDevice for our unit -; (scsi.device) prio 10, not ours -; PRI_CFD_BOOT compactflash.boot RTF_COLDSTART opens ptable.library, -; calls BootScanRDB -; -PRI_PTABLE_LIB equ 22 -PRI_CFD_DEVICE equ 21 -PRI_CFD_BOOT equ 9 diff --git a/src/lib/ptable_version.i b/src/lib/ptable_version.i deleted file mode 100644 index e52a562..0000000 --- a/src/lib/ptable_version.i +++ /dev/null @@ -1,10 +0,0 @@ -; Auto-generated by Makefile -LIB_VERSION = 1 -LIB_REVISION = 1 -LIB_VERSION_STRING macro - ifd __68020__ - dc.b "ptable.library 1.1 (07.06.2026) [68020]" - else - dc.b "ptable.library 1.1 (07.06.2026) [68000]" - endc - endm diff --git a/src/lib/raw_debug.i b/src/lib/raw_debug.i index b3bb2ff..4a56271 100644 --- a/src/lib/raw_debug.i +++ b/src/lib/raw_debug.i @@ -3,7 +3,7 @@ ; ; Provides _bootDebug: print NUL-terminated string at (a0) via ; Exec/RawPutChar, using (_AbsExecBase).w so a6 may hold any -; value on entry. All caller registers preserved. +; value on entry. All caller registers preserved. ; ; Independent of any per-mount (like Flags=8) ; Body is omitted in non-DEBUG builds. diff --git a/src/pcmciacheck.c b/src/pcmciacheck.c index aff1e00..b34c99d 100644 --- a/src/pcmciacheck.c +++ b/src/pcmciacheck.c @@ -7,8 +7,6 @@ * Based on original pcmciacheck 1.17 (29.08.2002) by Torsten Jager * Recreated in C for compactflash.device project * - * Build: make pcmciacheck (requires vbcc + NDK) - * Usage: pcmciacheck */ @@ -231,7 +229,7 @@ void WriteChunkHeader(const char *id, ULONG size) /* * Read 256 bytes using WORD access (mode 0) - * Matches assembly: 16 iterations × 8 word reads = 128 words = 256 bytes + * Matches assembly: 16 iterations x 8 word reads = 128 words = 256 bytes */ void ReadMode0(UBYTE *dest) { @@ -246,7 +244,7 @@ void ReadMode0(UBYTE *dest) /* * Read 256 bytes using BYTE access from data register (mode 1) - * Matches assembly: 16 iterations × 16 byte reads = 256 bytes + * Matches assembly: 16 iterations x 16 byte reads = 256 bytes */ void ReadMode1(UBYTE *dest) { @@ -261,7 +259,7 @@ void ReadMode1(UBYTE *dest) /* * Read 256 bytes using alternating BYTE access (mode 2) * Reads low byte from offset 8, high byte from offset 8+0x10001 - * Matches assembly: 16 iterations × 16 byte reads = 256 bytes + * Matches assembly: 16 iterations x 16 byte reads = 256 bytes */ void ReadMode2(UBYTE *dest) { @@ -277,7 +275,7 @@ void ReadMode2(UBYTE *dest) /* * Read 256 bytes using BYTE access from offset 8 (mode 3) - * Matches assembly: 16 iterations × 16 byte reads = 256 bytes + * Matches assembly: 16 iterations x 16 byte reads = 256 bytes */ void ReadMode3(UBYTE *dest) { @@ -882,7 +880,7 @@ static const char *DeviceSpeedName(UBYTE n) } /* CISTPL_DEVICE size byte: bits 7..3 = (address_units - 1), bits - * 2..0 = unit-size code. Returns size in bytes (matches the value + * 2..0 = unit-size code. Returns size in bytes (matches the value * the OS DeviceTuple call stores in CFU_DTSize). */ static ULONG DecodeDeviceSize(UBYTE sz) @@ -904,7 +902,7 @@ static ULONG DecodeDeviceSize(UBYTE sz) /* * Read one CIS byte at logical offset n. * PCMCIA cards in 8-bit attribute access put CIS bytes at every other - * byte address; the odd bytes are aliased / undefined. Walk by 2. + * byte address; the odd bytes are aliased / undefined. Walk by 2. */ static UBYTE CisByte(int offset) { @@ -1043,19 +1041,19 @@ static void HexDumpTuple(int data_off, UBYTE link) /* * Walk the PCMCIA attribute-memory CIS and print each tuple in - * human-readable form. Direct memory read at 0x00A00000, no + * human-readable form. Direct memory read at 0x00A00000, no * card.resource interaction, no OwnCard, no arbitration with - * compactflash.device or other handlers. Safe to run on cards that + * compactflash.device or other handlers. Safe to run on cards that * make the regular driver path hang. * * speed_ns: 0 leaves Gayle PCMCIA timing untouched; 100/150/250/720 * temporarily overrides $DAB000 bits 2-3 for the duration of the scan - * (restored on return). Useful for diagnosing cards whose CIS reads + * (restored on return). Useful for diagnosing cards whose CIS reads * are unstable at the default speed - rerun -cis with each value and * compare results. * * Tuple stride: each CIS byte is at attribute_base + n*2 (PCMCIA 8-bit - * attribute access aliases odd bytes). Walk terminates on CISTPL_END + * attribute access aliases odd bytes). Walk terminates on CISTPL_END * or after 32 tuples / 512 logical bytes - whichever comes first. */ int DumpCIS(int speed_ns)