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 6a657fd..18050fb 100644 --- a/Makefile +++ b/Makefile @@ -5,14 +5,14 @@ # Release version: YYYYMMDD package date + optional in-progress suffix # (-dev, -rc1, ...). Empty suffix for a final release. -RELEASE_DATE = 20260614 -VERSION_SUFFIX = +RELEASE_DATE = 20260730 +VERSION_SUFFIX = -dev # fat95 filesystem handler version -FAT95_MAJOR = 3 -FAT95_MINOR = 24 -FAT95_VERSION_SUFFIX = -FAT95_DATE = 07.06.2026 +FAT95_MAJOR = 4 +FAT95_MINOR = 0 +FAT95_VERSION_SUFFIX = -dev +FAT95_DATE = 30.07.2026 # Tools versions INSTALL95_MAJOR = 3 @@ -58,8 +58,14 @@ SETFILESIZE_VERSION = $(SETFILESIZE_MAJOR).$(SETFILESIZE_MINOR)$(SETFILESIZE_VER BOOT95_VERSION = $(BOOT95_MAJOR).$(BOOT95_MINOR)$(BOOT95_VERSION_SUFFIX) LSFSRES_VERSION = $(LSFSRES_MAJOR).$(LSFSRES_MINOR)$(LSFSRES_VERSION_SUFFIX) +# ptable.library + lsptres versions/dates read from the ptable build stamps. +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 = $(firstword $(shell cat $(PTABLE_LSPTRES_VERSION_FILE) 2>/dev/null)) +LSPTRES_DATE = $(word 2,$(shell cat $(PTABLE_LSPTRES_VERSION_FILE) 2>/dev/null)) + # Component table driving TOOLS and the README/dist auto-gen blocks. -COMPONENTS = FAT95 INSTALL95 DD DEBUG95 SETFILESIZE BOOT95 LSFSRES +COMPONENTS = FAT95 INSTALL95 DD DEBUG95 SETFILESIZE BOOT95 LSFSRES PLIB LSPTRES FAT95_NAME = fat95 FAT95_KIND = handler @@ -81,6 +87,12 @@ BOOT95_TARGET = $(TARGET_BOOT95) LSFSRES_NAME = lsfsres LSFSRES_KIND = tool LSFSRES_TARGET = $(TARGET_LSFSRES) +# Bundled from the ptable repo. +PLIB_NAME = ptable.library +PLIB_KIND = library +LSPTRES_NAME = lsptres +LSPTRES_KIND = tool +LSPTRES_TARGET = dist/c/lsptres # CPU tiers for the handler fan-out (tools stay single-tier). CPUS = 68020 68000 @@ -89,7 +101,9 @@ CPUS = 68020 68000 define _artifact_entries $(if $(filter tool,$($(1)_KIND)),\ $($(1)_NAME):$($(1)_TARGET):$($(1)_VERSION):$($(1)_DATE),\ -$(foreach c,$(CPUS),$($(1)_NAME)_$(c):$(OUTDIR)/$(c)/$($(1)_NAME):$($(1)_VERSION):$($(1)_DATE))) +$(if $(filter library,$($(1)_KIND)),\ +$(foreach c,$(CPUS),$($(1)_NAME)_$(c):dist/libs/$(c)/$($(1)_NAME):$($(1)_VERSION):$($(1)_DATE)),\ +$(foreach c,$(CPUS),$($(1)_NAME)_$(c):$(OUTDIR)/$(c)/$($(1)_NAME):$($(1)_VERSION):$($(1)_DATE)))) endef # "PREFIX|name|version|date" per component, fed to tools/components.sh @@ -142,17 +156,16 @@ OUTDIR = dist/l OUTDIR_020 = $(OUTDIR)/68020 OUTDIR_000 = $(OUTDIR)/68000 -# Files: Driver (two CPU tiers) -# 68020+ ships under l/68020/ (A1200 stock + 68020+ accelerators -# 030/040/060/080). 68000 ships under l/68000/ for stock A500/A600/ -# A1000/A2000/CDTV. Tools stay single-tier (68000) because they do -# no math hot-path work. +# ptable.library repo (override PTABLE= to point at a local checkout). Bundled +# into the release LIBS: so whole-disk auto-detect works without it in ROM. +PTABLE ?= extern/ptable +PTABLE_VERSION_FILE = $(PTABLE)/dist/ptable.version +PTABLE_LSPTRES_VERSION_FILE = $(PTABLE)/dist/lsptres.version + +# Files: Driver SOURCE = $(SRCDIR)/fat95.s TARGET_020 = $(OUTDIR_020)/fat95 TARGET_000 = $(OUTDIR_000)/fat95 -# TARGET retained as an alias for the 020+ binary for any downstream -# snippets that still reference it (e.g. tool-chain helpers). -TARGET = $(TARGET_020) DRIVER_TARGETS = $(TARGET_020) $(TARGET_000) # Files: Tools @@ -203,9 +216,45 @@ $(VERSION_STAMP): FORCE rm -f $(VERSION_STAMP).tmp; \ fi -# 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: +# Build ptable.library (small) + lsptres in the ptable repo and stage the +# built artifacts into dist/ for the release; nothing ptable-owned is rebuilt +# here, so every release ships the ptable-built bytes. MD2GUIDE/NDK are passed +# as absolute paths: the submodule's own relative defaults do not resolve from +# inside extern/ptable. Phony; a missing $(PTABLE) is a soft skip. +.PHONY: ptable-bundle +ptable-bundle: + $(Q)if [ -f "$(PTABLE)/Makefile" ]; then \ + $(MAKE) -C "$(PTABLE)" all guides MD2GUIDE=$(abspath $(MD2GUIDE)) NDK=$(abspath NDK) >/dev/null; \ + mkdir -p dist/libs/68020 dist/libs/68000 dist/c $(GUIDE_OUTPUT_DIR); \ + cp "$(PTABLE)/dist/small/68020/ptable.library" dist/libs/68020/; \ + cp "$(PTABLE)/dist/small/68000/ptable.library" dist/libs/68000/; \ + cp "$(PTABLE)/dist/c/lsptres" dist/c/lsptres; \ + cp "$(PTABLE)/dist/docs/lsptres.guide" $(GUIDE_OUTPUT_DIR)/; \ + echo " bundled ptable.library (small) + lsptres from $(PTABLE)"; \ + else \ + echo " NOTE: $(PTABLE) absent - ptable.library / lsptres not bundled"; \ + fi + +# Move the ptable checkout to its upstream tip and rebuild everything that +# bundles it. Uses the branch tip rather than "git submodule update": if the +# recorded commit was orphaned by an upstream history rewrite, restoring the +# pin would fail. Leaves the result uncommitted for review. Phony; a $(PTABLE) +# that is not a git checkout is a soft skip. +.PHONY: ptable-sync +ptable-sync: + $(Q)if [ -e "$(PTABLE)/.git" ]; then \ + git -C "$(PTABLE)" fetch origin; \ + git -C "$(PTABLE)" checkout --detach origin/master; \ + $(MAKE) all; \ + echo " ptable synced to $$(git -C "$(PTABLE)" rev-parse --short HEAD) ($$(cat $(PTABLE_VERSION_FILE)))"; \ + echo " review, then commit $(PTABLE) with the rebuilt dist/ artifacts"; \ + else \ + echo " NOTE: $(PTABLE) is not a git checkout - nothing to sync"; \ + fi + +# version-readme reads the ptable stamps for the PLIB/LSPTRES component versions, +# so the bundle (which builds them) must run first. +version-readme: ptable-bundle $(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" ' \ @@ -397,11 +446,18 @@ release: check-vasm version-readme all $(README_NAME) guide check-lha cp src/*.s src/*.i "$$S/fat95/src/"; \ cp $(README_NAME) "$$S/fat95/fat95.readme"; \ cp $(README_INFO) LICENSE "$$S/fat95/"; \ + if [ -d dist/libs ]; then \ + cp -r dist/libs "$$S/fat95/"; \ + echo " bundled ptable.library (small) + lsptres (staged by ptable-bundle)"; \ + else \ + echo " NOTE: $(PTABLE) absent - ptable.library / lsptres not bundled"; \ + fi; \ mkdir -p "$$S/fat95/docs"; \ cp $(GUIDE_FAT95) "$$S/fat95/docs/"; \ cp $(GUIDE_CHANGES) "$$S/fat95/docs/"; \ cp $(GUIDE_DD) "$$S/fat95/docs/"; \ cp $(GUIDE_LSFSRES) "$$S/fat95/docs/"; \ + [ -f $(GUIDE_LSPTRES) ] && cp $(GUIDE_LSPTRES) "$$S/fat95/docs/" || true; \ cp dist.info "$$S/fat95.info"; \ for d in dist/DOSDrivers dist/english dist/deutsch dist/magyar dist/polska dist/russian dist/espa* dist/fran*; do \ [ -d "$$d" ] && cp -r "$$d" "$$S/fat95/"; \ @@ -420,6 +476,7 @@ release: check-vasm version-readme all $(README_NAME) guide check-lha clean: rm -f $(DRIVER_TARGETS) $(TARGET_INSTALL95) $(TARGET_DD) $(TARGET_DEBUG95) $(TARGET_SETFILESIZE) $(TARGET_BOOT95) $(TARGET_LSFSRES) rm -f $(VERSION_FAT95_INC) $(VERSION_INSTALL95_INC) $(VERSION_DD_INC) $(VERSION_DEBUG95_INC) $(VERSION_SETFILESIZE_INC) $(VERSION_BOOT95_INC) $(VERSION_LSFSRES_INC) $(VERSION_STAMP) + rm -rf dist/libs dist/c/lsptres $(GUIDE_LSPTRES) $(Q)[ ! -d $(OUTDIR_020) ] || rmdir --ignore-fail-on-non-empty $(OUTDIR_020) $(Q)[ ! -d $(OUTDIR_000) ] || rmdir --ignore-fail-on-non-empty $(OUTDIR_000) @@ -450,6 +507,9 @@ help: @echo "Documentation targets:" @echo " guide / guides - Generate AmigaGuide documentation" @echo "" + @echo "Dependency targets:" + @echo " ptable-sync - Move $(PTABLE) to its upstream tip and rebuild (uncommitted)" + @echo "" @echo "Release targets:" @echo " version-readme - Update current release notes in docs/changes.md" @echo " readme - Generate $(README_NAME) from template" @@ -484,8 +544,7 @@ GUIDE_FAT95 = $(GUIDE_OUTPUT_DIR)/fat95.guide GUIDE_CHANGES = $(GUIDE_OUTPUT_DIR)/changes.guide GUIDE_DD = $(GUIDE_OUTPUT_DIR)/dd.guide GUIDE_LSFSRES = $(GUIDE_OUTPUT_DIR)/lsfsres.guide -# Backwards-compat alias for anything still referencing $(GUIDE_OUTPUT). -GUIDE_OUTPUT = $(GUIDE_FAT95) +GUIDE_LSPTRES = $(GUIDE_OUTPUT_DIR)/lsptres.guide MD2GUIDE = ../cfd/tools/md2guide.py guide guides: $(GUIDE_FAT95) $(GUIDE_CHANGES) $(GUIDE_DD) $(GUIDE_LSFSRES) diff --git a/README.md b/README.md index 31d5c7c..1ba41bb 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ Improvements to this handler are developed in my free time. If you'd like to sup * Every AMIGA, OS 1.3+ (OS 2.0+ for full functionality) * A suitable device file for low level disk access, like the mfm.device for floppies, compactflash.device for CF in PCMCIA. +* `ptable.library` v2 (in ROM or `LIBS:`) for whole-disk auto-detect + mounts of MBR/GPT cards. Mountlist entries that give explicit + geometry, and unpartitioned (superfloppy) volumes, do not need it. **Features** @@ -183,6 +186,9 @@ Available options: | `D` | Record "last accessed" date on file reads | ON | | `l` | Show 8.3 filenames lowercase (e.g., "test.txt") | OFF | | `L` | Show 8.3 filenames with uppercase initial (e.g., "Test.txt") | OFF | +| `q` | Quiet: never open error requesters (read/write/reinsert windows); errors are reported to the caller instead. Recommended for hot-plugged removable media | OFF | + +Regardless of `q`, no requester is opened once the handler has been asked to quit (`ACTION_DIE`), so an unmount can never stall behind a window. ### Startup Options @@ -453,6 +459,10 @@ The exact status shown may depend on the order of disk insertion and reinsertion | `c/SetFileSize` | File size modification utility | | `c/boot95` | Boot partition creation tool | | `c/lsfsres` | FileSystem.resource entry lister | +| `c/lsptres` | partition.resource entry lister (from ptable.library) | +| `libs//ptable.library` | partition scan/automount library (small), bundled | + +`ptable.library` and `lsptres` are built from the companion [amigaos-ptable](https://github.com/pulchart/amigaos-ptable) repo and bundled here so whole-disk auto-detect works without a separate install; `lsptres` lists `partition.resource` (the partition-side companion to `lsfsres`). ### dd @@ -480,6 +490,10 @@ This installs an Amiga automount sequence in the unused area between the MBR and Lists `FileSystem.resource` entries. See [docs/lsfsres.md](docs/lsfsres.md) for more details. +### lsptres + +Lists `partition.resource` entries (bundled from ptable.library). The partition-side companion to `lsfsres`. + ## License GNU LGPL v2.1 diff --git a/dist.readme.in b/dist.readme.in index 05fd515..2e0927e 100644 --- a/dist.readme.in +++ b/dist.readme.in @@ -4,7 +4,7 @@ Author: jaroslav.pulchart@gmail.com (Jaroslav Pulchart), based on work by Type: disk/misc Version: @VERSION@ Architecture: m68k-amigaos -Replaces: disk/misc/fat95.v20260609.lha +Replaces: disk/misc/fat95.v20260614.lha Kurz: Win95/98-kompatibles Dateisystem fat95 - Win95/98 compatible FAT filesystem handler for AmigaOS. Fork of disk/misc/fat95.lha. @@ -16,25 +16,25 @@ COMPONENTS IN THIS RELEASE WHAT'S NEW (@DATE@) ======================= -Tools: +fat95 handler: -This release is mainly a dd maintenance update. dd 2.2 adds TD64 support for -large-disk transfers, fixes unreliable NSD detection from the previous dd -release, and improves INSPECT output. +* New "q" (quiet) option: control "+q" silences all fat95 error + windows for a mount (errors go to the calling program instead). + Unmounting a removed card cancels any open window automatically. -dd 2.2: -* Support TD64 and harden NSD probe (fixes #20). -* INSPECT now shows a ">4GiB methods:" line listing which large-transfer - commands the device offers. Add VERBOSE to also print the device's - full command set. -* New CMD= option to force which command dd uses: AUTO (default), CMD, - TD64, NSCMD or SCSI. A forced command is used as-is, with no automatic - fallback. +* Shared partition scanning: fat95 auto-detects its FAT partition (MBR, + GPT, and flat whole-disk FAT) from the shared partition.resource + published by ptable.library, the same scan used by compactflash.device, + instead of scanning the partition table itself. The resolved mount + Flags/CONTROL are reported and shown by lsptres. Auto-detect now + requires ptable.library (bundled, install to LIBS:); explicit-geometry + mountlist entries still mount without it. -dd 2.1: -* On Kickstart older than 2.0 (V36), dd now prints a short message - saying it needs Kickstart 2.0+ and exits, instead of failing silently. -* Console output now uses VFPrintf. +Bundled: + +* ptable.library and lsptres are now included in the archive, shared with + the CompactFlash driver. lsptres lists partition.resource. + Library: https://github.com/pulchart/amigaos-ptable Purpose ======= @@ -48,6 +48,8 @@ System requirements * every AMIGA, OS 1.3+ (OS 2.0+ for full functionality) * a suitable device file for low level disk access, like the mfm.device for floppies, compactflash.device for CF in PCMCIA +* ptable.library (bundled; install to LIBS:) for partition auto-detect; + explicit-geometry mountlist entries do not need it Features ======== @@ -57,7 +59,7 @@ See fat95.guide for full documentation. * Workbench and applications support * Diskchange autosense * Format type autosense: FAT12, FAT16 and FAT32 -* MBR and GPT partition table support +* MBR, GPT, and flat (whole-disk FAT) partition support * Simple LINUX style partition selection or manual definition * Up to 4 GBytes of partition size for FAT16 * Large harddisk support via TD64 or direct SCSI @@ -101,6 +103,7 @@ fat95/docs/fat95.guide - FAT95 filesystem handler documentation fat95/docs/changes.guide - Release notes and original fat95 history fat95/docs/dd.guide - dd raw block transfer tool documentation fat95/docs/lsfsres.guide - lsfsres FileSystem.resource lister documentation +fat95/docs/lsptres.guide - lsptres partition.resource lister documentation fat95/l/68020/fat95 - FAT95 filesystem handler, 68020+ cpu tier fat95/l/68000/fat95 - FAT95 filesystem handler, 68000+ cpu tier @@ -110,6 +113,10 @@ fat95/c/debug95 - Debug information tool fat95/c/SetFileSize - File size modification utility fat95/c/boot95 - Boot partition creation tool fat95/c/lsfsres - FileSystem.resource entry lister +fat95/c/lsptres - partition.resource entry lister (from ptable.library) + +fat95/libs/68020/ptable.library - partition scan/automount library, 68020+ (small) +fat95/libs/68000/ptable.library - partition scan/automount library, 68000+ (small) fat95/DOSDrivers/ - Mount list examples diff --git a/dist/c/lsptres b/dist/c/lsptres new file mode 100755 index 0000000..898f2b4 --- /dev/null +++ b/dist/c/lsptres @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84b91add9464588dc9226249f1daa66032e2d5761fdcd0ad4b90ce5cc7507e9b +size 10524 diff --git a/dist/docs/changes.guide b/dist/docs/changes.guide index 37f101a..0699861 100644 --- a/dist/docs/changes.guide +++ b/dist/docs/changes.guide @@ -1,6 +1,6 @@ @database "fat95 release notes" -@$VER: fat95 release notes guide 20260614 (14.06.2026) -@author "Generated by md2guide.py v1.5 (20.05.2026)" +@$VER: fat95 release notes guide 20260730-dev (30.07.2026) +@author "Generated by md2guide.py v1.6 (14.06.2026)" @(c) "See LICENSE" @font topaz.font 8 @help Main @@ -10,6 +10,7 @@ @{b}fat95 release notes@{ub} + @{"20260730-dev" link 20260730_dev} @{"20260614" link 20260614} @{"20260609" link 20260609} @{"3.23 (19.05.2026)" link 3_23__19_05_2026_} @@ -26,6 +27,7 @@ @{"20260609" link 20260609} @{"20260614" link 20260614} + @{"20260730-dev" link 20260730_dev} @{"3.19 (01.02.2026)" link 3_19__01_02_2026_} @{"3.20 (16.03.2026)" link 3_20__16_03_2026_} @{"3.21 (18.04.2026)" link 3_21__18_04_2026_} @@ -36,6 +38,44 @@ @endnode +@node 20260730_dev "20260730-dev" +@{b}20260730-dev@{ub} + +@{i}Components in this release@{ui}: + + * @{fg shine}fat95 4.0-dev (30.07.2026)@{fg text} @{i}(new)@{ui} + * @{fg shine}install95 3.19 (25.01.2026)@{fg text} + * @{fg shine}dd 2.2 (13.06.2026)@{fg text} + * @{fg shine}debug95 3.19 (25.01.2026)@{fg text} + * @{fg shine}SetFileSize 1.1 (25.01.2026)@{fg text} + * @{fg shine}boot95 3.19 (25.01.2026)@{fg text} + * @{fg shine}lsfsres 1.0 (16.05.2026)@{fg text} + * @{fg shine}ptable.library 2.0-dev (30.07.2026)@{fg text} @{i}(new)@{ui} + * @{fg shine}lsptres 1.0-dev (30.07.2026)@{fg text} @{i}(new)@{ui} + +@{b}fat95 handler@{ub} + + * @{b}New @{fg shine}q@{fg text} (quiet) option.@{ub} Control @{fg shine}"+q"@{fg text} silences all fat95 error windows for a + mount (errors go to the calling program instead). Unmounting a removed card + now cancels any open window automatically. + * @{b}Shared partition scanning.@{ub} fat95 auto-detects its FAT partition (MBR, GPT, and + flat whole-disk FAT) from the shared @{fg shine}partition.resource@{fg text} published by + @{fg shine}ptable.library@{fg text} , the same scan used by @{fg shine}compactflash.device@{fg text} , instead of + scanning the partition table itself. The resolved mount Flags/CONTROL are + reported and shown by @{fg shine}lsptres@{fg text} . Auto-detect now requires @{fg shine}ptable.library@{fg text} + (bundled, install to @{fg shine}LIBS:@{fg text} ); explicit-geometry mountlist entries still mount + without it. See @{" ptable.guide " link "ptable.guide/Main"} and @{" lsptres.guide " link "lsptres.guide/Main"} . + +@{b}Tools@{ub} + + * @{fg shine}ptable.library@{fg text} and @{fg shine}lsptres@{fg text} are now bundled in the archive, shared with the + CompactFlash driver. @{fg shine}lsptres@{fg text} lists @{fg shine}partition.resource@{fg text} . + +---------------------------------------- +@{"<< Prev" link Main} @{"Contents" link Main} @{"Next >>" link 20260614} + +@endnode + @node 20260614 "20260614" @{b}20260614@{ub} @@ -73,7 +113,7 @@ IO (transfer) command usage changes: * Console output now uses @{fg shine}VFPrintf@{fg text}. ---------------------------------------- -@{"<< Prev" link Main} @{"Contents" link Main} @{"Next >>" link 20260609} +@{"<< Prev" link 20260730_dev} @{"Contents" link Main} @{"Next >>" link 20260609} @endnode diff --git a/dist/docs/dd.guide b/dist/docs/dd.guide index c15a5f3..a7d5250 100644 --- a/dist/docs/dd.guide +++ b/dist/docs/dd.guide @@ -1,6 +1,6 @@ @database "dd" @$VER: dd guide 2.2 (13.06.2026) -@author "Generated by md2guide.py v1.5 (20.05.2026)" +@author "Generated by md2guide.py v1.6 (14.06.2026)" @(c) "See LICENSE" @font topaz.font 8 @help Main diff --git a/dist/docs/fat95.guide b/dist/docs/fat95.guide index 9bccbd8..8c5c5d7 100644 --- a/dist/docs/fat95.guide +++ b/dist/docs/fat95.guide @@ -1,6 +1,6 @@ @database "fat95" -@$VER: fat95 guide 20260614 (14.06.2026) -@author "Generated by md2guide.py v1.5 (20.05.2026)" +@$VER: fat95 guide 20260704-dev (04.07.2026) +@author "Generated by md2guide.py v1.6 (14.06.2026)" @(c) "See LICENSE" @font topaz.font 8 @help Main @@ -39,6 +39,7 @@ @{"Debug95" link Debug95} @{"boot95" link boot95} @{"lsfsres" link lsfsres} + @{"lsptres" link lsptres} @{"License" link License} @endnode @@ -69,6 +70,7 @@ @{b}L@{ub} @{"License" link License} @{"lsfsres" link lsfsres} + @{"lsptres" link lsptres} @{b}M@{ub} @{"Manual Partition Definition" link Manual_Partition_Definition} @{"Method A: Shell Command" link Method_A__Shell_Command} @@ -133,6 +135,9 @@ on Ko-fi (https://ko-fi.com/jaroslavpulchart). * Every AMIGA, OS 1.3+ (OS 2.0+ for full functionality) * A suitable device file for low level disk access, like the mfm.device for floppies, compactflash.device for CF in PCMCIA. + * @{fg shine}ptable.library@{fg text} v2 (in ROM or @{fg shine}LIBS:@{fg text}) for whole-disk auto-detect + mounts of MBR/GPT cards. Mountlist entries that give explicit + geometry, and unpartitioned (superfloppy) volumes, do not need it. @{b}Features@{ub} @@ -379,6 +384,17 @@ Available options: @{fg shine}L@{fg text} Show 8.3 filenames with OFF uppercase initial (e.g., "Test.txt") + @{fg shine}q@{fg text} Quiet: never open error OFF + requesters + (read/write/reinsert + windows); errors are + reported to the caller + instead. Recommended for + hot-plugged removable + media + +Regardless of @{fg shine}q@{fg text} , no requester is opened once the handler has been asked +to quit ( @{fg shine}ACTION_DIE@{fg text} ), so an unmount can never stall behind a window. ---------------------------------------- @{"<< Prev" link File_System_Settings} @{"Contents" link Main} @{"Next >>" link Startup_Options} @@ -793,17 +809,27 @@ reinsertion. @{" Debug95 " link Debug95} @{" boot95 " link boot95} @{" lsfsres " link lsfsres} - - @{b}Tool@{ub} @{b}Description@{ub} - ------------- ----------------------------------- - @{fg shine}l/fat95@{fg text} FAT95 filesystem handler - @{fg shine}l/install95@{fg text} Locale installer (read/write locale - files) - @{fg shine}c/dd@{fg text} Raw block transfer tool - @{fg shine}c/debug95@{fg text} Debug information tool - @{fg shine}c/SetFileSize@{fg text} File size modification utility - @{fg shine}c/boot95@{fg text} Boot partition creation tool - @{fg shine}c/lsfsres@{fg text} FileSystem.resource entry lister + @{" lsptres " link lsptres} + + @{b}Tool@{ub} @{b}Description@{ub} + ------------------------- ------------------------------------- + @{fg shine}l/fat95@{fg text} FAT95 filesystem handler + @{fg shine}l/install95@{fg text} Locale installer (read/write locale + files) + @{fg shine}c/dd@{fg text} Raw block transfer tool + @{fg shine}c/debug95@{fg text} Debug information tool + @{fg shine}c/SetFileSize@{fg text} File size modification utility + @{fg shine}c/boot95@{fg text} Boot partition creation tool + @{fg shine}c/lsfsres@{fg text} FileSystem.resource entry lister + @{fg shine}c/lsptres@{fg text} partition.resource entry lister (from + ptable.library) + @{fg shine}libs//ptable.library@{fg text} partition scan/automount library + (small), bundled + +@{fg shine}ptable.library@{fg text} and @{fg shine}lsptres@{fg text} are built from the companion amigaos-ptable +(https://github.com/pulchart/amigaos-ptable) repo and bundled here so +whole-disk auto-detect works without a separate install; @{fg shine}lsptres@{fg text} lists +@{fg shine}partition.resource@{fg text} (the partition-side companion to @{fg shine}lsfsres@{fg text} ). ---------------------------------------- @{"<< Prev" link Disk_Status_Meanings} @{"Contents" link Main} @{"Next >>" link dd} @@ -857,7 +883,18 @@ MBR and first partition (~30KB). Requires fat95 in @{fg shine}L:@{fg text} drawe Lists @{fg shine}FileSystem.resource@{fg text} entries. See @{" docs/lsfsres.guide " link "lsfsres.guide/Main"} for more details. ---------------------------------------- -@{"<< Prev" link boot95} @{"Contents" link Main} @{"Next >>" link License} +@{"<< Prev" link boot95} @{"Contents" link Main} @{"Next >>" link lsptres} + +@endnode + +@node lsptres "lsptres" +@{i}lsptres@{ui} + +Lists @{fg shine}partition.resource@{fg text} entries (bundled from ptable.library). The +partition-side companion to @{fg shine}lsfsres@{fg text} . + +---------------------------------------- +@{"<< Prev" link lsfsres} @{"Contents" link Main} @{"Next >>" link License} @endnode @@ -867,6 +904,6 @@ Lists @{fg shine}FileSystem.resource@{fg text} entries. See @{" docs/lsfsres.gu GNU LGPL v2.1 ---------------------------------------- -@{"<< Prev" link lsfsres} @{"Contents" link Main} +@{"<< Prev" link lsptres} @{"Contents" link Main} @endnode diff --git a/dist/docs/lsfsres.guide b/dist/docs/lsfsres.guide index 04d5cc7..3790aa2 100644 --- a/dist/docs/lsfsres.guide +++ b/dist/docs/lsfsres.guide @@ -1,6 +1,6 @@ @database "lsfsres" @$VER: lsfsres guide 1.0 (16.05.2026) -@author "Generated by md2guide.py v1.5 (20.05.2026)" +@author "Generated by md2guide.py v1.6 (14.06.2026)" @(c) "See LICENSE" @font topaz.font 8 @help Main diff --git a/dist/docs/lsptres.guide b/dist/docs/lsptres.guide new file mode 100644 index 0000000..a243c45 --- /dev/null +++ b/dist/docs/lsptres.guide @@ -0,0 +1,253 @@ +@database "lsptres" +@$VER: lsptres guide 1.0-dev (30.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/l/68000/fat95 b/dist/l/68000/fat95 index cfd01d8..26baf40 100644 --- a/dist/l/68000/fat95 +++ b/dist/l/68000/fat95 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e996e22f6bb19b11ca3d67fdbc89c937aa4fadd8c2cd8223108eed10f0545ee -size 27472 +oid sha256:061dc2d6f6efeb2af409465b5c290996018cc0b6380f2066d648f555e74141e7 +size 27824 diff --git a/dist/l/68020/fat95 b/dist/l/68020/fat95 index 81c413a..bc4ced3 100644 --- a/dist/l/68020/fat95 +++ b/dist/l/68020/fat95 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:633dbae1bba52447e418b908d3d6f77d86145c076f08775733aab840db061d8f -size 27336 +oid sha256:209c6378540fda099aead825068b11d86cfb2cc101493dde84702f8afd0d2616 +size 27688 diff --git a/dist/libs/68000/ptable.library b/dist/libs/68000/ptable.library new file mode 100644 index 0000000..11232c9 Binary files /dev/null and b/dist/libs/68000/ptable.library differ diff --git a/dist/libs/68020/ptable.library b/dist/libs/68020/ptable.library new file mode 100644 index 0000000..2a353c2 Binary files /dev/null and b/dist/libs/68020/ptable.library differ diff --git a/docs/changes.md b/docs/changes.md index a16e169..01753a1 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,8 +1,33 @@ -## 20260614 +## 20260730-dev _Components in this release_: +- `fat95 4.0-dev (30.07.2026)` _(new)_ +- `install95 3.19 (25.01.2026)` +- `dd 2.2 (13.06.2026)` +- `debug95 3.19 (25.01.2026)` +- `SetFileSize 1.1 (25.01.2026)` +- `boot95 3.19 (25.01.2026)` +- `lsfsres 1.0 (16.05.2026)` +- `ptable.library 2.0-dev (30.07.2026)` _(new)_ +- `lsptres 1.0-dev (30.07.2026)` _(new)_ + + + +#### fat95 handler + +- **New `q` (quiet) option.** Control `"+q"` silences all fat95 error windows for a mount (errors go to the calling program instead). Unmounting a removed card now cancels any open window automatically. +- **Shared partition scanning.** fat95 auto-detects its FAT partition (MBR, GPT, and flat whole-disk FAT) from the shared `partition.resource` published by `ptable.library`, the same scan used by `compactflash.device`, instead of scanning the partition table itself. The resolved mount Flags/CONTROL are reported and shown by `lsptres`. Auto-detect now requires `ptable.library` (bundled, install to `LIBS:`); explicit-geometry mountlist entries still mount without it. 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). + +#### Tools + +- `ptable.library` and `lsptres` are now bundled in the archive, shared with the CompactFlash driver. `lsptres` lists `partition.resource`. + +## 20260614 + +_Components in this release_: + - `fat95 3.24 (07.06.2026)` - `install95 3.19 (25.01.2026)` - `dd 2.2 (13.06.2026)` _(new)_ @@ -10,7 +35,6 @@ _Components in this release_: - `SetFileSize 1.1 (25.01.2026)` - `boot95 3.19 (25.01.2026)` - `lsfsres 1.0 (16.05.2026)` - #### Tools diff --git a/extern/ptable b/extern/ptable new file mode 160000 index 0000000..eababbe --- /dev/null +++ b/extern/ptable @@ -0,0 +1 @@ +Subproject commit eababbe4b22d41a2d89eb74eb82541e39770c4e1 diff --git a/src/boot95.s b/src/boot95.s index 0963eeb..e1fa6a6 100644 --- a/src/boot95.s +++ b/src/boot95.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 diff --git a/src/dd.s b/src/dd.s index 79aa657..89d9298 100644 --- a/src/dd.s +++ b/src/dd.s @@ -10,7 +10,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 @@ -1631,7 +1631,7 @@ ArgTemplate: dc.b 'SRC,DST,UNIT/N,START/N,COUNT/N,BS/N,US=UNITSRC/N/K,UD=UNITDST/N/K,HELP=H/S,INSPECT=I/K,VERBOSE=V/S,CMD/K',0 even -;--- command-word → name lookup ---------------------------- +;--- command-word -> name lookup ---------------------------- ; Used by INSPECT printer and the per-transfer "via " line. ; Terminated with a 0-word entry. diff --git a/src/debug95.s b/src/debug95.s index b7699db..a24c46d 100644 --- a/src/debug95.s +++ b/src/debug95.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 diff --git a/src/fat95.s b/src/fat95.s index deebc93..6c5bacc 100644 --- a/src/fat95.s +++ b/src/fat95.s @@ -9,7 +9,7 @@ ; ; This handler 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 @@ -70,8 +70,8 @@ EXTBL macro ;sign-extend byte \1 to longword ; --- 68000-only clr.l avoidance -------------------------- ; On 68000/010 clr.l does a useless dummy read of the -; destination before writing zero. 68020+ skips that read, so -; clr.l is the right choice there. Use ZCLRL via a pre-zeroed +; destination before writing zero. 68020+ skips that read, so +; clr.l is the right choice there. Use ZCLRL via a pre-zeroed ; data register so the 68000 build emits move.l Dn, while ; the 020+ build keeps native clr.l (and the binary stays ; bit-identical on that tier). @@ -148,6 +148,8 @@ WaitIO = -474 OpenResource = -498 TypeOfMem = -534 OpenLibrary = -552 +FindResident = -96 +InitResident = -102 CopyMem = -624 ;struct Node @@ -847,6 +849,7 @@ QueryResult = 80 ;embedded struct NSDeviceQueryResult ;$0200 store last read date ;$0400 convert short names to lowercase ;$0800 dito, including initial +;$1000 quiet: suppress error requesters ("q" option) ;logical partition layout BlockSize = 96 @@ -2319,6 +2322,18 @@ CloseDisk: tst.w PhysFlags(a4) beq.s cd_ok ;nothing inserted +;-- never call into ptable while dying: UnmountPartitions holds the +; partition.resource lock across the ACTION_DIE it sent us, so +; MarkAbsent here would deadlock against it (and it retires the +; resource entry itself anyway) + tst.w PleaseUnmount(a4) + bne.s cd_noabsent + bsr _sreq_diepend ;ACTION_DIE already queued? + tst.l d0 + bne.s cd_noabsent + + bsr MarkAbsentViaPtable ;media gone: clear PRESENT in partition.resource +cd_noabsent: move.l VolumeNode(a4),d0 beq.s cd_report ;disk was invalid @@ -3840,10 +3855,10 @@ ReverseL macro ;reverse longword ;--- read a little-endian word from possibly-unaligned memory --- ; ReadLE_W takes three parameters: a constant byte-offset, an address ; register holding the base, and a data register receiving the host- -; endian value. E.g. ReadLE_W 0,a0,d0 +; endian value. E.g. ReadLE_W 0,a0,d0 ; ; On 68020+ the address can be unaligned, so the read is one move.w -; plus a ReverseW. On 68000 the read must be byte-by-byte; we +; plus a ReverseW. On 68000 the read must be byte-by-byte; we ; shift-and-pack into the destination register and clear the upper ; bytes first so the macro doesn't depend on caller pre-clearing ; the register. @@ -3861,7 +3876,7 @@ ReadLE_W macro ;\3 = LE word at (\1)(\2), zero-extended endm ;--- copy a little-endian longword from (a1)+ to a host-endian -; longword field at \1(a4), using \2 as scratch on 68020+. On 68000 +; longword field at \1(a4), using \2 as scratch on 68020+. On 68000 ; we keep the original four-move.b sequence so the 68000 binary does ; not grow; on 68020+ we collapse to one move.l + ReverseL + move.l. @@ -5412,99 +5427,6 @@ SetIntParams: movem.l (sp)+,d0-d1 rts -;--- evaluate partition table ------------------------------ -; d0 <- Partition # 1..4 or 0 for "extended Partition" -; a0 <- &struct MasterBootRecord -; a2 <-> struct PartFrame (ULONG length, ULONG AbsBlock#) -; a5 <- &StackFrame (PartFrame Table) -; d0 -> absolute Block # or 0 -; d1 -> length - -GPA_TABSIZE = 256 ;32 frame entries - -GetPartition: - movem.l d2-d3/a0,-(sp) - move.w d0,d2 - bne.s gpa_1 - - moveq.l #1,d2 -gpa_1: - move.w d2,d1 - lsl.w #4,d1 - add.w #430,d1 - add.w d1,a0 ;&entry in Partition table -gpa_check: - move.b 4(a0),d1 ;Partition type - moveq.l #0,d3 - subq.b #1,d1 - beq.s gpa_fat ;$01 = FAT12 - - moveq.l #1,d3 - subq.b #3,d1 - beq.s gpa_fat ;$04 = FAT16, < 32 M - - subq.b #1,d1 - beq.s gpa_ext ;$05 = extended Partition - - subq.b #1,d1 - beq.s gpa_fat ;$06 = FAT16, >= 32 M - - moveq.l #-1,d3 - subq.b #5,d1 - beq.s gpa_fat ;$0b = FAT32, <= 2 G - - subq.b #1,d1 - beq.s gpa_fat ;$0c = FAT32, LBA - - moveq.l #1,d3 - subq.b #2,d1 - beq.s gpa_fat ;$0e = FAT16, >= 32 M, LBA - - subq.b #1,d1 - bne.s gpa_next ;$0f = extended Partition, LBA -gpa_ext: - tst.w d0 - beq.s gpa_found - bra.s gpa_next -gpa_fat: - tst.w d0 - bne.s gpa_found -gpa_next: - add.w #16,a0 - addq.w #1,d2 - cmp.w #5,d2 - bcs.s gpa_check -gpa_error: - moveq.l #0,d0 ;"not found" - bra.s gpa_end -gpa_found: - move.w d3,FATType(a4) ;Info for AutoLayout() - move.l 12(a0),d1 - ReverseL d1 ;length in Sectors - move.l 8(a0),d0 - ReverseL d0 ;relative Block # - move.l d0,HiddenBlocks(a4) ;distance off MBR -gpa_fcheck: - cmp.l (a2),d0 - bcs.s gpa_fok ;start still within current frame.. - - addq.l #8,a2 ;..or maybe within parent,.. - cmp.l a5,a2 - bcs.s gpa_fcheck - - subq.l #8,a2 ;..but at least within start frame -gpa_fok: - add.l 4(a2),d0 ;absolute Block # - move.l a5,d2 - sub.l a2,d2 ;frame table.. - cmp.w #GPA_TABSIZE+1-8,d2 - bcc.s gpa_end ;..full - - move.l d0,-(a2) - move.l d1,-(a2) ;this Partition as new frame -gpa_end: - movem.l (sp)+,d2-d3/a0 - rts ;--- validate boot block ----------------------------------- ; a0 <-> &block contents @@ -5526,7 +5448,7 @@ IsBootBlock: cmp.b #36,d1 ;..at least behind parameter block blt.s ibb_error ibb_bscheck: - ;Reject NTFS (OEM ID "NTFS " at offset 3). 3(a0) is an odd + ;Reject NTFS (OEM ID "NTFS " at offset 3). 3(a0) is an odd ;address, so a `cmp.l #"NTFS",3(a0)` would Address-Error on 68000. ;Check byte at offset 3 first, then the remaining aligned long. cmp.b #'N',3(a0) ;NTFS OEM ID byte 0.. @@ -5568,6 +5490,265 @@ ibb_error: moveq.l #0,d0 bra.s ibb_end +;=========================================================== +; ScanViaPtable - resolve the selected partition through +; ptable.library v2 + partition.resource instead of parsing the +; MBR/GPT tables here. The walker lives in exactly one binary +; (ptable.library, shipped in LIBS:); fat95 is a pure consumer, so +; cfd and fat95 share one partition-table codebase. +; +; Only the auto-detect path uses this (explicit-geometry mounts set +; SearchMode and never reach here). Hard requirement: if +; ptable.library v2 is absent, auto-detect fails (d0 = 0). +; +; In : a4 = handler base (DevName / UnitNumber / PartitionSelector set) +; Out: d0 = 1 and FirstBlock/TotalBlocks/FATType/HiddenBlocks set, or 0 +; Preserves every other register (GetDiskParams keeps d3 = disk status). +;=========================================================== +_LVOScanPartitions = -36 +_LVORegisterPartition = -54 +_LVOMarkAbsent = -60 + +;-- partition.resource / PartEntry offsets, mirror of ptable_pub.i, +; The resource ABI is append-only, fields are only ever added at the +; end (never inserted), so these offsets stay valid against any newer +; publisher. PRES_Layout below exists when the resource header's +; lib_PosSize >= 98; a value below PRES_LAYOUT_MIN means an old +; pre-v2 layout we must not touch. +PRES_PartList = 34 +PRES_Layout = 94 ;UWORD layout version stamp +PRES_LAYOUT_MIN = 2 ;oldest layout these offsets fit +PENT_Device = 14 +PENT_Unit = 18 +PENT_PartIndex = 22 +PENT_Flags = 27 +PENT_StartLBA = 32 +PENT_BlockCount = 36 +PENT_DosType = 40 +PEB_PRESENT = 0 ;pe_Flags bit: entry valid/present + +ScanViaPtable: + movem.l d1-d7/a0-a3/a5-a6,-(sp) +;-- resource-first: if our partition is already published (cfd automount +; already ran), use it directly - no device re-read, no scan. + bsr svp_pick + tst.l d0 + bne.s svp_ok +;-- nothing usable yet (no cfd automount, fat95 is the first consumer): +; bootstrap ptable, scan once to publish, then retry the lookup. + bsr _OpenPtable ;open ptable.library (ROM bootstrap if needed) + move.l d0,d7 ;d7 = ptable.library base + beq.s svp_fail + move.l d7,a6 + move.l DevName(a4),a1 + move.l UnitNumber(a4),d0 + jsr _LVOScanPartitions(a6) ;publish partitions to the resource + move.l d7,a1 + CALLEXEC CloseLibrary ;resource persists after close + bsr svp_pick + tst.l d0 + beq.s svp_fail +svp_ok: + moveq.l #1,d0 + movem.l (sp)+,d1-d7/a0-a3/a5-a6 + rts +svp_fail: + moveq.l #0,d0 + movem.l (sp)+,d1-d7/a0-a3/a5-a6 + rts + +;=========================================================== +; svp_pick - locate this handler's partition in partition.resource +; WITHOUT scanning the device. In: a4 = handler base. +; Out: d0 = 1 with FirstBlock/TotalBlocks/HiddenBlocks/FATType/PartitionNum +; set; or d0 = 0 if the resource is absent or has no usable entry. +; Only PRESENT FAT-dostype entries for DevName+Unit are eligible (a stale +; entry from a removed card has PEB_PRESENT clear and is skipped). +;=========================================================== +svp_pick: + movem.l d2-d6/a0-a3/a5-a6,-(sp) + lea PartResName2(pc),a1 + CALLEXEC OpenResource + tst.l d0 + beq.w svp_pfail + move.l d0,a2 ;a2 = partition.resource +;-- layout guard: stamps exist when the header grew past the stamp +; fields (lib_PosSize >= 98). A stamp older than what these offsets +; need means an incompatible publisher (leave the resource alone). + cmp.w #98,18(a2) ;lib_PosSize + bcs.s svp_layok ;pre-stamp publisher -> assume v2 + cmp.w #PRES_LAYOUT_MIN,PRES_Layout(a2) + bcs.w svp_pfail ;older layout -> unusable +svp_layok: +;-- target selector (1-based; 0 -> autoselect first) + moveq.l #0,d2 + move.b PartitionSelector(a4),d2 + bne.s svp_haveS + moveq.l #1,d2 +svp_haveS: +;-- pick the d2-th match (by pe_PartIndex ascending) for DevName+Unit + moveq.l #-1,d3 ;d3 = prevIdx + move.l d2,d4 ;d4 = passes remaining +svp_kpass: + sub.l a5,a5 ;a5 = best entry (0 = none) + move.l #$7fffffff,d6 ;d6 = best idx + lea PRES_PartList(a2),a0 + move.l (a0),a1 ;a1 = first node +svp_walk: + move.l (a1),d0 ;ln_Succ + beq.s svp_passend ;tail sentinel + move.l UnitNumber(a4),d1 + cmp.l PENT_Unit(a1),d1 + bne.s svp_wnext + move.l PENT_Device(a1),a0 ;compare device name (C-strings) + move.l DevName(a4),a3 +svp_sc: + move.b (a0)+,d0 + cmp.b (a3)+,d0 + bne.s svp_wnext + tst.b d0 + bne.s svp_sc +;-- only PRESENT FAT-dostype entries count: the unified scanner also +; publishes RDB entries (DOS\x, PFS\x, ...) a FAT handler must not pick, +; and absent entries from a removed card must be skipped too + move.l PENT_DosType(a1),d1 + and.l #$ffffff00,d1 + cmp.l #"FAT"<<8,d1 + bne.s svp_wnext + btst #PEB_PRESENT,PENT_Flags(a1) + beq.s svp_wnext + move.l PENT_PartIndex(a1),d1 ;matched dev+unit: rank by index + cmp.l d3,d1 + ble.s svp_wnext ;idx <= prevIdx (already taken), signed: -1 < all + cmp.l d6,d1 + bge.s svp_wnext ;idx >= best (not smaller) + move.l d1,d6 + move.l a1,a5 +svp_wnext: + move.l (a1),a1 ;ln_Succ + bra.s svp_walk +svp_passend: + move.l a5,d0 + beq.s svp_pfail ;fewer than d2 matches -> not found + move.l d6,d3 ;prevIdx = best idx + subq.l #1,d4 + bne.s svp_kpass +;-- a5 = selected partition entry + move.l PENT_StartLBA(a5),FirstBlock(a4) + move.l PENT_BlockCount(a5),TotalBlocks(a4) + clr.l HiddenBlocks(a4) + move.w #2,FATType(a4) ;auto width (refined from the boot block) + move.w d2,PartitionNum(a4) + moveq.l #1,d0 + movem.l (sp)+,d2-d6/a0-a3/a5-a6 + rts +svp_pfail: + moveq.l #0,d0 + movem.l (sp)+,d2-d6/a0-a3/a5-a6 + rts + +;=========================================================== +; PublishViaPtable - register this device/unit in partition.resource. +; First ScanPartitions publishes the device's partitions as candidates +; (synthetic names, not mounted); then RegisterPartition overlays the volume +; this handler actually serves with its real DOS name (dn_Name) + mounted +; state, so an explicitly mounted volume shows e.g. "MS" instead of the +; synthesized automount name. Silent no-op if ptable.library is absent. +; In : a4 = handler base (DevName / UnitNumber / FirstBlock / TotalBlocks +; / DeviceNode set) +;=========================================================== +PublishViaPtable: + movem.l d0-d4/a0-a3/a6,-(sp) ;save working registers + bsr _OpenPtable ;open ptable.library (ROM bootstrap if needed) + move.l d0,a3 ;a3 = ptable.library base + beq.w pvp_done +;-- publish candidates. ScanViaPtable already did this on the +; partitioned path (PartitionNum != 0); scan here only for the +; superfloppy path (PartitionNum == 0). + tst.w PartitionNum(a4) + bne.s pvp_overlay + move.l a3,a6 + move.l DevName(a4),a1 + move.l UnitNumber(a4),d0 + jsr _LVOScanPartitions(a6) +pvp_overlay: +;-- overlay the served volume with its real DOS name + mounted state + move.l DeviceNode(a4),d0 ;our DOS DeviceNode + beq.s pvp_close ;no node -> skip + move.l d0,a2 ;a2 = devNode + move.l DOL_Name(a2),d0 ;BPTR dn_Name + beq.s pvp_close ;no name -> skip + lsl.l #2,d0 + move.l d0,a0 ;a0 = name BSTR + move.l DevName(a4),a1 + move.l UnitNumber(a4),d0 + move.l FirstBlock(a4),d1 + move.l TotalBlocks(a4),d2 + move.l DeviceFlags(a4),d3 ;flags we opened the device with + move.l EnvecBuf+DE_Control(a4),d4 ;de_Control BPTR (0 = none) + lsl.l #2,d4 ;-> APTR to control BSTR + move.l a3,a6 ;a6 = ptable base (a3 kept for CloseLibrary) + jsr _LVORegisterPartition(a6) +pvp_close: + move.l a3,a1 + CALLEXEC CloseLibrary +pvp_done: + movem.l (sp)+,d0-d4/a0-a3/a6 + rts + +;=========================================================== +; MarkAbsentViaPtable - on disk close/eject, clear PEB_PRESENT on this +; device+unit's partition.resource entries. The DOS node + handler stay. +; In : a4 = handler base (DevName / UnitNumber set). Preserves all registers. +;=========================================================== +MarkAbsentViaPtable: + movem.l d0-d2/a0-a3/a6,-(sp) + bsr _OpenPtable ;open ptable.library (ROM bootstrap if needed) + move.l d0,a3 ;a3 = ptable.library base + beq.s mav_done + move.l DevName(a4),a1 + move.l UnitNumber(a4),d0 + move.l a3,a6 + jsr _LVOMarkAbsent(a6) + move.l a3,a1 + CALLEXEC CloseLibrary +mav_done: + movem.l (sp)+,d0-d2/a0-a3/a6 + rts + +;=========================================================== +; _OpenPtable - OpenLibrary("ptable.library", v2); if not open, +; FindResident + InitResident it from ROM and retry. +; In : a4 = handler base (CALLEXEC reads ExecBase from it) +; Out: d0 = ptable.library base, or 0 if unavailable. +; Trashes d0/d1/a0/a1/a6. +;=========================================================== +_OpenPtable: + moveq.l #2,d0 + lea PtableLibName(pc),a1 + CALLEXEC OpenLibrary + tst.l d0 + bne.s _op_ret ;already open + lea PtableLibName(pc),a1 + CALLEXEC FindResident + tst.l d0 + beq.s _op_ret ;not in ROM -> d0 = 0 + move.l d0,a1 + sub.l a0,a0 ;segList = none + moveq.l #0,d1 + CALLEXEC InitResident + moveq.l #2,d0 + lea PtableLibName(pc),a1 + CALLEXEC OpenLibrary +_op_ret: + rts + +PtableLibName: + dc.b "ptable.library",0 +PartResName2: + dc.b "partition.resource",0 + even + ;--- read disk layout -------------------------------------- ; -> flags: Bit.. ; 0 = disk inserted @@ -5576,7 +5757,7 @@ ibb_error: ; 3 = boot block OK GetDiskParams: - link.w a5,#-GPA_TABSIZE + link.w a5,#0 ;no stack locals movem.l d2-d7/a2,-(sp) ;GPT path uses d5/d6/d7 too ;- - general check - - - - - - - - - - - - - - - - - - - - - @@ -5653,233 +5834,24 @@ gdp_notforeign: clr.w PartitionNum(a4) bsr IsBootBlock tst.w d0 - bne.w gdp_bootfound ;unpartitioned volume + beq.s gdp_chkpart ;no boot block -> try partition table + bra.w gdp_bootfound ;unpartitioned volume +gdp_chkpart: tst.b SearchMode(a4) bne.w gdp_ndos ;set manually, dont search -;- - check for GPT partition table - - - - - - - - - - - - - - ; - ; GPT Detection Flow: - ; ~~~~~~~~~~~~~~~~~~~ - ; MBR block 0 loaded (a0) - ; | - ; Check partition type 0xEE (protective MBR)? - ; |-- No --> gdp_mbr_search (normal MBR parsing) - ; | - ; Yes - ; | - ; Read LBA 1 (GPT header) - ; | - ; Check "EFI PART" signature - ; | - ; Scan partition entries for FAT GUID (EBD0A0A2-...) - ; | - ; Mount partition --> gdp_bootfound - ; - ;a0 still points to block 0 (MBR) - ;Check if first partition entry is type 0xEE (protective MBR for GPT) - cmp.b #$EE,446+4(a0) ;partition type at offset 446+4 - bne.w gdp_mbr_search ;not GPT, try MBR - - ;Protective MBR found - save d3 (disk status) and read GPT header - move.w d3,-(sp) ;save disk status (contains write-protect flag) - addq.b #1,SearchCount(a4) - moveq.l #1,d0 ;LBA 1 = GPT header - bsr ReadSingle ;FirstBlock is 0 here - tst.l d0 - beq.w gdp_gpt_cleanup ;read failed - - move.l d0,a1 ;&GPT header - cmp.l #"EFI ",(a1) ;check "EFI PART" signature - bne.w gdp_gpt_cleanup - cmp.l #"PART",4(a1) - bne.w gdp_gpt_cleanup - - ;GPT header valid - get partition entry info - move.l 72(a1),d4 ;Partition entries LBA low (little-endian) - ReverseL d4 - move.l 76(a1),d0 ;Partition entries LBA high - tst.l d0 - bne.w gdp_gpt_cleanup ;beyond 32-bit addressing - move.l 80(a1),d5 ;Number of partition entries (little-endian) - ReverseL d5 - move.l 84(a1),d6 ;Size of partition entry (little-endian) - ReverseL d6 - tst.w d6 - beq.w gdp_gpt_cleanup ;invalid entry size - - ;Get requested partition number - moveq.l #0,d2 - move.b PartitionSelector(a4),d2 - bgt.s gdp_gpt_p1 - moveq.l #1,d2 ;autoselect first FAT partition -gdp_gpt_p1: - move.w d2,PartitionNum(a4) - subq.w #1,d2 ;convert to 0-based index - bmi.w gdp_gpt_cleanup ;invalid partition number - - ;Scan GPT entries for FAT partition - moveq.l #0,d7 ;FAT partition counter - moveq.l #0,d0 ;current entry index (32-bit) -gdp_gpt_loop: - cmp.l d5,d0 ;scanned all entries? (32-bit index vs count) - bcc.w gdp_gpt_cleanup ;not found - - ;Calculate LBA and byte-offset for this entry - move.l d0,-(sp) ;save entry index - move.l d6,d1 ;d1 = entry size - UMUL32 ;d0 = entry_idx * entry_size (byte offset) - moveq.l #0,d1 - move.w BlockSize(a4),d1 ;BlockSize fits in 16 bits (512..4096) - UDIVMOD32 ;d0 = block offset (quot), d1 = byte offset in block (rem) - move.l d1,d3 ;d3 = byte offset within block - add.l d4,d0 ;d0 = absolute LBA - - ;Read block containing this entry (SingleBuf cache absorbs repeats) - bsr ReadSingle - move.l (sp)+,d1 ;restore entry index to d1 temporarily - tst.l d0 ;check if read succeeded - beq.w gdp_gpt_cleanup ;read failed - move.l d0,a1 ;block data - move.l d1,d0 ;restore entry index to d0 - - add.w d3,a1 ;a1 = &partition entry (d3 < BlockSize, fits pos. word) - - ;Check if entry is used (GUID not all zeros) - tst.l (a1) - beq.s gdp_gpt_next ;unused entry - - ;Check partition type GUID (full 16 bytes) against FAT-carrying GUIDs: - ; EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 Microsoft Basic Data - ; C12A7328-F81F-11D2-BA4B-00A0C93EC93B EFI System Partition - ; - ;Outer dbra loop over gdp_gpt_guids table (d1 = remaining GUIDs - 1). - ;Inner dbne loop: a3 walks entry GUID, a0 walks table; branches while - ;equal (Z=1), falls through on first mismatch (Z=0) without decrementing - ;d3, so lsl.l #2,d3 / add.l d3,a0 skips the unread longs of that table - ;entry and leaves a0 at the start of the next one for the outer loop. - lea gdp_gpt_guids(pc),a0 - moveq.l #1,d1 ;outer counter: 2 GUIDs (0-based for dbra) -gdp_gpt_cmp_outer: - move.l a1,a3 ;reset entry GUID scan pointer - moveq.l #3,d3 ;inner counter: 4 longs per GUID -gdp_gpt_cmp_inner: - cmpm.l (a3)+,(a0)+ - dbne d3,gdp_gpt_cmp_inner ;branch while equal; fall through on mismatch - beq.s gdp_gpt_match ;all 4 longs matched -> FAT partition - lsl.l #2,d3 ;bytes remaining in this table GUID - add.l d3,a0 ;skip to start of next table GUID - dbra d1,gdp_gpt_cmp_outer ;try next GUID; fall through when exhausted - bra.s gdp_gpt_next - -gdp_gpt_guids: - dc.l $A2A0D0EB,$E5B93344,$87C068B6,$B72699C7 ;MS Basic Data - dc.l $28732AC1,$1FF8D211,$BA4B00A0,$C93EC93B ;EFI System Partition - -gdp_gpt_match: - ;Found FAT partition - is it the one we want? - cmp.w d2,d7 ;d7 = FAT partition counter, d2 = requested index - beq.s gdp_gpt_found - addq.w #1,d7 ;next FAT partition -gdp_gpt_next: - addq.l #1,d0 ;next entry (32-bit) - bra.w gdp_gpt_loop - -gdp_gpt_found: - ;Get partition start and end LBA (little-endian, 64-bit) - move.l 32(a1),d0 ;First LBA low - ReverseL d0 - move.l 36(a1),d1 ;First LBA high - bne.s gdp_gpt_cleanup ;beyond 32-bit addressing - - move.l 40(a1),d1 ;Last LBA low - ReverseL d1 - move.l 44(a1),d3 ;Last LBA high - tst.l d3 - bne.s gdp_gpt_cleanup ;beyond 32-bit addressing - - ;Verify partition end is within 32-bit range BEFORE touching - ;any global state - a failed Test64 must not leave half-written - ;FirstBlock/TotalBlocks/HiddenBlocks visible to the caller. - sub.l d0,d1 - addq.l #1,d1 ;size = last - first + 1 - move.l d0,d2 ;save first LBA across Test64 - add.l d1,d0 - subq.l #1,d0 - bsr Test64 +;- - delegate partition lookup to ptable.library + resource - + bsr ScanViaPtable ;d0 = 1 found -> FirstBlock/TotalBlocks set tst.l d0 - beq.s gdp_gpt_cleanup ;partition exceeds 4 Gbyte - - ;Range OK - commit partition info to globals - move.w #2,FATType(a4) ;auto-detect FAT type - move.l d2,FirstBlock(a4) - move.l d1,TotalBlocks(a4) - clr.l HiddenBlocks(a4) - - ;Restore d3 and use shared boot block validation - move.w (sp)+,d3 ;restore disk status - bra.s gdp_readboot ;share boot block code with MBR path - -gdp_gpt_cleanup: - addq.l #2,sp ;discard saved d3 - bra.w gdp_none ;partition not found = no disk - -;- - search MBR partition - - - - - - - - - - - - - - - - - -gdp_mbr_search: - move.l a5,a2 ;&frame table - clr.l -(a2) ;start frame: from beginning.. - moveq.l #-1,d0 - move.l d0,-(a2) ;..to end - moveq.l #0,d2 - move.b PartitionSelector(a4),d2 - bgt.s gdp_p1 ;invalid MountList entry.. - - moveq.l #1,d2 ;..autoselect first FAT-partition -gdp_p1: - move.w d2,PartitionNum(a4) - subq.w #5,d2 - bcc.s gdp_plog ;logical partition requested - - addq.w #5,d2 - move.w d2,d0 - bsr GetPartition - move.l d0,d4 - bne.s gdp_pfound ;found primary partition - - moveq.l #0,d2 -gdp_plog: - moveq.l #0,d0 - bsr GetPartition - move.l d0,d4 - beq.w gdp_none ;partition not found = no disk - - bsr Test64 - tst.l d0 - beq.w gdp_none ;..or beyond 4 Gbyte - - addq.b #1,SearchCount(a4) - move.l d4,d0 - bsr ReadSingle ;read next partition table - tst.l d0 - beq.w gdp_ndos - - move.l d0,a0 - subq.w #1,d2 - bpl.s gdp_plog ;skip this logical partition - - moveq.l #1,d0 - bsr GetPartition - tst.l d0 ;partition not in expected place,.. - beq.s gdp_plog ;..search on below -gdp_pfound: - move.l d0,FirstBlock(a4) - move.l d1,TotalBlocks(a4) - add.l d1,d0 + beq.w gdp_none + move.l FirstBlock(a4),d0 + add.l TotalBlocks(a4),d0 subq.l #1,d0 bsr Test64 tst.l d0 beq.w gdp_none ;partition exceeds 4 Gbyte + bra.w gdp_readboot gdp_readboot: ;shared entry point for GPT addq.b #1,SearchCount(a4) @@ -5941,6 +5913,7 @@ gdp_bootfound: MoveLE32_BE TotalBlocks,d0 ;if >= 64K gdp_2: + bsr PublishViaPtable ;FirstBlock/TotalBlocks final: register volume tst.w RootDirEntries(a4) bne.s gdp_3 @@ -6436,6 +6409,40 @@ SafeDoIO: movem.l (sp)+,d2-d7/a2-a5 rts +;-- ProbeTD64: some drivers accept NSCMD_TD_READ64 but do not advertise it +; via NSCMD_DEVICEQUERY. When a >4GB device has not flagged TD64, try a +; single NSCMD_TD_READ64 read of block 0; if the device accepts it, +; mark TD64 available so the >4GB path uses it instead of fallinclaude g back +; to HD_SCSICMD (which IDE rejects). +; Preserves d2 (the command being built in DiskGeometry) and a4. +ProbeTD64: + movem.l d0-d1/a0-a2/a6,-(sp) + move.l #512,d0 + move.l #MEMF_PUBLIC,d1 + CALLEXEC AllocMem + tst.l d0 + beq.s ptd_done ;no mem -> leave TD64 bit clear + move.l d0,a2 ;a2 = scratch buffer + move.l DiskRequest(a4),a1 + move.w #NSCMD_TD_READ64,IO_Command(a1) + clr.b IO_Error(a1) + clr.l IO_Actual(a1) ;high 32 bits = 0 + clr.l IO_Offset(a1) ;low 32 bits = 0 (block 0) + move.l #512,IO_Length(a1) + move.l a2,IO_Data(a1) + bsr SafeDoIO ;a1 = IO request + move.l DiskRequest(a4),a1 + tst.b IO_Error(a1) + bne.s ptd_free ;rejected -> not supported + or.w #2,CmdFlags(a4) ;accepted -> TD64 available +ptd_free: + move.l a2,a1 + move.l #512,d0 + CALLEXEC FreeMem +ptd_done: + movem.l (sp)+,d0-d1/a0-a2/a6 + rts + DiskChangeNum: btst #0,CmdFlags+1(a4) beq.s dcn_end ;ETD commands unavailable @@ -6455,12 +6462,12 @@ DiskMotorOff: move.l DiskRequest(a4),a1 move.w #TD_MOTOR,IO_Command(a1) clr.l IO_Length(a1) - bra.s SafeDoIO + bra.w SafeDoIO DiskClear: move.l DiskRequest(a4),a1 move.w #CMD_CLEAR,IO_Command(a1) - bra.s SafeDoIO + bra.w SafeDoIO DiskUpdate: btst #3,CmdFlags+1(a4) @@ -6745,8 +6752,11 @@ dge_cmd1: beq.s dge_cmd2 ;..and if > 4 Gbyte.. btst #1,CmdFlags+1(a4) - beq.s dge_cmd2 ;..prefer TD64 commands.. - + bne.s dge_usetd64 ;..prefer TD64 commands.. + bsr ProbeTD64 ;>4GB but TD64 not advertised: try it + btst #1,CmdFlags+1(a4) + beq.s dge_cmd2 ;still none -> CMD/ETD (Test64 -> SCSI) +dge_usetd64: move.l #NSCMD_TD_READ64<<16+NSCMD_TD_WRITE64,d2 dge_cmd2: move.l d2,ReadCmd(a4) @@ -8222,7 +8232,7 @@ xtd_i2: tst.l XL_Parent(a0) bne.s xtd_idone ; Microsoft FAT spec: when the parent is the root, ".." must hold -; cluster 0, not the actual root cluster. Linux and Windows +; cluster 0, not the actual root cluster. Linux and Windows ; tolerate either form, but fsck.vfat flags the non-zero variant ; on FAT32 volumes. clr.w MSDE_Sizeof+MSDE_1L(a2) @@ -9110,7 +9120,7 @@ rf_scan: tst.w FATType(a4) beq.s rf_count ;FAT12: keep the GetFATEntry-based scan -; FAT16 fast path -- the on-disk entry is a little-endian word; 0 +; FAT16 fast path - the on-disk entry is a little-endian word; 0 ; means free regardless of byte order, so we can skip the per-cluster ; GetFATEntry call (saves a bsr + ReverseW + cmp for every cluster). move.l FATBuffer(a4),a0 @@ -9200,6 +9210,10 @@ ScanFAT32: addq.l #1,d5 sub.l d2,d5 ;# entries to go sf32_block: + tst.w DiskChanged(a4) ;card gone/swapped.. + bne.s sf32_abort ;..abandon the scan, dont read + tst.w PleaseUnmount(a4) ;unmount latched.. + bne.s sf32_abort ;..abandon the scan move.l d2,d0 moveq.l #0,d1 bsr MoveFATWindow @@ -9233,7 +9247,9 @@ sf32_next: ble.s sf32_finished ;all done!!! tst.w DiskChanged(a4) - bne.s sf32_end ;on disk change or.. + bne.s sf32_abort ;on disk change: abandon (dont reschedule) + tst.w PleaseUnmount(a4) + bne.s sf32_abort ;unmount latched: abandon move.l pr_MsgPort(a4),a0 add.w #MP_MsgList,a0 @@ -9247,6 +9263,15 @@ sf32_end: movem.l (sp)+,d2-d6 rts +;-- card gone or unmount in progress: stop validating for good so the idle +; loop can reach IdentifyDisk (media swap) or teardown (unmount). Unlike +; sf32_end this clears BackgroundJob instead of rescheduling, and unlike +; sf32_finished it leaves DiskState alone (re-derived on the change signal). +sf32_abort: + clr.l BackgroundJob(a4) + movem.l (sp)+,d2-d6 + rts + sf32_finished: clr.l BackgroundJob(a4) ;work done. moveq.l #ID_WRITE_PROT,d0 @@ -9739,9 +9764,9 @@ xch_add: move.l LastCluster(a4),d3 addq.l #1,d3 ; Watchdog: at most (LastCluster - 1) data clusters exist, so the -; wrap-around scan visits each one at most once. If FreeClusters +; wrap-around scan visits each one at most once. If FreeClusters ; is stale (e.g. FAT read errors filled the buffer with the "end -; of chain" placeholder) we'd otherwise spin forever -- catch it +; of chain" placeholder) we'd otherwise spin forever - catch it ; here and report disk full instead. move.l d3,d5 subq.l #2,d5 @@ -11350,6 +11375,7 @@ so_tab: dc.b 9,"D" dc.b 10,"L" dc.b 11,"l" + dc.b 12,"q" dc.w 0 ;--- local vars for ScanDisk() and SecurityErase() --------- @@ -12561,6 +12587,18 @@ DoRequest: link.w a5,#DREQ_TEXT2 move.l a2,-(sp) sub.l a2,a2 ;default: no parent window +;-- single-task handler: an open requester blocks the packet loop. +; Never requester once ACTION_DIE is latched or already queued on +; the port (teardown must not stall, and follow-up errors during +; it - e.g. the CloseDisk flush - must stay silent), or when the +; mount is configured quiet ("q" option). + tst.w PleaseUnmount(a4) + bne.w dreq_abort + bsr _sreq_diepend ;DIE waiting? -> no new UI either + tst.l d0 + bne.w dreq_abort + btst #4,CmdFlags(a4) ;word bit 12 = quiet + bne.w dreq_abort move.l DosPacket(a4),d0 beq.s dreq_case ;no order @@ -12656,7 +12694,7 @@ dreq_repeat: pea DREQ_POSTEXT(a5) pea DREQ_TEXT1(a5) ;&request text move.l a2,-(sp) ;&parent window - bsr _AutoRequest + bsr _SysRequest ;interruptible: DIE cancels, change retries add.w #32,sp cmp.b #TDERR_DISKCHANGED,8+3(a5) bne.s dreq_end ;"normal" read error @@ -13286,6 +13324,102 @@ _Permit: ;*** from intuition.library ******************************** +;--- interruptible system requester ------------------------- +; Same stack args as _AutoRequest (window, body, pos, neg, pFlag, +; nFlag, width, height). Unlike AutoRequest it also waits on the +; handler's own packet port while the requester is up: a queued +; ACTION_DIE cancels the requester (-> 0 "abort"), unconditionally +; and independent of the "q" option - the unmount must never wait +; for a human. Anything else keeps the requester up; gadget clicks +; behave exactly like AutoRequest (1/0). +; Falls back to the blocking _AutoRequest on pre-V36 intuition. +_SysRequest: + move.l IntBase(a4),d0 + beq.w _sreq_noui ;no intuition -> "abort" + move.l d0,a6 + cmp.w #36,LIB_Version(a6) + bcs.w _AutoRequest ;tail call: same stack args + movem.l d2-d3/a2-a3,-(sp) + movem.l 20(sp),a0-a3 ;window/body/posText/negText + moveq.l #0,d0 ;no extra IDCMP flags + move.l 44(sp),d1 ;width + move.l 48(sp),d2 ;height + jsr -360(a6) ;BuildSysRequest + moveq.l #1,d1 + cmp.l d1,d0 + bls.s _sreq_done ;0/1: intuition fallback = the answer + move.l d0,a2 ;a2 = requester window +_sreq_wait: +;-- test for a queued ACTION_DIE BEFORE sleeping: its port signal may +; already be consumed (by an earlier Wait), so testing only after +; Wait would sleep forever on a packet that is already there + bsr.s _sreq_diepend + tst.l d0 + bne.s _sreq_die + move.l 86(a2),a0 ;wd_UserPort + moveq.l #0,d0 + moveq.l #0,d1 + move.b MP_SigBit(a0),d1 + bset d1,d0 + move.l pr_MsgPort(a4),a0 ;handler port: packets + change int + move.b MP_SigBit(a0),d1 + bset d1,d0 + move.l ExecBase(a4),a6 + jsr Wait(a6) + move.l IntBase(a4),a6 + move.l a2,a0 + sub.l a1,a1 ;no IDCMP result wanted + moveq.l #0,d0 ;dont wait inside the handler call + jsr -600(a6) ;SysReqHandler + tst.l d0 + bmi.s _sreq_wait ;no click yet: re-test DIE, re-wait + bra.s _sreq_answer ;0/1 = gadget clicked +_sreq_die: + moveq.l #0,d0 ;dying -> "abort", no interaction +_sreq_answer: + move.l d0,d3 ;answer survives FreeSysRequest + move.l IntBase(a4),a6 + move.l a2,a0 + jsr -372(a6) ;FreeSysRequest + move.l d3,d0 +_sreq_done: + movem.l (sp)+,d2-d3/a2-a3 + rts +_sreq_noui: + moveq.l #0,d0 + rts + +;-- is an ACTION_DIE packet waiting on the handler port? +; -> d0 = 1 yes / 0 no. Preserves a2/a6-relative state of the caller. +_sreq_diepend: + movem.l a0-a1/a6,-(sp) + move.l ExecBase(a4),a6 + jsr Forbid(a6) + move.l pr_MsgPort(a4),a0 + move.l MP_MsgList(a0),a0 ;lh_Head +_srdp_walk: + move.l (a0),d0 ;ln_Succ (0 = tail sentinel) + beq.s _srdp_no + move.l LN_Name(a0),d1 ;&DosPacket + beq.s _srdp_next + move.l d1,a1 + moveq.l #5,d1 ;ACTION_DIE + cmp.l DP_Type(a1),d1 + beq.s _srdp_yes +_srdp_next: + move.l d0,a0 + bra.s _srdp_walk +_srdp_yes: + jsr Permit(a6) + moveq.l #1,d0 + movem.l (sp)+,a0-a1/a6 + rts +_srdp_no: + jsr Permit(a6) + moveq.l #0,d0 + movem.l (sp)+,a0-a1/a6 + rts + _AutoRequest: movem.l d2-d3/a2-a3,-(sp) movem.l 20(sp),a0-a3 diff --git a/src/fat95_version.i b/src/fat95_version.i index c832a1c..c1d873a 100644 --- a/src/fat95_version.i +++ b/src/fat95_version.i @@ -1,10 +1,10 @@ ; Auto-generated by Makefile. -FILE_VERSION = 3 -FILE_REVISION = 24 +FILE_VERSION = 4 +FILE_REVISION = 0 VERSION_STRING macro ifd __68020__ - dc.b "$VER: fat95 3.24 (07.06.2026) [68020]" + dc.b "$VER: fat95 4.0-dev (30.07.2026) [68020]" else - dc.b "$VER: fat95 3.24 (07.06.2026) [68000]" + dc.b "$VER: fat95 4.0-dev (30.07.2026) [68000]" endc endm diff --git a/src/install95.s b/src/install95.s index ea3656e..c60fb9d 100644 --- a/src/install95.s +++ b/src/install95.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 diff --git a/src/lsfsres.s b/src/lsfsres.s index dc84b34..d8dc9c3 100644 --- a/src/lsfsres.s +++ b/src/lsfsres.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. ; --- Includes --- @@ -81,7 +81,7 @@ ROM_EXT_HI = $00E80000 ;--- global vars (stack frame) ----------------------------- ; LINK allocates `VarsSize` bytes below a4. Offsets below are arranged ; so the larger buffers (Argv, NameBuf) live further from a4 than the -; scalar pointers above them — no overlap. +; scalar pointers above them. ExecBase = -4 ;long DosBase = -8 ;long @@ -143,7 +143,7 @@ s_loop: ; [1] = DosType (%08lx) ; [2] = pointer to 4-char ASCII (%s) ; [3] = Version (%08lx) - ; [4] = PatchFlags (%04lx) -- low 16 bits printed + ; [4] = PatchFlags (%04lx) - low 16 bits printed ; [5] = SegList byte address (%08lx) ; [6] = pointer to "[ROM]"/"[RAM]" (%s) ; [7] = pointer to Name string (%s) diff --git a/src/setfilesize.s b/src/setfilesize.s index 38feb91..3480bf3 100644 --- a/src/setfilesize.s +++ b/src/setfilesize.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