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

enum ArStatus ArchiveC2N ( const struct Archive archive,
const char *  filename 
)

Write an archive in Commodore C2N tape format

Parameters:
archive the archive to be written
filename host file name of the archive file
Returns:
status of the operation

tape header

data file header

number of bytes written

Definition at line 265 of file c2n.c.

References ArFail, ArNoSpace, ArOK, ArchiveEntry::data, c2n_header::endAddrHigh, c2n_header::endAddrLow, Archive::first, ArchiveEntry::length, ArchiveEntry::name, name2header(), ArchiveEntry::next, PRG, c2n_header::startAddrHigh, c2n_header::startAddrLow, c2n_header::tag, tBasic, tDataBlock, tDataHeader, tML, and Filename::type.

{
  FILE* f;
  struct ArchiveEntry* ae;

  if (!(f = fopen (filename, "wb")))
    return errno == ENOSPC ? ArNoSpace : ArFail;

  for (ae = archive->first; ae; ae = ae->next) {
    /** tape header */
    struct c2n_header header;
    name2header (&ae->name, &header);

    if (ae->name.type == PRG) {
      unsigned end = ae->length;
      if (end < 2)
      continue; /* too short file */

      header.startAddrLow = ae->data[0];
      header.startAddrHigh = ae->data[1];
      end += (unsigned) header.startAddrLow | (header.startAddrHigh << 8);
      header.endAddrLow = end -= 2;
      header.endAddrHigh = end >> 8;
      header.tag = header.startAddrLow == 1 ? tBasic : tML;

      if (1 != fwrite (&header, sizeof header, 1, f) ||
        ae->length - 2 != fwrite (ae->data + 2, 1, ae->length - 2, f)) {
      fail:
      fclose (f);
      return ArFail;
      }
    }
    else {
      /* convert anything else than programs to data files */
      /** data file header */
      static const byte_t dataheader[] = { tDataHeader, 0x3c, 3, 0xfc, 3 };
      /** number of bytes written */
      unsigned cnt = 0;
      memcpy (&header, dataheader, sizeof dataheader);
      if (1 != fwrite (&header, sizeof header, 1, f))
      goto fail;
      do {
      unsigned next = cnt + (sizeof header) - 1;
      header.tag = tDataBlock;
      if (next > ae->length) {
        memcpy (&header.startAddrLow, ae->data + cnt, ae->length - cnt);
        (&header.startAddrLow)[ae->length - cnt] = 0;
      }
      else
        memcpy (&header.startAddrLow, ae->data + cnt, (sizeof header) - 1);
      if (1 != fwrite (&header, sizeof header, 1, f))
        goto fail;
      cnt = next;
      } while (cnt < ae->length);
    }
  }

  fclose (f);
  return ArOK;
}


Generated by  Doxygen 1.6.0   Back to index