/*--------------------------------------------------------------------------*/
/*	Program name: 5_2_2.C                                               */
/*	Compile mode: Small                                                 */
/*	Image   file: 5_2_2.EXE                                             */
/*	Note        : Check track.                                          */
/*--------------------------------------------------------------------------*/


#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];
unsigned	char	sector_data[8192];
unsigned	char	slot_data[5];
unsigned	int	slot_ptr;

/*--------------------------------- 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);
}

/*--------------------------------- CHECK ----------------------------------*/

read_sector()
{	int	es;

	disk_parm->N=6;
	es=_ES;
	_ES=FP_SEG(sector_data);
	_BX=FP_OFF(sector_data);
	_CH=Track;
	_CL=Sector;
	_DH=Head;
	_DL=Drive;
	_AX=0x0201;
	geninterrupt(0x13);
	_ES=es;
	disk_parm->N=2;
	if ((_FLAGS&1)==0)	return(0);
	else			return(1);
}

check()
{	int	i,j;
	unsigned	char	ah;

	printf("checking...");
	disk_reset();
	for(i=0;i<100;i++)
	{	for(j=0;j<8192;j++)	sector_data[j]=0;
		for(j=0;j<3;j++)
		{	if (read_sector())
			{	_AH=1;
				geninterrupt(0x13);
				ah=_AH;
				if (ah==0x10)	break;
			}
		}
		if (j==3)
		{	printf("read_sector error!\n\r");
			show_disk_error_msg(ah);
			return(1);
		}

		if (i==0)
		{	for(slot_ptr=0x1700;slot_ptr<8192;slot_ptr++)
				if (sector_data[slot_ptr]!=0x4E) break;
			if ((slot_ptr==8192)||(slot_ptr==0x1700))
			{	printf("sector_data error!\n\r");
				return(1);
			}
			slot_ptr--;
			for(j=0;j<5;j++) slot_data[j]=sector_data[slot_ptr+j];
		}
		else
		{	for(j=0;j<5;j++)
				if (sector_data[slot_ptr+j]!=slot_data[j])
					break;
			if (j<5)
			{	printf("slot not stable!\n\r");
				return(1);
			}
		}
	}
	printf("done!\n\r");
	printf("SLOT: %04X->",slot_ptr);
	for(j=0;j<5;j++)	printf("%02X ",(unsigned char)slot_data[j]);
	printf("\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();
	check();
	quit();
}
