19#define MAX_DRIVES 0x100
44 case 0x00:
return "No error";
45 case 0x10:
return "Drive write protection error";
46 case 0x20:
return "DMA access across 64 kB boundary";
47 case 0x30:
return "End of cylinder";
48 case 0x40:
return "The drive name is invalid or the device have low health";
49 case 0x50:
return "Time out, data not written";
50 case 0x60:
return "Time out, drive not ready";
53 return "Illegal disk address";
55 return "Drive write protection error";
56 case 0x80:
return "Undefined error";
57 case 0x90:
return "Time out error";
58 case 0xA0:
return "CRC error in the ID section";
59 case 0xB0:
return "CRC error in the DATA section";
62 return "Seek failure";
64 return "No data (Sector not found)";
65 case 0xD0:
return "Bad cylinder";
66 case 0xE0:
return "No ID address mark was found";
67 case 0xF0:
return "No DATA address mark was found";
69 default:
return "Unknown error code";
76 CHAR ErrorCodeString[200];
81 RtlStringCbPrintfA(ErrorCodeString,
sizeof(ErrorCodeString),
"%s\n\nError Code: 0x%lx\nError: %s",
84 ERR(
"%s\n", ErrorCodeString);
128 WARN(
"DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DiskDrive->DaUa);
130 Regs.
b.
al = DiskDrive->DaUa;
131 Int386(0x1B, &Regs, &Regs);
156 switch (BytesPerSector)
180 REGS RegsIn, RegsOut;
204 RegsIn.
b.
al = DiskDrive->DaUa;
207 RegsIn.
w.
cx = SectorNumber & 0xFFFF;
208 RegsIn.
w.
dx = (SectorNumber >> 16) & 0xFFFF;
213 for (RetryCount = 0; RetryCount < 3; RetryCount++)
215 Int386(0x1B, &RegsIn, &RegsOut);
228 DiskError(
"Disk Read Failed in LBA mode", RegsOut.
b.
ah);
229 ERR(
"Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
243 UCHAR PhysicalSector;
247 ULONG NumberOfSectorsToRead;
248 REGS RegsIn, RegsOut;
251 DriveGeometry = DiskDrive->Geometry;
268 if (PhysicalSector > 1)
279 if ((PhysicalHead >= DriveGeometry.
Heads) ||
280 (PhysicalTrack >= DriveGeometry.
Cylinders) ||
281 ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.
SectorsPerTrack + 1)) ||
284 DiskError(
"Disk read exceeds drive geometry limits.", 0);
306 RegsIn.
b.
al = DiskDrive->DaUa;
309 RegsIn.
b.
cl = PhysicalTrack & 0xFFFF;
311 RegsIn.
b.
dl = PhysicalSector;
312 RegsIn.
b.
dh = PhysicalHead;
333 RegsIn.
b.
al = DiskDrive->DaUa;
336 RegsIn.
w.
cx = PhysicalTrack & 0xFFFF;
337 RegsIn.
b.
dl = PhysicalSector;
338 RegsIn.
b.
dh = PhysicalHead;
344 for (RetryCount = 0; RetryCount < 3; RetryCount++)
346 Int386(0x1B, &RegsIn, &RegsOut);
354 else if (RegsOut.
b.
ah == 0x08)
369 DiskError(
"Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.
b.
ah);
370 ERR(
"Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
378 SectorNumber += NumberOfSectorsToRead;
389 REGS RegsIn, RegsOut;
390 UCHAR UnitAddress = DaUa & 0x0F;
396 if (DiskEquipment & (1 << UnitAddress))
414 Int386(0x1B, &RegsIn, &RegsOut);
417 DiskDrive->Initialized =
FALSE;
421 DiskDrive->Geometry.Cylinders = RegsOut.
w.
cx;
422 DiskDrive->Geometry.Heads = RegsOut.
b.
dh;
423 DiskDrive->Geometry.SectorsPerTrack = RegsOut.
b.
dl;
424 DiskDrive->Geometry.BytesPerSector = RegsOut.
w.
bx;
425 DiskDrive->LBASupported =
FALSE;
426 DiskDrive->IsRemovable =
FALSE;
429 else if (ScsiParameters)
436 DiskDrive->Geometry.Cylinders = 0xFFFF;
437 DiskDrive->Geometry.Heads = 0xFFFF;
438 DiskDrive->Geometry.SectorsPerTrack = 0xFFFF;
439 DiskDrive->Geometry.BytesPerSector = 2048;
441 DiskDrive->LBASupported =
TRUE;
442 DiskDrive->IsRemovable =
TRUE;
447 DiskDrive->Geometry.Cylinders = 0xFFFF;
448 DiskDrive->Geometry.Heads = 8;
449 DiskDrive->Geometry.SectorsPerTrack = 32;
450 DiskDrive->Geometry.BytesPerSector = 512;
452 DiskDrive->LBASupported =
TRUE;
453 DiskDrive->IsRemovable =
TRUE;
457 DiskDrive->Initialized =
FALSE;
463 DiskDrive->Initialized =
FALSE;
467 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
468 DiskDrive->Geometry.Heads *
469 DiskDrive->Geometry.SectorsPerTrack;
471 DiskDrive->DaUa = DaUa;
473 DiskDrive->Initialized =
TRUE;
475 TRACE(
"InitScsiDrive(0x%x) returned:\n"
478 "Sects/Track: 0x%x\n"
479 "Bytes/Sect : 0x%x\n",
481 DiskDrive->Geometry.Cylinders,
482 DiskDrive->Geometry.Heads,
483 DiskDrive->Geometry.SectorsPerTrack,
484 DiskDrive->Geometry.BytesPerSector);
499 DiskDrive->Geometry.Cylinders = DeviceUnit->
Cylinders;
500 DiskDrive->Geometry.Heads = DeviceUnit->
Heads;
502 DiskDrive->Geometry.BytesPerSector = DeviceUnit->
SectorSize;
505 DiskDrive->DaUa = 0xFF;
506 DiskDrive->IdeUnitNumber = UnitNumber;
508 DiskDrive->LBASupported =
TRUE;
509 DiskDrive->IsRemovable =
TRUE;
510 DiskDrive->Initialized =
TRUE;
512 TRACE(
"InitIdeDrive(0x%x) returned:\n"
515 "Sects/Track: 0x%x\n"
516 "Bytes/Sect : 0x%x\n",
518 DiskDrive->Geometry.Cylinders,
519 DiskDrive->Geometry.Heads,
520 DiskDrive->Geometry.SectorsPerTrack,
521 DiskDrive->Geometry.BytesPerSector);
526 DiskDrive->Initialized =
FALSE;
535 REGS RegsIn, RegsOut;
545 Int386(0x1B, &RegsIn, &RegsOut);
563 Int386(0x1B, &RegsIn, &RegsOut);
566 DiskDrive->Initialized =
FALSE;
570 DiskDrive->Geometry.Cylinders = RegsOut.
w.
cx;
571 DiskDrive->Geometry.Heads = RegsOut.
b.
dh;
572 DiskDrive->Geometry.SectorsPerTrack = RegsOut.
b.
dl;
573 DiskDrive->Geometry.BytesPerSector = RegsOut.
w.
bx;
575 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
576 DiskDrive->Geometry.Heads *
577 DiskDrive->Geometry.SectorsPerTrack;
579 DiskDrive->DaUa = DaUa;
581 DiskDrive->LBASupported =
FALSE;
582 DiskDrive->IsRemovable =
FALSE;
583 DiskDrive->Initialized =
TRUE;
585 TRACE(
"InitHardDrive(0x%x) returned:\n"
588 "Sects/Track: 0x%x\n"
589 "Bytes/Sect : 0x%x\n",
591 DiskDrive->Geometry.Cylinders,
592 DiskDrive->Geometry.Heads,
593 DiskDrive->Geometry.SectorsPerTrack,
594 DiskDrive->Geometry.BytesPerSector);
604 REGS RegsIn, RegsOut;
626 Int386(0x1B, &RegsIn, &RegsOut);
629 DiskDrive->Initialized =
FALSE;
633 BytesPerSector = 128 << RegsOut.
b.
ch;
634 switch (BytesPerSector)
640 DiskDrive->Geometry.Cylinders = 80;
641 DiskDrive->Geometry.Heads = 2;
642 DiskDrive->Geometry.SectorsPerTrack = 16;
647 DiskDrive->Geometry.Cylinders = 77;
648 DiskDrive->Geometry.Heads = 2;
649 DiskDrive->Geometry.SectorsPerTrack = 26;
657 DiskDrive->Geometry.Cylinders = 80;
658 DiskDrive->Geometry.Heads = 2;
659 DiskDrive->Geometry.SectorsPerTrack = 18;
664 DiskDrive->Geometry.Cylinders = 80;
665 DiskDrive->Geometry.Heads = 2;
666 DiskDrive->Geometry.SectorsPerTrack = 8;
671 DiskDrive->Geometry.Cylinders = 80;
672 DiskDrive->Geometry.Heads = 2;
673 DiskDrive->Geometry.SectorsPerTrack = 15;
679 DiskDrive->Geometry.Cylinders = 77;
680 DiskDrive->Geometry.Heads = 2;
681 DiskDrive->Geometry.SectorsPerTrack = 8;
685 DiskDrive->Initialized =
FALSE;
689 DiskDrive->Geometry.BytesPerSector = BytesPerSector;
690 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
691 DiskDrive->Geometry.Heads *
692 DiskDrive->Geometry.SectorsPerTrack;
694 DiskDrive->DaUa = DaUa;
696 DiskDrive->LBASupported =
FALSE;
697 DiskDrive->IsRemovable =
TRUE;
698 DiskDrive->Initialized =
TRUE;
700 TRACE(
"InitFloppyDrive(0x%x) returned:\n"
703 "Sects/Track: 0x%x\n"
704 "Bytes/Sect : 0x%x\n",
706 DiskDrive->Geometry.Cylinders,
707 DiskDrive->Geometry.Heads,
708 DiskDrive->Geometry.SectorsPerTrack,
709 DiskDrive->Geometry.BytesPerSector);
719 UCHAR FakeFloppyDriveNumber = 0x30;
720 UCHAR FakeHardDriveDriveNumber = 0x80;
721 UCHAR FakeCdRomDriveNumber = 0xE0;
723 UCHAR IdeDetectedCount;
726 TRACE(
"Pc98InitializeBootDevices()\n");
739 for (
i = 0;
i < 4;
i++)
746 ++FakeFloppyDriveNumber;
750 for (
i = 0;
i < 4;
i++)
756 ++FakeFloppyDriveNumber;
760 for (
i = 0;
i < 4;
i++)
766 ++FakeFloppyDriveNumber;
772 for (
i = 0;
i < 4;
i++)
776 ++FakeHardDriveDriveNumber;
780 for (
i = 0;
i <= IdeDetectedCount;
i++)
784 ++FakeCdRomDriveNumber;
789 for (
i = 0;
i < 7;
i++)
799 ++FakeCdRomDriveNumber;
803 ++FakeHardDriveDriveNumber;
841 TRACE(
"Pc98DiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n",
854 TRACE(
"--> Using LBA\n");
860 TRACE(
"--> Using CHS\n");
870 TRACE(
"Pc98DiskGetDriveGeometry(0x%x)\n", DriveNumber);
#define DBG_DEFAULT_CHANNEL(ch)
VOID UiMessageBox(_In_ PCSTR Format,...)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
_In_ PUSB_DEVICE_HANDLE _Out_ PUSHORT DeviceAddress
BOOLEAN PcInitializeBootDevices(VOID)
PDEVICE_UNIT AtaGetDevice(_In_ UCHAR UnitNumber)
BOOLEAN AtaInit(_Out_ PUCHAR DetectedCount)
BOOLEAN AtaReadLogicalSectors(_In_ PDEVICE_UNIT DeviceUnit, _In_ ULONG64 SectorNumber, _In_ ULONG SectorCount, _Out_writes_bytes_all_(SectorCount *DeviceUnit->SectorSize) PVOID Buffer)
_In_ NDIS_ERROR_CODE ErrorCode
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
ULONG Pc98DiskGetCacheableBlockCount(UCHAR DriveNumber)
static BOOLEAN InitHardDrive(IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
static PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
PPC98_DISK_DRIVE Pc98DiskDriveNumberToDrive(IN UCHAR DriveNumber)
PC98_DISK_DRIVE Pc98DiskDrive[MAX_DRIVES]
static BOOLEAN Pc98DiskReadLogicalSectorsLBA(IN PPC98_DISK_DRIVE DiskDrive, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
BOOLEAN DiskResetController(IN PPC98_DISK_DRIVE DiskDrive)
LONG DiskReportError(BOOLEAN bShowError)
BOOLEAN Pc98InitializeBootDevices(VOID)
static BOOLEAN InitFloppyDrive(IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
BOOLEAN Pc98DiskReadLogicalSectors(IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
static BOOLEAN Pc98DiskReadLogicalSectorsCHS(IN PPC98_DISK_DRIVE DiskDrive, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
static BOOLEAN InitIdeDrive(IN UCHAR UnitNumber, IN OUT PPC98_DISK_DRIVE DiskDrive)
static BOOLEAN InitScsiDrive(IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
static UCHAR BytesPerSectorToSectorLengthCode(IN ULONG BytesPerSector)
BOOLEAN Pc98DiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
#define INT386_SUCCESS(regs)
int __cdecl Int386(int ivec, REGS *in, REGS *out)
Data structure for the ATA device.
ULONG BytesPerSector
Number of bytes per sector.
ULONG Cylinders
Number of cylinders on the disk.
ULONG SectorsPerTrack
Number of sectors per track.
ULONG Heads
Number of heads on the disk.
#define RtlZeroMemory(Destination, Length)
#define SECONDBYTE(VALUE)