; ATFMT.ASM - low level hard disk format for PC-AT. ; Create DOSFM.COM as follows: ; masm atfmt; ; link atfmt; ; exe2bin atfmt.exe atfmt.com ; del atfmt.exe cgroup group code code segment assume cs:cgroup,ds:cgroup,es:cgroup org 100h start: jmp init ; Data maxhead db ? maxcyl dw ? head db 0 cyl dw 0 warn db 'Low-level hard disk format for AT.',13,10 db 'Are you sure you want to destroy your disk (y/n)? $' crlf db 13,10,'$' diskerr db 13,10,'Disk error, format aborted',13,10,'$' init: mov dx,offset warn ; print warning message mov ah,9 int 21h mov ah,1 ; wait for key to be hit int 21h push ax ; save the key mov dx,offset crlf ; print new line mov ah,9 int 21h pop ax ; get back the key cmp al,'y' ; if Y or y, continue je continue cmp al,'Y' jne done continue: mov ah,8 ; get drive parameters mov dl,80h ; for drive c: int 13h jc error and cl,0c0h ; mask off max sector mov maxcyl,cx mov maxhead,dh dotrack: mov dh,head ; get head number mov cx,cyl ; get cylinder number mov bx,offset buff ; track interleave table address mov dl,80h ; drive C mov ah,5 ; format track int 13h ; call bios jc error ; Check for head overrun mov dh,head cmp dh,maxhead ; done all heads on one cylinder? je nextcyl ; yes - go to next cylinder inc dh ; no - go to next head mov head,dh jmp dotrack ; and format next track ; Check for cylinder overrun. This is tricky since ch contains ; the low eight bits, and bits <7:6> of cl contain the high two bits. nextcyl: mov head,dh mov head,0 mov cx,cyl cmp cx,maxcyl ; done all cylinders? je done ; yes - we're done inc ch ; low byte wrapped around? jnz nowrap ; no, skip incrementing high byte add cl,40h ; increment high two bits nowrap: mov cyl,cx ; save new cylinder number mov dl,'.' ; write a dot to screen mov ah,2 ; to let them know we're int 21h ; doing something jmp dotrack ; go do next cylinder error: mov dx,offset diskerr ; print error message mov ah,9 int 21h mov ax,4c01h ; error return int 21h done: mov ax,4c00h ; normal return int 21h ; Track interleave table. Quoting from the COMPAQ 386 Technical ; Reference, page 9-14: ; "The table contains 2 bytes per sector on the track. ; The first byte is 0 if the sector is to be formatted ; normally, or 80h if the sector is to be formatted bad. ; The second byte is the logical sector number of the ; sector..."dd" is a "don't care" byte used to make up a ; total of 512 bytes." ; The table shown here is for an interleave factor of 2. ; Tables for other interleaves are left as an exercise for the reader. buff db 0,1,0,0ah,0,2,0,0bh,0,3,0,0ch db 0,4,0,0dh,0,5,0,0eh,0,6,0,0fh db 0,7,0,10h,0,8,0,11h,0,9 dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh dw 0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh,0ddddh code ends end start