Jump to content

Photo

Atari_Ace's Blog - ACEC Disk 016A, or one byte isn't as good as ano


No replies to this topic

#1 RSS Bot OFFLINE  

RSS Bot

    Quadrunner

  • 8,675 posts

Posted Sat Aug 11, 2018 2:07 PM

In my initial examination of the ACE of Columbus disk archive, I was able to fix acec068b.atr by borrowing a couple of sectors from acec016a.atr.  This restored a Rubik's cube program, but if you compare the two files, they aren't the same.
 
As discussed in the past, BASIC files start with 14 bytes of pointers, then the variable names, then the variable values, then the lines of code.  In this case, the variable values are different, which is fine, those all get cleared when the program runs and whatever the last values were are what get SAVEd.  But there was one byte in the middle of the lines of code that was different, which I didn't expect.
 
So let's write a simple BASIC line validator.  Every line in a BASIC program starts with the line number and a byte count, and we expect the lines to be increasing in the file, so one simple validation might be to do the following.

sub bas {
  my ($file) = @_;
  my $program = read_file($file);
  my $length = length($program);
  my ($lomem, $vntp, $vntd, $vvtp, $stmtab, $stmcur, $starp)
    = unpack "v7", substr($program, 0, 14);
  my $offset = 14 + ($vntd - $vntp) + 1 + ($stmtab - $vvtp);
  my $lastLineNumber = -1;
  while ($offset + 3 < $length) {
    last if $lastLineNumber == 32768;
    my ($lineNumber, $lineLength) = unpack "vC", substr($program, $offset, 3);
    die sprintf "%04x: $lineNumber <= $lastLineNumber", $offset if $lineNumber <= $lastLineNumber;
    $lastLineNumber = $lineNumber;
    $offset += $lineLength;
  }
}
This reads in a Basic file, parses the first 14 bytes, and then locates the beginning of the statement table for typical programs.  It then parses all the lines in the file, terminating if we find a line number that goes backwards.  If we run this on the two versions of the program, it doesn't like the one from acec016a.atr.  Clearly a byte on the disk has flipped, so let's flip it back (from 0x20 to 0x7e at offset 0x44ea).
004490: SECTOR: 138: FILE:
     0  1d 36 8e 2d 8e 25 0e 40-34 00 00 00 00 14 2b 36   .6.-.%.@4.....+6
    10  8f 2d 8f 26 0e 40 64 00-00 00 00 16 74 04 2b 0f   .-.&.@d.....t.+.
    20  07 8d 21 0e 40 45 00 00-00 00 1b 1d 36 8e 2d 8e   ..!.@E......6.-.
    30  25 0e 40 17 00 00 00 00-14 2b 36 8f 2d 8f 26 0e   %.@......+6.-.&.
    40  40 64 00 00 00 00 16 79-04 0c 0c 36 8a 2d 81 38   @d.....y...6.-.8
    50  8d 2c 16 7b 04 07 07 03-8a 16 20 04 83 09 2c 8e   .,.{...... ...,.
    60  12 8f 14 17 2f 8e 12 8f-25 0e 40 16 00 00 00 00   ..../...%.@.....
    70  14 25 2c 8e 25 0e 40 01-00 00 00 00 12 10 8b 7d   .%,.%.@........}
which makes line 1056 => 1150.
 

 
Attached File(s)


http://atariage.com/forums/blog/734/entry-14956-acec-disk-016a-or-one-byte-isnt-as-good-as-another/




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users