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);
174 switch (BytesPerSector)
198 REGS RegsIn, RegsOut;
222 RegsIn.
b.
al = DiskDrive->DaUa;
225 RegsIn.
w.
cx = SectorNumber & 0xFFFF;
226 RegsIn.
w.
dx = (SectorNumber >> 16) & 0xFFFF;
231 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
233 Int386(0x1B, &RegsIn, &RegsOut);
246 DiskError(
"Disk Read Failed in LBA mode", RegsOut.
b.
ah);
247 ERR(
"Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
261 UCHAR PhysicalSector;
265 ULONG NumberOfSectorsToRead;
266 REGS RegsIn, RegsOut;
269 DriveGeometry = DiskDrive->Geometry;
286 if (PhysicalSector > 1)
297 if ((PhysicalHead >= DriveGeometry.
Heads) ||
298 (PhysicalTrack >= DriveGeometry.
Cylinders) ||
299 ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.
SectorsPerTrack + 1)) ||
302 DiskError(
"Disk read exceeds drive geometry limits.", 0);
324 RegsIn.
b.
al = DiskDrive->DaUa;
327 RegsIn.
b.
cl = PhysicalTrack & 0xFFFF;
329 RegsIn.
b.
dl = PhysicalSector;
330 RegsIn.
b.
dh = PhysicalHead;
351 RegsIn.
b.
al = DiskDrive->DaUa;
354 RegsIn.
w.
cx = PhysicalTrack & 0xFFFF;
355 RegsIn.
b.
dl = PhysicalSector;
356 RegsIn.
b.
dh = PhysicalHead;
362 for (RetryCount = 0; RetryCount < 3; ++RetryCount)
364 Int386(0x1B, &RegsIn, &RegsOut);
378 DiskError(
"Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.
b.
ah);
379 ERR(
"Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u)\n",
387 SectorNumber += NumberOfSectorsToRead;
398 REGS RegsIn, RegsOut;
399 UCHAR UnitAddress = DaUa & 0x0F;
405 if (DiskEquipment & (1 << UnitAddress))
423 Int386(0x1B, &RegsIn, &RegsOut);
426 DiskDrive->Initialized =
FALSE;
430 DiskDrive->Geometry.Cylinders = RegsOut.
w.
cx;
431 DiskDrive->Geometry.Heads = RegsOut.
b.
dh;
432 DiskDrive->Geometry.SectorsPerTrack = RegsOut.
b.
dl;
433 DiskDrive->Geometry.BytesPerSector = RegsOut.
w.
bx;
434 DiskDrive->LBASupported =
FALSE;
435 DiskDrive->IsRemovable =
FALSE;
438 else if (ScsiParameters)
445 DiskDrive->Geometry.Cylinders = 0xFFFF;
446 DiskDrive->Geometry.Heads = 0xFFFF;
447 DiskDrive->Geometry.SectorsPerTrack = 0xFFFF;
448 DiskDrive->Geometry.BytesPerSector = 2048;
450 DiskDrive->LBASupported =
TRUE;
451 DiskDrive->IsRemovable =
TRUE;
456 DiskDrive->Geometry.Cylinders = 0xFFFF;
457 DiskDrive->Geometry.Heads = 8;
458 DiskDrive->Geometry.SectorsPerTrack = 32;
459 DiskDrive->Geometry.BytesPerSector = 512;
461 DiskDrive->LBASupported =
TRUE;
462 DiskDrive->IsRemovable =
TRUE;
466 DiskDrive->Initialized =
FALSE;
472 DiskDrive->Initialized =
FALSE;
476 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
477 DiskDrive->Geometry.Heads *
478 DiskDrive->Geometry.SectorsPerTrack;
480 DiskDrive->DaUa = DaUa;
482 DiskDrive->Initialized =
TRUE;
484 TRACE(
"InitScsiDrive(0x%x) returned:\n"
487 "Sects/Track: 0x%x\n"
488 "Total Sects: 0x%llx\n"
489 "Bytes/Sect : 0x%x\n",
491 DiskDrive->Geometry.Cylinders,
492 DiskDrive->Geometry.Heads,
493 DiskDrive->Geometry.SectorsPerTrack,
494 DiskDrive->Geometry.Sectors,
495 DiskDrive->Geometry.BytesPerSector);
510 DiskDrive->Geometry.Cylinders = DeviceUnit->
Cylinders;
511 DiskDrive->Geometry.Heads = DeviceUnit->
Heads;
513 DiskDrive->Geometry.BytesPerSector = DeviceUnit->
SectorSize;
516 DiskDrive->DaUa = 0xFF;
517 DiskDrive->IdeUnitNumber = UnitNumber;
519 DiskDrive->LBASupported =
TRUE;
520 DiskDrive->IsRemovable =
TRUE;
521 DiskDrive->Initialized =
TRUE;
523 TRACE(
"InitIdeDrive(0x%x) returned:\n"
526 "Sects/Track: 0x%x\n"
527 "Total Sects: 0x%llx\n"
528 "Bytes/Sect : 0x%x\n",
530 DiskDrive->Geometry.Cylinders,
531 DiskDrive->Geometry.Heads,
532 DiskDrive->Geometry.SectorsPerTrack,
533 DiskDrive->Geometry.Sectors,
534 DiskDrive->Geometry.BytesPerSector);
539 DiskDrive->Initialized =
FALSE;
548 REGS RegsIn, RegsOut;
558 Int386(0x1B, &RegsIn, &RegsOut);
576 Int386(0x1B, &RegsIn, &RegsOut);
579 DiskDrive->Initialized =
FALSE;
583 DiskDrive->Geometry.Cylinders = RegsOut.
w.
cx;
584 DiskDrive->Geometry.Heads = RegsOut.
b.
dh;
585 DiskDrive->Geometry.SectorsPerTrack = RegsOut.
b.
dl;
586 DiskDrive->Geometry.BytesPerSector = RegsOut.
w.
bx;
588 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
589 DiskDrive->Geometry.Heads *
590 DiskDrive->Geometry.SectorsPerTrack;
592 DiskDrive->DaUa = DaUa;
594 DiskDrive->LBASupported =
FALSE;
595 DiskDrive->IsRemovable =
FALSE;
596 DiskDrive->Initialized =
TRUE;
598 TRACE(
"InitHardDrive(0x%x) returned:\n"
601 "Sects/Track: 0x%x\n"
602 "Total Sects: 0x%llx\n"
603 "Bytes/Sect : 0x%x\n",
605 DiskDrive->Geometry.Cylinders,
606 DiskDrive->Geometry.Heads,
607 DiskDrive->Geometry.SectorsPerTrack,
608 DiskDrive->Geometry.Sectors,
609 DiskDrive->Geometry.BytesPerSector);
619 REGS RegsIn, RegsOut;
641 Int386(0x1B, &RegsIn, &RegsOut);
644 DiskDrive->Initialized =
FALSE;
648 BytesPerSector = 128 << RegsOut.
b.
ch;
649 switch (BytesPerSector)
655 DiskDrive->Geometry.Cylinders = 80;
656 DiskDrive->Geometry.Heads = 2;
657 DiskDrive->Geometry.SectorsPerTrack = 16;
662 DiskDrive->Geometry.Cylinders = 77;
663 DiskDrive->Geometry.Heads = 2;
664 DiskDrive->Geometry.SectorsPerTrack = 26;
672 DiskDrive->Geometry.Cylinders = 80;
673 DiskDrive->Geometry.Heads = 2;
674 DiskDrive->Geometry.SectorsPerTrack = 18;
679 DiskDrive->Geometry.Cylinders = 80;
680 DiskDrive->Geometry.Heads = 2;
681 DiskDrive->Geometry.SectorsPerTrack = 8;
686 DiskDrive->Geometry.Cylinders = 80;
687 DiskDrive->Geometry.Heads = 2;
688 DiskDrive->Geometry.SectorsPerTrack = 15;
694 DiskDrive->Geometry.Cylinders = 77;
695 DiskDrive->Geometry.Heads = 2;
696 DiskDrive->Geometry.SectorsPerTrack = 8;
700 DiskDrive->Initialized =
FALSE;
704 DiskDrive->Geometry.BytesPerSector = BytesPerSector;
705 DiskDrive->Geometry.Sectors = (
ULONGLONG)DiskDrive->Geometry.Cylinders *
706 DiskDrive->Geometry.Heads *
707 DiskDrive->Geometry.SectorsPerTrack;
709 DiskDrive->DaUa = DaUa;
711 DiskDrive->LBASupported =
FALSE;
712 DiskDrive->IsRemovable =
TRUE;
713 DiskDrive->Initialized =
TRUE;
715 TRACE(
"InitFloppyDrive(0x%x) returned:\n"
718 "Sects/Track: 0x%x\n"
719 "Total Sects: 0x%llx\n"
720 "Bytes/Sect : 0x%x\n",
722 DiskDrive->Geometry.Cylinders,
723 DiskDrive->Geometry.Heads,
724 DiskDrive->Geometry.SectorsPerTrack,
725 DiskDrive->Geometry.Sectors,
726 DiskDrive->Geometry.BytesPerSector);
736 UCHAR FakeFloppyDriveNumber = 0x30;
737 UCHAR FakeHardDriveDriveNumber = 0x80;
738 UCHAR FakeCdRomDriveNumber = 0xE0;
740 UCHAR IdeDetectedCount;
743 TRACE(
"Pc98InitializeBootDevices()\n");
756 for (
i = 0;
i < 4;
i++)
763 ++FakeFloppyDriveNumber;
767 for (
i = 0;
i < 4;
i++)
773 ++FakeFloppyDriveNumber;
777 for (
i = 0;
i < 4;
i++)
783 ++FakeFloppyDriveNumber;
789 for (
i = 0;
i < 4;
i++)
793 ++FakeHardDriveDriveNumber;
797 for (
i = 0;
i <= IdeDetectedCount;
i++)
801 ++FakeCdRomDriveNumber;
806 for (
i = 0;
i < 7;
i++)
816 ++FakeCdRomDriveNumber;
820 ++FakeHardDriveDriveNumber;
858 TRACE(
"Pc98DiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64u SectorCount: %u Buffer: 0x%x\n",
871 TRACE(
"--> Using LBA\n");
877 TRACE(
"--> Using CHS\n");
887 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)
CONFIGURATION_TYPE DiskGetConfigType(_In_ UCHAR DriveNumber)
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)
enum _CONFIGURATION_TYPE CONFIGURATION_TYPE
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)