dos33: re-write mkdos33fs catalog creation a bit more robust

in theory can generate images with non-105 catalog entries
should test this thoroughly
This commit is contained in:
Vince Weaver 2022-09-05 20:47:29 -04:00
parent c2faa9ec61
commit 4cde5ae284
4 changed files with 104 additions and 40 deletions

View File

@ -139,7 +139,7 @@ static int dos33_allocate_sector(int fd, unsigned char *vtoc) {
int result; int result;
/* Find an empty sector */ /* Find an empty sector */
result=dos33_vtoc_find_free_sector(vtoc,&found_track,&found_sector); result=dos33_vtoc_find_free_sector(vtoc,&found_track,&found_sector,0);
if (result<0) { if (result<0) {
fprintf(stderr,"ERROR: dos33_allocate_sector: Disk full!\n"); fprintf(stderr,"ERROR: dos33_allocate_sector: Disk full!\n");

View File

@ -76,7 +76,7 @@ void dos33_vtoc_free_sector(unsigned char *vtoc, int track, int sector);
void dos33_vtoc_reserve_sector(unsigned char *vtoc, int track, int sector); void dos33_vtoc_reserve_sector(unsigned char *vtoc, int track, int sector);
void dos33_vtoc_dump_bitmap(unsigned char *vtoc, int num_tracks); void dos33_vtoc_dump_bitmap(unsigned char *vtoc, int num_tracks);
int dos33_vtoc_find_free_sector(unsigned char *vtoc, int dos33_vtoc_find_free_sector(unsigned char *vtoc,
int *found_track, int *found_sector); int *found_track, int *found_sector, int is_catalog);
/* dos33_catalog.c */ /* dos33_catalog.c */
unsigned char dos33_char_to_type(char type, int lock); unsigned char dos33_char_to_type(char type, int lock);

View File

@ -38,6 +38,19 @@ static int find_first_one(unsigned char byte) {
return i; return i;
} }
static int find_last_one(unsigned char byte) {
int i=7;
if (byte==0) return -1;
while((byte & (0x1<<i))==0) {
i--;
}
return i;
}
/* Return how many bytes free in the filesystem */ /* Return how many bytes free in the filesystem */
/* by reading the VTOC_FREE_BITMAP */ /* by reading the VTOC_FREE_BITMAP */
@ -142,7 +155,7 @@ void dos33_vtoc_dump_bitmap(unsigned char *vtoc, int num_tracks) {
/* reserve a sector in the sector bitmap */ /* reserve a sector in the sector bitmap */
int dos33_vtoc_find_free_sector(unsigned char *vtoc, int dos33_vtoc_find_free_sector(unsigned char *vtoc,
int *found_track, int *found_sector) { int *found_track, int *found_sector, int is_catalog) {
int start_track,track_dir,i; int start_track,track_dir,i;
int bitmap; int bitmap;
@ -168,22 +181,44 @@ int dos33_vtoc_find_free_sector(unsigned char *vtoc,
i=start_track; i=start_track;
do { do {
/* i+1 = sector 0..7 */ /* catalog tracks allocated backwards for some reason */
bitmap=vtoc[VTOC_FREE_BITMAPS+(i*4)+1]; if (is_catalog) {
if (bitmap!=0x00) { /* i+0 = sector 8..15 */
*found_sector=find_first_one(bitmap); bitmap=vtoc[VTOC_FREE_BITMAPS+(i*4)];
*found_track=i; if (bitmap!=0x00) {
found++; *found_sector=find_last_one(bitmap)+8;
break; *found_track=i;
} found++;
break;
}
/* i+0 = sector 8..15 */ /* i+1 = sector 0..7 */
bitmap=vtoc[VTOC_FREE_BITMAPS+(i*4)]; bitmap=vtoc[VTOC_FREE_BITMAPS+(i*4)+1];
if (bitmap!=0x00) { if (bitmap!=0x00) {
*found_sector=find_first_one(bitmap)+8; *found_sector=find_last_one(bitmap);
*found_track=i; *found_track=i;
found++; found++;
break; break;
}
}
else {
/* i+1 = sector 0..7 */
bitmap=vtoc[VTOC_FREE_BITMAPS+(i*4)+1];
if (bitmap!=0x00) {
*found_sector=find_first_one(bitmap);
*found_track=i;
found++;
break;
}
/* i+0 = sector 8..15 */
bitmap=vtoc[VTOC_FREE_BITMAPS+(i*4)];
if (bitmap!=0x00) {
*found_sector=find_first_one(bitmap)+8;
*found_track=i;
found++;
break;
}
} }
/* Move to next track, handling overflows */ /* Move to next track, handling overflows */
@ -202,10 +237,14 @@ int dos33_vtoc_find_free_sector(unsigned char *vtoc,
/* clear bit indicating in use */ /* clear bit indicating in use */
dos33_vtoc_reserve_sector(vtoc, *found_track, *found_sector); dos33_vtoc_reserve_sector(vtoc, *found_track, *found_sector);
/* update last track used and direction */
vtoc[VTOC_LAST_ALLOC_T]=*found_track;
vtoc[VTOC_ALLOC_DIRECT]=track_dir;
return 0; return 0;
} }
/* no room */ /* no room */
return -1; return ERROR_NO_SPACE;
} }

View File

@ -17,12 +17,12 @@ static void usage(char *binary,int help) {
printf("\tby Vince Weaver <vince@deater.net>\n"); printf("\tby Vince Weaver <vince@deater.net>\n");
printf("\thttp://www.deater.net/weave/vmwprod/apple/\n\n"); printf("\thttp://www.deater.net/weave/vmwprod/apple/\n\n");
if (help) { if (help) {
printf("Usage:\t%s [-t track] [-s sector] [-b size] " printf("Usage:\t%s [-d debug] [-t track] [-s sector] [-b size] "
"[-d filename] [-f filename] device_name\n\n",binary); "[-i filename] [-f filename] device_name\n\n",binary);
printf("\t-t tracks : number of tracks (default is 35)\n"); printf("\t-t tracks : number of tracks (default is 35)\n");
printf("\t-s sectors : number of sectors (default is 16)\n"); printf("\t-s sectors : number of sectors (default is 16)\n");
printf("\t-b blocksize : size of sector, in bytes (default is 256)\n"); printf("\t-b blocksize : size of sector, in bytes (default is 256)\n");
printf("\t-d filename : file to copy first 3 tracks over from\n"); printf("\t-i filename : file to copy first 3 tracks over from\n");
printf("\t-f filename : name of BASIC file to autoboot. Default is HELLO\n"); printf("\t-f filename : name of BASIC file to autoboot. Default is HELLO\n");
printf("\t-m maxfiles : maximum files in CATALOG (default is 105)\n"); printf("\t-m maxfiles : maximum files in CATALOG (default is 105)\n");
printf("\t-n volume : volume number (default is 254)\n"); printf("\t-n volume : volume number (default is 254)\n");
@ -36,7 +36,8 @@ int main(int argc, char **argv) {
int num_tracks=35,num_sectors=16,sector_size=256; int num_tracks=35,num_sectors=16,sector_size=256;
int max_files=105,catalog_track=17,vtoc_track=17,volume_number=254; int max_files=105,catalog_track=17,vtoc_track=17,volume_number=254;
int catalog_sectors,current_sector; int catalog_sectors,current_sector,current_track;
int next_track,next_sector;
int max_ts_pairs=255; int max_ts_pairs=255;
int fd,dos_fd; int fd,dos_fd;
char device[BUFSIZ],dos_src[BUFSIZ]; char device[BUFSIZ],dos_src[BUFSIZ];
@ -49,9 +50,12 @@ int main(int argc, char **argv) {
/* Parse Command Line Arguments */ /* Parse Command Line Arguments */
while ((c = getopt (argc, argv,"t:s:b:d:f:m:n:hv"))!=-1) { while ((c = getopt (argc, argv,"t:s:b:df:i:m:n:hv"))!=-1) {
switch (c) { switch (c) {
case 'd':
debug=1;
break;
case 't': case 't':
num_tracks=strtol(optarg,&endptr,10); num_tracks=strtol(optarg,&endptr,10);
if ( endptr == optarg ) usage(argv[0], 1); if ( endptr == optarg ) usage(argv[0], 1);
@ -77,7 +81,7 @@ int main(int argc, char **argv) {
if ( endptr == optarg ) usage(argv[0], 1); if ( endptr == optarg ) usage(argv[0], 1);
break; break;
case 'd': case 'i':
copy_dos=1; copy_dos=1;
strncpy(dos_src,optarg,BUFSIZ-1); strncpy(dos_src,optarg,BUFSIZ-1);
break; break;
@ -186,11 +190,11 @@ int main(int argc, char **argv) {
max_ts_pairs=255; max_ts_pairs=255;
} }
/* default is 105 files (15 catalog sectors) */
catalog_sectors=max_files/7; catalog_sectors=max_files/7;
if (max_files%7) catalog_sectors++; if (max_files%7) catalog_sectors++;
if (catalog_sectors>num_sectors-1) { if (catalog_sectors>num_sectors-1) {
printf("Warning! num_files leads to too many sectors %d, max is %d\n",catalog_sectors,num_sectors-1); printf("Warning! num_files higher than normal %d sectors, ususal is %d\n",catalog_sectors,num_sectors-1);
catalog_sectors=num_sectors-1;
} }
/***************/ /***************/
@ -297,30 +301,49 @@ int main(int argc, char **argv) {
memset(sector_buffer,0,sector_size); memset(sector_buffer,0,sector_size);
/* Set catalog next pointers */ /* Set catalog next pointers */
/* start at T17S15 */
vtoc_buffer[VTOC_LAST_ALLOC_T]=17;
vtoc_buffer[VTOC_ALLOC_DIRECT]=255; /* -1 direction */
/* Get first catalog sector */
if (dos33_vtoc_find_free_sector(vtoc_buffer,
&current_track,&current_sector,1)) {
return ERROR_NO_SPACE;
}
for(i=0;i<catalog_sectors;i++) { for(i=0;i<catalog_sectors;i++) {
/* point to next */ /* point to next */
/* for first sector_size-1 walk backwards from T17S15 */ /* for first sector_size-1 walk backwards from T17S15 */
/* if more, allocate room on disk??? */ /* if more, allocate room on disk */
/* Max on 140k disk is 280 or so */ /* Max on 140k disk is 280 or so */
current_sector=num_sectors-i-1;
if (i==catalog_sectors-1) { if (i==catalog_sectors-1) {
/* last one, pointer is to 0,0 */ /* last one, pointer is to 0,0 */
sector_buffer[1]=0; next_track=0;
sector_buffer[2]=0; next_sector=0;
} }
else { else {
printf("Writing $%02X,$%02X=%d,%d\n", if (dos33_vtoc_find_free_sector(vtoc_buffer,
catalog_track,current_sector, &next_track,&next_sector,1)) {
catalog_track,current_sector-1);
sector_buffer[1]=catalog_track; return ERROR_NO_SPACE;
sector_buffer[2]=current_sector-1; }
} }
/* reserve */ if (debug) {
dos33_vtoc_reserve_sector(vtoc_buffer, printf("Writing catalog track %d at "
catalog_track, current_sector); "T$%02X:S$%02X, next=T$%02X:S$%02X\n",
i,current_track,current_sector,
next_track,next_sector);
}
sector_buffer[1]=next_track;
sector_buffer[2]=next_sector;
lseek(fd,((catalog_track*num_sectors)+current_sector)* lseek(fd,((catalog_track*num_sectors)+current_sector)*
sector_size,SEEK_SET); sector_size,SEEK_SET);
@ -330,6 +353,8 @@ int main(int argc, char **argv) {
current_sector,strerror(errno)); current_sector,strerror(errno));
} }
current_track=next_track;
current_sector=next_sector;
} }
/**************************/ /**************************/