📄 ide_disk.c
字号:
//DelayBy(1000);
}
}
static void WriteSectors(unsigned int drive, unsigned short *buffer,
unsigned int NumberOfSectors)
{
int iCount, j, DataReg;
unsigned short data16;
while (drivebusy(drive));
outpw(drive_tab[drive].xHD_STATUS, WIN_WRITE);
DataReg = drive_tab[drive].xHD_DATA;
for (j=0; j < NumberOfSectors; j++)
{
if (!testAltSTAT(drive, READY_STAT | SEEK_STAT | DRQ_STAT))
break;
#ifdef __DSC_CFA__
UpdateMCR(1 << 5, 1 << 4);
#endif
for (iCount=SECTOR_SHORTS/2; iCount > 0; iCount--)
{
data16 = CvtByteOrder16(*buffer++);
outph(DataReg, data16);
data16 = CvtByteOrder16(*buffer++);
outph(DataReg, data16);
}
#ifdef __DSC_CFA__
UpdateMCR(3 << 4, 0);
#endif
//DelayBy(1000);
}
}
/* Read Hard Drive Identify Structure */
static int GetIdentifyStructure (int drive, struct hd_driveid *hd_id) {
unsigned short *shptr;
int i;
reset_IDE_DRIVE(drive);
outpw(drive_tab[drive].xHD_STATUS, WIN_IDENTIFY);
while (drivebusy(drive));
shptr = (unsigned short *)hd_id;
#ifdef __DSC_CFA__
UpdateMCR(1 << 5, 1 << 4);
#endif
for (i=0; i < SECTOR_SHORTS; i++)
*shptr++ = inph(drive_tab[drive].xHD_DATA);
#ifdef __DSC_CFA__
UpdateMCR(3 << 4, 0);
#endif
return 0;
}
/*
Initialize Drive it have to be always the first function.
return: at ok 0
at error <> 0
*/
static int InitializeDrive(int drive, struct hd_driveid *hd_id) {
unsigned long size;
if (-1 == GetIdentifyStructure (drive, hd_id))
return -1;
_hd_ident[drive].initialized = 1;
_hd_ident[drive].heads = (unsigned char)hd_id->heads;
_hd_ident[drive].sectors = (unsigned char)hd_id->sectors;
_hd_ident[drive].cylinders = hd_id->cyls;
_hd_ident[drive].start = 0;
if (hd_id->capability & LBA_capability) {
_hd_ident[drive].lba = 2;
size = CvtByteOrder32(hd_id->lba_capacity);
}
else {
_hd_ident[drive].lba = 0;
size = _hd_ident[drive].heads * _hd_ident[drive].sectors \
* _hd_ident[drive].cylinders;
}
_hd_ident[drive].tot_sectors = size;
return 0;
}
/*
Read Partition Sector
drive: 0..0
return value: at ok 0
at error -1
*/
static int ReadPartitionSector(int drive, struct PART_SECT *p_sect) {
/* read partiotion sector */
return r_w_Disk(drive, 0, 1, (unsigned short*)p_sect, 1);
}
/*
GetPartitionData (int drive, struct PART_SECT *p_sect)
reads partition data, convert to big endian and initialize _hd_ident
structure.
*/
static int GetPartitionData(int drive, struct PART_SECT *p_sect) {
int i;
/* partiotion sector */
if (ReadPartitionSector(drive, p_sect))
return -1;
for (i=0; i < 4; i++) {
if (p_sect->part_tab[i].partstatus == 0x80) {
_hd_ident[drive].activ_part = i;
}
}
if (CvtByteOrder16(p_sect->id_code) != 0xAA55) {
fprintf(stderr, "Partition has not valid identifier (0xAA55).\n");
return -2;
}
else {
for (i=0; i < 4; i++) {
_hd_ident[drive].part_tab[i].partstatus = p_sect->part_tab[i].partstatus;
_hd_ident[drive].part_tab[i].RW_head_part_start = p_sect->part_tab[i].RW_head_part_start;
_hd_ident[drive].part_tab[i].sect_part_start = p_sect->part_tab[i].sect_part_start;
_hd_ident[drive].part_tab[i].cyl_part_start = p_sect->part_tab[i].cyl_part_start;
_hd_ident[drive].part_tab[i].sys_ind = p_sect->part_tab[i].sys_ind;
_hd_ident[drive].part_tab[i].RW_head_part_end = p_sect->part_tab[i].RW_head_part_end;
_hd_ident[drive].part_tab[i].sect_part_end = p_sect->part_tab[i].sect_part_end;
_hd_ident[drive].part_tab[i].cyl_part_end = p_sect->part_tab[i].cyl_part_end;
_hd_ident[drive].part_tab[i].dist = CvtByteOrder32(p_sect->part_tab[i].dist);
_hd_ident[drive].part_tab[i].count_sect_part = CvtByteOrder32(p_sect->part_tab[i].count_sect_part);
}
}
return 0;
}
#ifdef __DSC_CFA__
int installDrive(int drive) {
int result;
hardware_drv.cs1 = (1 << 31) | (1 << 12);
hardware_drv.cs2 = (1 << 31) | (1 << 12) | 8;
hardware_drv.addroffs = 0;
hardware_drv.timeing = 0;
hardware_drv.word_access = (1<<13);
hardware_drv.irq = 3;
hardware_drv.drive = drive;
Outpw(REG0SEL, 1); /* enable PCMCIA */
Outpw(REG2SEL, Inpw(REG2SEL) & ~(1<<2)); /* enable PCMCIA Wait Pin */
UpdateBCR( (0x05 << 24) | 0x0a, (0x0a<<24) | 5);
// mem2: 1 setup, 6 access, 2 hold
UpdateMCR( 3 << 4, 1 << 26);
// mem2: 8 bit, wait pin enable
result = * (char *) 0x80001007; /* status register */
_init_hardware_tab( &hardware_drv, 1 << 13);
result = reset_IDE_DRIVE(hardware_drv.drive);
return result;
}
#else
#define SETUP_2 (1<<8)
#define ACCESS_6 (2<<5)
#define HOLD_2 (1<<3)
static int installDrive(int drive) {
hardware_drv.drive = drive;
hardware_drv.cs1 = 2 << 24;
hardware_drv.cs2 = 1 << 24;
hardware_drv.addroffs = 13;
hardware_drv.timeing = SETUP_2 | ACCESS_6 | HOLD_2;
hardware_drv.word_access = 0;
// hardware_drv.timeing = 0x3F8;
hardware_drv.irq = 3;
_init_hardware_tab( &hardware_drv, 0);
return reset_IDE_DRIVE(hardware_drv.drive);
}
#endif
/*
drive: 0
partnum: 0..3
return value: at ok 0, boot sector contents int boot_sect
at error -1
*/
int ReadBOOTSector(struct BOOT_SECT * boot_sect, int drive, int partnum /* 0..3 */) {
if (_hd_ident[drive].initialized)
r_w_Disk(drive, _hd_ident[drive].part_tab[partnum].dist, 1, (unsigned short*)boot_sect, READ_SEC);
else
return -1; /* partition sector is never read */
return 0;
}
/*
drive: 0
partnum: 0..3
return value: at ok 0, boot sector contents int boot_sect
at error -1
*/
int WriteBOOTSector(int drive, struct BOOT_SECT * boot_sect, int partnum /* 0..3 */) {
if (_hd_ident[drive].initialized)
r_w_Disk(drive, _hd_ident[drive].part_tab[partnum].dist, 1, (unsigned short*)boot_sect, 0);
else
return -1; /* partition sector is never read */
return 0;
}
int testFAT(struct BOOT_SECT * boot_sect) {
int fat_mode;
if (!memicmp(boot_sect->filesys, "FAT16", 5))
fat_mode = 16;
else
if (!memicmp(boot_sect->filesys, "FAT12", 5))
fat_mode = 12;
else
fat_mode = -1; /* error condition */
return fat_mode;
}
static int GetBootData(int drive, struct BOOT_SECT * boot_sect)
{
int partnum;
int found=0;
struct msdos_b_sect *tmp;
unsigned long MaxCluster;
for (partnum=0; partnum < 4; partnum++) {
unsigned long tmp1, tmp2;
tmp1 = _hd_ident[drive].part_tab[partnum].count_sect_part;
tmp2 = _hd_ident[drive].part_tab[partnum].sys_ind;
if ( tmp1 && ( (tmp2 == 1) || (tmp2 == 4) || (tmp2 == 6))) {
if (ReadBOOTSector(boot_sect, drive, partnum))
return -1;
tmp = malloc(sizeof(struct msdos_b_sect));
if (tmp) {
tmp->sectPerFat = CvtByteOrder16(boot_sect->sectPerFat);
tmp->FatSystem = (tmp2 == 1) ? 12 : 16;
tmp->bytesPerSector = CvtByteOrder16(boot_sect->bytesPerSector);
tmp->sectPerCluster = boot_sect->sectPerCluster;
tmp->resSectors = CvtByteOrder16(boot_sect->resSectors);
tmp->nFats = boot_sect->nFats;
tmp->nRootDir = CvtByteOrder16(boot_sect->nRootDir);
tmp->nSectors = CvtByteOrder16(boot_sect->nSectors);
tmp->nSectorHuge = CvtByteOrder32(boot_sect->nSectorHuge);
tmp->nHidden = CvtByteOrder32(boot_sect->nHidden);
tmp->extBoot = boot_sect->extBoot;
tmp->volid = CvtByteOrder32(boot_sect->volid);
MaxCluster = tmp->nSectors? tmp->nSectors:tmp->nSectorHuge;
MaxCluster = (MaxCluster-tmp->resSectors-
tmp->nFats*tmp->sectPerFat-
tmp->nRootDir/(SECTOR_SIZE/sizeof(struct directory)))/
tmp->sectPerCluster+1;
tmp->MaxCluster = MaxCluster;
tmp->FatStart = malloc(tmp->bytesPerSector*tmp->sectPerFat);// *tmp->nFats);
r_w_Disk(drive, tmp->nHidden + tmp->resSectors, tmp->sectPerFat /* *tmp->nFats*/, tmp->FatStart, READ);
tmp->RootDirStart = tmp->nHidden + tmp->resSectors + tmp->nFats * tmp->sectPerFat;
tmp->nDir = tmp->nRootDir / (tmp->bytesPerSector >> 5);
tmp->DataStart = tmp->nDir + tmp->RootDirStart;
memcpy(tmp->filesys, boot_sect->filesys, 8);
_hd_ident[drive].bootptr[partnum] = tmp;
}
else
return -1;
found = 1;
}
}
return found ? 0 : -1;
}
/*
Drive Numerierung
0 Channel 0 Master
1 Channel 0 Slave
2 Channel 1 Master
3 Channel 1 Slave
*/
int _install_ATA_sys(int channel, int drive, struct hd_driveid *id,
struct PART_SECT *p_sect,
struct BOOT_SECT *boot_sect)
{
int dist, pdrive;
if ((channel < MAX_CHANNEL_NUM) && (drive < 2) && (0 <= drive)) {
pdrive = (channel << 1) + drive;
if (installDrive(pdrive))
return -1;
if (InitializeDrive(pdrive, id)) /* initialize and identify hard disk */
return -2;
if (GetPartitionData(pdrive, p_sect))
return -3;
if (GetBootData(drive, boot_sect))
return -4;
}
else
return -5;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -