home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
16
/
FREEDOS.ZIP
/
FD_A4PRE.ZIP
/
SOURCE
/
MICROC.ZIP
/
FDFORMAT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-27
|
5KB
|
154 lines
#include <stdio.h>
#define MAXSECTOR 18 /* Maximum sectors/trk supported */
/* Global data easily accessable to asm functions */
unsigned char drive, type, heads, sectors, tracks, status;
main(int argc, char *argv[])
{
unsigned i, track;
unsigned char *ptr, sbuf[MAXSECTOR*4];
static char *drive_type_text[] = {
"5.25 LD", "5.25 HD", "3.5 LD", "3.5 HD" };
if(argc < 2)
abort("Use: fdformat <drive> [t=n h=n s=n]\n");
if(((drive = toupper(*argv[1]) - 'A') > 1) || (argv[1][1] != ':'))
abort("Please specify drive A: or B:");
/* Get default drive parameters from BIOS */
asm {
MOV DL,DGRP:_drive ; Get drive number
MOV AX,0800h ; Get drive ID function + default=0
INT 13h ; Call BIOS
JC gdterr ; Error, assume default
MOV DGRP:_type,BL ; Set drive type
INC DH ; Adjust # heads
MOV DGRP:_heads,DH ; Set # heads
AND CL,1Fh ; Remove track bits
MOV DGRP:_sectors,CL; Set # sectors
INC CH ; Adjust # tracks
MOV DGRP:_tracks,CH ; Set # tracks
gdterr:
}
if((type < 1) || (type > 4))
abort("Unable to obtain drive type from BIOS");
for(i=2; i < argc; ++i) {
ptr = argv[i];
switch((toupper(*ptr++) << 8) | *ptr++) {
case 'H=' : heads = atoi(ptr); break;
case 'S=' : sectors = atoi(ptr); break;
case 'T=' : tracks = atoi(ptr); break;
default:
printf("Unknown option: %s\n", argv[i]);
return; } }
printf("fdformat: %s disk in drive %c (Heads=%u, Sectors=%u, Tracks=%u)\n",
drive_type_text[type-1], drive + 'A', heads, sectors, tracks);
if(initialize_drive() || (--heads > 1))
abort("Unsupported drive parameters!");
for(track = 0; track < tracks; ++track) {
printf("\r Track %d of %d...", track, tracks);
ptr = sbuf;
for(i=1; i <= sectors; ++i) {
*ptr++ = track;
*ptr++ = 0;
*ptr++ = i;
*ptr++ = 2; }
if(format_track(sbuf, track, 0)) {
i = -1;
goto disk_error; }
if(heads) {
ptr = sbuf + 1;
for(i=1; i <= sectors; ++i) {
*ptr = 1;
ptr += 4; }
if(format_track(sbuf, track, 1)) {
i = -1;
goto disk_error; } } }
return;
disk_error:
printf("Un-recoverable disk error! status=%02x\n", status);
}
/*
* Initialize the drive
*/
initialize_drive() asm
{
; Reset the drive
MOV DL,DGRP:_drive ; Get drive id
XOR AH,AH ; Function 0 - reset disk
INT 13h ; Try it out
; Select the drive type
MOV CL,DGRP:_sectors; Get sectors
MOV CH,DGRP:_tracks ; Get tracks
DEC CH ; Adjust
MOV DL,DGRP:_drive ; Get drive number
MOV AH,18h ; Set media type for format
INT 13h ; Call BIOS
MOV AL,AH ; Get result
JC error ; Error has occured
; Copy over parameter table
MOV SI,DI ; Si = source offset
PUSH DS ; Save data seg
PUSH ES ; Save extra
XOR BX,BX ; Get zero
MOV DS,BX ; ES = 0
MOV BX,0078h ; Point to table
MOV DI,[BX] ; Get dest offset
INC BX ; Advance
INC BX ; One word
MOV ES,[BX] ; Get dest segment
POP DS ; Get source segment
MOV CX,11 ; size of table
rep MOVSB ; Perform the move
POP DS ; Restore data seg
XOR AX,AX ; Zero result
error:
}
/*
* Format a track on the floppy diskette
*/
format_track(buffer, track, head) asm
{
MOV DI,3 ; Retry count
fagain: PUSH DS ; Save data seg
POP ES ; Set extra seg
MOV BX,8[BP] ; Get buffer address
MOV CH,6[BP] ; Get track
MOV DH,4[BP] ; Get head
MOV DL,DGRP:_drive ; Get drive
MOV AX,0501h ; Command & interleave
INT 13h ; Call bios
JNC fok ; It worked
MOV DGRP:_status,AH ; Save command status
XOR AH,AH ; Reset command
INT 13h ; Ask BIOS
DEC DI ; Reduce count
JNZ fagain ; Do it again sam
MOV AX,-1 ; Indicate failure
JMP SHORT fexit ; And leave
fok: XOR AX,AX ; Indicate success
fexit:
}