The way the sectors are to be read is determined based upon media type and operating system.
Here is a brief summary:
Get drive and sector size | GET DEVICE PARAMETERS (DPB) | |
GET FREE SPACE | if DPB does not exist | |
Determine sector I/O function | INT 25/26 | floppy/hard drives for DOS/WinNT
floppy drives for Win31 loadable devices |
BIOS (INT 13) | floppy/hard drives for DOS/Win31
floppy drives for WinNT |
|
IOCTL | floppy drives | |
Read BOOT sector | if DPB does not exist
if removable media |
|
Calculate DOS data |
I HAVE TRIED VERY HARD TO KEEP THESE DOCUMENTS
CORRECT BUT
I CANNOT GIVE ANY GARAUNTEES THAT THERE ARE NOT ANY ERRORS |
Today's PCs have basically only two standard drive types: floppy and hard. AKA removable and fixed. But standard drive types are what the BIOS says are standard. As the BIOS evolved it supported more and more drive types, yet BIOSes will always lag behind the evolution of storage devices.
To support non-standard drives, and drives larger than DOS was developed for, DOS allows for people to write loadable device drivers to provide it with a way of thinking that non-standard drives are standard ones.
What all this means is that if the drive type is not directly supported by the BIOS, the BIOS can not be used to access the drive, you have to use DOS.
Removable media will almost certainly always be floppies. However, other
types of removable media are increasing in popularity.
As with removable media, fixed media must still be looked at carefully before accessing. The rule of thumb is always: Do not assume everything.
Remote drives are generally not accessible at the sector level. (Although
CD-ROMs can be, I will not address them until much later in these tutorials).
The structure of a BIOS call is loading the CPU registers with appropriate values and then issuing the interrupt. The registers for BIOS is:
To Call:
AH 08hReturns:
DL {drive} where {drive} is a zero based drive number
with bit 7 clear for floppy drives and bit 7 set for hard drives.
AH error code if carry setAnd in C:
CH tracks (low 8 bits of)
CL sectors (in bits 0-5) and high bits of tracks (in bits 6-7)
DH heads
int int13getparam(int disk, int *t, int *s, int *h)
{
int tmp;
union REGS regs;
regs.x.ax = 0x0800;
/* get drive parameters */
regs.h.dl = (unsigned char)adjdrv(disk);
int86(0x13,®s,®s);
if (regs.x.cflag)
return (int)regs.h.ah;
if (regs.h.bl == 0)
/* no drive connected/not found */
return -1;
*h = regs.h.dh;
*t = regs.h.ch;
/* low bits only */
tmp = *s = regs.h.cl;
/* has high bits of track also */
*s &= 0x3f;
/* mask off track high bits */
*t += (tmp >> 6) << 8;
/* shift and add track high bits */
return 0;
}
/* floppys: 0 - 7Fh, hards: 80h - FFh */
int adjdrv(int drv)
{
if (drv > 2)
return drv + (0x80 - 3);
return drv - 1;
}
What's funny here is how the BIOS provides you with the number of tracks.
Due to some strange technique, probably lost to history, probably by some
"clever IBM engineer", the number of tracks is split up between two registers
and shared with the register for the number sectors per track: The CH register
contains the low 8 bits of the number of tracks, and the CL register holds
sectors per track in it's lower 6 bits, and it's upper 2 bits are the high
2 bits for the number of tracks. Whew... Here's it visually:
CL | CH |
7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |
t t h h h h h h | t t t t t t t t |
Note also here that I used ints for the
drive parameter arguments rather than the typedef UINT16
I have used before. The reason is that C performs automatic type conversions
rather well in this situation.
It is the register size limits that causes the "528MB Barrrier" for PC hard disks. Get Hale Landis's " How it Works" documents for more information about this and how it was solved. |
For use with INT13.C is a program that creates an "industry standard" floppy image, or writes an image to a floppy. Most similar programs I have encountered (such as RAWRITE and FDIMAGE) only write an image file to a floppy. This program will do either. F2DD2F.C
You can get them both archived. Note
that this program ONLY supports the default disk type (whatever your BIOS
is setup for). For those interested, here is
RAWRITE.C,
the most widely used file-to-disk program, and then there's another called
FDIMAGE.C.
My simple BIOS disk editor, DISKBUG, also
uses INT13.C.
If you are interested in FAT, Directories and sector translation code
you can get the DISKED source code
-- it's all there albiet probably not easily discernible. For parsing just
the FAT there is code for it in the libraries
D_DISK
and
DISKLIB
.