📄 idectrl.c
字号:
#include "idevxd.h"
#include "vxd_clib.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;
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)
{
VXD_printf("WaitForInterrupt FAILED\n\r");
return;
}
Sleep(3);
}
}
BOOL CheckReg(USHORT wReg, UCHAR bValue)
{
ULONG dwTimeOut = 50;
while (TRUE)
{
if (inp(wReg) == bValue)
return TRUE;
if (--dwTimeOut == 0)
{
VXD_printf("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;
VXD_printf("Enter Initialize\n\r");
if (!CheckReg(ALT_STATUS_REG, 0x50))
{
VXD_printf("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))
{
VXD_printf("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;
VXD_printf("Enter SelectDrive \n\r");
bDriveValue = 0xa0;
bDriveValue |= (bDriveNumber << 4);
VXD_printf("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;
}
BOOL SendDeviceCommand(USHORT *pwCommand, USHORT *pwData, ULONG dwNumDataWord)
{
USHORT wCounter, wExtraData;
ULONG dwTimeOut = 50;
UCHAR bStatus;
if (!CheckReg(ALT_STATUS_REG, 0x50))
{
VXD_printf("SendDeviceCommand Error #1\n\r");
return FALSE;
}
inp(STATUS_REG);
if (!CheckReg(SECCNT_REG, 0x03))
{
VXD_printf("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))
{
VXD_printf("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)
{
VXD_printf("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++;
}
VXD_printf("Leaving SendDeviceCommand\n\r");
return TRUE;
}
BOOL ReadDataBuffer(USHORT *pwData, ULONG dwNumWord)
{
UCHAR bCheckStatus;
ULONG dwNumBuffer, dwCounter;
ULONG dwTimeOut = 50;
if (!CheckReg(SECCNT_REG, 0x02))
{
VXD_printf("ReadDataBuffer Error #1\n\r");
return FALSE;
}
if (!CheckReg(ALT_STATUS_REG, 0x58))
{
VXD_printf("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);
VXD_printf("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++;
}
}
//VXD_printf("Leaving ReadDataBuffer\n\r");
return TRUE;
}
BOOL 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.
VXD_printf("IDEVXD.VXD:GetDVDDriveStatus\n\r");
for (wController = 0; wController <= 1; wController++)
{
SetControllerAddress(wController);
for (wDrive = 0; wDrive <= 1; wDrive++)
{
VXD_printf("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 = NO_ERROR;
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;
}
BOOL IsDriveOpen(BOOL *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 + -