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

Extracting data from DOS 2.0/2.5 disks


Atari_Ace

480 views

In earlier posts I explained how data is organized on a DOS 2.0/2.5 disk, but didn't provide any code specific to the directories and files (other than link_data). This post remedies that, in part to fill in those gaps, and in part because I'm going to fix some disks that require a bit more effort than just copying a sector or two from another disk.

Let's start with a helper function

sub toascii {
  my ($val) = @_;
  $val =~ tr/\x00-\x1f\x60\x7b\x7d\x7e\x80-\x9a\x9c-\x9f\xff/./;
  $val =~ tr/\x7f\x9b\xa0-\xfe/\t\n\x20-\x7e/;
  $val;
}

This routine will convert some ATASCII text to ASCII text. It translates unprintable characters to periods, inverse characters to their non-inverse equivalents, and 0x7F and 0x9B to tab and carriage return.

OK, now let's write a function that dumps a DOS directory.

sub read_dos_dir {
  my ($file, $sector) = @_;
  my $disk = read_disk($file);
  $sector = 361 if !defined $sector;
  my $dirData = '';
  $dirData .= substr($disk->{buff}, (sector_offset($disk, $_))[0], 0x80) for ($sector .. $sector + ;
  for (my $i = 0; $i < 64; $i++) {
    my $dirEntry = substr($dirData, $i * 16, 16);
    my ($status, $sectorCount, $firstSector) = unpack "Cvv", substr($dirEntry, 0, 5);
    last if $status == 0;
    my $name = toascii(substr($dirEntry, 5));
    printf "%02d %02x %03d %03d %s\n", $i, $status, $sectorCount, $firstSector, $name;
  }
}

Recall that the directory is in sectors 361 to 368, so this routine first reads in those sectors. Actually, it reads in 8 sectors from anywhere on the disk, since MYDOS can locates sub-directory information in other locations and we may want to reuse this code in the future. It then reads each 16-byte entry, getting the start, sector count, first sector and name (which it converts to ascii, thus the helper) and printing them. It stops when it gets to an entry that has a status byte set to zero.

Note that this routine works even with double density disks, by ignoring the 2nd half of every sector. sector_offset returns the size of the sectors, but we ignore that and always use 0x80 = 128.

OK, now let's see if we can extract a file from a DOS disk:

sub read_dos_file {
  my ($file, $sector, $ascii) = @_;
  $ascii = 0 if !defined $ascii;
  my $disk = read_disk($file);
  my $out = '';
  for (;;) {
    my ($pos, $sectorSize) = sector_offset($disk, $sector);
    my $sectorData = substr($disk->{buff}, $pos, $sectorSize);
    my ($nextSector, $nBytes) = link_data($sectorData);
    $out .= substr($sectorData, 0, $nBytes);
    $sector = $nextSector & 0x3ff;
    last if $sector == 0;
  }
  $out = toascii($out) if $ascii;
  write_file('out.bin', $out);
}

In this routine, you provide the first sector of the file you want to extract. It then follows the sector links until the next sector is 0. It then writes the file out, optionally converting it to ascii first if requested.

Now to hook this up to our tool, we add the calls into our main subroutine as follows:

  read_dos_dir(@_) if $opt eq '-dir';
  read_dos_file(@_) if $opt eq '-file';

And voila, atr.pl has some rudimentary DOS inspection abilities. You can exercise them on Bellcom Disk #1 like so.

C:> atr.pl -dir 001.atr
00 62 037 004 DOS     SYS
01 62 042 041 DUP     SYS
02 62 012 083 AUTORUN SYS
03 62 016 095 HELP    DOC
04 62 132 111 ENTPRIS1BAS
05 62 235 243 ENTPRIS2BAS
06 62 047 487 STARTREKDOC
07 62 184 534 STARTREKBAS
C:> atr.pl -file 001.atr 95 1
C:> head out.bin

       - B  E  L  L  C  O  M -
       [Public Domain Library]
       BOX 1043,  PETERBOROUGH
       ONTARIO, CANADA K9J 7A5

       -----------------------
       ATARI MENU INSTRUCTIONS
       -----------------------


That's enough for today, I've attached the current scripts to this post for anyone who wants to use them without constructing them from the snippets in the posts.
 

atr1.zip

  • Like 1

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...