program unBINSCII;

var firstTime, match: Boolean;
    size, last, limit, i, j, k: integer;
    fileSize, chunkSize, lines: long;
    fileName: string[32];
    xlate: string[64];
    line: string[132];
    values: array[0..63] of byte;
    out: array[0..47] of byte;
    a: text;
    b: file of byte;

procedure Convert4x6to3x8(iX, oX: integer);
  var i, j: integer;
      temp: long;
      bytes: array[0..3] of byte;
  begin
    for i := 0 to 3
      do begin
        j := 0;
        repeat
          j := j + 1;
          match := line[iX + i + 1] = xlate[j]
        until match or (j = 64);
        if match
            then bytes[i] := j - 1
          else bytes[i] := 255
      end;
    temp := (long(bytes[3]) and $3F) shl 18
             + (bytes[2] and $3F) shl 12
             + (bytes[1] and $3F) shl 6
             + bytes[0] and $3F;
    out[oX] := temp shr 16;
    out[oX + 1] := (temp shr 8) and $FF;
    out[oX + 2] := temp and $FF
  end;

function reverse3: long;
  begin
    reverse3 := out[2] * 65536 + out[1] * 256 + out[0]
  end;

begin
  firstTime := true;
  if ParamCount <> 1
      then begin
        writeln('Usage: unBINSCII pathname');
        halt(20)
      end
    else fileName := ParamStr(1);
  assign(a, fileName);
  reset(a);
  repeat
    repeat
      readln(a, line)
    until (line = 'FiLeStArTfIlEsTaRt') or eof(a);
    if eof(a)
        then begin
          writeln('Unexpected EOF!');
          close(a);
          close(b);
          halt(20)
        end;
    readln(a, line);
    if length(line) <> 64
        then begin
          writeln('Translate table error!');
          close(a);
          close(b);
          halt(20)
        end
      else xlate := line;
    readln(a, line);
    if length(line) <> 52
        then begin
          writeln('File attributes error');
          close(a);
          close(b);
          halt(20)
        end;
    if firstTime
        then begin
          size := ord(line[1]) - 64;
          fileName := copy(line, 2, size);
          writeln('The output file will be named ''', fileName, '''');
          assign(b, fileName);
          rewrite(b);
          Convert4x6to3x8(16, 0);
          fileSize := reverse3;
          writeln('File size = ',fileSize)
          firstTime := false
        end;
    Convert4x6to3x8(44, 0);
    chunkSize := reverse3;
    writeln('  Chunk size = ', chunkSize);
    lines := chunkSize div 48;
    last := chunkSize mod 48;
    if last <> 0
        then lines := lines + 1;
    limit := 47;
    for i := 1 to lines
      do begin
        readln(a, line);
        if length(line) <> 64
            then begin
              writeln('Data line error!');
              close(a);
              close(b);
              halt(20)
            end;
        k := 0;
        for j := 0 to 15
          do begin
            Convert4x6to3x8(j * 4, k);
            k := k + 3
          end;
        if (i = lines) and (last <> 0)
            then limit := last - 1;
        for j := 0 to limit
          do write(b, out[j])
      end;
    readln(a, line)
    if length(line) <> 4
        then begin
          writeln('Wrong size chunk trailer!');
          close(a);
          close(b);
          halt(20)
        end
  until eof(a);
  close(b);
  close(a)
end.
