home *** CD-ROM | disk | FTP | other *** search
- /* XTI 1.2b - format convertors */
- /* filename : xti_conv.c */
-
-
-
- /* global flags, buffers and counters */
-
-
- int theFormat;
- int theSide;
- int theCut;
- unsigned char theCutLo;
- unsigned char theCutHi;
- int DETrick;
-
- FILE *Source;
- FILE *Merger;
- FILE *Target;
-
- #define k8KB 0x2000
- #define k16KB 0x4000
-
- unsigned char TrackBuff[k16KB]; /* target track including header, at most 16k */
- unsigned char HeaderBuff[256]; /* target file header */
- unsigned char InputBuff[k8KB]; /* source header: at most 8k */
- unsigned char SectorBuff[k8KB]; /* glue buffer: 8k */
-
- long targetOffset; /* offset to end of target file (after header) */
- int trackOffset; /* offset to next track size in header */
- int SInfoOffset; /* offset to next sector info list in track buffer */
- int SDataOffset; /* offset to next sector data in same buffer */
-
- int extCall;
-
- #define kOldSizeOffset 0x32
- #define kTrackNumOffset 0x30
- #define kSideNumOffset 0x31
-
- #define min(i,j) (((i)>(j))?(j):(i))
- #define max(i,j) (((i)>(j))?(i):(j))
-
- #define kNUL 255
-
-
- /* conversion sub routines */
-
-
-
-
-
- void Reset()
- {
- #if MSDOS == 1
- _fmode = O_BINARY;
- #endif
-
- targetOffset = 256;
- trackOffset = 0x34;
- theCut = 6*1024;
- theFormat = kNUL;
- DETrick = 0;
- extCall = 0;
- }
-
- int NtoSize(unsigned char N)
- {
- int i = (0x80 << min(N,8));
-
- return ( min(i,theCut) );
- }
-
- long Bword32Load(FILE *source) /* load a big endian long from file */
- {
- long i = 0, j;
-
- for(j=0; j<4; j++) i = ((i<<8) | fgetc(source));
- return(i);
- }
-
- long Bword32Acc(unsigned char *buff) /* compute big endian long from buffer */
- {
- long i = 0, j;
-
- for (j=0; j<4; j++) i = ((i<<8) | (*buff++));
- return(i);
- }
-
- long Lword32Acc(unsigned char *buff) /* compute little endian long from buffer */
- {
- long i = *buff++;
- i |= ((*buff++)<<8);
- i |= ((*buff++)<<16);
- i |= ((*buff++)<<24);
- return(i);
- }
-
-
-
- void SetUpDSKHeader(unsigned char *Buff, int numtrack, int numside)
- {
- int i;
- for(i=0; i<256; i++) Buff[i] = 0;
-
- sprintf(Buff, "EXTENDED CPC DSK File\r\nDisk-Info\r\n");
- sprintf(Buff + 34 , "Image XTender\n");
-
- if ((numtrack > 100) || (numside > 2))
- { fprintf(stderr,"Error: Invalid structure !\n"); exit(6); }
- Buff[kTrackNumOffset] = numtrack;
- Buff[kSideNumOffset] = (numside & 0x3F) | (DETrick << 7);
- }
-
-
- void SetUpTrackHeader(unsigned char *Buff, int tracknum, int sidenum,
- int sectsize, int numsect,
- unsigned char GAP, unsigned char filler)
- {
- int i;
- for(i=0; i<k16KB; i++) Buff[i] = 0;
-
- sprintf (Buff, "Track-Info\r\n");
-
- Buff[0x10] = tracknum;
- Buff[0x11] = sidenum;
- Buff[0x14] = sectsize;
- Buff[0x15] = numsect;
- Buff[0x16] = GAP;
- Buff[0x17] = filler;
- SInfoOffset = 0x18; /* set up for future increments */
- SDataOffset = 256;
- }
-
-
- void StoreTrack(unsigned char *Buff)
- {
- int i;
-
- if (SDataOffset & 255) SDataOffset = (SDataOffset & 0xFF00) + 0x100; /* rounding */
- HeaderBuff[trackOffset++] = SDataOffset >> 8;
- fseek (Target, targetOffset, SEEK_SET); /* make sure we're at the right place */
- for (i=0; i<SDataOffset; i++) fputc(Buff[i], Target); /* dump with padding */
- targetOffset += SDataOffset;
- }
-
-
- void StoreHeader(unsigned char *Buff)
- {
- int i;
- unsigned char test;
- int ok = 1;
-
- fseek(Target, 0, 0);
- for (i= trackOffset-1; (Buff[i]==0) && (i > 0x33); i--) ; /* fewer tracks than expected */
- if (1 == Buff[kSideNumOffset]) Buff[kTrackNumOffset] = i-0x33; /* careful rounding */
- else Buff[kTrackNumOffset] = (i-0x32)>>1;
-
- test = Buff[0x34]; /* compute old style track length - may be removed ! */
- for (i=0x35; i<0x34+Buff[kTrackNumOffset]; i++)
- if (Buff[i] != test) {ok =0; break;}
- if (ok) Buff[kOldSizeOffset+1] = test;
- for (i=0; i<256; i++) fputc(Buff[i], Target);
- }
-
-
- void AddSector(unsigned char *Buff, unsigned char *SourceBuff,
- int track, int side, unsigned char ID, unsigned char N,
- unsigned char ST1, unsigned char ST2, int length)
- {
- int i;
-
- Buff[SInfoOffset++] = track;
- Buff[SInfoOffset++] = side;
- Buff[SInfoOffset++] = ID;
- Buff[SInfoOffset++] = N;
- Buff[SInfoOffset++] = ST1;
- Buff[SInfoOffset++] = ST2;
- Buff[SInfoOffset++] = length;
- Buff[SInfoOffset++] = length >> 8;
-
- if ( (SDataOffset + length) > k16KB)
- { fprintf(stderr,"Error: Track too long !\n"); exit(5); }
- for(i=0; i<length; i++) Buff[SDataOffset++] = SourceBuff[i];
- }
-
-
-
-
-
-
- /* format convertors start here */
-
-
-
-
-
- void edsk2edsk() /* when flag extCall (extractor call) armed, keeps only one side */
- {
- int i,c,k,l, Tsize, t,tno,sno,sno2;
- int unique = 1, FirstSize;
- unsigned char TrS[256];
- unsigned char TrS2[256];
-
- fseek(Source, 0x30, 0);
- fputs("EXTENDED CPC DSK File\r\nDisk-Info\r\n" , Target);
- fputs("Image XTender\n" , Target);
-
- for(c=0x30; c<256; c++) TrS2[c] = TrS[c] = fgetc(Source);
- k = l = 0x34;
- sno = sno2 = TrS[kSideNumOffset];
- if (extCall)
- {
- if (theSide) k++;
- for(c=k; c<256; c += 2) TrS2[l++] = TrS[c]; /* skip unneeded tracks */
- sno2 = 1;
- }
-
- for (i = TrS[kTrackNumOffset]*sno2+0x34; (TrS2[i]==0) && (i > 0x33); i--) ;
- /* fewer tracks than expected */
- if (sno != 2)
- { /* single sided */
- if (extCall)
- { fprintf(stderr,"Error: Image is single-sided !\n"); exit(14); }
- TrS2[kTrackNumOffset] = i-0x33;
- }
- else
- {
- if (extCall) TrS2[kTrackNumOffset] = i-0x33; /* same as single side */
- else TrS2[kTrackNumOffset] = (i-0x32)>>1; /* careful rounding */
- }
- for(i=0x30; i<256; i++) fputc(TrS2[i], Target);
-
- FirstSize = TrS[k]<<8;
-
- for(t=0; t<TrS[kTrackNumOffset]*sno; t++)
- {
- Tsize = TrS[t+0x34]<<8;
- if (extCall && ((t&1) ^ theSide) )
- { fseek(Source, Tsize, SEEK_CUR); continue; }
- if (Tsize != FirstSize) unique = 0;
- if (!Tsize) continue; /* track missing: nothing to clean */
-
- fseek(Source, 16, SEEK_CUR);
- fputs("Track-Info\r\n", Target);
- for(c=12; c<16; c++) fputc(0, Target);
- tno = fgetc(Source);
- sno2 = fgetc(Source);
- fputc(tno, Target);
- if (extCall) fputc(0, Target); else fputc(sno2, Target);
- for(c=18; c<Tsize; c++) fputc(fgetc(Source), Target);
- }
-
- if (!extCall)
- while( (c = getc(Source)) != EOF) fputc( c ,Target); /* support for supertrack */
-
- fseek(Target, kSideNumOffset, SEEK_SET);
-
- if (!extCall)
- fputc( (TrS[kSideNumOffset] & 0x3F) | (DETrick<<7) ,Target); /* DE marking */
- else
- fputc(1 | (TrS[kSideNumOffset] & 128) , Target);
- /* don't change anything if called from extractor */
-
- if (unique) {fputc(0, Target); fputc(TrS[k],Target);}
- }
-
-
-
- void dif2edsk()
- {
- int i,j,k, NumSect;
- unsigned char filler;
- int InputPt; /* used to scan header in InputBuff */
- int size, size2, NTr;
- unsigned char N, ST2;
-
- for(i=0; i<k8KB; i++) InputBuff[i] = fgetc(Source);
- SetUpDSKHeader(HeaderBuff,NTr = InputBuff[1], 1);
- InputPt = 2; /* first track descriptor */
-
- for (j=0; j<NTr; j++)
- {
- NumSect = InputBuff[InputPt++];
-
- if (NumSect == 0) SDataOffset = 0; else /* unformatted track */
- {
- SetUpTrackHeader(TrackBuff, j ,0, 2, NumSect, 0x4e, 0xe5 );
- for (k=0; k<NumSect; k++)
- {
- size = NtoSize(N = InputBuff[InputPt+3]); /* in target */
- size2 = (0x80 << min(N,8)); /* in source */
- size2 = min(k8KB,size2); /* Sector buffer limit = 8k */
-
- if ((ST2 = InputBuff[InputPt+6])>>7)
- {
- filler = InputBuff[InputPt+7];
- for (i=0; i<size; i++) SectorBuff[i] = filler; /* decompress sector */
- }
- else
- for (i=0; i<size2; i++) SectorBuff[i] = fgetc(Source);
-
- if ((SDataOffset+size) > k16KB) size = 0; /* fix some special protections */
- AddSector(TrackBuff, SectorBuff, InputBuff[InputPt], InputBuff[InputPt+1],
- InputBuff[InputPt+2], N, InputBuff[InputPt+5],
- ST2 & 0x7F, size);
- InputPt += 8;
- }
- }
-
- StoreTrack(TrackBuff);
- }
- StoreHeader(HeaderBuff);
- }
-
-
-
- void Odif2edsk()
- {
- int i,j,k, NumSect;
- unsigned char filler;
- int InputPt; /* used to scan header in InputBuff */
- int size, size2, NTr;
- unsigned char N, ST1, ST2;
-
- for(i=0; i<2048; i++) InputBuff[i] = fgetc(Source); /* shorter header */
- SetUpDSKHeader(HeaderBuff,NTr = InputBuff[1], 1);
- InputPt = 2; /* first track descriptor */
-
- for (j=0; j<NTr; j++)
- {
- NumSect = InputBuff[InputPt++];
-
- if (NumSect == 0) SDataOffset = 0; else /* unformatted track */
- {
- SetUpTrackHeader(TrackBuff, j ,0, 2, NumSect, 0x4e, 0xe5 );
- for (k=0; k<NumSect; k++)
- {
- size = NtoSize(N = InputBuff[InputPt+3]); /* in target */
- size2 = (0x80 << min(N,8)); /* in source */
- size2 = min(k8KB,size2); /* Sector buffer limit = 8k */
-
- for (i=0; i<size2; i++) SectorBuff[i] = fgetc(Source);
-
- if (N > 5) { ST1 = ST2 = 0x20; } else { ST1 = 0x80; ST2 = 0;}
- if ((SDataOffset+size) > k16KB) size = 0; /* fix some special protections */
-
- AddSector(TrackBuff, SectorBuff, InputBuff[InputPt], InputBuff[InputPt+1],
- InputBuff[InputPt+2], N, ST1, ST2, size);
- InputPt += 4; /* shorter sector descriptors */
- }
- }
-
- StoreTrack(TrackBuff);
- }
- StoreHeader(HeaderBuff);
- }
-
-
-
- void dsk2edsk()
- {
- int i,j,k,l;
- int SectSize, ShiftSize, Ts;
- long Toffset;
- int SizePt, HeadPt, NTr, Ns;
-
- for(i=0; i<256; i++) InputBuff[i] = fgetc(Source);
- Ts = InputBuff[kOldSizeOffset] + (InputBuff[kOldSizeOffset+1]<<8);
- SetUpDSKHeader(HeaderBuff, NTr = InputBuff[kTrackNumOffset],
- Ns = InputBuff[kSideNumOffset]);
- for(i=64; i<256; i++) HeaderBuff[i] = InputBuff[i]; /* copy some extra data */
-
- for(i=0; i<NTr; i++) /* loop on cylinders */
- for(j=0; j<Ns; j++) /* loop on surfaces */
- {
- fseek(Source, Toffset = 256L+(long)Ts*(i*Ns +j), SEEK_SET);
- for(k=0; k<256; k++) TrackBuff[k] = fgetc(Source); /* copy everything */
- sprintf(TrackBuff, "Track-Info\r\n");
-
- if (TrackBuff[0x15])
- {
- SizePt = 0x18+6;
- ShiftSize = 128<<TrackBuff[0x14]; /* unique size in source */
- SDataOffset = 256;
-
- for(k=0; k<TrackBuff[0x15]; k++)
- {
- fseek(Source, Toffset+k*ShiftSize+256, SEEK_SET);
- SectSize = NtoSize(TrackBuff[SizePt-3]);
- if ( (SDataOffset + SectSize) > k16KB)
- { fprintf(stderr,"Error: Track too long !\n"); exit(5); }
- for (l=0; l<SectSize; l++) TrackBuff[SDataOffset++] = fgetc(Source);
-
- TrackBuff[SizePt] = SectSize;
- TrackBuff[SizePt+1] = SectSize>>8; /* add new data to sector info */
- SizePt += 8;
- if ( SizePt > 255 )
- { fprintf(stderr,"Error: Invalid structure !\n"); exit(6); }
- }
- } else SDataOffset = 0; /* unformatted track */
-
- StoreTrack(TrackBuff);
- }
-
- StoreHeader(HeaderBuff);
- }
-
-
-
- void cpd2edsk()
- {
- int j,k, Ntr, Max_SectSize, NumSect;
- long i;
- unsigned char C,H,R,N,ST1,ST2;
- int size;
-
- fseek(Source, 8, SEEK_SET);
- Ntr = fgetc(Source);
- SetUpDSKHeader(HeaderBuff, Ntr, 1);
-
- for(i=0; i<Ntr; i++)
- {
- fseek(Source, 9+(5120+132)*i, SEEK_SET);
- for(j=0; j<132; j++) InputBuff[j] = fgetc(Source);
- for(j=0, Max_SectSize = 0; j<132; j++)
- {
- if (InputBuff[j] == 0xFF) break; /* count sectors */
- if (InputBuff[j+66] > Max_SectSize)
- Max_SectSize = InputBuff[j+66];
- }
- NumSect = j;
-
- if (NumSect)
- {
- SetUpTrackHeader(TrackBuff, i, 0, Max_SectSize, NumSect, 0x4e, 0xe5);
- for(j=0; j<NumSect; j++)
- {
- size = NtoSize(N = InputBuff[j+66]);
- C = i;
- H = 0;
- R = InputBuff[j];
- ST1 = 0x80;
- ST2 = 0;
-
- if (size > k8KB) { fprintf(stderr, "Error: Sector too long !\n"); exit(7); }
-
- for(k=0; k<size; k++) SectorBuff[k] = fgetc(Source);
- AddSector(TrackBuff, SectorBuff, C, H, R, N, ST1, ST2, size);
- }
- } else SDataOffset = 0; /* unformatted track */
-
- StoreTrack(TrackBuff);
- }
- StoreHeader(HeaderBuff);
- }
-
-
- void emc2edsk()
- {
- long FSize;
- long Toffset, Soffset;
- int i,j,k,l, N, Ns;
- int SectPt, size;
- unsigned int CRC, CRC2;
- unsigned char ST1, ST2;
-
- fseek(Source, 12, SEEK_SET);
- FSize = Bword32Load(Source);
- if ((FSize/4816) > 42) Ns = 2; else Ns = 1; /* arbitrary limit: 4.5k + header */
- SetUpDSKHeader(HeaderBuff, 40, Ns);
-
- for(i=0; i<40; i++)
- for(j=0; j<Ns; j++)
- {
- fseek(Source, Toffset = 16 + 4816*(i + j*40), SEEK_SET);
- for(k=0; k<208; k++) InputBuff[k] = fgetc(Source);
- for(k=1; k<208; k+=8) if (InputBuff[k] > 5) break;
-
- if (k == 1) SDataOffset = 0; else /* unformatted track */
- {
- SetUpTrackHeader(TrackBuff, i, j, InputBuff[1], (--k)>>3, 0x4e, 0xe5 );
- for(SectPt=0; SectPt<k; SectPt+=8)
- {
- N = InputBuff[SectPt+1];
- size = NtoSize(N);
- Soffset = Toffset + 208 + Bword32Acc(InputBuff+SectPt+4);
- fseek(Source, Soffset, SEEK_SET);
- CRC = 0;
- CRC2 = (InputBuff[SectPt+2]<<8) | InputBuff[SectPt+3];
-
- for(l=0; l<size; l++) CRC += (SectorBuff[l] = fgetc(Source));
- if (CRC == CRC2) { ST1 = 0x80; ST2 = 0; } else { ST2 = ST1 = 0x20; }
-
- AddSector(TrackBuff, SectorBuff, i, j, InputBuff[SectPt], N, ST1, ST2, size);
- }
- }
-
- StoreTrack(TrackBuff);
- }
- StoreHeader(HeaderBuff);
- }
-
-
-
- void ami2edsk()
- {
- int i,j,k;
- unsigned char C,H,R,N,ST1, ST2;
-
- fseek(Source, 0, SEEK_SET);
- SetUpDSKHeader(HeaderBuff, 42, 1);
-
- for(i=0; i<42; i++)
- {
- SetUpTrackHeader(TrackBuff, i, 0, 2, 9, 0x4e, 0xe5 );
-
- for(j=0; j<9; j++)
- {
- C = fgetc(Source);
- H = fgetc(Source);
- N = fgetc(Source);
- R = fgetc(Source);
- if (N <= 2) { ST1 = 0x80; ST2 = 0; } else { ST2 = ST1 = 0x20; }
- ST2 |= (C != i)<<4; /* wrong track */
-
- for(k=0; k<512; k++) SectorBuff[k] = fgetc(Source);
-
- AddSector(TrackBuff, SectorBuff, C, H, R, N, ST1, ST2, min(512, NtoSize(N)) );
- }
-
- StoreTrack(TrackBuff);
- }
-
- StoreHeader(HeaderBuff);
- }
-
-
- void cpc2edsk()
- {
- long i,j,k, Nt,Ns,Sect;
- int SectPt, size1, size2;
- unsigned char C,H,R,N,ST1, ST2;
-
- fseek(Source, 32, SEEK_SET);
- for(i=0; i<32; i++) InputBuff[i] = fgetc(Source);
- Nt = 10*(InputBuff[0] - 48) + (InputBuff[1] - 48);
- if (!strcmp(InputBuff+16, "DoubleSided")) Ns = 2; else Ns = 1;
-
- SetUpDSKHeader(HeaderBuff, Nt, Ns);
-
- for(i=0; i<Nt; i++)
- for(j=0; j<Ns; j++)
- {
- SetUpTrackHeader(TrackBuff, i, j, 2, 0, 0x4e, 0xe5 ); /* dummy sector number */
- fseek(Source, 128 + (i*Ns+j)*6144, SEEK_SET);
- Sect = 0;
-
- for(; ;)
- {
- for(k=0; k<8; k++) InputBuff[k] = fgetc(Source);
- if (!strncmp(InputBuff+4, "IDFD", 4)) Sect++; else break; /* EOT */
-
- C = fgetc(Source);
- H = fgetc(Source);
- R = fgetc(Source);
- N = fgetc(Source);
- for(k=12; k<32; k++) fgetc(Source);
-
- size1 = min (128<<N, k8KB);
- size2 = NtoSize(N);
-
- if (N<6) { ST1 = 0x80; ST2 = 0; } else { ST2 = ST1 = 0x20; }
- ST2 |= (C != i)<<4; /* wrong track */
-
- for(k=0; k<size1; k++) SectorBuff[k] = fgetc(Source);
-
- AddSector(TrackBuff, SectorBuff, C, H, R, N, ST1, ST2, size2 );
- }
-
- if (Sect) TrackBuff[0x15] = Sect; else SDataOffset = 0; /* correct the */
- StoreTrack(TrackBuff); /* sector number and unformatted track case ... */
- }
-
- StoreHeader(HeaderBuff);
- }
-
-
-
- void npc2edsk()
- {
- unsigned char Rbase;
- int TotTracks, curTrack, curSect, offset;
- long Size;
-
- fseek(Source, 0, SEEK_END);
- Size = ftell(Source);
- TotTracks = (Size-2L)/4608L;
- fseek(Source, 0, SEEK_SET);
- fgetc(Source);
- Rbase = fgetc(Source);
-
- SetUpDSKHeader(HeaderBuff, TotTracks, 1);
- for(curTrack = 0; curTrack<TotTracks; curTrack++)
- {
- SetUpTrackHeader(TrackBuff, 0, curTrack, 2, 9, 0x4e, 0xe5);
- for(curSect = 0; curSect<9; curSect++)
- {
- for(offset = 0; offset<512; offset++) SectorBuff[offset] = fgetc(Source);
- AddSector(TrackBuff, SectorBuff, curTrack, 0,
- Rbase+curSect, 2, 0x80, 0, 512);
- }
- StoreTrack(TrackBuff);
- }
- StoreHeader(HeaderBuff);
- }
-