utils: dos33: split off catalog code

This commit is contained in:
Vince Weaver 2021-03-29 16:02:55 -04:00
parent 8e05dc8b32
commit c3a278b76a
4 changed files with 327 additions and 670 deletions

View File

@ -13,8 +13,12 @@ char2hex.o: char2hex.c
###
dos33: dos33.o dos33_vtoc_bitmap.o
$(CC) -o dos33 dos33.o dos33_vtoc_bitmap.o $(LFLAGS)
dos33: dos33.o \
dos33_catalog.o \
dos33_vtoc_bitmap.o
$(CC) -o dos33 dos33.o \
dos33_catalog.o \
dos33_vtoc_bitmap.o $(LFLAGS)
dos33.o: dos33.c dos33.h
$(CC) $(CFLAGS) -g -c dos33.c
@ -59,6 +63,11 @@ dos33_vtoc_bitmap.o: dos33_vtoc_bitmap.c dos33.h
###
dos33_catalog.o: dos33_catalog.c dos33.h
$(CC) $(CFLAGS) -c dos33_catalog.c
###
install:
cp dos33 dos33_raw mkdos33fs make_b dos33_text2ascii char2hex $(INSTALL_LOC)

File diff suppressed because it is too large Load Diff

View File

@ -53,9 +53,20 @@
#define TS_TO_INT(__x,__y) ((((int)__x)<<8)+__y)
#define DISK_OFFSET(__track,__sector) ((((__track)*SECTORS_PER_TRACK)+(__sector))*BYTES_PER_SECTOR)
#define DOS33_FILE_NORMAL 0
#define DOS33_FILE_DELETED 1
/* dos33_vtoc_bitmap.c */
int dos33_vtoc_free_space(unsigned char *vtoc);
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_dump_bitmap(unsigned char *vtoc, int num_tracks);
int dos33_vtoc_find_free_sector(unsigned char *vtoc,
int *found_track, int *found_sector);
/* dos33_catalog.c */
unsigned char dos33_char_to_type(char type, int lock);
void dos33_catalog(int dos_fd, unsigned char *vtoc);
char *dos33_filename_to_ascii(char *dest,unsigned char *src,int len);
unsigned char dos33_file_type(int value);

View File

@ -0,0 +1,178 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "dos33.h"
unsigned char dos33_file_type(int value) {
unsigned char result;
switch(value&0x7f) {
case 0x0: result='T'; break;
case 0x1: result='I'; break;
case 0x2: result='A'; break;
case 0x4: result='B'; break;
case 0x8: result='S'; break;
case 0x10: result='R'; break;
case 0x20: result='N'; break;
case 0x40: result='L'; break;
default: result='?'; break;
}
return result;
}
unsigned char dos33_char_to_type(char type, int lock) {
unsigned char result,temp_type;
temp_type=type;
/* Covert to upper case */
if (temp_type>='a') temp_type=temp_type-0x20;
switch(temp_type) {
case 'T': result=0x0; break;
case 'I': result=0x1; break;
case 'A': result=0x2; break;
case 'B': result=0x4; break;
case 'S': result=0x8; break;
case 'R': result=0x10; break;
case 'N': result=0x20; break;
case 'L': result=0x40; break;
default: result=0x0;
}
if (lock) result|=0x80;
return result;
}
/* dos33 filenames have top bit set on ascii chars */
/* and are padded with spaces */
char *dos33_filename_to_ascii(char *dest,unsigned char *src,int len) {
int i=0,last_nonspace=0;
for(i=0;i<len;i++) if (src[i]!=0xA0) last_nonspace=i;
for(i=0;i<last_nonspace+1;i++) {
dest[i]=src[i]^0x80; /* toggle top bit */
}
dest[i]='\0';
return dest;
}
/* Get a T/S value from a Catalog Sector */
static int dos33_get_catalog_ts(unsigned char *vtoc) {
return TS_TO_INT(vtoc[VTOC_CATALOG_T],vtoc[VTOC_CATALOG_S]);
}
/* returns the next valid catalog entry */
/* after the one passed in */
static int dos33_find_next_file(int fd,int catalog_tsf,unsigned char *vtoc) {
int catalog_track,catalog_sector,catalog_file;
int file_track,i;
int result;
unsigned char sector_buffer[BYTES_PER_SECTOR];
catalog_file=catalog_tsf>>16;
catalog_track=(catalog_tsf>>8)&0xff;
catalog_sector=(catalog_tsf&0xff);
catalog_loop:
/* Read in Catalog Sector */
lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET);
result=read(fd,sector_buffer,BYTES_PER_SECTOR);
i=catalog_file;
while(i<7) {
file_track=sector_buffer[CATALOG_FILE_LIST+
(i*CATALOG_ENTRY_SIZE)];
/* 0xff means file deleted */
/* 0x0 means empty */
if ((file_track!=0xff) && (file_track!=0x0)) {
return ((i<<16)+(catalog_track<<8)+catalog_sector);
}
i++;
}
catalog_track=sector_buffer[CATALOG_NEXT_T];
catalog_sector=sector_buffer[CATALOG_NEXT_S];
if (catalog_sector!=0) {
catalog_file=0;
goto catalog_loop;
}
if (result<0) fprintf(stderr,"Error on I/O\n");
return -1;
}
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;
unsigned char sector_buffer[BYTES_PER_SECTOR];
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));
dos33_filename_to_ascii(temp_string,sector_buffer+(CATALOG_FILE_LIST+
(catalog_file*CATALOG_ENTRY_SIZE+FILE_NAME)),30);
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;
}
void dos33_catalog(int dos_fd, unsigned char *vtoc) {
int catalog_entry;
/* get first catalog */
catalog_entry=dos33_get_catalog_ts(vtoc);
printf("\nDISK VOLUME %i\n\n",vtoc[VTOC_DISK_VOLUME]);
while(catalog_entry>0) {
catalog_entry=dos33_find_next_file(dos_fd,catalog_entry,vtoc);
if (catalog_entry>0) {
dos33_print_file_info(dos_fd,catalog_entry);
/* why 1<<16 ? */
catalog_entry+=(1<<16);
/* dos33_find_next_file() handles wrapping issues */
}
}
printf("\n");
}