Repository navigation
Do not write a refused MFM track into the space of another one (#921) - #967
Open
enver-haase wants to merge 1 commit into
Open
enver-haase wants to merge 1 commit into
enver-haase wants to merge 1 commit into
Conversation
MfmDisk::UpdateTrack() assigns the file position only when it accepts the track, and returns -1 for a track or side out of range and -2 when the decoded sectors need more room than the image reserved. WRITE TRACK ignored that return value and wrote newTrack.actualDataSize bytes at 'offset' regardless, and on a refusal 'offset' still held whatever the command before had left there. So a format the image could not hold overwrote a different track's data. The format is lost either way; the data that was there need not be. The completion now writes nothing when the track was refused, and says which track it was and by how much it missed. Where the refusal is knowable before the transfer, WRITE TRACK is refused when it arrives: a track the image reserved no space for can never be stored, whatever the drive sends. That is also the only moment at which the drive can be told, since both the 1571 and the 1581 leave their byte loop when busy drops and report the command as failed, while neither reads the status after a WRITE TRACK that ran to the end. Lost data is the status the data sheet defines for this command; record not found, which this file uses on the read paths, is undefined for it. Lost data is now cleared per command beside record not found, as the data sheet has both reset when updated, so the bit cannot be read as the outcome of the command after the one that set it. New E2E suite g71-mfm-format-refused: a G71 whose cylinder 35 is 4000 bytes, cylinder 36 a full track and cylinder 37 100 bytes, each formatted from the C64 with the 1571's partial burst format, nine 512-byte sectors. Cylinder 36 is the control and has to show up in the image file. Cylinders 35 and 37 have to stay as they were, and the drive has to answer after the refusal on arrival. On 3.15a cylinder 35's header says nine MFM sectors whose data was never stored, and cylinder 37 is marked MFM and holds the refused fill byte. The write at the stale position into another track goes to the drive's copy of the image, which a C64 cannot read back, so the suite does not see that part. Refs GideonZ#921.
Contributor
Author
|
Green, same Ultimate II+L and C64: v3.15a plus only this PR's On cylinder 37, the 1571 takes lost data on arrival as |
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.
Fixes #921.
What was wrong
MfmDisk::UpdateTrack()assigns the file position only when it accepts a track, and returns -1 for a track or side out of range and -2 when the decoded sectors need more room than the image reserved. The WRITE TRACK completion ignored that: it wrote the sectors atoffset, which on a refusal still held whatever the previous command had left there, and then had the track recorded as formatted. So a format the image could not hold went into another track's space, and the image claimed a format that was never stored.The fix (
software/drive/wd177x.cconly)UpdateTrack()refuses the track, nothing is written and the track is not recorded; the log says which track and by how much it missed. The drive cannot be told at this point, since it read the status when busy dropped (Firmware-side write failures never reach the drive CPU: the WD177x block clears BUSY 64 us after the last byte #937).Test
New E2E suite
g71-mfm-format-refused(tests/e2e/drive/g71_mfm_format_refused_test.pywithmfm_format_command.asm, registered inrun-tests). A G71 with GCR tracks 1 to 35 and three extra cylinders on side 0 is mounted read/write on a 1571, and each cylinder is formatted from the C64 with the 1571's partial burst format command, nine 512-byte sectors (4608 bytes). Only the command travels over the bus, so a C64 is enough. The suite reads the image file back over FTP after each format.Afterwards the suite discards the image's changes (
unlink,remove), deletes it, and puts the drive back to the model and power state it had.Red, Ultimate II+L in a C64, official 3.15a (
dddd29b2), FPGA 125:0x8fa0is the MFM marker on a 4000-byte track, with nine sectors in its table and none of their data;0x8064is the marker on the 100-byte track, which now holds the refused format's fill byte.Green, same Ultimate II+L and C64: v3.15a plus only this PR's
wd177x.ccchange (git_commit_hashcef333fb), FPGA 125, suite at c019a9d:Details: #967 (comment)
This branch itself builds with
make u2pl_swonly. Gate checks without a device:registry_test,lint_test(ruff) andstale_gates_testpass.What the suite cannot see
Where master writes the refused sectors at the stale position into another track, that lands in the drive's copy of the image (
gcr_ram_file) and reaches the file only when the image is saved. A C64 cannot read MFM sectors back, as that takes burst transfers, which need a C128. A drive-side reader (M-W/M-Einto the 1571,M-Rover the slow bus) could close that gap; it is not part of this PR.Not tested: the 1581 with a D81. There the space per track is fixed, and a format with more sectors than a track holds would take the same completion path.