home *** CD-ROM | disk | FTP | other *** search
/ Emulator Universe CD / emulatoruniversecd1998.iso / CPC / Utils / DSKutil / XTI_INCL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-13  |  6.3 KB  |  261 lines

  1. /* XTI 1.2 - AMSDOS file inclusion routines */
  2. /* filename: xti_incl.c */
  3.  
  4.  
  5.  
  6.  
  7. #define kBAD    0
  8. #define kDATA   1
  9. #define kSYSTEM 2
  10. #define kTsize (512*9+256)
  11.  
  12. long DirOffset;
  13. long resTracks;
  14.  
  15. FILE *ImageFile;
  16.  
  17. char *DataString = "Data";
  18. char *SysString  = "System";
  19.  
  20. int FreeBlockTags[180];    /* arrays of booleans */
  21. int FreeBlockNumber;
  22. int FreeEntryTags[64];
  23. int FreeEntryNumber;
  24. char AllNames[64][11];
  25. int  NextName;
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33. long Block2Offset(int numero, int block)
  34. {
  35.  int track;
  36.  int sector;
  37.  
  38.  track = (block*2)/9 + resTracks;
  39.  sector = (block*2)%9;
  40.  
  41.  if (numero)
  42.     { sector++;                      /* skip possible track header */
  43.       if (sector == 9) {track++; sector = 0;} }
  44.  
  45.  return((256+kTsize*track)+(256+512*sector));
  46. }
  47.  
  48.  
  49. void getDirectory()
  50. {
  51.  int i,j;
  52.  char x;
  53.  unsigned char Directory[2048];
  54.  
  55.  FreeEntryNumber = 0;
  56.  for (i=0; i<64; i++) FreeEntryTags[i] = 1;
  57.  NextName = 0;
  58.  for (i=0; i<(64*11); i++) *(*AllNames+i) = 0;
  59.  
  60.  if (theFormat == kSYSTEM) { resTracks = 2;  FreeBlockNumber = 169;}
  61.                       else { resTracks = 0;  FreeBlockNumber = 178;}
  62.  DirOffset = 512 + kTsize*resTracks;
  63.  
  64.  fseek(ImageFile, DirOffset, SEEK_SET);
  65.  for (i=0; i<2048; i++) Directory[i] = fgetc(ImageFile);
  66.  for (i=0; i<2; i++) FreeBlockTags[i] = 0;
  67.  for (i=2; i<(2+FreeBlockNumber); i++) FreeBlockTags[i] = 1;
  68.  
  69.  for (i=0; i<2048; i+= 32)
  70.     {
  71.     if (Directory[i] == 0xe5)
  72.          { FreeEntryNumber++; continue;} /* erased ? */
  73.     FreeEntryTags[i>>5] = 0;
  74.  
  75.     for(j = i+16; j<i+32; j++)     /* create bit map */
  76.         if (!Directory[j]) break; else
  77.          { FreeBlockTags[Directory[j]] = 0;
  78.            FreeBlockNumber--; }
  79.  
  80.     if (Directory[i+12] != 0) continue; /* not first */
  81.     for(j = 0; j<11; j++)
  82.           {
  83.           x = Directory[i+j+1];
  84.           if (!x) x = ' ';
  85.           AllNames[NextName][j] = x;
  86.           }
  87.     NextName++;
  88.     }
  89. }
  90.  
  91.  
  92. void CheckFormat(char *fileName)
  93. {
  94.  FILE *Scanned;
  95.  unsigned char buffer[13];
  96.  int  i;
  97.  
  98.  theFormat = kBAD;
  99.  if ( (Scanned = fopen(fileName, "r")) != NULL)
  100.   {
  101.    fseek(Scanned, 128, SEEK_SET);
  102.    for(i=0; i<13; i++) buffer[i] = fgetc(Scanned);
  103.      if (!strcmp(buffer, "Data Disk\n"))   theFormat = kDATA;
  104. else if (!strcmp(buffer, "System Disk\n")) theFormat = kSYSTEM;
  105.    fclose(Scanned);
  106.   }  
  107. }
  108.  
  109.  
  110.  
  111.  
  112. int IncludeFile()
  113. {
  114.  char SourceName[256];
  115.  char TargetName[12];
  116.  char c,x;
  117.  char *DotPt;
  118.  unsigned char EntryBuff[32];
  119.  unsigned char BlockBuff[1024];
  120.  FILE *Source;
  121.  int  h,i,j,s, delta, cmax, lmax, rem, adj;
  122.  int  sector, offset, selectedcluster, ePos;
  123.  int  entry, cluster, TotBytes;
  124.  char k = 'A';
  125.  unsigned long size;
  126.  
  127.  
  128.  if (!(FreeBlockNumber && FreeEntryNumber))
  129.      { printf("Image is full !\n"); return(0); }
  130.  printf("Include ? ");
  131.  scanf("%s", SourceName);
  132.  if (*SourceName == '.') return(0);
  133.  if ((Source = fopen(SourceName, "rb")) == NULL) 
  134.      { printf("\nFile not found...\n"); return (1); }
  135.  
  136.  fseek(Source, 0, SEEK_END);
  137.  size = ftell(Source);
  138.  fseek(Source, 0, SEEK_SET);
  139.  
  140.  if ((size>(FreeBlockNumber*1024L)) || (size>(FreeEntryNumber*16384L)))
  141.     { printf ("\nSorry, file is too big...\n"); return (1); }
  142.  if (!size) { printf ("\nThis file is empty !\n"); return(1); }
  143.  
  144.  s = strlen(SourceName);
  145.  j = 0;
  146.  
  147.  for(i=0; i<11; i++)
  148.   {
  149.   if (j<s)
  150.    {
  151.    c = toupper(SourceName[j++]);
  152.    if (c == '.')
  153.       {
  154.       if (i>7)  i--;
  155.          else { x = ' '; j--; }
  156.       }
  157.      else
  158.       { if (!isalnum(c)) x = '#'; else x = c; }
  159.    }
  160.    else x = ' ';
  161.   TargetName[i] = x;
  162.   }
  163.  
  164.  TargetName[11] = 0;
  165.  
  166.  for(j=10; TargetName[j] == ' '; j--) ;
  167.  
  168. retest:
  169.  for(i=0; i<NextName; i++) if (!strncmp(TargetName, AllNames[i], 11)) break;
  170.  if (i<NextName) { TargetName[j] = k++; goto retest; }
  171.  
  172.  printf("Including file as %s\n", TargetName);
  173.  sprintf(AllNames[NextName++], "%s", TargetName);
  174.  
  175.  h = size >> 14;              /* number of entries, careful rounding */
  176.  if (delta = (size & 0x3FFF)) h++;
  177.  FreeEntryNumber -= h;
  178.  
  179.  cmax = delta >> 10;          /* number of blocks in last entry */
  180.  if (!delta) cmax = 16;
  181.  if (rem = (delta & 0x3FF)) cmax++;
  182.  
  183.  adj = rem >> 7;              /* number of chunks in last block */
  184.  if (!rem) adj = 8;
  185.  if (rem & 0x7F) adj++;
  186.  
  187.  for(entry=0; entry<h; entry++)   /* loop on entries */
  188.    {
  189.    TotBytes = 0;
  190.    for(i=0; i<32; i++) EntryBuff[i] = 0;
  191.    sprintf(EntryBuff+1, "%s", TargetName);
  192.    lmax = (entry == (h-1)) ? cmax : 16;   /* wait for last entry */
  193.  
  194.    for (cluster=0; cluster<lmax; cluster++) /* loop on clusters */
  195.      {
  196.      if ( (cluster == (lmax-1)) && (entry == (h-1)) )
  197.        {   /* last of last ... */
  198.        for(j=0; j<rem; j++) BlockBuff[j] = fgetc(Source);
  199.        for(j=rem; j<1024; j++) BlockBuff[j] = 0;
  200.        TotBytes += adj;
  201.        }
  202.       else
  203.        {   /* normal case */
  204.        for(j=0; j<1024; j++) BlockBuff[j] = fgetc(Source);
  205.        TotBytes += 8;
  206.        }
  207.  
  208.      for(selectedcluster = 0; selectedcluster<180; selectedcluster++)
  209.             if (FreeBlockTags[selectedcluster]) break;
  210.  
  211.      for(sector=0; sector<2; sector++)     /* loop on sectors */
  212.        {
  213.        fseek(ImageFile, Block2Offset(sector, selectedcluster), SEEK_SET);
  214.        for (offset=0; offset<512; offset++)  /* loop on bytes */
  215.                 fputc(BlockBuff[offset+512*sector], ImageFile);
  216.        }
  217.  
  218.      EntryBuff[cluster+16] = selectedcluster;
  219.      FreeBlockTags[selectedcluster] = 0;
  220.      FreeBlockNumber--;
  221.      }
  222.  
  223.    for(ePos = 0; ePos<64; ePos++) if (FreeEntryTags[ePos]) break;
  224.    fseek(ImageFile, DirOffset+32*ePos, SEEK_SET);
  225.    EntryBuff[12] = entry;
  226.    EntryBuff[15] = TotBytes;
  227.  
  228.    for (i=0; i<32; i++) fputc(EntryBuff[i], ImageFile);
  229.    FreeEntryTags[ePos] = 0;
  230.    }
  231.  
  232.  return(1);
  233. }
  234.  
  235.  
  236.  
  237. void doIncluder(char *ImageName)
  238. {
  239.  char *FormString;
  240.  
  241.  CheckFormat(ImageName);
  242.  
  243.  if (theFormat == kBAD)
  244.     { fprintf(stderr,"Improper file format !\n");
  245.       exit(1);}
  246.  
  247.  if ((ImageFile = fopen(ImageName,"r+b")) == NULL)  /* dubious file mode */
  248.     { fprintf(stderr,"Cannot write to Image !\n");
  249.       exit(3);}
  250.  
  251.  getDirectory();
  252.  if (theFormat == kDATA) FormString = DataString;
  253.                     else FormString = SysString;
  254.  printf("Image is %s, with %d K free, %d files over %d entries.\n",
  255.         FormString, FreeBlockNumber, NextName, 64-FreeEntryNumber); 
  256.  
  257.  while (IncludeFile()) ;
  258.  
  259.  fclose(ImageFile);
  260. }
  261.