⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdcmnds.c

📁 用于motorala 68K系列处理器的小实时多任务操作系统 The OMU Kernel was written to provide a cut-down Unix-like O/S for a
💻 C
字号:
/****************************************************************************** *	Fdcmnds.c	Low level floppy drive commands for Eltec kit ****************************************************************************** */#include "floppy.h"#include "buffer.h"extern	int	dtype;char status;/* *	Fdcinit()	Initialise floppy disk hardware */fdcinit(){}/* *	Select() Selects drive if not alreay selected (via status varible) */select(drive)char drive;{	register char mask;	status |= FIVE_SEL;	status &= ~(SDEN);	/* Special for high density checking *//*	if(drive == 3){		status &= ~FIVE_SEL;		FDC_PORT->bits = status;		drive = 1;	} */	mask = 1<<drive;	if((status & 0x0F)!= mask){		status &= 0xf0;		/* deselect all */		status |= mask;		delay(120);	/* wait 1200 micro s before deselecting */		FDC_PORT->bits = status;		delay(1200);		/* delay 120ms after sel */	}	return 0;}/* *	Side()	Changes side of disk if incorrect ( via status varible ) */side(no)char	no;{	register char set;	set=0;	if (no == SIDE_ZERO){		if(status & SIDE_ONE){			status &= ~SIDE_ONE;			set++;		}	}	else{		if(!(status & SIDE_ONE)){			status |= SIDE_ONE;			set++;		}	}	if(set){		delay(100);	/* 1000 micro s delay before selection */		FDC_PORT->bits = status;		delay(10);		/* 100 micro s delay after selection */	}	return 0;}/* *	TYPE I COMMANDS FOR THE 2791 *	ALL RETURN THE CONTENTS OF *	THE STATUS REGISTER *//* *	Restor()	Restores drive to track 0 */restor(flags)short	flags;{	motoron();	/* Switches FDC controller to high speed for seek */	FDC_PORT->bits = status & ~FIVE_SEL;	while(FDC_PORT->csr & BUSY);	/* wait for any other cmnd */	FDC_PORT->csr = (RESTORE | flags|LOAD_HEAD); /* send restor */	wait_fin();	FDC_PORT->bits = status;	/* Resets to normal speed */	return;}/* *	MOTOR	Motor on/off routines */motoron(){	if(!(status&MOTOR_ON)){		status|=MOTOR_ON;		FDC_PORT->bits=status;		delay(120000);	}	/* Sets machine tick count to indicate motor has been switched on */	mach_fdon();}motoroff(){	status&= ~MOTOR_ON;	FDC_PORT->bits=status;}/* *	Get_track()	Gets present track no */get_track(){	return FDC_PORT->track;}/* *	Set_track()	Sets track no */set_track(trackno)register short trackno;{	FDC_PORT->track=trackno;	return trackno;}/* *	Set_status()	Sets status */set_status(stat)register char stat;{	FDC_PORT->bits=stat;}get_status(){	return(status);}/* *	Seek()	Seeks track specified if flag = VERIFY verifies position *//* *	seek with verify and error return */ver_seek(track)short track;{	return(seek(track,VERIFY) & SK_ERR);}/* *	seek with no verify, no error return */raw_seek(track)short track;{	return(seek(track,NO_FLAGS) & SK_ERR);}seek(track,flags)short	track, flags;{	short intlevel;#ifdef TFLOPPYprintf("Seeking %d\n",track);#endif	motoron();	/* Switches FDC controller to high speed for seek */	FDC_PORT->bits = status & ~FIVE_SEL;	while(FDC_PORT->csr & BUSY);	/* wait for any other cmnd */	intlevel = spl6();	FDC_PORT->data = track;	/* set track reg */	FDC_PORT->csr = (SEEK |LOAD_HEAD);	/* send seek */	splx(intlevel);	wait_fin();	while((FDC_PORT->csr &BUSY)||(FDC_PORT->csr&NOT_RDY));	FDC_PORT->bits = status;		/* Returns to normal mode */	intlevel = spl6();	FDC_PORT->data = track;	/* set track reg */	FDC_PORT->csr = (SEEK |flags|LOAD_HEAD);	/* send seek */	splx(intlevel);	return wait_fin();}wait_fin(){	int count=0;	while (!(FDC_PORT->bits & INT_REQ));	/* wait for finish */	return	FDC_PORT->csr;		/* return status */}/* *	TYPE II COMMANDS FOR THE 2791 *	ALL RETURN THE CONTENTS OF *	THE STATUS REGISTER *//* *	Read_sect()	read of sectors to buffer */read_sect(buf, start_sect, sect_count, flags)char	*buf;short	start_sect, sect_count, flags;{	register short	byte_count, error;	short intlevel;#ifdef TFLOPPYprintf("Read sector %d\n",start_sect);printf("Read flags %d\n",flags);#endif	motoron();	while(FDC_PORT->csr & (BUSY |NOT_RDY));	/* wait till rdy */	intlevel = spl6();	FDC_PORT->sector = start_sect;	/* set up first sector address */	if ( sect_count != 1)		flags = flags | MULTI_RECORD;	byte_count = sect_count * SECTLENGTH;	FDC_PORT->csr = (READSECTOR | flags);	/* do until all done or interrupts out of its own accord */	error = r_sectc(buf,byte_count);	splx(intlevel);	force_intr(TERMINATE);	if(dtype & DTYPEINTEL) swapbyte(buf, byte_count);#ifdef TFLOPPYprintf("Error returned %x\n",error);printf("Track %d\n",FDC_PORT->track);#endif	return (error & READ_ERR);}/* *	Write_sect()	Write of sectors from buffer */write_sect(buf, start_sect, sect_count, flags)char	*buf;short	start_sect, sect_count, flags;{	register short	byte_count, error;	short intlevel;	if(dtype & DTYPEINTEL) swapbyte(buf, byte_count);	motoron();	while(FDC_PORT->csr & (BUSY |NOT_RDY));	/* wait till rdy */	intlevel = spl6();	FDC_PORT->sector = start_sect;	/* set up first sector address */	if ( sect_count != 1)		flags = flags | MULTI_RECORD;	byte_count = sect_count * SECTLENGTH;	FDC_PORT->csr = (WRITESECTOR | flags);	/* do until all done or interrupts out of its own accord */	error = w_sectc(buf,byte_count);	splx(intlevel);	force_intr(TERMINATE);	return (error & WRITE_ERR);}/* *	TYPE III COMMANDS FOR THE 2791 *	ALL RETURN THE CONTENTS OF *	THE STATUS REGISTER *//* *	Read_addr()	Reads track information from disk into buffer */read_addr(buf)char *buf;{	short intlevel, error;	motoron();	while(FDC_PORT->csr & (BUSY |NOT_RDY));	/* wait till rdy */	intlevel = spl6();	FDC_PORT->csr = (READADDRESS | DELAY_15) ;	error = raw_read(buf);	splx(intlevel);	return (error & RAD_ERR);}/* *	Read_track()	Reads whole track into buffer */read_track(buf)char	*buf;{	short intlevel, error;	short	tmp;	motoron();	while(FDC_PORT->csr & (BUSY |NOT_RDY));	/* wait till rdy */	intlevel = spl6();	FDC_PORT->csr = (READTRACK | DELAY_15) ;	error = raw_read(buf);	splx(intlevel);	return (error & RRD_ERR);}/* *	Write_track()	Writes whole track to buffer */write_track(buf)char	*buf;{	short intlevel, error;	motoron();	while(FDC_PORT->csr & (BUSY |NOT_RDY));	/* wait till rdy */	intlevel = spl6();	FDC_PORT->csr = (WRITETRACK | DELAY_15) ;	error = raw_write(buf);	splx(intlevel);	return (error & RWR_ERR);}/* *	TYPE IV COMMAND FOR THE 2791 *	RETURNS THE CONTENTS OF *	THE STATUS REGISTER */force_intr(flags)int	flags;{	char	loop;	loop = DELAY_TIME;	FDC_PORT->csr = (FORCEINTERRUPT | flags) ;	/* issue cmnd */	while(loop-- != 0);			/* wait at least 16 us */	if (flags & IMMEDIATE){		FDC_PORT->csr = (FORCEINTERRUPT | TERMINATE) ;		while(loop++ != DELAY_TIME);	/* wait at least 16 us */	}	return (int)FDC_PORT->csr;}delay(time){	/* delay for time x 10 micro secs (approx) */	for(;time > 0;time--);}/* *	Swapbyte()	Swaps bytes around in an array */swapbyte(buf, num)register char	*buf;register int	num;{	register char	c;	while(num -= 2){		c = *buf;		*buf = *(buf + 1);		*(buf + 1) = c;		buf += 2;	}}/* *	THESE ROUTINES ARE THE SOURCES OF THE HAND-OPTIMIZED *	.68K ROUTINES IN read_write.68k THEY ARE HERE FOR *	REFERENCE ONLY * *r_sect(buf,count) *char	*buf; *short	count;{ * *	char	error; * *	error = 0; *	do{ *		if( !(FDC_PORT->bits & NOT_DATA_REQ) ){ *			*buf++ = FDC_PORT->data; *			count--; *		} *		if( !(FDC_PORT->bits & NOT_INT_REQ) ){ *			error = FDC_PORT->csr; *			break; *		} *	}while( (count >= 1) && !error); *	return error; *} * *w_sect(buf,count) *char	*buf; *short	count;{ * *	char	error; * *	error = 0; *	do{ *		if( !(FDC_PORT->bits & NOT_DATA_REQ) ){ *			FDC_PORT->data = *buf++; *			count--; *		} *		if( !(FDC_PORT->bits & NOT_INT_REQ) ){ *			error = FDC_PORT->csr; *			break; *		} *	}while( (count >= 1) && !error); *	return error; *} * * *raw_read(buf) *char	*buf;{ *	while(FDC_PORT->bits & NOT_INT_REQ) *		if ( !(FDC_PORT->bits & NOT_DATA_REQ) ) *			*buf++ = FDC_PORT->data;	 *} * *raw_write(buf) *char	*buf;{ *	while(FDC_PORT->bits & NOT_INT_REQ) *		if( !(FDC_PORT->bits & NOT_DATA_REQ) ) *			FDC_PORT->data = *buf++;	 *} * * * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -