Logo Search packages:      
Sourcecode: cbmlink version File versions  Download package

int disk_read ( const struct comm comm,
unsigned  unit,
unsigned  interleave,
unsigned  track,
unsigned  track_end,
FILE *  file,
char *  buf 
)

copy a disk from the remote host

Parameters:
comm the communication primitives
unit the disk unit (drive 0 or 1)
interleave the interleave factor (number of sectors to skip)
track number of the track to start reading from
track_end number of the last track, plus 1
file output file
buf a buffer of at least 1256 bytes
Returns:
zero on success, nonzero on error

current sector and number of blocks

communication status

drive unit

position of the "track" display

interleave table

Definition at line 282 of file disk.c.

References backspaces, and read_sector().

Referenced by drive_image_read().

{
  /** current sector and number of blocks */
  unsigned sector, blocks;
  /** communication status */
  int status;
  /** drive unit */
  char drive = unit ? '1' : '0';
  /** position of the "track" display */
  unsigned pos = 0;
  /** interleave table */
  char* iltab = buf + 256;

  for (blocks = 0; track < track_end; track++) {
    if (pos)
      fputs (backspaces + (sizeof backspaces - 1) - pos, stderr);
    pos = fprintf (stderr, "track %u", track);
    fflush (stderr);

    if (interleave) {
      unsigned highsect = 1000, sectdone = 0;
      memset (iltab, 0, 1000);
      for (sector = 0; sectdone < highsect;
         sector += interleave + 1, sector %= highsect) {
      while (iltab[sector]) {
        if (++sector == highsect) {
        findnext:
          for (sector = 0; iltab[++sector]; );
          break;
        }
      }
      switch ((status = read_sector (comm, drive, track, sector, buf))) {
      case 0: /* ok, mark the sector read */
        iltab[sector] = 1;
        break;
      case 1: /* no such sector */
        iltab[highsect = sector] = 2;
        if (sectdone < highsect)
          goto findnext;
        continue;
      case 2: /* end of disk */
        blocks += sectdone;
        goto done;
      default:
        return status;
      }
      sectdone++;
#ifdef __BCC__
      {
        long ofs = 256L * (blocks + sector);
        if (lseek (file->fd, ofs, SEEK_SET) != ofs) {
          perror ("\ndisk_read: lseek");
          return 2;
        }
      }
#else /* __BCC__ */
      if (fseek (file, 256L * (blocks + sector), SEEK_SET)) {
        perror ("\ndisk_read: fseek");
        return -2;
      }
#endif /* __BCC__ */
      if (256 != fwrite (buf, 1, 256, file)) {
        perror ("\ndisk_read: fwrite");
        return -2;
      }
      }
      blocks += sectdone;
    }
    else {
      for (sector = 0; sector < 1000; sector++, blocks++) {
      switch ((status = read_sector (comm, drive, track, sector, buf))) {
      case 0:
        break;
      case 1: /* end of track */
        goto next_track;
      case 2: /* end of disk */
        goto done;
      default:
        return status;
      }
      if (256 != fwrite (buf, 1, 256, file)) {
        perror ("\ndisk_read: fwrite");
        return -2;
      }
      }
    }
  next_track:
    continue;
  }

 done:
  fprintf (stderr, "\ndisk_read: %u blocks\n", blocks);
  return 0;
}


Generated by  Doxygen 1.6.0   Back to index