📄 ide_access.c
字号:
#include "ide_include.h"
IDE_Internal_t IDE_Internal;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
UI8 IDE_SectorByte(UI16 sublocation)
{
UI8 data=0;
#ifdef DEBUG_LV0_ON
if(sublocation > (HDD_SECTOR_SIZE-1))DEBUG_OUT("\r\ndy's debug:in <IDE_SectorByte()>:sublocation > 511\r\n");
#endif
data=IDE_Internal.currentsector[sublocation]; // Read Data from specified pos
return (data);
}
//-----------------------------------------------------------------------------
// IDE_SectorWord: Function is used to retrieve a word from the 'currentsector'
// array. The value passed in must be between 0 - 510.
//
// Parameters: Word location within currentsector
//
// Returns: Word of data requested from currentsector
//-----------------------------------------------------------------------------
UI16 IDE_SectorWord(UI16 sublocation) // Return Word at position specified
{
#ifdef DEBUG_LV0_ON
if(sublocation > (HDD_SECTOR_SIZE-2))
{
DEBUG_OUT("\r\ndy's debug:in <IDE_SectorWord()>:sublocation > 510\r\n");
s3c44b0x_SysHalt();
}
#endif
return (IDE_Internal.currentsector[sublocation]+(IDE_Internal.currentsector[sublocation+1]<<8));
// Return value
//不用指针取数是因为可能给出的索引值并不能保证字对齐
}
//-----------------------------------------------------------------------------
// IDE_SectorUI32: Function is used to retrieve a 32 bit value from the
// 'currentsector' array. The value passed in must be between 0 - 511.
//
// Parameters: Word offset within current sector
//
// Returns: 32 bit unsigned data as requested
//
// Functions Used: None
//
//-----------------------------------------------------------------------------
UI32 IDE_SectorUI32(UI16 sublocation) // Return UI32 at position specified
{
#ifdef DEBUG_LV0_ON
if(sublocation > (HDD_SECTOR_SIZE-4))
{
DEBUG_OUT("\r\ndy's debug:in <IDE_SectorUI32()>:sublocation > 508\r\n");
s3c44b0x_SysHalt();
}
#endif
return (IDE_Internal.currentsector[sublocation] + (IDE_Internal.currentsector[sublocation+1]<<8) + (IDE_Internal.currentsector[sublocation+2]<<16) + (IDE_Internal.currentsector[sublocation+3]<<24));
// Return value
//不用指针取数是因为可能给出的索引值并不能保证长字对齐
}
//-----------------------------------------------------------------------------
// IDE_BufferSector: This function recieves the LBA address of a sector and reads into
// an array of 512 bytes (1 sector) called 'currentsector'.
//
// Parameters: 32bit Unsigned Logical Block Address
//
// Returns: An integer error code: 1 means read successfull, 0 means read fail.
//
// Functions Used: WriteReg, CheckforError, ReadErrors, Wait_DRQ, Set_Address,
// DataInputSetup, s3c44b0x_Printf
//
//-----------------------------------------------------------------------------
int IDE_BufferSector(UI32 LBALocation)
{
UI16 i;
if (LBALocation>=IDE_Internal.maxLBA)
{
s3c44b0x_Printf("\r\nIDE_BufferSector: Out of Range Disc Read of 0x%lx", LBALocation);
// Return failure
return 0;
}
if (IDE_Internal.SectorCurrentlyLoaded!=LBALocation) // Dont reload if already loaded
{
IDE_Internal.SectorCurrentlyLoaded=LBALocation; // update current sector loaded
WriteReg(SECTOR_COUNT, 1); // 1 Sector to be read only
WriteReg(HEAD_DEVICE_PIO, (((LBALocation >> 24) & 0xFF) | 0xE0));
WriteReg(CYLINDERHIGH, ((LBALocation >> 16) & 0xFF));
WriteReg(CYLINDERLOW,((LBALocation >> 8) & 0xFF));
WriteReg(START_SECTOR,(LBALocation & 0xFF));
//===========================
// if (CheckforError()) ReadErrors(); // Were there any Errors ?
// Wait_DRQ(); // Wait till Data is available in IDE buffer
//上面的部分被下面的替换了,这样便可以工作
//===========================
//===========================
WriteReg(COMMAND, READ); // Read sector
Wait_DRQBusy();
//源自陈猛
//===========================
// Reading Status Register reset INT too
#ifdef DEBUG_LV0_ON
DEBUG_OUT("\n\rdy's debug:in<IDE_BufferSector> Exit <Wait_DRQ>");
#endif
for(i=0; i <HDD_SECTOR_SIZE; i=i+2)
{
*((UI16*)(&(IDE_Internal.currentsector[i]))) = ReadWord(DATA);
}
if (CheckforError()) ReadErrors(); // Were there any Errors ?
}
// Return Success
return 1;
}
//-----------------------------------------------------------------------------
// IDE_PowerOn: Function set port directions, default values of output pins
// and performs a Hard Reset
//-----------------------------------------------------------------------------
void IDE_Reset(void)
{
// Set to defualt value
IDE_Internal.SectorCurrentlyLoaded = 0xffffffff;
}
//-----------------------------------------------------------------------------
// InitDrive: Drive Initialisation routine, required before you use the drive
// for reading or writting to the actual media.
//-----------------------------------------------------------------------------
void IDE_InitDrive(void)
{
/*
Initialize device parameters
OPCODE
- 91h
INPUTS
- The Sector Count register specifies the number of logical sectors per logical track, and the
Device/Head register which specifies the number of logical heads minus 1.
ERROR OUTPUTS
- Aborted Command if the device does not support the requested CHS translation.
DESCRIPTION
- This command enables the host to set the number of logical sectors per track and the
number of logical heads minus 1, per logical cylinder for the current CHS translation mode.
Upon receipt of the command, the device sets the BSY bit, saves the parameters, clears the BSY bit, and
generates an interrupt.
A device shall support the CHS translation described in words 1, 3 and 6 of the IDENTIFY DEVICE
information. Support of other CHS translations is optional.
If the requested CHS translation is not supported, the device shall set the Error bit in the Status register and
set the Aborted Command bit in the Error register before clearing the BSY bit in the Status register.
If the requested CHS translation is not supported, the device shall fail all media access commands with an ID
Not Found error until a valid CHS translation is established.
*/
WriteReg(SECTOR_COUNT, 0x3F);
WriteReg(HEAD_DEVICE_PIO, 0xAF);
WriteReg(COMMAND, 0x91); // This command is essential
// Select LBA, Master Drive and Head 0
WriteReg(HEAD_DEVICE_PIO, 0xE0);
/*
#ifdef DEBUG_LV0_ON
DEBUG_OUT("\n\rdy's debug:Enter <WriteReg(HEAD_DEVICE_PIO,(0xA0+(0xe0&0x10)));>");
#endif
WriteReg(HEAD_DEVICE_PIO,(0xA0+(0xe0&0x10)));
#ifdef DEBUG_LV0_ON
DEBUG_OUT("\n\rdy's debug:Exit <WriteReg(HEAD_DEVICE_PIO,(0xA0+(0xe0&0x10)));>");
#endif
*/
// Read Max LBA Read address
IDE_Internal.maxLBA = Fetch_ID_Max_LBA(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -