static int dos33_print_file_info(int fd,int catalog_tsf) { int catalog_track,catalog_sector,catalog_file,i; char temp_string[BUFSIZ]; int result; catalog_file=catalog_tsf>>16; catalog_track=(catalog_tsf>>8)&0xff; catalog_sector=(catalog_tsf&0xff); /* Read in Catalog Sector */ lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET); result=read(fd,sector_buffer,BYTES_PER_SECTOR); if (sector_buffer[CATALOG_FILE_LIST+(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE]>0x7f) { printf("*"); } else { printf(" "); } printf("%c",dos33_file_type(sector_buffer[CATALOG_FILE_LIST+(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE])); printf(" "); printf("%.3i ",sector_buffer[CATALOG_FILE_LIST+(catalog_file*CATALOG_ENTRY_SIZE+FILE_SIZE_L)]+ (sector_buffer[CATALOG_FILE_LIST+(catalog_file*CATALOG_ENTRY_SIZE+FILE_SIZE_H)]<<8)); strncpy(temp_string, dos33_filename_to_ascii(temp_string,sector_buffer+(CATALOG_FILE_LIST+ (catalog_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"); if (result<0) fprintf(stderr,"Error on I/O\n"); return 0; }
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; }
/* load a file. fts=entry/track/sector */ static int dos33_load_file(int fd,int fts,char *filename) { int output_fd; int catalog_file,catalog_track,catalog_sector; int file_type,file_size=-1,tsl_track,tsl_sector,data_t,data_s; unsigned char data_sector[BYTES_PER_SECTOR]; int tsl_pointer=0,output_pointer=0; int result; /* Fix me! Warn if overwriting file! */ output_fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666); if (output_fd<0) { fprintf(stderr,"Error! could not open %s for local save\n",filename); return -1; } catalog_file=fts>>16; catalog_track=(fts>>8)&0xff; catalog_sector=(fts&0xff); /* Read in Catalog Sector */ lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET); result=read(fd,sector_buffer,BYTES_PER_SECTOR); tsl_track=sector_buffer[CATALOG_FILE_LIST+ (catalog_file*CATALOG_ENTRY_SIZE)+FILE_TS_LIST_T]; tsl_sector=sector_buffer[CATALOG_FILE_LIST+ (catalog_file*CATALOG_ENTRY_SIZE)+FILE_TS_LIST_S]; file_type=dos33_file_type(sector_buffer[CATALOG_FILE_LIST+ (catalog_file*CATALOG_ENTRY_SIZE) +FILE_TYPE]); // printf("file_type: %c\n",file_type); keep_saving: /* Read in TSL Sector */ lseek(fd,DISK_OFFSET(tsl_track,tsl_sector),SEEK_SET); result=read(fd,sector_buffer,BYTES_PER_SECTOR); tsl_pointer=0; /* check each track/sector pair in the list */ while(tsl_pointer<TSL_MAX_NUMBER) { /* get the t/s value */ data_t=sector_buffer[TSL_LIST+(tsl_pointer*TSL_ENTRY_SIZE)]; data_s=sector_buffer[TSL_LIST+(tsl_pointer*TSL_ENTRY_SIZE)+1]; if ((data_s==0) && (data_t==0)) { /* empty */ } else { lseek(fd,DISK_OFFSET(data_t,data_s),SEEK_SET); result=read(fd,&data_sector,BYTES_PER_SECTOR); /* some file formats have the size in the first sector */ /* so cheat and get real file size from file itself */ if (output_pointer==0) { switch(file_type) { case 'A': case 'I': file_size=data_sector[0]+(data_sector[1]<<8)+2; break; case 'B': file_size=data_sector[2]+(data_sector[3]<<8)+4; break; default: file_size=-1; } } /* write the block read in out to the output file */ lseek(output_fd,output_pointer*BYTES_PER_SECTOR,SEEK_SET); result=write(output_fd,&data_sector,BYTES_PER_SECTOR); } output_pointer++; tsl_pointer++; } /* finished with TSL sector, see if we have another */ tsl_track=sector_buffer[TSL_NEXT_TRACK]; tsl_sector=sector_buffer[TSL_NEXT_SECTOR]; // printf("Next track/sector=%d/%d op=%d\n",tsl_track,tsl_sector, // output_pointer*BYTES_PER_SECTOR); if ((tsl_track==0) && (tsl_sector==0)) { } else goto keep_saving; /* Correct the file size */ if (file_size>=0) { // printf("Truncating file size to %d\n",file_size); result=ftruncate(output_fd,file_size); } if (result<0) fprintf(stderr,"Error on I/O\n"); return 0; }