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_read.o \
prodos_catalog.o \
prodos_dump.o \
prodos_volume_bitmap.o
$(CC) -o prodos prodos.o \
prodos_read.o \
prodos_catalog.o \
prodos_dump.o \
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 \
prodos_volume_bitmap.o
prodos_read.o prodos_volume_bitmap.o
mkprodosfs.o: mkprodosfs.c prodos.h
$(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:
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;
}
#if 0
/* zero out file */
for(i=0;i<num_tracks*num_sectors;i++) {
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));
}
#endif
close(fd);

View File

@ -21,26 +21,6 @@ static unsigned char get_low_byte(int value) {
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 */
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];
/* 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) {
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) {
@ -85,7 +68,7 @@ static int prodos_read_voldir(int fd, struct voldir_t *voldir) {
/* Checks if "filename" exists */
/* returns entry/track/sector */
static int dos33_check_file_exists(int fd,
static int prodos_check_file_exists(int fd,
char *filename,
int file_deleted) {
@ -118,7 +101,7 @@ repeat_catalog:
if (file_track!=0x0) {
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);
if (file_deleted) {
@ -129,7 +112,7 @@ repeat_catalog:
}
}
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);
/* return if we found the file */
if (!strncmp(filename,file_name,30)) {
@ -150,13 +133,13 @@ repeat_catalog:
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;
/* 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 */
lseek(fd,DISK_OFFSET(PRODOS_VOLDIR_TRACK,PRODOS_VOLDIR_BLOCK),SEEK_SET);
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) {
fprintf(stderr,"Error on I/O\n");
}
#endif
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 result;
/* 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) {
fprintf(stderr,"ERROR: dos33_allocate_sector: Disk full!\n");
fprintf(stderr,"ERROR: prodos_allocate_sector: Disk full!\n");
return -1;
}
#if 0
/* store new track/direction info */
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);
if (result<0) fprintf(stderr,"Error on I/O\n");
#endif
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 */
/* Get free space on device */
free_space=dos33_vtoc_free_space(voldir);
free_space=prodos_vtoc_free_space(voldir);
/* Check for 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;
/* allocate a sector for the new list */
ts_list=dos33_allocate_sector(fd,voldir);
ts_list=prodos_allocate_sector(fd,voldir);
sectors_used++;
if (ts_list<0) return -1;
@ -346,7 +329,7 @@ static int prodos_add_file(struct voldir_t *voldir,
}
/* allocate a sector */
data_ts=dos33_allocate_sector(fd,voldir);
data_ts=prodos_allocate_sector(fd,voldir);
sectors_used++;
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);
/* set 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);
@ -485,7 +468,7 @@ got_a_dentry:
/* 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 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];
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+
file_type=prodos_file_type(sector_buffer[CATALOG_FILE_LIST+
(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE]);
// printf("file_type: %c\n",file_type);
@ -589,7 +572,7 @@ keep_saving:
}
/* 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 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 */
/* FIXME: can we rename a locked file? */
/* 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 x,result;
@ -758,13 +741,13 @@ keep_deleting:
(catalog_buffer[TSL_LIST+2*i+1]==0)) {
}
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]);
}
}
/* 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 */
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];
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) {
printf("\ndos33 version %s\n",VERSION);
printf("\nprodos version %s\n",VERSION);
printf("by Vince Weaver <vince@deater.net>\n");
printf("\n");
@ -1060,7 +1043,7 @@ int main(int argc, char **argv) {
/* 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,
DOS33_FILE_NORMAL);
if (catalog_entry<0) {
@ -1069,7 +1052,7 @@ int main(int argc, char **argv) {
goto exit_and_close;
}
dos33_load_file(dos_fd,catalog_entry,local_filename);
prodos_load_file(dos_fd,catalog_entry,local_filename);
break;
@ -1098,7 +1081,7 @@ int main(int argc, char **argv) {
case COMMAND_BSAVE:
if (debug) printf("\ttype=%c\n",type);
#if 0
if (argc==optind) {
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);
catalog_entry=dos33_check_file_exists(dos_fd,apple_filename,
catalog_entry=prodos_check_file_exists(dos_fd,apple_filename,
DOS33_FILE_NORMAL);
if (catalog_entry>=0) {
@ -1160,7 +1143,7 @@ int main(int argc, char **argv) {
}
}
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) {
prodos_add_file(&voldir,dos_fd,type,
@ -1172,6 +1155,7 @@ int main(int argc, char **argv) {
ADD_BINARY, address, length,
local_filename,apple_filename);
}
#endif
break;
@ -1193,7 +1177,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]);
catalog_entry=dos33_check_file_exists(dos_fd,
catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename,
DOS33_FILE_NORMAL);
if (catalog_entry<0) {
@ -1228,7 +1212,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]);
/* 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,
DOS33_FILE_NORMAL);
if (catalog_entry<0) {
@ -1237,7 +1221,7 @@ int main(int argc, char **argv) {
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;
@ -1266,7 +1250,7 @@ int main(int argc, char **argv) {
truncate_filename(new_filename,argv[optind]);
/* 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,
DOS33_FILE_NORMAL);
if (catalog_entry<0) {
@ -1275,7 +1259,7 @@ int main(int argc, char **argv) {
goto exit_and_close;
}
dos33_rename_file(dos_fd,catalog_entry,new_filename);
prodos_rename_file(dos_fd,catalog_entry,new_filename);
break;
@ -1294,7 +1278,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]);
/* 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,
DOS33_FILE_DELETED);
if (catalog_entry<0) {
@ -1317,7 +1301,7 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,argv[optind]);
catalog_entry=dos33_check_file_exists(dos_fd,
catalog_entry=prodos_check_file_exists(dos_fd,
apple_filename,
DOS33_FILE_NORMAL);
@ -1326,11 +1310,11 @@ int main(int argc, char **argv) {
"Warning! File %s does not exist\n",
apple_filename);
}
dos33_rename_hello(dos_fd,apple_filename);
prodos_rename_hello(dos_fd,apple_filename);
break;
case COMMAND_INIT:
/* use common code from mkdos33fs? */
/* use common code from mkprodosfs? */
case COMMAND_COPY:
/* use temp file? Walking a sector at a time seems a pain */
default:

View File

@ -9,6 +9,7 @@
#define PRODOS_VOLDIR_BLOCK 2
struct voldir_t {
int fd;
unsigned char storage_type;
unsigned char name_length;
unsigned char version;
@ -23,21 +24,6 @@ struct voldir_t {
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 */
#define CATALOG_NEXT_T 0x01
#define CATALOG_NEXT_S 0x02
@ -74,22 +60,22 @@ struct voldir_t {
#define DOS33_FILE_DELETED 1
/* prodos_volume_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 prodos_voldir_free_space(struct voldir_t *voldir);
void prodos_voldir_free_sector(struct voldir_t *voldir, int track, int sector);
void prodos_voldir_reserve_sector(struct voldir_t *voldir, int track, int sector);
void prodos_voldir_dump_bitmap(struct voldir_t *voldir);
int prodos_voldir_find_free_sector(struct voldir_t *voldir,
int *found_track, int *found_sector);
/* 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);
char *dos33_filename_to_ascii(char *dest,unsigned char *src,int len);
unsigned char dos33_file_type(int value);
char *prodos_filename_to_ascii(char *dest,unsigned char *src,int len);
unsigned char prodos_file_type(int value);
/* prodos_dump.c */
int prodos_dump(struct voldir_t *voldir, int fd);
int prodos_showfree(struct voldir_t *voldir, int fd);
/* prodos.c */
int prodos_read_block(int fd,unsigned char *block, int blocknum);
/* prodos_read.c */
int prodos_read_block(struct voldir_t *voldir,unsigned char *block, int blocknum);

View File

@ -7,7 +7,7 @@
static int debug=0;
unsigned char dos33_file_type(int value) {
unsigned char prodos_file_type(int value) {
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 result,temp_type;
unsigned char prodos_char_to_type(char type, int lock) {
unsigned char result=0,temp_type;
#if 0
temp_type=type;
/* Covert to upper case */
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;
}
if (lock) result|=0x80;
#endif
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 */
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;
@ -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 */
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 */
/* 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 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",
catalog_file,catalog_track,catalog_sector);
}
#if 0
catalog_loop:
/* Read in Catalog Sector */
@ -137,11 +139,11 @@ catalog_loop:
}
#endif
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;
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",
catalog_file,catalog_track,catalog_sector);
#if 0
/* Read in Catalog Sector */
lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET);
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("%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("%.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+
prodos_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++) {
@ -186,7 +188,7 @@ static int dos33_print_file_info(int fd,int catalog_tsf) {
printf("\n");
if (result<0) fprintf(stderr,"Error on I/O\n");
#endif
return 0;
}
@ -196,17 +198,17 @@ void prodos_catalog(int dos_fd, struct voldir_t *voldir) {
#if 0
/* 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]);
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 (catalog_entry>0) {
dos33_print_file_info(dos_fd,catalog_entry);
prodos_print_file_info(dos_fd,catalog_entry);
/* why 1<<16 ? */
catalog_entry+=(1<<16);
/* dos33_find_next_file() handles wrapping issues */
/* prodos_find_next_file() handles wrapping issues */
}
}
#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) {
unsigned char volume_name[16];
@ -64,7 +73,9 @@ static void dump_voldir(struct voldir_t *voldir) {
printf("\tVersion: %d\n",voldir->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("\tEntries per block: %d\n",voldir->entries_per_block);
printf("\tFile Count: %d\n",voldir->file_count);
@ -87,14 +98,10 @@ int prodos_dump(struct voldir_t *voldir, int fd) {
int result;
dump_voldir(voldir);
prodos_voldir_dump_bitmap(voldir);
#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:
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];
sectors_per_track=voldir[VTOC_S_PER_TRACK];
dos33_vtoc_dump_bitmap(voldir,num_tracks);
prodos_voldir_dump_bitmap(voldir);
/* Reserve DOS */
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 */
/* 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];
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++) {
bitmap[0]=vtoc[VTOC_FREE_BITMAPS+(i*4)];
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]>>4)&0xf];
}
#endif
return sectors_free*PRODOS_BYTES_PER_BLOCK;
}
/* 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 */
/* 1 indicates free, 0 indicates used */
if (sector<8) {
@ -79,11 +87,13 @@ void dos33_vtoc_free_sector(unsigned char *vtoc, int track, int sector) {
else {
fprintf(stderr,"Error vtoc_free_sector! sector too big %d\n",sector);
}
#endif
}
/* 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 */
/* 1 indicates free, 0 indicates used */
if (sector<8) {
@ -101,16 +111,18 @@ void dos33_vtoc_reserve_sector(unsigned char *vtoc, int track, int sector) {
else {
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;
printf("\nFree sector bitmap:\n");
printf("\tU=used, .=free\n");
printf("\tTrack FEDCBA98 76543210\n");
#if 0
for(i=0;i<num_tracks;i++) {
printf("\t $%02X: ",i);
for(j=0;j<8;j++) {
@ -132,17 +144,18 @@ void dos33_vtoc_dump_bitmap(unsigned char *vtoc, int num_tracks) {
}
printf("\n");
}
#endif
}
/* 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 start_track,track_dir,i;
int bitmap;
int found=0;
#if 0
/* Originally used to keep things near center of disk for speed */
/* We can use to avoid fragmentation possibly */
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) {
/* 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;
}
#endif
/* no room */
return -1;