?? ide_io.h
字號:
#define IDE_INTERRUPT FALSE
//IDE basic I/O
#define IDE_ADDR_CTRL 0x00
#define IDE_ADDR_CMD 0x10
#define IDE_IO_RE P3_7
#define IDE_IO_WE P3_6
#define IDE_IO_CS0 0x80 //P4_2
#define IDE_IO_CS1 0x40 //P4_3
#define IDE_IO_DA0 0x01 //P4_1
#define IDE_IO_DA1 0x02 //P4_4
#define IDE_IO_DA2 0x04 //P4_0
#define IDE_IO_RESET P5_0
#define IDE_ADDR_BASE 0x8000
#define IDE_ADDR_CTRL 0x1000
#define IDE_ADDR_CMD 0x0000
//IDE設備控制寄存器地址
#define IDE_ADDR_CTRL_STATUS IDE_ADDR_BASE + IDE_ADDR_CTRL + IDE_IO_DA2 + IDE_IO_DA1
#define IDE_ADDR_CTRL_CONTROL IDE_ADDR_BASE + IDE_ADDR_CTRL + IDE_IO_DA2 + IDE_IO_DA1
//IDE設備命令寄存器地址
#define IDE_ADDR_CMD_DATA IDE_ADDR_BASE + IDE_ADDR_CMD
#define IDE_ADDR_CMD_ERROR IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA0
#define IDE_ADDR_CMD_SECCNT IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA1
#define IDE_ADDR_CMD_LBA0 IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA1 + IDE_IO_DA0
#define IDE_ADDR_CMD_LBA1 IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2
#define IDE_ADDR_CMD_LBA2 IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2 + IDE_IO_DA0
#define IDE_ADDR_CMD_LBA3 IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2 + IDE_IO_DA1
#define IDE_ADDR_CMD_STATUS IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2 + IDE_IO_DA1 + IDE_IO_DA0
#define IDE_ADDR_CMD_COMMAND IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2 + IDE_IO_DA1 + IDE_IO_DA0
#define IDE_ADDR_CMD_SECTOR IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA1 + IDE_IO_DA0
#define IDE_ADDR_CMD_CYLMSB IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2
#define IDE_ADDR_CMD_CYLLSB IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2 + IDE_IO_DA0
#define IDE_ADDR_CMD_HEAD IDE_ADDR_BASE + IDE_ADDR_CMD + IDE_IO_DA2 + IDE_IO_DA1
//IDE data port
#define IDE_PORT_DATLSB ACC
#define IDE_PORT_DATMSB DAT16H
//IDE status bit
#define IDE_STATUS_BSY 0x80
#define IDE_STATUS_DRDY 0x40
#define IDE_STATUS_DF 0x20
#define IDE_STATUS_DSC 0x10
#define IDE_STATUS_DRQ 0x08
#define IDE_STATUS_CORR 0x04
#define IDE_STATUS_IDX 0x02
#define IDE_STATUS_ERR 0x01
//IDE error bit
#define IDE_ERR_UNC 0x40
#define IDE_ERR_MC 0x20
#define IDE_ERR_IDNF 0x10
#define IDE_ERR_MCR 0x08
#define IDE_ERR_ABRT 0x04
#define IDE_ERR_TK0NF 0x02
#define IDE_ERR_AMNF 0x01
//IDE control bit
#define IDE_CTRL_SRST 0x04
#define IDE_CTRL_nIEN 0x02
#define IDE_CTRL_LBA 0x40
#define IDE_CTRL_DEV 0x10
//IDE device operate mode
#define IDE_MODE_DEVICE0_LBA 0xE0
#define IDE_MODE_DEVICE0_CHS 0xA0
#define IDE_MODE_DEVICE1_LBA 0xF0
#define IDE_MODE_DEVICE1_CHS 0xB0
//IDE command
#define IDE_CMD_RECAL 0x10
#define IDE_CMD_READ 0x20
#define IDE_CMD_WRITE 0x30
#define IDE_CMD_DEVDIAG 0x90
#define IDE_CMD_INIT 0x91
#define IDE_CMD_SPINDOWN 0xE0
#define IDE_CMD_SPINUP 0xE1
#define IDE_CMD_IDENTIFYDEV 0xEC
#define IDE_DEVICE0 0
#define IDE_DEVICE1 1
#define IDE_WAIT TRUE
#define IDE_NOWAIT FALSE
#define IDE_RESET_HARDWARE 0
#define IDE_RESET_SOFTWARE 1
//IDE function return value
#define IDE_SUCCESSFUL 0x00
#define IDE_ERROR_RESET 0x01
#define IDE_ERROR_DIAGNOSTIC 0x01
#define IDE_ERROR_BUSY 0x10
#define IDE_ERROR_NOREADY 0x11
#define IDE_ERROR_DEVFAULT 0x12
#define IDE_ERROR_NODATA 0x13
#define IDE_READ_LSB(addr,dat) dat=*((BYTE xdata *)addr)
#define IDE_READ_MSB(addr) SET_BIT_6(AUXR),*((BYTE xdata *)addr),CLEAR_BIT_6(AUXR),IDE_PORT_DATMSB
#define IDE_WRITE_LSB(addr,dat) *((BYTE xdata *)addr)=dat
#define IDE_WRITE_MSB(addr,dat) IDE_PORT_DATMSB=dat,EXT16=1,*((BYTE xdata *)addr|(dat<<8)),EXT16=0
#define IDE_READ_WORD(addr,lo,hi) SET_BIT_6(AUXR);lo=*((BYTE xdata *)addr);hi=IDE_PORT_DATMSB;CLEAR_BIT_6(AUXR)
#define IDE_WRITE_WORD(addr,lo,hi) SET_BIT_6(AUXR);IDE_PORT_DATMSB=hi;*((BYTE xdata *)addr)=lo;CLEAR_BIT_6(AUXR)
#define DRIVER_TYPE_HDD 0x00 //硬盤
#define DRIVER_TYPE_CDROM 0x01 //光驅
#define DRIVER_TYPE_FLASH 0x02 //FLASH
#define IDEReadSector(X) IDE.CurrentSector=X; _IDEReadSector()
#define IDEWriteSector(X) IDE.CurrentSector=X; _IDEWriteSector()
struct IDEStr
{
BYTE TotalDrivers; //驅動器數量
BYTE CurrentDriver; //當前驅動器
BYTE DriverType; //驅動器類型
WORD BytesPerSec; //每扇區字節數 512
DWORD CurrentSector; //當前扇區號
}IDE;
struct HDDStr //硬盤介質參數表
{
BYTE TotalPartitions; //分區數
BYTE CurrentPartition; //當前分區
}HDD;
BYTE IDEInit(void);
BYTE IDEReset(BYTE bRestMode);
int IDE_Busy();
BOOL IDEStatus(BYTE flag,BYTE wait,BYTE logic,WORD timeout);
void IDESpinUP(); //硬盤啟動
void IDESpinDOWN(); //硬盤停止
BYTE _IDEReadSector(); //讀一個扇區
BYTE _IDEWriteSector(); //寫一個扇區
BYTE IDEInit(void)
{
IDE.TotalDrivers=1;
IDE.CurrentDriver=1;
IDE.DriverType=DRIVER_TYPE_HDD;
IDE.BytesPerSec=512;
IDE_WRITE_LSB(IDE_ADDR_CMD_HEAD, 0xE0); //SELECT MASTER HDD FOR LBA MODE
IDE_WRITE_LSB(IDE_ADDR_CTRL_CONTROL,0x02);
IDE_WRITE_LSB(IDE_ADDR_CMD_COMMAND,0x10);
return(0);
/* if (IDEReset(IDE_RESET_HARDWARE)) return(IDE_ERROR_RESET); //IDE device reset
if (!IDEStatus(IDE_STATUS_DRDY,IDE_WAIT,TRUE,255)) return(IDE_ERROR_NOREADY);
#if (IDE_INTERRUPT)
IDE_WRITE_LSB(IDE_ADDR_CTRL_CONTROL,0x00); //enable interrupt mode
#else
IDE_WRITE_LSB(IDE_ADDR_CTRL_CONTROL,IDE_CTRL_nIEN); //disable interrupt mode
#endif
//check device 0 (MASTER)
if (IDEIdentifyDevice(IDE_DEVICE0)==IDE_SUCCESSFUL)
{
}
else printf("Device 0 error!\n");
//check device 1 (SLAVE)
if (IDEIdentifyDevice(IDE_DEVICE1)==IDE_SUCCESSFUL)
{
}
else printf("Device 1 error!\n");
return(IDE_SUCCESSFUL);
*/
}
BYTE IDEReset(BYTE bRestMode)
{
register BYTE i;
if (bRestMode==IDE_RESET_HARDWARE) //hardware reset
{
IDE_IO_RESET=0;
for (i=0;i<10;i++);
IDE_IO_RESET=1;
}
else if (bRestMode==IDE_RESET_SOFTWARE) //software reset
{
#if (IDE_INTERRUPT)
IDE_WRITE_LSB(IDE_ADDR_CTRL_CONTROL,IDE_CTRL_SRST); //enable interrupt mode
#else
IDE_WRITE_LSB(IDE_ADDR_CTRL_CONTROL,IDE_CTRL_SRST|IDE_CTRL_nIEN); //disable interrupt mode
#endif
}
if (IDEStatus(IDE_STATUS_BSY,IDE_WAIT,FALSE,1000)) //wait for device reset
return(IDE_SUCCESSFUL);
else
return(IDE_ERROR_RESET);
}
BOOL IDEStatus(BYTE flag,BYTE wait,BYTE logic,WORD timeout)
{
register BYTE i,status;
IDE_READ_LSB(IDE_ADDR_CTRL_STATUS,status);
if (wait)
{
while((BOOL)((status&flag))^logic)
{
for(i=0;i<255;i++); timeout--;
if (timeout==0) return(FALSE);
IDE_READ_LSB(IDE_ADDR_CTRL_STATUS,status);
}
return(TRUE);
}
else
return(status&flag|0);
}
int IDE_Busy()
{
register int res,i = 0,j;
do
{
IDE_READ_LSB(IDE_ADDR_CTRL_STATUS,res);
for(j=0;j<100;j++);
if(i++>5000) return -1;
}while(res&0x80);
return res;
}
void IDESpinUp(void)
{
IDE_WRITE_LSB(IDE_ADDR_CMD_COMMAND,IDE_CMD_SPINUP);
IDE_Busy();
}
void IDESpinDown(void)
{
IDE_Busy();
IDE_WRITE_LSB(IDE_ADDR_CMD_COMMAND,IDE_CMD_SPINDOWN);
IDE_Busy();
}
BYTE _IDEReadSector(void)
{
register BYTE *sector;
register WORD i;
sector=(BYTE *)&IDE.CurrentSector;
if (!IDEStatus(IDE_STATUS_BSY,IDE_WAIT,FALSE,255)) {printf("BSY error\n"); return(0);}
if (!IDEStatus(IDE_STATUS_DRDY,IDE_WAIT,TRUE,255)) {printf("DRDY error\n"); return(0);}
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA0,sector[3]);
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA1,sector[2]);
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA2,sector[1]);
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA3,0xe0|(sector[0]&0x0f));
IDE_WRITE_LSB(IDE_ADDR_CMD_SECCNT,0x01);
IDE_WRITE_LSB(IDE_ADDR_CMD_COMMAND,IDE_CMD_READ);
if (!IDEStatus(IDE_STATUS_BSY,IDE_WAIT,FALSE,255)) {printf("BSY error\n"); return(0);}
if (!IDEStatus(IDE_STATUS_DRQ,IDE_WAIT,TRUE,255)) {printf("DRQ error\n"); return(0);}
for(i=0;i<512;)
{
IDE_READ_WORD(IDE_ADDR_CMD_DATA,DiskBuffer[i++],DiskBuffer[i++]);
}
return(0);
}
BYTE _IDEWriteSector(void)
{
register BYTE *sector;
register WORD i;
sector=(BYTE *)&IDE.CurrentSector;
if (!IDEStatus(IDE_STATUS_BSY,IDE_WAIT,FALSE,255)) {printf("BSY error\n"); return(0);}
if (!IDEStatus(IDE_STATUS_DRDY,IDE_WAIT,TRUE,255)) {printf("DRDY error\n"); return(0);}
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA0,sector[3]);
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA1,sector[2]);
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA2,sector[1]);
IDE_WRITE_LSB(IDE_ADDR_CMD_LBA3,0xe0|(sector[0]&0x0f));
IDE_WRITE_LSB(IDE_ADDR_CMD_SECCNT,0x01);
IDE_WRITE_LSB(IDE_ADDR_CMD_COMMAND,IDE_CMD_WRITE);
if (!IDEStatus(IDE_STATUS_BSY,IDE_WAIT,FALSE,255)) {printf("BSY error\n"); return(0);}
if (!IDEStatus(IDE_STATUS_DRQ,IDE_WAIT,TRUE,255)) {printf("DRQ error\n"); return(0);}
for(i=0;i<512;)
{
IDE_WRITE_WORD(IDE_ADDR_CMD_DATA,DiskBuffer[i++],DiskBuffer[i++]);
}
return(0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -