📄 pccard.cpp
字号:
#include "system.h"
#include "pccard.h"
#define CFMEM_BASE 0x6ffb0000
//ATA, Basic PC card select
#define ATA_MUX CFMEM_BASE+0x1800
//PC card SFR base
#define PCCARD_SFR_BASE CFMEM_BASE+0x1820
// PC Card Memory map
#define PCCARD_CIS_BASE CFMEM_BASE
#define PCCARD_IO_BASE CFMEM_BASE+0x800
#define PCCARD_MEM_BASE CFMEM_BASE+0x1000
/*=========================================================================
* ata Command
*=========================================================================
*/
#define IDENTIFYDEVICE 0xec
#define READSECTOR 0x20
#define READMULTIPLE 0xc4
#define READDMA 0xc8
#define WRITESECTOR 0x30
#define WRITEMULTIPLE 0xc5
#define WRITEDMA 0xca
#define SETFEATURES 0xef
/*=========================================================================
* pccard Register Address
*=========================================================================
*/
#define PCCARD_MEM_DATA (PCCARD_MEM_BASE + 0x00)
#define PCCARD_MEM_ERROR (PCCARD_MEM_BASE + 0x01)
#define PCCARD_MEM_FEATURE (PCCARD_MEM_BASE + 0x01)
#define PCCARD_MEM_SECTOR (PCCARD_MEM_BASE + 0x02)
#define PCCARD_MEM_LOWLBA (PCCARD_MEM_BASE + 0x03)
#define PCCARD_MEM_MIDLBA (PCCARD_MEM_BASE + 0x04)
#define PCCARD_MEM_HIGHLBA (PCCARD_MEM_BASE + 0x05)
#define PCCARD_MEM_DEVICE (PCCARD_MEM_BASE + 0x06)
#define PCCARD_MEM_STATUS (PCCARD_MEM_BASE + 0x07)
#define PCCARD_MEM_COMMAND (PCCARD_MEM_BASE + 0x07)
#define PCCARD_MEM_ALTANATE (PCCARD_MEM_BASE + 0x0e)
#define PCCARD_MEM_CONTROL (PCCARD_MEM_BASE + 0x0e)
bool PCCARD::OpenMedia(void)
{
// Output pad disable, Card power off, PC card mode
Outp32(ATA_MUX, 0x06);
Delay(10);
// Output pad enable, Card power off, PC card mode
Outp32(ATA_MUX, 0x02);
Delay(10);
// Card Power on (PC Card mode)
Outp32(ATA_MUX, 0x00);
// wait for at least 20ms (SanDisk: 25ms, MicroDrive: 125ms, Hagiwara: )
// No other method available.
Delay(2500); // 125ms
return true;
}
bool PCCARD::CloseMedia(void)
{
// Output pad disable, Card power off, PC card mode
Outp32(ATA_MUX, 0x06);
return true;
}
void PCCARD::GetAttribData(u32 index, u8& data)
{
Inp8(PCCARD_CIS_BASE+index, data);
}
void PCCARD::ReadRegister(u32 nRegister, u8& data)
{
Inp8(nRegister, data);
}
void PCCARD::WriteRegister(u32 nRegister, u8 nValue)
{
u8 temp;
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
} while (temp == 0x80) ;
Outp8(nRegister, nValue);
}
void PCCARD::PutDataToDevice(u16 nData)
{
Outp16(PCCARD_MEM_DATA, nData);
}
void PCCARD::GetDataFromDevice(u16& uData)
{
Inp16(PCCARD_MEM_DATA, uData);
}
#if 0
void PCCARD::ReadSectors(u32 uLba, u32 uBlocks, u32 uDstAddr)
{
// uBlocks: sector count
// uLba: (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
// uDstAddr: host address
u8 temp;
u16* uCurrentAddr = (u16*) uDstAddr;
WriteRegister(PCCARD_MEM_FEATURE,0);
WriteRegister(PCCARD_MEM_SECTOR,uBlocks);
WriteRegister(PCCARD_MEM_LOWLBA,(uLba&0x00ff));
WriteRegister(PCCARD_MEM_MIDLBA,((uLba>>8)&0x00ff));
WriteRegister(PCCARD_MEM_HIGHLBA,((uLba>>16)&0x00ff));
WriteRegister(PCCARD_MEM_DEVICE,((uLba>>24)&0x000f) | 0xe0); //LBA enabled, Drive 0
WriteRegister(PCCARD_MEM_COMMAND, READSECTOR);
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x58) ;
for (u32 j=0; j<uBlocks; j++)
{
for (u32 i=0; i<512/2; i++)
{
#if 0 // both case are OK
GetDataFromDevice(*uCurrentAddr);
#else
Inp16(PCCARD_MEM_BASE+0x400+i*2, *uCurrentAddr);
#endif
uCurrentAddr++;
}
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x50 && temp != 0x58) ;
}
}
void PCCARD::WriteSectors(u32 uLba, u32 uBlocks, u32 uSrcAddr)
{
u8 temp;
u16* uCurrentAddr = (u16*) uSrcAddr;
// uBlocks: sector count
// uLba: (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
// uSrcAddr: host address
WriteRegister(PCCARD_MEM_FEATURE,0);
WriteRegister(PCCARD_MEM_SECTOR,uBlocks);
WriteRegister(PCCARD_MEM_LOWLBA,(uLba&0x00ff));
WriteRegister(PCCARD_MEM_MIDLBA,((uLba>>8)&0x00ff));
WriteRegister(PCCARD_MEM_HIGHLBA,((uLba>>16)&0x00ff));
WriteRegister(PCCARD_MEM_DEVICE,((uLba>>24)&0x000f) | 0xe0); //LBA enabled, Drive 0
WriteRegister(PCCARD_MEM_COMMAND, WRITESECTOR);
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x58) ;
for (u32 j=0; j<uBlocks; j++)
{
for (u32 i=0; i<512/2; i++)
{
#if 0 // both case are OK
PutDataToDevice(*uCurrentAddr);
#else
Outp16(PCCARD_MEM_BASE+0x400+i*2, *uCurrentAddr);
#endif
uCurrentAddr++;
}
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x50 && temp != 0x58) ;
}
}
#endif
bool PCCARD::ReadBlocks(u32 uStBlock, u32 uBlocks, u32 uBufAddr)
{
// uBlocks: sector count
// uLba: (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
// uDstAddr: host address
u8 temp;
u16* uCurrentAddr = (u16*) uBufAddr;
WriteRegister(PCCARD_MEM_FEATURE,0);
WriteRegister(PCCARD_MEM_SECTOR,uBlocks);
WriteRegister(PCCARD_MEM_LOWLBA,(uStBlock&0x00ff));
WriteRegister(PCCARD_MEM_MIDLBA,((uStBlock>>8)&0x00ff));
WriteRegister(PCCARD_MEM_HIGHLBA,((uStBlock>>16)&0x00ff));
WriteRegister(PCCARD_MEM_DEVICE,((uStBlock>>24)&0x000f) | 0xe0); //LBA enabled, Drive 0
WriteRegister(PCCARD_MEM_COMMAND, READSECTOR);
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x58) ;
for (u32 j=0; j<uBlocks; j++)
{
for (u32 i=0; i<512/2; i++)
{
#if 0 // both case are OK
GetDataFromDevice(*uCurrentAddr);
#else
Inp16(PCCARD_MEM_BASE+0x400+i*2, *uCurrentAddr);
#endif
uCurrentAddr++;
}
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x50 && temp != 0x58) ;
}
return true;
}
bool PCCARD::WriteBlocks(u32 uStBlock, u32 uBlocks, u32 uBufAddr)
{
u8 temp;
u16* uCurrentAddr = (u16*) uBufAddr;
// uBlocks: sector count
// uLba: (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
// uSrcAddr: host address
WriteRegister(PCCARD_MEM_FEATURE,0);
WriteRegister(PCCARD_MEM_SECTOR,uBlocks);
WriteRegister(PCCARD_MEM_LOWLBA,(uStBlock&0x00ff));
WriteRegister(PCCARD_MEM_MIDLBA,((uStBlock>>8)&0x00ff));
WriteRegister(PCCARD_MEM_HIGHLBA,((uStBlock>>16)&0x00ff));
WriteRegister(PCCARD_MEM_DEVICE,((uStBlock>>24)&0x000f) | 0xe0); //LBA enabled, Drive 0
WriteRegister(PCCARD_MEM_COMMAND, WRITESECTOR);
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x58) ;
for (u32 j=0; j<uBlocks; j++)
{
for (u32 i=0; i<512/2; i++)
{
#if 0 // both case are OK
PutDataToDevice(*uCurrentAddr);
#else
Outp16(PCCARD_MEM_BASE+0x400+i*2, *uCurrentAddr);
#endif
uCurrentAddr++;
}
do
{
ReadRegister(PCCARD_MEM_STATUS, temp);
}
while(temp != 0x50 && temp != 0x58) ;
}
return true;
}
bool PCCARD::StartReadingBlocks(u32 uStBlock, u32 uBlocks, u32 uBufAddr)
{
return false;
}
bool PCCARD::StartWritingBlocks(u32 uStBlock, u32 uBlocks, u32 uBufAddr)
{
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -