diff --git a/utils/prodos-utils/Makefile b/utils/prodos-utils/Makefile index ba43b044..a3ad09c3 100644 --- a/utils/prodos-utils/Makefile +++ b/utils/prodos-utils/Makefile @@ -10,12 +10,14 @@ prodos: prodos.o \ prodos_read.o \ prodos_catalog.o \ prodos_dump.o \ - prodos_volume_bitmap.o + prodos_volume_bitmap.o \ + prodos_voldir.o $(CC) -o prodos prodos.o \ prodos_read.o \ prodos_catalog.o \ prodos_dump.o \ - prodos_volume_bitmap.o $(LFLAGS) + prodos_volume_bitmap.o \ + prodos_voldir.o $(LFLAGS) prodos.o: prodos.c prodos.h $(CC) $(CFLAGS) -g -c prodos.c @@ -46,9 +48,11 @@ text_to_prodos.o: text_to_prodos.c ### -mkprodosfs: mkprodosfs.o prodos_read.o prodos_volume_bitmap.o +mkprodosfs: mkprodosfs.o prodos_read.o prodos_volume_bitmap.o \ + prodos_voldir.o $(CC) $(LFLAGS) -o mkprodosfs mkprodosfs.o \ - prodos_read.o prodos_volume_bitmap.o + prodos_read.o prodos_volume_bitmap.o \ + prodos_voldir.o mkprodosfs.o: mkprodosfs.c prodos.h $(CC) $(CFLAGS) -c mkprodosfs.c @@ -75,6 +79,12 @@ prodos_read.o: prodos_read.c prodos.h ### +prodos_voldir.o: prodos_voldir.c prodos.h + $(CC) $(CFLAGS) -c prodos_voldir.c + + +### + install: cp prodos mkprodosfs prodoscat text_to_prodos $(INSTALL_LOC) diff --git a/utils/prodos-utils/mkprodosfs.c b/utils/prodos-utils/mkprodosfs.c index d1d6a342..300aa85e 100644 --- a/utils/prodos-utils/mkprodosfs.c +++ b/utils/prodos-utils/mkprodosfs.c @@ -9,7 +9,11 @@ #include "prodos.h" -int debug=0; +int debug=1; + +static int ones_lookup[8]={ + 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, +}; static void usage(char *binary,int help) { @@ -17,15 +21,12 @@ static void usage(char *binary,int help) { printf("\tby Vince Weaver \n"); printf("\thttp://www.deater.net/weave/vmwprod/apple/\n\n"); if (help) { - printf("Usage:\t%s [-t track] [-s sector] [-b size] " - "[-d filename] [-f filename] device_name\n\n",binary); - printf("\t-t tracks : number of tracks (default is 35)\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-d 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-m maxfiles : maximum files in CATALOG (default is 105)\n"); - printf("\t-n volume : volume number (default is 254)\n"); + printf("Usage:\t%s [-b size] [-i interleave] " + "[-s bootsector] device_name\n\n",binary); + printf("\t-b size : size of image, in 512B blocks\n"); + printf("\t-i interleave : PRODOS (default) or DOS33\n"); + printf("\t-s filename : bootsector\n"); + printf("\t-n volume : volume name\n"); printf("\n\n"); } exit(0); @@ -34,61 +35,52 @@ static void usage(char *binary,int help) { int main(int argc, char **argv) { - int num_tracks=35,num_sectors=16,sector_size=256; - int max_files=105,catalog_track=17,vtoc_track=17,volume_number=254; - int catalog_sectors,current_sector; - int max_ts_pairs=255; - int fd,dos_fd; - char device[BUFSIZ],dos_src[BUFSIZ]; - unsigned char *vtoc_buffer=NULL,*sector_buffer=NULL; + int num_blocks=280; + int fd; + char device[BUFSIZ]; char *endptr; - int i,c,copy_dos=0; + int i,j,c; int result; + unsigned char data_buffer[PRODOS_BYTES_PER_BLOCK]; + struct voldir_t voldir; + char volname[PRODOS_VOLNAME_LEN]; + int volname_len; + int interleave=PRODOS_INTERLEAVE_PRODOS; + int num_voldirs=4,num_bitmaps,num_bitmap_blocks,ones_to_write; - char boot_filename[30]="HELLO "; + strncpy(volname,"EMPTY",6); + volname_len=strlen(volname); /* Parse Command Line Arguments */ - while ((c = getopt (argc, argv,"t:s:b:d:f:m:n:hv"))!=-1) { + while ((c = getopt (argc, argv,"b:i:s:n:hv"))!=-1) { switch (c) { - - case 't': - num_tracks=strtol(optarg,&endptr,10); - if ( endptr == optarg ) usage(argv[0], 1); - break; - - case 's': - num_sectors=strtol(optarg,&endptr,10); - if ( endptr == optarg ) usage(argv[0], 1); - break; - case 'b': - sector_size=strtol(optarg,&endptr,10); + num_blocks=strtol(optarg,&endptr,10); if ( endptr == optarg ) usage(argv[0], 1); break; - - case 'm': - max_files=strtol(optarg,&endptr,10); - if ( endptr == optarg ) usage(argv[0], 1); - break; - - case 'n': - volume_number=strtol(optarg,&endptr,10); - if ( endptr == optarg ) usage(argv[0], 1); - break; - - case 'd': - copy_dos=1; - strncpy(dos_src,optarg,BUFSIZ-1); - break; - case 'f': - if (strlen(optarg)>30) { - fprintf(stderr,"Auto boot filename too long!\n"); - exit(1); + case 'i': + if (!strncasecmp(optarg,"prodos",6)) { + interleave=PRODOS_INTERLEAVE_PRODOS; } - memcpy(boot_filename,optarg,strlen(optarg)); - for(i=strlen(optarg);i<30;i++) boot_filename[i]=' '; -// printf("Writing boot filename \"%s\"\n",boot_filename); + else if (!strncasecmp(optarg,"dos33",5)) { + interleave=PRODOS_INTERLEAVE_DOS33; + } + else { + fprintf(stderr,"Error! Unknown interleave: %s\n",optarg); + } + break; + case 's': + fprintf(stderr,"Error! -s not implemented yet!\n"); + break; + case 'n': + memset(volname,0,sizeof(volname)); + volname_len=strlen(optarg); + if (volname_len>PRODOS_VOLNAME_LEN) { + fprintf(stderr,"Volname: %s is too long!\n",optarg); + return -1; + } + memcpy(volname,optarg,volname_len); break; case 'v': usage(argv[0],0); case 'h': usage(argv[0],1); @@ -107,41 +99,11 @@ int main(int argc, char **argv) { /***********************/ /* sectors: 2->32 (limited by 4-byte bitfields) */ - if ((num_sectors<2) || (num_sectors>32)) { - printf("Number of sectors must be >2 and <=32\n\n"); + if ((num_blocks<6) || (num_blocks>65536)) { + printf("Number of blocks must be >2 and <65536\n\n"); goto end_of_program; } - /* tracks 18-50 ->(sector_size-0x38)/4 */ - /* limited by VTOC room for freespace bitmap (which is $38 to $ff) */ - /* VOTC is always on track 17 so we need at least that many */ - /* though could double if we used the unused sector fields */ - if ((num_tracks(sector_size-0x38)/4)) { - printf("Number of tracks must be >%d and <=%i\n\n", - vtoc_track,(sector_size-0x38)/4); - goto end_of_program; - } - - /* sector_size 256->65536 (or 512 based on one byte t/s size field?) */ - if ((sector_size<256)||(sector_size>65536)) { - printf("Block size must be >=256 and <65536\n\n"); - goto end_of_program; - } - - /* allocate space for buffers */ - vtoc_buffer=calloc(1,sizeof(char)*sector_size); - if (vtoc_buffer==NULL) { - fprintf(stderr,"Error allocating memory!\n"); - goto end_of_program; - } - - sector_buffer=calloc(1,sizeof(char)*sector_size); - if (sector_buffer==NULL) { - fprintf(stderr,"Error allocating memory!\n"); - goto end_of_program; - } - - /* Open device */ fd=open(device,O_RDWR|O_CREAT,0666); if (fd<0) { @@ -150,205 +112,129 @@ int main(int argc, char **argv) { goto end_of_program; } -#if 0 - /* zero out file */ - for(i=0;i255) { - printf("Warning! Truncating volume number %d to %d\n", - volume_number,volume_number&0xff); - volume_number&=0xff; - } - - if (catalog_track>num_tracks) { - printf("Warning! Catalog track too high! Adjusting...\n"); - catalog_track=(num_tracks/2)+1; - } - - if (vtoc_track>num_tracks) { - printf("Warning! VTOC track too high! Adjusting...\n"); - vtoc_track=(num_tracks/2)+1; - } - - if (vtoc_track!=17) { - printf("Warning! VTOC track is %d, not 17, so unpatched DOS won't be able to find it!\n", - vtoc_track); - } - - max_ts_pairs=((sector_size-0xc)/2); - if (max_ts_pairs>255) { - printf("Warning! Truncating max_ts pairs to 255\n"); - max_ts_pairs=255; - } - - catalog_sectors=max_files/7; - if (max_files%7) catalog_sectors++; - 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); - catalog_sectors=num_sectors-1; - } - - /***************/ - /* Create VTOC */ - /***************/ - - /* fake dos 3.3 */ - vtoc_buffer[VTOC_DOS_RELEASE]=0x3; - - /* 1st Catalog typically at 0x11/0xf */ - vtoc_buffer[VTOC_CATALOG_T]=catalog_track; - vtoc_buffer[VTOC_CATALOG_S]=num_sectors-1; - - /* typically volume is 254 */ - vtoc_buffer[VTOC_DISK_VOLUME]=volume_number; - - /* Number of T/S pairs fitting */ - /* in a T/S list sector */ - /* Note, overflows if sector_size>524 */ - vtoc_buffer[VTOC_MAX_TS_PAIRS]=max_ts_pairs; - - /* last track space was allocated on */ - /* so filesystem can try to do things in order */ - /* also start at catalog track and work our way outward */ - vtoc_buffer[VTOC_LAST_ALLOC_T]=catalog_track+1; - vtoc_buffer[VTOC_ALLOC_DIRECT]=1; - - vtoc_buffer[VTOC_NUM_TRACKS]=num_tracks; - vtoc_buffer[VTOC_S_PER_TRACK]=num_sectors; - vtoc_buffer[VTOC_BYTES_PER_SL]=sector_size&0xff; - vtoc_buffer[VTOC_BYTES_PER_SH]=(sector_size>>8)&0xff; - - /* Set sector bitmap so whole disk is free */ - for(i=VTOC_FREE_BITMAPS;i16) { - vtoc_buffer[i+2]=0xff; - vtoc_buffer[i+3]=0xff; - } - } - - - /* Copy over OS from elsewhere, if desired */ - if (copy_dos) { - dos_fd=open(dos_src,O_RDONLY); - if (fd<0) { - fprintf(stderr,"Error opening %s\n",dos_src); - goto end_of_program; - } - lseek(fd,0,SEEK_SET); - /* copy first 3 sectors */ - for(i=0;i<3*(num_sectors);i++) { - result=read(dos_fd,vtoc_buffer,sector_size); - result=write(fd,vtoc_buffer,sector_size); - } - close(dos_fd); - - /* Set boot filename */ - - /* Track 1 sector 9 */ - lseek(fd,((1*num_sectors)+9)*sector_size,SEEK_SET); - result=read(fd,vtoc_buffer,sector_size); - - /* filename begins at offset 75 */ - for(i=0;i<30;i++) { - vtoc_buffer[0x75+i]=boot_filename[i]|0x80; - } - lseek(fd,((1*num_sectors)+9)*sector_size,SEEK_SET); - result=write(fd,vtoc_buffer,sector_size); - - /* if copying dos reserve tracks 1 and 2 as well */ - - vtoc_buffer[VTOC_FREE_BITMAPS+4]=0x00; - vtoc_buffer[VTOC_FREE_BITMAPS+5]=0x00; - vtoc_buffer[VTOC_FREE_BITMAPS+6]=0x00; - vtoc_buffer[VTOC_FREE_BITMAPS+7]=0x00; - vtoc_buffer[VTOC_FREE_BITMAPS+8]=0x00; - vtoc_buffer[VTOC_FREE_BITMAPS+9]=0x00; - vtoc_buffer[VTOC_FREE_BITMAPS+10]=0x00; - vtoc_buffer[VTOC_FREE_BITMAPS+11]=0x00; - - } - - - /* reserve track 0 */ - /* No user data can be stored here as track=0 is used */ - /* as a special-case end of file indicator */ - for(i=0;i0) { + data_buffer[0]=(PRODOS_VOLDIR_KEY_BLOCK+i-1)&0xff; + data_buffer[1]=(PRODOS_VOLDIR_KEY_BLOCK+i-1)>>8; + } + /* next */ + if (i>8; + } + result=prodos_write_block(&voldir,data_buffer,i+PRODOS_VOLDIR_KEY_BLOCK); + } + + /*********************************/ + /* create the bitmaps */ + /*********************************/ + num_bitmaps=num_blocks/8; + num_bitmap_blocks=1+((num_bitmaps-1)/512); + + for(i=0;inum_blocks) { + ones_to_write=512; } else { - printf("Writing $%02X,$%02X=%d,%d\n", - catalog_track,current_sector, - catalog_track,current_sector-1); - sector_buffer[1]=catalog_track; - sector_buffer[2]=current_sector-1; + ones_to_write=num_blocks%(512*8); } - /* reserve */ - dos33_vtoc_reserve_sector(vtoc_buffer, - catalog_track, current_sector); + if (debug) printf("Writing %d ones\n",ones_to_write); - lseek(fd,((catalog_track*num_sectors)+current_sector)* - sector_size,SEEK_SET); - result=write(fd,sector_buffer,sector_size); - if (result!=sector_size) { - fprintf(stderr,"Error writing catalog sector %d! (%s)\n", - current_sector,strerror(errno)); + for(j=0;jinterleave=interleave; - voldir->image_offset=image_offset; - - /* read in VOLDIR KEY Block*/ - voldir->fd=fd; - result=prodos_read_block(voldir,voldir_buffer,PRODOS_VOLDIR_KEY_BLOCK); - - if (result<0) { - fprintf(stderr,"Error reading VOLDIR\n"); - return -1; - } - - voldir->fd=fd; - - voldir->storage_type=(voldir_buffer[0x4]>>4)&0xf; - voldir->name_length=(voldir_buffer[0x4]&0xf); - if (voldir->storage_type!=0xf) { - fprintf(stderr,"ERROR! Expected storage type F\n"); - } - - memcpy(voldir->volume_name,&voldir_buffer[0x5],voldir->name_length); - voldir->volume_name[voldir->name_length]=0; - - voldir->creation_time=(voldir_buffer[0x1c]<<16)| - (voldir_buffer[0x1d]<<24)| - (voldir_buffer[0x1e]<<0)| - (voldir_buffer[0x1f]<<8); - - voldir->version=voldir_buffer[0x20]; - voldir->min_version=voldir_buffer[0x21]; - voldir->access=voldir_buffer[0x22]; - voldir->entry_length=voldir_buffer[0x23]; - - if (voldir->entry_length!=PRODOS_FILE_DESC_LEN) { - printf("Error! Unexpected desc len %d\n", - voldir->entry_length); - } - - voldir->entries_per_block=voldir_buffer[0x24]; - voldir->file_count=voldir_buffer[0x25]|(voldir_buffer[0x26]<<8); - voldir->bit_map_pointer=voldir_buffer[0x27]|(voldir_buffer[0x28]<<8); - voldir->total_blocks=voldir_buffer[0x29]|(voldir_buffer[0x2A]<<8); - voldir->next_block=voldir_buffer[0x2]|(voldir_buffer[0x3]<<8); - - return 0; -} - /* Given filename, return voldir/offset */ static int prodos_lookup_file(struct voldir_t *voldir, @@ -480,6 +426,10 @@ static int prodos_add_file(struct voldir_t *voldir, /* write back existing voldir entry */ result=prodos_write_block(voldir,data_buffer,inode>>8); + /* update file count */ + voldir->file_count++; + prodos_sync_voldir(voldir); + return 0; } @@ -900,66 +850,6 @@ static int truncate_filename(char *out, char *in) { return truncated; } -static int prodos_sync_voldir(struct voldir_t *voldir) { - - unsigned char newvoldir[PRODOS_BYTES_PER_BLOCK]; - - memset(newvoldir,0,PRODOS_BYTES_PER_BLOCK); - - newvoldir[0x4]=(voldir->storage_type<<4)|(voldir->name_length&0xf); - memcpy(&newvoldir[0x5],voldir->volume_name,voldir->name_length); - - /* FIXME: probably endianess issues */ - - newvoldir[0x1c]=(voldir->creation_time>>16)&0xff; - newvoldir[0x1d]=(voldir->creation_time>>24)&0xff; - newvoldir[0x1e]=(voldir->creation_time>>0)&0xff; - newvoldir[0x1f]=(voldir->creation_time>>8)&0xff; - - newvoldir[0x20]=voldir->version; - newvoldir[0x21]=voldir->min_version; - newvoldir[0x22]=voldir->access; - newvoldir[0x23]=voldir->entry_length; - - newvoldir[0x24]=voldir->entries_per_block; - - newvoldir[0x25]=voldir->file_count&0xff; - newvoldir[0x26]=(voldir->file_count>>8)&0xff; - - newvoldir[0x27]=voldir->bit_map_pointer&0xff; - newvoldir[0x28]=(voldir->bit_map_pointer>>8)&0xff; - - newvoldir[0x29]=voldir->total_blocks&0xff; - newvoldir[0x2A]=(voldir->total_blocks>>8)&0xff; - - newvoldir[0x2]=voldir->next_block&0xff; - newvoldir[0x3]=(voldir->next_block>>8)&0xff; - - prodos_write_block(voldir,newvoldir,PRODOS_VOLDIR_KEY_BLOCK); - - return 0; - -} - -static int change_volume_name(struct voldir_t *voldir, char *volname) { - - int volname_len; - - volname_len=strlen(volname); - if (volname_len>15) { - printf("Warning! Volume name %s is too long, truncating\n", - volname); - volname_len=15; - } - - memcpy(voldir->volume_name,volname,15); - voldir->name_length=volname_len; - - prodos_sync_voldir(voldir); - - return 0; - -} int main(int argc, char **argv) { @@ -1387,7 +1277,7 @@ int main(int argc, char **argv) { goto exit_and_close; } - change_volume_name(&voldir,argv[optind]); + prodos_change_volume_name(&voldir,argv[optind]); break; diff --git a/utils/prodos-utils/prodos.h b/utils/prodos-utils/prodos.h index 9a430409..eaf43f4b 100644 --- a/utils/prodos-utils/prodos.h +++ b/utils/prodos-utils/prodos.h @@ -1,9 +1,10 @@ /* For now hard-coded */ /* Could be made dynamic if we want to be useful */ /* On dos3.2 disks, or larger filesystems */ -#define TRACKS_PER_DISK 0x23 -#define BLOCKS_PER_TRACK 0x8 + #define PRODOS_BYTES_PER_BLOCK 0x200 +#define PRODOS_VOLNAME_LEN 15 +#define PRODOS_FILENAME_LEN 15 #define PRODOS_INTERLEAVE_PRODOS 0x0 #define PRODOS_INTERLEAVE_DOS33 0x1 @@ -86,3 +87,9 @@ int prodos_showfree(struct voldir_t *voldir, int fd); /* prodos_read.c */ int prodos_read_block(struct voldir_t *voldir,unsigned char *block, int blocknum); int prodos_write_block(struct voldir_t *voldir,unsigned char *block, int blocknum); + +/* prodos_voldir.c */ +int prodos_sync_voldir(struct voldir_t *voldir); +int prodos_change_volume_name(struct voldir_t *voldir, char *volname); +int prodos_read_voldir(int fd, struct voldir_t *voldir, + int interleave, int image_offset); diff --git a/utils/prodos-utils/prodos_voldir.c b/utils/prodos-utils/prodos_voldir.c new file mode 100644 index 00000000..86ba4066 --- /dev/null +++ b/utils/prodos-utils/prodos_voldir.c @@ -0,0 +1,131 @@ +#include +#include /* exit() */ +#include /* strncpy() */ +#include /* struct stat */ +#include /* O_RDONLY */ +#include /* lseek() */ +#include /* toupper() */ +#include + +#include "version.h" + +#include "prodos.h" + +extern int debug; + + /* Read volume directory into a buffer */ +int prodos_read_voldir(int fd, struct voldir_t *voldir, + int interleave, int image_offset) { + + int result; + unsigned char voldir_buffer[PRODOS_BYTES_PER_BLOCK]; + + voldir->interleave=interleave; + voldir->image_offset=image_offset; + + /* read in VOLDIR KEY Block*/ + voldir->fd=fd; + result=prodos_read_block(voldir,voldir_buffer,PRODOS_VOLDIR_KEY_BLOCK); + + if (result<0) { + fprintf(stderr,"Error reading VOLDIR\n"); + return -1; + } + + voldir->fd=fd; + + voldir->storage_type=(voldir_buffer[0x4]>>4)&0xf; + voldir->name_length=(voldir_buffer[0x4]&0xf); + if (voldir->storage_type!=0xf) { + fprintf(stderr,"ERROR! Expected storage type F\n"); + } + + memcpy(voldir->volume_name,&voldir_buffer[0x5],voldir->name_length); + voldir->volume_name[voldir->name_length]=0; + + voldir->creation_time=(voldir_buffer[0x1c]<<16)| + (voldir_buffer[0x1d]<<24)| + (voldir_buffer[0x1e]<<0)| + (voldir_buffer[0x1f]<<8); + + voldir->version=voldir_buffer[0x20]; + voldir->min_version=voldir_buffer[0x21]; + voldir->access=voldir_buffer[0x22]; + voldir->entry_length=voldir_buffer[0x23]; + + if (voldir->entry_length!=PRODOS_FILE_DESC_LEN) { + printf("Error! Unexpected desc len %d\n", + voldir->entry_length); + } + + voldir->entries_per_block=voldir_buffer[0x24]; + voldir->file_count=voldir_buffer[0x25]|(voldir_buffer[0x26]<<8); + voldir->bit_map_pointer=voldir_buffer[0x27]|(voldir_buffer[0x28]<<8); + voldir->total_blocks=voldir_buffer[0x29]|(voldir_buffer[0x2A]<<8); + voldir->next_block=voldir_buffer[0x2]|(voldir_buffer[0x3]<<8); + + return 0; +} + + + +int prodos_sync_voldir(struct voldir_t *voldir) { + + unsigned char newvoldir[PRODOS_BYTES_PER_BLOCK]; + + memset(newvoldir,0,PRODOS_BYTES_PER_BLOCK); + + newvoldir[0x4]=(voldir->storage_type<<4)|(voldir->name_length&0xf); + memcpy(&newvoldir[0x5],voldir->volume_name,voldir->name_length); + + /* FIXME: probably endianess issues */ + + newvoldir[0x1c]=(voldir->creation_time>>16)&0xff; + newvoldir[0x1d]=(voldir->creation_time>>24)&0xff; + newvoldir[0x1e]=(voldir->creation_time>>0)&0xff; + newvoldir[0x1f]=(voldir->creation_time>>8)&0xff; + + newvoldir[0x20]=voldir->version; + newvoldir[0x21]=voldir->min_version; + newvoldir[0x22]=voldir->access; + newvoldir[0x23]=voldir->entry_length; + + newvoldir[0x24]=voldir->entries_per_block; + + newvoldir[0x25]=voldir->file_count&0xff; + newvoldir[0x26]=(voldir->file_count>>8)&0xff; + + newvoldir[0x27]=voldir->bit_map_pointer&0xff; + newvoldir[0x28]=(voldir->bit_map_pointer>>8)&0xff; + + newvoldir[0x29]=voldir->total_blocks&0xff; + newvoldir[0x2A]=(voldir->total_blocks>>8)&0xff; + + newvoldir[0x2]=voldir->next_block&0xff; + newvoldir[0x3]=(voldir->next_block>>8)&0xff; + + prodos_write_block(voldir,newvoldir,PRODOS_VOLDIR_KEY_BLOCK); + + return 0; + +} + +int prodos_change_volume_name(struct voldir_t *voldir, char *volname) { + + int volname_len; + + volname_len=strlen(volname); + if (volname_len>15) { + printf("Warning! Volume name %s is too long, truncating\n", + volname); + volname_len=15; + } + + memcpy(voldir->volume_name,volname,15); + voldir->name_length=volname_len; + + prodos_sync_voldir(voldir); + + return 0; + +}