Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!apple!agate!ucbvax!bloom-beacon!eru!hagbard!sunic!news.funet.fi!ousrvr.oulu.fi!stekt!jml From: jml@stekt.oulu.fi (Lepp{j{rvi Jouni) Newsgroups: comp.os.msdos.programmer Subject: Formatting diskettes (summary) Message-ID: <1991Apr25.144559.15976@ousrvr.oulu.fi> Date: 25 Apr 91 14:45:59 GMT Sender: news@ousrvr.oulu.fi Organization: University of Oulu, Finland Lines: 284 Formatting diskettes on IBM PC/XT/AT and compatibles using BIOS calls --------------------------------------------------------------------- Disclaimer : My intention is, of course, provide correct data. I don't, however, take any responsibility for any damage or loss caused by incorrectness on incompleteness of this document. This document has been written with floppy disk formatting in mind. Parameters and procedures for hard disk formatting are likely to differ. Trademarks and the like may appear in this document, which are, by definition, the property of their holders. Any information in this document derived from degugging DOS applies to MS-DOS v. 3.3. BIOS functions used with disk formatting ---------------------------------------- The bios function used is int 13h (disk services). The subfunctions used are : ah = 00h, reset disk system --------------------------- This should be called before anything else to force the disk system into a known state. (Usually this does not make a difference, however.) on entry : ah = 00h upon return : ah = status, 0 = ok, any other means error carry flag set on error (ah != 0) The status codes (also HD codes are included for completeness) : 00h : ok 01h : bad command (or missing support for a subfunction) 02h : address mark not found 03h : attempted write protect violation (floppy) 04h : sector not found 05h : reset failed (HD) 06h : disk changed (floppy) 07h : bad parameter table (HD) 08h : DMA overrun (floppy) 09h : attempted DMA over 64k boundary 0ah : bad sector flag (HD) 0bh : bad cylinder detected (HD) * 0ch : media type not found (floppy) * 0dh : invalid number of sectors in format (HD) * 0eh : control data address mark detected (HD) * 0fh : DMA arbitration level out of allowable range (HD) * 10h : CRC or ECC error on read 11h : ECC corrected data error (HD) 20h : controller failed 40h : seek failed 80h : timeout, drive not ready aah : drive not ready (HD) bbh : undefined error (HD) cch : write fault (HD) e0h : status error (HD) ffh : sense operation failed (HD) * (floppy) applies only to floppy drives (HD) applies only to hard disks * applies to PS/2 and extented bios only Calling this function prior to actually starting to format also takes care of the likely 'disk changed' (status = 06h) situation, in which the disk system has sensed a disk change since the last disk operation. ah = 04h, verify sectors ------------------------ This function is used to verify (the formatted) sectors. on entry : ah = 04h al = # of sectors ch = track # (0 - (n-1)) cl = sector # (1 - n) dh = head # (0,1) dl = drive # (0 = A, 1 = B) [es:bx = buffer, see below] upon return : ah = status, 0 = ok, any other means error carry flag set on error (ah != 0) See ah = 0 (reset disk system) above for status codes. While single sectors can be verified with this function, it is recommented that entrire tracks are verified at once to achieve better performance. The Programmers PC sourcebook (and Commodore PC's technical handbook) mention that es:bx should contain a buffer address. The sourcebook mentions that this is not required for AT bios after 11/15/85, but it does not mention PC's or XT's at all. Advanced MS-DOS programming, however, does not mention this setting, instead it explictly states that 'no data is transferred to of from memory by this operation'. Debugging DOS's disk driver's behavior reveals that it assumes that no buffer is needed since it has bx:es = 0000:0000 upon entry to int 13h with this subfunction. So, I figure that the value in es:bx can be quite safely ignored. It can't hurt, however, to set es:bx to some buffer in which bios could safely write the verified sectors. (I assume that this is about the only use for the buffer.) ah = 05h, format track ---------------------- This function is used to format a complete track (or 'cylinder'). I've the impression that signle sectors cannot be formatted, since this operation actually sets the sector marks on the disk that are later used to locate the sectors. on entry : ah = 05h al = # of sectors es:bx pointer sector header table ch = track # (0 .. (n-1)) cl = sector # (appears to have no effect, I use 0 always) dh = head # (0,1) dl = drive # (0 = A, 1 = B) upon return : ah = status, 0 = ok, any other means error carry flag set on error (ah != 0) See ah = 0 (reset disk system) above for status codes. The sector header table is an array of four byte entries, one entry for each sector in a track. Single entry layout is as follows : offset contents 0 track number (0 - (n-1)) 1 head number (0 - (n-1)) 2 sector number (1 - n) (note the range, 1 = first sector !) 3 bytes / sector, 0 = 128, 1 = 256, 2 = 512, 3 = 1024 From studying the bios listing I have the impression that the sector header table is passed to the floppy controller using DMA controller. The DMA controller has an address space of only 64 k which is extented to 1 M with a page register which can be set to one of the 16 64k chunks of the entire 1 M space. Therefore the entrire sector header table should be fully inside of one these pages or formatting fails. The same applies to any disk buffer in this context : they all should be within one DMA page. ah = 18h, set media type for format ----------------------------------- This function is used to get (it doesn't actually set anything) the pointer to the media descriptor table for a specific kind of disk. Int 1eh vector is then replaced with this pointer to actually set the media type. This function is available in IBM bioses after 11/15/85 (AT) and 1/10/86 (XT). on entry: ah = 18h ch = highest track #, that is, # of tracks - 1 cl = # of sectors dl = drive #, (0 = A, 1 = B) upon return: ah = status, 0 = ok, any other means error carry flag set on error (ah != 0) See ah = 0 (reset disk system) above for a list of status codes. The error (if any) is most likely due to lack of support for the media type being 'set'. Older bioses may also lack the entire function. On PC/XT bioses this should be no problem, since their drives can handle only one major flavor of disks anyway and the bios defaults to this. Parameters for the usual disk types : capasity tracks sectors 360k 40 9 1.2M 80 15 720k 80 9 1.44M 80 18 (The numbers above are decimal.) Although setting the vector 1eh to the value returned by this subfunction might seem like an unclean hack, this is the way it works. My debugging of DOS's disk driver in io.sys revealed that it does just this. The formatting procedure ------------------------ 1. Reset the controller with subfunction 00h. 2. Get the parameter table pointer for the disk type to be formatted with subfunc 18h. Set the interrupt vector 1eh to this value. (I think it is a good idea to store the old value of this vector and restore it when the formatting is done. I'm not sure, however, if this is actually required.) 3. Format the disk, track by track, with subfunction 05h. (Though not required it would be a good idea to verify the formatted tracks with subfunction 04h as they are formatted to detect defects on the disk.) Note that the disk formatted is not the same as produced by DOS's format-command. The formatting actually only sets the disk up, so that its sectors can be written and read. At this point, you could e.g. copy a similar disk's contents on it track by track, and so create a copy comparable to one made by DOS's diskcopy. To make the disk appear as one created by DOS's format-command you would need to write a bootblock, FAT(s) and a root directory on it. (The bootblock is vital even if the disk is not meant to be bootable, since DOS stores the disk parameters in it.) A complete discussion about all this is beyond the scope of this document. The information needed can be found e.g. from the book 'Advanced MS-DOS Programming'. Another way to format a disk would be to use DOS int 21h function 44h (ioctl). DOS's format appears to do this. However, I couln't find complete documentation for the subfunctions (0dh,0fh) used for this. (PC sourcebook was about the only of my references to even mention these functions.) Despites these calls are valid only from DOS 3.2 (PC sourcebook). DOS's disk driver appears to use the bios calls for regular diskettes anyway, so there is not much use to do this via the DOS ioctl's, other than that one might be able to write a formatter that might handle also excotic disks. Bibliography ------------ Thom Hogan, The programmers PC sourcebook Microsoft press, ISBN 1-55615-118-7 Ray Duncan, Advanced MS-DOS programming Microsoft press, ISBN 0-914845-77-2 Ralf Brown's interrupt list IBM PC/XT/AT Technical reference ----------------------------------------------------------------------------- This document was written by Jouni Leppjrvi, jml@stekt.oulu.fi. It may be freely distributed on a non-commercial basis. Comments corrections, clarifications and additions are wellcome. ----------------------------------------------------------------------------- -- - Jouni Lepp{j{rvi / jml@stekt.oulu.fi - - '.. but only maybe, life is a joy .. ' -