📄 ide.c
字号:
/* Device Control Register
+-----+----------+----------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+----------------------------------------------------------+
| 7 | Reserved | |
| 6 | Reserved | |
| 5 | Reserved | |
| 4 | Reserved | |
| 3 | 1 | Always set. |
| 2 | SRST | Host Software Reset bit. When this bit is set the drive |
| | | is held reset. If two drives are daisy chained on the |
| | | interface, this bit resets both drives simultaneously. |
| | | |
| 1 | nIEN | Drive Interrupt Enable bit. The enable bit for the drive |
| | | interrupt to the host. When nIEN is 0 or the drive is |
| | | selected the host interrupt signal INTRQ is enabled |
| | | through a tri state buffer to the host. When nIEN is 1 |
| | | or the drive is not selected the host interrupt signal |
| | | INTRQ is in a hig himpedance state regardless of the |
| | | presence or absence of a pending interrupt. |
| | | |
| 0 | 0 | Always clear. |
+-----+----------+----------------------------------------------------------+
*/
#define nIEN 0x2
#define SRST 0x4
/* Driver Address Register
+-----+----------+------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+------------------------------------------------------+
| 7 | HiZ | This bit is in high impedance when read. |
| 6 | nWTG | Write Gate bit. When a write to the hard drive is in |
| | | progress, nWTG is 0 |
| 5 | nHS3 | Negated MSB of head number |
| 4 | nHS2 | |
| 3 | nHS1 | |
| 2 | nHS0 | Negated LSB of head number. |
| 1 | nDS1 | Drive 1 Select bit. When 0, Drive 1 is selected. |
| 0 | nDS0 | Drive 0 Select bit. When 0, Drive 0 is selected. |
+-----+----------+------------------------------------------------------+
*/
#define nDS0 0x1
#define nDS1 0x2
#define nHS0 0x4
#define nHS1 0x8
#define nHS2 0x10
#define nHS3 0x20
#define nWTG 0x40
#define HiZ 0x80
/*
* error string.
*/
static const char *ErrString[10] =
{
"Primary Drive: No error detected.\n",
"Primary Drive: Formatter device error.\n",
"Primary Drive: Sector buffer error.\n",
"Primary Drive: ECC circuitry error.\n",
"Primary Drive: Controller microprocessor error.\n",
"Slave Drive: No error detected.\n",
"Slave Drive: Formatter device error.\n",
"Slave Drive: Sector buffer error.\n",
"Slave Drive: ECC circuitry error.\n",
"Slave Drive: Controller microprocessor error.\n"
};
/*
* status string.
*/
static const char *StaString[8] =
{
"Data address mark not found after correct ID field found.\n",
"Track 0 not found during execution of Recalibrate command.\n",
"Command aborted due to drive status error or invalid command.\n",
"",
"Requested sector's ID field not found.\n",
"",
"Uncorrectable data error encountered.\n",
"Bad block mark detected in the requested sector's ID field.\n"
};
/*
* name: ReadAlternateStatus()
* parameter: void
* return: unsigned char
* indicate alternate status.
* description: read alternate status register.
*/
static inline unsigned char ReadAlternateStatus(void)
{
return *(volatile unsigned char *)(ADDR_CONTROL | ALTERN_STATUS);
}
/*
* name: ReadDriveAddress()
* parameter: void
* return: unsigned char
* drive select and head select addresses for
* the drive currently selected.
* description: read drive addresss register.
*/
static inline unsigned char ReadDriveAddress(void)
{
return *(volatile unsigned char *)(ADDR_CONTROL | DRIVE_ADDRESS);
}
/*
* name: WriteDeviceControl()
* parameter: conttrl ---input, control bits.
* return: void
* description: write device control register.
*/
static inline void WriteDeviceControl(unsigned char control)
{
*(volatile unsigned char *)(ADDR_CONTROL | DEVICE_CONTROL) = (control | 0x08);
}
/*
* name: ReadData()
* parameter: void
* return: unsigned short
* 16bits data.
* description: read data port register.
*/
static inline unsigned short ReadData(void)
{
return *(volatile unsigned short *)(ADDR_COMMAND | DATA_PORT);
}
/*
* name: WriteData()
* parameter: data ---input, 16bits data
* return: void
* description: write data port register.
*/
static inline void WriteData(unsigned short data)
{
*(volatile unsigned short *)(ADDR_COMMAND | DATA_PORT) = data;
}
/*
* name: ReadError()
* parameter: void
* return: unsigned char
* error status.
* description: read error register.
*/
static inline unsigned char ReadError(void)
{
return *(volatile unsigned char *)(ADDR_COMMAND | ERROR_REGISTER);
}
/*
* name: WritePrecompensation()
* parameter: precomp ---input, precompensation value.
* return: void
* description: write precompensation register.
*/
static inline void WritePrecompensation(unsigned char precomp)
{
*(volatile unsigned char *)(ADDR_COMMAND | PRECOMP) = precomp;
}
/*
* name: ReadSectorCount()
* parameter: void
* return: unsigned char
* number of sectors to be to be transferred.
* description: read sector count register.
*/
static inline unsigned char ReadSectorCount(void)
{
return *(volatile unsigned char *)(ADDR_COMMAND | SECTOR_COUNT);
}
/*
* name: WriteSectorCount()
* parameter: count ---input, sector count
* return: void
* description: write sector count register
*/
static inline unsigned char WriteSectorCount(unsigned char count)
{
*(volatile unsigned char *)(ADDR_COMMAND | SECTOR_COUNT) = count;
}
/*
* name: ReadSectorNumber()
* parameter: void
* return: unsigned char
* number of the first sector to be accessed.
* description: read sector number register.
*/
static inline unsigned char ReadSectorNumber()
{
return *(volatile unsigned char *)(ADDR_COMMAND | SECTOR_NUMBER);
}
/*
* name: WriteSectorNumber()
* parameter: number ---input, first sector number.
* return: void
* description: write sector number register.
*/
static inline void WriteSectorNumber(unsigned char number)
{
*(volatile unsigned char *)(ADDR_COMMAND | SECTOR_NUMBER) = number;
}
/*
* name: ReadCylinder()
* parameter: void
* return: unsigned short
* cylinder address.
* description: read cylinder low and high register.
*/
static inline unsigned short ReadCylinder(void)
{
return (unsigned short)
((*(volatile unsigned char *)(ADDR_COMMAND | CYLINDER_LOW)) |
((*(volatile unsigned char *)(ADDR_COMMAND | CYLINDER_HIGH)) << 8));
}
/*
* name: WriteCylinder()
* parameter: cylinder ---input, cylinder number.
* return: void
* description: write cylinder low and high register.
*/
static inline unsigned short WriteCylinder(unsigned short cylinder)
{
*(volatile unsigned char *)(ADDR_COMMAND | CYLINDER_LOW) = (unsigned char)cylinder;
*(volatile unsigned char *)(ADDR_COMMAND | CYLINDER_HIGH) = (unsigned char)(cylinder >> 8);
}
/*
* name: ReadDriveHead()
* parameter: void
* return: unsigned char
* contains the drive ID number and its head number for any disk access.
* description: read drive/head register
*/
static inline unsigned char ReadDriveHead(void)
{
return *(volatile unsigned char *)(ADDR_COMMAND | DRIVE_HEAD);
}
/*
* name: WriteDriveHead()
* parameter: dh ---input, drive id & its head number.
* return: void
* description: write drive/head register
*/
static inline void WriteDriveHead(unsigned char drvhd)
{
*(volatile unsigned char *)(ADDR_COMMAND | DRIVE_HEAD) = drvhd | (REV5|REV7);
}
/*
* name: ReadStatus()
* parameter: void
* return: unsigned char
* contains information about the status of the drive and controller.
* description: read status register.
*/
static inline unsigned char ReadStatus(void)
{
return *(volatile unsigned char *)(ADDR_COMMAND | STATUS);
}
/*
* name: WriteCommand()
* parameter: command ---input, host request command.
* return: void
* description: write command register.
*/
static inline void WriteCommand(unsigned char command)
{
*(volatile unsigned char *)(ADDR_COMMAND | COMMAND) = command;
}
/*
* name: WaitForNoBUSY()
* parameter: void
* return: status code.
* description: waiting, till no busy.
*/
static unsigned int WaitForNoBUSY(void)
{
unsigned char status;
do
{
status = ReadStatus();
if(status & ERROR)
return ReadError();
} while(status & BUSY);
return ERR_NOERR;
}
/*
* name: WaitForNoBUSY_igError()
* parameter: void
* return: status code.
* description: waiting and ignore error, till no busy.
*/
static unsigned int WaitForNoBUSY_igError(void)
{
unsigned char status;
do
{
status = ReadStatus();
/*
if(status & ERROR)
return ReadError();
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -