Implement some missing Hyppo DOS traps, with long filename support - #946
Open
psnr wants to merge 1 commit into
Open
Implement some missing Hyppo DOS traps, with long filename support#946psnr wants to merge 1 commit into
psnr wants to merge 1 commit into
Conversation
Several DOS trap slots were bare labels sharing a single
jmp invalid_subfunction, so calling them just reported an invalid
sub-function. This fills some of them in, finishes fstat, and extends
mkfile. All of them follow the existing convention: sub-function in
A, STA $D640, then CLV, and carry clear on return means failure with a
reason in dos_geterrorcode (A=$38).
A=$08 getdisksize Y = destination page. Fills $YY00 with the fields
already tracked in dos_disk_table: sectors per
cluster, cluster count, FAT size and so on. It
does not count free clusters, which would mean a
full FAT scan.
A=$0A getcwd Y = destination page. $YY00 = drive number,
$YY01 = offset of a NUL-terminated path within
the same page. Resolved on demand by walking the
cwd up to the root - there is no persistent path
to go stale, so the answer is right however the
cwd got where it is.
A=$0E mkdir Name via setname (A=$2E) first. Creates a
sub-directory in the cwd, with its own "." and
".." entries. Fails with file_exists if the name
is taken.
A=$10 rmdir Name via setname first. Refuses anything that is
not a directory, or a directory holding more than
"." and "..".
A=$1E mkfile Already worked for 8.3 names, contiguous
allocation and all. Now runs the name through the
long-name path, reserving the extra dirent slots
the VFAT pieces need rather than the single slot
it used to take.
A=$24 seekfile X/Y/Z = 24-bit sector number within the open
file. Walks the cluster chain forward without
transferring any data, which is the cheap way to
reach a sector - reading there instead would move
every byte in between. FAT32 chains are singly
linked, so seeking is always from the start, and
there is no length to bounds-check against: going
past the end fails when the chain runs out.
A=$28 fstat Existed, but never called
hypervisor_setup_copy_region, so it wrote through
whatever destination the previous trap had
established - after the usual setname + findfile
that is the caller's filename buffer - and
ignored its own Y. Now Y = destination page for
the raw 32-byte dirent.
A=$2A rename Renames the open file, or the open directory from
opendir. A name that still fits 8.3 is rewritten
in place; one that needs VFAT pieces moves the
entry to a large enough run of free slots. Either
way the attributes, dates, cluster and length are
carried across untouched.
Long filenames
--------------
Hyppo could already read long names - dos_readdir has understood VFAT
pieces for a long time, behind the enable switch that syspart patches
into disable_lfn_byte. What it could not do is create them, so anything
Hyppo wrote got a plain 8.3 name regardless.
That side is now implemented: pieces are written with their checksum,
short names are built by truncating and appending ~1 through ~9 until
one does not collide with an existing entry, the preceding pieces are
removed when a file is deleted, and rename relocates an entry when the
new name needs more slots than the old one occupied. getcwd returns the
long name of each level where there is one.
The existing switch still governs all of it. With long names disabled
every path falls back to 8.3, and so do entries that have no long name
or whose pieces fail their checksum against the short entry - a stale
chain is ignored rather than trusted.
One consequence worth knowing: a path segment can now be 64 characters
instead of 12, so getcwd's 255-byte buffer can be exhausted at about
four levels rather than nineteen. It checks before writing and returns
dos_errorcode_path_too_long, an error code that has been defined and
unused until now.
Freeze and unfreeze
-------------------
A task's current directory is now carried across a freeze in the process
descriptor. Previously, a task frozen in one directory always resumed in
the root directory. Now saving cwd on freeze and on resume the saved cluster
is only trusted if the directory is still listed in its parent, since
removing a directory leaves its own "." and ".." intact and a freed cluster
may since have been handed to a file. If it has gone, its parent is tried
in turn.
Other changes / Hyppo space usage
---------------------------------
The 4510's 16-bit relative branches replace the branch-over-jmp idiom in
twenty places, buying back 43 bytes. Even so, this uses up most of what
hyppo had left: the space below DOSDiskTable_Start goes from about 1.6KB
free to 38 bytes. ACME is now run with --strict-segments, because the
fixed data areas from $BB00 up are placed by winding * backwards, and it
otherwise only warns once code has already grown into them.
Are these changes worth the space it takes up? Do we want to use the space
available to other traps instead?
Tests
-----
hyppotest could not execute the branches: of the ten opcodes only BCC
was both present and correct, four took their displacement from the low
byte alone and four were missing entirely.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fills in several Hyppo DOS trap slots (getdisksize, getcwd, mkdir, rmdir, seekfile, rename), finishes fstat, and extends mkfile with long-filename support.
Also adds writing of VFAT long names (Hyppo could already read them, not create them), and fixes the current working directory not being carried across a freeze.
See the commit message for full details on each trap.
Tested on MEGA65 R6 hardware: all new traps, long filenames enabled and
disabled, and freeze/resume across getcwd/mkdir/rmdir/rename including with
directories deleted or renamed out from under a frozen task's saved cwd.
Note on headroom: this uses up most of what Hyppo had left below the
fixed data area — free space there drops from roughly 1.6KB before this
branch to about 38 bytes now.