prodos: working on volume bitmaps

This commit is contained in:
Vince Weaver
2021-07-27 01:57:00 -04:00
parent a889cbd1aa
commit 87b44bb7f3
8 changed files with 169 additions and 125 deletions

View File

@@ -5,10 +5,12 @@ all: prodos mkprodosfs
### ###
prodos: prodos.o \ prodos: prodos.o \
prodos_read.o \
prodos_catalog.o \ prodos_catalog.o \
prodos_dump.o \ prodos_dump.o \
prodos_volume_bitmap.o prodos_volume_bitmap.o
$(CC) -o prodos prodos.o \ $(CC) -o prodos prodos.o \
prodos_read.o \
prodos_catalog.o \ prodos_catalog.o \
prodos_dump.o \ prodos_dump.o \
prodos_volume_bitmap.o $(LFLAGS) prodos_volume_bitmap.o $(LFLAGS)
@@ -19,9 +21,9 @@ prodos.o: prodos.c prodos.h
### ###
mkprodosfs: mkprodosfs.o prodos_volume_bitmap.o mkprodosfs: mkprodosfs.o prodos_read.o prodos_volume_bitmap.o
$(CC) $(LFLAGS) -o mkprodosfs mkprodosfs.o \ $(CC) $(LFLAGS) -o mkprodosfs mkprodosfs.o \
prodos_volume_bitmap.o prodos_read.o prodos_volume_bitmap.o
mkprodosfs.o: mkprodosfs.c prodos.h mkprodosfs.o: mkprodosfs.c prodos.h
$(CC) $(CFLAGS) -c mkprodosfs.c $(CC) $(CFLAGS) -c mkprodosfs.c
@@ -43,6 +45,11 @@ prodos_dump.o: prodos_dump.c prodos.h
### ###
prodos_read.o: prodos_read.c prodos.h
$(CC) $(CFLAGS) -c prodos_read.c
###
install: install:
cp prodos prodos_raw mkprodosfs make_b prodos_text2ascii char2hex $(INSTALL_LOC) cp prodos prodos_raw mkprodosfs make_b prodos_text2ascii char2hex $(INSTALL_LOC)

View File

@@ -148,6 +148,7 @@ int main(int argc, char **argv) {
goto end_of_program; goto end_of_program;
} }
#if 0
/* zero out file */ /* zero out file */
for(i=0;i<num_tracks*num_sectors;i++) { for(i=0;i<num_tracks*num_sectors;i++) {
result=write(fd,vtoc_buffer,sector_size); result=write(fd,vtoc_buffer,sector_size);
@@ -339,7 +340,7 @@ int main(int argc, char **argv) {
fprintf(stderr,"Error writing VTOC (%s)!\n",strerror(errno)); fprintf(stderr,"Error writing VTOC (%s)!\n",strerror(errno));
} }
#endif
close(fd); close(fd);

View File

@@ -21,26 +21,6 @@ static unsigned char get_low_byte(int value) {
return (value&0xff); return (value&0xff);
} }
int prodos_read_block(int fd,unsigned char *block, int blocknum) {
int result;
/* Note, we need to handle interleave, etc */
/* For now assume it's linear */
/* Seek to VOLDIR */
lseek(fd,blocknum*PRODOS_BYTES_PER_BLOCK,SEEK_SET);
result=read(fd,block,PRODOS_BYTES_PER_BLOCK);
if (result<PRODOS_BYTES_PER_BLOCK) {
fprintf(stderr,"Error reading block %d\n",blocknum);
return -1;
}
return 0;
}
/* Read volume directory into a buffer */ /* Read volume directory into a buffer */
static int prodos_read_voldir(int fd, struct voldir_t *voldir) { static int prodos_read_voldir(int fd, struct voldir_t *voldir) {
@@ -48,13 +28,16 @@ static int prodos_read_voldir(int fd, struct voldir_t *voldir) {
unsigned char voldir_buffer[PRODOS_BYTES_PER_BLOCK]; unsigned char voldir_buffer[PRODOS_BYTES_PER_BLOCK];
/* read in VOLDIR */ /* read in VOLDIR */
result=prodos_read_block(fd,voldir_buffer,PRODOS_VOLDIR_BLOCK); voldir->fd=fd;
result=prodos_read_block(voldir,voldir_buffer,PRODOS_VOLDIR_BLOCK);
if (result<0) { if (result<0) {
fprintf(stderr,"Error reading VOLDIR\n"); fprintf(stderr,"Error reading VOLDIR\n");
return -1; return -1;
} }
voldir->fd=fd;
voldir->storage_type=(voldir_buffer[0x4]>>4)&0xf; voldir->storage_type=(voldir_buffer[0x4]>>4)&0xf;
voldir->name_length=(voldir_buffer[0x4]&0xf); voldir->name_length=(voldir_buffer[0x4]&0xf);
if (voldir->storage_type!=0xf) { if (voldir->storage_type!=0xf) {
@@ -85,7 +68,7 @@ static int prodos_read_voldir(int fd, struct voldir_t *voldir) {
/* Checks if "filename" exists */ /* Checks if "filename" exists */
/* returns entry/track/sector */ /* returns entry/track/sector */
static int dos33_check_file_exists(int fd, static int prodos_check_file_exists(int fd,
char *filename, char *filename,
int file_deleted) { int file_deleted) {
@@ -118,7 +101,7 @@ repeat_catalog:
if (file_track!=0x0) { if (file_track!=0x0) {
if (file_track==0xff) { if (file_track==0xff) {
dos33_filename_to_ascii(file_name, prodos_filename_to_ascii(file_name,
catalog_buffer+(CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE+FILE_NAME)),29); catalog_buffer+(CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE+FILE_NAME)),29);
if (file_deleted) { if (file_deleted) {
@@ -129,7 +112,7 @@ repeat_catalog:
} }
} }
else { else {
dos33_filename_to_ascii(file_name, prodos_filename_to_ascii(file_name,
catalog_buffer+(CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE+FILE_NAME)),30); catalog_buffer+(CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE+FILE_NAME)),30);
/* return if we found the file */ /* return if we found the file */
if (!strncmp(filename,file_name,30)) { if (!strncmp(filename,file_name,30)) {
@@ -150,13 +133,13 @@ repeat_catalog:
return -1; return -1;
} }
static int dos33_free_sector(unsigned char *voldir,int fd,int track,int sector) { static int prodos_free_sector(struct voldir_t *voldir,int fd,int track,int sector) {
int result; int result;
/* mark as free in VTOC */ /* mark as free in VTOC */
dos33_vtoc_free_sector(voldir,track,sector); prodos_voldir_free_sector(voldir,track,sector);
#if 0
/* write modified VTOC back out */ /* write modified VTOC back out */
lseek(fd,DISK_OFFSET(PRODOS_VOLDIR_TRACK,PRODOS_VOLDIR_BLOCK),SEEK_SET); lseek(fd,DISK_OFFSET(PRODOS_VOLDIR_TRACK,PRODOS_VOLDIR_BLOCK),SEEK_SET);
result=write(fd,&voldir,PRODOS_BYTES_PER_BLOCK); result=write(fd,&voldir,PRODOS_BYTES_PER_BLOCK);
@@ -164,24 +147,24 @@ static int dos33_free_sector(unsigned char *voldir,int fd,int track,int sector)
if (result<0) { if (result<0) {
fprintf(stderr,"Error on I/O\n"); fprintf(stderr,"Error on I/O\n");
} }
#endif
return 0; return 0;
} }
static int dos33_allocate_sector(int fd, unsigned char *voldir) { static int prodos_allocate_sector(int fd, struct voldir_t *voldir) {
int found_track=0,found_sector=0; int found_track=0,found_sector=0;
int result; int result;
/* Find an empty sector */ /* Find an empty sector */
result=dos33_vtoc_find_free_sector(voldir,&found_track,&found_sector); result=prodos_voldir_find_free_sector(voldir,&found_track,&found_sector);
if (result<0) { if (result<0) {
fprintf(stderr,"ERROR: dos33_allocate_sector: Disk full!\n"); fprintf(stderr,"ERROR: prodos_allocate_sector: Disk full!\n");
return -1; return -1;
} }
#if 0
/* store new track/direction info */ /* store new track/direction info */
voldir[VTOC_LAST_ALLOC_T]=found_track; voldir[VTOC_LAST_ALLOC_T]=found_track;
@@ -195,7 +178,7 @@ static int dos33_allocate_sector(int fd, unsigned char *voldir) {
result=write(fd,voldir,PRODOS_BYTES_PER_BLOCK); result=write(fd,voldir,PRODOS_BYTES_PER_BLOCK);
if (result<0) fprintf(stderr,"Error on I/O\n"); if (result<0) fprintf(stderr,"Error on I/O\n");
#endif
return ((found_track<<8)+found_sector); return ((found_track<<8)+found_sector);
} }
@@ -272,7 +255,7 @@ static int prodos_add_file(struct voldir_t *voldir,
(file_size/(122*PRODOS_BYTES_PER_BLOCK)); /* extra t/s lists */ (file_size/(122*PRODOS_BYTES_PER_BLOCK)); /* extra t/s lists */
/* Get free space on device */ /* Get free space on device */
free_space=dos33_vtoc_free_space(voldir); free_space=prodos_vtoc_free_space(voldir);
/* Check for free space */ /* Check for free space */
if (needed_sectors*PRODOS_BYTES_PER_BLOCK>free_space) { if (needed_sectors*PRODOS_BYTES_PER_BLOCK>free_space) {
@@ -303,7 +286,7 @@ static int prodos_add_file(struct voldir_t *voldir,
old_ts_list=ts_list; old_ts_list=ts_list;
/* allocate a sector for the new list */ /* allocate a sector for the new list */
ts_list=dos33_allocate_sector(fd,voldir); ts_list=prodos_allocate_sector(fd,voldir);
sectors_used++; sectors_used++;
if (ts_list<0) return -1; if (ts_list<0) return -1;
@@ -346,7 +329,7 @@ static int prodos_add_file(struct voldir_t *voldir,
} }
/* allocate a sector */ /* allocate a sector */
data_ts=dos33_allocate_sector(fd,voldir); data_ts=prodos_allocate_sector(fd,voldir);
sectors_used++; sectors_used++;
if (data_ts<0) return -1; if (data_ts<0) return -1;
@@ -453,7 +436,7 @@ got_a_dentry:
catalog_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)+1]=(initial_ts_list&0xff); catalog_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)+1]=(initial_ts_list&0xff);
/* set file type */ /* set file type */
catalog_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)+FILE_TYPE]= catalog_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)+FILE_TYPE]=
dos33_char_to_type(dos_type,0); prodos_char_to_type(dos_type,0);
// printf("Pointing T/S to %x/%x\n",(initial_ts_list>>8)&0xff,initial_ts_list&0xff); // printf("Pointing T/S to %x/%x\n",(initial_ts_list>>8)&0xff,initial_ts_list&0xff);
@@ -485,7 +468,7 @@ got_a_dentry:
/* load a file. fts=entry/track/sector */ /* load a file. fts=entry/track/sector */
static int dos33_load_file(int fd,int fts,char *filename) { static int prodos_load_file(int fd,int fts,char *filename) {
int output_fd; int output_fd;
int catalog_file,catalog_track,catalog_sector; int catalog_file,catalog_track,catalog_sector;
@@ -516,7 +499,7 @@ static int dos33_load_file(int fd,int fts,char *filename) {
(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TS_LIST_T]; (catalog_file*CATALOG_ENTRY_SIZE)+FILE_TS_LIST_T];
tsl_sector=sector_buffer[CATALOG_FILE_LIST+ tsl_sector=sector_buffer[CATALOG_FILE_LIST+
(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TS_LIST_S]; (catalog_file*CATALOG_ENTRY_SIZE)+FILE_TS_LIST_S];
file_type=dos33_file_type(sector_buffer[CATALOG_FILE_LIST+ file_type=prodos_file_type(sector_buffer[CATALOG_FILE_LIST+
(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE]); (catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE]);
// printf("file_type: %c\n",file_type); // printf("file_type: %c\n",file_type);
@@ -589,7 +572,7 @@ keep_saving:
} }
/* lock a file. fts=entry/track/sector */ /* lock a file. fts=entry/track/sector */
static int dos33_lock_file(int fd,int fts,int lock) { static int prodos_lock_file(int fd,int fts,int lock) {
int catalog_file,catalog_track,catalog_sector; int catalog_file,catalog_track,catalog_sector;
int file_type,result; int file_type,result;
@@ -628,7 +611,7 @@ static int dos33_lock_file(int fd,int fts,int lock) {
/* rename a file. fts=entry/track/sector */ /* rename a file. fts=entry/track/sector */
/* FIXME: can we rename a locked file? */ /* FIXME: can we rename a locked file? */
/* FIXME: validate the new filename is valid */ /* FIXME: validate the new filename is valid */
static int dos33_rename_file(int fd,int fts,char *new_name) { static int prodos_rename_file(int fd,int fts,char *new_name) {
int catalog_file,catalog_track,catalog_sector; int catalog_file,catalog_track,catalog_sector;
int x,result; int x,result;
@@ -758,13 +741,13 @@ keep_deleting:
(catalog_buffer[TSL_LIST+2*i+1]==0)) { (catalog_buffer[TSL_LIST+2*i+1]==0)) {
} }
else { else {
dos33_free_sector(voldir,fd,catalog_buffer[TSL_LIST+2*i], prodos_free_sector(voldir,fd,catalog_buffer[TSL_LIST+2*i],
catalog_buffer[TSL_LIST+2*i+1]); catalog_buffer[TSL_LIST+2*i+1]);
} }
} }
/* free the t/s list */ /* free the t/s list */
dos33_free_sector(voldir,fd,ts_track,ts_sector); prodos_free_sector(voldir,fd,ts_track,ts_sector);
/* Point to next t/s list */ /* Point to next t/s list */
ts_track=catalog_buffer[TSL_NEXT_TRACK]; ts_track=catalog_buffer[TSL_NEXT_TRACK];
@@ -802,7 +785,7 @@ keep_deleting:
} }
/* ??? */ /* ??? */
static int dos33_rename_hello(int fd, char *new_name) { static int prodos_rename_hello(int fd, char *new_name) {
char buffer[PRODOS_BYTES_PER_BLOCK]; char buffer[PRODOS_BYTES_PER_BLOCK];
int i; int i;
@@ -826,7 +809,7 @@ static int dos33_rename_hello(int fd, char *new_name) {
} }
static void display_help(char *name, int version_only) { static void display_help(char *name, int version_only) {
printf("\ndos33 version %s\n",VERSION); printf("\nprodos version %s\n",VERSION);
printf("by Vince Weaver <vince@deater.net>\n"); printf("by Vince Weaver <vince@deater.net>\n");
printf("\n"); printf("\n");
@@ -1060,7 +1043,7 @@ int main(int argc, char **argv) {
/* get the entry/track/sector for file */ /* get the entry/track/sector for file */
catalog_entry=dos33_check_file_exists(dos_fd, catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename, apple_filename,
DOS33_FILE_NORMAL); DOS33_FILE_NORMAL);
if (catalog_entry<0) { if (catalog_entry<0) {
@@ -1069,7 +1052,7 @@ int main(int argc, char **argv) {
goto exit_and_close; goto exit_and_close;
} }
dos33_load_file(dos_fd,catalog_entry,local_filename); prodos_load_file(dos_fd,catalog_entry,local_filename);
break; break;
@@ -1098,7 +1081,7 @@ int main(int argc, char **argv) {
case COMMAND_BSAVE: case COMMAND_BSAVE:
if (debug) printf("\ttype=%c\n",type); if (debug) printf("\ttype=%c\n",type);
#if 0
if (argc==optind) { if (argc==optind) {
fprintf(stderr,"Error! Need file_name\n"); fprintf(stderr,"Error! Need file_name\n");
@@ -1146,7 +1129,7 @@ int main(int argc, char **argv) {
if (debug) printf("\tApple filename: %s\n",apple_filename); if (debug) printf("\tApple filename: %s\n",apple_filename);
catalog_entry=dos33_check_file_exists(dos_fd,apple_filename, catalog_entry=prodos_check_file_exists(dos_fd,apple_filename,
DOS33_FILE_NORMAL); DOS33_FILE_NORMAL);
if (catalog_entry>=0) { if (catalog_entry>=0) {
@@ -1160,7 +1143,7 @@ int main(int argc, char **argv) {
} }
} }
fprintf(stderr,"Deleting previous version...\n"); fprintf(stderr,"Deleting previous version...\n");
dos33_delete_file(voldir,dos_fd,catalog_entry); prodos_delete_file(voldir,dos_fd,catalog_entry);
} }
if (command==COMMAND_SAVE) { if (command==COMMAND_SAVE) {
prodos_add_file(&voldir,dos_fd,type, prodos_add_file(&voldir,dos_fd,type,
@@ -1172,6 +1155,7 @@ int main(int argc, char **argv) {
ADD_BINARY, address, length, ADD_BINARY, address, length,
local_filename,apple_filename); local_filename,apple_filename);
} }
#endif
break; break;
@@ -1193,7 +1177,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]); truncate_filename(apple_filename,argv[optind]);
catalog_entry=dos33_check_file_exists(dos_fd, catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename, apple_filename,
DOS33_FILE_NORMAL); DOS33_FILE_NORMAL);
if (catalog_entry<0) { if (catalog_entry<0) {
@@ -1228,7 +1212,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]); truncate_filename(apple_filename,argv[optind]);
/* get the entry/track/sector for file */ /* get the entry/track/sector for file */
catalog_entry=dos33_check_file_exists(dos_fd, catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename, apple_filename,
DOS33_FILE_NORMAL); DOS33_FILE_NORMAL);
if (catalog_entry<0) { if (catalog_entry<0) {
@@ -1237,7 +1221,7 @@ int main(int argc, char **argv) {
goto exit_and_close; goto exit_and_close;
} }
dos33_lock_file(dos_fd,catalog_entry,command==COMMAND_LOCK); prodos_lock_file(dos_fd,catalog_entry,command==COMMAND_LOCK);
break; break;
@@ -1266,7 +1250,7 @@ int main(int argc, char **argv) {
truncate_filename(new_filename,argv[optind]); truncate_filename(new_filename,argv[optind]);
/* get the entry/track/sector for file */ /* get the entry/track/sector for file */
catalog_entry=dos33_check_file_exists(dos_fd, catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename, apple_filename,
DOS33_FILE_NORMAL); DOS33_FILE_NORMAL);
if (catalog_entry<0) { if (catalog_entry<0) {
@@ -1275,7 +1259,7 @@ int main(int argc, char **argv) {
goto exit_and_close; goto exit_and_close;
} }
dos33_rename_file(dos_fd,catalog_entry,new_filename); prodos_rename_file(dos_fd,catalog_entry,new_filename);
break; break;
@@ -1294,7 +1278,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]); truncate_filename(apple_filename,argv[optind]);
/* get the entry/track/sector for file */ /* get the entry/track/sector for file */
catalog_entry=dos33_check_file_exists(dos_fd, catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename, apple_filename,
DOS33_FILE_DELETED); DOS33_FILE_DELETED);
if (catalog_entry<0) { if (catalog_entry<0) {
@@ -1317,7 +1301,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]); truncate_filename(apple_filename,argv[optind]);
catalog_entry=dos33_check_file_exists(dos_fd, catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename, apple_filename,
DOS33_FILE_NORMAL); DOS33_FILE_NORMAL);
@@ -1326,11 +1310,11 @@ int main(int argc, char **argv) {
"Warning! File %s does not exist\n", "Warning! File %s does not exist\n",
apple_filename); apple_filename);
} }
dos33_rename_hello(dos_fd,apple_filename); prodos_rename_hello(dos_fd,apple_filename);
break; break;
case COMMAND_INIT: case COMMAND_INIT:
/* use common code from mkdos33fs? */ /* use common code from mkprodosfs? */
case COMMAND_COPY: case COMMAND_COPY:
/* use temp file? Walking a sector at a time seems a pain */ /* use temp file? Walking a sector at a time seems a pain */
default: default:

View File

@@ -9,6 +9,7 @@
#define PRODOS_VOLDIR_BLOCK 2 #define PRODOS_VOLDIR_BLOCK 2
struct voldir_t { struct voldir_t {
int fd;
unsigned char storage_type; unsigned char storage_type;
unsigned char name_length; unsigned char name_length;
unsigned char version; unsigned char version;
@@ -23,21 +24,6 @@ struct voldir_t {
unsigned int creation_time; unsigned int creation_time;
}; };
/* VTOC Values */
#define VTOC_CATALOG_T 0x1
#define VTOC_CATALOG_S 0x2
#define VTOC_DOS_RELEASE 0x3
#define VTOC_DISK_VOLUME 0x6
#define VTOC_MAX_TS_PAIRS 0x27
#define VTOC_LAST_ALLOC_T 0x30
#define VTOC_ALLOC_DIRECT 0x31
#define VTOC_NUM_TRACKS 0x34
#define VTOC_S_PER_TRACK 0x35
#define VTOC_BYTES_PER_SL 0x36
#define VTOC_BYTES_PER_SH 0x37
#define VTOC_FREE_BITMAPS 0x38
/* CATALOG_VALUES */ /* CATALOG_VALUES */
#define CATALOG_NEXT_T 0x01 #define CATALOG_NEXT_T 0x01
#define CATALOG_NEXT_S 0x02 #define CATALOG_NEXT_S 0x02
@@ -74,22 +60,22 @@ struct voldir_t {
#define DOS33_FILE_DELETED 1 #define DOS33_FILE_DELETED 1
/* prodos_volume_bitmap.c */ /* prodos_volume_bitmap.c */
int dos33_vtoc_free_space(unsigned char *vtoc); int prodos_voldir_free_space(struct voldir_t *voldir);
void dos33_vtoc_free_sector(unsigned char *vtoc, int track, int sector); void prodos_voldir_free_sector(struct voldir_t *voldir, int track, int sector);
void dos33_vtoc_reserve_sector(unsigned char *vtoc, int track, int sector); void prodos_voldir_reserve_sector(struct voldir_t *voldir, int track, int sector);
void dos33_vtoc_dump_bitmap(unsigned char *vtoc, int num_tracks); void prodos_voldir_dump_bitmap(struct voldir_t *voldir);
int dos33_vtoc_find_free_sector(unsigned char *vtoc, int prodos_voldir_find_free_sector(struct voldir_t *voldir,
int *found_track, int *found_sector); int *found_track, int *found_sector);
/* prodos_catalog.c */ /* prodos_catalog.c */
unsigned char dos33_char_to_type(char type, int lock); unsigned char prodos_char_to_type(char type, int lock);
void prodos_catalog(int dos_fd, struct voldir_t *voldir); void prodos_catalog(int dos_fd, struct voldir_t *voldir);
char *dos33_filename_to_ascii(char *dest,unsigned char *src,int len); char *prodos_filename_to_ascii(char *dest,unsigned char *src,int len);
unsigned char dos33_file_type(int value); unsigned char prodos_file_type(int value);
/* prodos_dump.c */ /* prodos_dump.c */
int prodos_dump(struct voldir_t *voldir, int fd); int prodos_dump(struct voldir_t *voldir, int fd);
int prodos_showfree(struct voldir_t *voldir, int fd); int prodos_showfree(struct voldir_t *voldir, int fd);
/* prodos.c */ /* prodos_read.c */
int prodos_read_block(int fd,unsigned char *block, int blocknum); int prodos_read_block(struct voldir_t *voldir,unsigned char *block, int blocknum);

View File

@@ -7,7 +7,7 @@
static int debug=0; static int debug=0;
unsigned char dos33_file_type(int value) { unsigned char prodos_file_type(int value) {
unsigned char result; unsigned char result;
@@ -26,10 +26,10 @@ unsigned char dos33_file_type(int value) {
} }
unsigned char dos33_char_to_type(char type, int lock) { unsigned char prodos_char_to_type(char type, int lock) {
unsigned char result,temp_type;
unsigned char result=0,temp_type;
#if 0
temp_type=type; temp_type=type;
/* Covert to upper case */ /* Covert to upper case */
if (temp_type>='a') temp_type=temp_type-0x20; if (temp_type>='a') temp_type=temp_type-0x20;
@@ -46,12 +46,13 @@ unsigned char dos33_char_to_type(char type, int lock) {
default: result=0x0; default: result=0x0;
} }
if (lock) result|=0x80; if (lock) result|=0x80;
#endif
return result; return result;
} }
/* dos33 filenames have top bit set on ascii chars */ /* prodos filenames have top bit set on ascii chars */
/* and are padded with spaces */ /* and are padded with spaces */
char *dos33_filename_to_ascii(char *dest,unsigned char *src,int len) { char *prodos_filename_to_ascii(char *dest,unsigned char *src,int len) {
int i=0,last_nonspace=0; int i=0,last_nonspace=0;
@@ -66,14 +67,15 @@ char *dos33_filename_to_ascii(char *dest,unsigned char *src,int len) {
} }
/* Get a T/S value from a Catalog Sector */ /* Get a T/S value from a Catalog Sector */
static int dos33_get_catalog_ts(unsigned char *voldir) { static int prodos_get_catalog_ts(struct voldir_t *voldir) {
return TS_TO_INT(voldir[VTOC_CATALOG_T],voldir[VTOC_CATALOG_S]); // return TS_TO_INT(voldir[VTOC_CATALOG_T],voldir[VTOC_CATALOG_S]);
return 0;
} }
/* returns the next valid catalog entry */ /* returns the next valid catalog entry */
/* after the one passed in */ /* after the one passed in */
static int dos33_find_next_file(int fd,int catalog_tsf,unsigned char *voldir) { static int prodos_find_next_file(int fd,int catalog_tsf,unsigned char *voldir) {
int catalog_track,catalog_sector,catalog_file; int catalog_track,catalog_sector,catalog_file;
int file_track,i; int file_track,i;
@@ -89,7 +91,7 @@ static int dos33_find_next_file(int fd,int catalog_tsf,unsigned char *voldir) {
"CURRENT FILE=%X TRACK=%X SECTOR=%X\n", "CURRENT FILE=%X TRACK=%X SECTOR=%X\n",
catalog_file,catalog_track,catalog_sector); catalog_file,catalog_track,catalog_sector);
} }
#if 0
catalog_loop: catalog_loop:
/* Read in Catalog Sector */ /* Read in Catalog Sector */
@@ -137,11 +139,11 @@ catalog_loop:
} }
#endif
return -1; return -1;
} }
static int dos33_print_file_info(int fd,int catalog_tsf) { static int prodos_print_file_info(int fd,int catalog_tsf) {
int catalog_track,catalog_sector,catalog_file,i; int catalog_track,catalog_sector,catalog_file,i;
char temp_string[BUFSIZ]; char temp_string[BUFSIZ];
@@ -154,7 +156,7 @@ static int dos33_print_file_info(int fd,int catalog_tsf) {
if (debug) fprintf(stderr,"CATALOG FILE=%X TRACK=%X SECTOR=%X\n", if (debug) fprintf(stderr,"CATALOG FILE=%X TRACK=%X SECTOR=%X\n",
catalog_file,catalog_track,catalog_sector); catalog_file,catalog_track,catalog_sector);
#if 0
/* Read in Catalog Sector */ /* Read in Catalog Sector */
lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET); lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET);
result=read(fd,sector_buffer,PRODOS_BYTES_PER_BLOCK); result=read(fd,sector_buffer,PRODOS_BYTES_PER_BLOCK);
@@ -166,12 +168,12 @@ static int dos33_print_file_info(int fd,int catalog_tsf) {
printf(" "); printf(" ");
} }
printf("%c",dos33_file_type(sector_buffer[CATALOG_FILE_LIST+(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE])); printf("%c",prodos_file_type(sector_buffer[CATALOG_FILE_LIST+(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE]));
printf(" "); printf(" ");
printf("%.3i ",sector_buffer[CATALOG_FILE_LIST+(catalog_file*CATALOG_ENTRY_SIZE+FILE_SIZE_L)]+ 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)); (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+ prodos_filename_to_ascii(temp_string,sector_buffer+(CATALOG_FILE_LIST+
(catalog_file*CATALOG_ENTRY_SIZE+FILE_NAME)),30); (catalog_file*CATALOG_ENTRY_SIZE+FILE_NAME)),30);
for(i=0;i<strlen(temp_string);i++) { for(i=0;i<strlen(temp_string);i++) {
@@ -186,7 +188,7 @@ static int dos33_print_file_info(int fd,int catalog_tsf) {
printf("\n"); printf("\n");
if (result<0) fprintf(stderr,"Error on I/O\n"); if (result<0) fprintf(stderr,"Error on I/O\n");
#endif
return 0; return 0;
} }
@@ -196,17 +198,17 @@ void prodos_catalog(int dos_fd, struct voldir_t *voldir) {
#if 0 #if 0
/* get first catalog */ /* get first catalog */
catalog_entry=dos33_get_catalog_ts(voldir); catalog_entry=prodos_get_catalog_ts(voldir);
printf("\nDISK VOLUME %i\n\n",voldir[VTOC_DISK_VOLUME]); printf("\nDISK VOLUME %i\n\n",voldir[VTOC_DISK_VOLUME]);
while(catalog_entry>0) { while(catalog_entry>0) {
catalog_entry=dos33_find_next_file(dos_fd,catalog_entry,voldir); catalog_entry=prodos_find_next_file(dos_fd,catalog_entry,voldir);
if (debug) fprintf(stderr,"CATALOG entry=$%X\n",catalog_entry); if (debug) fprintf(stderr,"CATALOG entry=$%X\n",catalog_entry);
if (catalog_entry>0) { if (catalog_entry>0) {
dos33_print_file_info(dos_fd,catalog_entry); prodos_print_file_info(dos_fd,catalog_entry);
/* why 1<<16 ? */ /* why 1<<16 ? */
catalog_entry+=(1<<16); catalog_entry+=(1<<16);
/* dos33_find_next_file() handles wrapping issues */ /* prodos_find_next_file() handles wrapping issues */
} }
} }
#endif #endif

View File

@@ -43,6 +43,15 @@ static void prodos_print_time(int t) {
} }
static void prodos_print_access(int access) {
if (access&0x80) printf("DESTROY ");
if (access&0x40) printf("RENAME ");
if (access&0x20) printf("VOLDIR_NEW ");
if (access&0x2) printf("VOLDIR_WRITE ");
if (access&0x1) printf("VOLDIR_READ ");
}
static void dump_voldir(struct voldir_t *voldir) { static void dump_voldir(struct voldir_t *voldir) {
unsigned char volume_name[16]; unsigned char volume_name[16];
@@ -64,7 +73,9 @@ static void dump_voldir(struct voldir_t *voldir) {
printf("\tVersion: %d\n",voldir->version); printf("\tVersion: %d\n",voldir->version);
printf("\tMin Version: %d\n",voldir->min_version); printf("\tMin Version: %d\n",voldir->min_version);
printf("\tAccess: %d\n",voldir->access); printf("\tAccess: $%X ",voldir->access);
prodos_print_access(voldir->access);
printf("\n");
printf("\tEntry Length: %d\n",voldir->entry_length); printf("\tEntry Length: %d\n",voldir->entry_length);
printf("\tEntries per block: %d\n",voldir->entries_per_block); printf("\tEntries per block: %d\n",voldir->entries_per_block);
printf("\tFile Count: %d\n",voldir->file_count); printf("\tFile Count: %d\n",voldir->file_count);
@@ -87,14 +98,10 @@ int prodos_dump(struct voldir_t *voldir, int fd) {
int result; int result;
dump_voldir(voldir); dump_voldir(voldir);
prodos_voldir_dump_bitmap(voldir);
#if 0 #if 0
catalog_t=voldir[VTOC_CATALOG_T];
catalog_s=voldir[VTOC_CATALOG_S];
ts_total=voldir[VTOC_MAX_TS_PAIRS];
num_tracks=voldir[VTOC_NUM_TRACKS];
dos33_vtoc_dump_bitmap(voldir,num_tracks);
repeat_catalog: repeat_catalog:
printf("\nCatalog Sector $%02X/$%02x\n",catalog_t,catalog_s); printf("\nCatalog Sector $%02X/$%02x\n",catalog_t,catalog_s);
@@ -215,7 +222,7 @@ int prodos_showfree(struct voldir_t *voldir, int fd) {
num_tracks=voldir[VTOC_NUM_TRACKS]; num_tracks=voldir[VTOC_NUM_TRACKS];
sectors_per_track=voldir[VTOC_S_PER_TRACK]; sectors_per_track=voldir[VTOC_S_PER_TRACK];
dos33_vtoc_dump_bitmap(voldir,num_tracks); prodos_voldir_dump_bitmap(voldir);
/* Reserve DOS */ /* Reserve DOS */
for(i=0;i<3;i++) for(j=0;j<16;j++) usage[i][j]='$'; for(i=0;i<3;i++) for(j=0;j<16;j++) usage[i][j]='$';

View File

@@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h> /* exit() */
#include <string.h> /* strncpy() */
#include <sys/stat.h> /* struct stat */
#include <fcntl.h> /* O_RDONLY */
#include <unistd.h> /* lseek() */
#include <ctype.h> /* toupper() */
#include <errno.h>
#include "version.h"
#include "prodos.h"
#if 0
static int debug=0,ignore_errors=0;
static unsigned char get_high_byte(int value) {
return (value>>8)&0xff;
}
static unsigned char get_low_byte(int value) {
return (value&0xff);
}
#endif
int prodos_read_block(struct voldir_t *voldir,
unsigned char *block, int blocknum) {
int result;
/* Note, we need to handle interleave, etc */
/* For now assume it's linear */
/* Seek to VOLDIR */
lseek(voldir->fd,blocknum*PRODOS_BYTES_PER_BLOCK,SEEK_SET);
result=read(voldir->fd,block,PRODOS_BYTES_PER_BLOCK);
if (result<PRODOS_BYTES_PER_BLOCK) {
fprintf(stderr,"Error reading block %d\n",blocknum);
return -1;
}
return 0;
}

View File

@@ -41,11 +41,18 @@ static int find_first_one(unsigned char byte) {
/* 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 */
int dos33_vtoc_free_space(unsigned char *vtoc) { int prodos_voldir_free_space(struct voldir_t *voldir) {
int volblocks;
unsigned char temp_block[PRODOS_BYTES_PER_BLOCK];
unsigned char bitmap[4]; unsigned char bitmap[4];
int i,sectors_free=0; int i,sectors_free=0;
volblocks=1+voldir->total_blocks/(PRODOS_BYTES_PER_BLOCK*8);
prodos_read_block(voldir,temp_block,voldir->bit_map_pointer);
#if 0
for(i=0;i<TRACKS_PER_DISK;i++) { for(i=0;i<TRACKS_PER_DISK;i++) {
bitmap[0]=vtoc[VTOC_FREE_BITMAPS+(i*4)]; bitmap[0]=vtoc[VTOC_FREE_BITMAPS+(i*4)];
bitmap[1]=vtoc[VTOC_FREE_BITMAPS+(i*4)+1]; bitmap[1]=vtoc[VTOC_FREE_BITMAPS+(i*4)+1];
@@ -55,13 +62,14 @@ int dos33_vtoc_free_space(unsigned char *vtoc) {
sectors_free+=ones_lookup[bitmap[1]&0xf]; sectors_free+=ones_lookup[bitmap[1]&0xf];
sectors_free+=ones_lookup[(bitmap[1]>>4)&0xf]; sectors_free+=ones_lookup[(bitmap[1]>>4)&0xf];
} }
#endif
return sectors_free*PRODOS_BYTES_PER_BLOCK; return sectors_free*PRODOS_BYTES_PER_BLOCK;
} }
/* free a sector from the sector bitmap */ /* free a sector from the sector bitmap */
void dos33_vtoc_free_sector(unsigned char *vtoc, int track, int sector) { void prodos_voldir_free_sector(struct voldir_t *voldir, int track, int sector) {
#if 0
/* each bitmap is 32 bits. With 16-sector tracks only first 16 used */ /* each bitmap is 32 bits. With 16-sector tracks only first 16 used */
/* 1 indicates free, 0 indicates used */ /* 1 indicates free, 0 indicates used */
if (sector<8) { if (sector<8) {
@@ -79,11 +87,13 @@ void dos33_vtoc_free_sector(unsigned char *vtoc, int track, int sector) {
else { else {
fprintf(stderr,"Error vtoc_free_sector! sector too big %d\n",sector); fprintf(stderr,"Error vtoc_free_sector! sector too big %d\n",sector);
} }
#endif
} }
/* reserve a sector in the sector bitmap */ /* reserve a sector in the sector bitmap */
void dos33_vtoc_reserve_sector(unsigned char *vtoc, int track, int sector) { void prodos_voldir_reserve_sector(struct voldir_t *voldir, int track, int sector) {
#if 0
/* each bitmap is 32 bits. With 16-sector tracks only first 16 used */ /* each bitmap is 32 bits. With 16-sector tracks only first 16 used */
/* 1 indicates free, 0 indicates used */ /* 1 indicates free, 0 indicates used */
if (sector<8) { if (sector<8) {
@@ -101,16 +111,18 @@ void dos33_vtoc_reserve_sector(unsigned char *vtoc, int track, int sector) {
else { else {
fprintf(stderr,"Error vtoc_reserve_sector! sector too big %d\n",sector); fprintf(stderr,"Error vtoc_reserve_sector! sector too big %d\n",sector);
} }
#endif
} }
void dos33_vtoc_dump_bitmap(unsigned char *vtoc, int num_tracks) { void prodos_voldir_dump_bitmap(struct voldir_t *voldir) {
int i,j; int i,j;
printf("\nFree sector bitmap:\n"); printf("\nFree sector bitmap:\n");
printf("\tU=used, .=free\n"); printf("\tU=used, .=free\n");
printf("\tTrack FEDCBA98 76543210\n"); printf("\tTrack FEDCBA98 76543210\n");
#if 0
for(i=0;i<num_tracks;i++) { for(i=0;i<num_tracks;i++) {
printf("\t $%02X: ",i); printf("\t $%02X: ",i);
for(j=0;j<8;j++) { for(j=0;j<8;j++) {
@@ -132,17 +144,18 @@ void dos33_vtoc_dump_bitmap(unsigned char *vtoc, int num_tracks) {
} }
printf("\n"); printf("\n");
} }
#endif
} }
/* reserve a sector in the sector bitmap */ /* reserve a sector in the sector bitmap */
int dos33_vtoc_find_free_sector(unsigned char *vtoc, int prodos_voldir_find_free_sector(struct voldir_t *voldir,
int *found_track, int *found_sector) { int *found_track, int *found_sector) {
int start_track,track_dir,i; int start_track,track_dir,i;
int bitmap; int bitmap;
int found=0; int found=0;
#if 0
/* Originally used to keep things near center of disk for speed */ /* Originally used to keep things near center of disk for speed */
/* We can use to avoid fragmentation possibly */ /* We can use to avoid fragmentation possibly */
start_track=vtoc[VTOC_LAST_ALLOC_T]%TRACKS_PER_DISK; start_track=vtoc[VTOC_LAST_ALLOC_T]%TRACKS_PER_DISK;
@@ -195,11 +208,11 @@ int dos33_vtoc_find_free_sector(unsigned char *vtoc,
if (found) { if (found) {
/* clear bit indicating in use */ /* clear bit indicating in use */
dos33_vtoc_reserve_sector(vtoc, *found_track, *found_sector); prodos_voldir_reserve_sector(voldir, *found_track, *found_sector);
return 0; return 0;
} }
#endif
/* no room */ /* no room */
return -1; return -1;