/* Get a T/S value from a Catalog Sector */ static int dos33_get_catalog_ts(int fd) { dos33_read_vtoc(fd); return TS_TO_INT(sector_buffer[VTOC_CATALOG_T], sector_buffer[VTOC_CATALOG_S]); }
/* returns entry/track/sector */ static int dos33_check_file_exists(int fd, char *filename, int file_deleted) { int catalog_track,catalog_sector; int i,file_track; char file_name[31]; int result; /* read the VTOC into buffer */ dos33_read_vtoc(fd); /* get the catalog track and sector from the VTOC */ catalog_track=sector_buffer[VTOC_CATALOG_T]; catalog_sector=sector_buffer[VTOC_CATALOG_S]; repeat_catalog: /* Read in Catalog Sector */ lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET); result=read(fd,sector_buffer,BYTES_PER_SECTOR); /* scan all file entries in catalog sector */ for(i=0;i<7;i++) { file_track=sector_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)]; /* 0xff means file deleted */ /* 0x0 means empty */ if (file_track!=0x0) { if (file_track==0xff) { dos33_filename_to_ascii(file_name, sector_buffer+(CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE+FILE_NAME)),29); if (file_deleted) { /* return if we found the file */ if (!strncmp(filename,file_name,29)) { return ((i<<16)+(catalog_track<<8)+catalog_sector); } } } else { dos33_filename_to_ascii(file_name, sector_buffer+(CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE+FILE_NAME)),30); /* return if we found the file */ if (!strncmp(filename,file_name,30)) { return ((i<<16)+(catalog_track<<8)+catalog_sector); } } } } /* point to next catalog track/sector */ catalog_track=sector_buffer[CATALOG_NEXT_T]; catalog_sector=sector_buffer[CATALOG_NEXT_S]; if (catalog_sector!=0) goto repeat_catalog; if (result<0) fprintf(stderr,"Error on I/O\n"); return -1; }
/* Calculate available freespace */ static int dos33_free_space(int fd) { unsigned char bitmap[4]; int i,sectors_free=0; /* Read Vtoc */ dos33_read_vtoc(fd); for(i=0;i<TRACKS_PER_DISK;i++) { bitmap[0]=sector_buffer[VTOC_FREE_BITMAPS+(i*4)]; bitmap[1]=sector_buffer[VTOC_FREE_BITMAPS+(i*4)+1]; sectors_free+=ones_lookup[bitmap[0]&0xf]; sectors_free+=ones_lookup[(bitmap[0]>>4)&0xf]; sectors_free+=ones_lookup[bitmap[1]&0xf]; sectors_free+=ones_lookup[(bitmap[1]>>4)&0xf]; } return sectors_free*BYTES_PER_SECTOR; }
static int dos33_allocate_sector(int fd) { int found_track=0,found_sector=0; unsigned char bitmap[4]; int i,start_track,track_dir,byte; int result; dos33_read_vtoc(fd); /* Originally used to keep things near center of disk for speed */ /* We can use to avoid fragmentation possibly */ start_track=sector_buffer[VTOC_LAST_ALLOC_T]%TRACKS_PER_DISK; track_dir=sector_buffer[VTOC_ALLOC_DIRECT]; if (track_dir==255) track_dir=-1; if ((track_dir!=1) && (track_dir!=-1)) { fprintf(stderr,"ERROR! Invalid track dir %i\n",track_dir); } if (((start_track>VTOC_TRACK) && (track_dir!=1)) || ((start_track<VTOC_TRACK) && (track_dir!=-1))) { fprintf(stderr,"Warning! Non-optimal values for track dir t=%i d=%i!\n", start_track,track_dir); } i=start_track; do { for(byte=1;byte>-1;byte--) { bitmap[byte]=sector_buffer[VTOC_FREE_BITMAPS+(i*4)+byte]; if (bitmap[byte]!=0x00) { found_sector=find_first_one(bitmap[byte]); found_track=i; /* clear bit indicating in use */ sector_buffer[VTOC_FREE_BITMAPS+(i*4)+byte]&=~(0x1<<found_sector); found_sector+=(8*(1-byte)); goto found_one; } } /* Move to next track, handling overflows */ i+=track_dir; if (i<0) { i=VTOC_TRACK; track_dir=1; } if (i>=TRACKS_PER_DISK) { i=VTOC_TRACK; track_dir=-1; } } while (i!=start_track); fprintf(stderr,"No room left!\n"); return -1; found_one: /* store new track/direction info */ sector_buffer[VTOC_LAST_ALLOC_T]=found_track; if (found_track>VTOC_TRACK) sector_buffer[VTOC_ALLOC_DIRECT]=1; else sector_buffer[VTOC_ALLOC_DIRECT]=-1; /* Seek to VTOC */ lseek(fd,DISK_OFFSET(VTOC_TRACK,VTOC_SECTOR),SEEK_SET); /* Write out VTOC */ result=write(fd,§or_buffer,BYTES_PER_SECTOR); if (result<0) fprintf(stderr,"Error on I/O\n"); return ((found_track<<8)+found_sector); }
static int dos33_dump(int fd) { int num_tracks,catalog_t,catalog_s,file,ts_t,ts_s,ts_total,track,sector; int i,j; int deleted=0; char temp_string[BUFSIZ]; unsigned char tslist[BYTES_PER_SECTOR]; int result; /* Read Track 1 Sector 9 */ lseek(fd,DISK_OFFSET(1,9),SEEK_SET); result=read(fd,sector_buffer,BYTES_PER_SECTOR); printf("Finding name of startup file, Track 1 Sector 9 offset $75\n"); dump_sector(); printf("Startup Filename: "); for(i=0;i<30;i++) printf("%c",sector_buffer[0x75+i]&0x7f); printf("\n"); dos33_read_vtoc(fd); printf("\nVTOC Sector:\n"); dump_sector(); printf("\n\n"); printf("VTOC INFORMATION:\n"); catalog_t=sector_buffer[VTOC_CATALOG_T]; catalog_s=sector_buffer[VTOC_CATALOG_S]; printf("\tFirst Catalog = %02X/%02X\n",catalog_t,catalog_s); printf("\tDOS RELEASE = 3.%i\n",sector_buffer[VTOC_DOS_RELEASE]); printf("\tDISK VOLUME = %i\n",sector_buffer[VTOC_DISK_VOLUME]); ts_total=sector_buffer[VTOC_MAX_TS_PAIRS]; printf("\tT/S pairs that will fit in T/S List = %i\n",ts_total); printf("\tLast track where sectors were allocated = $%02X\n", sector_buffer[VTOC_LAST_ALLOC_T]); printf("\tDirection of track allocation = %i\n", sector_buffer[VTOC_ALLOC_DIRECT]); num_tracks=sector_buffer[VTOC_NUM_TRACKS]; printf("\tNumber of tracks per disk = %i\n",num_tracks); printf("\tNumber of sectors per track = %i\n", sector_buffer[VTOC_S_PER_TRACK]); printf("\tNumber of bytes per sector = %i\n", (sector_buffer[VTOC_BYTES_PER_SH]<<8)+sector_buffer[VTOC_BYTES_PER_SL]); printf("\nFree sector bitmap:\n"); printf("\tTrack FEDCBA98 76543210\n"); for(i=0;i<num_tracks;i++) { printf("\t $%02X: ",i); for(j=0;j<8;j++) { if ((sector_buffer[VTOC_FREE_BITMAPS+(i*4)]<<j)&0x80) printf("."); else printf("U"); } printf(" "); for(j=0;j<8;j++) { if ((sector_buffer[VTOC_FREE_BITMAPS+(i*4)+1]<<j)&0x80) printf("."); else printf("U"); } printf("\n"); } repeat_catalog: printf("\nCatalog Sector $%02X/$%02x\n",catalog_t,catalog_s); lseek(fd,DISK_OFFSET(catalog_t,catalog_s),SEEK_SET); result=read(fd,sector_buffer,BYTES_PER_SECTOR); dump_sector(); for(file=0;file<7;file++) { printf("\n\n"); ts_t=sector_buffer[(CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE+FILE_TS_LIST_T))]; ts_s=sector_buffer[(CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE+FILE_TS_LIST_S))]; printf("%i+$%02X/$%02X - ",file,catalog_t,catalog_s); deleted=0; if (ts_t==0xff) { printf("**DELETED** "); deleted=1; ts_t=sector_buffer[(CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE+FILE_NAME+0x1e))]; } if (ts_t==0x00) { printf("UNUSED!\n"); goto continue_dump; } strncpy(temp_string,dos33_filename_to_ascii(temp_string, sector_buffer+(CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE+FILE_NAME)),30), BUFSIZ); for(i=0;i<strlen(temp_string);i++) { if (temp_string[i]<0x20) printf("^%c",temp_string[i]+0x40); else printf("%c",temp_string[i]); } printf("\n"); printf("\tLocked = %s\n", sector_buffer[CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE)+FILE_TYPE]>0x7f? "YES":"NO"); printf("\tType = %c\n", dos33_file_type(sector_buffer[CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE)+FILE_TYPE])); printf("\tSize in sectors = %i\n", sector_buffer[CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE+FILE_SIZE_L)]+ (sector_buffer[CATALOG_FILE_LIST+(file*CATALOG_ENTRY_SIZE+FILE_SIZE_H)]<<8)); repeat_tsl: printf("\tT/S List $%02X/$%02X:\n",ts_t,ts_s); if (deleted) goto continue_dump; lseek(fd,DISK_OFFSET(ts_t,ts_s),SEEK_SET); result=read(fd,&tslist,BYTES_PER_SECTOR); for(i=0;i<ts_total;i++) { track=tslist[TSL_LIST+(i*TSL_ENTRY_SIZE)]; sector=tslist[TSL_LIST+(i*TSL_ENTRY_SIZE)+1]; if ((track==0) && (sector==0)) printf("."); else printf("\n\t\t%02X/%02X",track,sector); } ts_t=tslist[TSL_NEXT_TRACK]; ts_s=tslist[TSL_NEXT_SECTOR]; if (!((ts_s==0) && (ts_t==0))) goto repeat_tsl; continue_dump:; } catalog_t=sector_buffer[CATALOG_NEXT_T]; catalog_s=sector_buffer[CATALOG_NEXT_S]; if (catalog_s!=0) { file=0; goto repeat_catalog; } printf("\n"); if (result<0) fprintf(stderr,"Error on I/O\n"); return 0; }