prodos: work on LOAD functionality

This commit is contained in:
Vince Weaver
2021-07-30 00:37:52 -04:00
parent 643aca2973
commit 7231194c5c
4 changed files with 27 additions and 126 deletions

View File

@@ -13,15 +13,6 @@
static int debug=0,ignore_errors=0; static int debug=0,ignore_errors=0;
#if 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
/* Read volume directory into a buffer */ /* Read volume directory into a buffer */
static int prodos_read_voldir(int fd, struct voldir_t *voldir, int interleave) { static int prodos_read_voldir(int fd, struct voldir_t *voldir, int interleave) {
@@ -77,73 +68,25 @@ static int prodos_read_voldir(int fd, struct voldir_t *voldir, int interleave) {
/* Checks if "filename" exists */ /* Checks if "filename" exists */
/* returns entry/block */ /* returns file type */
static int prodos_check_file_exists(int fd, static int prodos_check_file_exists(struct voldir_t *voldir,
char *filename, char *filename,
int file_deleted) { struct file_entry_t *file) {
#if 0
int catalog_track,catalog_sector;
int i,file_track;
char file_name[31];
int result;
struct voldir_t voldir;
unsigned char catalog_buffer[PRODOS_BYTES_PER_BLOCK];
/* read the VOLDIR into buffer */ int catalog_block,catalog_offset,catalog_inode;
prodos_read_voldir(fd,&voldir,interleave);
/* FIXME: we have a function for this */ catalog_block=PRODOS_VOLDIR_KEY_BLOCK;
/* get the catalog track and sector from the VTOC */ catalog_offset=0; /* skip the header */
catalog_track=voldir[VTOC_CATALOG_T]; catalog_inode=(catalog_block<<8)|catalog_offset;
catalog_sector=voldir[VTOC_CATALOG_S];
repeat_catalog:
/* Read in Catalog Sector */ while(1) {
lseek(fd,DISK_OFFSET(catalog_track,catalog_sector),SEEK_SET); catalog_inode=prodos_find_next_file(catalog_inode,voldir);
result=read(fd,catalog_buffer,PRODOS_BYTES_PER_BLOCK); if (catalog_inode==-1) break;
/* scan all file entries in catalog sector */
for(i=0;i<7;i++) {
file_track=catalog_buffer[CATALOG_FILE_LIST+(i*CATALOG_ENTRY_SIZE)];
/* 0xff means file deleted */
/* 0x0 means empty */
if (file_track!=0x0) {
if (file_track==0xff) {
prodos_filename_to_ascii(file_name,
catalog_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 {
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)) {
return ((i<<16)+(catalog_track<<8)+catalog_sector);
}
}
}
} }
/* point to next catalog track/sector */ return 0;
catalog_track=catalog_buffer[CATALOG_NEXT_T];
catalog_sector=catalog_buffer[CATALOG_NEXT_S];
if (catalog_sector!=0) goto repeat_catalog;
if (result<0) fprintf(stderr,"Error on I/O\n");
#endif
return -1;
} }
static int prodos_free_block(struct voldir_t *voldir,int block) { static int prodos_free_block(struct voldir_t *voldir,int block) {
@@ -489,10 +432,10 @@ got_a_dentry:
} }
/* load a file. fts=entry/track/sector */ /* load a file from the disk image. */
static int prodos_load_file(int fd,int fts,char *filename) { static int prodos_load_file(struct voldir_t *voldir,
int inode,char *filename) {
#if 0
int output_fd; int output_fd;
int catalog_file,catalog_track,catalog_sector; int catalog_file,catalog_track,catalog_sector;
int file_type,file_size=-1,tsl_track,tsl_sector,data_t,data_s; int file_type,file_size=-1,tsl_track,tsl_sector,data_t,data_s;
@@ -509,24 +452,7 @@ static int prodos_load_file(int fd,int fts,char *filename) {
return -1; return -1;
} }
catalog_file=fts>>16; #if 0
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,PRODOS_BYTES_PER_BLOCK);
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=prodos_file_type(sector_buffer[CATALOG_FILE_LIST+
(catalog_file*CATALOG_ENTRY_SIZE)+FILE_TYPE]);
// printf("file_type: %c\n",file_type);
keep_saving: keep_saving:
/* Read in TSL Sector */ /* Read in TSL Sector */
lseek(fd,DISK_OFFSET(tsl_track,tsl_sector),SEEK_SET); lseek(fd,DISK_OFFSET(tsl_track,tsl_sector),SEEK_SET);
@@ -838,6 +764,7 @@ int main(int argc, char **argv) {
int c; int c;
int address=0, length=0; int address=0, length=0;
struct voldir_t voldir; struct voldir_t voldir;
struct file_entry_t file;
/* Check command line arguments */ /* Check command line arguments */
while ((c = getopt (argc, argv,"a:i:l:t:s:dhvxy"))!=-1) { while ((c = getopt (argc, argv,"a:i:l:t:s:dhvxy"))!=-1) {

View File

@@ -106,10 +106,13 @@ int prodos_voldir_find_free_block(struct voldir_t *voldir,
int *found_block); int *found_block);
/* prodos_catalog.c */ /* prodos_catalog.c */
unsigned char prodos_char_to_type(char type, int lock); int prodos_find_next_file(int inode, struct voldir_t *voldir);
int prodos_populate_filedesc(unsigned char *file_desc,
struct file_entry_t *file_entry);
//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 *prodos_filename_to_ascii(char *dest,unsigned char *src,int len); //char *prodos_filename_to_ascii(char *dest,unsigned char *src,int len);
unsigned char prodos_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);

View File

@@ -13,7 +13,7 @@
/* inode = block<<8|entry */ /* inode = block<<8|entry */
static int prodos_find_next_file(int inode, struct voldir_t *voldir) { int prodos_find_next_file(int inode, struct voldir_t *voldir) {
int result,catalog_block,catalog_offset; int result,catalog_block,catalog_offset;
unsigned char catalog_buffer[PRODOS_BYTES_PER_BLOCK]; unsigned char catalog_buffer[PRODOS_BYTES_PER_BLOCK];
@@ -112,7 +112,8 @@ static int prodos_print_short_filetype(int type) {
return 0; return 0;
} }
static unsigned char prodos_capital_month_names[12][4]={ static unsigned char prodos_capital_month_names[13][4]={
"???",
"JAN","FEB","MAR","APR","MAY","JUN", "JAN","FEB","MAR","APR","MAY","JUN",
"JUL","AUG","SEP","OCT","NOV","DEC", "JUL","AUG","SEP","OCT","NOV","DEC",
}; };
@@ -128,7 +129,7 @@ static int prodos_text_timestamp(int t, unsigned char *timestamp) {
minute=t&0x3f; minute=t&0x3f;
sprintf((char *)timestamp,"%2d-%s-%02d %2d:%02d", sprintf((char *)timestamp,"%2d-%s-%02d %2d:%02d",
day,prodos_capital_month_names[month-1],year,hour,minute); day,prodos_capital_month_names[month],year,hour,minute);
timestamp[16]=0; timestamp[16]=0;
return 0; return 0;

View File

@@ -215,12 +215,7 @@ int prodos_dump(struct voldir_t *voldir, int fd) {
memcpy(file_desc, memcpy(file_desc,
catalog_buffer+4+file*PRODOS_FILE_DESC_LEN, catalog_buffer+4+file*PRODOS_FILE_DESC_LEN,
PRODOS_FILE_DESC_LEN); PRODOS_FILE_DESC_LEN);
prodos_populate_filedesc(&file_desc,&file_entry);
file_entry.storage_type=(file_desc[0]>>4)&0xf;
file_entry.name_length=file_desc[0]&0xf;
memcpy(&file_entry.file_name[0],&file_desc[1],
file_entry.name_length);
file_entry.file_name[file_entry.name_length]=0;
if (file_entry.storage_type==PRODOS_FILE_DELETED) continue; if (file_entry.storage_type==PRODOS_FILE_DELETED) continue;
@@ -230,57 +225,32 @@ int prodos_dump(struct voldir_t *voldir, int fd) {
prodos_print_storage_type(file_entry.storage_type); prodos_print_storage_type(file_entry.storage_type);
printf("\t"); printf("\t");
file_entry.file_type=file_desc[0x10];
prodos_print_file_type(file_entry.file_type); prodos_print_file_type(file_entry.file_type);
file_entry.key_pointer=file_desc[0x11]|
file_desc[0x12]<<8;
printf("\tKey pointer: $%x\n",file_entry.key_pointer); printf("\tKey pointer: $%x\n",file_entry.key_pointer);
file_entry.blocks_used=file_desc[0x13]|
file_desc[0x14]<<8;
printf("\tBlocks Used: %d\n",file_entry.blocks_used); printf("\tBlocks Used: %d\n",file_entry.blocks_used);
file_entry.eof=file_desc[0x15]|
file_desc[0x16]<<8|
file_desc[0x17]<<16;
printf("\tFile size (eof): %d\n",file_entry.eof); printf("\tFile size (eof): %d\n",file_entry.eof);
file_entry.creation_time=(file_desc[0x18]<<16)|
(file_desc[0x19]<<24)|
(file_desc[0x1a]<<0)|
(file_desc[0x1b]<<8);
printf("\tCreation Time (%x): ",file_entry.creation_time); printf("\tCreation Time (%x): ",file_entry.creation_time);
prodos_print_time(file_entry.creation_time); prodos_print_time(file_entry.creation_time);
printf("\n"); printf("\n");
file_entry.version=file_desc[0x1c];
printf("\tVersion: %d\n",file_entry.version); printf("\tVersion: %d\n",file_entry.version);
file_entry.min_version=file_desc[0x1d];
printf("\tMin Version: %d\n",file_entry.min_version); printf("\tMin Version: %d\n",file_entry.min_version);
file_entry.access=file_desc[0x1e];
printf("\tAccess (%x): ",file_entry.access); printf("\tAccess (%x): ",file_entry.access);
prodos_print_access(file_entry.access); prodos_print_access(file_entry.access);
printf("\n"); printf("\n");
file_entry.aux_type=file_desc[0x1f]|
file_desc[0x20]<<8;
printf("\tAux Type: %x\n",file_entry.aux_type); printf("\tAux Type: %x\n",file_entry.aux_type);
file_entry.last_mod=(file_desc[0x21]<<16)|
(file_desc[0x22]<<24)|
(file_desc[0x23]<<0)|
(file_desc[0x24]<<8);
printf("\tLast mod Time: (%x) ",file_entry.last_mod); printf("\tLast mod Time: (%x) ",file_entry.last_mod);
prodos_print_time(file_entry.last_mod); prodos_print_time(file_entry.last_mod);
printf("\n"); printf("\n");
file_entry.header_pointer=file_desc[0x25]|
file_desc[0x26]<<8;
printf("\tHeader pointer: %x\n",file_entry.header_pointer); printf("\tHeader pointer: %x\n",file_entry.header_pointer);
} }