home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
109_01
/
ucsdir.c
< prev
next >
Wrap
Text File
|
1985-03-10
|
8KB
|
300 lines
/* -------------------------------------------------------
*** Template for Procedure Heading ***
Name:
Result:
Errors:
Globals:
Macros:
Procedures:
Action:
------------------------------------------------------- */
/* : : : : : : : : : : : : : : : : : : : : : : : : : : : :
ucsdir -- List the directory of a UCSD Pascal diskette
H.Moran 10/27/79
column labels added 2/13/80
quick and dirty sort added 2/14/80
: : : : : : : : : : : : : : : : : : : : : : : : : : : : */
/* : : : : : : : : : : : : : : : : : : : : : : : : : : : :
Constants
: : : : : : : : : : : : : : : : : : : : : : : : : : : : */
#define SEL_DSK 14 /* bdos function number */
#define SET_DMA 26 /* bdos function number */
#define SET_TRK 9 /* bios index number */
#define SET_SEC 10 /* bios index number */
#define READ 12 /* bios index number */
#define DUMMY 0 /* dummy parameter for bios routine */
#define D_ENT_SZ 26 /* UCSD directory entry size */
#define D_TITLE 6 /* offset to entry title */
#define UCSD_NAM_SZ 17 /* size of the name part of ucsd dir entry */
#define UCSD_DIR_SZ 2048 /* size of UCSD directory in bytes */
#define SECT_SIZE 128 /* bytes per physical sector */
#define BLOK_SIZE 512 /* bytes per UCSD logical block */
#define SECT_PER_BLOK 4 /* physical sectors per logical block */
/* : : : : : : : : : : : : : : : : : : : : : : : : : : : :
Globals -- these would be static if it were available
: : : : : : : : : : : : : : : : : : : : : : : : : : : : */
int lsn; /* logical sector number */
int lstlsn; /* last logical sector number */
int nbytes; /* number of bytes remaining in ucsd file buffer */
char ucsdbuf[BLOK_SIZE]; /* 1 block buffer for ucsd directory */
char *ptr; /* pointer to current byte in ucsd buffer */
/* -------------------------------------------------------
Name: main(argc,argv)
Result: ---
Errors: ---
Globals: lsn,lstlsn,nbytes,ptr,ucsdbuf[]
Macros: ---
Procedures: printf(),exit(),ucsdir()
Action: Handle invocation errors
Call ucsdir() to list from drive B
a UCSD formatted directory
------------------------------------------------------- */
main(argc,argv)
int argc;
char *argv[];
{
lsn = lstlsn = nbytes = 0; /* init globals */
ptr = ucsdbuf;
if( argc != 1 ) {
printf("Proper invocation form is:\n\n");
printf("ucsdir\n");
printf("Will list the directory of the UCSD disk on drive B\n");
exit(1);
}
ucsdir();
exit(0);
}
/* -------------------------------------------------------
Name: ucsdir()
Result: ---
Errors: sector read error (aborts)
Globals: lsn,lstlsn
Macros: D_TITLE,UCSD_NAM_SZ,UCSD_NAM_SZ
D_ENT_SZ,SECT_PER_BLOK
Procedures: read_ucsd(),putchar(),puts()
Action: Read from the diskette on drive B
and print on the console
the directory of a presumed
UCSD Pascal formatted disk
------------------------------------------------------- */
ucsdir()
{
char ucsd_dir[UCSD_DIR_SZ];
char *dir,*saved_dir;
int name_len,colct,entries,dunno;
int cmpare(),i;
read_ucsd(ucsd_dir,(2*SECT_PER_BLOK),4); /* get entire directory */
dir = &ucsd_dir[D_TITLE]; /* print volume label */
puts("\nDirectory of : ");
name_len = *dir++;
while ( name_len-- )
putchar(*dir++);
puts("\n\n");
dir = &ucsd_dir[(D_TITLE + D_ENT_SZ)]; /* point to 1'st entry */
i = 0;
while( *(dir+i) != 0 && (dir+i) < &ucsd_dir[UCSD_DIR_SZ] )
i += D_ENT_SZ;
qsort((dir-D_TITLE),(i)/D_ENT_SZ,D_ENT_SZ,&cmpare);
entries = 0;
puts("\nFilename locn len type");
puts(" Filename locn len type");
puts("\n---------------- ---- ---- ----");
puts(" ---------------- ---- ---- ----\n");
while ( dir < &ucsd_dir[UCSD_DIR_SZ] ) {/* print directory entries */
saved_dir = dir;
colct = 1;
name_len = *dir++;
if( name_len <= 0 || name_len > (UCSD_NAM_SZ-1) )
break;
while( name_len-- ) { /* print the file name */
putchar(*dir++);
colct++;
}
while( colct++ <UCSD_NAM_SZ ) /* print spaces to max name length */
putchar(' ');
dir = saved_dir - D_TITLE; /* point to begin of entry */
/* i.e. block alloc. indicators */
lsn = *dir++ + ( *dir++ << 8);/* lsn = starting logical block # */
lstlsn= *dir++ +(*dir++ << 8);/* lstlsn = ending logical block # */
dunno = *dir++ + (*dir++ <<8);/* file type */
printf(" %4d %4d %4d",lsn,lstlsn-lsn,dunno);
dir = saved_dir + D_ENT_SZ; /* dir = pointer to next entry */
entries & 1 ? puts("\n") : puts(" ");
entries++;
}
return;
}
/* -------------------------------------------------------
Name: read_ucsd(buf,rn,count)
Result: result of selecting drive A
Errors: sector read error (exit to CP/M)
Globals: ---
Macros: SEL_DSK,SET_DMA,SET_TRK,SET_SEC
READ,DUMMY,SECT_SIZE,SEL_DSK
Procedures: bdos(),bios(),printf(),exit()
track(),sector()
Action: Read count UCSD sized blocks from drive B
into buf[] starting at logical record number
rn using the UCSD Pascal logical record
number to physical sector mapping
------------------------------------------------------- */
read_ucsd(buf,rn,count)
char *buf;
int rn;
int count;
{
char bios();
int seccnt; seccnt = count*4;
bdos(SEL_DSK,1);
while( seccnt-- ) {
bdos(SET_DMA,buf);
bios(SET_TRK,track(rn));
bios(SET_SEC,sector(rn));
if( bios(READ,DUMMY) ) {
printf("read error @ track %2d sector %2d",track(rn),sector(rn));
exit(1);
}
buf += SECT_SIZE;
rn++;
}
return bdos(SEL_DSK,0);
}
/* -------------------------------------------------------
Name: sector(rn)
Result: physical sector number
Errors: ---
Globals: ---
Macros: ---
Procedures: ---
Action: This code maps logical sectors to physical
sectors by selecting every second sector
in order (accounting for the modulo 26
process) on the diskette except that at a
track switchover point there is an additional
'gap' of 6 sectors (total of 7) to allow
for the drive to seek. This is UCSD's
attempt to minimize disk access time.
------------------------------------------------------- */
sector(rn)
unsigned rn;
{
unsigned t1,t2,trk,t3,sect;
t1 = rn % 26;
t2 = t1 << 1;
if(t1 > 12)
t2++;
trk = rn/26; /* zero based absolute track */
t3 = t2 + 6*trk; /* new logical sector number */
sect = t3 % 26; /* new zero based absolute sector */
return ++sect; /* one based absolute sector */
}
/* -------------------------------------------------------
Name: track(rn)
Result: physical track number
Errors: ---
Globals: ---
Macros: ---
Procedures: ---
Action: convert logical sector number to
absolute track number. This is simply
the modulo 26 process except that
track 0 is not considered part of the
logical sector space.
------------------------------------------------------- */
track(rn)
unsigned rn;
{
return rn/26 + 1;
}
/* tacked on compare of filenames */
cmpare(x,y)
char *x,*y;
{
int i,j,k;
x += D_TITLE;
y += D_TITLE;
for( i = *x++, j = *y++; j & i; i--, j--, x++, y++ ) {
if( *x > *y )
return -1;
if( *x < *y )
return 1;
}
if( i && ! j )
return 1;
if( j && ! i )
return -1;
return 0;
}