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

📄 idectrl.c

📁 wince host 和 target PCI驱动程序
💻 C
字号:
#include "idesys.h"
USHORT DATA_REG, ERROR_REG, FEATURE_REG, SECCNT_REG, IRQ_REASON_REG;
USHORT BUFSIZE_REG_LOW, BUFSIZE_REG_HI, DRIVE_REG, STATUS_REG;
USHORT COMMAND_REG, ALT_STATUS_REG;

//***Prototype functions
int debugPrintf(ULONG iDebugLevel, CHAR* pzFmt, ...);

UCHAR inp(USHORT wPort)
{
	UCHAR bReturn;
	_asm
	{
		xor eax,eax
		xor edx,edx
		mov dx, wPort
		in  al, dx
		mov bReturn, al
	}
	return bReturn;
}

void outp(USHORT wPort, UCHAR bValue)
{
	_asm 
	{
		xor eax, eax
		xor edx,edx
		mov dx, wPort
		mov al, bValue
		out dx, al
	}
}

USHORT inpw(USHORT wPort)
{
	USHORT wReturn;
	_asm
	{
		xor eax,eax
		xor edx,edx
		mov dx, wPort
		in  ax, dx
		mov wReturn, ax
	}
	return wReturn;
}

void outpw(USHORT wPort, USHORT wValue)
{
	_asm 
	{
		xor eax, eax
		xor edx,edx
		mov dx, wPort
		mov ax, wValue
		out dx, ax
	}
}

void SetControllerAddress(USHORT wController)
{
   if(wController == 1) //***Slave Controller
   {
      DATA_REG          = 0x170;   //  r/w
      ERROR_REG         = 0x171;   //  r
      FEATURE_REG       = 0x171;   //  w
      SECCNT_REG        = 0x172;   //  r/w
      IRQ_REASON_REG    = 0x1f2;   //  r
      BUFSIZE_REG_LOW   = 0x174;   //  r
      BUFSIZE_REG_HI    = 0x175;   //  r
      DRIVE_REG         = 0x176;   //  r/w
      STATUS_REG        = 0x177;   //  r
      COMMAND_REG       = 0x177;   //  w
      ALT_STATUS_REG    = 0x376;   //  r
   }
   else                 //***Master Controller
   {
      DATA_REG          = 0x1f0;   //  r/w
      ERROR_REG         = 0x1f1;   //  r
      FEATURE_REG       = 0x1f1;   //  w
      SECCNT_REG        = 0x1f2;   //  r/w
      IRQ_REASON_REG    = 0x1f2;   //  r
      BUFSIZE_REG_LOW   = 0x1f4;   //  r
      BUFSIZE_REG_HI    = 0x1f5;   //  r
      DRIVE_REG         = 0x1f6;   //  r/w
      STATUS_REG        = 0x1f7;   //  r
      COMMAND_REG       = 0x1f7;   //  w
      ALT_STATUS_REG    = 0x3f6;   //  r
   }
}

void WaitForInterrupt()
{
  ULONG dwTimeOut = 50;
  while (TRUE)
  {
    if ((inp(ALT_STATUS_REG) & 0x80) == 0x80)
      return;
    if (--dwTimeOut == 0)
    {
      debugPrintf(0,"WaitForInterrupt FAILED\n\r");
      return;
    }
    Sleep(3);
  }
}

BOOLEAN CheckReg(USHORT wReg, UCHAR bValue)
{
  ULONG dwTimeOut = 50;
  while (TRUE)
  {
    if (inp(wReg) == bValue)
      return TRUE;
    if (--dwTimeOut == 0)
    {
      debugPrintf(0,"CheckReg Reg:%x Value:%x FAILED\n\r",wReg,bValue);
      return FALSE;
    }
    Sleep(3);
  }

}

//***The purpose of the function is to set the IDE controller to PIO mode***
void Initialize(void)
{
  ULONG dwCounter;

  debugPrintf(0,"Enter Initialize\n\r");

  if (!CheckReg(ALT_STATUS_REG, 0x50))
  {
    debugPrintf(0,"Initialize ERROR #1\n\r");
    return;
  }
  inp(STATUS_REG);

  outp(BUFSIZE_REG_LOW, 0x00);
  outp(BUFSIZE_REG_HI, 0x00);
  outp(FEATURE_REG, 0x00);  //***Unknown feature
  outp(COMMAND_REG, 0xa0);

  if (!CheckReg(ALT_STATUS_REG, 0x58))
  {
    debugPrintf(0,"Initialize ERROR #2\n\r");
    return;
  }
  inp(STATUS_REG);

  for (dwCounter=0; dwCounter < 6; dwCounter++)
    outp(DATA_REG, 0x00);
}

void SelectDrive(UCHAR bDriveNumber)
{
  UCHAR bDriveValue;

  debugPrintf(0,"Enter SelectDrive \n\r");
  bDriveValue = 0xa0;
  bDriveValue |= (bDriveNumber << 4);
  debugPrintf(0,"Drive Select = %x\n\r",bDriveValue);
  outp(DRIVE_REG, bDriveValue);
  return;
}

void ResetDrive(void)
{
    ULONG dwTimeOut=5000;
    outp(ALT_STATUS_REG, 0x00);
    outp(ALT_STATUS_REG, 0x04);
    while (inp(ALT_STATUS_REG) != 0x50 && --dwTimeOut != 0) Sleep(5);
    return;
}


BOOLEAN SendDeviceCommand(USHORT *pwCommand, USHORT *pwData, ULONG dwNumDataWord)
{
  USHORT wCounter, wExtraData;
  ULONG dwTimeOut = 50;
  UCHAR bStatus;

  if (!CheckReg(ALT_STATUS_REG, 0x50))
  {
    debugPrintf(0,"SendDeviceCommand Error #1\n\r");
    return FALSE;
  }

  inp(STATUS_REG);

  if (!CheckReg(SECCNT_REG, 0x03))
  {
    debugPrintf(0,"SendDeviceCommand Error #2\n\r");
    return FALSE;
  }

  outp(BUFSIZE_REG_LOW, 0xFF);
  outp(BUFSIZE_REG_HI, 0xFF);
  outp(FEATURE_REG, 0x00);
  outp(COMMAND_REG, 0xa0);

  if (!CheckReg(ALT_STATUS_REG, 0x58))
  {
    debugPrintf(0,"SendDeviceCommand Error #3\n\r");
    return FALSE;
  }
  inp(STATUS_REG);
  
  //***Sending the 6 WORDS command	
  for (wCounter = 0; wCounter < 6; wCounter++)
  {
    outpw(DATA_REG, *pwCommand);
    pwCommand++;
  }


  if(dwNumDataWord == 0)
    return TRUE;

  dwTimeOut = 50;
  while(TRUE)
  {
    bStatus = inp(ALT_STATUS_REG);

    if (bStatus == 0x50)
      return TRUE;

    if (bStatus == 0x58)
      break;

    if(--dwTimeOut == 0)
    {
      debugPrintf(0,"SendDeviceCommand Error #4 %x\n\r",bStatus);
      return FALSE;
    }
    Sleep(3);
  }

  inp(STATUS_REG);

  if (inp(SECCNT_REG) != 0x00)
    return TRUE;
  

  wExtraData = inp(BUFSIZE_REG_HI);
  wExtraData = wExtraData << 8;
  wExtraData += inp(BUFSIZE_REG_LOW);

  wExtraData = wExtraData >> 1;

  for(wCounter = 0; wCounter < wExtraData; wCounter++)
  {
    if (wCounter >= dwNumDataWord)
      break;
    outpw(DATA_REG, *pwData);
    pwData++;
  }
  debugPrintf(0,"Leaving SendDeviceCommand\n\r");
  return TRUE;	
}

BOOLEAN ReadDataBuffer(USHORT *pwData, ULONG dwNumWord)
{
  UCHAR bCheckStatus;
  ULONG dwNumBuffer, dwCounter;
  ULONG dwTimeOut = 50;

  if (!CheckReg(SECCNT_REG, 0x02))
  {
    debugPrintf(0,"ReadDataBuffer Error #1\n\r");
    return FALSE;
  }

  if (!CheckReg(ALT_STATUS_REG, 0x58))
  {
    debugPrintf(0,"ReadDataBuffer Error #2: %x\n\r",inp(ALT_STATUS_REG));
    return FALSE;
  }

  inp(STATUS_REG);				  

  dwNumBuffer = (ULONG)(USHORT)(UCHAR)inp(BUFSIZE_REG_LOW);
  dwNumBuffer += (((ULONG)(USHORT)(UCHAR)inp(BUFSIZE_REG_HI)) << 8);
  debugPrintf(0,"Number of Bytes going to read = %d\n\r", dwNumBuffer);

  dwNumBuffer = dwNumBuffer >> 1;     //***Number of WORDS here.
  for (dwCounter=0; dwCounter < dwNumBuffer; dwCounter++)
  {
  	//***We don't have enough buffer to read!
    if (dwCounter > dwNumWord)
      inpw(DATA_REG);
    else
    {
      *pwData = inpw(DATA_REG);
      pwData++;
    }
  }
  //debugPrintf(0,"Leaving ReadDataBuffer\n\r");
  return TRUE;
}

BOOLEAN GetDVDDriveStatus(ULONG *pdwDVDErrorCode)
{
  	USHORT wController, wDrive;
  	USHORT InquiryCmd[6] = {0x0012, 0x000, 0x0024, 0x0000, 0x0000, 0x0000};
  	USHORT Mechanic[6] = {0x00BD, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000};
  	USHORT MechanicRead[4];
	USHORT CreativeVenID[4] = {0x414d, 0x5354, 0x4948, 0x4154};
	USHORT CreativeProID[8] = {0x5644,0x2d44,0x4f52,0x204d,0x5253,0x382d,0x3835,0x2031};	
	USHORT InquiryRead[20];  //***Partial information is good enough for me.
	
	debugPrintf(0,"IDEVXD.VXD:GetDVDDriveStatus\n\r");
	
    for (wController = 0; wController <= 1; wController++)
    {
        SetControllerAddress(wController);
        for (wDrive = 0; wDrive <= 1; wDrive++)
        {
			debugPrintf(0,"Controller = %d	Drive = %d\n\r",wController,wDrive);
			SelectDrive((UCHAR)wDrive);
			if (SendDeviceCommand(InquiryCmd, NULL, 0))
			{
				if (ReadDataBuffer(InquiryRead, sizeof(InquiryRead)))
//					if((InquiryRead[0] & 0xff) == 0x05)	//***C/DVD Rom Drive type
//Take Vendor                if (InquiryRead[4] == CreativeVenID[0] && //***Creative Lab
//ID out                   InquiryRead[5] == CreativeVenID[1] && //***Vendor ID
//???                   InquiryRead[6] == CreativeVenID[2] &&
//???                   InquiryRead[7] == CreativeVenID[3])
                {
						  Initialize();
                    *pdwDVDErrorCode = ERROR_NONE;
                    return TRUE;//***Found Creative Lab DVD-Rom
                                //***I don't even check for ProductID
                                //***because it may change in the future
                }  
			}
		}		
	}
	*pdwDVDErrorCode = ERR_NO_DVDROM_DRIVE;
	return FALSE;
}

BOOLEAN IsDriveOpen(BOOLEAN *pfOpen)
{
  	USHORT Mechanic[6] = {0x00BD, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000};
  	USHORT MechanicRead[4];
	if (SendDeviceCommand(Mechanic, NULL, 0))
		if (ReadDataBuffer(MechanicRead, sizeof(MechanicRead)))
			*pfOpen = (MechanicRead[0] & 0x1000) == 0x1000  ? TRUE : FALSE;
	return TRUE;
}

⌨️ 快捷键说明

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