mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Added #define organisation over mfg logo (no actual build effect though just for neatness) Creating a CubeMX project to match settings for future use More comments and cleaning up
284 lines
9.2 KiB
C
284 lines
9.2 KiB
C
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. ********************
|
||
File Name : 2FAT12.c
|
||
Version : S100 APP Ver 2.11
|
||
Description:
|
||
Author : bure & Celery
|
||
Data: 2015/08/03
|
||
History:
|
||
2015/08/03 ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
*******************************************************************************/
|
||
#include <string.h>
|
||
#include "FAT12.h"
|
||
#include "Bios.h"
|
||
|
||
#define FAT_LEN 0x1800
|
||
#define FAT1_BASE 0x00001000 // FAT1
|
||
#define FAT2_BASE 0x00002800 // FAT2
|
||
#define ROOT_BASE 0x00004000 //
|
||
#define FILE_BASE 0x00008000 //
|
||
#define SEC_LEN 0x200 //
|
||
#define FAT1_SEC 0x0C // FAT1
|
||
#define FAT2_SEC 0x0C // FAT2
|
||
|
||
#define OK 0 //
|
||
#define SEC_ERR 1 //
|
||
#define FAT_ERR 2 //
|
||
#define OVER 3 //
|
||
#define NEW 4 //
|
||
#define END 0xFFF //
|
||
|
||
#define OW 0 //
|
||
#define RW 1 //
|
||
|
||
/*******************************************************************************
|
||
Function:
|
||
Description:
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 NextCluster(u16* pCluster) {
|
||
u16 FatNum;
|
||
u32 Addr = FAT1_BASE + (*pCluster + *pCluster / 2);
|
||
|
||
*(pCluster + 1) = *pCluster; // <20><><EFBFBD><EFBFBD>ǰһ<C7B0><D2BB><EFBFBD>غ<EFBFBD>
|
||
// *(pCluster+1)= 0;
|
||
if ((*pCluster >= END) || (*pCluster < 2))
|
||
return OK;
|
||
if (ReadDiskData((u8*) &FatNum, Addr, 2) != OK)
|
||
return SEC_ERR;
|
||
*pCluster = (*pCluster & 1) ? (FatNum >> 4) : (FatNum & 0x0FFF); // ָ<><D6B8><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
|
||
return OK;
|
||
}
|
||
/*******************************************************************************
|
||
Function:
|
||
Description:
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 ReadFileSec(u8* pBuffer, u16* pCluster) {
|
||
u32 ReadAddr = FILE_BASE + SEC_LEN * (*pCluster - 2);
|
||
|
||
if (ReadDiskData(pBuffer, ReadAddr, 256) != OK)
|
||
return SEC_ERR; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
pBuffer += 256;
|
||
ReadAddr += 256;
|
||
if (ReadDiskData(pBuffer, ReadAddr, 256) != OK)
|
||
return SEC_ERR; // Failed to read the sector
|
||
if (NextCluster(pCluster) != 0)
|
||
return FAT_ERR; // ȡ<><C8A1>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
|
||
return OK;
|
||
}
|
||
/*******************************************************************************
|
||
Function:
|
||
Description:
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 ProgFileSec(u8* pBuffer, u16* pCluster) {
|
||
u16 Tmp;
|
||
u32 ProgAddr = FILE_BASE + SEC_LEN * (*pCluster - 2);
|
||
|
||
if (ProgDiskPage(pBuffer, ProgAddr) != OK)
|
||
return SEC_ERR; // дǰ<D0B4><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
pBuffer += 256;
|
||
ProgAddr += 256;
|
||
if (ProgDiskPage(pBuffer, ProgAddr) != OK)
|
||
return SEC_ERR; // д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
Tmp = *pCluster;
|
||
switch (Tmp) {
|
||
case 0: // <20><><EFBFBD>дغ<D0B4>
|
||
case 1: // <20><><EFBFBD>дغ<D0B4>
|
||
if (SeekBlank(pBuffer, pCluster) != OK)
|
||
return OVER;
|
||
if (SetCluster(pBuffer, pCluster) != OK)
|
||
return SEC_ERR;
|
||
*(pCluster + 1) = Tmp;
|
||
return OK;
|
||
case END: // <20><><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>
|
||
default:
|
||
if (NextCluster(pCluster) != OK)
|
||
return FAT_ERR; // ȡ<><C8A1>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
|
||
return OK;
|
||
}
|
||
}
|
||
/*******************************************************************************
|
||
Function:
|
||
Description:
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 SeekBlank(u8* pBuffer, u16* pCluster) {
|
||
u16 Offset, Tmp, i, n = 0;
|
||
u32 SecAddr;
|
||
|
||
for (i = 0; i < 4096; i++) {
|
||
Offset = i + i / 2;
|
||
if ((Offset % 256) == 0) {
|
||
SecAddr = FAT1_BASE + (Offset & (~0xFF));
|
||
if (ReadDiskData(pBuffer, SecAddr, 258) != 0)
|
||
return SEC_ERR;
|
||
}
|
||
Offset %= 256;
|
||
Tmp = pBuffer[Offset] + (pBuffer[Offset + 1] << 8);
|
||
Tmp = (i & 1) ? (Tmp >> 4) : (Tmp & 0xFFF);
|
||
if (Tmp == 0) {
|
||
*pCluster++ = i;
|
||
n++;
|
||
if (n > 1)
|
||
return OK;
|
||
}
|
||
}
|
||
*(pCluster + 1) = 0xFFF;
|
||
return OK;
|
||
}
|
||
/*******************************************************************************
|
||
Function:
|
||
Description:
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 SetCluster(u8* pBuffer, u16* pCluster) {
|
||
u16 Offset, Tmp, i, k;
|
||
u32 SecAddr;
|
||
|
||
i = *pCluster; // <20><>ȡԭ<C8A1><D4AD>ǰ<EFBFBD>غ<EFBFBD>
|
||
k = *(pCluster + 1); // <20><>ȡ<EFBFBD><C8A1>һ<EFBFBD>غ<EFBFBD>
|
||
*pCluster = k;
|
||
Offset = i + i / 2;
|
||
SecAddr = FAT1_BASE + (Offset & (~0xFF));
|
||
Tmp = Offset & 0xFF;
|
||
if (ReadDiskData(pBuffer, SecAddr, 256) != 0)
|
||
return SEC_ERR;
|
||
if (i & 1)
|
||
pBuffer[Tmp] = ((k << 4) & 0xF0) + (pBuffer[Tmp] & 0x0F);
|
||
else
|
||
pBuffer[Tmp] = k;
|
||
if (Tmp++ < 256) {
|
||
if (i & 1)
|
||
pBuffer[Tmp] = k >> 4;
|
||
else
|
||
pBuffer[Tmp] = ((k >> 8) & 0x0F) + (pBuffer[Tmp] & 0xF0);
|
||
if (ProgDiskPage(pBuffer, SecAddr) != 0)
|
||
return SEC_ERR;
|
||
} else {
|
||
if (ProgDiskPage(pBuffer, SecAddr) != 0)
|
||
return SEC_ERR;
|
||
SecAddr += 256;
|
||
if (ReadDiskData(pBuffer, SecAddr, 256) != 0)
|
||
return SEC_ERR;
|
||
if (i & 1)
|
||
pBuffer[0] = k >> 4;
|
||
else
|
||
pBuffer[0] = ((k >> 8) & 0x0F) + (pBuffer[0] & 0xF0);
|
||
if (ProgDiskPage(pBuffer, SecAddr) != 0)
|
||
return SEC_ERR;
|
||
}
|
||
return OK;
|
||
}
|
||
/*******************************************************************************
|
||
Function:
|
||
Description:
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 FAT_SearchFile(u8* pBuffer, u8* pFileName, u16* pCluster, u32* pDirAddr,
|
||
u32* flag) {
|
||
u16 i, n;
|
||
|
||
*pCluster = 0;
|
||
for (*pDirAddr = ROOT_BASE; *pDirAddr < FILE_BASE;) {
|
||
if (ReadDiskData(pBuffer, *pDirAddr, 256) != OK)
|
||
return SEC_ERR;
|
||
for (n = 0; n < 256; n += 32) {
|
||
for (i = 0; i < 4; i++) {
|
||
if (pBuffer[n + i] != 0) {
|
||
if (pBuffer[n + i] != pFileName[i])
|
||
break;
|
||
if (i == 3) { // <20>ҵ<EFBFBD><D2B5>ļ<EFBFBD><C4BC><EFBFBD>
|
||
*pCluster = *(u16*) (pBuffer + n + 0x1A); // <20>ļ<EFBFBD><C4BC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
|
||
return OK;
|
||
}
|
||
} else
|
||
return NEW; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>հ<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD>
|
||
}
|
||
*pDirAddr += 32;
|
||
}
|
||
}
|
||
return OVER;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
Function:OpenFileRd
|
||
Description: Opens a file for reading from
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 OpenFileRd(u8* pBuffer, u8* pFileName, u16* pCluster, u32* pDirAddr) {
|
||
u16 i, n;
|
||
|
||
*pCluster = 0;
|
||
for (*pDirAddr = ROOT_BASE; *pDirAddr < FILE_BASE;) {
|
||
if (ReadDiskData(pBuffer, *pDirAddr, 256) != OK)
|
||
return SEC_ERR;
|
||
for (n = 0; n < 256; n += 32) {
|
||
for (i = 0; i < 11; i++) {
|
||
if (pBuffer[n + i] != 0) {
|
||
if (pBuffer[n + i] != pFileName[i])
|
||
break;
|
||
if (i == 10) { // <20>ҵ<EFBFBD><D2B5>ļ<EFBFBD><C4BC><EFBFBD>
|
||
*pCluster = *(u16*) (pBuffer + n + 0x1A); // <20>ļ<EFBFBD><C4BC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
|
||
return OK;
|
||
}
|
||
} else
|
||
return NEW; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>հ<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD>
|
||
}
|
||
*pDirAddr += 32;
|
||
}
|
||
}
|
||
return OVER;
|
||
}
|
||
/*******************************************************************************
|
||
Function: OpenFileWr
|
||
Description: Opens a file for writing to
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 OpenFileWr(u8* pBuffer, u8* pFileName, u16* pCluster, u32* pDirAddr) {
|
||
u16 i, n;
|
||
|
||
i = OpenFileRd(pBuffer, pFileName, pCluster, pDirAddr);
|
||
if (i != NEW)
|
||
return i;
|
||
else { // <20><>ǰ<EFBFBD><C7B0>Ϊ<EFBFBD>հ<EFBFBD>Ŀ¼<C4BF><C2BC>
|
||
if (SeekBlank(pBuffer, pCluster) != OK)
|
||
return OVER; // <20><>FAT<41><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
n = *pDirAddr & 0xFF; // nΪ<6E><CEAA>ǰҳĿ¼<C4BF><C2BC>
|
||
if (ReadDiskData(pBuffer, (*pDirAddr) - n, 256) != OK)
|
||
return SEC_ERR;
|
||
for (i = 0; i < 11; i++)
|
||
pBuffer[n + i] = pFileName[i]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC>
|
||
*(u16*) (pBuffer + n + 0x1A) = *pCluster;
|
||
if (ProgDiskPage(pBuffer, (*pDirAddr) - n) != OK)
|
||
return SEC_ERR;
|
||
return OK;
|
||
}
|
||
}
|
||
/*******************************************************************************
|
||
Function: CloseFile
|
||
Description: Closes a file that was previously opened
|
||
Input:
|
||
*******************************************************************************/
|
||
u8 CloseFile(u8* pBuffer, u32 Lenght, u16* pCluster, u32* pDirAddr) {
|
||
u16 n;
|
||
|
||
// *pCluster = *(pCluster+1); // <20><>ȡǰһ<C7B0><D2BB><EFBFBD>غ<EFBFBD>
|
||
*(pCluster + 1) = 0xFFF;
|
||
SetCluster(pBuffer, pCluster);
|
||
if (ReadDiskData(pBuffer, (*pDirAddr & (~0xFF)), 256) != OK)
|
||
return SEC_ERR;
|
||
*(u8*) (pBuffer + (*pDirAddr & 0xFF) + 0x0B) = 0x20;
|
||
*(u32*) (pBuffer + (*pDirAddr & 0xFF) + 0x1C) = Lenght;
|
||
if (ProgDiskPage(pBuffer, (*pDirAddr & (~0xFF))) != OK)
|
||
return SEC_ERR;
|
||
for (n = 0; n < FAT1_SEC; n++) {
|
||
if (ReadDiskData(pBuffer, FAT1_BASE + n * 256, 256) != OK)
|
||
return SEC_ERR;
|
||
if (ProgDiskPage(pBuffer, FAT2_BASE + n * 256) != OK)
|
||
return SEC_ERR;
|
||
}
|
||
return OK;
|
||
}
|
||
/******************************** END OF FILE *********************************/
|