[comp.os.minix] more fsck

Chuck_M_Grandgent@cup.portal.com (02/25/89)

I while back I threatened to fix fsck1.s and fsck.c so it
would work for partitions with sector offsets greatter than
64k.  Well, I've been really tied up with a Thermodynamics
course I'm taking and haven't been able to deliver what I
wanted.  However, in lieu of that, I'd like to post the
following program (Microsoft "C" 5.1) that illustrates the
int 13h principles involved.  It uses the functions which
return drive parameters, so it ought to be possible to make
a version that wouldn't have to have the drive parameters
hard coded...
========================================================
sun!portal!cup.portal.com!chuck_m_grandgent
AEG Modicon Industrial Automation Systems Group
North Andover, Mass.
========================================================

#define LINT_ARGS   1

#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <malloc.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <process.h>

int main(void);
void display_table(void);

/*
 * INT 13H takes:
 * CH = cylinder #
 * CL, upper 2 bits : high order bits for cylinder #,
 *     making a 10-bit cylinder #
 * CL, bottom 6 bits : sector number
 * DH = head #
 *
 *
 * > 
 * > Given the number of heads and sectors per track, this should
 * >  translate an 'abs_sec' number to 'cyl, hed, sec' coordinates:
 * > 
 * > trak = abs_sec / secs_per_trk      
 * > cyl  = trak / heads                
 * > hed  = trak % heads                
 * > sec  = abs_sec % secs_per_trk + 1  
 */

#define SECS_PER_TRK   17
#define HEADS           4

int main()
    {
    union REGS ir, otr; /* ir=registers in      otr=register out */
    struct SREGS sr;    /* get segment registers */
    unsigned char drive = 0x80;
    int result;
    long size;
    unsigned int max_cyl, sector;

    printf("\nSome disk drive parameters:\n");
    printf("\nWhen using Bios Int 13h to read and write absolute sectors,
           you must provide");
    printf("\nCylinder #, Sector #, and Head #.\n");
    printf("\nGiven absolute sector 'abs_sec', the formula is:");
    printf("\ntrak = abs_sec / secs_per_trk");
    printf("\ncyl  = trak / heads");
    printf("\nhed  = trak %% heads");
    printf("\nsec  = abs_sec %% secs_per_trk + 1\n");
    printf("\nNote that for Bios Int 13H,");
    printf("\nCH = low order 8 bits of cylinder number");
    printf("\nCL:  upper 2 bits are high order bits of 10 bit cylinder #");
    printf("\n     lower 6 bits are beginning sector number.\n");
    segread(&sr);       /* read segment registers */
    sr.es = sr.ds;      /* set ds, es */

    ir.h.ah = 1;        /* read drive status */
    ir.h.dl = drive;    /* drive # */
    result = int86x(0x13, &ir, &otr, &sr);
                        /* read drive parameters */
    if (otr.x.cflag) {
        printf("\nError getting drive status, status = 0x%X\n", result);
        goto nomore;
        }
#if 0
    else 
        printf("\nDrive status: 0x%X", (int) otr.h.al);
#endif

    ir.h.ah = 8;        /* read drive parameters */
    ir.h.dl = drive;    /* drive # */
    result = int86x(0x13, &ir, &otr, &sr);
                        /* read drive parameters */
    if (otr.x.cflag) {
        printf("\nError getting drive params, status = 0x%X\n", result);
        goto nomore;
        }
    else {
        max_cyl = (((unsigned int) (otr.h.cl & 0xC0)) << 2) + 
            (unsigned int) otr.h.ch;
        sector = (unsigned int) (otr.h.cl & 0x3F);
        printf("\nFrom function 8, Bios Int 13h,");
        printf("\nMaximum useable value for Cylinder: %04d", max_cyl);
        printf("\nMaximum useable value for Sector:   %04d", (int) sector);
        printf("\nMaximum useable value for Head:     %04d", (int) otr.h.dh);
        }

    ir.h.ah = 0x15;     /* get disk type */
    ir.h.dl = drive;    /* drive # */
    result = int86x(0x13, &ir, &otr, &sr);
                        /* read drive parameters */
    if (otr.x.cflag) {
        printf("\nError getting drive type, status = 0x%X\n", result);
        goto nomore;
        }
    else {
        if (otr.h.ah == 3)
            size = ((long) otr.x.cx << 16) + (long) otr.x.dx;
        else size = 0L;
        printf("\nFrom function 0x15, Bios Int 13h,");
        printf("\nThis drive has %ld sectors and a capacity of %ld bytes.\n",
               size, size * 512L);
        }

    printf("\nExample:\n");
    display_table();    /* display table */

nomore:
    exit(0);

    return 0;
    }

void display_table(){
    long abs_sec, trak, cyl, hed, sec;

    /*
     * > trak = abs_sec / SECS_PER_TRK      
     * > cyl  = trak / HEADS                
     * > hed  = trak % HEADS                
     * > sec  = abs_sec % SECS_PER_TRK + 1  
     */
    for (abs_sec = 0L;  abs_sec < 170L;  abs_sec += 17L) {
        trak = abs_sec / SECS_PER_TRK;
        cyl = trak / HEADS;
        hed = trak % HEADS;
        sec = abs_sec % SECS_PER_TRK + 1;
        printf("\nabs_sec: %06ld  trak: %06ld  cyl: %06ld  hed: %06ld
                 sec: %06ld",
            abs_sec, trak, cyl, hed, sec);
        }
    }
=========================== end of source ====================