DOS file linkage fixing simplified
In my last post I fixed a couple of Bellcom disks by copying missing sectors from another disk, and then "fix[ing] the sector links". This post is going to discuss that, and modify our copy tool to do it automatically.
As explained earlier, the last three bytes of a DOS 2.0/2.5 file contains file metadata, specifically the file index, the next sector, and the number of bytes. When a sector is dropped and you find a replacement on another disk, two of these three values are unlikely to be what the other disk expects, and so you need to change them to the correct values.
In almost all cases, the next sector value will be the current sector plus one, and the file index can be inferred from the next sector. So let's add some code to do that to save us from having to do this manually. To do this, we'll replace the copy_sector routine with the following two routines.
sub link_data { unpack "nC", substr($_[0], -3, 3); } sub copy_sector { my ($srcFile, $dstFile, $srcSector, $dstSector, $fixlink) = @_; $fixlink = 1 if !defined $fixlink; my ($dst, $src) = (read_disk($dstFile), read_disk($srcFile)); my ($dstBuff, $srcBuff) = ($dst->{buff}, $src->{buff}); my ($srcOffset, undef, $dstOffset, $sectorSize) = (sector_offset($src, $srcSector), sector_offset($dst, $dstSector)); my $sectorData = substr($srcBuff, $srcOffset, $sectorSize); substr($dstBuff, $dstOffset, $sectorSize) = $sectorData; if ($fixlink) { my ($nextSector, $nBytes) = link_data($sectorData); my $fullSector = $nBytes == $sectorSize - 3; my $offset = $fullSector ? $sectorSize : -$sectorSize; ($nextSector, $nBytes) = link_data(substr($dstBuff, $dstOffset + $offset, $sectorSize)); $nextSector = ($nextSector & 0xfc00) | ($fullSector ? $dstSector + 1 : 0); substr($sectorData, - 3, 2) = pack "n", $nextSector; } substr($dstBuff, $dstOffset, $sectorSize) = $sectorData; write_file($dstFile, $dstBuff); }
The code here assumes you want to fix the link, but you can pass a zero in if you want the code to be skipped. In the case that you do want to fix the link, it looks at the current sector. If the sector is a full sector, it will take the file index from the next sector and set the next sector to the current sector plus one, otherwise it will take the index from the previous sector and set the next sector to zero.
That's it! In 95% of the cases, this works and avoids having to go in to the file with a hex editor to do this manually.
0 Comments
Recommended Comments
There are no comments to display.