Jump to content
  • entries
    45
  • comments
    10
  • views
    10,422

DOS file linkage fixing simplified


Atari_Ace

438 views

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.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...