📄 cfdisk.c
字号:
/*
Module Name:
CFDisk.c
Abstract:
Implements routines to access a file from an MS-DOS partition.
*/
#include <windows.h>
#include <halether.h>
#include <atapi.h>
#include "CFDisk.h"
#include "CFLoad.h"
#include "msdos.h"
volatile PBYTE pATA;
#define mAtaNormalTimeout 0xFFFFF
#define mAtaLongTimeout 0xFFFFFFF
#define mCardReadyTimeout 0xFFFFF
#define mCardReadyValidTimeout10us 0x1FFFF
// bit definitions for logicalBlockNumber[3] field
#define mAtaLBAMask 0x0F
#define mAtaDriveSelectMask (1 << 4)
#define mAtaRequiredBitsMask (1 << 7) | (1 << 5)
#define mAtaEnableLBAModeMask (1 << 6)
//
BOOL CFAtaDiskDownload(UINT AtaDiskCmdAddress)
{
AtaStatus status;
pATA = (volatile PBYTE)AtaDiskCmdAddress;
//EdbgOutputDebugString("pATA[ATA_REG_SECT_CNT]= 0x%X[0x%X] \r\n", pATA, ATA_REG_SECT_CNT);
//EdbgOutputDebugString("pATA[ATA_REG_SECT_NUM]= 0x%X[0x%X] \r\n", pATA, ATA_REG_SECT_NUM);
//EdbgOutputDebugString("pATA[ATA_REG_CYL_LOW] = 0x%X[0x%X] \r\n", pATA, ATA_REG_CYL_LOW);
//EdbgOutputDebugString("pATA[ATA_REG_CYL_HIGH]= 0x%X[0x%X] \r\n", pATA, ATA_REG_CYL_HIGH);
//EdbgOutputDebugString("pATA[ATA_REG_DRV_HEAD]= 0x%X[0x%X] \r\n", pATA, ATA_REG_DRV_HEAD);
//EdbgOutputDebugString("pATA[ATA_REG_COMMAND] = 0x%X[0x%X] \r\n", pATA, ATA_REG_COMMAND);
status = CFWaitForAtaDisk(mAtaWaitForReady, mAtaLongTimeout);
if (status != mAtaOk)
{
EdbgOutputDebugString("Media not present!\r\n");
return FALSE;
}
if (!findBootPartition())
{
EdbgOutputDebugString("Partition type is not supported!\r\n");
return FALSE;
}
if (!processBootRecord())
{
EdbgOutputDebugString("FAT too large!\r\n");
return FALSE;
}
EdbgOutputDebugString("CFDISK: ATA disk ready\r\n");
if(!CFLoadFile())
{
EdbgOutputDebugString("Load from CF ATA Disk failed\r\n");
return FALSE;
}
return TRUE;
}
// ATA disk access services
//
static AtaStatus CFWaitForAtaDisk(AtaWaitType type, ULONG timeout)
{
BYTE status;
// DumpATARegisters();
while (timeout > 0)
{
status = pATA[ATA_REG_STATUS];
// EdbgOutputDebugString("CFWaitForAtaDisk: status= %x\r\n", status);
if (status & ATA_STATUS_BUSY)
{
if (type == mAtaWaitForBusy)
return mAtaOk;
}
else
{
if (type == mAtaWaitForNotBusy)
return mAtaOk;
else
{
if (type == mAtaWaitForDataReadyIgnoreErr)
if (status & ATA_STATUS_DATA_REQ)
return mAtaOk;
if (status & ATA_STATUS_ERROR)
return mAtaIoErr;
if (type == mAtaWaitForReady)
if (status & ATA_STATUS_READY)
return mAtaOk;
if (type == mAtaWaitForDataReady)
if (status & ATA_STATUS_DATA_REQ)
return mAtaOk;
}
}
timeout--;
}
return mAtaTimeout;
}
BOOL CFReadSector(int sector, PBYTE ramAddress)
{
AtaStatus status;
//EdbgOutputDebugString("CFReadSector: sector %d to %x\r\n", sector, ramAddress);
// abandon when there is no card present
//
// Here can insert a verification of card insertion
status = CFReadAtaSector(sector, ramAddress);
if (status != mAtaOk)
{
EdbgOutputDebugString("CFReadSector: CFReadATASector error (%x)=%d!\r\n", &status, status);
return FALSE;
}
return TRUE;
}
static
AtaStatus CFReadAtaSector(DWORD sector, PUCHAR pSectorData)
{
AtaStatus status;
#if 1 // 16 bits ata data access
LPWORD pSectorBuffer = (LPWORD) pSectorData;
LPWORD pATA_DataReg = (LPWORD)pATA;
DWORD SectorLength = mBytesPerSector/2;
#else // 8 bits ata data access
LPBYTE pSectorBuffer = (LPBYTE) pSectorData;
LPBYTE pATA_DataReg = (LPBYTE)pATA;
DWORD SectorLength = mBytesPerSector;
#endif
DWORD i;
// wait for ATA disk to be ready to accept a command
status = CFWaitForAtaDisk(mAtaWaitForNotBusy, mAtaNormalTimeout);
if (status != mAtaOk)
return status;
// send the read command to read one sector
pATA[ATA_REG_SECT_CNT] = 1;
pATA[ATA_REG_SECT_NUM] = (BYTE) (sector & 0xFF);
pATA[ATA_REG_CYL_LOW] = (BYTE)((sector >> 8) & 0xFF);
pATA[ATA_REG_CYL_HIGH] = (BYTE)((sector >> 16) & 0xFF);
pATA[ATA_REG_DRV_HEAD] = (BYTE)((sector >> 24) & 0xFF) | ATA_HEAD_DRIVE_1 | ATA_HEAD_LBA_MODE;
pATA[ATA_REG_COMMAND] = ATA_CMD_READ;
// wait for ATA disk to have data ready
status = CFWaitForAtaDisk(mAtaWaitForDataReady, mAtaNormalTimeout);
if (status != mAtaOk)
return status;
// copy the data
for (i = 0; i < SectorLength; i++)
{
*pSectorBuffer = *pATA_DataReg;
//EdbgOutputDebugString("%x ", *pSectorData);
pSectorBuffer++;
}
//EdbgOutputDebugString("\r\n ");
return status;
}
//
//
//
BOOL
CFDisk_Open(PBYTE filename, PBYTE extention)
{
BYTE fileNameData[mBootfileNameLength + 1];
BYTE fileExtData[mBootfileExtLength + 1];
FormatDosName(fileNameData, filename, mBootfileNameLength);
FormatDosName(fileExtData, extention, mBootfileExtLength);
EdbgOutputDebugString("fileNameData = %s!\r\n", fileNameData);
EdbgOutputDebugString("fileExtData = %s!\r\n", fileExtData);
if (findBootFile(fileNameData, fileExtData))
return TRUE;
return FALSE;
}
void
CFDisk_Read(PBYTE fileAddr, ULONG bytesToRead, PULONG bytesRead)
{
readBootFile(fileAddr, bytesToRead, bytesRead);
}
// copies s into d, padding it with spaces until d has size characters in total
static void FormatDosName(PBYTE d, PBYTE s, DWORD size)
{
DWORD i;
// copy string
for (i = 0; *s && (i < size); i++)
d[i] = *s++;
// append with spaces
while (i < size)
d[i++] = ' ';
// add terminator
d[i] = 0;
}
static void DumpATARegisters(void)
{
#if 1
EdbgOutputDebugString("ATA @ %x\n", pATA);
EdbgOutputDebugString("ATA_REG_DATA = %x\n", pATA[ATA_REG_DATA]);
EdbgOutputDebugString("ATA_REG_FEATURE = %x\n", pATA[ATA_REG_FEATURE]);
EdbgOutputDebugString("ATA_REG_ERROR = %x\n", pATA[ATA_REG_ERROR]);
EdbgOutputDebugString("ATA_REG_SECT_CNT = %x\n", pATA[ATA_REG_SECT_CNT]);
EdbgOutputDebugString("ATA_REG_SECT_NUM = %x\n", pATA[ATA_REG_SECT_NUM]);
EdbgOutputDebugString("ATA_REG_CYL_LOW = %x\n", pATA[ATA_REG_CYL_LOW]);
EdbgOutputDebugString("ATA_REG_CYL_HIGH = %x\n", pATA[ATA_REG_CYL_HIGH]);
EdbgOutputDebugString("ATA_REG_DRV_HEAD = %x\n", pATA[ATA_REG_DRV_HEAD]);
EdbgOutputDebugString("ATA_REG_COMMAND = %x\n", pATA[ATA_REG_COMMAND]);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -