📄 cf_ide.c
字号:
ATA_CMD.DH = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA
// read command
ATA_CMD.CMD = 0x20;
// Send ATA Command
ATA_send_command();
// Wait for IRQ
ATA_wait_for_it();
// Collect Buffer
for(i=0; i<256; i++)
ATA_buffer[i] = _inpw(IDE_RDD);
}
/******************************************************************************
* CF_IDE: ATA_read_fat_sector()
*
* Purpose:
* expects a cluster number to read and converts it to LBA address for
* fetch from CF
*
* Actions:
*
*****************************************************************************/
MC void ATA_read_fat_sector(DWORD LBAsec)
{
int i, w;
// skip reserved sectors and add hidden for LBA addressing
LBAsec += ATA_P.BPB_RsvdSecCnt + ATA_LBAHidden;
#if 1//A_DP
printf("LBA: %d\n", LBAsec);
#endif
// prepare command buffer
ATA_CMD.SC = 1; // one 512 byte sector
ATA_CMD.SN = (LBAsec & 0x000000ff); // sec number
ATA_CMD.CL = (LBAsec & 0x0000ff00)>> 8; // cyl low
ATA_CMD.CH = (LBAsec & 0x00ff0000)>>16; // cyl high
ATA_CMD.DH = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA
// read command
ATA_CMD.CMD = 0x20;
// Send ATA Command
ATA_send_command();
// Wait for IRQ
ATA_wait_for_it();
// Collect Buffer
for(i=0; i<256; i++)
{
ATA_CurFATBuffer[i] = _inpw(IDE_RDD);
// wait loop
for (w=0; w<PIOWAIT; w++)
_inp(0xffa00000);
}
}
/******************************************************************************
* CF_IDE: ATA_read_cluster()
*
* Purpose:
* expects a cluster number to read and converts it to LBA address for
* fetch from CF
*
* Actions:
*
*****************************************************************************/
MC void ATA_read_cluster(DWORD Cluster, DWORD* buffer)
{
int i, j, w;
DWORD LBAsec;
BYTE Timeout;
WORD *buf = (WORD*) buffer;
WORD status;
// allocation starts with sector 2, add data offset and hidden
LBAsec = (Cluster-2) * ATA_P.BPB_SecPerClus + ATA_FirstDataSector + ATA_LBAHidden;
#if 1//A_DP
printf("LBA: %d\n", LBAsec);
#endif
// loop for number of sectors per cluster
for (j = 0; j<ATA_P.BPB_SecPerClus; j++)
{
// prepare command buffer
ATA_CMD.SC = 1; // one cluster
ATA_CMD.SN = (LBAsec & 0x000000ff); // sec number
ATA_CMD.CL = (LBAsec & 0x0000ff00)>> 8; // cyl low
ATA_CMD.CH = (LBAsec & 0x00ff0000)>>16; // cyl high
ATA_CMD.DH = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA
// read command
ATA_CMD.CMD = 0x20;
// Send ATA Command
ATA_send_command();
// Wait for IRQ
ATA_wait_for_it();
// Collect Buffer
for(i=0; i < 256; i++)
{
*buf++ = _inpw(IDE_RDD);
//wait loop
for (w=0; w<PIOWAIT; w++)
_inp(0xffa00000);
}
// increment sector pointer
LBAsec += 1;
// set Timeout to 1 sec
Timeout_DISK = 4;
// wait for rdy
while(Timeout_DISK)
{
if (_inpw(IDE_STAT)&0x40) break;
}
// no ready so we must reset
if (!Timeout_DISK) ATA_reset();
}
}
/******************************************************************************
* CF_IDE: ATA_read_directory()
*
* Purpose:
* reads the directory and returns a parsed list of entries
*
* Actions:
*
*****************************************************************************/
MC void ATA_read_directory(WORD cluster, BYTE ROOTread)
{
BYTE* pd = (BYTE*) ATA_buffer;
BYTE entry = 0;
DWORD LBAsec;
int i, j, k;
// convert cluster to LBA
if (ROOTread == ROOT)
{
LBAsec = cluster + ATA_RootDirSecCnt + ATA_LBAHidden;
}
else
{
LBAsec = (cluster-2) * ATA_P.BPB_SecPerClus + ATA_FirstDataSector + ATA_LBAHidden;
}
#if 1//A_DP
printf("LBA: %d\n", LBAsec);
#endif
// prepare command buffer
ATA_CMD.SC = 1; // one sector
ATA_CMD.SN = (LBAsec & 0x000000ff); // sec number
ATA_CMD.CL = (LBAsec & 0x0000ff00)>> 8; // cyl low
ATA_CMD.CH = (LBAsec & 0x00ff0000)>>16; // cyl high
ATA_CMD.DH = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA
// read command
ATA_CMD.CMD = 0x20;
// Send ATA Command
ATA_send_command();
// Wait for IRQ
ATA_wait_for_it();
// Collect Buffer
for(i=0; i<256; i++)
ATA_buffer[i] = _inpw(IDE_RDD);
for (i=0; i<16; i++)
{
// no further entries
if (*pd == 0)
{
break;
}
if (*pd != 0xe5)
{
for (j=0; j<8; j++)
{
if (*(pd+j) == 0x20) break;
ATA_D[entry].DIR_Name[j] = *(pd+j);
}
ATA_D[entry].DIR_Name[j] = 0x2e;
memcpy(&ATA_D[entry].DIR_Name[j+1] , pd+ 8, 3);
ATA_D[entry].DIR_Name[12] = 0x00;
memcpy(&ATA_D[entry].DIR_Attr , pd+11, 1);
memcpy(&ATA_D[entry].DIR_NTRes , pd+12, 1);
memcpy(&ATA_D[entry].DIR_CrtTimeTenth , pd+13, 1);
memcpy(&ATA_D[entry].DIR_CrtTime , pd+14, 2);
memcpy(&ATA_D[entry].DIR_CrtDate , pd+16, 2);
memcpy(&ATA_D[entry].DIR_LstAccDate , pd+18, 2);
memcpy(&ATA_D[entry].DIR_FstClusHI , pd+20, 2);
memcpy(&ATA_D[entry].DIR_WrtTime , pd+22, 2);
memcpy(&ATA_D[entry].DIR_WrtDate , pd+24, 2);
memcpy(&ATA_D[entry].DIR_FstClusLO , pd+26, 2);
memcpy(&ATA_D[entry].DIR_FileSize , pd+28, 4);
// proper entry, let's increment
entry++;
}
// move pointer to next possible location
pd += 32;
}
// signal last element if array is not full
if (entry < 16) memcpy(&ATA_D[entry].DIR_Name, "\0", 1);
#if A_DP
for (i=0; i< entry; i++)
printf("%13s, %02x, %08x, %04x, %04x\n", ATA_D[i].DIR_Name, ATA_D[i].DIR_Attr, ATA_D[i].DIR_FileSize, ATA_D[i].DIR_FstClusHI, ATA_D[i].DIR_FstClusLO);
#endif
}
/******************************************************************************
* CF_IDE: ATA_read_short_dir()
*
* Purpose:
* reads basic parameters the directory and returns a parsed list of entries
*
* Actions:
*
*****************************************************************************/
MC void ATA_read_short_dir(WORD cluster, BYTE ROOTread)
{
BYTE* pd = (BYTE*) ATA_buffer;
DWORD LBAsec;
int i, j, k;
// convert cluster to LBA
if (ROOTread == ROOT)
LBAsec = cluster + ATA_RootDirSecCnt + ATA_LBAHidden;
else
LBAsec = (cluster-2) * ATA_P.BPB_SecPerClus + ATA_FirstDataSector + ATA_LBAHidden;
for (k=0; k < MAX_SHORT_DIR; )
{
#if A_DP
printf("LBA: %d\n", LBAsec);
#endif
// prepare command buffer
ATA_CMD.SC = 1; // one sector
ATA_CMD.SN = (LBAsec & 0x000000ff); // sec number
ATA_CMD.CL = (LBAsec & 0x0000ff00)>> 8; // cyl low
ATA_CMD.CH = (LBAsec & 0x00ff0000)>>16; // cyl high
ATA_CMD.DH = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA
// read command
ATA_CMD.CMD = 0x20;
// Send ATA Command
ATA_send_command();
// Wait for IRQ
ATA_wait_for_it();
// Collect Buffer
for(i=0; i<256; i++)
ATA_buffer[i] = _inpw(IDE_RDD);
// 16 entries per sector
for (i=0; i<16; i++)
{
// no further entries
if (*pd == 0)
{
// store number of entries
ATA_CurDirEnt = k;
// signal last element if array is not full
if (k < MAX_SHORT_DIR) memcpy(&ATA_DS[k].DIR_Name, "\0", 1);
#if 1//A_DP
for (i=0; i<k; i++)
printf("%13s, %02x, %08x, %04x, %04x\n", ATA_DS[i].DIR_Name, ATA_DS[i].DIR_Attr, ATA_DS[i].DIR_FileSize, ATA_DS[i].DIR_FstClusLO);
#endif
// exit subfunction
return;
}
if (*pd != 0xe5)
{
for (j=0; j<8; j++)
{
if (*(pd+j) == 0x20) break;
ATA_DS[k].DIR_Name[j] = *(pd+j);
}
ATA_DS[k].DIR_Name[j+0] = 0x2e;
memcpy(&ATA_DS[k].DIR_Name[j+1] , pd+ 8, 3);
ATA_DS[k].DIR_Name[j+4] = 0x00;
memcpy(&ATA_DS[k].DIR_Attr , pd+11, 1);
memcpy(&ATA_DS[k].DIR_FstClusLO , pd+26, 2);
memcpy(&ATA_DS[k].DIR_FileSize , pd+28, 4);
// increment number of entries
k++;
}
// move pointer to next possible location
pd += 32;
}
// increment LBA Sector
LBAsec += 1;
// reset pointer
pd = (BYTE*) ATA_buffer;
}
// signal last element if array is not full
if (k < MAX_SHORT_DIR) memcpy(&ATA_DS[k].DIR_Name, "\0", 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -