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 ====================