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

📄 fdc.c

📁 用于motorala 68K系列处理器的小实时多任务操作系统 The OMU Kernel was written to provide a cut-down Unix-like O/S for a
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * reads a complete track starting at sector 1	 * for nsects, assumes that drive selection and	 * side selection are already performed	 */	short	cerr;#ifdef EXBUF	register short count = 0, sect, err = 0;	char addr[20];	while(count < 10){		if(cerr = read_addr(addr)){			err = cerr;printf("Deverr: Read address error %x\n",cerr);			count++;		}		else{			sect = addr[2] + 1;		/* sector number */			sect = (sect > nsects)? sect - nsects:sect;			cerr = read_sect(buffer + (SIZE * (sect - 1)),sect,nsects - sect + 1,0);			if(sect != 1)				cerr |= read_sect(buffer,1,sect - 1,0);			if(cerr){				err = cerr;				count++;			}			else				break;		}	}#else	register short count = 0,err;	while(count < 10){		if(cerr = read_sect(buffer,1,nsects,0)){			err = cerr;			count++;		}		else			break;	}#endif EXBUF	if(err)		fdcerror = err;	return count;}tr_write(buffer,nsects)char *buffer;short nsects;{	/*	 * writes a complete track starting at sector 1	 * for nsects, assumes that drive selection and	 * side selection are already performed	 */	short	cerr;#ifdef EXBUF	register short count = 0, sect, err = 0;	char addr[20];	while(count < 10){		if(cerr = read_addr(addr)){			err = cerr;			count++;		}		else{			sect = addr[2] + 1;		/* sector number */			sect = (sect > nsects)? sect - nsects:sect;			cerr = write_sect(buffer + (SIZE * (sect - 1)),sect,nsects - sect + 1,0);			if(sect != 1)				cerr |= write_sect(buffer,1,sect - 1,0);			if(cerr){				err = cerr;				count++;			}			else				break;		}	}#else	register count = 0,err;	while(count < 10){		if(cerr = write_sect(buffer,1,nsects,0)){			err = cerr;			count++;		}		else			break;	}#endif EXBUF	if(err)		fdcerror = err;	return count;}oldest(aged)short aged;{	/*	 *	makes the buffer age aged to become	 *	the oldest and adjust all the buffers	 *	that were older than it to become 1	 *	younger returns the array index of the oldest	 */	register short p = 0, newone;	while(p < NO_BUFS){		if(fdb[p].age >= aged){			if(fdb[p].age == aged){				newone = p;				fdb[p].age = NO_BUFS;			}			fdb[p].age--;		}		p++;	}	return newone;}youngest(aged)short aged;{	/*	 *	makes the buffer age aged to become	 *	the youngest and adjust all the buffers	 *	that were younger than it to become 1	 *	older returns the array index of the youngest	 */	register short p = 0, newone;	while(p < NO_BUFS){		if(fdb[p].age <= aged){			if(fdb[p].age == aged){				newone = p;				fdb[p].age = -1;			}			fdb[p].age++;		}		p++;	}	return newone;}/* * Deverr - general error message */deverr(str, count, buf)char *str;struct buf *buf;{	printf("\n\rDeverr: ");	if (count >= 10)		printf("Fatal\007 ");	else if (count > 1)		printf("%d of ", count);	printf("%s at blk %d on %d, FDC error: %x\n", str, buf->b_bno, buf->b_dev,fdcerror);	return;}doseek(trk, twostep)int	trk;char	twostep;{	register short count = 0,err;	if(twostep){		while((err = raw_seek(trk)) && count < 10){			restor(0);			fdcerror = err;			count++;		}	}	else {		while((err = ver_seek(trk)) && count < 10){			restor(0);			fdcerror = err;			count++;		}	}	return count;}/* *	ioctl for floppies, allows reading and writing of *	tracks (for formatting or weird disk reads) and *	reading of address fields (God knows what to use that for!) */fdioctl(dev,req,args)int dev,req;struct fdcntrl *args;{	int (*func)();	register char *emsg;	register short reps;	register struct drive_info *fds;	int	track;	int	write_track(), read_track(), read_addr();	dtype = fdstatus[dev & 0x3].d_type;	tmpb.b_bno = -1;	/* allows us to use deverr for error reports */	tmpb.b_dev = dev;	/*	"	"	"	" */	/* select dev */	if (select(dev & 0x3) == ERROR){		deverr("dev not ready", 1, &tmpb);		return ERROR;	}	switch(req){	default:		/* simply return when an uknown ioctl appears */		printf("\n\rUNKNOW Ioctl for floppy, %x\n\r",req);		return NOERROR;#ifdef FULLBUFFERING 	case TIOCFLUSH:		/*			flush all buffers that are dirty on this 			device and make them available		 */		return flushall(dev);		/* NOTREACHED */		break;#else	case TIOCFLUSH:		return 0;#endif FULLBUFFERING 	case WRITETRACK:		func = write_track;		emsg = "write track:";		break;	case READTRACK:		func = read_track;		emsg = "read track:";		break;	case READADDR:		func = read_addr;		emsg = "read addr:";		break;	case MULTIREAD:		func = tr_read;		emsg = "mutli read";		break;	case MULTIWRITE:		func = tr_write;		emsg = "multi write";		break;	case WRITESECT:		func = write_sect;		emsg = "Write sect";		break;	case READSECT:		func = read_sect;		emsg = "Read sect";		break;	}	switch(req){	case READADDR: case READTRACK: case WRITETRACK:		/*			raw operator, possibly on a raw disk			that has lost formatting info so			seek with no verify etc		 */		/* find current position */		fds = &fdstatus[dev & 0x3];		/* Gets floppy drive track number */		if(fds->d_type & DTYPE40) track = args->trackno * 2;		else track = args->trackno;		if ((set_track(fds->d_curtrk)) != track){			/*				raw_seek simply seeks from where ever				it thinks the head is to the track specified				no error checking, no verify so the head				postion had better be right!			 */				raw_seek(track);		}		fds->d_curtrk = track;		set_track(args->trackno);	/* Sets real track 40/80 */					side(args->sideno);	/* side select */		reps = raw_tr_op(args->buffer,func);		break;	case MULTIREAD: case MULTIWRITE:		/*			reads or writes the track as multiple			sectors, disk MUST be formatted for 			this to work		 */		/*			setup the disk, because the diskset routine			uses the track value to decide on which side			as well, this kludge allows diskset to not			only seek to the correct track but also			do side selection too		 */		fds = &fdstatus[dev & 0x3];		/* Gets floppy drive track number */		if(fds->d_type & DTYPESS) track = args->trackno;		else track = (args->trackno * 2) + args->sideno;		fdcerror = reps = diskset(&tmpb, track);		if(reps == ERROR)			return ERROR;		reps = (*func)(args->buffer,P_TRK);		break;	case READSECT: case WRITESECT:		/*			reads or writes the track as multiple			sectors, disk MUST be formatted for 			this to work		 */		/*			setup the disk, because the diskset routine			uses the track value to decide on which side			as well, this kludge allows diskset to not			only seek to the correct track but also			do side selection too		 */		fds = &fdstatus[dev & 0x3];		/* Gets floppy drive track number */		if(fds->d_type & DTYPESS) track = args->trackno;		else track = (args->trackno * 2) + args->sideno;		fdcerror = reps = diskset(&tmpb, track);		if(reps == ERROR)			return ERROR;		fdcerror = reps = (*func)(args->buffer,args->sect, 1, 0);		break;	}	if(reps){		deverr(emsg,reps,&tmpb);		if(reps >= 10)			return ERROR;		else			return NOERROR;	}	return 0;}raw_tr_op(b,fn)char *b;int (*fn)();{	/*		writes or reads a track/address field  with the data in b	 */	register short count = 0,err;	while(count < 10){		if(err = (*fn)(b)){			fdcerror = err;			count++;		}		else			break;	}	return count;}#ifdef FULLBUFFERING flush1(p)short p;{	/*		given a track buffer number p		this flushes it to the correct disk if it		can and does nowt else	 */	short reps;	/*		to be able to use diskset we set up a buffer		with info from the track buffer we are flushing	 */	tmpb.b_dev = fdb[p].d_minor;	tmpb.b_bno = fdb[p].bstart;	if(diskset(&tmpb,NOTATRACK) == ERROR)		return ERROR;	else{		mode = fdstatus[drive & 0x3].d_type;		reps = tr_write(fdb[p].fdata,P_TRK);		if(reps){			deverr("track flush",reps,&tmpb);			if(reps >= 10){				/*					at the mo do nothing					with fatal track errors				 */				return ERROR;			}		}		return NOERROR;	}			}flushall(dev)int dev;{	/*		walk thru all the buffers flushing all		those that are relevant to this device		and are recently written	 */	register short p = 0;	while(p < NO_BUFS){		/* release all the allocated buffers */		if((fdb[p].d_minor == dev) && (fdb[p].type & WRITTEN))				/*					attempt to flush a dirty buffer				 */				if(flush1(p) == ERROR)					/*						Oh well it was a good try						for the mo leave its state						alone					 */					return ERROR;				else{					/*						succeeded in the flush						now make it the oldest						but leave it with a READABLE						flag					 */					fdb[p].type &= ~WRITTEN;					oldest(fdb[p].age);				}		p++;	}	return NOERROR;}#endif FULLBUFFERING 

⌨️ 快捷键说明

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