home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / sysutl / dsk-bio7.lbr / DSK-BIO7.CQ / DSK-BIO7.C
Text File  |  1985-10-06  |  12KB  |  311 lines

  1. /*      Disk Biology    Mar 29, 1984              
  2.  
  3.         Version:        3.7
  4.  
  5.         Written by:     John P. Hohensee
  6.                         San Bernardino, CA
  7.                         (714) 884-0825
  8.  
  9.         The CP/M system utilizes information contained in the system
  10.         (B)asic (D)isk (O)perating (S)ystem to identify the format 
  11.         of a specific disk.  Disk Parameter Header will locate items
  12.         of interest about a disk drive, while the Disk Parameter
  13.         Block details the information about the drive.  
  14.  
  15.         This program will read all drives reporting the vital stat-
  16.         istics contained within the CP/M system about the drive,
  17.         location of this information, specific information and what
  18.         the information does for your drive.
  19.  
  20.         This program was written with The Software Toolworks C/80
  21.         C language compiler version 2.0.  "CPMCALL.C", providing bdos   
  22.         and bios routines for the C/80 version of C, was written by 
  23.         T. Bolstad, ELECTROKONSULT AS, and published in Dr. Dobbs 
  24.         Journal, Jun 83.
  25.  
  26.         The following is an example of the output product for the CP/M
  27.         standard disk format:
  28.  
  29.         DSK-BIO x       Request specified drive parameters
  30.                         where x = ('a' -> 'p') OR ('A' -> 'P')
  31.         DSK-BIO *       Request all drive parameters
  32.         DSK-BIO         Or any other character, Built-in HELP file
  33.  
  34.  
  35. Disk Biology  -  Version 3.7  -  John P. Hohensee
  36. Placed in the Public Domain  -          29 Mar 84
  37.  
  38.        DISK PARAMETER BLOCK               For disk drive A:
  39. SPT = 1A00  Records per track    26       
  40. BSH = 03    Block shift fact      3              DISK PARAMETER HEADER
  41. BLM = 07    Block shift mask      7       Disk Parameter Header starts @ E345
  42. EXM = 00    Extent mask           0
  43. DSM = F200  Num Alloc Blocks    242       Skew table starts            @ E47B
  44. DRM = 3F00  Num Dir entries -1   63       Directory Buffer starts      @ F556
  45. AL0 = 1100$0000B  Blocks reserved         Disk Parameter Block starts  @ E3D6
  46. AL1 = 0000$0000B  for directory           Directory checksum starts    @ FA62
  47. CKS = 1000  Dir check size       16       Disk allocation table        @ FAA2
  48. OFF = 0200  Num System trks       2
  49.  
  50. Allocation size    = 1024         Extent size        =   16K
  51. Capacity of disk   =  241K        Number of tracks   =   77 
  52. Disk type is 8", 48tpi, Single Sided
  53.  
  54. Physical Rec Sequence for logical rec: (1, 2, 3, etc):
  55.    1   7  13  19  25   5  11  17  23   3   9  15  21   2   8  14
  56.   20  26   6  12  18  24   4  10  16  22
  57.  
  58.  
  59. */ 
  60.  
  61.  
  62.  
  63. #include "cpmcall.c"    /*  Written by T. Bolstad, ELECTROKONSULT AS  */
  64. #include "printf.c"     /*  Standard print formatting                 */
  65. #define short char      /*  Makes reading the data size easier        */
  66.  
  67. int res, dsk;           /*  Global variable, Ones count, dsk drive    */
  68.  
  69. main(argc,argv)
  70. int argc;
  71. char *argv[];
  72. {
  73.  
  74.         /*  Test for all logical drives  */
  75.  
  76.     if(*argv[1] == '*')                 
  77.         {
  78.         for(dsk = 0; dsk < 16; dsk++)
  79.             {
  80.             biology();
  81.             printf("\n\n\t\tPress <RETURN> to continue:");
  82.             getchar();
  83.             }
  84.         exit();
  85.         }
  86.  
  87.         /*  Test for a specified drive  */
  88.  
  89.     if('A' <= *argv[1] && *argv[1] <= 'P' )
  90.         {
  91.         dsk = (*argv[1] & 037) - 1;
  92.         biology();
  93.         exit();
  94.         }
  95.  
  96.         /*  Print HELP file  */
  97.  
  98.     printf("\nDSK-BIO      Print this built-in help file.");
  99.     printf("\nDSK-BIO x    Parameters for the specified drive.");
  100.     printf("\nDSK-BIO *    Parameters for all logical drives.");
  101.  
  102. }
  103.  
  104.  
  105. biology()
  106. {
  107.     int i, j, k;                        /*  Temp variables     */
  108.     int spt, spb, bpd, nsect, tpd;      /*  Compute variables  */
  109.     char *skew_addr;            /*  Skew locations     */
  110.         
  111.     struct dpblock{     /*  DISK PARAMETER BLOCK              */
  112.         unsigned spt;   /*  Sectors per track                 */
  113.         short  bsh;     /*  Block Shift factor                */
  114.         short  blm;     /*  Block shift mask                  */
  115.         short  exm;     /*  Extent mask                       */
  116.         unsigned dsm;   /*  Drive storage capacity            */
  117.         unsigned drm;   /*  Number of directory entries -1    */
  118.         short  al0;     /*  Reserved for directory            */
  119.         short  al1;     /*  Reserved for dir 2                */
  120.         unsigned cks;   /*  Directory check vector size       */
  121.         unsigned off;   /*  Number of reserved system tracks  */
  122.         } *dpbptr;
  123.  
  124.     struct dph{                 /*  DISK PARAMETER HEADER       */
  125.         int     *skew_table;    /*  Pointer to Skew table       */
  126.         int     b1,b2,b3;       /*  BDOS work area              */
  127.         int     *dirbuff;       /*  Pointer to directory buff   */
  128.         struct  dpblock  *dpb;  /*  Pointer to disk param block */
  129.         int     *csv;           /*  Pointer to directory ck sum */
  130.         int     *alv;           /*  Pointer to block alloc tble */
  131.         } *dpbase;
  132.  
  133.  
  134.               
  135.         /*  bios(funct,arg1,arg2) as defined in "CPMCALL.C",
  136.  
  137.                 [funct] is one of the bios calls, SETTRK, SELDSK etc.
  138.  
  139.                 [arg1] and [arg2] are information required for the 
  140.                 function.  
  141.  
  142.             bdos(funct,arg1) as defined in "CPMCALL.C", 
  143.                 
  144.                 [funct] is one of the bdos calls, RESET, RETCD etc.
  145.  
  146.                 [arg1] is information required for that function.
  147.  
  148.         */
  149.  
  150.  
  151.     dpbase = bios(SELDSK,dsk,0);                /*  Current drive */
  152.  
  153.     if(dpbase == 0) exit();     /*  Disk Param Block Not Found   */
  154.  
  155.     dpbptr = dpbase->dpb;       /*  Pointer to disk param        */
  156.     spt = dpbptr->spt;          /*  Number of records per track  */
  157.  
  158.     printf("\nDisk Biology  -  Version 3.7  -  John P. Hohensee\n");
  159.     printf("Placed in the Public Domain  -            29 Mar 84\n");
  160.  
  161.     printf("\n        DISK PARAMETER BLOCK");
  162.     printf("\t\tFor disk drive %c:",dsk+'A');
  163.  
  164.     printf("\nSPT = %2x%2x  Records per trk  %4d",
  165.                     (dpbptr->spt & 0377),(dpbptr->spt)>>8,dpbptr->spt);
  166.  
  167.     printf("\nBSH = %2x    Block shift fact %4d",dpbptr->bsh,dpbptr->bsh);
  168.     printf("\t\tDISK PARAMETER HEADER");
  169.  
  170.     printf("\nBLM = %2x    Block shift mask %4d",dpbptr->blm,dpbptr->blm);
  171.     printf("\tDisk Parameter Header starts @ %4x",dpbase);
  172.  
  173.     printf("\nEXM = %2x    Extent mask      %4d",dpbptr->exm,dpbptr->exm);
  174.  
  175.     printf("\nDSM = %2x%2x  Num Alloc Blocks %4d",
  176.                     (dpbptr->dsm & 0377),(dpbptr->dsm)>>8,dpbptr->dsm);
  177.     skew_addr = dpbase->skew_table;
  178.  
  179.     if(skew_addr)
  180.         if(skew_addr < 32767)
  181.             printf("\tNon-Standard Skew table defined.");
  182.         else
  183.             printf("\tSkew table starts            @ %4x",dpbase->skew_table);
  184.     else 
  185.          printf("\tNo Skew table address given");
  186.  
  187.     printf("\nDRM = %2x%2x  Num Dir entries  %4d",
  188.                     (dpbptr->drm & 0377),(dpbptr->drm)>>8,dpbptr->drm);
  189.     printf("\tDirectory Buffer starts      @ %4x",dpbase->dirbuff);
  190.  
  191.     res = 0;
  192.     printf("\nAL0 = ");
  193.     binary(dpbptr->al0);           /*  Print hex digit in binary  */
  194.     printf("  Blocks reserved");
  195.     printf("\tDisk Param Block starts      @ %4x",dpbptr);
  196.  
  197.     printf("\nAL1 = ");
  198.     binary(dpbptr->al1);
  199.     printf("  for directory    ");
  200.     printf("\tDirectory checksum starts    @ %4x",dpbase->csv);
  201.  
  202.     printf("\nCKS = %2x%2x  Dir check size   %4d",
  203.                     (dpbptr->cks & 0377),(dpbptr->cks)>>8,dpbptr->cks);
  204.     printf("\tDisk allocation table        @ %4x",dpbase->alv);
  205.  
  206.     printf("\nOFF = %2x%2x  Num System trks  %4d",
  207.                     (dpbptr->off & 0377),(dpbptr->off)>>8,dpbptr->off);
  208.  
  209.     /*  Allocation Size:  is one CP/M record, 128 bytes, times the log2
  210.         of the BSH.  This is accomplished by shifting the constant 128
  211.         left BSH times.  IE.  files are written in multiples of the 
  212.         allocation size.    */
  213.  
  214.     printf("\n");
  215.     j = 128;
  216.     i = j <<= dpbptr->bsh;              /*  Compute allocation size  */
  217.         
  218.     /*  Reserve: defines the number of reserved allocation blocks, see
  219.         the number of ONE'S printed in AL0 and AL1.  Each block holds
  220.         information for the directory on floppy disks.  */
  221.  
  222.     printf("\nAllocation size    = %4d",i);  
  223.     printf("\tExtent size        = %4dK",(dpbptr->exm+1) * 16);
  224.  
  225.     /*  Disk Capacity:  (D)isk (S)ector (M)aximum, do not confuse this with
  226.         your sector size, defines the number of allocation blocks on this
  227.         disk drive.  (B)lock (S)hift (M)ask is a log2 of the multiplier 
  228.         used to define the maximum disk capacity.  From the maximum capacity
  229.         the size of system and directory space must be subtracted.      */
  230.         
  231.     j = dpbptr->dsm+1;
  232.     k = j <<= ((dpbptr->bsh) - 3);      /*  Compute disk capacity  */
  233.     printf("\nCapacity of disk   = %4dK",k - ( i / 1024 * res));
  234.  
  235.     bpd = dpbptr->dsm+1;        /*  This method is used to prevent  */
  236.     spb = dpbptr->blm+1;        /*  possible overflow when large    */
  237.     nsect = 0;                  /*  capacity disks, ie hard disks   */
  238.     tpd = 1;                    /*  are addressed.                  */
  239.     for(i=0; i<bpd; i++)
  240.         {
  241.             nsect += spb;
  242.             if(nsect > spt)
  243.                 {
  244.                     nsect -= spt;
  245.                     tpd++;
  246.                 }
  247.         }
  248.     tpd += dpbptr->off;
  249.  
  250.     printf("\tNumber of tracks   = %4d",tpd);
  251.  
  252.     printf("\nDisk type is ");
  253.  
  254.     if(tpd < 42)                printf("5\", 48tpi, Single Sided");
  255.     if(tpd > 74 && tpd < 78)    printf("8\", 48tpi, Single Sided");
  256.     if(tpd > 78 && tpd < 82)
  257.         printf("5\", 48tpi, Double Sided or 5\", 96tpi, Single Sided");
  258.     if(tpd > 150 && tpd < 158)  printf("8\", 48tpi, Double Sided");
  259.     if(tpd > 158)               printf("undeterminable.");
  260.  
  261.  
  262.     /*  SKEW PATTERN:  Some drives use an offset between logical and physical
  263.         records to improve the read/write speed of the drive.  This pattern
  264.         is reflected in the Physical record sequence.  The print-out will 
  265.         display the sequence of logical records on the drive.   */
  266.  
  267.         
  268.     if(skew_addr > 32767)       /*  Print skew table if used  */
  269.         {
  270.         skew_addr--;            /*  Initial decrement of skew location  */
  271.         printf("\n\nPhysical Rec Sequence for logical rec: (1, 2, 3, etc)\n");
  272.         for(i=0; i<spt; i++)
  273.             {
  274.             skew_addr++;        /*  Increment skew location     */
  275.             printf("%3d%c",*skew_addr,(i%16==15 || i==spt-1) ? '\n' : ' ');
  276.             }
  277.         }
  278.     else  if(skew_addr)
  279.               printf("\n\nSkew addr contents = %4x",skew_addr);
  280.           else
  281.               printf("\n\n");
  282. }
  283.  
  284. /* * * * * * * * * * *  SUB-ROUTINES  * * * * * * * * * * * * * */
  285.  
  286. binary(c)               /*  Convert byte to ones and zero's     */
  287. char c;
  288. {
  289. int i;
  290.  
  291.     i = c;                      /*  Convert character into integer      */
  292.     i <<= 8;                    /*  Move lower 8 to upper 8 bits        */
  293.     one_out(i);                 /*  Do upper hex digit first            */
  294.     putchar('$');               /*  Print seperator                     */
  295.     one_out(i <<= 4);           /*  Do lower hex digit next             */
  296.     putchar('B');               /*  Print binary symbol                 */
  297. }
  298.  
  299. one_out(c)      /*  Convert hexidecimal digit to a binary string        */
  300. int c;          
  301. {
  302. int j;
  303.  
  304.     for(j=0;j<4;j++)            /*  Make four passes, each binary bit   */
  305.     {
  306.         putchar(c < 0 ? '1' : '0'); /* print a '1' or '0'       */
  307.         if(c < 0) res++;        /*  Count the number of '1's    */
  308.         c <<= 1;                /*  move next bit to sign       */
  309.     }
  310. }
  311.