1 /* #includes */ /*{{{C}}}*//*{{{*/
18 /* #defines */ /*{{{*/
24 /* mkfs -- make file system */ /*{{{*/
25 static int mkfs(struct cpmSuperBlock *drive, const char *name, const char *format, const char *label, char *bootTracks, int timeStamps)
27 /* variables */ /*{{{*/
33 unsigned int trkbytes;
36 /* open image file */ /*{{{*/
37 if ((fd = open(name, O_BINARY|O_CREAT|O_WRONLY, 0666)) < 0)
43 /* write system tracks */ /*{{{*/
44 /* this initialises only whole tracks, so it skew is not an issue */
45 trkbytes=drive->secLength*drive->sectrk;
46 for (i=0; i<trkbytes*drive->boottrk; i+=drive->secLength) if (write(fd, bootTracks+i, drive->secLength)!=(ssize_t)drive->secLength)
53 /* write directory */ /*{{{*/
55 bytes=drive->maxdir*32;
56 if (bytes%trkbytes) bytes=((bytes+trkbytes)/trkbytes)*trkbytes;
57 if (timeStamps && (drive->type==CPMFS_P2DOS || drive->type==CPMFS_DR3)) buf[3*32]=0x21;
58 memcpy(firstbuf,buf,128);
59 if (drive->type==CPMFS_DR3)
66 for (i=0; i<11 && *label; ++i,++label) firstbuf[1+i]=toupper(*label&0x7f);
67 while (i<11) firstbuf[1+i++]=' ';
68 firstbuf[12]=timeStamps ? 0x11 : 0x01; /* label set and first time stamp is creation date */
69 memset(&firstbuf[13],0,1+2+8);
77 min=((t->tm_min/10)<<4)|(t->tm_min%10);
78 hour=((t->tm_hour/10)<<4)|(t->tm_hour%10);
79 for (year=1978,days=0; year<1900+t->tm_year; ++year)
82 if (year%4==0 && (year%100!=0 || year%400==0)) ++days;
84 days += t->tm_yday + 1;
85 firstbuf[24]=firstbuf[28]=days&0xff; firstbuf[25]=firstbuf[29]=days>>8;
86 firstbuf[26]=firstbuf[30]=hour;
87 firstbuf[27]=firstbuf[31]=min;
90 for (i=0; i<bytes; i+=128) if (write(fd, i==0 ? firstbuf : buf, 128)!=128)
97 /* close image file */ /*{{{*/
104 if (timeStamps && !(drive->type==CPMFS_P2DOS || drive->type==CPMFS_DR3)) /*{{{*/
107 struct cpmInode ino, root;
108 static const char sig[] = "!!!TIME";
109 unsigned int records;
111 struct cpmSuperBlock super;
114 if ((err=Device_open(&super.dev,name,O_RDWR,NULL)))
116 fprintf(stderr,"%s: can not open %s (%s)\n",cmd,name,err);
119 cpmReadSuper(&super,&root,format);
121 records=root.sb->maxdir/8;
122 if (!(ds=malloc(records*128)))
127 memset(ds,0,records*128);
129 for (i=0; i<records; i++)
131 for (j=0; j<7; j++,offset+=16)
133 *((char*)ds+offset) = sig[j];
135 /* skip checksum byte */
139 /* Set things up so cpmSync will generate checksums and write the
142 if (cpmCreat(&root,"00!!!TIME&.DAT",&ino,0)==-1)
144 fprintf(stderr,"%s: Unable to create DateStamper file: %s\n",cmd,boo);
157 const char cmd[]="mkfs.cpm";
159 int main(int argc, char *argv[]) /*{{{*/
164 struct cpmSuperBlock drive;
165 struct cpmInode root;
166 const char *label="unlabeled";
168 size_t bootTrackSize,used;
170 const char *boot[4]={(const char*)0,(const char*)0,(const char*)0,(const char*)0};
172 if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
173 while ((c=getopt(argc,argv,"b:f:L:th?"))!=EOF) switch(c)
177 if (boot[0]==(const char*)0) boot[0]=optarg;
178 else if (boot[1]==(const char*)0) boot[1]=optarg;
179 else if (boot[2]==(const char*)0) boot[2]=optarg;
180 else if (boot[3]==(const char*)0) boot[3]=optarg;
184 case 'f': format=optarg; break;
185 case 'L': label=optarg; break;
186 case 't': timeStamps=1; break;
188 case '?': usage=1; break;
191 if (optind!=(argc-1)) usage=1;
192 else image=argv[optind++];
196 fprintf(stderr,"Usage: %s [-f format] [-b boot] [-L label] [-t] image\n",cmd);
200 cpmReadSuper(&drive,&root,format);
201 bootTrackSize=drive.boottrk*drive.secLength*drive.sectrk;
202 if ((bootTracks=malloc(bootTrackSize))==(void*)0)
204 fprintf(stderr,"%s: can not allocate boot track buffer: %s\n",cmd,strerror(errno));
207 memset(bootTracks,0xe5,bootTrackSize);
209 for (c=0; c<4 && boot[c]; ++c)
214 if ((fd=open(boot[c],O_BINARY|O_RDONLY))==-1)
216 fprintf(stderr,"%s: can not open %s: %s\n",cmd,boot[c],strerror(errno));
219 size=read(fd,bootTracks+used,bootTrackSize-used);
221 fprintf(stderr,"%d %04x %s\n",c,used+0x800,boot[c]);
223 if (size%drive.secLength) size=(size|(drive.secLength-1))+1;
227 if (mkfs(&drive,image,format,label,bootTracks,timeStamps)==-1)
229 fprintf(stderr,"%s: can not make new file system: %s\n",cmd,boo);