home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
sysutl
/
dsk-bio7.lbr
/
DSK-BIO7.CQ
/
DSK-BIO7.C
Wrap
Text File
|
1985-10-06
|
12KB
|
311 lines
/* Disk Biology Mar 29, 1984
Version: 3.7
Written by: John P. Hohensee
San Bernardino, CA
(714) 884-0825
The CP/M system utilizes information contained in the system
(B)asic (D)isk (O)perating (S)ystem to identify the format
of a specific disk. Disk Parameter Header will locate items
of interest about a disk drive, while the Disk Parameter
Block details the information about the drive.
This program will read all drives reporting the vital stat-
istics contained within the CP/M system about the drive,
location of this information, specific information and what
the information does for your drive.
This program was written with The Software Toolworks C/80
C language compiler version 2.0. "CPMCALL.C", providing bdos
and bios routines for the C/80 version of C, was written by
T. Bolstad, ELECTROKONSULT AS, and published in Dr. Dobbs
Journal, Jun 83.
The following is an example of the output product for the CP/M
standard disk format:
DSK-BIO x Request specified drive parameters
where x = ('a' -> 'p') OR ('A' -> 'P')
DSK-BIO * Request all drive parameters
DSK-BIO Or any other character, Built-in HELP file
Disk Biology - Version 3.7 - John P. Hohensee
Placed in the Public Domain - 29 Mar 84
DISK PARAMETER BLOCK For disk drive A:
SPT = 1A00 Records per track 26
BSH = 03 Block shift fact 3 DISK PARAMETER HEADER
BLM = 07 Block shift mask 7 Disk Parameter Header starts @ E345
EXM = 00 Extent mask 0
DSM = F200 Num Alloc Blocks 242 Skew table starts @ E47B
DRM = 3F00 Num Dir entries -1 63 Directory Buffer starts @ F556
AL0 = 1100$0000B Blocks reserved Disk Parameter Block starts @ E3D6
AL1 = 0000$0000B for directory Directory checksum starts @ FA62
CKS = 1000 Dir check size 16 Disk allocation table @ FAA2
OFF = 0200 Num System trks 2
Allocation size = 1024 Extent size = 16K
Capacity of disk = 241K Number of tracks = 77
Disk type is 8", 48tpi, Single Sided
Physical Rec Sequence for logical rec: (1, 2, 3, etc):
1 7 13 19 25 5 11 17 23 3 9 15 21 2 8 14
20 26 6 12 18 24 4 10 16 22
*/
#include "cpmcall.c" /* Written by T. Bolstad, ELECTROKONSULT AS */
#include "printf.c" /* Standard print formatting */
#define short char /* Makes reading the data size easier */
int res, dsk; /* Global variable, Ones count, dsk drive */
main(argc,argv)
int argc;
char *argv[];
{
/* Test for all logical drives */
if(*argv[1] == '*')
{
for(dsk = 0; dsk < 16; dsk++)
{
biology();
printf("\n\n\t\tPress <RETURN> to continue:");
getchar();
}
exit();
}
/* Test for a specified drive */
if('A' <= *argv[1] && *argv[1] <= 'P' )
{
dsk = (*argv[1] & 037) - 1;
biology();
exit();
}
/* Print HELP file */
printf("\nDSK-BIO Print this built-in help file.");
printf("\nDSK-BIO x Parameters for the specified drive.");
printf("\nDSK-BIO * Parameters for all logical drives.");
}
biology()
{
int i, j, k; /* Temp variables */
int spt, spb, bpd, nsect, tpd; /* Compute variables */
char *skew_addr; /* Skew locations */
struct dpblock{ /* DISK PARAMETER BLOCK */
unsigned spt; /* Sectors per track */
short bsh; /* Block Shift factor */
short blm; /* Block shift mask */
short exm; /* Extent mask */
unsigned dsm; /* Drive storage capacity */
unsigned drm; /* Number of directory entries -1 */
short al0; /* Reserved for directory */
short al1; /* Reserved for dir 2 */
unsigned cks; /* Directory check vector size */
unsigned off; /* Number of reserved system tracks */
} *dpbptr;
struct dph{ /* DISK PARAMETER HEADER */
int *skew_table; /* Pointer to Skew table */
int b1,b2,b3; /* BDOS work area */
int *dirbuff; /* Pointer to directory buff */
struct dpblock *dpb; /* Pointer to disk param block */
int *csv; /* Pointer to directory ck sum */
int *alv; /* Pointer to block alloc tble */
} *dpbase;
/* bios(funct,arg1,arg2) as defined in "CPMCALL.C",
[funct] is one of the bios calls, SETTRK, SELDSK etc.
[arg1] and [arg2] are information required for the
function.
bdos(funct,arg1) as defined in "CPMCALL.C",
[funct] is one of the bdos calls, RESET, RETCD etc.
[arg1] is information required for that function.
*/
dpbase = bios(SELDSK,dsk,0); /* Current drive */
if(dpbase == 0) exit(); /* Disk Param Block Not Found */
dpbptr = dpbase->dpb; /* Pointer to disk param */
spt = dpbptr->spt; /* Number of records per track */
printf("\nDisk Biology - Version 3.7 - John P. Hohensee\n");
printf("Placed in the Public Domain - 29 Mar 84\n");
printf("\n DISK PARAMETER BLOCK");
printf("\t\tFor disk drive %c:",dsk+'A');
printf("\nSPT = %2x%2x Records per trk %4d",
(dpbptr->spt & 0377),(dpbptr->spt)>>8,dpbptr->spt);
printf("\nBSH = %2x Block shift fact %4d",dpbptr->bsh,dpbptr->bsh);
printf("\t\tDISK PARAMETER HEADER");
printf("\nBLM = %2x Block shift mask %4d",dpbptr->blm,dpbptr->blm);
printf("\tDisk Parameter Header starts @ %4x",dpbase);
printf("\nEXM = %2x Extent mask %4d",dpbptr->exm,dpbptr->exm);
printf("\nDSM = %2x%2x Num Alloc Blocks %4d",
(dpbptr->dsm & 0377),(dpbptr->dsm)>>8,dpbptr->dsm);
skew_addr = dpbase->skew_table;
if(skew_addr)
if(skew_addr < 32767)
printf("\tNon-Standard Skew table defined.");
else
printf("\tSkew table starts @ %4x",dpbase->skew_table);
else
printf("\tNo Skew table address given");
printf("\nDRM = %2x%2x Num Dir entries %4d",
(dpbptr->drm & 0377),(dpbptr->drm)>>8,dpbptr->drm);
printf("\tDirectory Buffer starts @ %4x",dpbase->dirbuff);
res = 0;
printf("\nAL0 = ");
binary(dpbptr->al0); /* Print hex digit in binary */
printf(" Blocks reserved");
printf("\tDisk Param Block starts @ %4x",dpbptr);
printf("\nAL1 = ");
binary(dpbptr->al1);
printf(" for directory ");
printf("\tDirectory checksum starts @ %4x",dpbase->csv);
printf("\nCKS = %2x%2x Dir check size %4d",
(dpbptr->cks & 0377),(dpbptr->cks)>>8,dpbptr->cks);
printf("\tDisk allocation table @ %4x",dpbase->alv);
printf("\nOFF = %2x%2x Num System trks %4d",
(dpbptr->off & 0377),(dpbptr->off)>>8,dpbptr->off);
/* Allocation Size: is one CP/M record, 128 bytes, times the log2
of the BSH. This is accomplished by shifting the constant 128
left BSH times. IE. files are written in multiples of the
allocation size. */
printf("\n");
j = 128;
i = j <<= dpbptr->bsh; /* Compute allocation size */
/* Reserve: defines the number of reserved allocation blocks, see
the number of ONE'S printed in AL0 and AL1. Each block holds
information for the directory on floppy disks. */
printf("\nAllocation size = %4d",i);
printf("\tExtent size = %4dK",(dpbptr->exm+1) * 16);
/* Disk Capacity: (D)isk (S)ector (M)aximum, do not confuse this with
your sector size, defines the number of allocation blocks on this
disk drive. (B)lock (S)hift (M)ask is a log2 of the multiplier
used to define the maximum disk capacity. From the maximum capacity
the size of system and directory space must be subtracted. */
j = dpbptr->dsm+1;
k = j <<= ((dpbptr->bsh) - 3); /* Compute disk capacity */
printf("\nCapacity of disk = %4dK",k - ( i / 1024 * res));
bpd = dpbptr->dsm+1; /* This method is used to prevent */
spb = dpbptr->blm+1; /* possible overflow when large */
nsect = 0; /* capacity disks, ie hard disks */
tpd = 1; /* are addressed. */
for(i=0; i<bpd; i++)
{
nsect += spb;
if(nsect > spt)
{
nsect -= spt;
tpd++;
}
}
tpd += dpbptr->off;
printf("\tNumber of tracks = %4d",tpd);
printf("\nDisk type is ");
if(tpd < 42) printf("5\", 48tpi, Single Sided");
if(tpd > 74 && tpd < 78) printf("8\", 48tpi, Single Sided");
if(tpd > 78 && tpd < 82)
printf("5\", 48tpi, Double Sided or 5\", 96tpi, Single Sided");
if(tpd > 150 && tpd < 158) printf("8\", 48tpi, Double Sided");
if(tpd > 158) printf("undeterminable.");
/* SKEW PATTERN: Some drives use an offset between logical and physical
records to improve the read/write speed of the drive. This pattern
is reflected in the Physical record sequence. The print-out will
display the sequence of logical records on the drive. */
if(skew_addr > 32767) /* Print skew table if used */
{
skew_addr--; /* Initial decrement of skew location */
printf("\n\nPhysical Rec Sequence for logical rec: (1, 2, 3, etc)\n");
for(i=0; i<spt; i++)
{
skew_addr++; /* Increment skew location */
printf("%3d%c",*skew_addr,(i%16==15 || i==spt-1) ? '\n' : ' ');
}
}
else if(skew_addr)
printf("\n\nSkew addr contents = %4x",skew_addr);
else
printf("\n\n");
}
/* * * * * * * * * * * SUB-ROUTINES * * * * * * * * * * * * * */
binary(c) /* Convert byte to ones and zero's */
char c;
{
int i;
i = c; /* Convert character into integer */
i <<= 8; /* Move lower 8 to upper 8 bits */
one_out(i); /* Do upper hex digit first */
putchar('$'); /* Print seperator */
one_out(i <<= 4); /* Do lower hex digit next */
putchar('B'); /* Print binary symbol */
}
one_out(c) /* Convert hexidecimal digit to a binary string */
int c;
{
int j;
for(j=0;j<4;j++) /* Make four passes, each binary bit */
{
putchar(c < 0 ? '1' : '0'); /* print a '1' or '0' */
if(c < 0) res++; /* Count the number of '1's */
c <<= 1; /* move next bit to sign */
}
}