3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 /////////////////////////////////////////////////////////////////////////////////////////////
31 /////////////////////////////////////////////////////////////////////////////////////////////
33 VOID
DiskError(PUCHAR ErrorString
)
35 UCHAR ErrorCodeString
[80];
37 sprintf(ErrorCodeString
, "%s\nError Code: 0x%x", ErrorString
, BiosInt13GetLastErrorCode());
39 DbgPrint((DPRINT_DISK
, "%s\n", ErrorCodeString
));
41 UiMessageBox(ErrorCodeString
);
44 BOOL
DiskReadLogicalSectors(U32 DriveNumber
, U32 SectorNumber
, U32 SectorCount
, PVOID Buffer
)
49 GEOMETRY DriveGeometry
;
50 U32 NumberOfSectorsToRead
;
52 DbgPrint((DPRINT_DISK
, "ReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %d SectorCount: %d Buffer: 0x%x\n", DriveNumber
, SectorNumber
, SectorCount
, Buffer
));
55 // Check to see if it is a fixed disk drive
56 // If so then check to see if Int13 extensions work
57 // If they do then use them, otherwise default back to BIOS calls
59 if ((DriveNumber
>= 0x80) && (IsSetupLdr
|| BiosInt13ExtensionsSupported(DriveNumber
)))
61 DbgPrint((DPRINT_DISK
, "Using Int 13 Extensions for read. BiosInt13ExtensionsSupported(%d) = %s\n", DriveNumber
, BiosInt13ExtensionsSupported(DriveNumber
) ? "TRUE" : "FALSE"));
64 // LBA is easy, nothing to calculate
67 if (!BiosInt13ReadExtended(DriveNumber
, SectorNumber
, SectorCount
, Buffer
))
69 DiskError("Disk read error.");
76 // Get the drive geometry
78 if (!DiskGetDriveGeometry(DriveNumber
, &DriveGeometry
))
87 // Calculate the physical disk offsets
89 PhysicalSector
= 1 + (SectorNumber
% DriveGeometry
.Sectors
);
90 PhysicalHead
= (SectorNumber
/ DriveGeometry
.Sectors
) % DriveGeometry
.Heads
;
91 PhysicalTrack
= (SectorNumber
/ DriveGeometry
.Sectors
) / DriveGeometry
.Heads
;
94 // Calculate how many sectors we are supposed to read
96 if (PhysicalSector
> 1)
98 if (SectorCount
>= (DriveGeometry
.Sectors
- (PhysicalSector
- 1)))
99 NumberOfSectorsToRead
= (DriveGeometry
.Sectors
- (PhysicalSector
- 1));
101 NumberOfSectorsToRead
= SectorCount
;
105 if (SectorCount
>= DriveGeometry
.Sectors
)
106 NumberOfSectorsToRead
= DriveGeometry
.Sectors
;
108 NumberOfSectorsToRead
= SectorCount
;
111 DbgPrint((DPRINT_DISK
, "Calling BiosInt13Read() with PhysicalHead: %d\n", PhysicalHead
));
112 DbgPrint((DPRINT_DISK
, "Calling BiosInt13Read() with PhysicalTrack: %d\n", PhysicalTrack
));
113 DbgPrint((DPRINT_DISK
, "Calling BiosInt13Read() with PhysicalSector: %d\n", PhysicalSector
));
114 DbgPrint((DPRINT_DISK
, "Calling BiosInt13Read() with NumberOfSectorsToRead: %d\n", NumberOfSectorsToRead
));
117 // Make sure the read is within the geometry boundaries
119 if ((PhysicalHead
>= DriveGeometry
.Heads
) ||
120 (PhysicalTrack
>= DriveGeometry
.Cylinders
) ||
121 ((NumberOfSectorsToRead
+ PhysicalSector
) > (DriveGeometry
.Sectors
+ 1)) ||
122 (PhysicalSector
> DriveGeometry
.Sectors
))
124 DiskError("Disk read exceeds drive geometry limits.");
131 if (!BiosInt13Read(DriveNumber
, PhysicalHead
, PhysicalTrack
, PhysicalSector
, NumberOfSectorsToRead
, Buffer
))
133 DiskError("Disk read error.");
137 Buffer
+= (NumberOfSectorsToRead
* DriveGeometry
.BytesPerSector
);
138 SectorCount
-= NumberOfSectorsToRead
;
139 SectorNumber
+= NumberOfSectorsToRead
;