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

📄 fd_0.c

📁 阿基米德操作系统的源代码
💻 C
字号:
////////////////////////////////////////////////////////////////////////
#include "general.h"
#include "inb_outb.h"
#include "sti_cli.h"
#include "copy_block.h"

#include "hd_info_struct.h"
#include "dir_entry.h"
#include "msdos_dir_entry.h"
#include "d_inode.h"
#include "m_inode.h"
#include "buffer_head.h"
#include "fat_cache.h"
#include "file.h"
#include "hd_request_struct.h"
#include "super_block.h"

#include "common_head.h"
///////////////////////////////////////////////////////////////////////////////

void setup_DMA(int temp_rwflag)
{
	unsigned long temp_uLong;
	unsigned char temp_uChar;

	outb_p(0x06,DMA_MASK_REG);
	if (temp_rwflag)
		outb_p(DMA_MODE_READ,DMA_MODE_REG);
	else
		outb_p(DMA_MODE_WRITE,DMA_MODE_REG);
	outb_p(0x00,DMA_CLEAR_FF_REG);

	temp_uLong	= (unsigned long)floppy_buffer;
	temp_uChar	= temp_uLong & 0xff;
	outb_p(temp_uChar,DMA_ADDR_2);
	temp_uChar	= (temp_uLong >>  8) & 0xff;
	outb_p(temp_uChar,DMA_ADDR_2);
	temp_uChar	= (temp_uLong >> 16) & 0xff;
	outb_p(temp_uChar,DMA_PAGE_2);
	
	outb_p(0xff,DMA_CNT_2);
	outb_p(0x03,DMA_CNT_2);

	outb_p(0x02,DMA_MASK_REG);

	return;
}

int output_byte(unsigned char Command)
{
	int	i;

	sti();
	for (i = 0; i < 50000; i++)
	{
		if ((inb(FD_STATUS) & (STATUS_READY | STATUS_DIR)) == STATUS_READY)
		{
			outb(Command,FD_DATA);
			cli();
			return 0;
		}
	}
	cli();
	return -1;
}

int get_result(void)
{
	unsigned char Status;
	int ret_val = 0;
	int i;

	sti();
	for (i = 0; i < 50000; i++)
	{
		Status = inb(FD_STATUS) & (STATUS_DIR | STATUS_READY | STATUS_BUSY);
		if (Status == STATUS_READY)
		{
			cli();
			return ret_val;
		}
		if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
		{
			reply_buffer[ret_val++] = inb(FD_DATA);
			if (ret_val >= 8)
			{
				cli();
				return -1;
			}
		}
	}

	cli();
	return -1;
}

int output0_byte(unsigned char Command)
{
	int	i;

	for (i = 0; i < 50000; i++)
	{
		if ((inb(FD_STATUS) & (STATUS_READY | STATUS_DIR)) == STATUS_READY)
		{
			outb(Command,FD_DATA);
			return 0;
		}
	}
	return -1;
}

int get0_result(void)
{
	unsigned char Status;
	int ret_val = 0;
	int i;

	for (i = 0; i < 50000; i++)
	{
		Status = inb(FD_STATUS) & (STATUS_DIR | STATUS_READY | STATUS_BUSY);
		if (Status == STATUS_READY)
			return ret_val;
		if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
		{
			reply_buffer[ret_val++] = inb(FD_DATA);
			if (ret_val >= 8)
				return -1;
		}
	}

	return -1;
}
//////////////////////////////////////////////////////////////////////////////
void fd_rwblock_0(void)
{
	floppy_temp_track	= start_request_f->cyl;
	floppy_temp_head	= start_request_f->head;
	floppy_temp_sector	= start_request_f->sector;
	floppy_temp_rwflag	= start_request_f->cmd;
	
	start_request_f->bh->b_dirt = 0;

	floppy_timerval		= FD_DRIVER_DOWN;
	floppy_finishedflag = 0;
	switch (floppy_state)
	{
	case 4:
		floppy_state	= 5;
		output_byte(FD_RECALIBRATE);
		output_byte(0x00);
		break;

	case 8:
		if ((floppy_temp_track != floppy_current_track) ||
			(floppy_temp_head != floppy_current_head))
		{
			floppy_state = 7;
			output_byte(FD_SEEK);
			output_byte(floppy_temp_head << 2);
			output_byte(floppy_temp_track);
		}
		else
		{
			setup_DMA(floppy_temp_rwflag);

			if (floppy_temp_rwflag)
			{
				floppy_state = 9;
				output_byte(FD_READ);
			}
			else
			{
				copy_block(start_request_f->bh->b_data,floppy_buffer);
				floppy_state = 11;
				output_byte(FD_WRITE);
			}
			output_byte(floppy_temp_head << 2);
			output_byte(floppy_temp_track);
			output_byte(floppy_temp_head);
			output_byte(floppy_temp_sector);
			output_byte(0x02);
			output_byte(0x12);
			output_byte(0x1b);
			output_byte(0xff);
		}
		break;
	}

	return;
}


void fd_rwblock_1(void)
{
	floppy_temp_track	= start_request_f->cyl;
	floppy_temp_head	= start_request_f->head;
	floppy_temp_sector	= start_request_f->sector;
	floppy_temp_rwflag	= start_request_f->cmd;
	
	start_request_f->bh->b_dirt = 0;

	floppy_timerval		= FD_DRIVER_DOWN;
	floppy_finishedflag = 0;
	switch (floppy_state)
	{
	case 2:
		floppy_state	= 3;
		floppy_timerval	= FD_DRIVER_UP;
		outb_p(0x1c,FD_DOR);
		break;

	case 4:
		floppy_state	= 5;
		output0_byte(FD_RECALIBRATE);
		output0_byte(0x00);
		break;

	case 8:
		if ((floppy_temp_track != floppy_current_track) ||
			(floppy_temp_head != floppy_current_head))
		{
			floppy_state = 7;
			output0_byte(FD_SEEK);
			output0_byte(floppy_temp_head << 2);
			output0_byte(floppy_temp_track);
		}
		else
		{
			setup_DMA(floppy_temp_rwflag);

			if (floppy_temp_rwflag)
			{
				floppy_state = 9;
				output0_byte(FD_READ);
			}
			else
			{
				copy_block(start_request_f->bh->b_data,floppy_buffer);
				floppy_state = 11;
				output0_byte(FD_WRITE);
			}
			output0_byte(floppy_temp_head << 2);
			output0_byte(floppy_temp_track);
			output0_byte(floppy_temp_head);
			output0_byte(floppy_temp_sector);
			output0_byte(0x02);
			output0_byte(0x12);
			output0_byte(0x1b);
			output0_byte(0xff);
		}
		break;
	}

	return;
}

//////////////////////////////////////////////////////////////////////////////
void do_fd(void)
{
	struct buffer_head * temp_bh;

	floppy_timerval = FD_DRIVER_DOWN;
	switch (floppy_state)
	{
	case 1:
		output_byte(FD_SPECIFY);
		output_byte(0xcf);
		output_byte(0x06);
		floppy_state		= 2;
		floppy_timerval		= 0;
		floppy_finishedflag = 1;
		return;

	case 5:
		output_byte(FD_SENSEI);
		reply_length = get_result();
		if (reply_length != 2)
			while (1);
		if (reply_buffer[0] & 0xc0)
		{
			floppy_errors++;
			if (floppy_errors <= 5)
			{
				output_byte(FD_RECALIBRATE);
				output_byte(0x00);
				return;
			}
			floppy_state	= floppy_state + 100;
			floppy_rwerrors	= 0;
		}
		else
		{
			floppy_state = 6;
			floppy_current_track= 0;
		}
		floppy_errors= 0;
		break;

	case 7:
		output_byte(FD_SENSEI);
		reply_length = get_result();
		if (reply_length != 2)
			while (1);
		if (reply_buffer[0] & 0xc0)
		{
			floppy_errors++;
			if (floppy_errors <= 5)
			{
				output_byte(FD_SEEK);
				output_byte(floppy_temp_head << 2);
				output_byte(floppy_temp_track);
				return;
			}
			floppy_state	= floppy_state + 100;
			floppy_rwerrors = 0;
		}
		else
		{
			floppy_state = 8;
			floppy_current_track= floppy_temp_track;
			floppy_current_head = floppy_temp_head;
		}
		floppy_errors= 0;
		break;

	case 9:
		reply_length = get_result();
		if (reply_length != 7)
			while (1);
		if ((reply_buffer[0] & 0xc0) || reply_buffer[1] || reply_buffer[2])
		{
			floppy_rwerrors++;
			if (floppy_rwerrors <= 5)
			{
				floppy_state	= 5;
				output_byte(FD_RECALIBRATE);
				output_byte(0x00);
				return;
			}
			floppy_state = floppy_state + 100;
		}
		else
		{
			floppy_state			= 10;
			floppy_current_track	= reply_buffer[3];
			floppy_current_head		= reply_buffer[4];
			floppy_current_sector	= reply_buffer[5];
		}
		
		floppy_rwerrors= 0;
		break;

	case 11:
		reply_length = get_result();
		if (reply_length != 7)
			while (1);
		if ((reply_buffer[0] & 0xc0) || reply_buffer[1] || reply_buffer[2])
		{
			if (reply_buffer[1] & 0x02)
			{
				floppy_state	= floppy_state + 100;
				floppy_rwerrors = 0;
				break;
			}

			floppy_rwerrors++;
			if (floppy_rwerrors <= 5)
			{
				floppy_state	= 5;
				output_byte(FD_RECALIBRATE);
				output_byte(0x00);
				return;
			}
			floppy_state = floppy_state + 100;
		}
		else
		{
			floppy_state = 12;
			floppy_current_track	= reply_buffer[3];
			floppy_current_head		= reply_buffer[4];
			floppy_current_sector	= reply_buffer[5];
		}
		
		floppy_rwerrors= 0;
		break;

	}

	temp_bh	= start_request_f->bh;

	switch (floppy_state)
	{
	case 6:
			floppy_state = 7;
			output_byte(FD_SEEK);
			output_byte(floppy_temp_head << 2);
			output_byte(floppy_temp_track);
			return;
	case 8:
			setup_DMA(floppy_temp_rwflag);

			if (floppy_temp_rwflag)
			{
				floppy_state = 9;
				output_byte(FD_READ);
			}
			else
			{
				copy_block(temp_bh->b_data,floppy_buffer);
				floppy_state = 11;
				output_byte(FD_WRITE);
			}
			output_byte(floppy_temp_head << 2);
			output_byte(floppy_temp_track);
			output_byte(floppy_temp_head);
			output_byte(floppy_temp_sector);
			output_byte(0x02);
			output_byte(0x12);
			output_byte(0x1b);
			output_byte(0xff);
			return;
			
	case 10:
	case 12:
			floppy_state		= 8;
			floppy_finishedflag = 1;
			break;

	case 105:
	case 107:
	case 109:
	case 111:
			floppy_state		= 4;
			floppy_finishedflag	= -1;
			break;
	}

	/////////////////////////////////////////////
	if ((temp_bh->b_count == 0) && (temp_bh->b_dirt == 0)){
		if (free_list == NULL)
			free_list = temp_bh;
		else {
			temp_bh->b_next_free = free_list;	
			temp_bh->b_prev_free = free_list->b_prev_free;
			free_list->b_prev_free->b_next_free = temp_bh;
			free_list->b_prev_free = temp_bh;
			if (floppy_finishedflag == -1)
				free_list = temp_bh;
		}
	}

	if (floppy_finishedflag == 1)
	{
		temp_bh->b_uptodate = temp_bh->b_uptodate | 0x01;
		if (floppy_temp_rwflag)
			copy_block(floppy_buffer,temp_bh->b_data);
	}
	else
	{
		temp_bh->b_uptodate = temp_bh->b_uptodate & 0xfe;
		if (temp_bh->b_uptodate & 0x80)
			floppy_workstate = -1;
	}

	temp_bh->b_lock = 0;

	start_request_f->hd	= -1;
	start_request_f     = start_request_f->next;
	if (!start_request_f)
		end_request_f = NULL;
	else
		fd_rwblock_0();
	return;

	/////////////////////////////////////////////

}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////




⌨️ 快捷键说明

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