1 /* #includes */ /*{{{C}}}*//*{{{*/
10 extern int optind,opterr,optopt;
11 int getopt(int argc, char * const *argv, const char *optstring);
15 /* #defines */ /*{{{*/
21 /* mkfs -- make file system */ /*{{{*/
22 static int mkfs(struct cpmSuperBlock *drive, const char *name, const char *label, char *bootTracks)
24 /* variables */ /*{{{*/
33 /* open image file */ /*{{{*/
34 if ((fd = open(name, O_BINARY|O_CREAT|O_WRONLY, 0666)) < 0)
40 /* write system tracks */ /*{{{*/
41 /* this initialises only whole tracks, so it skew is not an issue */
42 trkbytes=drive->secLength*drive->sectrk;
43 for (i=0; i<trkbytes*drive->boottrk; i+=drive->secLength) if (write(fd, bootTracks+i, drive->secLength)!=drive->secLength)
50 /* write directory */ /*{{{*/
52 bytes=drive->maxdir*32;
53 if (bytes%trkbytes) bytes=((bytes+trkbytes)/trkbytes)*trkbytes;
54 if (drive->type==CPMFS_P2DOS || drive->type==CPMFS_DR3) buf[3*32]=0x21;
55 memcpy(firstbuf,buf,128);
56 if (drive->type==CPMFS_DR3)
63 for (i=0; i<11 && *label; ++i,++label) firstbuf[1+i]=toupper(*label&0x7f);
64 while (i<11) firstbuf[1+i++]=' ';
65 firstbuf[12]=0x11; /* label set and first time stamp is creation date */
66 memset(&firstbuf[13],0,1+2+8);
69 min=((t->tm_min/10)<<4)|(t->tm_min%10);
70 hour=((t->tm_hour/10)<<4)|(t->tm_hour%10);
71 for (i=1978,days=0; i < 1900 + t->tm_year; ++i)
74 if (i%4==0 && (i%100!=0 || i%400==0)) ++days;
76 days += t->tm_yday + 1;
77 firstbuf[24]=firstbuf[28]=days&0xff; firstbuf[25]=firstbuf[29]=days>>8;
78 firstbuf[26]=firstbuf[30]=hour;
79 firstbuf[27]=firstbuf[31]=min;
81 for (i=0; i < bytes; i += 128) if (write(fd, i==0 ? firstbuf : buf, 128)!=128)
88 /* close image file */ /*{{{*/
99 const char cmd[]="mkfs.cpm";
101 int main(int argc, char *argv[]) /*{{{*/
104 const char *format=FORMAT;
106 struct cpmSuperBlock drive;
107 struct cpmInode root;
108 const char *label="unlabeled";
109 size_t bootTrackSize,used;
111 const char *boot[4]={(const char*)0,(const char*)0,(const char*)0,(const char*)0};
113 while ((c=getopt(argc,argv,"b:f:L:h?"))!=EOF) switch(c)
117 if (boot[0]==(const char*)0) boot[0]=optarg;
118 else if (boot[1]==(const char*)0) boot[1]=optarg;
119 else if (boot[2]==(const char*)0) boot[2]=optarg;
120 else if (boot[3]==(const char*)0) boot[3]=optarg;
124 case 'f': format=optarg; break;
125 case 'L': label=optarg; break;
127 case '?': usage=1; break;
130 if (optind!=(argc-1)) usage=1;
131 else image=argv[optind];
135 fprintf(stderr,"Usage: %s [-f format] [-b boot] [-L label] image\n",cmd);
139 cpmReadSuper(&drive,&root,format);
140 bootTrackSize=drive.boottrk*drive.secLength*drive.sectrk;
141 if ((bootTracks=malloc(bootTrackSize))==(void*)0)
143 fprintf(stderr,"%s: can not allocate boot track buffer: %s\n",cmd,strerror(errno));
146 memset(bootTracks,0xe5,bootTrackSize);
148 for (c=0; c<4 && boot[c]; ++c)
153 if ((fd=open(boot[c],O_BINARY|O_RDONLY))==-1)
155 fprintf(stderr,"%s: can not open %s: %s\n",cmd,boot[c],strerror(errno));
158 size=read(fd,bootTracks+used,bootTrackSize-used);
160 fprintf(stderr,"%d %04x %s\n",c,used+0x800,boot[c]);
162 if (size%drive.secLength) size=(size|(drive.secLength-1))+1;
166 if (mkfs(&drive,image,label,bootTracks)==-1)
168 fprintf(stderr,"%s: can not make new file system: %s\n",cmd,boo);