/******************************************************************************/ /* showdpb() */ /* Copyright (c) 1984 by Paul M. Sittler */ /******************************************************************************/ #include "bdosdef.h" #include "cbiosdef.h" showdpb() { /******************************************************************************/ /* local variables */ /******************************************************************************/ char al0binstr[10]; /* AL0 as binary coded ascii array */ char al1binstr[10]; /* AL1 as binary coded ascii array */ char alvbinstr[10]; /* ALV as binary coded ascii array */ char dpb_str[16]; /* disk parameter block array */ char dph_str[17]; /* disk parameter header array */ char curdrive; /* currently logged-in drive */ char *ptr; /* needs to be set to char, not int!! */ char drive; /* drive number (0 - 15) */ char i; /* all-purpose i */ unsigned totl; /* total number of allocation vector bytes */ int *dpbaddr; /* disk parameter block address */ int *dphaddr; /* disk parameter header address */ int sysversn; /* operating system version number */ unsigned spt;/* SPT: (word) total # of logical 128-byte sectors/track */ char bsh; /* BSH: (byte) data allocation block shift factor, determined */ /* by data block allocation size */ /* 1k=3 2k=4 4k=5 8k=6 16k=7 */ char blm; /* BLM: (byte) data allocation block mask (2**[BSH-1]) */ /* 1k=7 2k=15 4k=31 8k=63 16k=127 */ char exm; /* EXM: (byte) extent mask, determined by the data block */ /* allocation size and the number of disk blocks */ /* 1k=0 2k=1 4k=3 8k=7 16k=15 if DSM < 256 */ /* 1k=n 2k=0 4k=1 8k=3 16k=7 if DSM > 256 */ unsigned dsm;/* DSM: (word) disk size in blocks-1; determines the total */ /* storage capacity of the disk size */ unsigned drm;/* DRM: (word) directory size-1; determines the total number */ /* directory entries that can be stored on this */ /* drive. DRM: = ((# dir entries) / 4) -1 */ /* AL0, AL1 determine reserved directory blocks. */ char al0; /* AL0: (byte) alloc0 (1100 0000) 2 blocks/dir */ /* (1000 0000) 1 block/dir */ char al1; /* AL1: (byte) alloc1 (0000 0000) */ /* Note that AL0: and AL1: are taken together */ /* as a single sixteen-bit mask for the number */ /* of blocks of directory allocation. */ /* (1100 0000 0000 0000) 2 blocks/dir */ /* (1000 0000 0000 0000) 1 block/dir */ unsigned cks;/* CKS: (word) directory check vector size */ unsigned off;/* OFF: (word) # of reserved system tracks (offset) at the */ /* beginning of the (logical) disk. The */ /* directory begins at the first sector of the */ /* track defined by this number. */ unsigned xlt;/* XLT: (word) address of the logical to physical sector */ /* translation vector, if used, for this */ /* particular drive; or the value 0x0000 if no */ /* sector translation takes place (i.e., the */ /* logical and physical sector numbers are the */ /* same). Disk drives with identical sector skew */ /* factors share the same translate tables. */ unsigned dirbuf;/* DIRBUF: (word) Address of a 128-byte scratchpad area for */ /* for directory operations within BDOS. All */ /* DPH's address the same scratchpad area. */ unsigned dphdpb;/* DPHDPB: (word) Disk parameter block address in dp header */ /* which can be used as a check for the DPB */ /* address obtained from the bdos call. */ unsigned csv; /* CSV: (word) Address of a scratchpad area used for software */ /* check for changed disks. This address is */ /* different for each DPH. */ unsigned alv; /* ALV: (word) Address of a scratchpad area used by BDOS to */ /* keep disk storage allocation information. */ /* This address is different for each DPH. */ int block_size; /* The data allocation block size in Kbytes */ unsigned tot_size_disk;/* The total size of the disk in Kbytes */ unsigned dir_entries;/* The number of directory entries blocked for */ unsigned dir_size_disk;/* The directory area of the disk in Kbytes */ unsigned use_size_disk;/* The useful size of the disk in Kbytes */ #ifdef CDR_BIOS /* for H/Z CDR bios include: */ char *cdraddr; /* CDR-specific disk parameter block address */ char cdrbinstr[10]; /* CDR disk type as binary coded ascii array */ char cdr_str[7]; /* CDR-specific extended disk parameter block array */ char cdr_type; /* CDR: (byte) CDR-defined disk type */ char cdr_skw; /* SKW: (byte) CDR-defined skewing factor */ char cdr_stp; /* STP: (byte) CDR-defined step time value */ char cdr_hst; /* HST: (byte) CDR-defined host-sectors/track */ char cdr_sph; /* SPH: (byte) CDR-defined log-sectors/host-sector */ char cdr_tps; /* TPS: (byte) CDR-defined # tracks/disk side -1 */ #endif while (1) { puts("\n\n\tDo you wish to PROBE a drive's parameters (Y/N) ? "); do { puts("\bY\b"); drive = toupper(getchar()); if (drive == '\n') { drive = 'Y'; break; } } while (drive != 'Y' && drive != 'N'); if (drive == 'N') return; puts("\n\tWhich drive do you wish to PROBE (A - P) ? A\b"); while (1) { drive = toupper(getchar()); if (drive == '\n') { drive = 0; break; } if ( (drive < 'A') || (drive > 'P') ) { puts("\bA\b"); continue; } drive = drive - 'A'; break; } if ( (sysversn = bdos(RETURNVER,0) ) < 100) /* not MP/M ? */ bdos(RESETDISK,0); /* reset disk system */ dphaddr = biosh(SELDSK,drive,0);/* select drive where 0 = A: */ /* 1 = B:, etc. and store the dphaddr */ if (dphaddr == 0) /* if dphaddr = 0, error occurred */ continue; /* so go try another disk */ bdos(SELDISK,drive); /* select drive where 0 = A: */ /* 1 = B:, etc. */ curdrive = bdos(GETDISK,0) + 'A'; /* get current drive number and */ /* convert to ASCII */ dpbaddr = bdos(GETDPB,0); /* get disk parm block address */ ptr = dpbaddr; /* set ptr to disk parm block address */ for (i = 0; i < 15; i++) /* read the disk parameter block from */ dpb_str[i] = ptr[i]; /* memory into dpb_str[] */ spt = (*ptr++) + (*ptr++ << 8); /* SPT: (word) 128-byte sectors/track */ bsh = *ptr++; /* BSH: (byte) block shift factor */ blm = *ptr++; /* BLM: (byte) block mask */ exm = *ptr++; /* EXM: (byte) extent mask */ dsm = (*ptr++) + (*ptr++ << 8); /* DSM: (word) disk size in blocks-1 */ drm = (*ptr++) + (*ptr++ << 8); /* DSM: (word) directory size-1 */ al0 = *ptr++; /* AL0: (byte) alloc0 (1100 0000) */ al1 = *ptr++; /* AL1: (byte) alloc1 (0000 0000) */ cks = (*ptr++) + (*ptr++ << 8); /* CKS: (word) directory check size */ off = (*ptr++) + (*ptr++ << 8); /* OFF: (word) reserved system tracks */ #ifdef CDR_BIOS /* for H/Z CDR bios include: */ cdr_type = *ptr++; /* CDR: (byte) CDR-defined disk type */ cdr_skw = *ptr++; /* SKW: (byte) CDR-defined skew fact */ cdr_stp = *ptr++; /* STP: (byte) CDR-defined step time */ cdr_hst = *ptr++; /* HST: (byte) host sectors/track */ cdr_sph = *ptr++; /* SPH: (byte) l-sectors/host sector */ cdr_tps = *ptr; /* TPS: (byte) # tracks/disk side-1 */ ptr = dpbaddr; /* set pointer to start of dpb */ ptr += 15; /* set pointer to start of the */ /* CDR-specific additional disk */ /* parameters for the CDR bios */ cdraddr = ptr; /* save CDR-specif parm block address */ for (i = 0; i < 6; i++) /* read the CDR bios specific disk */ cdr_str[i] = ptr[i]; /* parameters into cdr_str[] */ asciitobin(cdr_type,cdrbinstr); /* represent cdr_type as bin string */ #endif asciitobin(al0,al0binstr); /* represent al0 as binary string */ asciitobin(al1,al1binstr); /* represent al1 as binary string */ printf("\n\nFor drive %c:, the disk parameter block address is %05x hex\n", curdrive,dpbaddr); puts("\nThe disk parameter block as it appears in memory (in hex):"); printf("\n\t%04x\t",dpbaddr); for (i = 0; i < 15; i++) printf(" %02x",dpb_str[i]); puts("\n\n\tParameter (SYM) Hex Decimal\t[ Binary ]"); printf("\n\tSectors per Track (SPT) = %04x %4u",spt,spt); printf("\n\tBlock Shift Factor (BSH) = %02x %4d",bsh,bsh); printf("\n\tAllocation Block Mask (BLM) = %02x %4d",blm,blm); printf("\n\tExtent Mask (EXM) = %02x %4d",exm,exm); printf("\n\tDisk Size Maximum (DSM) = %04x %4u",dsm,dsm); printf("\n\tDirectory Maximum -1 (DRM) = %04x %4u",drm,drm); printf("\n\tAllocation Mask 0 (AL0) = %02x %4d\t[%s]", al0,al0,al0binstr); printf("\n\tAllocation Mask 1 (AL1) = %02x %4d\t[%s]", al1,al1,al1binstr); printf("\n\tDirectory Check Size (CKS) = %04x %4u",cks,cks); printf("\n\tSystem Tracks Offset (OFF) = %04x %4u",off,off); puts("\n\n\tThe whole disk parameter block looks like:"); puts("\n\tSPT: BSH: BLM: EXM: DSM: DRM: AL0: AL1: CKS: OFF:"); printf( "\n\t%04x %02x %02x %02x %04x %04x %02x %02x %04x %04x", spt, bsh, blm, exm, dsm, drm, al0, al1, cks, off); #ifdef CDR_BIOS /* for H/Z CDR bios include: */ puts("\n\nThe following values are specific to the CDR Bios:\n"); puts("\nThe CDR parameter block as it appears in memory (in hex):"); printf("\n\t%04x\t",(cdraddr) ); for (i = 0; i < 6; i++) printf(" %02x",cdr_str[i]); puts("\n\n\tParameter (SYM) Hex Decimal\t[ Binary ]"); printf("\n\tCDR-defined Disk Type (CDR) = %02x %4d\t[%s]", cdr_type,cdr_type,cdrbinstr); printf("\n\tCDR Skewing factor (SKW) = %02x %4d", cdr_skw,cdr_skw); printf("\n\tDrive Stepping rate (STP) = %02x %4d", cdr_stp,cdr_stp); printf("\n\tHost Sectors/Track (HST) = %02x %4d", cdr_hst,cdr_hst); printf("\n\tLog-Sectors/Host Sector (SPH) = %02x %4d", cdr_sph,cdr_sph); printf("\n\tTracks/Side of Disk -1 (TPS) = %02x %4d\n", cdr_tps,cdr_tps); #endif printf("\n\nFor drive %c:, the disk parameter header address is %05x hex\n", curdrive,dphaddr); ptr = dphaddr; /* set ptr to disk parm hdr address */ for (i = 0; i < 16; i++) /* read the disk parameter hdr from */ dph_str[i] = ptr[i]; /* memory into dph_str[] */ puts("\nThe disk parameter header as it appears in memory (in hex):"); printf("\n\t%04x\t",dphaddr); for (i = 0; i < 16; i++) printf(" %02x",dph_str[i]); ptr = dphaddr; /* set ptr to disk parm hdr address */ xlt = (*ptr++) + (*ptr++ << 8); /* XLT: (word) translate table addr */ ptr += 6; /* skip over the scratchpad areas. */ dirbuf = (*ptr++) + (*ptr++ << 8); /* DIRBUF: (word) dir opn scratchpad */ dphdpb = (*ptr++) + (*ptr++ << 8); /* DPHDPB: (word) dpb address */ csv = (*ptr++) + (*ptr++ << 8); /* CSV: (word) check changed disks */ alv = (*ptr++) + (*ptr++ << 8); /* ALV: (word) disk storage alloc vect*/ puts("\n\n\tAddress Vector Description (SYM) Hex"); printf("\n\tLog to physical sector trans (XLT) = %04x",xlt); printf("\n\tDirectory buffer scratchpad (DIRBUF) = %04x",dirbuf); printf("\n\tDPB address in DPH (DPB) = %04x",dphdpb); printf("\n\tCheck changed disk scratchpad (CSV) = %04x",csv); printf("\n\tDisk space allocation vector (ALV) = %04x",alv); block_size = 1 << (bsh - 3); /* The data allocation block size in */ /* kilobytes (K) is determined by: */ /* first normalizing the block shift*/ /* factor (bsh) by subtracting 3, and */ /* then using that value as the */ /* exponent of the power of two times */ /* 1. This is conveniently done by */ /* merely shifting a value of one */ /* left by the normalized bsh. */ tot_size_disk = (dsm + 1) * block_size; /* The total disk size in Kbytes is */ /* simply the disk size maximum (in */ /* allocation blocks) times the */ /* block size in Kbytes. The dsm */ /* represents the number of groups */ /* blocked for by CP/M where the */ /* count begins at zero, so we add */ /* one to get useable figure here. */ dir_entries = drm + 1; /* The number of directory entries */ /* equals the DiRectory Maximum (DRM) */ /* plus one. */ dir_size_disk = (drm + 1) >> 5; /* Since each directory entry uses */ /* 32 bytes, the amount of disk used */ /* for the directory in Kbytes equals */ /* the total number of directory */ /* entries divided by 32. This is */ /* conveniently done by shifting the */ /* total number of directory entries */ /* right by 5 (divide by 2**5) */ use_size_disk = tot_size_disk - dir_size_disk; /* The useable size of the disk in */ /* Kbytes equals the total size of */ /* the disk in kbytes minus the */ /* amount of space allocated by CP/M */ /* for the directory in Kbytes. */ printf("\n\n\tThe data allocation block or group size is %5d Kbytes", block_size); printf("\n\tThe total disk size is . . . . . . . . . . %5u Kbytes", tot_size_disk); printf("\n\tThe # of directory entries blocked for is %5u Entries", dir_entries); printf("\n\twhich requires . . . . . . . . . . . . . . %5u Kbytes", dir_size_disk); printf("\n\tLeaving a useful disk capacity of. . . . . %5u Kbytes", use_size_disk); ptr = xlt; /* set ptr to disk allocation vector address */ ptr = alv; /* set ptr to disk allocation vector address */ totl = (dsm + 1) >> 3; /* this is the total number of */ /* allocation vector bytes. */ /* It is calculated by taking the */ /* total number of blocks and */ /* dividing by eight (shift right 3) */ for (i = 0; i < totl; i++) { if (!(i % 32) ) { /* print first and every 32 bytes thereafter: */ printf("\n\n\n\t%dK Disk Allocation Block Number",block_size); puts("\n\t(Hex) 0123 4567 89AB CDEF 0123 4567 89AB CDEF"); puts("\n\t----- ---- ---- ---- ---- ---- ---- ---- ----"); } if (!(i % 4) ) { /* print first and every 4 bytes thereafter: */ printf("\n\t%04x:\t",i << 3 ); /* block_num needs to be */ /* byte_number multiplied */ /* by 8 (shift left 3) */ } /* every byte is printed as follows: */ asciitobin(ptr[i],alvbinstr); /* represent alv as binary string */ printf("%s ",alvbinstr); } } }