ReactOS 0.4.16-dev-303-g11d5cb8
pc98disk.c File Reference
#include <freeldr.h>
#include <hwide.h>
#include <debug.h>
Include dependency graph for pc98disk.c:

Go to the source code of this file.

Macros

#define MAX_DRIVES   0x100
 

Functions

 DBG_DEFAULT_CHANNEL (DISK)
 
LONG DiskReportError (BOOLEAN bShowError)
 
static PCSTR DiskGetErrorCodeString (ULONG ErrorCode)
 
static VOID DiskError (PCSTR ErrorString, ULONG ErrorCode)
 
BOOLEAN DiskResetController (IN PPC98_DISK_DRIVE DiskDrive)
 
VOID Pc98DiskPrepareForReactOS (VOID)
 
PPC98_DISK_DRIVE Pc98DiskDriveNumberToDrive (IN UCHAR DriveNumber)
 
static UCHAR BytesPerSectorToSectorLengthCode (IN ULONG BytesPerSector)
 
static BOOLEAN Pc98DiskReadLogicalSectorsLBA (IN PPC98_DISK_DRIVE DiskDrive, 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 InitScsiDrive (IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
 
static BOOLEAN InitIdeDrive (IN UCHAR UnitNumber, IN OUT PPC98_DISK_DRIVE DiskDrive)
 
static BOOLEAN InitHardDrive (IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
 
static BOOLEAN InitFloppyDrive (IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
 
BOOLEAN Pc98InitializeBootDevices (VOID)
 
BOOLEAN Pc98DiskReadLogicalSectors (IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
 
BOOLEAN Pc98DiskGetDriveGeometry (UCHAR DriveNumber, PGEOMETRY Geometry)
 
ULONG Pc98DiskGetCacheableBlockCount (UCHAR DriveNumber)
 

Variables

PC98_DISK_DRIVE Pc98DiskDrive [MAX_DRIVES]
 
static LONG lReportError = 0
 

Macro Definition Documentation

◆ MAX_DRIVES

#define MAX_DRIVES   0x100

Definition at line 19 of file pc98disk.c.

Function Documentation

◆ BytesPerSectorToSectorLengthCode()

static UCHAR BytesPerSectorToSectorLengthCode ( IN ULONG  BytesPerSector)
inlinestatic

Definition at line 159 of file pc98disk.c.

160{
161 switch (BytesPerSector)
162 {
163 case 128:
164 return 0;
165 case 256:
166 return 1;
167 case 512:
168 return 2;
169 case 1024:
170 return 3;
171 case 2048:
172 return 4;
173 default:
174 return 0;
175 }
176}

Referenced by Pc98DiskReadLogicalSectorsCHS().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( DISK  )

◆ DiskError()

static VOID DiskError ( PCSTR  ErrorString,
ULONG  ErrorCode 
)
static

Definition at line 74 of file pc98disk.c.

75{
76 CHAR ErrorCodeString[200];
77
78 if (lReportError < 0)
79 return;
80
81 RtlStringCbPrintfA(ErrorCodeString, sizeof(ErrorCodeString), "%s\n\nError Code: 0x%lx\nError: %s",
83
84 ERR("%s\n", ErrorCodeString);
85
86 UiMessageBox(ErrorCodeString);
87}
#define ERR(fmt,...)
Definition: precomp.h:57
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
static LONG lReportError
Definition: pc98disk.c:26
static PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
Definition: pc98disk.c:40
char CHAR
Definition: xmlstorage.h:175

Referenced by Pc98DiskReadLogicalSectorsCHS(), and Pc98DiskReadLogicalSectorsLBA().

◆ DiskGetErrorCodeString()

static PCSTR DiskGetErrorCodeString ( ULONG  ErrorCode)
static

Definition at line 40 of file pc98disk.c.

41{
42 switch (ErrorCode & 0xF0)
43 {
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";
51 case 0x70:
52 if (ErrorCode == 0x78)
53 return "Illegal disk address";
54 else
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";
60 case 0xC0:
61 if (ErrorCode == 0xC8)
62 return "Seek failure";
63 else
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";
68
69 default: return "Unknown error code";
70 }
71}

Referenced by DiskError(), Pc98DiskReadLogicalSectorsCHS(), and Pc98DiskReadLogicalSectorsLBA().

◆ DiskReportError()

LONG DiskReportError ( BOOLEAN  bShowError)

Definition at line 29 of file pc98disk.c.

30{
31 /* Set the reference count */
32 if (bShowError)
34 else
36 return lReportError;
37}

◆ DiskResetController()

BOOLEAN DiskResetController ( IN PPC98_DISK_DRIVE  DiskDrive)

Definition at line 91 of file pc98disk.c.

92{
93 REGS Regs;
94
95 if (DiskDrive->Type & DRIVE_FDD)
96 {
97 /* Int 1Bh AH=07h
98 * DISK BIOS - Recalibrate
99 *
100 * Call with:
101 * AL - drive number
102 *
103 * Return:
104 * CF - set on error, clear if successful
105 * AH - status
106 */
107 Regs.b.ah = 0x07;
108 }
109 else if (DiskDrive->Type != (DRIVE_IDE | DRIVE_CDROM))
110 {
111 /* Int 1Bh AH=03h
112 * DISK BIOS - Initialize
113 *
114 * Call with:
115 * AL - drive number
116 *
117 * Return:
118 * CF - set on error, clear if successful
119 * AH - status
120 */
121 Regs.b.ah = 0x03;
122 }
123 else
124 {
125 return FALSE;
126 }
127
128 WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DiskDrive->DaUa);
129
130 Regs.b.al = DiskDrive->DaUa;
131 Int386(0x1B, &Regs, &Regs);
132 return INT386_SUCCESS(Regs);
133}
#define WARN(fmt,...)
Definition: precomp.h:61
#define FALSE
Definition: types.h:117
#define DRIVE_IDE
Definition: machpc98.h:117
#define DRIVE_CDROM
Definition: machpc98.h:119
#define DRIVE_FDD
Definition: machpc98.h:120
#define INT386_SUCCESS(regs)
Definition: pcbios.h:179
int __cdecl Int386(int ivec, REGS *in, REGS *out)
unsigned char al
Definition: pcbios.h:131
unsigned char ah
Definition: pcbios.h:132
Definition: pcbios.h:159
BYTEREGS b
Definition: pcbios.h:163

Referenced by Pc98DiskReadLogicalSectorsCHS(), and Pc98DiskReadLogicalSectorsLBA().

◆ InitFloppyDrive()

static BOOLEAN InitFloppyDrive ( IN UCHAR  DaUa,
IN OUT PPC98_DISK_DRIVE  DiskDrive 
)
static

Definition at line 605 of file pc98disk.c.

608{
609 REGS RegsIn, RegsOut;
610 USHORT BytesPerSector;
611 UCHAR DeviceAddress = DaUa & 0xF0;
612
613 /* There's no way to obtain floppy disk geometry in BIOS */
614
615 /* Int 1Bh AH=4Ah
616 * DISK BIOS - Read ID
617 *
618 * Call with:
619 * AL - drive number
620 *
621 * Return:
622 * CH - sector size
623 * CL - cylinder
624 * DH - head
625 * DL - sector
626 * CF - set on error, clear if successful
627 * AH - status
628 */
629 RegsIn.b.ah = 0x4A;
630 RegsIn.b.al = DaUa;
631 Int386(0x1B, &RegsIn, &RegsOut);
632 if (!INT386_SUCCESS(RegsOut))
633 {
634 DiskDrive->Initialized = FALSE;
635 return FALSE;
636 }
637
638 BytesPerSector = 128 << RegsOut.b.ch;
639 switch (BytesPerSector)
640 {
641 case 256:
642 if (DeviceAddress == 0x50)
643 {
644 /* 320 kB 2DD */
645 DiskDrive->Geometry.Cylinders = 80;
646 DiskDrive->Geometry.Heads = 2;
647 DiskDrive->Geometry.SectorsPerTrack = 16;
648 }
649 else
650 {
651 /* 1 MB 2HD */
652 DiskDrive->Geometry.Cylinders = 77;
653 DiskDrive->Geometry.Heads = 2;
654 DiskDrive->Geometry.SectorsPerTrack = 26;
655 }
656 break;
657
658 case 512:
659 if (DeviceAddress == 0x30 || DeviceAddress == 0xB0)
660 {
661 /* 1.44 MB 2HD */
662 DiskDrive->Geometry.Cylinders = 80;
663 DiskDrive->Geometry.Heads = 2;
664 DiskDrive->Geometry.SectorsPerTrack = 18;
665 }
666 else if (DeviceAddress == 0x70 || DeviceAddress == 0xF0)
667 {
668 /* 720/640 kB 2DD */
669 DiskDrive->Geometry.Cylinders = 80;
670 DiskDrive->Geometry.Heads = 2;
671 DiskDrive->Geometry.SectorsPerTrack = 8;
672 }
673 else
674 {
675 /* 1.2 MB 2HC */
676 DiskDrive->Geometry.Cylinders = 80;
677 DiskDrive->Geometry.Heads = 2;
678 DiskDrive->Geometry.SectorsPerTrack = 15;
679 }
680 break;
681
682 case 1024:
683 /* 1.25 MB 2HD */
684 DiskDrive->Geometry.Cylinders = 77;
685 DiskDrive->Geometry.Heads = 2;
686 DiskDrive->Geometry.SectorsPerTrack = 8;
687 break;
688
689 default:
690 DiskDrive->Initialized = FALSE;
691 return FALSE;
692 }
693
694 DiskDrive->Geometry.BytesPerSector = BytesPerSector;
695 DiskDrive->Geometry.Sectors = (ULONGLONG)DiskDrive->Geometry.Cylinders *
696 DiskDrive->Geometry.Heads *
697 DiskDrive->Geometry.SectorsPerTrack;
698
699 DiskDrive->DaUa = DaUa;
700 DiskDrive->Type = DRIVE_FDD;
701 DiskDrive->LBASupported = FALSE;
702 DiskDrive->IsRemovable = TRUE;
703 DiskDrive->Initialized = TRUE;
704
705 TRACE("InitFloppyDrive(0x%x) returned:\n"
706 "Cylinders : 0x%x\n"
707 "Heads : 0x%x\n"
708 "Sects/Track: 0x%x\n"
709 "Bytes/Sect : 0x%x\n",
710 DaUa,
711 DiskDrive->Geometry.Cylinders,
712 DiskDrive->Geometry.Heads,
713 DiskDrive->Geometry.SectorsPerTrack,
714 DiskDrive->Geometry.BytesPerSector);
715
716 return TRUE;
717}
#define TRUE
Definition: types.h:120
_In_ PUSB_DEVICE_HANDLE _Out_ PUSHORT DeviceAddress
Definition: hubbusif.h:360
unsigned short USHORT
Definition: pedump.c:61
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char ch
Definition: pcbios.h:138
uint64_t ULONGLONG
Definition: typedefs.h:67
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by Pc98InitializeBootDevices().

◆ InitHardDrive()

static BOOLEAN InitHardDrive ( IN UCHAR  DaUa,
IN OUT PPC98_DISK_DRIVE  DiskDrive 
)
static

Definition at line 536 of file pc98disk.c.

539{
540 REGS RegsIn, RegsOut;
541
542 /* Int 1Bh AH=8Eh
543 * DISK BIOS - Set half-height operation mode
544 *
545 * Call with:
546 * AL - drive number
547 */
548 RegsIn.b.al = DaUa;
549 RegsIn.b.ah = 0x8E;
550 Int386(0x1B, &RegsIn, &RegsOut);
551
552 /* Int 1Bh AH=84h
553 * DISK BIOS - Sense
554 *
555 * Call with:
556 * AL - drive number
557 *
558 * Return:
559 * BX - bytes per sector
560 * CX - cylinders number
561 * DH - heads number
562 * DL - sectors number
563 * CF - set on error, clear if successful
564 * AH - status
565 */
566 RegsIn.b.al = DaUa;
567 RegsIn.b.ah = 0x84;
568 Int386(0x1B, &RegsIn, &RegsOut);
569 if (!INT386_SUCCESS(RegsOut) || RegsOut.w.cx == 0)
570 {
571 DiskDrive->Initialized = FALSE;
572 return FALSE;
573 }
574
575 DiskDrive->Geometry.Cylinders = RegsOut.w.cx;
576 DiskDrive->Geometry.Heads = RegsOut.b.dh;
577 DiskDrive->Geometry.SectorsPerTrack = RegsOut.b.dl;
578 DiskDrive->Geometry.BytesPerSector = RegsOut.w.bx;
579
580 DiskDrive->Geometry.Sectors = (ULONGLONG)DiskDrive->Geometry.Cylinders *
581 DiskDrive->Geometry.Heads *
582 DiskDrive->Geometry.SectorsPerTrack;
583
584 DiskDrive->DaUa = DaUa;
585 DiskDrive->Type = DRIVE_IDE;
586 DiskDrive->LBASupported = FALSE;
587 DiskDrive->IsRemovable = FALSE;
588 DiskDrive->Initialized = TRUE;
589
590 TRACE("InitHardDrive(0x%x) returned:\n"
591 "Cylinders : 0x%x\n"
592 "Heads : 0x%x\n"
593 "Sects/Track: 0x%x\n"
594 "Bytes/Sect : 0x%x\n",
595 DaUa,
596 DiskDrive->Geometry.Cylinders,
597 DiskDrive->Geometry.Heads,
598 DiskDrive->Geometry.SectorsPerTrack,
599 DiskDrive->Geometry.BytesPerSector);
600
601 return TRUE;
602}
unsigned char dl
Definition: pcbios.h:140
unsigned char dh
Definition: pcbios.h:141
unsigned short cx
Definition: pcbios.h:113
unsigned short bx
Definition: pcbios.h:112
WORDREGS w
Definition: pcbios.h:162

Referenced by Pc98InitializeBootDevices().

◆ InitIdeDrive()

static BOOLEAN InitIdeDrive ( IN UCHAR  UnitNumber,
IN OUT PPC98_DISK_DRIVE  DiskDrive 
)
static

Definition at line 495 of file pc98disk.c.

498{
499 PDEVICE_UNIT DeviceUnit = AtaGetDevice(UnitNumber);
500
501 /* We work directly only with ATAPI drives because BIOS has ATA support */
502 if (DeviceUnit && DeviceUnit->Flags & ATA_DEVICE_ATAPI)
503 {
504 DiskDrive->Geometry.Cylinders = DeviceUnit->Cylinders;
505 DiskDrive->Geometry.Heads = DeviceUnit->Heads;
506 DiskDrive->Geometry.SectorsPerTrack = DeviceUnit->Sectors;
507 DiskDrive->Geometry.BytesPerSector = DeviceUnit->SectorSize;
508 DiskDrive->Geometry.Sectors = DeviceUnit->TotalSectors;
509
510 DiskDrive->DaUa = 0xFF;
511 DiskDrive->IdeUnitNumber = UnitNumber;
512 DiskDrive->Type = DRIVE_IDE | DRIVE_CDROM;
513 DiskDrive->LBASupported = TRUE;
514 DiskDrive->IsRemovable = TRUE;
515 DiskDrive->Initialized = TRUE;
516
517 TRACE("InitIdeDrive(0x%x) returned:\n"
518 "Cylinders : 0x%x\n"
519 "Heads : 0x%x\n"
520 "Sects/Track: 0x%x\n"
521 "Bytes/Sect : 0x%x\n",
522 UnitNumber,
523 DiskDrive->Geometry.Cylinders,
524 DiskDrive->Geometry.Heads,
525 DiskDrive->Geometry.SectorsPerTrack,
526 DiskDrive->Geometry.BytesPerSector);
527
528 return TRUE;
529 }
530
531 DiskDrive->Initialized = FALSE;
532 return FALSE;
533}
PDEVICE_UNIT AtaGetDevice(IN UCHAR UnitNumber)
Definition: hwide.c:178
#define ATA_DEVICE_ATAPI
Definition: hwide.h:303
USHORT Flags
Definition: hwide.h:299
ULONG Cylinders
Definition: hwide.h:294
ULONG SectorSize
Definition: hwide.h:297
ULONG Sectors
Definition: hwide.h:296
ULONGLONG TotalSectors
Definition: hwide.h:298
ULONG Heads
Definition: hwide.h:295

Referenced by Pc98InitializeBootDevices().

◆ InitScsiDrive()

static BOOLEAN InitScsiDrive ( IN UCHAR  DaUa,
IN OUT PPC98_DISK_DRIVE  DiskDrive 
)
static

Definition at line 390 of file pc98disk.c.

393{
394 REGS RegsIn, RegsOut;
395 UCHAR UnitAddress = DaUa & 0x0F;
396 USHORT DiskEquipment = *(PUCHAR)MEM_DISK_EQUIPS;
397 ULONG ScsiParameters = *(PULONG)(MEM_SCSI_TABLE + UnitAddress * sizeof(ULONG));
399
400 /* Hard drives */
401 if (DiskEquipment & (1 << UnitAddress))
402 {
403 /* Int 1Bh AH=84h
404 * DISK BIOS - Sense
405 *
406 * Call with:
407 * AL - drive number
408 *
409 * Return:
410 * BX - bytes per sector
411 * CX - cylinders number
412 * DH - heads number
413 * DL - sectors number
414 * CF - set on error, clear if successful
415 * AH - status
416 */
417 RegsIn.b.al = DaUa;
418 RegsIn.b.ah = 0x84;
419 Int386(0x1B, &RegsIn, &RegsOut);
420 if (!INT386_SUCCESS(RegsOut) || RegsOut.w.cx == 0)
421 {
422 DiskDrive->Initialized = FALSE;
423 return FALSE;
424 }
425
426 DiskDrive->Geometry.Cylinders = RegsOut.w.cx;
427 DiskDrive->Geometry.Heads = RegsOut.b.dh;
428 DiskDrive->Geometry.SectorsPerTrack = RegsOut.b.dl;
429 DiskDrive->Geometry.BytesPerSector = RegsOut.w.bx;
430 DiskDrive->LBASupported = FALSE;
431 DiskDrive->IsRemovable = FALSE;
432 }
433 /* Other devices */
434 else if (ScsiParameters)
435 {
436 DeviceType = ScsiParameters & 0x1F;
437 switch (DeviceType)
438 {
439 case 0x05:
440 /* CD-ROM */
441 DiskDrive->Geometry.Cylinders = 0xFFFF;
442 DiskDrive->Geometry.Heads = 0xFFFF;
443 DiskDrive->Geometry.SectorsPerTrack = 0xFFFF;
444 DiskDrive->Geometry.BytesPerSector = 2048;
445 DiskDrive->Type = DRIVE_CDROM;
446 DiskDrive->LBASupported = TRUE;
447 DiskDrive->IsRemovable = TRUE;
448 break;
449
450 case 0x07:
451 /* Magneto-optical drive */
452 DiskDrive->Geometry.Cylinders = 0xFFFF;
453 DiskDrive->Geometry.Heads = 8;
454 DiskDrive->Geometry.SectorsPerTrack = 32;
455 DiskDrive->Geometry.BytesPerSector = 512;
456 DiskDrive->Type = DRIVE_MO;
457 DiskDrive->LBASupported = TRUE;
458 DiskDrive->IsRemovable = TRUE;
459 break;
460
461 default:
462 DiskDrive->Initialized = FALSE;
463 return FALSE;
464 }
465 }
466 else
467 {
468 DiskDrive->Initialized = FALSE;
469 return FALSE;
470 }
471
472 DiskDrive->Geometry.Sectors = (ULONGLONG)DiskDrive->Geometry.Cylinders *
473 DiskDrive->Geometry.Heads *
474 DiskDrive->Geometry.SectorsPerTrack;
475
476 DiskDrive->DaUa = DaUa;
477 DiskDrive->Type |= DRIVE_SCSI;
478 DiskDrive->Initialized = TRUE;
479
480 TRACE("InitScsiDrive(0x%x) returned:\n"
481 "Cylinders : 0x%x\n"
482 "Heads : 0x%x\n"
483 "Sects/Track: 0x%x\n"
484 "Bytes/Sect : 0x%x\n",
485 DaUa,
486 DiskDrive->Geometry.Cylinders,
487 DiskDrive->Geometry.Heads,
488 DiskDrive->Geometry.SectorsPerTrack,
489 DiskDrive->Geometry.BytesPerSector);
490
491 return TRUE;
492}
#define DRIVE_SCSI
Definition: machpc98.h:118
#define MEM_SCSI_TABLE
Definition: machpc98.h:24
#define DRIVE_MO
Definition: machpc98.h:121
#define MEM_DISK_EQUIPS
Definition: machpc98.h:30
DeviceType
Definition: mmdrv.h:42
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59

Referenced by Pc98InitializeBootDevices().

◆ Pc98DiskDriveNumberToDrive()

PPC98_DISK_DRIVE Pc98DiskDriveNumberToDrive ( IN UCHAR  DriveNumber)

Definition at line 141 of file pc98disk.c.

142{
143 PPC98_DISK_DRIVE DiskDrive;
144
145 ASSERT((0 <= DriveNumber) && (DriveNumber < RTL_NUMBER_OF(Pc98DiskDrive)));
146
147 /* Retrieve a slot */
148 DiskDrive = &Pc98DiskDrive[DriveNumber];
149
150 /* The pre-initialization of the BIOS disks was already done in Pc98InitializeBootDevices() */
151 if (DiskDrive->Initialized)
152 return DiskDrive;
153 else
154 return NULL;
155}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define NULL
Definition: types.h:112
#define ASSERT(a)
Definition: mode.c:44
PC98_DISK_DRIVE Pc98DiskDrive[MAX_DRIVES]
Definition: pc98disk.c:22
BOOLEAN Initialized
Definition: machpc98.h:137

Referenced by ChainLoadBiosBootSectorCode(), Pc98DiskGetCacheableBlockCount(), Pc98DiskGetDriveGeometry(), Pc98DiskReadLogicalSectors(), and Pc98GetBootSectorLoadAddress().

◆ Pc98DiskGetCacheableBlockCount()

ULONG Pc98DiskGetCacheableBlockCount ( UCHAR  DriveNumber)

Definition at line 887 of file pc98disk.c.

888{
889 PPC98_DISK_DRIVE DiskDrive;
890
891 DiskDrive = Pc98DiskDriveNumberToDrive(DriveNumber);
892 if (!DiskDrive)
893 return 1; // Unknown count.
894
895 /*
896 * If LBA is supported then the block size will be 64 sectors (32k).
897 * If not then the block size is the size of one track.
898 */
899 if (DiskDrive->LBASupported)
900 return 64;
901 else
902 return DiskDrive->Geometry.SectorsPerTrack;
903}
PPC98_DISK_DRIVE Pc98DiskDriveNumberToDrive(IN UCHAR DriveNumber)
Definition: pc98disk.c:141
ULONG SectorsPerTrack
Number of sectors per track.
Definition: disk.h:29
BOOLEAN LBASupported
Definition: machpc98.h:125
GEOMETRY Geometry
Definition: machpc98.h:106

Referenced by MachInit().

◆ Pc98DiskGetDriveGeometry()

BOOLEAN Pc98DiskGetDriveGeometry ( UCHAR  DriveNumber,
PGEOMETRY  Geometry 
)

Definition at line 871 of file pc98disk.c.

872{
873 PPC98_DISK_DRIVE DiskDrive;
874
875 TRACE("Pc98DiskGetDriveGeometry(0x%x)\n", DriveNumber);
876
877 DiskDrive = Pc98DiskDriveNumberToDrive(DriveNumber);
878 if (!DiskDrive)
879 return FALSE;
880
881 *Geometry = DiskDrive->Geometry;
882
883 return TRUE;
884}

Referenced by DetectBiosDisks(), MachInit(), and Pc98GetHarddiskConfigurationData().

◆ Pc98DiskPrepareForReactOS()

VOID Pc98DiskPrepareForReactOS ( VOID  )

Definition at line 135 of file pc98disk.c.

136{
137 AtaFree();
138}
VOID AtaFree()

Referenced by Pc98PrepareForReactOS().

◆ Pc98DiskReadLogicalSectors()

BOOLEAN Pc98DiskReadLogicalSectors ( IN UCHAR  DriveNumber,
IN ULONGLONG  SectorNumber,
IN ULONG  SectorCount,
OUT PVOID  Buffer 
)

Definition at line 838 of file pc98disk.c.

843{
844 PPC98_DISK_DRIVE DiskDrive;
845
846 TRACE("Pc98DiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n",
847 DriveNumber, SectorNumber, SectorCount, Buffer);
848
849 /* 16-bit BIOS addressing limitation */
850 ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF);
851
852 DiskDrive = Pc98DiskDriveNumberToDrive(DriveNumber);
853 if (!DiskDrive)
854 return FALSE;
855
856 if (DiskDrive->LBASupported)
857 {
858 /* LBA is easy, nothing to calculate. Just do the read. */
859 TRACE("--> Using LBA\n");
860 return Pc98DiskReadLogicalSectorsLBA(DiskDrive, SectorNumber, SectorCount, Buffer);
861 }
862 else
863 {
864 /* LBA is not supported, default to CHS */
865 TRACE("--> Using CHS\n");
866 return Pc98DiskReadLogicalSectorsCHS(DiskDrive, SectorNumber, SectorCount, Buffer);
867 }
868}
Definition: bufpool.h:45
ULONG SectorCount
Definition: part_xbox.c:31
static BOOLEAN Pc98DiskReadLogicalSectorsLBA(IN PPC98_DISK_DRIVE DiskDrive, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
Definition: pc98disk.c:179
static BOOLEAN Pc98DiskReadLogicalSectorsCHS(IN PPC98_DISK_DRIVE DiskDrive, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
Definition: pc98disk.c:242
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by MachInit().

◆ Pc98DiskReadLogicalSectorsCHS()

static BOOLEAN Pc98DiskReadLogicalSectorsCHS ( IN PPC98_DISK_DRIVE  DiskDrive,
IN ULONGLONG  SectorNumber,
IN ULONG  SectorCount,
OUT PVOID  Buffer 
)
static

Definition at line 242 of file pc98disk.c.

247{
248 UCHAR PhysicalSector;
249 UCHAR PhysicalHead;
250 ULONG PhysicalTrack;
251 GEOMETRY DriveGeometry;
252 ULONG NumberOfSectorsToRead;
253 REGS RegsIn, RegsOut;
254 ULONG RetryCount;
255
256 DriveGeometry = DiskDrive->Geometry;
257
258 while (SectorCount > 0)
259 {
260 /*
261 * Calculate the physical disk offsets.
262 * Note: DriveGeometry.SectorsPerTrack < 64
263 */
264 PhysicalSector = (UCHAR)(SectorNumber % DriveGeometry.SectorsPerTrack);
265 PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.SectorsPerTrack) % DriveGeometry.Heads);
266 PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.SectorsPerTrack) / DriveGeometry.Heads);
267
268 /* Floppy sectors value always start at 1 */
269 if (DiskDrive->Type & DRIVE_FDD)
270 ++PhysicalSector;
271
272 /* Calculate how many sectors we need to read this round */
273 if (PhysicalSector > 1)
274 {
275 NumberOfSectorsToRead = min(SectorCount,
276 (DriveGeometry.SectorsPerTrack - (PhysicalSector - 1)));
277 }
278 else
279 {
280 NumberOfSectorsToRead = min(SectorCount, DriveGeometry.SectorsPerTrack);
281 }
282
283 /* Make sure the read is within the geometry boundaries */
284 if ((PhysicalHead >= DriveGeometry.Heads) ||
285 (PhysicalTrack >= DriveGeometry.Cylinders) ||
286 ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.SectorsPerTrack + 1)) ||
287 (PhysicalSector > DriveGeometry.SectorsPerTrack))
288 {
289 DiskError("Disk read exceeds drive geometry limits.", 0);
290 return FALSE;
291 }
292
293 if (DiskDrive->Type & DRIVE_FDD)
294 {
295 /* Int 1Bh AH=x6h
296 * DISK BIOS - Read data
297 *
298 * Call with:
299 * AL - drive number
300 * BX - bytes to read
301 * CH - sector length code
302 * CL - cylinder number
303 * DH - head number
304 * DL - sector number
305 * ES:BP -> buffer to read data into
306 *
307 * Return:
308 * CF - set on error, clear if successful
309 * AH - status
310 */
311 RegsIn.b.al = DiskDrive->DaUa;
312 RegsIn.b.ah = 0x56; /* With SEEK, and use double-density format (MFM) */
313 RegsIn.w.bx = DriveGeometry.BytesPerSector * (UCHAR)NumberOfSectorsToRead;
314 RegsIn.b.cl = PhysicalTrack & 0xFFFF;
315 RegsIn.b.ch = BytesPerSectorToSectorLengthCode(DriveGeometry.BytesPerSector);
316 RegsIn.b.dl = PhysicalSector;
317 RegsIn.b.dh = PhysicalHead;
318 RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
319 RegsIn.w.bp = ((ULONG_PTR)Buffer) & 0x0F;
320 }
321 else
322 {
323 /* Int 1Bh AH=06h
324 * DISK BIOS - Read data
325 *
326 * Call with:
327 * AL - drive number
328 * BX - bytes to read
329 * CX - cylinder number
330 * DH - head number
331 * DL - sector number
332 * ES:BP -> buffer to read data into
333 *
334 * Return:
335 * CF - set on error, clear if successful
336 * AH - status
337 */
338 RegsIn.b.al = DiskDrive->DaUa;
339 RegsIn.b.ah = 0x06;
340 RegsIn.w.bx = DriveGeometry.BytesPerSector * (UCHAR)NumberOfSectorsToRead;
341 RegsIn.w.cx = PhysicalTrack & 0xFFFF;
342 RegsIn.b.dl = PhysicalSector;
343 RegsIn.b.dh = PhysicalHead;
344 RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
345 RegsIn.w.bp = ((ULONG_PTR)Buffer) & 0x0F;
346 }
347
348 /* Perform the read. Retry 3 times. */
349 for (RetryCount = 0; RetryCount < 3; RetryCount++)
350 {
351 Int386(0x1B, &RegsIn, &RegsOut);
352
353 /* If it worked break out */
354 if (INT386_SUCCESS(RegsOut))
355 {
356 break;
357 }
358 /* If it was a corrected ECC error then the data is still good */
359 else if (RegsOut.b.ah == 0x08)
360 {
361 break;
362 }
363 /* If it failed then do the next retry */
364 else
365 {
366 DiskResetController(DiskDrive);
367 continue;
368 }
369 }
370
371 /* If we retried 3 times then fail */
372 if (RetryCount >= 3)
373 {
374 DiskError("Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.b.ah);
375 ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
376 RegsOut.b.ah, DiskGetErrorCodeString(RegsOut.b.ah),
377 DiskDrive->DaUa, SectorNumber, SectorCount);
378 return FALSE;
379 }
380
381 Buffer = (PVOID)((ULONG_PTR)Buffer + (NumberOfSectorsToRead * DriveGeometry.BytesPerSector));
382 SectorCount -= NumberOfSectorsToRead;
383 SectorNumber += NumberOfSectorsToRead;
384 }
385
386 return TRUE;
387}
#define ULONG_PTR
Definition: config.h:101
#define min(a, b)
Definition: monoChain.cc:55
BOOLEAN DiskResetController(IN PPC98_DISK_DRIVE DiskDrive)
Definition: pc98disk.c:91
static UCHAR BytesPerSectorToSectorLengthCode(IN ULONG BytesPerSector)
Definition: pc98disk.c:159
static VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
Definition: pc98disk.c:74
unsigned char cl
Definition: pcbios.h:137
unsigned short bp
Definition: pcbios.h:118
unsigned short es
Definition: pcbios.h:121
Definition: disk.h:26
ULONG BytesPerSector
Number of bytes per sector.
Definition: disk.h:30
ULONG Cylinders
Number of cylinders on the disk.
Definition: disk.h:27
ULONG Heads
Number of heads on the disk.
Definition: disk.h:28
void * PVOID
Definition: typedefs.h:50

Referenced by Pc98DiskReadLogicalSectors().

◆ Pc98DiskReadLogicalSectorsLBA()

static BOOLEAN Pc98DiskReadLogicalSectorsLBA ( IN PPC98_DISK_DRIVE  DiskDrive,
IN ULONGLONG  SectorNumber,
IN ULONG  SectorCount,
OUT PVOID  Buffer 
)
static

Definition at line 179 of file pc98disk.c.

184{
185 REGS RegsIn, RegsOut;
186 ULONG RetryCount;
187
188 if (DiskDrive->Type & DRIVE_IDE && DiskDrive->Type & DRIVE_CDROM)
189 {
190 return AtaAtapiReadLogicalSectorsLBA(AtaGetDevice(DiskDrive->IdeUnitNumber), SectorNumber, SectorCount, Buffer);
191 }
192 else
193 {
194 /* Int 1Bh AH=06h
195 * DISK BIOS - Read data
196 *
197 * Call with:
198 * AL - drive number
199 * BX - bytes to read
200 * CX - cylinder number
201 * DH - head number
202 * DL - sector number
203 * ES:BP -> buffer to read data into
204 *
205 * Return:
206 * CF - set on error, clear if successful
207 * AH - status
208 */
209 RegsIn.b.al = DiskDrive->DaUa;
210 RegsIn.b.ah = 0x06;
211 RegsIn.w.bx = DiskDrive->Geometry.BytesPerSector * SectorCount;
212 RegsIn.w.cx = SectorNumber & 0xFFFF;
213 RegsIn.w.dx = (SectorNumber >> 16) & 0xFFFF;
214 RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
215 RegsIn.w.bp = ((ULONG_PTR)Buffer) & 0x0F;
216
217 /* Retry 3 times */
218 for (RetryCount = 0; RetryCount < 3; RetryCount++)
219 {
220 Int386(0x1B, &RegsIn, &RegsOut);
221
222 /* If it worked, or if it was a corrected ECC error
223 * and the data is still good, return success */
224 if (INT386_SUCCESS(RegsOut) || (RegsOut.b.ah == 0x08))
225 return TRUE;
226
227 /* It failed, do the next retry */
228 DiskResetController(DiskDrive);
229 }
230 }
231
232 /* If we get here then the read failed */
233 DiskError("Disk Read Failed in LBA mode", RegsOut.b.ah);
234 ERR("Disk Read Failed in LBA mode: %x (%s) (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n",
235 RegsOut.b.ah, DiskGetErrorCodeString(RegsOut.b.ah),
236 DiskDrive->DaUa, SectorNumber, SectorCount);
237
238 return FALSE;
239}
BOOLEAN AtaAtapiReadLogicalSectorsLBA(IN OUT PDEVICE_UNIT DeviceUnit, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
Definition: hwide.c:187
unsigned short dx
Definition: pcbios.h:114

Referenced by Pc98DiskReadLogicalSectors().

◆ Pc98InitializeBootDevices()

BOOLEAN Pc98InitializeBootDevices ( VOID  )

Definition at line 721 of file pc98disk.c.

722{
723 PPC98_DISK_DRIVE DiskDrive;
724 UCHAR FakeFloppyDriveNumber = 0x30;
725 UCHAR FakeHardDriveDriveNumber = 0x80;
726 UCHAR FakeCdRomDriveNumber = 0xE0;
727 USHORT DiskEquipment = *(PUSHORT)MEM_DISK_EQUIP & ~(*(PUCHAR)MEM_RDISK_EQUIP);
728 UCHAR IdeDetectedCount;
729 UCHAR i;
730
731 TRACE("Pc98InitializeBootDevices()\n");
732
734
735 /*
736 * Map DA/UA to drive number, i.e.
737 * 0x90 -> 0x30
738 * 0x80 -> 0x80
739 * 0xA0 -> 0x81, etc.
740 */
741
742 /* Map floppies */
743
744 for (i = 0; i < 4; i++)
745 {
746 DiskDrive = &Pc98DiskDrive[FakeFloppyDriveNumber];
747 if (FIRSTBYTE(DiskEquipment) & (1 << i))
748 {
749 if (InitFloppyDrive(0x30 + i, DiskDrive) || InitFloppyDrive(0xB0 + i, DiskDrive) ||
750 InitFloppyDrive(0x90 + i, DiskDrive) || InitFloppyDrive(0x10 + i, DiskDrive))
751 ++FakeFloppyDriveNumber;
752 }
753 }
754
755 for (i = 0; i < 4; i++)
756 {
757 DiskDrive = &Pc98DiskDrive[FakeFloppyDriveNumber];
758 if (FIRSTBYTE(DiskEquipment) & (16 << i))
759 {
760 if (InitFloppyDrive(0x50 + i, DiskDrive))
761 ++FakeFloppyDriveNumber;
762 }
763 }
764
765 for (i = 0; i < 4; i++)
766 {
767 DiskDrive = &Pc98DiskDrive[FakeFloppyDriveNumber];
768 if (SECONDBYTE(DiskEquipment) & (16 << i))
769 {
770 if (InitFloppyDrive(0x70 + i, DiskDrive) || InitFloppyDrive(0xF0 + i, DiskDrive))
771 ++FakeFloppyDriveNumber;
772 }
773 }
774
775 /* Map IDE/SASI drives */
776
777 for (i = 0; i < 4; i++)
778 {
779 DiskDrive = &Pc98DiskDrive[FakeHardDriveDriveNumber];
780 if (InitHardDrive(0x80 + i, DiskDrive) || InitHardDrive(0x00 + i, DiskDrive))
781 ++FakeHardDriveDriveNumber;
782 }
783
784 AtaInit(&IdeDetectedCount);
785 for (i = 0; i <= IdeDetectedCount; i++)
786 {
787 DiskDrive = &Pc98DiskDrive[FakeCdRomDriveNumber];
788 if (InitIdeDrive(i, DiskDrive))
789 ++FakeCdRomDriveNumber;
790 }
791
792 /* Map SCSI drives */
793
794 for (i = 0; i < 7; i++)
795 {
796 DiskDrive = &Pc98DiskDrive[FakeHardDriveDriveNumber];
797 if (InitScsiDrive(0xA0 + i, DiskDrive) || InitScsiDrive(0x20 + i, DiskDrive))
798 {
799 if (DiskDrive->Type & DRIVE_CDROM || DiskDrive->Type & DRIVE_MO)
800 {
801 /* Move to CD-ROM area */
802 Pc98DiskDrive[FakeCdRomDriveNumber] = *DiskDrive;
803 RtlZeroMemory(DiskDrive, sizeof(PC98_DISK_DRIVE));
804 ++FakeCdRomDriveNumber;
805 }
806 else
807 {
808 ++FakeHardDriveDriveNumber;
809 }
810 }
811 }
812
813#if 1
814 // Ugly HACK: Force ISO boot
815 // FIXME: Fill ARC disk blocks completely
816 // to allow usage of CD-ROM root path (See floppy_pc98.ini).
817 FrldrBootDrive = 0xE0;
818 FrldrBootPartition = 0xFF;
819#else
820 /* Reassign boot drive */
821 for (i = 0; i < MAX_DRIVES - 1; i++)
822 {
823 DiskDrive = &Pc98DiskDrive[i];
824 if (DiskDrive->Initialized && DiskDrive->DaUa == FrldrBootDrive)
825 {
826 TRACE("Boot drive: old 0x%x, new 0x%x\n", FrldrBootDrive, i);
828 break;
829 }
830 }
831#endif
832
833 /* Call PC version */
835}
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
Definition: glfuncs.h:248
BOOLEAN PcInitializeBootDevices(VOID)
Definition: hwdisk.c:473
BOOLEAN AtaInit(OUT PUCHAR DetectedCount)
Definition: hwide.c:139
#define MEM_RDISK_EQUIP
Definition: machpc98.h:33
#define MEM_DISK_EQUIP
Definition: machpc98.h:41
static BOOLEAN InitHardDrive(IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
Definition: pc98disk.c:536
static BOOLEAN InitFloppyDrive(IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
Definition: pc98disk.c:605
#define MAX_DRIVES
Definition: pc98disk.c:19
static BOOLEAN InitIdeDrive(IN UCHAR UnitNumber, IN OUT PPC98_DISK_DRIVE DiskDrive)
Definition: pc98disk.c:495
static BOOLEAN InitScsiDrive(IN UCHAR DaUa, IN OUT PPC98_DISK_DRIVE DiskDrive)
Definition: pc98disk.c:390
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
UCHAR FrldrBootDrive
Definition: uefidisk.c:47
ULONG FrldrBootPartition
Definition: uefidisk.c:48
#define SECONDBYTE(VALUE)
Definition: rtlfuncs.h:807
#define FIRSTBYTE(VALUE)
Definition: rtlfuncs.h:806

Referenced by MachInit().

Variable Documentation

◆ lReportError

LONG lReportError = 0
static

Definition at line 26 of file pc98disk.c.

Referenced by DiskError(), and DiskReportError().

◆ Pc98DiskDrive

PC98_DISK_DRIVE Pc98DiskDrive[MAX_DRIVES]

Definition at line 22 of file pc98disk.c.

Referenced by Pc98DiskDriveNumberToDrive(), and Pc98InitializeBootDevices().