/*--------------------------------------------------------------------------*/
/*	Program name: 5_2_1.C                                               */
/*	Compile mode: Small                                                 */
/*	Image   file: 5_2_1.EXE                                             */
/*	Note        : Format key disk.                                      */
/*--------------------------------------------------------------------------*/


#include	<stdio.h>
#include	<dos.h>

struct	DISK_PARM {	char	SRT;
			char	HLT;
			char	WAIT_TIME;
			char	N;		/* may  be set to 2	*/
			char	EOT;		/* must be set to 9	*/
			char	GAP;		/* must be set to 2AH	*/
			char	DTL;		/* may  be set to FFH	*/
			char	GAP3;		/* must be set to 50H	*/
			char	FILL;		/* may  be set to F6H	*/
			char	SETTLE;
			char	START_TIME;
		  }	far	*disk_parm,disk_parm_buffer;
unsigned	char	Head,Drive,Track,Sector,N;
unsigned	char	format_parm[20][4];

/*--------------------------------- UTILITY --------------------------------*/

save_disk_parm()
{	char	far	*p,*q,i;

	p=(char far *)disk_parm;
	q=(char *)&disk_parm_buffer;
	for(i=0;i<11;i++)	*q=*p;
}

restore_disk_parm()
{	char	far	*p,*q,i;

	p=(char far *)disk_parm;
	q=(char *)&disk_parm_buffer;
	for(i=0;i<11;i++)	*p=*q;
}

show_disk_error_msg(int	ah)
{	printf("ERROR_CODE:%02X   ",ah);
	switch(ah)
	{	case	0x01:	printf("BAD_CMD\n\r");		break;
		case	0x02:	printf("BAD_ADDR_MARK\n\r");	break;
		case	0x03:	printf("WRITE_PROTECT\n\r");	break;
		case	0x04:	printf("RECORD_NOT_FND\n\r");	break;
		case	0x06:	printf("MEDIA_CHANGE\n\r");	break;
		case	0x08:	printf("BAD_DMA\n\r");		break;
		case	0x09:	printf("DMA_BOUNDARY\n\r");	break;
		case	0x10:	printf("BAD_CRC\n\r");		break;
		case	0x20:	printf("BAD_NEC\n\r");		break;
		case	0x40:	printf("BAD_SEEK\n\r");		break;
		case	0x80:	printf("TIME_OUT\n\r");		break;
	}
}

show_disk_error()
{	unsigned	char	ah;

	_AH=1;
	geninterrupt(0x13);
	ah=_AH;
	show_disk_error_msg(ah);
}

disk_reset()
{	_AX=0;
	geninterrupt(0x13);
}

/*--------------------------------- FORMAT ---------------------------------*/

format_reset()
{	int	i;

	for(i=0;i<5;i++)
	{	_DH=0;
		_DL=Drive;
		_AX=0x1702;
		geninterrupt(0x13);
		if ((_FLAGS&1)==0) return(0);
	}
	return(1);
}

format_track()
{	int	es;

	es=_ES;
	_ES=FP_SEG(format_parm);
	_BX=FP_OFF(format_parm);
	_CH=Track;
	_CL=Sector;
	_DH=Head;
	_DL=Drive;
	_AX=0x0501;
	geninterrupt(0x13);
	_ES=es;
	if ((_FLAGS&1)==0)	return(0);
	else			return(1);
}

set_format_parm()
{	int	i;

	for(i=0;i<9;i++)
	{	format_parm[i][0]=Track;
		format_parm[i][1]=Head;
		format_parm[i][2]=i+1;
		format_parm[i][3]=N;
	}
}

format()
{	set_format_parm();
	printf("formatting...");
	disk_reset();
	if (format_reset())
	{	printf("error!\n\r");
		show_disk_error();
		return(1);
	}
	if (format_track())
	{	printf("error!\n\r");
		show_disk_error();
		return(1);
	}
	printf("done!\n\r");
	return(0);
}

/*---------------------------------- MAIN ----------------------------------*/

init()
{	disk_parm=MK_FP(0,0x0522);
	save_disk_parm();
	disk_parm->N=2;
	disk_parm->EOT=9;
	disk_parm->GAP=0x2A;
	disk_parm->GAP3=0x50;
	Track=0x28;
	Head=0;
	Drive=0;
	Sector=1;
	N=6;
}

quit()
{	restore_disk_parm();
}

main()
{	init();
	format();
	quit();
}
