[FREELDR]: More local changes merging, part 2/x:
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 28 Jan 2017 23:47:35 +0000 (23:47 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 28 Jan 2017 23:47:35 +0000 (23:47 +0000)
- Move the HW detection code specific to the PC architecture from hardware.c to machpc.c, keeping in hardware.c the code that is shared between PC and XBOX.
- Move what remained of i386disk.c into pcdisk.c (specific to PC architecture) + code formatting.
- Move what remained of xboxhw.c into machxbox.c (specific to XBOX architecture); we discover that some code related to disk management is actually shared with PC architecture (in hwdisk.c): hwdisk.c therefore contains disk-management routines common to both PC & XBOX.
- xboxdisk.c: Code formatting only.
- Cleanup in disk.c/disk.h

svn path=/trunk/; revision=73616

12 files changed:
reactos/boot/freeldr/freeldr/CMakeLists.txt
reactos/boot/freeldr/freeldr/arch/i386/hardware.c
reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c
reactos/boot/freeldr/freeldr/arch/i386/i386disk.c [deleted file]
reactos/boot/freeldr/freeldr/arch/i386/machpc.c
reactos/boot/freeldr/freeldr/arch/i386/machxbox.c
reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c
reactos/boot/freeldr/freeldr/arch/i386/xboxdisk.c
reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c [deleted file]
reactos/boot/freeldr/freeldr/disk/disk.c
reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h
reactos/boot/freeldr/freeldr/include/disk.h

index 970c725..c4ca5b4 100644 (file)
@@ -123,7 +123,6 @@ if(ARCH STREQUAL "i386")
         arch/i386/hwdisk.c
         arch/i386/hwpci.c
         arch/i386/i386bug.c
-        arch/i386/i386disk.c
         arch/i386/i386idt.c
         arch/i386/i386rtl.c
         arch/i386/i386vid.c
@@ -137,7 +136,6 @@ if(ARCH STREQUAL "i386")
         arch/i386/xboxcons.c
         arch/i386/xboxdisk.c
         arch/i386/xboxfont.c
-        arch/i386/xboxhw.c
         arch/i386/xboxi2c.c
         arch/i386/xboxmem.c
         arch/i386/xboxrtc.c
@@ -170,7 +168,6 @@ elseif(ARCH STREQUAL "amd64")
         arch/i386/hwpci.c
         arch/i386/i386bug.c
         arch/i386/i386rtl.c
-        arch/i386/i386disk.c
         arch/i386/i386vid.c
         arch/i386/machpc.c
         arch/i386/pccons.c
index eb24cb1..414f27d 100644 (file)
  */
 
 #include <freeldr.h>
-#include <cportlib/cportlib.h>
 
 #define NDEBUG
 #include <debug.h>
 
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+
 #define MILLISEC     (10)
 #define PRECISION    (8)
 
 #define CLOCK_TICK_RATE (1193182)
 #define LATCH (CLOCK_TICK_RATE / HZ)
 
-
-/* Maximum number of COM and LPT ports */
-#define MAX_COM_PORTS   4
-#define MAX_LPT_PORTS   3
-
-/* No Mouse */
-#define MOUSE_TYPE_NONE            0
-/* Microsoft Mouse with 2 buttons */
-#define MOUSE_TYPE_MICROSOFT       1
-/* Logitech Mouse with 3 buttons */
-#define MOUSE_TYPE_LOGITECH        2
-/* Microsoft Wheel Mouse (aka Z Mouse) */
-#define MOUSE_TYPE_WHEELZ          3
-/* Mouse Systems Mouse */
-#define MOUSE_TYPE_MOUSESYSTEMS    4
-
-
-/* PS2 stuff */
-
-/* Controller registers. */
-#define CONTROLLER_REGISTER_STATUS                      0x64
-#define CONTROLLER_REGISTER_CONTROL                     0x64
-#define CONTROLLER_REGISTER_DATA                        0x60
-
-/* Controller commands. */
-#define CONTROLLER_COMMAND_READ_MODE                    0x20
-#define CONTROLLER_COMMAND_WRITE_MODE                   0x60
-#define CONTROLLER_COMMAND_GET_VERSION                  0xA1
-#define CONTROLLER_COMMAND_MOUSE_DISABLE                0xA7
-#define CONTROLLER_COMMAND_MOUSE_ENABLE                 0xA8
-#define CONTROLLER_COMMAND_TEST_MOUSE                   0xA9
-#define CONTROLLER_COMMAND_SELF_TEST                    0xAA
-#define CONTROLLER_COMMAND_KEYBOARD_TEST                0xAB
-#define CONTROLLER_COMMAND_KEYBOARD_DISABLE             0xAD
-#define CONTROLLER_COMMAND_KEYBOARD_ENABLE              0xAE
-#define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER    0xD3
-#define CONTROLLER_COMMAND_WRITE_MOUSE                  0xD4
-
-/* Controller status */
-#define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL            0x01
-#define CONTROLLER_STATUS_INPUT_BUFFER_FULL             0x02
-#define CONTROLLER_STATUS_SELF_TEST                     0x04
-#define CONTROLLER_STATUS_COMMAND                       0x08
-#define CONTROLLER_STATUS_UNLOCKED                      0x10
-#define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL      0x20
-#define CONTROLLER_STATUS_GENERAL_TIMEOUT               0x40
-#define CONTROLLER_STATUS_PARITY_ERROR                  0x80
-#define AUX_STATUS_OUTPUT_BUFFER_FULL                   (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
-                                                         CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
-
-/* Timeout in ms for sending to keyboard controller. */
-#define CONTROLLER_TIMEOUT                              250
-
-DBG_DEFAULT_CHANNEL(HWDETECT);
-
 static unsigned int delay_count = 1;
-
 extern UCHAR PcBiosDiskCount;
 
 PCHAR
@@ -96,10 +42,9 @@ GetHarddiskIdentifier(
     UCHAR DriveNumber);
 
 BOOLEAN
-HwInitializeBiosDisks(VOID);
-
-/* FUNCTIONS ****************************************************************/
+InitializeBiosDisks(VOID);
 
+/* FUNCTIONS *****************************************************************/
 
 static
 VOID
@@ -109,14 +54,12 @@ __StallExecutionProcessor(ULONG Loops)
     for (i = 0; i < Loops; i++);
 }
 
-
 VOID StallExecutionProcessor(ULONG Microseconds)
 {
     ULONGLONG LoopCount = ((ULONGLONG)delay_count * (ULONGLONG)Microseconds) / 1000ULL;
     __StallExecutionProcessor((ULONG)LoopCount);
 }
 
-
 static
 ULONG
 Read8254Timer(VOID)
@@ -130,7 +73,6 @@ Read8254Timer(VOID)
     return Count;
 }
 
-
 static
 VOID
 WaitFor8254Wraparound(VOID)
@@ -156,7 +98,6 @@ WaitFor8254Wraparound(VOID)
     while (Delta < 300);
 }
 
-
 VOID
 HalpCalibrateStallExecution(VOID)
 {
@@ -225,213 +166,6 @@ HalpCalibrateStallExecution(VOID)
     delay_count /= (MILLISEC / 2);
 }
 
-static
-VOID
-DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
-    PCM_PNP_BIOS_INSTALLATION_CHECK InstData;
-    PCONFIGURATION_COMPONENT_DATA BusKey;
-    ULONG x;
-    ULONG NodeSize = 0;
-    ULONG NodeCount = 0;
-    UCHAR NodeNumber;
-    ULONG FoundNodeCount;
-    int i;
-    ULONG PnpBufferSize;
-    ULONG Size;
-    char *Ptr;
-
-    InstData = (PCM_PNP_BIOS_INSTALLATION_CHECK)PnpBiosSupported();
-    if (InstData == NULL || strncmp((CHAR*)InstData->Signature, "$PnP", 4))
-    {
-        TRACE("PnP-BIOS not supported\n");
-        return;
-    }
-
-    TRACE("PnP-BIOS supported\n");
-    TRACE("Signature '%c%c%c%c'\n",
-          InstData->Signature[0], InstData->Signature[1],
-          InstData->Signature[2], InstData->Signature[3]);
-
-    x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount);
-    if (x == 0x82)
-    {
-        TRACE("PnP-BIOS function 'Get Number of System Device Nodes' not supported\n");
-        return;
-    }
-
-    NodeCount &= 0xFF; // needed since some fscked up BIOSes return
-    // wrong info (e.g. Mac Virtual PC)
-    // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c
-    if (x != 0 || NodeSize == 0 || NodeCount == 0)
-    {
-        ERR("PnP-BIOS failed to enumerate device nodes\n");
-        return;
-    }
-    TRACE("MaxNodeSize %u  NodeCount %u\n", NodeSize, NodeCount);
-    TRACE("Estimated buffer size %u\n", NodeSize * NodeCount);
-
-    /* Set 'Configuration Data' value */
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST)
-           + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK) + (NodeSize * NodeCount);
-    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-    if (PartialResourceList == NULL)
-    {
-        ERR("Failed to allocate resource descriptor\n");
-        return;
-    }
-    memset(PartialResourceList, 0, Size);
-
-    /* Initialize resource descriptor */
-    PartialResourceList->Version = 1;
-    PartialResourceList->Revision = 1;
-    PartialResourceList->Count = 1;
-    PartialResourceList->PartialDescriptors[0].Type =
-        CmResourceTypeDeviceSpecific;
-    PartialResourceList->PartialDescriptors[0].ShareDisposition =
-        CmResourceShareUndetermined;
-
-    /* The buffer starts after PartialResourceList->PartialDescriptors[0] */
-    Ptr = (char *)(PartialResourceList + 1);
-
-    /* Set installation check data */
-    memcpy (Ptr, InstData, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
-    Ptr += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
-
-    /* Copy device nodes */
-    FoundNodeCount = 0;
-    PnpBufferSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
-    for (i = 0; i < 0xFF; i++)
-    {
-        NodeNumber = (UCHAR)i;
-
-        x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer);
-        if (x == 0)
-        {
-            DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DiskReadBuffer;
-
-            TRACE("Node: %u  Size %u (0x%x)\n",
-                  DeviceNode->Node,
-                  DeviceNode->Size,
-                  DeviceNode->Size);
-
-            if (PnpBufferSize + DeviceNode->Size > Size)
-            {
-                ERR("Buffer too small!\n");
-                break;
-            }
-
-            memcpy(Ptr, DeviceNode, DeviceNode->Size);
-
-            Ptr += DeviceNode->Size;
-            PnpBufferSize += DeviceNode->Size;
-
-            FoundNodeCount++;
-            if (FoundNodeCount >= NodeCount)
-                break;
-        }
-    }
-
-    /* Set real data size */
-    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
-        PnpBufferSize;
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + PnpBufferSize;
-
-    TRACE("Real buffer size: %u\n", PnpBufferSize);
-    TRACE("Resource size: %u\n", Size);
-
-    /* Create component key */
-    FldrCreateComponentKey(SystemKey,
-                           AdapterClass,
-                           MultiFunctionAdapter,
-                           0x0,
-                           0x0,
-                           0xFFFFFFFF,
-                           "PNP BIOS",
-                           PartialResourceList,
-                           Size,
-                           &BusKey);
-
-    (*BusNumber)++;
-}
-
-
-
-static PCM_PARTIAL_RESOURCE_LIST
-GetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
-    EXTENDED_GEOMETRY ExtGeometry;
-    GEOMETRY Geometry;
-    ULONG Size;
-
-    //
-    // Initialize returned size
-    //
-    *pSize = 0;
-
-    /* Set 'Configuration Data' value */
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
-           sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
-    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-    if (PartialResourceList == NULL)
-    {
-        ERR("Failed to allocate a full resource descriptor\n");
-        return NULL;
-    }
-
-    memset(PartialResourceList, 0, Size);
-    PartialResourceList->Version = 1;
-    PartialResourceList->Revision = 1;
-    PartialResourceList->Count = 1;
-    PartialResourceList->PartialDescriptors[0].Type =
-        CmResourceTypeDeviceSpecific;
-//  PartialResourceList->PartialDescriptors[0].ShareDisposition =
-//  PartialResourceList->PartialDescriptors[0].Flags =
-    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
-        sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
-
-    /* Get pointer to geometry data */
-    DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
-
-    /* Get the disk geometry */
-    ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
-    if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
-    {
-        DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
-        DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
-        DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
-        DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
-    }
-    else if(MachDiskGetDriveGeometry(DriveNumber, &Geometry))
-    {
-        DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
-        DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
-        DiskGeometry->SectorsPerTrack = Geometry.Sectors;
-        DiskGeometry->NumberOfHeads = Geometry.Heads;
-    }
-    else
-    {
-        TRACE("Reading disk geometry failed\n");
-        FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
-        return NULL;
-    }
-    TRACE("Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
-          DriveNumber,
-          DiskGeometry->NumberOfCylinders,
-          DiskGeometry->NumberOfHeads,
-          DiskGeometry->SectorsPerTrack,
-          DiskGeometry->BytesPerSector);
-
-    //
-    // Return configuration data
-    //
-    *pSize = Size;
-    return PartialResourceList;
-}
 
 static
 UCHAR
@@ -445,7 +179,6 @@ GetFloppyCount(VOID)
     return ((Data & 0xF0) ? 1 : 0) + ((Data & 0x0F) ? 1 : 0);
 }
 
-
 static
 UCHAR
 GetFloppyType(UCHAR DriveNumber)
@@ -463,7 +196,6 @@ GetFloppyType(UCHAR DriveNumber)
     return 0;
 }
 
-
 static
 PVOID
 GetInt1eTable(VOID)
@@ -474,7 +206,6 @@ GetInt1eTable(VOID)
     return (PVOID)((ULONG_PTR)(((ULONG)(*SegPtr)) << 4) + (ULONG)(*OfsPtr));
 }
 
-
 static
 VOID
 DetectBiosFloppyPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey)
@@ -546,9 +277,8 @@ DetectBiosFloppyPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey)
     }
 }
 
-
 static
-VOID
+PCONFIGURATION_COMPONENT_DATA
 DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey)
 {
     PCONFIGURATION_COMPONENT_DATA ControllerKey;
@@ -558,16 +288,16 @@ DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey)
     ULONG FloppyCount;
 
     FloppyCount = GetFloppyCount();
-    TRACE("Floppy count: %u\n",
-          FloppyCount);
+    TRACE("Floppy count: %u\n", FloppyCount);
 
+    /* Always create a BIOS disk controller, no matter if we have floppy drives or not */
     Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
            2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
     PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
     if (PartialResourceList == NULL)
     {
         ERR("Failed to allocate resource descriptor\n");
-        return;
+        return NULL;
     }
     memset(PartialResourceList, 0, Size);
 
@@ -615,10 +345,12 @@ DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey)
                            &ControllerKey);
     TRACE("Created key: DiskController\\0\n");
 
-    if (FloppyCount) DetectBiosFloppyPeripheral(ControllerKey);
+    if (FloppyCount)
+        DetectBiosFloppyPeripheral(ControllerKey);
+
+    return ControllerKey;
 }
 
-static
 PCONFIGURATION_COMPONENT_DATA
 DetectSystem(VOID)
 {
@@ -688,24 +420,25 @@ DetectSystem(VOID)
     return SystemKey;
 }
 
-static
+extern PCM_PARTIAL_RESOURCE_LIST
+PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize);
+
+#define GetHarddiskConfigurationData PcGetHarddiskConfigurationData
+
+// static
 VOID
 DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey)
 {
-    PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
+    PCONFIGURATION_COMPONENT_DATA ControllerKey, DiskKey;
     ULONG i;
 
-    FldrCreateComponentKey(BusKey,
-                           ControllerClass,
-                           DiskController,
-                           Output | Input,
-                           0x0,
-                           0xFFFFFFFF,
-                           NULL,
-                           NULL,
-                           0,
-                           &ControllerKey);
-    TRACE("Created key: DiskController\\0\n");
+    /* Use the floppy disk controller as our controller */
+    ControllerKey = DetectBiosFloppyController(BusKey);
+    if (!ControllerKey)
+    {
+        ERR("Failed to detect BIOS disk controller\n");
+        return;
+    }
 
     /* Create and fill subkey for each harddisk */
     for (i = 0; i < PcBiosDiskCount; i++)
@@ -733,1133 +466,47 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey)
     }
 }
 
-static
 VOID
-InitializeSerialPort(PUCHAR Port,
-                     UCHAR LineControl)
-{
-    WRITE_PORT_UCHAR(Port + 3, 0x80);  /* set DLAB on   */
-    WRITE_PORT_UCHAR(Port,     0x60);  /* speed LO byte */
-    WRITE_PORT_UCHAR(Port + 1, 0);     /* speed HI byte */
-    WRITE_PORT_UCHAR(Port + 3, LineControl);
-    WRITE_PORT_UCHAR(Port + 1, 0);     /* set comm and DLAB to 0 */
-    WRITE_PORT_UCHAR(Port + 4, 0x09);  /* DR int enable */
-    READ_PORT_UCHAR(Port + 5);  /* clear error bits */
-}
-
-
-static
-ULONG
-DetectSerialMouse(PUCHAR Port)
-{
-    CHAR Buffer[4];
-    ULONG i;
-    ULONG TimeOut;
-    UCHAR LineControl;
-
-    /* Shutdown mouse or something like that */
-    LineControl = READ_PORT_UCHAR(Port + 4);
-    WRITE_PORT_UCHAR(Port + 4, (LineControl & ~0x02) | 0x01);
-    StallExecutionProcessor(100000);
-
-    /*
-     * Clear buffer
-     * Maybe there is no serial port although BIOS reported one (this
-     * is the case on Apple hardware), or the serial port is misbehaving,
-     * therefore we must give up after some time.
-     */
-    TimeOut = 200;
-    while (READ_PORT_UCHAR(Port + 5) & 0x01)
-    {
-        if (--TimeOut == 0)
-            return MOUSE_TYPE_NONE;
-        READ_PORT_UCHAR(Port);
-    }
-
-    /*
-     * Send modem control with 'Data Terminal Ready', 'Request To Send' and
-     * 'Output Line 2' message. This enables mouse to identify.
-     */
-    WRITE_PORT_UCHAR(Port + 4, 0x0b);
-
-    /* Wait 10 milliseconds for the mouse getting ready */
-    StallExecutionProcessor(10000);
-
-    /* Read first four bytes, which contains Microsoft Mouse signs */
-    TimeOut = 200;
-    for (i = 0; i < 4; i++)
-    {
-        while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
-        {
-            StallExecutionProcessor(1000);
-            --TimeOut;
-            if (TimeOut == 0)
-                return MOUSE_TYPE_NONE;
-        }
-        Buffer[i] = READ_PORT_UCHAR(Port);
-    }
-
-    TRACE("Mouse data: %x %x %x %x\n",
-          Buffer[0], Buffer[1], Buffer[2], Buffer[3]);
-
-    /* Check that four bytes for signs */
-    for (i = 0; i < 4; ++i)
-    {
-        if (Buffer[i] == 'B')
-        {
-            /* Sign for Microsoft Ballpoint */
-//      DbgPrint("Microsoft Ballpoint device detected\n");
-//      DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
-            return MOUSE_TYPE_NONE;
-        }
-        else if (Buffer[i] == 'M')
-        {
-            /* Sign for Microsoft Mouse protocol followed by button specifier */
-            if (i == 3)
-            {
-                /* Overflow Error */
-                return MOUSE_TYPE_NONE;
-            }
-
-            switch (Buffer[i + 1])
-            {
-            case '3':
-                TRACE("Microsoft Mouse with 3-buttons detected\n");
-                return MOUSE_TYPE_LOGITECH;
-
-            case 'Z':
-                TRACE("Microsoft Wheel Mouse detected\n");
-                return MOUSE_TYPE_WHEELZ;
-
-                /* case '2': */
-            default:
-                TRACE("Microsoft Mouse with 2-buttons detected\n");
-                return MOUSE_TYPE_MICROSOFT;
-            }
-        }
-    }
-
-    return MOUSE_TYPE_NONE;
-}
-
-
-static ULONG
-GetSerialMousePnpId(PUCHAR Port, char *Buffer)
+FrLdrCheckCpuCompatibility(VOID)
 {
-    ULONG TimeOut;
-    ULONG i = 0;
-    char c;
-    char x;
-
-    WRITE_PORT_UCHAR(Port + 4, 0x09);
-
-    /* Wait 10 milliseconds for the mouse getting ready */
-    StallExecutionProcessor(10000);
-
-    WRITE_PORT_UCHAR(Port + 4, 0x0b);
-
-    StallExecutionProcessor(10000);
-
-    for (;;)
-    {
-        TimeOut = 200;
-        while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
-        {
-            StallExecutionProcessor(1000);
-            --TimeOut;
-            if (TimeOut == 0)
-            {
-                return 0;
-            }
-        }
+    INT CpuInformation[4] = {-1};
+    ULONG NumberOfIds;
 
-        c = READ_PORT_UCHAR(Port);
-        if (c == 0x08 || c == 0x28)
-            break;
-    }
+    /* Check if the processor first supports ID 1 */
+    __cpuid(CpuInformation, 0);
 
-    Buffer[i++] = c;
-    x = c + 1;
+    NumberOfIds = CpuInformation[0];
 
-    for (;;)
+    if (NumberOfIds == 0)
     {
-        TimeOut = 200;
-        while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
-        {
-            StallExecutionProcessor(1000);
-            --TimeOut;
-            if (TimeOut == 0)
-                return 0;
-        }
-        c = READ_PORT_UCHAR(Port);
-        Buffer[i++] = c;
-        if (c == x)
-            break;
-        if (i >= 256)
-            break;
+        FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
+                                 __FILE__,
+                                 __LINE__,
+                                 "ReactOS requires the CPUID instruction to return "
+                                 "more than one supported ID.\n\n");
     }
 
-    return i;
-}
-
-
-static
-VOID
-DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey,
-                              PUCHAR Base)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    char Buffer[256];
-    CHAR Identifier[256];
-    PCONFIGURATION_COMPONENT_DATA PeripheralKey;
-    ULONG MouseType;
-    ULONG Size, Length;
-    ULONG i;
-    ULONG j;
-    ULONG k;
-
-    TRACE("DetectSerialPointerPeripheral()\n");
-
-    Identifier[0] = 0;
-
-    InitializeSerialPort(Base, 2);
-    MouseType = DetectSerialMouse(Base);
-
-    if (MouseType != MOUSE_TYPE_NONE)
+    /* NumberOfIds will be greater than 1 if the processor is new enough */
+    if (NumberOfIds == 1)
     {
-        Length = GetSerialMousePnpId(Base, Buffer);
-        TRACE( "PnP ID length: %u\n", Length);
+        INT ProcessorFamily;
 
-        if (Length != 0)
-        {
-            /* Convert PnP sting to ASCII */
-            if (Buffer[0] == 0x08)
-            {
-                for (i = 0; i < Length; i++)
-                    Buffer[i] += 0x20;
-            }
-            Buffer[Length] = 0;
-
-            TRACE("PnP ID string: %s\n", Buffer);
-
-            /* Copy PnpId string */
-            for (i = 0; i < 7; i++)
-            {
-                Identifier[i] = Buffer[3 + i];
-            }
-            memcpy(&Identifier[7],
-                   L" - ",
-                   3 * sizeof(WCHAR));
-
-            /* Skip device serial number */
-            i = 10;
-            if (Buffer[i] == '\\')
-            {
-                for (j = ++i; i < Length; ++i)
-                {
-                    if (Buffer[i] == '\\')
-                        break;
-                }
-                if (i >= Length)
-                    i -= 3;
-            }
-
-            /* Skip PnP class */
-            if (Buffer[i] == '\\')
-            {
-                for (j = ++i; i < Length; ++i)
-                {
-                    if (Buffer[i] == '\\')
-                        break;
-                }
-
-                if (i >= Length)
-                    i -= 3;
-            }
-
-            /* Skip compatible PnP Id */
-            if (Buffer[i] == '\\')
-            {
-                for (j = ++i; i < Length; ++i)
-                {
-                    if (Buffer[i] == '\\')
-                        break;
-                }
-                if (Buffer[j] == '*')
-                    ++j;
-                if (i >= Length)
-                    i -= 3;
-            }
-
-            /* Get product description */
-            if (Buffer[i] == '\\')
-            {
-                for (j = ++i; i < Length; ++i)
-                {
-                    if (Buffer[i] == ';')
-                        break;
-                }
-                if (i >= Length)
-                    i -= 3;
-                if (i > j + 1)
-                {
-                    for (k = 0; k < i - j; k++)
-                    {
-                        Identifier[k + 10] = Buffer[k + j];
-                    }
-                    Identifier[10 + (i - j)] = 0;
-                }
-            }
-
-            TRACE("Identifier string: %s\n", Identifier);
-        }
+        /* Get information */
+        __cpuid(CpuInformation, 1);
 
-        if (Length == 0 || strlen(Identifier) < 11)
-        {
-            switch (MouseType)
-            {
-            case MOUSE_TYPE_LOGITECH:
-                strcpy(Identifier, "LOGITECH SERIAL MOUSE");
-                break;
-
-            case MOUSE_TYPE_WHEELZ:
-                strcpy(Identifier, "MICROSOFT SERIAL MOUSE WITH WHEEL");
-                break;
-
-            case MOUSE_TYPE_MICROSOFT:
-            default:
-                strcpy(Identifier, "MICROSOFT SERIAL MOUSE");
-                break;
-            }
-        }
+        ProcessorFamily = (CpuInformation[0] >> 8) & 0xF;
 
-        /* Set 'Configuration Data' value */
-        Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
-               sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-        if (PartialResourceList == NULL)
+        /* If it's Family 4 or lower, bugcheck */
+        if (ProcessorFamily < 5)
         {
-            ERR("Failed to allocate resource descriptor\n");
-            return;
+            FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
+                                     __FILE__,
+                                     __LINE__,
+                                     "Processor is too old (family %u < 5)\n"
+                                     "ReactOS requires a Pentium-level processor or newer.",
+                                     ProcessorFamily);
         }
-        memset(PartialResourceList, 0, Size);
-        PartialResourceList->Version = 1;
-        PartialResourceList->Revision = 1;
-        PartialResourceList->Count = 0;
-
-        /* Create 'PointerPeripheral' key */
-        FldrCreateComponentKey(ControllerKey,
-                               PeripheralClass,
-                               PointerPeripheral,
-                               Input,
-                               0x0,
-                               0xFFFFFFFF,
-                               Identifier,
-                               PartialResourceList,
-                               Size,
-                               &PeripheralKey);
-
-        TRACE("Created key: PointerPeripheral\\0\n");
     }
 }
 
-
-static
-VOID
-DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
-    PCM_SERIAL_DEVICE_DATA SerialDeviceData;
-    ULONG Irq[MAX_COM_PORTS] = {4, 3, 4, 3};
-    ULONG Base;
-    CHAR Buffer[80];
-    PUSHORT BasePtr;
-    ULONG ControllerNumber = 0;
-    PCONFIGURATION_COMPONENT_DATA ControllerKey;
-    ULONG i;
-    ULONG Size;
-
-    TRACE("DetectSerialPorts()\n");
-
-    /*
-     * The BIOS data area 0x400 holds the address of the first valid COM port.
-     * Each COM port address is stored in a 2-byte field.
-     * Infos at: http://www.bioscentral.com/misc/bda.htm
-     */
-    BasePtr = (PUSHORT)0x400;
-
-    for (i = 0; i < MAX_COM_PORTS; i++, BasePtr++)
-    {
-        Base = (ULONG) * BasePtr;
-        if (Base == 0 || !CpDoesPortExist((PUCHAR)Base))
-            continue;
-
-        TRACE("Found COM%u port at 0x%x\n", i + 1, Base);
-
-        /* Set 'Identifier' value */
-        sprintf(Buffer, "COM%ld", i + 1);
-
-        /* Build full device descriptor */
-        Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
-               2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
-               sizeof(CM_SERIAL_DEVICE_DATA);
-        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-        if (PartialResourceList == NULL)
-        {
-            ERR("Failed to allocate resource descriptor\n");
-            continue;
-        }
-        memset(PartialResourceList, 0, Size);
-
-        /* Initialize resource descriptor */
-        PartialResourceList->Version = 1;
-        PartialResourceList->Revision = 1;
-        PartialResourceList->Count = 3;
-
-        /* Set IO Port */
-        PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
-        PartialDescriptor->Type = CmResourceTypePort;
-        PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-        PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
-        PartialDescriptor->u.Port.Start.LowPart = Base;
-        PartialDescriptor->u.Port.Start.HighPart = 0x0;
-        PartialDescriptor->u.Port.Length = 7;
-
-        /* Set Interrupt */
-        PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
-        PartialDescriptor->Type = CmResourceTypeInterrupt;
-        PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
-        PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
-        PartialDescriptor->u.Interrupt.Level = Irq[i];
-        PartialDescriptor->u.Interrupt.Vector = Irq[i];
-        PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
-
-        /* Set serial data (device specific) */
-        PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
-        PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
-        PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
-        PartialDescriptor->Flags = 0;
-        PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_SERIAL_DEVICE_DATA);
-
-        SerialDeviceData =
-            (PCM_SERIAL_DEVICE_DATA)&PartialResourceList->PartialDescriptors[3];
-        SerialDeviceData->BaudClock = 1843200; /* UART Clock frequency (Hertz) */
-
-        /* Create controller key */
-        FldrCreateComponentKey(BusKey,
-                               ControllerClass,
-                               SerialController,
-                               Output | Input | ConsoleIn | ConsoleOut,
-                               ControllerNumber,
-                               0xFFFFFFFF,
-                               Buffer,
-                               PartialResourceList,
-                               Size,
-                               &ControllerKey);
-
-        if (!Rs232PortInUse(UlongToPtr(Base)))
-        {
-            /* Detect serial mouse */
-            DetectSerialPointerPeripheral(ControllerKey, UlongToPtr(Base));
-        }
-
-        ControllerNumber++;
-    }
-}
-
-
-static VOID
-DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
-    ULONG Irq[MAX_LPT_PORTS] = {7, 5, (ULONG) - 1};
-    CHAR Buffer[80];
-    PCONFIGURATION_COMPONENT_DATA ControllerKey;
-    PUSHORT BasePtr;
-    ULONG Base;
-    ULONG ControllerNumber = 0;
-    ULONG i;
-    ULONG Size;
-
-    TRACE("DetectParallelPorts() called\n");
-
-    /*
-     * The BIOS data area 0x408 holds the address of the first valid LPT port.
-     * Each LPT port address is stored in a 2-byte field.
-     * Infos at: http://www.bioscentral.com/misc/bda.htm
-     */
-    BasePtr = (PUSHORT)0x408;
-
-    for (i = 0; i < MAX_LPT_PORTS; i++, BasePtr++)
-    {
-        Base = (ULONG) * BasePtr;
-        if (Base == 0)
-            continue;
-
-        TRACE("Parallel port %u: %x\n", ControllerNumber, Base);
-
-        /* Set 'Identifier' value */
-        sprintf(Buffer, "PARALLEL%ld", i + 1);
-
-        /* Build full device descriptor */
-        Size = sizeof(CM_PARTIAL_RESOURCE_LIST);
-        if (Irq[i] != (ULONG) - 1)
-            Size += sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-
-        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-        if (PartialResourceList == NULL)
-        {
-            ERR("Failed to allocate resource descriptor\n");
-            continue;
-        }
-        memset(PartialResourceList, 0, Size);
-
-        /* Initialize resource descriptor */
-        PartialResourceList->Version = 1;
-        PartialResourceList->Revision = 1;
-        PartialResourceList->Count = (Irq[i] != (ULONG) - 1) ? 2 : 1;
-
-        /* Set IO Port */
-        PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
-        PartialDescriptor->Type = CmResourceTypePort;
-        PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-        PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
-        PartialDescriptor->u.Port.Start.LowPart = Base;
-        PartialDescriptor->u.Port.Start.HighPart = 0x0;
-        PartialDescriptor->u.Port.Length = 3;
-
-        /* Set Interrupt */
-        if (Irq[i] != (ULONG) - 1)
-        {
-            PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
-            PartialDescriptor->Type = CmResourceTypeInterrupt;
-            PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
-            PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
-            PartialDescriptor->u.Interrupt.Level = Irq[i];
-            PartialDescriptor->u.Interrupt.Vector = Irq[i];
-            PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
-        }
-
-        /* Create controller key */
-        FldrCreateComponentKey(BusKey,
-                               ControllerClass,
-                               ParallelController,
-                               Output,
-                               ControllerNumber,
-                               0xFFFFFFFF,
-                               Buffer,
-                               PartialResourceList,
-                               Size,
-                               &ControllerKey);
-
-        ControllerNumber++;
-    }
-
-    TRACE("DetectParallelPorts() done\n");
-}
-
-
-//static
-BOOLEAN
-DetectKeyboardDevice(VOID)
-{
-    UCHAR Status;
-    UCHAR Scancode;
-    ULONG Loops;
-    BOOLEAN Result = TRUE;
-
-    /* Identify device */
-    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
-
-    /* Wait for reply */
-    for (Loops = 0; Loops < 100; Loops++)
-    {
-        StallExecutionProcessor(10000);
-        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-        if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
-            break;
-    }
-
-    if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
-    {
-        /* PC/XT keyboard or no keyboard */
-        Result = FALSE;
-    }
-
-    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
-    if (Scancode != 0xFA)
-    {
-        /* No ACK received */
-        Result = FALSE;
-    }
-
-    StallExecutionProcessor(10000);
-
-    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-    if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
-    {
-        /* Found AT keyboard */
-        return Result;
-    }
-
-    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
-    if (Scancode != 0xAB)
-    {
-        /* No 0xAB received */
-        Result = FALSE;
-    }
-
-    StallExecutionProcessor(10000);
-
-    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-    if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
-    {
-        /* No byte in buffer */
-        Result = FALSE;
-    }
-
-    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
-    if (Scancode != 0x41)
-    {
-        /* No 0x41 received */
-        Result = FALSE;
-    }
-
-    /* Found MF-II keyboard */
-    return Result;
-}
-
-
-static VOID
-DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
-    PCM_KEYBOARD_DEVICE_DATA KeyboardData;
-    PCONFIGURATION_COMPONENT_DATA PeripheralKey;
-    ULONG Size;
-
-    /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2
-    if (DetectKeyboardDevice()) */
-    {
-        /* Set 'Configuration Data' value */
-        Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
-               sizeof(CM_KEYBOARD_DEVICE_DATA);
-        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-        if (PartialResourceList == NULL)
-        {
-            ERR("Failed to allocate resource descriptor\n");
-            return;
-        }
-
-        /* Initialize resource descriptor */
-        memset(PartialResourceList, 0, Size);
-        PartialResourceList->Version = 1;
-        PartialResourceList->Revision = 1;
-        PartialResourceList->Count = 1;
-
-        PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
-        PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
-        PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
-        PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA);
-
-        KeyboardData = (PCM_KEYBOARD_DEVICE_DATA)(PartialDescriptor + 1);
-        KeyboardData->Version = 1;
-        KeyboardData->Revision = 1;
-        KeyboardData->Type = 4;
-        KeyboardData->Subtype = 0;
-        KeyboardData->KeyboardFlags = 0x20;
-
-        /* Create controller key */
-        FldrCreateComponentKey(ControllerKey,
-                               PeripheralClass,
-                               KeyboardPeripheral,
-                               Input | ConsoleIn,
-                               0x0,
-                               0xFFFFFFFF,
-                               "PCAT_ENHANCED",
-                               PartialResourceList,
-                               Size,
-                               &PeripheralKey);
-        TRACE("Created key: KeyboardPeripheral\\0\n");
-    }
-}
-
-
-static
-VOID
-DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
-    PCONFIGURATION_COMPONENT_DATA ControllerKey;
-    ULONG Size;
-
-    /* Set 'Configuration Data' value */
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
-           2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-    if (PartialResourceList == NULL)
-    {
-        ERR("Failed to allocate resource descriptor\n");
-        return;
-    }
-
-    /* Initialize resource descriptor */
-    memset(PartialResourceList, 0, Size);
-    PartialResourceList->Version = 1;
-    PartialResourceList->Revision = 1;
-    PartialResourceList->Count = 3;
-
-    /* Set Interrupt */
-    PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
-    PartialDescriptor->Type = CmResourceTypeInterrupt;
-    PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
-    PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
-    PartialDescriptor->u.Interrupt.Level = 1;
-    PartialDescriptor->u.Interrupt.Vector = 1;
-    PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
-
-    /* Set IO Port 0x60 */
-    PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
-    PartialDescriptor->Type = CmResourceTypePort;
-    PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-    PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
-    PartialDescriptor->u.Port.Start.LowPart = 0x60;
-    PartialDescriptor->u.Port.Start.HighPart = 0x0;
-    PartialDescriptor->u.Port.Length = 1;
-
-    /* Set IO Port 0x64 */
-    PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
-    PartialDescriptor->Type = CmResourceTypePort;
-    PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-    PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
-    PartialDescriptor->u.Port.Start.LowPart = 0x64;
-    PartialDescriptor->u.Port.Start.HighPart = 0x0;
-    PartialDescriptor->u.Port.Length = 1;
-
-    /* Create controller key */
-    FldrCreateComponentKey(BusKey,
-                           ControllerClass,
-                           KeyboardController,
-                           Input | ConsoleIn,
-                           0x0,
-                           0xFFFFFFFF,
-                           NULL,
-                           PartialResourceList,
-                           Size,
-                           &ControllerKey);
-    TRACE("Created key: KeyboardController\\0\n");
-
-    DetectKeyboardPeripheral(ControllerKey);
-}
-
-
-static
-VOID
-PS2ControllerWait(VOID)
-{
-    ULONG Timeout;
-    UCHAR Status;
-
-    for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
-    {
-        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-        if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
-            return;
-
-        /* Sleep for one millisecond */
-        StallExecutionProcessor(1000);
-    }
-}
-
-
-static
-BOOLEAN
-DetectPS2AuxPort(VOID)
-{
-#if 1
-    /* Current detection is too unreliable. Just do as if
-     * the PS/2 aux port is always present
-     */
-    return TRUE;
-#else
-    ULONG Loops;
-    UCHAR Status;
-
-    /* Put the value 0x5A in the output buffer using the
-     * "WriteAuxiliary Device Output Buffer" command (0xD3).
-     * Poll the Status Register for a while to see if the value really turns up
-     * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
-     * to 1 in the Status Register, we assume this controller has an
-     *  Auxiliary Port (a.k.a. Mouse Port).
-     */
-    PS2ControllerWait();
-    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
-                     CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
-    PS2ControllerWait();
-
-    /* 0x5A is a random dummy value */
-    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
-                     0x5A);
-
-    for (Loops = 0; Loops < 10; Loops++)
-    {
-        StallExecutionProcessor(10000);
-        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-        if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
-            break;
-    }
-
-    READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
-
-    return (Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL);
-#endif
-}
-
-
-static
-BOOLEAN
-DetectPS2AuxDevice(VOID)
-{
-    UCHAR Scancode;
-    UCHAR Status;
-    ULONG Loops;
-    BOOLEAN Result = TRUE;
-
-    PS2ControllerWait();
-    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
-                     CONTROLLER_COMMAND_WRITE_MOUSE);
-    PS2ControllerWait();
-
-    /* Identify device */
-    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
-
-    /* Wait for reply */
-    for (Loops = 0; Loops < 100; Loops++)
-    {
-        StallExecutionProcessor(10000);
-        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-        if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
-            break;
-    }
-
-    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-    if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
-        Result = FALSE;
-
-    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
-    if (Scancode != 0xFA)
-        Result = FALSE;
-
-    StallExecutionProcessor(10000);
-
-    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
-    if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
-        Result = FALSE;
-
-    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
-    if (Scancode != 0x00)
-        Result = FALSE;
-
-    return Result;
-}
-
-
-static
-VOID
-DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCONFIGURATION_COMPONENT_DATA ControllerKey;
-    PCONFIGURATION_COMPONENT_DATA PeripheralKey;
-    ULONG Size;
-
-    if (DetectPS2AuxPort())
-    {
-        TRACE("Detected PS2 port\n");
-
-        PartialResourceList = FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST), TAG_HW_RESOURCE_LIST);
-        if (PartialResourceList == NULL)
-        {
-            ERR("Failed to allocate resource descriptor\n");
-            return;
-        }
-        memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST));
-
-        /* Initialize resource descriptor */
-        PartialResourceList->Version = 1;
-        PartialResourceList->Revision = 1;
-        PartialResourceList->Count = 1;
-
-        /* Set Interrupt */
-        PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeInterrupt;
-        PartialResourceList->PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
-        PartialResourceList->PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
-        PartialResourceList->PartialDescriptors[0].u.Interrupt.Level = 12;
-        PartialResourceList->PartialDescriptors[0].u.Interrupt.Vector = 12;
-        PartialResourceList->PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
-
-        /* Create controller key */
-        FldrCreateComponentKey(BusKey,
-                               ControllerClass,
-                               PointerController,
-                               Input,
-                               0x0,
-                               0xFFFFFFFF,
-                               NULL,
-                               PartialResourceList,
-                               sizeof(CM_PARTIAL_RESOURCE_LIST),
-                               &ControllerKey);
-        TRACE("Created key: PointerController\\0\n");
-
-        if (DetectPS2AuxDevice())
-        {
-            TRACE("Detected PS2 mouse\n");
-
-            /* Initialize resource descriptor */
-            Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
-                   sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-            PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-            if (PartialResourceList == NULL)
-            {
-                ERR("Failed to allocate resource descriptor\n");
-                return;
-            }
-            memset(PartialResourceList, 0, Size);
-            PartialResourceList->Version = 1;
-            PartialResourceList->Revision = 1;
-            PartialResourceList->Count = 0;
-
-            /* Create peripheral key */
-            FldrCreateComponentKey(ControllerKey,
-                                   ControllerClass,
-                                   PointerPeripheral,
-                                   Input,
-                                   0x0,
-                                   0xFFFFFFFF,
-                                   "MICROSOFT PS2 MOUSE",
-                                   PartialResourceList,
-                                   Size,
-                                   &PeripheralKey);
-            TRACE("Created key: PointerPeripheral\\0\n");
-        }
-    }
-}
-
-
-static VOID
-DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
-    CHAR Buffer[80];
-    PCONFIGURATION_COMPONENT_DATA ControllerKey;
-    USHORT VesaVersion;
-
-    /* FIXME: Set 'ComponentInformation' value */
-
-    VesaVersion = BiosIsVesaSupported();
-    if (VesaVersion != 0)
-    {
-        TRACE("VESA version %c.%c\n",
-              (VesaVersion >> 8) + '0',
-              (VesaVersion & 0xFF) + '0');
-    }
-    else
-    {
-        TRACE("VESA not supported\n");
-    }
-
-    if (VesaVersion >= 0x0200)
-    {
-        strcpy(Buffer, "VBE Display");
-    }
-    else
-    {
-        strcpy(Buffer, "VGA Display");
-    }
-
-    FldrCreateComponentKey(BusKey,
-                           ControllerClass,
-                           DisplayController,
-                           0x0,
-                           0x0,
-                           0xFFFFFFFF,
-                           Buffer,
-                           NULL,
-                           0,
-                           &ControllerKey);
-    TRACE("Created key: DisplayController\\0\n");
-
-    /* FIXME: Add display peripheral (monitor) data */
-    if (VesaVersion != 0)
-    {
-        if (BiosIsVesaDdcSupported())
-        {
-            TRACE("VESA/DDC supported!\n");
-            if (BiosVesaReadEdid())
-            {
-                TRACE("EDID data read successfully!\n");
-
-            }
-        }
-    }
-}
-
-
-static
-VOID
-DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCONFIGURATION_COMPONENT_DATA BusKey;
-    ULONG Size;
-
-    /* Increment bus number */
-    (*BusNumber)++;
-
-    /* Set 'Configuration Data' value */
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
-           sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-    if (PartialResourceList == NULL)
-    {
-        ERR("Failed to allocate resource descriptor\n");
-        return;
-    }
-
-    /* Initialize resource descriptor */
-    memset(PartialResourceList, 0, Size);
-    PartialResourceList->Version = 1;
-    PartialResourceList->Revision = 1;
-    PartialResourceList->Count = 0;
-
-    /* Create new bus key */
-    FldrCreateComponentKey(SystemKey,
-                           AdapterClass,
-                           MultiFunctionAdapter,
-                           0x0,
-                           0x0,
-                           0xFFFFFFFF,
-                           "ISA",
-                           PartialResourceList,
-                           Size,
-                           &BusKey);
-
-    /* Detect ISA/BIOS devices */
-    DetectBiosDisks(BusKey);
-
-    DetectBiosFloppyController(BusKey);
-
-    DetectSerialPorts(BusKey);
-
-    DetectParallelPorts(BusKey);
-
-    DetectKeyboardController(BusKey);
-
-    DetectPS2Mouse(BusKey);
-
-    DetectDisplayController(BusKey);
-
-    /* FIXME: Detect more ISA devices */
-}
-
-BOOLEAN
-PcInitializeBootDevices(VOID)
-{
-    return HwInitializeBiosDisks();
-}
-
-PCONFIGURATION_COMPONENT_DATA
-PcHwDetect(VOID)
-{
-    PCONFIGURATION_COMPONENT_DATA SystemKey;
-    ULONG BusNumber = 0;
-
-    TRACE("DetectHardware()\n");
-
-    /* Create the 'System' key */
-    SystemKey = DetectSystem();
-
-    /* Detect buses */
-    DetectPciBios(SystemKey, &BusNumber);
-    DetectApmBios(SystemKey, &BusNumber);
-    DetectPnpBios(SystemKey, &BusNumber);
-    DetectIsaBios(SystemKey, &BusNumber);
-    DetectAcpiBios(SystemKey, &BusNumber);
-
-    TRACE("DetectHardware() Done\n");
-
-    return SystemKey;
-}
-
-VOID
-PcHwIdle(VOID)
-{
-    REGS Regs;
-
-    /* Select APM 1.0+ function */
-    Regs.b.ah = 0x53;
-
-    /* Function 05h: CPU idle */
-    Regs.b.al = 0x05;
-
-    /* Call INT 15h */
-    Int386(0x15, &Regs, &Regs);
-
-    /* Check if successfull (CF set on error) */
-    if (INT386_SUCCESS(Regs))
-        return;
-
-    /*
-     * No futher processing here.
-     * Optionally implement HLT instruction handling.
-   */
-}
-
-VOID
-FrLdrCheckCpuCompatibility(VOID)
-{
-    INT CpuInformation[4] = {-1};
-    ULONG NumberOfIds;
-
-    /* Check if the processor first supports ID 1 */
-    __cpuid(CpuInformation, 0);
-
-    NumberOfIds = CpuInformation[0];
-
-    if (NumberOfIds == 0)
-    {
-        FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
-                                 __FILE__,
-                                 __LINE__,
-                                 "ReactOS requires the CPUID instruction to return "
-                                 "more than one supported ID.\n\n");
-    }
-
-    /* NumberOfIds will be greater than 1 if the processor is new enough. */
-    if (NumberOfIds == 1)
-    {
-        INT ProcessorFamily;
-
-        /* Get information. */
-        __cpuid(CpuInformation, 1);
-
-        ProcessorFamily = (CpuInformation[0] >> 8) & 0xF;
-
-        /* If it's Family 4 or lower, bugcheck. */
-        if(ProcessorFamily < 5)
-        {
-            FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
-                                     __FILE__,
-                                     __LINE__,
-                                     "Processor is too old (family %u < 5)\n"
-                                     "ReactOS requires a Pentium-level processor or newer.",
-                                     ProcessorFamily);
-        }
-    }
-}
-
-
 /* EOF */
index a5889e3..e251d4d 100644 (file)
@@ -39,13 +39,19 @@ extern ULONG reactos_disk_count;
 extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
 
 static CHAR Hex[] = "0123456789abcdef";
+
 UCHAR PcBiosDiskCount = 0;
-CHAR PcDiskIdentifier[32][20];
+static CHAR PcDiskIdentifier[32][20];
+
 PVOID DiskReadBuffer;
 SIZE_T DiskReadBufferSize;
 
 
-static ARC_STATUS DiskClose(ULONG FileId)
+/* FUNCTIONS *****************************************************************/
+
+// static
+ARC_STATUS
+DiskClose(ULONG FileId)
 {
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
 
@@ -53,7 +59,9 @@ static ARC_STATUS DiskClose(ULONG FileId)
     return ESUCCESS;
 }
 
-static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
+// static
+ARC_STATUS
+DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
 {
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
 
@@ -64,7 +72,8 @@ static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Informat
     return ESUCCESS;
 }
 
-static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
+static ARC_STATUS
+DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
 {
     DISKCONTEXT* Context;
     UCHAR DriveNumber;
@@ -84,9 +93,12 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
     }
     else
     {
-        /* This is either a floppy disk device (DrivePartition == 0) or
-         * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
-         * it doesn't matter which one because they both have 512 bytes per sector */
+        /*
+         * This is either a floppy disk device (DrivePartition == 0) or
+         * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF)
+         * but it doesn't matter which one because they both have 512 bytes
+         * per sector.
+         */
         SectorSize = 512;
     }
 
@@ -94,13 +106,21 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
     {
         if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
             return EINVAL;
+
         SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
         SectorCount = PartitionTableEntry.PartitionSectorCount;
     }
+#if 0 // FIXME: Investigate
+    else
+    {
+        SectorCount = 0; /* FIXME */
+    }
+#endif
 
     Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
     if (!Context)
         return ENOMEM;
+
     Context->DriveNumber = DriveNumber;
     Context->SectorSize = SectorSize;
     Context->SectorOffset = SectorOffset;
@@ -111,7 +131,9 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
     return ESUCCESS;
 }
 
-static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
+// static
+ARC_STATUS
+DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
 {
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
     UCHAR* Ptr = (UCHAR*)Buffer;
@@ -123,7 +145,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
     MaxSectors   = DiskReadBufferSize / Context->SectorSize;
     SectorOffset = Context->SectorNumber + Context->SectorOffset;
 
-    ret = 1;
+    ret = TRUE;
 
     while (TotalSectors)
     {
@@ -131,11 +153,10 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
         if (ReadSectors > MaxSectors)
             ReadSectors = MaxSectors;
 
-        ret = MachDiskReadLogicalSectors(
-            Context->DriveNumber,
-            SectorOffset,
-            ReadSectors,
-            DiskReadBuffer);
+        ret = MachDiskReadLogicalSectors(Context->DriveNumber,
+                                         SectorOffset,
+                                         ReadSectors,
+                                         DiskReadBuffer);
         if (!ret)
             break;
 
@@ -156,7 +177,9 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
     return (!ret) ? EIO : ESUCCESS;
 }
 
-static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
+// static
+ARC_STATUS
+DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
 {
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
 
@@ -169,7 +192,8 @@ static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekM
     return ESUCCESS;
 }
 
-static const DEVVTBL DiskVtbl = {
+static const DEVVTBL DiskVtbl =
+{
     DiskClose,
     DiskGetFileInformation,
     DiskOpen,
@@ -177,6 +201,7 @@ static const DEVVTBL DiskVtbl = {
     DiskSeek,
 };
 
+
 PCHAR
 GetHarddiskIdentifier(
     UCHAR DriveNumber)
@@ -264,14 +289,13 @@ GetHarddiskInformation(
     Identifier[15] = Hex[(Signature >> 4) & 0x0F];
     Identifier[16] = Hex[Signature & 0x0F];
     Identifier[17] = '-';
-    Identifier[18] = 'A';
+    Identifier[18] = 'A'; // FIXME: Not always 'A' ...
     Identifier[19] = 0;
     TRACE("Identifier: %s\n", Identifier);
 }
 
-
 BOOLEAN
-HwInitializeBiosDisks(VOID)
+PcInitializeBootDevices(VOID)
 {
     UCHAR DiskCount, DriveNumber;
     ULONG i;
@@ -314,9 +338,11 @@ HwInitializeBiosDisks(VOID)
 
         DiskCount++;
         DriveNumber++;
-        memset(DiskReadBuffer, 0xcd, 512);
+        memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
     }
     DiskReportError(TRUE);
+    TRACE("BIOS reports %d harddisk%s\n",
+          (int)DiskCount, (DiskCount == 1) ? "" : "s");
 
     /* Get the drive we're booting from */
     MachDiskGetBootPath(BootPath, sizeof(BootPath));
@@ -366,5 +392,5 @@ HwInitializeBiosDisks(VOID)
     TRACE("BIOS reports %d harddisk%s\n",
           (int)DiskCount, (DiskCount == 1) ? "": "s");
 
-    return DiskCount != 0;
+    return (DiskCount != 0);
 }
diff --git a/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c b/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c
deleted file mode 100644 (file)
index 07062e9..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- *  FreeLoader
- *  Copyright (C) 1998-2003  Brian Palmer  <brianp@sginet.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <freeldr.h>
-
-#define NDEBUG
-#include <debug.h>
-
-DBG_DEFAULT_CHANNEL(DISK);
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-// FUNCTIONS
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-BOOLEAN DiskResetController(UCHAR DriveNumber)
-{
-    REGS    RegsIn;
-    REGS    RegsOut;
-
-    WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
-
-    // BIOS Int 13h, function 0 - Reset disk system
-    // AH = 00h
-    // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
-    // Return:
-    // AH = status
-    // CF clear if successful
-    // CF set on error
-    RegsIn.b.ah = 0x00;
-    RegsIn.b.dl = DriveNumber;
-
-    // Reset the disk controller
-    Int386(0x13, &RegsIn, &RegsOut);
-
-    return INT386_SUCCESS(RegsOut);
-}
-
-BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber)
-{
-    static UCHAR    LastDriveNumber = 0xff;
-    static BOOLEAN    LastSupported;
-    REGS    RegsIn;
-    REGS    RegsOut;
-
-    TRACE("PcDiskInt13ExtensionsSupported()\n");
-
-    if (DriveNumber == LastDriveNumber)
-    {
-        TRACE("Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber);
-        return LastSupported;
-    }
-
-    // Some BIOSes report that extended disk access functions are not supported
-    // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
-    // with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
-    // we can assume that all El Torito capable BIOSes support INT 13 extensions.
-    // We simply detect whether we're booting from CD by checking whether the drive
-    // number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
-    if (DriveNumber >= 0x8A)
-    {
-        LastSupported = TRUE;
-        return TRUE;
-    }
-
-    LastDriveNumber = DriveNumber;
-
-    // IBM/MS INT 13 Extensions - INSTALLATION CHECK
-    // AH = 41h
-    // BX = 55AAh
-    // DL = drive (80h-FFh)
-    // Return:
-    // CF set on error (extensions not supported)
-    // AH = 01h (invalid function)
-    // CF clear if successful
-    // BX = AA55h if installed
-    // AH = major version of extensions
-    // 01h = 1.x
-    // 20h = 2.0 / EDD-1.0
-    // 21h = 2.1 / EDD-1.1
-    // 30h = EDD-3.0
-    // AL = internal use
-    // CX = API subset support bitmap
-    // DH = extension version (v2.0+ ??? -- not present in 1.x)
-    //
-    // Bitfields for IBM/MS INT 13 Extensions API support bitmap
-    // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
-    // Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
-    // Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
-    //        extended drive parameter table is valid
-    // Bits 3-15 reserved
-    RegsIn.b.ah = 0x41;
-    RegsIn.w.bx = 0x55AA;
-    RegsIn.b.dl = DriveNumber;
-
-    // Reset the disk controller
-    Int386(0x13, &RegsIn, &RegsOut);
-
-    if (!INT386_SUCCESS(RegsOut))
-    {
-        // CF set on error (extensions not supported)
-        LastSupported = FALSE;
-        return FALSE;
-    }
-
-    if (RegsOut.w.bx != 0xAA55)
-    {
-        // BX = AA55h if installed
-        LastSupported = FALSE;
-        return FALSE;
-    }
-
-    if (!(RegsOut.w.cx & 0x0001))
-    {
-        // CX = API subset support bitmap
-        // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
-        DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber);
-        LastSupported = FALSE;
-        return FALSE;
-    }
-
-    LastSupported = TRUE;
-    return TRUE;
-}
-
-VOID DiskStopFloppyMotor(VOID)
-{
-    WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
-}
-
-BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize)
-{
-    REGS    RegsIn;
-    REGS    RegsOut;
-    PUSHORT    Ptr = (PUSHORT)(BIOSCALLBUFFER);
-
-    TRACE("DiskGetExtendedDriveParameters()\n");
-
-    if (!DiskInt13ExtensionsSupported(DriveNumber))
-            return FALSE;
-
-    // Initialize transfer buffer
-    *Ptr = BufferSize;
-
-    // BIOS Int 13h, function 48h - Get drive parameters
-    // AH = 48h
-    // DL = drive (bit 7 set for hard disk)
-    // DS:SI = result buffer
-    // Return:
-    // CF set on error
-    // AH = status (07h)
-    // CF clear if successful
-    // AH = 00h
-    // DS:SI -> result buffer
-    RegsIn.b.ah = 0x48;
-    RegsIn.b.dl = DriveNumber;
-    RegsIn.x.ds = BIOSCALLBUFSEGMENT;    // DS:SI -> result buffer
-    RegsIn.w.si = BIOSCALLBUFOFFSET;
-
-    // Get drive parameters
-    Int386(0x13, &RegsIn, &RegsOut);
-
-    if (!INT386_SUCCESS(RegsOut))
-    {
-        return FALSE;
-    }
-
-    memcpy(Buffer, Ptr, BufferSize);
-
-#if DBG
-    TRACE("size of buffer:                          %x\n", Ptr[0]);
-    TRACE("information flags:                       %x\n", Ptr[1]);
-    TRACE("number of physical cylinders on drive:   %u\n", *(PULONG)&Ptr[2]);
-    TRACE("number of physical heads on drive:       %u\n", *(PULONG)&Ptr[4]);
-    TRACE("number of physical sectors per track:    %u\n", *(PULONG)&Ptr[6]);
-    TRACE("total number of sectors on drive:        %I64u\n", *(unsigned long long*)&Ptr[8]);
-    TRACE("bytes per sector:                        %u\n", Ptr[12]);
-    if (Ptr[0] >= 0x1e)
-    {
-        TRACE("EED configuration parameters:            %x:%x\n", Ptr[13], Ptr[14]);
-        if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
-        {
-           PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
-           TRACE("SpecPtr:                                 %x\n", SpecPtr);
-           TRACE("physical I/O port base address:          %x\n", *(PUSHORT)&SpecPtr[0]);
-           TRACE("disk-drive control port address:         %x\n", *(PUSHORT)&SpecPtr[2]);
-           TRACE("drive flags:                             %x\n", SpecPtr[4]);
-           TRACE("proprietary information:                 %x\n", SpecPtr[5]);
-           TRACE("IRQ for drive:                           %u\n", SpecPtr[6]);
-           TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]);
-           TRACE("DMA control:                             %x\n", SpecPtr[8]);
-           TRACE("programmed I/O control:                  %x\n", SpecPtr[9]);
-           TRACE("drive options:                           %x\n", *(PUSHORT)&SpecPtr[10]);
-        }
-    }
-    if (Ptr[0] >= 0x42)
-    {
-        TRACE("signature:                             %x\n", Ptr[15]);
-    }
-#endif
-
-    return TRUE;
-}
-
-/* EOF */
index 07083f0..e08e7e0 100644 (file)
  */
 
 #include <freeldr.h>
+#include <cportlib/cportlib.h>
+
+#define NDEBUG
+#include <debug.h>
+
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+
+/* Maximum number of COM and LPT ports */
+#define MAX_COM_PORTS   4
+#define MAX_LPT_PORTS   3
+
+/* No Mouse */
+#define MOUSE_TYPE_NONE            0
+/* Microsoft Mouse with 2 buttons */
+#define MOUSE_TYPE_MICROSOFT       1
+/* Logitech Mouse with 3 buttons */
+#define MOUSE_TYPE_LOGITECH        2
+/* Microsoft Wheel Mouse (aka Z Mouse) */
+#define MOUSE_TYPE_WHEELZ          3
+/* Mouse Systems Mouse */
+#define MOUSE_TYPE_MOUSESYSTEMS    4
+
+
+/* PS2 stuff */
+
+/* Controller registers. */
+#define CONTROLLER_REGISTER_STATUS                      0x64
+#define CONTROLLER_REGISTER_CONTROL                     0x64
+#define CONTROLLER_REGISTER_DATA                        0x60
+
+/* Controller commands. */
+#define CONTROLLER_COMMAND_READ_MODE                    0x20
+#define CONTROLLER_COMMAND_WRITE_MODE                   0x60
+#define CONTROLLER_COMMAND_GET_VERSION                  0xA1
+#define CONTROLLER_COMMAND_MOUSE_DISABLE                0xA7
+#define CONTROLLER_COMMAND_MOUSE_ENABLE                 0xA8
+#define CONTROLLER_COMMAND_TEST_MOUSE                   0xA9
+#define CONTROLLER_COMMAND_SELF_TEST                    0xAA
+#define CONTROLLER_COMMAND_KEYBOARD_TEST                0xAB
+#define CONTROLLER_COMMAND_KEYBOARD_DISABLE             0xAD
+#define CONTROLLER_COMMAND_KEYBOARD_ENABLE              0xAE
+#define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER    0xD3
+#define CONTROLLER_COMMAND_WRITE_MOUSE                  0xD4
+
+/* Controller status */
+#define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL            0x01
+#define CONTROLLER_STATUS_INPUT_BUFFER_FULL             0x02
+#define CONTROLLER_STATUS_SELF_TEST                     0x04
+#define CONTROLLER_STATUS_COMMAND                       0x08
+#define CONTROLLER_STATUS_UNLOCKED                      0x10
+#define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL      0x20
+#define CONTROLLER_STATUS_GENERAL_TIMEOUT               0x40
+#define CONTROLLER_STATUS_PARITY_ERROR                  0x80
+#define AUX_STATUS_OUTPUT_BUFFER_FULL                   (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
+                                                         CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
+
+/* Timeout in ms for sending to keyboard controller. */
+#define CONTROLLER_TIMEOUT                              250
+
+
+// NOTE: Similar to xboxhw.c!XboxGetHarddiskConfigurationData(),
+// but with extended geometry support.
+// static
+PCM_PARTIAL_RESOURCE_LIST
+PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+    EXTENDED_GEOMETRY ExtGeometry;
+    GEOMETRY Geometry;
+    ULONG Size;
+
+    //
+    // Initialize returned size
+    //
+    *pSize = 0;
+
+    /* Set 'Configuration Data' value */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+           sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        ERR("Failed to allocate a full resource descriptor\n");
+        return NULL;
+    }
+
+    memset(PartialResourceList, 0, Size);
+    PartialResourceList->Version = 1;
+    PartialResourceList->Revision = 1;
+    PartialResourceList->Count = 1;
+    PartialResourceList->PartialDescriptors[0].Type =
+        CmResourceTypeDeviceSpecific;
+//  PartialResourceList->PartialDescriptors[0].ShareDisposition =
+//  PartialResourceList->PartialDescriptors[0].Flags =
+    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+        sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+
+    /* Get pointer to geometry data */
+    DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
+
+    /* Get the disk geometry */
+    ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
+    if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
+    {
+        DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
+        DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
+        DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
+        DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
+    }
+    else if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+    {
+        DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
+        DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
+        DiskGeometry->SectorsPerTrack = Geometry.Sectors;
+        DiskGeometry->NumberOfHeads = Geometry.Heads;
+    }
+    else
+    {
+        TRACE("Reading disk geometry failed\n");
+        FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
+        return NULL;
+    }
+    TRACE("Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
+          DriveNumber,
+          DiskGeometry->NumberOfCylinders,
+          DiskGeometry->NumberOfHeads,
+          DiskGeometry->SectorsPerTrack,
+          DiskGeometry->BytesPerSector);
+
+    //
+    // Return configuration data
+    //
+    *pSize = Size;
+    return PartialResourceList;
+}
+
+static
+VOID
+DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
+    PCM_PNP_BIOS_INSTALLATION_CHECK InstData;
+    PCONFIGURATION_COMPONENT_DATA BusKey;
+    ULONG x;
+    ULONG NodeSize = 0;
+    ULONG NodeCount = 0;
+    UCHAR NodeNumber;
+    ULONG FoundNodeCount;
+    int i;
+    ULONG PnpBufferSize;
+    ULONG Size;
+    char *Ptr;
+
+    InstData = (PCM_PNP_BIOS_INSTALLATION_CHECK)PnpBiosSupported();
+    if (InstData == NULL || strncmp((CHAR*)InstData->Signature, "$PnP", 4))
+    {
+        TRACE("PnP-BIOS not supported\n");
+        return;
+    }
+
+    TRACE("PnP-BIOS supported\n");
+    TRACE("Signature '%c%c%c%c'\n",
+          InstData->Signature[0], InstData->Signature[1],
+          InstData->Signature[2], InstData->Signature[3]);
+
+    x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount);
+    if (x == 0x82)
+    {
+        TRACE("PnP-BIOS function 'Get Number of System Device Nodes' not supported\n");
+        return;
+    }
+
+    NodeCount &= 0xFF; // needed since some fscked up BIOSes return
+    // wrong info (e.g. Mac Virtual PC)
+    // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c
+    if (x != 0 || NodeSize == 0 || NodeCount == 0)
+    {
+        ERR("PnP-BIOS failed to enumerate device nodes\n");
+        return;
+    }
+    TRACE("MaxNodeSize %u  NodeCount %u\n", NodeSize, NodeCount);
+    TRACE("Estimated buffer size %u\n", NodeSize * NodeCount);
+
+    /* Set 'Configuration Data' value */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST)
+           + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK) + (NodeSize * NodeCount);
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        ERR("Failed to allocate resource descriptor\n");
+        return;
+    }
+    memset(PartialResourceList, 0, Size);
+
+    /* Initialize resource descriptor */
+    PartialResourceList->Version = 1;
+    PartialResourceList->Revision = 1;
+    PartialResourceList->Count = 1;
+    PartialResourceList->PartialDescriptors[0].Type =
+        CmResourceTypeDeviceSpecific;
+    PartialResourceList->PartialDescriptors[0].ShareDisposition =
+        CmResourceShareUndetermined;
+
+    /* The buffer starts after PartialResourceList->PartialDescriptors[0] */
+    Ptr = (char *)(PartialResourceList + 1);
+
+    /* Set installation check data */
+    memcpy (Ptr, InstData, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
+    Ptr += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
+
+    /* Copy device nodes */
+    FoundNodeCount = 0;
+    PnpBufferSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
+    for (i = 0; i < 0xFF; i++)
+    {
+        NodeNumber = (UCHAR)i;
+
+        x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer);
+        if (x == 0)
+        {
+            DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DiskReadBuffer;
+
+            TRACE("Node: %u  Size %u (0x%x)\n",
+                  DeviceNode->Node,
+                  DeviceNode->Size,
+                  DeviceNode->Size);
+
+            if (PnpBufferSize + DeviceNode->Size > Size)
+            {
+                ERR("Buffer too small!\n");
+                break;
+            }
+
+            memcpy(Ptr, DeviceNode, DeviceNode->Size);
+
+            Ptr += DeviceNode->Size;
+            PnpBufferSize += DeviceNode->Size;
+
+            FoundNodeCount++;
+            if (FoundNodeCount >= NodeCount)
+                break;
+        }
+    }
+
+    /* Set real data size */
+    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+        PnpBufferSize;
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + PnpBufferSize;
+
+    TRACE("Real buffer size: %u\n", PnpBufferSize);
+    TRACE("Resource size: %u\n", Size);
+
+    /* Create component key */
+    FldrCreateComponentKey(SystemKey,
+                           AdapterClass,
+                           MultiFunctionAdapter,
+                           0x0,
+                           0x0,
+                           0xFFFFFFFF,
+                           "PNP BIOS",
+                           PartialResourceList,
+                           Size,
+                           &BusKey);
+
+    (*BusNumber)++;
+}
+
+static
+VOID
+InitializeSerialPort(PUCHAR Port,
+                     UCHAR LineControl)
+{
+    WRITE_PORT_UCHAR(Port + 3, 0x80);  /* set DLAB on   */
+    WRITE_PORT_UCHAR(Port,     0x60);  /* speed LO byte */
+    WRITE_PORT_UCHAR(Port + 1, 0);     /* speed HI byte */
+    WRITE_PORT_UCHAR(Port + 3, LineControl);
+    WRITE_PORT_UCHAR(Port + 1, 0);     /* set comm and DLAB to 0 */
+    WRITE_PORT_UCHAR(Port + 4, 0x09);  /* DR int enable */
+    READ_PORT_UCHAR(Port + 5);  /* clear error bits */
+}
+
+static
+ULONG
+DetectSerialMouse(PUCHAR Port)
+{
+    CHAR Buffer[4];
+    ULONG i;
+    ULONG TimeOut;
+    UCHAR LineControl;
+
+    /* Shutdown mouse or something like that */
+    LineControl = READ_PORT_UCHAR(Port + 4);
+    WRITE_PORT_UCHAR(Port + 4, (LineControl & ~0x02) | 0x01);
+    StallExecutionProcessor(100000);
+
+    /*
+     * Clear buffer
+     * Maybe there is no serial port although BIOS reported one (this
+     * is the case on Apple hardware), or the serial port is misbehaving,
+     * therefore we must give up after some time.
+     */
+    TimeOut = 200;
+    while (READ_PORT_UCHAR(Port + 5) & 0x01)
+    {
+        if (--TimeOut == 0)
+            return MOUSE_TYPE_NONE;
+        READ_PORT_UCHAR(Port);
+    }
+
+    /*
+     * Send modem control with 'Data Terminal Ready', 'Request To Send' and
+     * 'Output Line 2' message. This enables mouse to identify.
+     */
+    WRITE_PORT_UCHAR(Port + 4, 0x0b);
+
+    /* Wait 10 milliseconds for the mouse getting ready */
+    StallExecutionProcessor(10000);
+
+    /* Read first four bytes, which contains Microsoft Mouse signs */
+    TimeOut = 200;
+    for (i = 0; i < 4; i++)
+    {
+        while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
+        {
+            StallExecutionProcessor(1000);
+            --TimeOut;
+            if (TimeOut == 0)
+                return MOUSE_TYPE_NONE;
+        }
+        Buffer[i] = READ_PORT_UCHAR(Port);
+    }
+
+    TRACE("Mouse data: %x %x %x %x\n",
+          Buffer[0], Buffer[1], Buffer[2], Buffer[3]);
+
+    /* Check that four bytes for signs */
+    for (i = 0; i < 4; ++i)
+    {
+        if (Buffer[i] == 'B')
+        {
+            /* Sign for Microsoft Ballpoint */
+//      DbgPrint("Microsoft Ballpoint device detected\n");
+//      DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
+            return MOUSE_TYPE_NONE;
+        }
+        else if (Buffer[i] == 'M')
+        {
+            /* Sign for Microsoft Mouse protocol followed by button specifier */
+            if (i == 3)
+            {
+                /* Overflow Error */
+                return MOUSE_TYPE_NONE;
+            }
+
+            switch (Buffer[i + 1])
+            {
+            case '3':
+                TRACE("Microsoft Mouse with 3-buttons detected\n");
+                return MOUSE_TYPE_LOGITECH;
+
+            case 'Z':
+                TRACE("Microsoft Wheel Mouse detected\n");
+                return MOUSE_TYPE_WHEELZ;
+
+                /* case '2': */
+            default:
+                TRACE("Microsoft Mouse with 2-buttons detected\n");
+                return MOUSE_TYPE_MICROSOFT;
+            }
+        }
+    }
+
+    return MOUSE_TYPE_NONE;
+}
+
+static ULONG
+GetSerialMousePnpId(PUCHAR Port, char *Buffer)
+{
+    ULONG TimeOut;
+    ULONG i = 0;
+    char c;
+    char x;
+
+    WRITE_PORT_UCHAR(Port + 4, 0x09);
+
+    /* Wait 10 milliseconds for the mouse getting ready */
+    StallExecutionProcessor(10000);
+
+    WRITE_PORT_UCHAR(Port + 4, 0x0b);
+
+    StallExecutionProcessor(10000);
+
+    for (;;)
+    {
+        TimeOut = 200;
+        while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
+        {
+            StallExecutionProcessor(1000);
+            --TimeOut;
+            if (TimeOut == 0)
+            {
+                return 0;
+            }
+        }
+
+        c = READ_PORT_UCHAR(Port);
+        if (c == 0x08 || c == 0x28)
+            break;
+    }
+
+    Buffer[i++] = c;
+    x = c + 1;
+
+    for (;;)
+    {
+        TimeOut = 200;
+        while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
+        {
+            StallExecutionProcessor(1000);
+            --TimeOut;
+            if (TimeOut == 0)
+                return 0;
+        }
+        c = READ_PORT_UCHAR(Port);
+        Buffer[i++] = c;
+        if (c == x)
+            break;
+        if (i >= 256)
+            break;
+    }
+
+    return i;
+}
+
+static
+VOID
+DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey,
+                              PUCHAR Base)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    char Buffer[256];
+    CHAR Identifier[256];
+    PCONFIGURATION_COMPONENT_DATA PeripheralKey;
+    ULONG MouseType;
+    ULONG Size, Length;
+    ULONG i;
+    ULONG j;
+    ULONG k;
+
+    TRACE("DetectSerialPointerPeripheral()\n");
+
+    Identifier[0] = 0;
+
+    InitializeSerialPort(Base, 2);
+    MouseType = DetectSerialMouse(Base);
+
+    if (MouseType != MOUSE_TYPE_NONE)
+    {
+        Length = GetSerialMousePnpId(Base, Buffer);
+        TRACE( "PnP ID length: %u\n", Length);
+
+        if (Length != 0)
+        {
+            /* Convert PnP sting to ASCII */
+            if (Buffer[0] == 0x08)
+            {
+                for (i = 0; i < Length; i++)
+                    Buffer[i] += 0x20;
+            }
+            Buffer[Length] = 0;
+
+            TRACE("PnP ID string: %s\n", Buffer);
+
+            /* Copy PnpId string */
+            for (i = 0; i < 7; i++)
+            {
+                Identifier[i] = Buffer[3 + i];
+            }
+            memcpy(&Identifier[7],
+                   L" - ",
+                   3 * sizeof(WCHAR));
+
+            /* Skip device serial number */
+            i = 10;
+            if (Buffer[i] == '\\')
+            {
+                for (j = ++i; i < Length; ++i)
+                {
+                    if (Buffer[i] == '\\')
+                        break;
+                }
+                if (i >= Length)
+                    i -= 3;
+            }
+
+            /* Skip PnP class */
+            if (Buffer[i] == '\\')
+            {
+                for (j = ++i; i < Length; ++i)
+                {
+                    if (Buffer[i] == '\\')
+                        break;
+                }
+
+                if (i >= Length)
+                    i -= 3;
+            }
+
+            /* Skip compatible PnP Id */
+            if (Buffer[i] == '\\')
+            {
+                for (j = ++i; i < Length; ++i)
+                {
+                    if (Buffer[i] == '\\')
+                        break;
+                }
+                if (Buffer[j] == '*')
+                    ++j;
+                if (i >= Length)
+                    i -= 3;
+            }
+
+            /* Get product description */
+            if (Buffer[i] == '\\')
+            {
+                for (j = ++i; i < Length; ++i)
+                {
+                    if (Buffer[i] == ';')
+                        break;
+                }
+                if (i >= Length)
+                    i -= 3;
+                if (i > j + 1)
+                {
+                    for (k = 0; k < i - j; k++)
+                    {
+                        Identifier[k + 10] = Buffer[k + j];
+                    }
+                    Identifier[10 + (i - j)] = 0;
+                }
+            }
+
+            TRACE("Identifier string: %s\n", Identifier);
+        }
+
+        if (Length == 0 || strlen(Identifier) < 11)
+        {
+            switch (MouseType)
+            {
+            case MOUSE_TYPE_LOGITECH:
+                strcpy(Identifier, "LOGITECH SERIAL MOUSE");
+                break;
+
+            case MOUSE_TYPE_WHEELZ:
+                strcpy(Identifier, "MICROSOFT SERIAL MOUSE WITH WHEEL");
+                break;
+
+            case MOUSE_TYPE_MICROSOFT:
+            default:
+                strcpy(Identifier, "MICROSOFT SERIAL MOUSE");
+                break;
+            }
+        }
+
+        /* Set 'Configuration Data' value */
+        Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+               sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+        if (PartialResourceList == NULL)
+        {
+            ERR("Failed to allocate resource descriptor\n");
+            return;
+        }
+        memset(PartialResourceList, 0, Size);
+        PartialResourceList->Version = 1;
+        PartialResourceList->Revision = 1;
+        PartialResourceList->Count = 0;
+
+        /* Create 'PointerPeripheral' key */
+        FldrCreateComponentKey(ControllerKey,
+                               PeripheralClass,
+                               PointerPeripheral,
+                               Input,
+                               0x0,
+                               0xFFFFFFFF,
+                               Identifier,
+                               PartialResourceList,
+                               Size,
+                               &PeripheralKey);
+
+        TRACE("Created key: PointerPeripheral\\0\n");
+    }
+}
+
+static
+VOID
+DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+    PCM_SERIAL_DEVICE_DATA SerialDeviceData;
+    ULONG Irq[MAX_COM_PORTS] = {4, 3, 4, 3};
+    ULONG Base;
+    CHAR Buffer[80];
+    PUSHORT BasePtr;
+    ULONG ControllerNumber = 0;
+    PCONFIGURATION_COMPONENT_DATA ControllerKey;
+    ULONG i;
+    ULONG Size;
+
+    TRACE("DetectSerialPorts()\n");
+
+    /*
+     * The BIOS data area 0x400 holds the address of the first valid COM port.
+     * Each COM port address is stored in a 2-byte field.
+     * Infos at: http://www.bioscentral.com/misc/bda.htm
+     */
+    BasePtr = (PUSHORT)0x400;
+
+    for (i = 0; i < MAX_COM_PORTS; i++, BasePtr++)
+    {
+        Base = (ULONG) * BasePtr;
+        if (Base == 0 || !CpDoesPortExist((PUCHAR)Base))
+            continue;
+
+        TRACE("Found COM%u port at 0x%x\n", i + 1, Base);
+
+        /* Set 'Identifier' value */
+        sprintf(Buffer, "COM%ld", i + 1);
+
+        /* Build full device descriptor */
+        Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+               2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
+               sizeof(CM_SERIAL_DEVICE_DATA);
+        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+        if (PartialResourceList == NULL)
+        {
+            ERR("Failed to allocate resource descriptor\n");
+            continue;
+        }
+        memset(PartialResourceList, 0, Size);
+
+        /* Initialize resource descriptor */
+        PartialResourceList->Version = 1;
+        PartialResourceList->Revision = 1;
+        PartialResourceList->Count = 3;
+
+        /* Set IO Port */
+        PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+        PartialDescriptor->Type = CmResourceTypePort;
+        PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+        PartialDescriptor->u.Port.Start.LowPart = Base;
+        PartialDescriptor->u.Port.Start.HighPart = 0x0;
+        PartialDescriptor->u.Port.Length = 7;
+
+        /* Set Interrupt */
+        PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
+        PartialDescriptor->Type = CmResourceTypeInterrupt;
+        PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+        PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+        PartialDescriptor->u.Interrupt.Level = Irq[i];
+        PartialDescriptor->u.Interrupt.Vector = Irq[i];
+        PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+
+        /* Set serial data (device specific) */
+        PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
+        PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
+        PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+        PartialDescriptor->Flags = 0;
+        PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_SERIAL_DEVICE_DATA);
+
+        SerialDeviceData =
+            (PCM_SERIAL_DEVICE_DATA)&PartialResourceList->PartialDescriptors[3];
+        SerialDeviceData->BaudClock = 1843200; /* UART Clock frequency (Hertz) */
+
+        /* Create controller key */
+        FldrCreateComponentKey(BusKey,
+                               ControllerClass,
+                               SerialController,
+                               Output | Input | ConsoleIn | ConsoleOut,
+                               ControllerNumber,
+                               0xFFFFFFFF,
+                               Buffer,
+                               PartialResourceList,
+                               Size,
+                               &ControllerKey);
+
+        if (!Rs232PortInUse(UlongToPtr(Base)))
+        {
+            /* Detect serial mouse */
+            DetectSerialPointerPeripheral(ControllerKey, UlongToPtr(Base));
+        }
+
+        ControllerNumber++;
+    }
+}
+
+static VOID
+DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+    ULONG Irq[MAX_LPT_PORTS] = {7, 5, (ULONG) - 1};
+    CHAR Buffer[80];
+    PCONFIGURATION_COMPONENT_DATA ControllerKey;
+    PUSHORT BasePtr;
+    ULONG Base;
+    ULONG ControllerNumber = 0;
+    ULONG i;
+    ULONG Size;
+
+    TRACE("DetectParallelPorts() called\n");
+
+    /*
+     * The BIOS data area 0x408 holds the address of the first valid LPT port.
+     * Each LPT port address is stored in a 2-byte field.
+     * Infos at: http://www.bioscentral.com/misc/bda.htm
+     */
+    BasePtr = (PUSHORT)0x408;
+
+    for (i = 0; i < MAX_LPT_PORTS; i++, BasePtr++)
+    {
+        Base = (ULONG) * BasePtr;
+        if (Base == 0)
+            continue;
+
+        TRACE("Parallel port %u: %x\n", ControllerNumber, Base);
+
+        /* Set 'Identifier' value */
+        sprintf(Buffer, "PARALLEL%ld", i + 1);
+
+        /* Build full device descriptor */
+        Size = sizeof(CM_PARTIAL_RESOURCE_LIST);
+        if (Irq[i] != (ULONG) - 1)
+            Size += sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+
+        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+        if (PartialResourceList == NULL)
+        {
+            ERR("Failed to allocate resource descriptor\n");
+            continue;
+        }
+        memset(PartialResourceList, 0, Size);
+
+        /* Initialize resource descriptor */
+        PartialResourceList->Version = 1;
+        PartialResourceList->Revision = 1;
+        PartialResourceList->Count = (Irq[i] != (ULONG) - 1) ? 2 : 1;
+
+        /* Set IO Port */
+        PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+        PartialDescriptor->Type = CmResourceTypePort;
+        PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+        PartialDescriptor->u.Port.Start.LowPart = Base;
+        PartialDescriptor->u.Port.Start.HighPart = 0x0;
+        PartialDescriptor->u.Port.Length = 3;
+
+        /* Set Interrupt */
+        if (Irq[i] != (ULONG) - 1)
+        {
+            PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
+            PartialDescriptor->Type = CmResourceTypeInterrupt;
+            PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+            PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+            PartialDescriptor->u.Interrupt.Level = Irq[i];
+            PartialDescriptor->u.Interrupt.Vector = Irq[i];
+            PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+        }
+
+        /* Create controller key */
+        FldrCreateComponentKey(BusKey,
+                               ControllerClass,
+                               ParallelController,
+                               Output,
+                               ControllerNumber,
+                               0xFFFFFFFF,
+                               Buffer,
+                               PartialResourceList,
+                               Size,
+                               &ControllerKey);
+
+        ControllerNumber++;
+    }
+
+    TRACE("DetectParallelPorts() done\n");
+}
+
+//static
+BOOLEAN
+DetectKeyboardDevice(VOID)
+{
+    UCHAR Status;
+    UCHAR Scancode;
+    ULONG Loops;
+    BOOLEAN Result = TRUE;
+
+    /* Identify device */
+    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
+
+    /* Wait for reply */
+    for (Loops = 0; Loops < 100; Loops++)
+    {
+        StallExecutionProcessor(10000);
+        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+        if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
+            break;
+    }
+
+    if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
+    {
+        /* PC/XT keyboard or no keyboard */
+        Result = FALSE;
+    }
+
+    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+    if (Scancode != 0xFA)
+    {
+        /* No ACK received */
+        Result = FALSE;
+    }
+
+    StallExecutionProcessor(10000);
+
+    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+    if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
+    {
+        /* Found AT keyboard */
+        return Result;
+    }
+
+    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+    if (Scancode != 0xAB)
+    {
+        /* No 0xAB received */
+        Result = FALSE;
+    }
+
+    StallExecutionProcessor(10000);
+
+    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+    if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
+    {
+        /* No byte in buffer */
+        Result = FALSE;
+    }
+
+    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+    if (Scancode != 0x41)
+    {
+        /* No 0x41 received */
+        Result = FALSE;
+    }
+
+    /* Found MF-II keyboard */
+    return Result;
+}
+
+static VOID
+DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+    PCM_KEYBOARD_DEVICE_DATA KeyboardData;
+    PCONFIGURATION_COMPONENT_DATA PeripheralKey;
+    ULONG Size;
+
+    /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2
+    if (DetectKeyboardDevice()) */
+    {
+        /* Set 'Configuration Data' value */
+        Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+               sizeof(CM_KEYBOARD_DEVICE_DATA);
+        PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+        if (PartialResourceList == NULL)
+        {
+            ERR("Failed to allocate resource descriptor\n");
+            return;
+        }
+
+        /* Initialize resource descriptor */
+        memset(PartialResourceList, 0, Size);
+        PartialResourceList->Version = 1;
+        PartialResourceList->Revision = 1;
+        PartialResourceList->Count = 1;
+
+        PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+        PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
+        PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+        PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA);
+
+        KeyboardData = (PCM_KEYBOARD_DEVICE_DATA)(PartialDescriptor + 1);
+        KeyboardData->Version = 1;
+        KeyboardData->Revision = 1;
+        KeyboardData->Type = 4;
+        KeyboardData->Subtype = 0;
+        KeyboardData->KeyboardFlags = 0x20;
+
+        /* Create controller key */
+        FldrCreateComponentKey(ControllerKey,
+                               PeripheralClass,
+                               KeyboardPeripheral,
+                               Input | ConsoleIn,
+                               0x0,
+                               0xFFFFFFFF,
+                               "PCAT_ENHANCED",
+                               PartialResourceList,
+                               Size,
+                               &PeripheralKey);
+        TRACE("Created key: KeyboardPeripheral\\0\n");
+    }
+}
+
+static
+VOID
+DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+    PCONFIGURATION_COMPONENT_DATA ControllerKey;
+    ULONG Size;
+
+    /* Set 'Configuration Data' value */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+           2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        ERR("Failed to allocate resource descriptor\n");
+        return;
+    }
+
+    /* Initialize resource descriptor */
+    memset(PartialResourceList, 0, Size);
+    PartialResourceList->Version = 1;
+    PartialResourceList->Revision = 1;
+    PartialResourceList->Count = 3;
+
+    /* Set Interrupt */
+    PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+    PartialDescriptor->Type = CmResourceTypeInterrupt;
+    PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+    PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+    PartialDescriptor->u.Interrupt.Level = 1;
+    PartialDescriptor->u.Interrupt.Vector = 1;
+    PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+
+    /* Set IO Port 0x60 */
+    PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
+    PartialDescriptor->Type = CmResourceTypePort;
+    PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+    PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+    PartialDescriptor->u.Port.Start.LowPart = 0x60;
+    PartialDescriptor->u.Port.Start.HighPart = 0x0;
+    PartialDescriptor->u.Port.Length = 1;
+
+    /* Set IO Port 0x64 */
+    PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
+    PartialDescriptor->Type = CmResourceTypePort;
+    PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+    PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+    PartialDescriptor->u.Port.Start.LowPart = 0x64;
+    PartialDescriptor->u.Port.Start.HighPart = 0x0;
+    PartialDescriptor->u.Port.Length = 1;
+
+    /* Create controller key */
+    FldrCreateComponentKey(BusKey,
+                           ControllerClass,
+                           KeyboardController,
+                           Input | ConsoleIn,
+                           0x0,
+                           0xFFFFFFFF,
+                           NULL,
+                           PartialResourceList,
+                           Size,
+                           &ControllerKey);
+    TRACE("Created key: KeyboardController\\0\n");
+
+    DetectKeyboardPeripheral(ControllerKey);
+}
+
+static
+VOID
+PS2ControllerWait(VOID)
+{
+    ULONG Timeout;
+    UCHAR Status;
+
+    for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
+    {
+        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+        if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
+            return;
+
+        /* Sleep for one millisecond */
+        StallExecutionProcessor(1000);
+    }
+}
+
+static
+BOOLEAN
+DetectPS2AuxPort(VOID)
+{
+#if 1
+    /* Current detection is too unreliable. Just do as if
+     * the PS/2 aux port is always present
+     */
+    return TRUE;
+#else
+    ULONG Loops;
+    UCHAR Status;
+
+    /* Put the value 0x5A in the output buffer using the
+     * "WriteAuxiliary Device Output Buffer" command (0xD3).
+     * Poll the Status Register for a while to see if the value really turns up
+     * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
+     * to 1 in the Status Register, we assume this controller has an
+     *  Auxiliary Port (a.k.a. Mouse Port).
+     */
+    PS2ControllerWait();
+    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
+                     CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
+    PS2ControllerWait();
+
+    /* 0x5A is a random dummy value */
+    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
+                     0x5A);
+
+    for (Loops = 0; Loops < 10; Loops++)
+    {
+        StallExecutionProcessor(10000);
+        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+        if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
+            break;
+    }
+
+    READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+
+    return (Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL);
+#endif
+}
+
+static
+BOOLEAN
+DetectPS2AuxDevice(VOID)
+{
+    UCHAR Scancode;
+    UCHAR Status;
+    ULONG Loops;
+    BOOLEAN Result = TRUE;
+
+    PS2ControllerWait();
+    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
+                     CONTROLLER_COMMAND_WRITE_MOUSE);
+    PS2ControllerWait();
+
+    /* Identify device */
+    WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
+
+    /* Wait for reply */
+    for (Loops = 0; Loops < 100; Loops++)
+    {
+        StallExecutionProcessor(10000);
+        Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+        if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
+            break;
+    }
+
+    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+    if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
+        Result = FALSE;
+
+    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+    if (Scancode != 0xFA)
+        Result = FALSE;
+
+    StallExecutionProcessor(10000);
+
+    Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+    if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
+        Result = FALSE;
+
+    Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+    if (Scancode != 0x00)
+        Result = FALSE;
+
+    return Result;
+}
+
+// FIXME: Missing: DetectPS2Peripheral!! (for corresponding 'PointerPeripheral')
+
+static
+VOID
+DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCONFIGURATION_COMPONENT_DATA ControllerKey;
+    PCONFIGURATION_COMPONENT_DATA PeripheralKey;
+    ULONG Size;
+
+    if (DetectPS2AuxPort())
+    {
+        TRACE("Detected PS2 port\n");
+
+        PartialResourceList = FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST), TAG_HW_RESOURCE_LIST);
+        if (PartialResourceList == NULL)
+        {
+            ERR("Failed to allocate resource descriptor\n");
+            return;
+        }
+        memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST));
+
+        /* Initialize resource descriptor */
+        PartialResourceList->Version = 1;
+        PartialResourceList->Revision = 1;
+        PartialResourceList->Count = 1;
+
+        /* Set Interrupt */
+        PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeInterrupt;
+        PartialResourceList->PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
+        PartialResourceList->PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+        PartialResourceList->PartialDescriptors[0].u.Interrupt.Level = 12;
+        PartialResourceList->PartialDescriptors[0].u.Interrupt.Vector = 12;
+        PartialResourceList->PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
+
+        /* Create controller key */
+        FldrCreateComponentKey(BusKey,
+                               ControllerClass,
+                               PointerController,
+                               Input,
+                               0x0,
+                               0xFFFFFFFF,
+                               NULL,
+                               PartialResourceList,
+                               sizeof(CM_PARTIAL_RESOURCE_LIST),
+                               &ControllerKey);
+        TRACE("Created key: PointerController\\0\n");
+
+        if (DetectPS2AuxDevice())
+        {
+            TRACE("Detected PS2 mouse\n");
+
+            /* Initialize resource descriptor */
+            Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+                   sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+            PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+            if (PartialResourceList == NULL)
+            {
+                ERR("Failed to allocate resource descriptor\n");
+                return;
+            }
+            memset(PartialResourceList, 0, Size);
+            PartialResourceList->Version = 1;
+            PartialResourceList->Revision = 1;
+            PartialResourceList->Count = 0;
+
+            /* Create peripheral key */
+            FldrCreateComponentKey(ControllerKey,
+                                   ControllerClass,
+                                   PointerPeripheral,
+                                   Input,
+                                   0x0,
+                                   0xFFFFFFFF,
+                                   "MICROSOFT PS2 MOUSE",
+                                   PartialResourceList,
+                                   Size,
+                                   &PeripheralKey);
+            TRACE("Created key: PointerPeripheral\\0\n");
+        }
+    }
+}
+
+static VOID
+DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+    CHAR Buffer[80];
+    PCONFIGURATION_COMPONENT_DATA ControllerKey;
+    USHORT VesaVersion;
+
+    /* FIXME: Set 'ComponentInformation' value */
+
+    VesaVersion = BiosIsVesaSupported();
+    if (VesaVersion != 0)
+    {
+        TRACE("VESA version %c.%c\n",
+              (VesaVersion >> 8) + '0',
+              (VesaVersion & 0xFF) + '0');
+    }
+    else
+    {
+        TRACE("VESA not supported\n");
+    }
+
+    if (VesaVersion >= 0x0200)
+    {
+        strcpy(Buffer, "VBE Display");
+    }
+    else
+    {
+        strcpy(Buffer, "VGA Display");
+    }
+
+    FldrCreateComponentKey(BusKey,
+                           ControllerClass,
+                           DisplayController,
+                           0x0,
+                           0x0,
+                           0xFFFFFFFF,
+                           Buffer,
+                           NULL,
+                           0,
+                           &ControllerKey);
+    TRACE("Created key: DisplayController\\0\n");
+
+    /* FIXME: Add display peripheral (monitor) data */
+    if (VesaVersion != 0)
+    {
+        if (BiosIsVesaDdcSupported())
+        {
+            TRACE("VESA/DDC supported!\n");
+            if (BiosVesaReadEdid())
+            {
+                TRACE("EDID data read successfully!\n");
+
+            }
+        }
+    }
+}
+
+extern VOID
+DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey);
+
+static
+VOID
+DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCONFIGURATION_COMPONENT_DATA BusKey;
+    ULONG Size;
+
+    /* Set 'Configuration Data' value */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+           sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        ERR("Failed to allocate resource descriptor\n");
+        return;
+    }
+
+    /* Initialize resource descriptor */
+    memset(PartialResourceList, 0, Size);
+    PartialResourceList->Version = 1;
+    PartialResourceList->Revision = 1;
+    PartialResourceList->Count = 0;
+
+    /* Create new bus key */
+    FldrCreateComponentKey(SystemKey,
+                           AdapterClass,
+                           MultiFunctionAdapter,
+                           0x0,
+                           0x0,
+                           0xFFFFFFFF,
+                           "ISA",
+                           PartialResourceList,
+                           Size,
+                           &BusKey);
+
+    /* Increment bus number */
+    (*BusNumber)++;
+
+    /* Detect ISA/BIOS devices */
+    DetectBiosDisks(BusKey);
+    DetectSerialPorts(BusKey);
+    DetectParallelPorts(BusKey);
+    DetectKeyboardController(BusKey);
+    DetectPS2Mouse(BusKey);
+    DetectDisplayController(BusKey);
+
+    /* FIXME: Detect more ISA devices */
+}
+
+extern PCONFIGURATION_COMPONENT_DATA
+DetectSystem(VOID);
+
+PCONFIGURATION_COMPONENT_DATA
+PcHwDetect(VOID)
+{
+    PCONFIGURATION_COMPONENT_DATA SystemKey;
+    ULONG BusNumber = 0;
+
+    TRACE("DetectHardware()\n");
+
+    /* Create the 'System' key */
+    SystemKey = DetectSystem();
+
+    /* Detect buses */
+    DetectPciBios(SystemKey, &BusNumber);
+    DetectApmBios(SystemKey, &BusNumber);
+    DetectPnpBios(SystemKey, &BusNumber);
+    DetectIsaBios(SystemKey, &BusNumber); // TODO: Detect first EISA or MCA, before ISA
+    DetectAcpiBios(SystemKey, &BusNumber);
+
+    TRACE("DetectHardware() Done\n");
+    return SystemKey;
+}
+
+VOID
+PcHwIdle(VOID)
+{
+    REGS Regs;
+
+    /* Select APM 1.0+ function */
+    Regs.b.ah = 0x53;
+
+    /* Function 05h: CPU idle */
+    Regs.b.al = 0x05;
+
+    /* Call INT 15h */
+    Int386(0x15, &Regs, &Regs);
+
+    /* Check if successfull (CF set on error) */
+    if (INT386_SUCCESS(Regs))
+        return;
+
+    /*
+     * No futher processing here.
+     * Optionally implement HLT instruction handling.
+     */
+}
+
+
+/******************************************************************************/
 
 VOID
 PcMachInit(const char *CmdLine)
@@ -53,10 +1390,9 @@ PcMachInit(const char *CmdLine)
 VOID
 PcPrepareForReactOS(IN BOOLEAN Setup)
 {
-    //
-    // On PC, prepare video and turn off the floppy motor
-    //
+    /* On PC, prepare video and turn off the floppy motor */
     PcVideoPrepareForReactOS(Setup);
     DiskStopFloppyMotor();
 }
+
 /* EOF */
index 627a848..c66ba87 100644 (file)
 
 #include <freeldr.h>
 
+#define NDEBUG
+#include <debug.h>
+
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+
+static CHAR Hex[] = "0123456789ABCDEF";
+
+extern ULONG reactos_disk_count;
+extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
+
+typedef struct tagDISKCONTEXT
+{
+    UCHAR DriveNumber;
+    ULONG SectorSize;
+    ULONGLONG SectorOffset;
+    ULONGLONG SectorCount;
+    ULONGLONG SectorNumber;
+} DISKCONTEXT;
+
+
+
+// NOTE: Similar to hardware.c!PcGetHarddiskConfigurationData(),
+// but without extended geometry support.
+static
+PCM_PARTIAL_RESOURCE_LIST
+XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+    //EXTENDED_GEOMETRY ExtGeometry;
+    GEOMETRY Geometry;
+    ULONG Size;
+
+    //
+    // Initialize returned size
+    //
+    *pSize = 0;
+
+    /* Set 'Configuration Data' value */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+           sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        ERR("Failed to allocate a full resource descriptor\n");
+        return NULL;
+    }
+
+    memset(PartialResourceList, 0, Size);
+    PartialResourceList->Version = 1;
+    PartialResourceList->Revision = 1;
+    PartialResourceList->Count = 1;
+    PartialResourceList->PartialDescriptors[0].Type =
+        CmResourceTypeDeviceSpecific;
+//  PartialResourceList->PartialDescriptors[0].ShareDisposition =
+//  PartialResourceList->PartialDescriptors[0].Flags =
+    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+        sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+
+    /* Get pointer to geometry data */
+    DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
+
+    /* Get the disk geometry */
+    //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
+
+    if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+    {
+        DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
+        DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
+        DiskGeometry->SectorsPerTrack = Geometry.Sectors;
+        DiskGeometry->NumberOfHeads = Geometry.Heads;
+    }
+    else
+    {
+        ERR("Reading disk geometry failed\n");
+        FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
+        return NULL;
+    }
+    TRACE("Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
+          DriveNumber,
+          DiskGeometry->NumberOfCylinders,
+          DiskGeometry->NumberOfHeads,
+          DiskGeometry->SectorsPerTrack,
+          DiskGeometry->BytesPerSector);
+
+    //
+    // Return configuration data
+    //
+    *pSize = Size;
+    return PartialResourceList;
+}
+
+#define GetHarddiskConfigurationData XboxGetHarddiskConfigurationData
+
+
+extern ARC_STATUS
+DiskClose(ULONG FileId);
+
+extern ARC_STATUS
+DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
+
+static
+ARC_STATUS
+DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
+{
+    DISKCONTEXT* Context;
+    ULONG DrivePartition, SectorSize;
+    UCHAR DriveNumber;
+    ULONGLONG SectorOffset = 0;
+    ULONGLONG SectorCount = 0;
+    PARTITION_TABLE_ENTRY PartitionTableEntry;
+    CHAR FileName[1];
+
+    if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
+        return EINVAL;
+
+    if (DrivePartition == 0xff)
+    {
+        /* This is a CD-ROM device */
+        SectorSize = 2048;
+    }
+    else
+    {
+        /* This is either a floppy disk device (DrivePartition == 0) or
+         * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
+         * it doesn't matter which one because they both have 512 bytes per sector */
+        SectorSize = 512;
+    }
+
+    if (DrivePartition != 0xff && DrivePartition != 0)
+    {
+        if (!XboxDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
+            return EINVAL;
+        SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
+        SectorCount = PartitionTableEntry.PartitionSectorCount;
+    }
+    else
+    {
+        SectorCount = 0; /* FIXME */
+    }
+
+    Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
+    if (!Context)
+        return ENOMEM;
+    Context->DriveNumber = DriveNumber;
+    Context->SectorSize = SectorSize;
+    Context->SectorOffset = SectorOffset;
+    Context->SectorCount = SectorCount;
+    Context->SectorNumber = 0;
+    FsSetDeviceSpecific(*FileId, Context);
+
+    return ESUCCESS;
+}
+
+extern ARC_STATUS
+DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count);
+
+extern ARC_STATUS
+DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
+
+static const DEVVTBL DiskVtbl =
+{
+    DiskClose,
+    DiskGetFileInformation,
+    DiskOpen,
+    DiskRead,
+    DiskSeek,
+};
+
+static
+VOID
+GetHarddiskIdentifier(PCHAR Identifier,
+                      UCHAR DriveNumber)
+{
+    PMASTER_BOOT_RECORD Mbr;
+    PULONG Buffer;
+    ULONG i;
+    ULONG Checksum;
+    ULONG Signature;
+    CHAR ArcName[MAX_PATH];
+    PARTITION_TABLE_ENTRY PartitionTableEntry;
+
+    /* Read the MBR */
+    if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
+    {
+        ERR("Reading MBR failed\n");
+        return;
+    }
+
+    Buffer = (ULONG*)DiskReadBuffer;
+    Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
+
+    Signature = Mbr->Signature;
+    TRACE("Signature: %x\n", Signature);
+
+    /* Calculate the MBR checksum */
+    Checksum = 0;
+    for (i = 0; i < 512 / sizeof(ULONG); i++)
+    {
+        Checksum += Buffer[i];
+    }
+    Checksum = ~Checksum + 1;
+    TRACE("Checksum: %x\n", Checksum);
+
+    /* Fill out the ARC disk block */
+    reactos_arc_disk_info[reactos_disk_count].DiskSignature.Signature = Signature;
+    reactos_arc_disk_info[reactos_disk_count].DiskSignature.CheckSum = Checksum;
+    sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count);
+    strcpy(reactos_arc_disk_info[reactos_disk_count].ArcName, ArcName);
+    reactos_arc_disk_info[reactos_disk_count].DiskSignature.ArcName =
+        reactos_arc_disk_info[reactos_disk_count].ArcName;
+    reactos_disk_count++;
+
+    sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80);
+    FsRegisterDevice(ArcName, &DiskVtbl);
+
+    /* Add partitions */
+    i = 1;
+    DiskReportError(FALSE);
+    while (XboxDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
+    {
+        if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
+        {
+            sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - 0x80, i);
+            FsRegisterDevice(ArcName, &DiskVtbl);
+        }
+        i++;
+    }
+    DiskReportError(TRUE);
+
+    /* Convert checksum and signature to identifier string */
+    Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
+    Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
+    Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
+    Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
+    Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
+    Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
+    Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
+    Identifier[7] = Hex[Checksum & 0x0F];
+    Identifier[8] = '-';
+    Identifier[9] = Hex[(Signature >> 28) & 0x0F];
+    Identifier[10] = Hex[(Signature >> 24) & 0x0F];
+    Identifier[11] = Hex[(Signature >> 20) & 0x0F];
+    Identifier[12] = Hex[(Signature >> 16) & 0x0F];
+    Identifier[13] = Hex[(Signature >> 12) & 0x0F];
+    Identifier[14] = Hex[(Signature >> 8) & 0x0F];
+    Identifier[15] = Hex[(Signature >> 4) & 0x0F];
+    Identifier[16] = Hex[Signature & 0x0F];
+    Identifier[17] = '-';
+    Identifier[18] = 'A';
+    Identifier[19] = 0;
+    TRACE("Identifier: %s\n", Identifier);
+}
+
+static
+VOID
+DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
+                PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_INT13_DRIVE_PARAMETER Int13Drives;
+    GEOMETRY Geometry;
+    PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
+    UCHAR DiskCount;
+    ULONG i;
+    ULONG Size;
+    BOOLEAN Changed;
+
+    /* Count the number of visible drives */
+    DiskReportError(FALSE);
+    DiskCount = 0;
+
+    /* There are some really broken BIOSes out there. There are even BIOSes
+        * that happily report success when you ask them to read from non-existent
+        * harddisks. So, we set the buffer to known contents first, then try to
+        * read. If the BIOS reports success but the buffer contents haven't
+        * changed then we fail anyway */
+    memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
+    while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
+    {
+        Changed = FALSE;
+        for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
+        {
+            Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
+        }
+        if (! Changed)
+        {
+            TRACE("BIOS reports success for disk %d but data didn't change\n",
+                  (int)DiskCount);
+            break;
+        }
+        DiskCount++;
+        memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
+    }
+    DiskReportError(TRUE);
+    TRACE("BIOS reports %d harddisk%s\n",
+          (int)DiskCount, (DiskCount == 1) ? "" : "s");
+
+    //DetectBiosFloppyController(BusKey);
+
+    /* Allocate resource descriptor */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+           sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        ERR("Failed to allocate resource descriptor\n");
+        return;
+    }
+
+    /* Initialize resource descriptor */
+    memset(PartialResourceList, 0, Size);
+    PartialResourceList->Version = 1;
+    PartialResourceList->Revision = 1;
+    PartialResourceList->Count = 1;
+    PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific;
+    PartialResourceList->PartialDescriptors[0].ShareDisposition = 0;
+    PartialResourceList->PartialDescriptors[0].Flags = 0;
+    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+        sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
+
+    /* Get harddisk Int13 geometry data */
+    Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
+    for (i = 0; i < DiskCount; i++)
+    {
+        if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
+        {
+            Int13Drives[i].DriveSelect = 0x80 + i;
+            Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
+            Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
+            Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
+            Int13Drives[i].NumberDrives = DiskCount;
+
+            TRACE(
+                "Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
+                0x80 + i,
+                Geometry.Cylinders - 1,
+                Geometry.Heads - 1,
+                Geometry.Sectors,
+                Geometry.BytesPerSector);
+        }
+    }
+
+    FldrCreateComponentKey(BusKey,
+                           ControllerClass,
+                           DiskController,
+                           Output | Input,
+                           0,
+                           0xFFFFFFFF,
+                           NULL,
+                           PartialResourceList,
+                           Size,
+                           &ControllerKey);
+    TRACE("Created key: DiskController\\0\n");
+
+    /* Create and fill subkey for each harddisk */
+    for (i = 0; i < DiskCount; i++)
+    {
+        CHAR Identifier[20];
+
+        /* Get disk values */
+        PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size);
+        GetHarddiskIdentifier(Identifier, 0x80 + i);
+
+        /* Create disk key */
+        FldrCreateComponentKey(ControllerKey,
+                               PeripheralClass,
+                               DiskPeripheral,
+                               Output | Input,
+                               0,
+                               0xFFFFFFFF,
+                               Identifier,
+                               PartialResourceList,
+                               Size,
+                               &DiskKey);
+    }
+}
+
+BOOLEAN
+XboxInitializeBootDevices(VOID)
+{
+    // Emulate old behavior
+    return XboxHwDetect() != NULL;
+}
+
+
+
+
+static
+VOID
+DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCONFIGURATION_COMPONENT_DATA BusKey;
+    ULONG Size;
+
+    /* Set 'Configuration Data' value */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+           sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        TRACE("Failed to allocate resource descriptor\n");
+        return;
+    }
+
+    /* Initialize resource descriptor */
+    memset(PartialResourceList, 0, Size);
+    PartialResourceList->Version = 1;
+    PartialResourceList->Revision = 1;
+    PartialResourceList->Count = 0;
+
+    /* Create new bus key */
+    FldrCreateComponentKey(SystemKey,
+                           AdapterClass,
+                           MultiFunctionAdapter,
+                           0x0,
+                           0x0,
+                           0xFFFFFFFF,
+                           "ISA",
+                           PartialResourceList,
+                           Size,
+                           &BusKey);
+
+    /* Increment bus number */
+    (*BusNumber)++;
+
+    /* Detect ISA/BIOS devices */
+    DetectBiosDisks(SystemKey, BusKey);
+
+    /* FIXME: Detect more ISA devices */
+}
+
+PCONFIGURATION_COMPONENT_DATA
+XboxHwDetect(VOID)
+{
+    PCONFIGURATION_COMPONENT_DATA SystemKey;
+    ULONG BusNumber = 0;
+
+    TRACE("DetectHardware()\n");
+
+    /* Create the 'System' key */
+    FldrCreateSystemKey(&SystemKey);
+
+    /* TODO: Build actual xbox's hardware configuration tree */
+    DetectIsaBios(SystemKey, &BusNumber);
+
+    TRACE("DetectHardware() Done\n");
+    return SystemKey;
+}
+
+VOID XboxHwIdle(VOID)
+{
+    /* UNIMPLEMENTED */
+}
+
+
+/******************************************************************************/
+
 VOID
 XboxMachInit(const char *CmdLine)
 {
-  /* Set LEDs to red before anything is initialized */
-  XboxSetLED("rrrr");
-
-  /* Initialize our stuff */
-  XboxMemInit();
-  XboxVideoInit();
-
-  /* Setup vtbl */
-  MachVtbl.ConsPutChar = XboxConsPutChar;
-  MachVtbl.ConsKbHit = XboxConsKbHit;
-  MachVtbl.ConsGetCh = XboxConsGetCh;
-  MachVtbl.VideoClearScreen = XboxVideoClearScreen;
-  MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
-  MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
-  MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
-  MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
-  MachVtbl.VideoPutChar = XboxVideoPutChar;
-  MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
-  MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
-  MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
-  MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
-  MachVtbl.VideoSync = XboxVideoSync;
-  MachVtbl.Beep = PcBeep;
-  MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
-  MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
-  MachVtbl.DiskGetBootPath = DiskGetBootPath;
-  MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
-  MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
-  MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
-  MachVtbl.GetTime = XboxGetTime;
-  MachVtbl.InitializeBootDevices = XboxInitializeBootDevices;
-  MachVtbl.HwDetect = XboxHwDetect;
-  MachVtbl.HwIdle = XboxHwIdle;
-
-  /* Set LEDs to orange after init */
-  XboxSetLED("oooo");
+    /* Set LEDs to red before anything is initialized */
+    XboxSetLED("rrrr");
+
+    /* Initialize our stuff */
+    XboxMemInit();
+    XboxVideoInit();
+
+    /* Setup vtbl */
+    MachVtbl.ConsPutChar = XboxConsPutChar;
+    MachVtbl.ConsKbHit = XboxConsKbHit;
+    MachVtbl.ConsGetCh = XboxConsGetCh;
+    MachVtbl.VideoClearScreen = XboxVideoClearScreen;
+    MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
+    MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
+    MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
+    MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
+    MachVtbl.VideoPutChar = XboxVideoPutChar;
+    MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
+    MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
+    MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
+    MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
+    MachVtbl.VideoSync = XboxVideoSync;
+    MachVtbl.Beep = PcBeep;
+    MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
+    MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
+    MachVtbl.DiskGetBootPath = DiskGetBootPath;
+    MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
+    MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
+    MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
+    MachVtbl.GetTime = XboxGetTime;
+    MachVtbl.InitializeBootDevices = PcInitializeBootDevices;
+    MachVtbl.HwDetect = XboxHwDetect;
+    MachVtbl.HwIdle = XboxHwIdle;
+
+    /* Set LEDs to orange after init */
+    XboxSetLED("oooo");
 }
 
 VOID
 XboxPrepareForReactOS(IN BOOLEAN Setup)
 {
-    //
-    // On XBOX, prepare video and turn off the floppy motor
-    //
+    /* On XBOX, prepare video and turn off the floppy motor */
     XboxVideoPrepareForReactOS(Setup);
     DiskStopFloppyMotor();
 }
+
+/* EOF */
index f6055cc..fd85af7 100644 (file)
@@ -18,6 +18,8 @@
  */
 
 #include <freeldr.h>
+
+#define NDEBUG
 #include <debug.h>
 
 DBG_DEFAULT_CHANNEL(DISK);
@@ -25,41 +27,40 @@ DBG_DEFAULT_CHANNEL(DISK);
 #include <pshpack2.h>
 typedef struct
 {
-    UCHAR        PacketSize;                // 00h - Size of packet (10h or 18h)
-    UCHAR        Reserved;                // 01h - Reserved (0)
-    USHORT        LBABlockCount;            // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
-    USHORT        TransferBufferOffset;    // 04h - Transfer buffer offset (seg:off)
-    USHORT        TransferBufferSegment;    //       Transfer buffer segment (seg:off)
-    ULONGLONG        LBAStartBlock;            // 08h - Starting absolute block number
-    //ULONGLONG        TransferBuffer64;        // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
-                                    //       used if DWORD at 04h is FFFFh:FFFFh
-                                    //       Commented since some earlier BIOSes refuse to work with
-                                    //       such extended structure
+    UCHAR       PacketSize;             // 00h - Size of packet (10h or 18h)
+    UCHAR       Reserved;               // 01h - Reserved (0)
+    USHORT      LBABlockCount;          // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
+    USHORT      TransferBufferOffset;   // 04h - Transfer buffer offset (seg:off)
+    USHORT      TransferBufferSegment;  //       Transfer buffer segment (seg:off)
+    ULONGLONG   LBAStartBlock;          // 08h - Starting absolute block number
+//  ULONGLONG   TransferBuffer64;       // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
+                                        //       used if DWORD at 04h is FFFFh:FFFFh
+                                        //       Commented since some earlier BIOSes refuse to work with
+                                        //       such extended structure
 } I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
 #include <poppack.h>
 
-/////////////////////////////////////////////////////////////////////////////////////////////
-// FUNCTIONS
-/////////////////////////////////////////////////////////////////////////////////////////////
+/* FUNCTIONS *****************************************************************/
 
-static BOOLEAN PcDiskResetController(UCHAR DriveNumber)
+BOOLEAN DiskResetController(UCHAR DriveNumber)
 {
-    REGS    RegsIn;
-    REGS    RegsOut;
-
-    WARN("PcDiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
-
-    // BIOS Int 13h, function 0 - Reset disk system
-    // AH = 00h
-    // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
-    // Return:
-    // AH = status
-    // CF clear if successful
-    // CF set on error
+    REGS RegsIn, RegsOut;
+
+    WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
+
+    /*
+     * BIOS Int 13h, function 0 - Reset disk system
+     * AH = 00h
+     * DL = drive (if bit 7 is set both hard disks and floppy disks reset)
+     * Return:
+     * AH = status
+     * CF clear if successful
+     * CF set on error
+     */
     RegsIn.b.ah = 0x00;
     RegsIn.b.dl = DriveNumber;
 
-    // Reset the disk controller
+    /* Reset the disk controller */
     Int386(0x13, &RegsIn, &RegsOut);
 
     return INT386_SUCCESS(RegsOut);
@@ -67,23 +68,16 @@ static BOOLEAN PcDiskResetController(UCHAR DriveNumber)
 
 static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
-    REGS                        RegsIn;
-    REGS                        RegsOut;
-    ULONG                       RetryCount;
-    PI386_DISK_ADDRESS_PACKET    Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
+    REGS RegsIn, RegsOut;
+    ULONG RetryCount;
+    PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
 
     TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
     ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF);
 
-    // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
-    RegsIn.b.ah = 0x42;                 // Subfunction 42h
-    RegsIn.b.dl = DriveNumber;          // Drive number in DL (0 - floppy, 0x80 - harddisk)
-    RegsIn.x.ds = BIOSCALLBUFSEGMENT;   // DS:SI -> disk address packet
-    RegsIn.w.si = BIOSCALLBUFOFFSET;
-
-    // Setup disk address packet
-    RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
-    Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
+    /* Setup disk address packet */
+    RtlZeroMemory(Packet, sizeof(*Packet));
+    Packet->PacketSize = sizeof(*Packet);
     Packet->Reserved = 0;
     Packet->LBABlockCount = (USHORT)SectorCount;
     ASSERT(Packet->LBABlockCount == SectorCount);
@@ -91,39 +85,45 @@ static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNu
     Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4);
     Packet->LBAStartBlock = SectorNumber;
 
-    // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
-    // Return:
-    // CF clear if successful
-    // AH = 00h
-    // CF set on error
-    // AH = error code
-    // disk address packet's block count field set to the
-    // number of blocks successfully transferred
+    /*
+     * BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
+     * Return:
+     * CF clear if successful
+     * AH = 00h
+     * CF set on error
+     * AH = error code
+     * Disk address packet's block count field set to the
+     * number of blocks successfully transferred.
+     */
+    RegsIn.b.ah = 0x42;                 // Subfunction 42h
+    RegsIn.b.dl = DriveNumber;          // Drive number in DL (0 - floppy, 0x80 - harddisk)
+    RegsIn.x.ds = BIOSCALLBUFSEGMENT;   // DS:SI -> disk address packet
+    RegsIn.w.si = BIOSCALLBUFOFFSET;
 
-    // Retry 3 times
+    /* Retry 3 times */
     for (RetryCount=0; RetryCount<3; RetryCount++)
     {
         Int386(0x13, &RegsIn, &RegsOut);
 
-        // If it worked return TRUE
+        /* If it worked return TRUE */
         if (INT386_SUCCESS(RegsOut))
         {
             return TRUE;
         }
-        // If it was a corrected ECC error then the data is still good
+        /* If it was a corrected ECC error then the data is still good */
         else if (RegsOut.b.ah == 0x11)
         {
             return TRUE;
         }
-        // If it failed then do the next retry
+        /* If it failed then do the next retry */
         else
         {
-            PcDiskResetController(DriveNumber);
+            DiskResetController(DriveNumber);
             continue;
         }
     }
 
-    // If we get here then the read failed
+    /* If we get here then the read failed */
     ERR("Disk Read Failed in LBA mode: %x (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n", RegsOut.b.ah, DriveNumber, SectorNumber, SectorCount);
 
     return FALSE;
@@ -131,20 +131,17 @@ static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNu
 
 static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
-    UCHAR            PhysicalSector;
-    UCHAR            PhysicalHead;
-    ULONG            PhysicalTrack;
-    GEOMETRY    DriveGeometry;
-    ULONG            NumberOfSectorsToRead;
-    REGS        RegsIn;
-    REGS        RegsOut;
-    ULONG            RetryCount;
+    UCHAR PhysicalSector;
+    UCHAR PhysicalHead;
+    ULONG PhysicalTrack;
+    GEOMETRY DriveGeometry;
+    ULONG NumberOfSectorsToRead;
+    REGS RegsIn, RegsOut;
+    ULONG RetryCount;
 
     TRACE("PcDiskReadLogicalSectorsCHS()\n");
 
-    //
-    // Get the drive geometry
-    //
+    /* Get the drive geometry */
     if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
         DriveGeometry.Sectors == 0 ||
         DriveGeometry.Heads == 0)
@@ -154,18 +151,15 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
 
     while (SectorCount)
     {
-
-        //
-        // Calculate the physical disk offsets
-        // Note: DriveGeometry.Sectors < 64
-        //
+        /*
+         * Calculate the physical disk offsets.
+         * Note: DriveGeometry.Sectors < 64
+         */
         PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors);
         PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
         PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
 
-        //
-        // Calculate how many sectors we need to read this round
-        //
+        /* Calculate how many sectors we need to read this round */
         if (PhysicalSector > 1)
         {
             if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
@@ -181,9 +175,7 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
                 NumberOfSectorsToRead = SectorCount;
         }
 
-        //
-        // Make sure the read is within the geometry boundaries
-        //
+        /* Make sure the read is within the geometry boundaries */
         if ((PhysicalHead >= DriveGeometry.Heads) ||
             (PhysicalTrack >= DriveGeometry.Cylinders) ||
             ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
@@ -193,22 +185,24 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
             return FALSE;
         }
 
-        // BIOS Int 13h, function 2 - Read Disk Sectors
-        // AH = 02h
-        // AL = number of sectors to read (must be nonzero)
-        // CH = low eight bits of cylinder number
-        // CL = sector number 1-63 (bits 0-5)
-        //      high two bits of cylinder (bits 6-7, hard disk only)
-        // DH = head number
-        // DL = drive number (bit 7 set for hard disk)
-        // ES:BX -> data buffer
-        // Return:
-        // CF set on error
-        // if AH = 11h (corrected ECC error), AL = burst length
-        // CF clear if successful
-        // AH = status
-        // AL = number of sectors transferred
-        //  (only valid if CF set for some BIOSes)
+        /*
+         * BIOS Int 13h, function 2 - Read Disk Sectors
+         * AH = 02h
+         * AL = number of sectors to read (must be nonzero)
+         * CH = low eight bits of cylinder number
+         * CL = sector number 1-63 (bits 0-5)
+         *      high two bits of cylinder (bits 6-7, hard disk only)
+         * DH = head number
+         * DL = drive number (bit 7 set for hard disk)
+         * ES:BX -> data buffer
+         * Return:
+         * CF set on error
+         * if AH = 11h (corrected ECC error), AL = burst length
+         * CF clear if successful
+         * AH = status
+         * AL = number of sectors transferred
+         *  (only valid if CF set for some BIOSes)
+         */
         RegsIn.b.ah = 0x02;
         RegsIn.b.al = (UCHAR)NumberOfSectorsToRead;
         RegsIn.b.ch = (PhysicalTrack & 0xFF);
@@ -218,41 +212,37 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
         RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
         RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
 
-        //
-        // Perform the read
-        // Retry 3 times
-        //
+        /* Perform the read. Retry 3 times. */
         for (RetryCount=0; RetryCount<3; RetryCount++)
         {
             Int386(0x13, &RegsIn, &RegsOut);
 
-            // If it worked break out
+            /* If it worked break out */
             if (INT386_SUCCESS(RegsOut))
             {
                 break;
             }
-            // If it was a corrected ECC error then the data is still good
+            /* If it was a corrected ECC error then the data is still good */
             else if (RegsOut.b.ah == 0x11)
             {
                 break;
             }
-            // If it failed the do the next retry
+            /* If it failed the do the next retry */
             else
             {
-                PcDiskResetController(DriveNumber);
-
+                DiskResetController(DriveNumber);
                 continue;
             }
         }
 
-        // If we retried 3 times then fail
+        /* If we retried 3 times then fail */
         if (RetryCount >= 3)
         {
             ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x\n", RegsOut.b.ah);
             return FALSE;
         }
 
-        // I have learned that not all bioses return
+        // I have learned that not all BIOSes return
         // the sector read count in the AL register (at least mine doesn't)
         // even if the sectors were read correctly. So instead
         // of checking the sector read count we will rely solely
@@ -266,122 +256,287 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
     return TRUE;
 }
 
+static BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber)
+{
+    static UCHAR LastDriveNumber = 0xff;
+    static BOOLEAN LastSupported;
+    REGS RegsIn, RegsOut;
+
+    TRACE("DiskInt13ExtensionsSupported()\n");
+
+    if (DriveNumber == LastDriveNumber)
+    {
+        TRACE("Using cached value %s for drive 0x%x\n",
+              LastSupported ? "TRUE" : "FALSE", DriveNumber);
+        return LastSupported;
+    }
+
+    /*
+     * Some BIOSes report that extended disk access functions are not supported
+     * when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
+     * with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
+     * we can assume that all El Torito capable BIOSes support INT 13 extensions.
+     * We simply detect whether we're booting from CD by checking whether the drive
+     * number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
+     */
+    if (DriveNumber >= 0x8A)
+    {
+        LastSupported = TRUE;
+        return TRUE;
+    }
+
+    LastDriveNumber = DriveNumber;
+
+    /*
+     * IBM/MS INT 13 Extensions - INSTALLATION CHECK
+     * AH = 41h
+     * BX = 55AAh
+     * DL = drive (80h-FFh)
+     * Return:
+     * CF set on error (extensions not supported)
+     * AH = 01h (invalid function)
+     * CF clear if successful
+     * BX = AA55h if installed
+     * AH = major version of extensions
+     * 01h = 1.x
+     * 20h = 2.0 / EDD-1.0
+     * 21h = 2.1 / EDD-1.1
+     * 30h = EDD-3.0
+     * AL = internal use
+     * CX = API subset support bitmap
+     * DH = extension version (v2.0+ ??? -- not present in 1.x)
+     *
+     * Bitfields for IBM/MS INT 13 Extensions API support bitmap
+     * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
+     * Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
+     * Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
+     *        extended drive parameter table is valid
+     * Bits 3-15 reserved
+     */
+    RegsIn.b.ah = 0x41;
+    RegsIn.w.bx = 0x55AA;
+    RegsIn.b.dl = DriveNumber;
+
+    /* Reset the disk controller */
+    Int386(0x13, &RegsIn, &RegsOut);
+
+    if (!INT386_SUCCESS(RegsOut))
+    {
+        /* CF set on error (extensions not supported) */
+        LastSupported = FALSE;
+        return FALSE;
+    }
+
+    if (RegsOut.w.bx != 0xAA55)
+    {
+        /* BX = AA55h if installed */
+        LastSupported = FALSE;
+        return FALSE;
+    }
+
+    if (!(RegsOut.w.cx & 0x0001))
+    {
+        /*
+         * CX = API subset support bitmap.
+         * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported.
+         */
+        DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n",
+                 RegsOut.w.cx, DriveNumber);
+        LastSupported = FALSE;
+        return FALSE;
+    }
+
+    LastSupported = TRUE;
+    return TRUE;
+}
+
 BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
     BOOLEAN ExtensionsSupported;
 
-    TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
+    TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n",
+          DriveNumber, SectorNumber, SectorCount, Buffer);
 
-    //
-    // Check to see if it is a fixed disk drive
-    // If so then check to see if Int13 extensions work
-    // If they do then use them, otherwise default back to BIOS calls
-    //
+    /*
+     * Check to see if it is a fixed disk drive.
+     * If so then check to see if Int13 extensions work.
+     * If they do then use them, otherwise default back to BIOS calls.
+     */
     ExtensionsSupported = DiskInt13ExtensionsSupported(DriveNumber);
 
     if ((DriveNumber >= 0x80) && ExtensionsSupported)
     {
         TRACE("Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, ExtensionsSupported ? "TRUE" : "FALSE");
 
-        //
-        // LBA is easy, nothing to calculate
-        // Just do the read
-        //
+        /* LBA is easy, nothing to calculate. Just do the read. */
         return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
     }
     else
     {
-        // LBA is not supported default to the CHS calls
+        /* LBA is not supported default to the CHS calls */
         return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
     }
 
     return TRUE;
 }
 
+VOID DiskStopFloppyMotor(VOID)
+{
+    WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
+}
+
+BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize)
+{
+    REGS RegsIn, RegsOut;
+    PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER);
+
+    TRACE("DiskGetExtendedDriveParameters()\n");
+
+    if (!DiskInt13ExtensionsSupported(DriveNumber))
+        return FALSE;
+
+    /* Initialize transfer buffer */
+    *Ptr = BufferSize;
+
+    /*
+     * BIOS Int 13h, function 48h - Get drive parameters
+     * AH = 48h
+     * DL = drive (bit 7 set for hard disk)
+     * DS:SI = result buffer
+     * Return:
+     * CF set on error
+     * AH = status (07h)
+     * CF clear if successful
+     * AH = 00h
+     * DS:SI -> result buffer
+     */
+    RegsIn.b.ah = 0x48;
+    RegsIn.b.dl = DriveNumber;
+    RegsIn.x.ds = BIOSCALLBUFSEGMENT;   // DS:SI -> result buffer
+    RegsIn.w.si = BIOSCALLBUFOFFSET;
+
+    /* Get drive parameters */
+    Int386(0x13, &RegsIn, &RegsOut);
+    if (!INT386_SUCCESS(RegsOut))
+        return FALSE;
+
+    memcpy(Buffer, Ptr, BufferSize);
+
+#if DBG
+    TRACE("size of buffer:                          %x\n", Ptr[0]);
+    TRACE("information flags:                       %x\n", Ptr[1]);
+    TRACE("number of physical cylinders on drive:   %u\n", *(PULONG)&Ptr[2]);
+    TRACE("number of physical heads on drive:       %u\n", *(PULONG)&Ptr[4]);
+    TRACE("number of physical sectors per track:    %u\n", *(PULONG)&Ptr[6]);
+    TRACE("total number of sectors on drive:        %I64u\n", *(unsigned long long*)&Ptr[8]);
+    TRACE("bytes per sector:                        %u\n", Ptr[12]);
+    if (Ptr[0] >= 0x1e)
+    {
+        TRACE("EED configuration parameters:            %x:%x\n", Ptr[13], Ptr[14]);
+        if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
+        {
+           PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
+           TRACE("SpecPtr:                                 %x\n", SpecPtr);
+           TRACE("physical I/O port base address:          %x\n", *(PUSHORT)&SpecPtr[0]);
+           TRACE("disk-drive control port address:         %x\n", *(PUSHORT)&SpecPtr[2]);
+           TRACE("drive flags:                             %x\n", SpecPtr[4]);
+           TRACE("proprietary information:                 %x\n", SpecPtr[5]);
+           TRACE("IRQ for drive:                           %u\n", SpecPtr[6]);
+           TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]);
+           TRACE("DMA control:                             %x\n", SpecPtr[8]);
+           TRACE("programmed I/O control:                  %x\n", SpecPtr[9]);
+           TRACE("drive options:                           %x\n", *(PUSHORT)&SpecPtr[10]);
+        }
+    }
+    if (Ptr[0] >= 0x42)
+    {
+        TRACE("signature:                             %x\n", Ptr[15]);
+    }
+#endif
+
+    return TRUE;
+}
+
 BOOLEAN
 PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
 {
-  EXTENDED_GEOMETRY ExtGeometry;
-  REGS RegsIn;
-  REGS RegsOut;
-  ULONG Cylinders;
-
-  TRACE("DiskGetDriveGeometry()\n");
-
-  /* Try to get the extended geometry first */
-  ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
-  if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
-  {
-    Geometry->Cylinders = ExtGeometry.Cylinders;
-    Geometry->Heads = ExtGeometry.Heads;
-    Geometry->Sectors = ExtGeometry.SectorsPerTrack;
-    Geometry->BytesPerSector = ExtGeometry.BytesPerSector;
+    EXTENDED_GEOMETRY ExtGeometry;
+    REGS RegsIn, RegsOut;
+    ULONG Cylinders;
 
-    return TRUE;
-  }
-
-  /* BIOS Int 13h, function 08h - Get drive parameters
-   * AH = 08h
-   * DL = drive (bit 7 set for hard disk)
-   * ES:DI = 0000h:0000h to guard against BIOS bugs
-   * Return:
-   * CF set on error
-   * AH = status (07h)
-   * CF clear if successful
-   * AH = 00h
-   * AL = 00h on at least some BIOSes
-   * BL = drive type (AT/PS2 floppies only)
-   * CH = low eight bits of maximum cylinder number
-   * CL = maximum sector number (bits 5-0)
-   *      high two bits of maximum cylinder number (bits 7-6)
-   * DH = maximum head number
-   * DL = number of drives
-   * ES:DI -> drive parameter table (floppies only)
-   */
-  RegsIn.b.ah = 0x08;
-  RegsIn.b.dl = DriveNumber;
-  RegsIn.w.es = 0x0000;
-  RegsIn.w.di = 0x0000;
-
-  /* Get drive parameters */
-  Int386(0x13, &RegsIn, &RegsOut);
-
-  if (! INT386_SUCCESS(RegsOut))
+    TRACE("DiskGetDriveGeometry()\n");
+
+    /* Try to get the extended geometry first */
+    ExtGeometry.Size = sizeof(ExtGeometry);
+    if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
     {
-      return FALSE;
+        Geometry->Cylinders = ExtGeometry.Cylinders;
+        Geometry->Heads = ExtGeometry.Heads;
+        Geometry->Sectors = ExtGeometry.SectorsPerTrack;
+        Geometry->BytesPerSector = ExtGeometry.BytesPerSector;
+        return TRUE;
     }
 
-  Cylinders = (RegsOut.b.cl & 0xC0) << 2;
-  Cylinders += RegsOut.b.ch;
-  Cylinders++;
-  Geometry->Cylinders = Cylinders;
-  Geometry->Heads = RegsOut.b.dh + 1;
-  Geometry->Sectors = RegsOut.b.cl & 0x3F;
-  Geometry->BytesPerSector = 512;            /* Just assume 512 bytes per sector */
+    /*
+     * BIOS Int 13h, function 08h - Get drive parameters
+     * AH = 08h
+     * DL = drive (bit 7 set for hard disk)
+     * ES:DI = 0000h:0000h to guard against BIOS bugs
+     * Return:
+     * CF set on error
+     * AH = status (07h)
+     * CF clear if successful
+     * AH = 00h
+     * AL = 00h on at least some BIOSes
+     * BL = drive type (AT/PS2 floppies only)
+     * CH = low eight bits of maximum cylinder number
+     * CL = maximum sector number (bits 5-0)
+     *      high two bits of maximum cylinder number (bits 7-6)
+     * DH = maximum head number
+     * DL = number of drives
+     * ES:DI -> drive parameter table (floppies only)
+     */
+    RegsIn.b.ah = 0x08;
+    RegsIn.b.dl = DriveNumber;
+    RegsIn.w.es = 0x0000;
+    RegsIn.w.di = 0x0000;
 
-  return TRUE;
+    /* Get drive parameters */
+    Int386(0x13, &RegsIn, &RegsOut);
+    if (!INT386_SUCCESS(RegsOut))
+        return FALSE;
+
+    Cylinders = (RegsOut.b.cl & 0xC0) << 2;
+    Cylinders += RegsOut.b.ch;
+    Cylinders++;
+    Geometry->Cylinders = Cylinders;
+    Geometry->Heads = RegsOut.b.dh + 1;
+    Geometry->Sectors = RegsOut.b.cl & 0x3F;
+    Geometry->BytesPerSector = 512;     /* Just assume 512 bytes per sector */
+
+    return TRUE;
 }
 
 ULONG
 PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
 {
-  GEOMETRY    Geometry;
+    GEOMETRY Geometry;
 
-  /* If LBA is supported then the block size will be 64 sectors (32k)
-   * If not then the block size is the size of one track */
-  if (DiskInt13ExtensionsSupported(DriveNumber))
+    /* If LBA is supported then the block size will be 64 sectors (32k)
+     * If not then the block size is the size of one track. */
+    if (DiskInt13ExtensionsSupported(DriveNumber))
     {
-      return 64;
+        return 64;
     }
-  /* Get the disk geometry
-   * If this fails then we will just return 1 sector to be safe */
-  else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
+    /* Get the disk geometry. If this fails then we will
+     * just return 1 sector to be safe. */
+    else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
     {
-      return 1;
+        return 1;
     }
-  else
+    else
     {
-      return Geometry.Sectors;
+        return Geometry.Sectors;
     }
 }
 
index 1a28eda..fa3e0a1 100644 (file)
@@ -36,22 +36,22 @@ DBG_DEFAULT_CHANNEL(DISK);
 
 static struct
 {
-  ULONG SectorCountBeforePartition;
-  ULONG PartitionSectorCount;
-  UCHAR SystemIndicator;
+    ULONG SectorCountBeforePartition;
+    ULONG PartitionSectorCount;
+    UCHAR SystemIndicator;
 } XboxPartitions[] =
 {
-  /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
-  { 0x0055F400, 0x0098f800, PARTITION_FAT32  }, /* Store, E: */
-  { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
-  { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
-  { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
-  { 0x002EE400, 0x00177000, PARTITION_FAT_16 }  /* Cache3, Z: */
+    /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
+    { 0x0055F400, 0x0098f800, PARTITION_FAT32  }, /* Store , E: */
+    { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
+    { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
+    { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
+    { 0x002EE400, 0x00177000, PARTITION_FAT_16 }  /* Cache3, Z: */
 };
 
-#define  IDE_SECTOR_BUF_SZ         512
-#define  IDE_MAX_POLL_RETRIES      100000
-#define  IDE_MAX_BUSY_RETRIES      50000
+#define  IDE_SECTOR_BUF_SZ      512
+#define  IDE_MAX_POLL_RETRIES   100000
+#define  IDE_MAX_BUSY_RETRIES   50000
 
 /* Control Block offsets and masks */
 #define  IDE_REG_ALT_STATUS     0x0000
@@ -111,131 +111,131 @@ static struct
  *  Each macro takes an address of the command port block, and data
  */
 #define IDEReadError(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
 #define IDEWritePrecomp(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
 #define IDEReadSectorCount(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
 #define IDEWriteSectorCount(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
 #define IDEReadSectorNum(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
 #define IDEWriteSectorNum(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
 #define IDEReadCylinderLow(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
 #define IDEWriteCylinderLow(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
 #define IDEReadCylinderHigh(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
 #define IDEWriteCylinderHigh(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
 #define IDEReadDriveHead(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
 #define IDEWriteDriveHead(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
 #define IDEReadStatus(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
 #define IDEWriteCommand(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
 #define IDEReadDMACommand(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address))))
+    (READ_PORT_UCHAR((PUCHAR)((Address))))
 #define IDEWriteDMACommand(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
 #define IDEReadDMAStatus(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
 #define IDEWriteDMAStatus(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
 #define IDEWritePRDTable(Address, Data) \
-  (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
+    (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
 
 /*
  *  Data block read and write commands
  */
 #define IDEReadBlock(Address, Buffer, Count) \
-  (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
+    (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
 #define IDEWriteBlock(Address, Buffer, Count) \
-  (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
+    (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
 
 #define IDEReadBlock32(Address, Buffer, Count) \
-  (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
+    (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
 #define IDEWriteBlock32(Address, Buffer, Count) \
-  (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
+    (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
 
 #define IDEReadWord(Address) \
-  (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT)))
+    (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT)))
 
 /*
  *  Access macros for control registers
  *  Each macro takes an address of the control port blank and data
  */
 #define IDEReadAltStatus(Address) \
-  (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
+    (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
 #define IDEWriteDriveControl(Address, Data) \
-  (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
+    (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
 
 /* IDE_DRIVE_IDENTIFY */
 
 typedef struct _IDE_DRIVE_IDENTIFY
 {
-  USHORT   ConfigBits;          /*00*/
-  USHORT   LogicalCyls;         /*01*/
-  USHORT   Reserved02;          /*02*/
-  USHORT   LogicalHeads;        /*03*/
-  USHORT   BytesPerTrack;       /*04*/
-  USHORT   BytesPerSector;      /*05*/
-  USHORT   SectorsPerTrack;     /*06*/
-  UCHAR    InterSectorGap;      /*07*/
-  UCHAR    InterSectorGapSize;
-  UCHAR    Reserved08H;         /*08*/
-  UCHAR    BytesInPLO;
-  USHORT   VendorUniqueCnt;     /*09*/
-  char  SerialNumber[20];    /*10*/
-  USHORT   ControllerType;      /*20*/
-  USHORT   BufferSize;          /*21*/
-  USHORT   ECCByteCnt;          /*22*/
-  char  FirmwareRev[8];      /*23*/
-  char  ModelNumber[40];     /*27*/
-  USHORT   RWMultImplemented;   /*47*/
-  USHORT   DWordIo;         /*48*/
-  USHORT   Capabilities;        /*49*/
+    USHORT   ConfigBits;          /*00*/
+    USHORT   LogicalCyls;         /*01*/
+    USHORT   Reserved02;          /*02*/
+    USHORT   LogicalHeads;        /*03*/
+    USHORT   BytesPerTrack;       /*04*/
+    USHORT   BytesPerSector;      /*05*/
+    USHORT   SectorsPerTrack;     /*06*/
+    UCHAR    InterSectorGap;      /*07*/
+    UCHAR    InterSectorGapSize;
+    UCHAR    Reserved08H;         /*08*/
+    UCHAR    BytesInPLO;
+    USHORT   VendorUniqueCnt;     /*09*/
+    UCHAR    SerialNumber[20];    /*10*/
+    USHORT   ControllerType;      /*20*/
+    USHORT   BufferSize;          /*21*/
+    USHORT   ECCByteCnt;          /*22*/
+    UCHAR    FirmwareRev[8];      /*23*/
+    UCHAR    ModelNumber[40];     /*27*/
+    USHORT   RWMultImplemented;   /*47*/
+    USHORT   DWordIo;             /*48*/
+    USHORT   Capabilities;        /*49*/
 #define IDE_DRID_STBY_SUPPORTED   0x2000
 #define IDE_DRID_IORDY_SUPPORTED  0x0800
 #define IDE_DRID_IORDY_DISABLE    0x0400
 #define IDE_DRID_LBA_SUPPORTED    0x0200
 #define IDE_DRID_DMA_SUPPORTED    0x0100
-  USHORT   Reserved50;          /*50*/
-  USHORT   MinPIOTransTime;     /*51*/
-  USHORT   MinDMATransTime;     /*52*/
-  USHORT   TMFieldsValid;       /*53*/
-  USHORT   TMCylinders;         /*54*/
-  USHORT   TMHeads;             /*55*/
-  USHORT   TMSectorsPerTrk;     /*56*/
-  USHORT   TMCapacityLo;        /*57*/
-  USHORT   TMCapacityHi;        /*58*/
-  USHORT   RWMultCurrent;       /*59*/
-  USHORT   TMSectorCountLo;     /*60*/
-  USHORT   TMSectorCountHi;     /*61*/
-  USHORT   DmaModes;            /*62*/
-  USHORT   MultiDmaModes;       /*63*/
-  USHORT   Reserved64[5];       /*64*/
-  USHORT   Reserved69[2];       /*69*/
-  USHORT   Reserved71[4];       /*71*/
-  USHORT   MaxQueueDepth;       /*75*/
-  USHORT   Reserved76[4];       /*76*/
-  USHORT   MajorRevision;       /*80*/
-  USHORT   MinorRevision;       /*81*/
-  USHORT   SupportedFeatures82; /*82*/
-  USHORT   SupportedFeatures83; /*83*/
-  USHORT   SupportedFeatures84; /*84*/
-  USHORT   EnabledFeatures85;   /*85*/
-  USHORT   EnabledFeatures86;   /*86*/
-  USHORT   EnabledFeatures87;   /*87*/
-  USHORT   UltraDmaModes;       /*88*/
-  USHORT   Reserved89[11];      /*89*/
-  USHORT   Max48BitAddress[4];  /*100*/
-  USHORT   Reserved104[151];    /*104*/
-  USHORT   Checksum;            /*255*/
+    USHORT   Reserved50;          /*50*/
+    USHORT   MinPIOTransTime;     /*51*/
+    USHORT   MinDMATransTime;     /*52*/
+    USHORT   TMFieldsValid;       /*53*/
+    USHORT   TMCylinders;         /*54*/
+    USHORT   TMHeads;             /*55*/
+    USHORT   TMSectorsPerTrk;     /*56*/
+    USHORT   TMCapacityLo;        /*57*/
+    USHORT   TMCapacityHi;        /*58*/
+    USHORT   RWMultCurrent;       /*59*/
+    USHORT   TMSectorCountLo;     /*60*/
+    USHORT   TMSectorCountHi;     /*61*/
+    USHORT   DmaModes;            /*62*/
+    USHORT   MultiDmaModes;       /*63*/
+    USHORT   Reserved64[5];       /*64*/
+    USHORT   Reserved69[2];       /*69*/
+    USHORT   Reserved71[4];       /*71*/
+    USHORT   MaxQueueDepth;       /*75*/
+    USHORT   Reserved76[4];       /*76*/
+    USHORT   MajorRevision;       /*80*/
+    USHORT   MinorRevision;       /*81*/
+    USHORT   SupportedFeatures82; /*82*/
+    USHORT   SupportedFeatures83; /*83*/
+    USHORT   SupportedFeatures84; /*84*/
+    USHORT   EnabledFeatures85;   /*85*/
+    USHORT   EnabledFeatures86;   /*86*/
+    USHORT   EnabledFeatures87;   /*87*/
+    USHORT   UltraDmaModes;       /*88*/
+    USHORT   Reserved89[11];      /*89*/
+    USHORT   Max48BitAddress[4];  /*100*/
+    USHORT   Reserved104[151];    /*104*/
+    USHORT   Checksum;            /*255*/
 } IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
 
 /*  XboxDiskPolledRead
@@ -247,21 +247,20 @@ typedef struct _IDE_DRIVE_IDENTIFY
  *    PASSIVE_LEVEL
  *
  *  ARGUMENTS:
- *    ULONG   CommandPort   Address of command port for drive
- *    ULONG   ControlPort   Address of control port for drive
- *    UCHAR    PreComp       Value to write to precomp register
- *    UCHAR    SectorCnt     Value to write to sectorCnt register
- *    UCHAR    SectorNum     Value to write to sectorNum register
- *    UCHAR    CylinderLow   Value to write to CylinderLow register
- *    UCHAR    CylinderHigh  Value to write to CylinderHigh register
- *    UCHAR    DrvHead       Value to write to Drive/Head register
- *    UCHAR    Command       Value to write to Command register
- *    PVOID Buffer        Buffer for output data
+ *    ULONG CommandPort     Address of command port for drive
+ *    ULONG ControlPort     Address of control port for drive
+ *    UCHAR PreComp         Value to write to precomp register
+ *    UCHAR SectorCnt       Value to write to sectorCnt register
+ *    UCHAR SectorNum       Value to write to sectorNum register
+ *    UCHAR CylinderLow     Value to write to CylinderLow register
+ *    UCHAR CylinderHigh    Value to write to CylinderHigh register
+ *    UCHAR DrvHead         Value to write to Drive/Head register
+ *    UCHAR Command         Value to write to Command register
+ *    PVOID Buffer          Buffer for output data
  *
  *  RETURNS:
  *    BOOLEAN: TRUE success, FALSE error
  */
-
 static BOOLEAN
 XboxDiskPolledRead(ULONG CommandPort,
                    ULONG ControlPort,
@@ -274,300 +273,296 @@ XboxDiskPolledRead(ULONG CommandPort,
                    UCHAR Command,
                    PVOID Buffer)
 {
-  ULONG SectorCount = 0;
-  ULONG RetryCount;
-  BOOLEAN Junk = FALSE;
-  UCHAR Status;
+    ULONG SectorCount = 0;
+    ULONG RetryCount;
+    BOOLEAN Junk = FALSE;
+    UCHAR Status;
 
-  /* Wait for BUSY to clear */
-  for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
+    /* Wait for BUSY to clear */
+    for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
     {
-      Status = IDEReadStatus(CommandPort);
-      if (!(Status & IDE_SR_BUSY))
-        {
-          break;
-        }
-      StallExecutionProcessor(10);
+        Status = IDEReadStatus(CommandPort);
+        if (!(Status & IDE_SR_BUSY))
+            break;
+
+        StallExecutionProcessor(10);
     }
-  TRACE("status=0x%x\n", Status);
-  TRACE("waited %d usecs for busy to clear\n", RetryCount * 10);
-  if (RetryCount >= IDE_MAX_BUSY_RETRIES)
+    TRACE("status=0x%x\n", Status);
+    TRACE("waited %d usecs for busy to clear\n", RetryCount * 10);
+    if (RetryCount >= IDE_MAX_BUSY_RETRIES)
     {
-      WARN("Drive is BUSY for too long\n");
-      return FALSE;
+        WARN("Drive is BUSY for too long\n");
+        return FALSE;
     }
 
-  /*  Write Drive/Head to select drive  */
-  IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
-  StallExecutionProcessor(500);
+    /* Write Drive/Head to select drive */
+    IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
+    StallExecutionProcessor(500);
 
-  /* Disable interrupts */
-  IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
-  StallExecutionProcessor(500);
+    /* Disable interrupts */
+    IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
+    StallExecutionProcessor(500);
 
-  /*  Issue command to drive  */
-  if (DrvHead & IDE_DH_LBA)
+    /* Issue command to drive */
+    if (DrvHead & IDE_DH_LBA)
     {
-      TRACE("READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n",
-            DrvHead & IDE_DH_DRV1 ? 1 : 0,
-            ((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
-            SectorCnt,
-            Command);
+        TRACE("READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n",
+              DrvHead & IDE_DH_DRV1 ? 1 : 0,
+              ((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
+              SectorCnt,
+              Command);
     }
-  else
+    else
     {
-      TRACE("READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%x\n",
-            DrvHead & IDE_DH_DRV1 ? 1 : 0,
-            CylinderHigh,
-            CylinderLow,
-            DrvHead & 0x0f,
-            SectorNum,
-            SectorCnt,
-            Command);
+        TRACE("READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%x\n",
+              DrvHead & IDE_DH_DRV1 ? 1 : 0,
+              CylinderHigh,
+              CylinderLow,
+              DrvHead & 0x0f,
+              SectorNum,
+              SectorCnt,
+              Command);
     }
 
-  /*  Setup command parameters  */
-  IDEWritePrecomp(CommandPort, PreComp);
-  IDEWriteSectorCount(CommandPort, SectorCnt);
-  IDEWriteSectorNum(CommandPort, SectorNum);
-  IDEWriteCylinderHigh(CommandPort, CylinderHigh);
-  IDEWriteCylinderLow(CommandPort, CylinderLow);
-  IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
+    /* Setup command parameters */
+    IDEWritePrecomp(CommandPort, PreComp);
+    IDEWriteSectorCount(CommandPort, SectorCnt);
+    IDEWriteSectorNum(CommandPort, SectorNum);
+    IDEWriteCylinderHigh(CommandPort, CylinderHigh);
+    IDEWriteCylinderLow(CommandPort, CylinderLow);
+    IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
 
-  /*  Issue the command  */
-  IDEWriteCommand(CommandPort, Command);
-  StallExecutionProcessor(50);
+    /* Issue the command */
+    IDEWriteCommand(CommandPort, Command);
+    StallExecutionProcessor(50);
 
-  /*  wait for DRQ or error  */
-  for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
-    {
-      Status = IDEReadStatus(CommandPort);
-      if (!(Status & IDE_SR_BUSY))
+    /* Wait for DRQ or error */
+    for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
     {
-      if (Status & IDE_SR_ERR)
-        {
-          IDEWriteDriveControl(ControlPort, 0);
-          StallExecutionProcessor(50);
-          IDEReadStatus(CommandPort);
-
-          return FALSE;
-        }
-
-      if (Status & IDE_SR_DRQ)
-        {
-          break;
-        }
-      else
+        Status = IDEReadStatus(CommandPort);
+        if (!(Status & IDE_SR_BUSY))
         {
-          IDEWriteDriveControl(ControlPort, 0);
-          StallExecutionProcessor(50);
-          IDEReadStatus(CommandPort);
+            if (Status & IDE_SR_ERR)
+            {
+                IDEWriteDriveControl(ControlPort, 0);
+                StallExecutionProcessor(50);
+                IDEReadStatus(CommandPort);
+                return FALSE;
+            }
 
-          return FALSE;
+            if (Status & IDE_SR_DRQ)
+            {
+                break;
+            }
+            else
+            {
+                IDEWriteDriveControl(ControlPort, 0);
+                StallExecutionProcessor(50);
+                IDEReadStatus(CommandPort);
+                return FALSE;
+            }
         }
-    }
-      StallExecutionProcessor(10);
+        StallExecutionProcessor(10);
     }
 
-  /*  timed out  */
-  if (RetryCount >= IDE_MAX_POLL_RETRIES)
+    /* Timed out */
+    if (RetryCount >= IDE_MAX_POLL_RETRIES)
     {
-      IDEWriteDriveControl(ControlPort, 0);
-      StallExecutionProcessor(50);
-      IDEReadStatus(CommandPort);
-
-      return FALSE;
+        IDEWriteDriveControl(ControlPort, 0);
+        StallExecutionProcessor(50);
+        IDEReadStatus(CommandPort);
+        return FALSE;
     }
 
-  while (1)
+    while (1)
     {
-      /*  Read data into buffer  */
-      if (Junk == FALSE)
-    {
-      IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
-      Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ);
-    }
-      else
-    {
-      UCHAR JunkBuffer[IDE_SECTOR_BUF_SZ];
-      IDEReadBlock(CommandPort, JunkBuffer, IDE_SECTOR_BUF_SZ);
-    }
-      SectorCount++;
-
-      /*  Check for error or more sectors to read  */
-      for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
-    {
-      Status = IDEReadStatus(CommandPort);
-      if (!(Status & IDE_SR_BUSY))
-        {
-          if (Status & IDE_SR_ERR)
+        /* Read data into buffer */
+        if (Junk == FALSE)
         {
-          IDEWriteDriveControl(ControlPort, 0);
-          StallExecutionProcessor(50);
-          IDEReadStatus(CommandPort);
-
-          return FALSE;
+            IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
+            Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ);
         }
-          if (Status & IDE_SR_DRQ)
+        else
         {
-          if (SectorCount >= SectorCnt)
-            {
-              TRACE("Buffer size exceeded!\n");
-              Junk = TRUE;
-            }
-          break;
+            UCHAR JunkBuffer[IDE_SECTOR_BUF_SZ];
+            IDEReadBlock(CommandPort, JunkBuffer, IDE_SECTOR_BUF_SZ);
         }
-          else
+        SectorCount++;
+
+        /* Check for error or more sectors to read */
+        for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
         {
-          if (SectorCount > SectorCnt)
+            Status = IDEReadStatus(CommandPort);
+            if (!(Status & IDE_SR_BUSY))
             {
-              TRACE("Read %lu sectors of junk!\n",
-                    SectorCount - SectorCnt);
+                if (Status & IDE_SR_ERR)
+                {
+                    IDEWriteDriveControl(ControlPort, 0);
+                    StallExecutionProcessor(50);
+                    IDEReadStatus(CommandPort);
+                    return FALSE;
+                }
+                if (Status & IDE_SR_DRQ)
+                {
+                    if (SectorCount >= SectorCnt)
+                    {
+                        TRACE("Buffer size exceeded!\n");
+                        Junk = TRUE;
+                    }
+                    break;
+                }
+                else
+                {
+                    if (SectorCount > SectorCnt)
+                    {
+                        TRACE("Read %lu sectors of junk!\n",
+                              SectorCount - SectorCnt);
+                    }
+
+                    IDEWriteDriveControl(ControlPort, 0);
+                    StallExecutionProcessor(50);
+                    IDEReadStatus(CommandPort);
+                    return TRUE;
+                }
             }
-          IDEWriteDriveControl(ControlPort, 0);
-          StallExecutionProcessor(50);
-          IDEReadStatus(CommandPort);
-
-          return TRUE;
-        }
         }
     }
-    }
 }
 
 BOOLEAN
 XboxDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
-  ULONG StartSector;
-  UCHAR Count;
+    ULONG StartSector;
+    UCHAR Count;
 
-  if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
+    if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
     {
-      /* Xbox has only 1 IDE controller and no floppy */
-      WARN("Invalid drive number\n");
-      return FALSE;
+        /* Xbox has only 1 IDE controller and no floppy */
+        WARN("Invalid drive number\n");
+        return FALSE;
     }
 
-  if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
+    if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
     {
-      FIXME("48bit LBA required but not implemented\n");
-      return FALSE;
+        FIXME("48bit LBA required but not implemented\n");
+        return FALSE;
     }
 
-  StartSector = (ULONG) SectorNumber;
-  while (0 < SectorCount)
+    StartSector = (ULONG) SectorNumber;
+    while (0 < SectorCount)
     {
-      Count = (SectorCount <= 255 ? (UCHAR)SectorCount : 255);
-      if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
-                               XBOX_IDE_CONTROL_PORT,
-                               0, Count,
-                               StartSector & 0xff,
-                               (StartSector >> 8) & 0xff,
-                               (StartSector >> 16) & 0xff,
-                               ((StartSector >> 24) & 0x0f) | IDE_DH_LBA |
-                               (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
-                               IDE_CMD_READ,
+        Count = (SectorCount <= 255 ? (UCHAR)SectorCount : 255);
+        if (!XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
+                                XBOX_IDE_CONTROL_PORT,
+                                0, Count,
+                                StartSector & 0xff,
+                                (StartSector >> 8) & 0xff,
+                                (StartSector >> 16) & 0xff,
+                                ((StartSector >> 24) & 0x0f) | IDE_DH_LBA |
+                                (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
+                                IDE_CMD_READ,
                                 Buffer))
         {
-          return FALSE;
+            return FALSE;
         }
-      SectorCount -= Count;
-      Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
+        SectorCount -= Count;
+        Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
     }
 
-  return TRUE;
+    return TRUE;
 }
 
 BOOLEAN
 XboxDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
 {
-  UCHAR SectorData[IDE_SECTOR_BUF_SZ];
-
-  /* This is the Xbox, chances are that there is a Xbox-standard partitionless
-   * disk in it so let's check that first */
-
-  if (1 <= PartitionNumber && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) &&
-      MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, SectorData))
+    UCHAR SectorData[IDE_SECTOR_BUF_SZ];
+
+    /*
+     * This is the Xbox, chances are that there is a Xbox-standard
+     * partitionless disk in it so let's check that first.
+     */
+    if (1 <= PartitionNumber && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) &&
+        MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, SectorData))
     {
-      if (*((PULONG) SectorData) == XBOX_SIGNATURE)
+        if (*((PULONG) SectorData) == XBOX_SIGNATURE)
         {
-          memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
-          PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
-          PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
-          PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
-          return TRUE;
+            memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
+            PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
+            PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
+            PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
+            return TRUE;
         }
     }
 
-  /* No magic Xbox partitions. Maybe there's a MBR */
-  return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
+    /* No magic Xbox partitions. Maybe there's a MBR */
+    return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
 }
 
 BOOLEAN
 XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
 {
-  IDE_DRIVE_IDENTIFY DrvParms;
-  ULONG i;
-  BOOLEAN Atapi;
-
-  Atapi = FALSE; /* FIXME */
-  /*  Get the Drive Identify block from drive or die  */
-  if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
-                           XBOX_IDE_CONTROL_PORT,
-                           0,
-                           1,
-                           0,
-                           0,
-                           0,
-                           (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
-                           (Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
-                           (PUCHAR) &DrvParms))
+    IDE_DRIVE_IDENTIFY DrvParms;
+    ULONG i;
+    BOOLEAN Atapi;
+
+    Atapi = FALSE; /* FIXME */
+    /* Get the Drive Identify block from drive or die */
+    if (!XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
+                            XBOX_IDE_CONTROL_PORT,
+                            0,
+                            1,
+                            0,
+                            0,
+                            0,
+                            (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
+                            (Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
+                            (PUCHAR) &DrvParms))
     {
-      ERR("XboxDiskPolledRead() failed\n");
-      return FALSE;
+        ERR("XboxDiskPolledRead() failed\n");
+        return FALSE;
     }
 
-  Geometry->Cylinders = DrvParms.LogicalCyls;
-  Geometry->Heads = DrvParms.LogicalHeads;
-  Geometry->Sectors = DrvParms.SectorsPerTrack;
+    Geometry->Cylinders = DrvParms.LogicalCyls;
+    Geometry->Heads = DrvParms.LogicalHeads;
+    Geometry->Sectors = DrvParms.SectorsPerTrack;
 
-  if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED))
+    if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED))
     {
-      /* LBA ATA drives always have a sector size of 512 */
-      Geometry->BytesPerSector = 512;
+        /* LBA ATA drives always have a sector size of 512 */
+        Geometry->BytesPerSector = 512;
     }
-  else
+    else
     {
-      TRACE("BytesPerSector %d\n", DrvParms.BytesPerSector);
-      if (DrvParms.BytesPerSector == 0)
+        TRACE("BytesPerSector %d\n", DrvParms.BytesPerSector);
+        if (DrvParms.BytesPerSector == 0)
         {
-          Geometry->BytesPerSector = 512;
+            Geometry->BytesPerSector = 512;
         }
-      else
+        else
         {
-          for (i = 1 << 15; i; i /= 2)
+            for (i = 1 << 15; i; i /= 2)
             {
-              if (0 != (DrvParms.BytesPerSector & i))
+                if ((DrvParms.BytesPerSector & i) != 0)
                 {
-                  Geometry->BytesPerSector = i;
-                  break;
+                    Geometry->BytesPerSector = i;
+                    break;
                 }
             }
         }
     }
-  TRACE("Cylinders %d\n", Geometry->Cylinders);
-  TRACE("Heads %d\n", Geometry->Heads);
-  TRACE("Sectors %d\n", Geometry->Sectors);
-  TRACE("BytesPerSector %d\n", Geometry->BytesPerSector);
+    TRACE("Cylinders %d\n", Geometry->Cylinders);
+    TRACE("Heads %d\n", Geometry->Heads);
+    TRACE("Sectors %d\n", Geometry->Sectors);
+    TRACE("BytesPerSector %d\n", Geometry->BytesPerSector);
 
-  return TRUE;
+    return TRUE;
 }
 
 ULONG
 XboxDiskGetCacheableBlockCount(UCHAR DriveNumber)
 {
-  /* 64 seems a nice number, it is used by the machpc code for LBA devices */
-  return 64;
+    /* 64 seems a nice number, it is used by the machpc code for LBA devices */
+    return 64;
 }
 
 /* EOF */
diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c
deleted file mode 100644 (file)
index d5a6881..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- *  FreeLoader
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <freeldr.h>
-
-#define NDEBUG
-#include <debug.h>
-
-DBG_DEFAULT_CHANNEL(HWDETECT);
-
-static CHAR Hex[] = "0123456789ABCDEF";
-//static unsigned int delay_count = 1;
-
-extern ULONG reactos_disk_count;
-extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
-
-static
-PCM_PARTIAL_RESOURCE_LIST
-GetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
-    //EXTENDED_GEOMETRY ExtGeometry;
-    GEOMETRY Geometry;
-    ULONG Size;
-
-    //
-    // Initialize returned size
-    //
-    *pSize = 0;
-
-    /* Set 'Configuration Data' value */
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
-           sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
-    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-    if (PartialResourceList == NULL)
-    {
-        ERR("Failed to allocate a full resource descriptor\n");
-        return NULL;
-    }
-
-    memset(PartialResourceList, 0, Size);
-    PartialResourceList->Version = 1;
-    PartialResourceList->Revision = 1;
-    PartialResourceList->Count = 1;
-    PartialResourceList->PartialDescriptors[0].Type =
-        CmResourceTypeDeviceSpecific;
-//  PartialResourceList->PartialDescriptors[0].ShareDisposition =
-//  PartialResourceList->PartialDescriptors[0].Flags =
-    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
-        sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
-
-    /* Get pointer to geometry data */
-    DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
-
-    /* Get the disk geometry */
-    //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
-
-    if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
-    {
-        DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
-        DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
-        DiskGeometry->SectorsPerTrack = Geometry.Sectors;
-        DiskGeometry->NumberOfHeads = Geometry.Heads;
-    }
-    else
-    {
-        ERR("Reading disk geometry failed\n");
-        FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
-        return NULL;
-    }
-    TRACE("Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
-          DriveNumber,
-          DiskGeometry->NumberOfCylinders,
-          DiskGeometry->NumberOfHeads,
-          DiskGeometry->SectorsPerTrack,
-          DiskGeometry->BytesPerSector);
-
-    //
-    // Return configuration data
-    //
-    *pSize = Size;
-    return PartialResourceList;
-}
-
-typedef struct tagDISKCONTEXT
-{
-    UCHAR DriveNumber;
-    ULONG SectorSize;
-    ULONGLONG SectorOffset;
-    ULONGLONG SectorCount;
-    ULONGLONG SectorNumber;
-} DISKCONTEXT;
-
-static
-ARC_STATUS
-DiskClose(ULONG FileId)
-{
-    DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
-    FrLdrTempFree(Context, TAG_HW_DISK_CONTEXT);
-    return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
-{
-    DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
-    RtlZeroMemory(Information, sizeof(FILEINFORMATION));
-    Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
-    Information->CurrentAddress.QuadPart = (Context->SectorOffset + Context->SectorNumber) * Context->SectorSize;
-
-    return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
-{
-    DISKCONTEXT* Context;
-    ULONG DrivePartition, SectorSize;
-    UCHAR DriveNumber;
-    ULONGLONG SectorOffset = 0;
-    ULONGLONG SectorCount = 0;
-    PARTITION_TABLE_ENTRY PartitionTableEntry;
-    CHAR FileName[1];
-
-    if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
-        return EINVAL;
-
-    if (DrivePartition == 0xff)
-    {
-        /* This is a CD-ROM device */
-        SectorSize = 2048;
-    }
-    else
-    {
-        /* This is either a floppy disk device (DrivePartition == 0) or
-         * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
-         * it doesn't matter which one because they both have 512 bytes per sector */
-        SectorSize = 512;
-    }
-
-    if (DrivePartition != 0xff && DrivePartition != 0)
-    {
-        if (!XboxDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
-            return EINVAL;
-        SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
-        SectorCount = PartitionTableEntry.PartitionSectorCount;
-    }
-    else
-    {
-        SectorCount = 0; /* FIXME */
-    }
-
-    Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
-    if (!Context)
-        return ENOMEM;
-    Context->DriveNumber = DriveNumber;
-    Context->SectorSize = SectorSize;
-    Context->SectorOffset = SectorOffset;
-    Context->SectorCount = SectorCount;
-    Context->SectorNumber = 0;
-    FsSetDeviceSpecific(*FileId, Context);
-
-    return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
-{
-    DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-    UCHAR* Ptr = (UCHAR*)Buffer;
-    ULONG i, Length, Sectors;
-    BOOLEAN ret;
-
-    *Count = 0;
-    i = 0;
-    while (N > 0)
-    {
-        Length = N;
-        if (Length > DiskReadBufferSize)
-            Length = DiskReadBufferSize;
-        Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
-        ret = MachDiskReadLogicalSectors(
-                  Context->DriveNumber,
-                  Context->SectorNumber + Context->SectorOffset + i,
-                  Sectors,
-                  DiskReadBuffer);
-        if (!ret)
-            return EIO;
-        RtlCopyMemory(Ptr, DiskReadBuffer, Length);
-        Ptr += Length;
-        *Count += Length;
-        N -= Length;
-        i += Sectors;
-    }
-
-    return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
-{
-    DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
-    if (SeekMode != SeekAbsolute)
-        return EINVAL;
-    if (Position->LowPart & (Context->SectorSize - 1))
-        return EINVAL;
-
-    /* FIXME: take HighPart into account */
-    Context->SectorNumber = Position->LowPart / Context->SectorSize;
-    return ESUCCESS;
-}
-
-static const DEVVTBL DiskVtbl =
-{
-    DiskClose,
-    DiskGetFileInformation,
-    DiskOpen,
-    DiskRead,
-    DiskSeek,
-};
-
-static
-VOID
-GetHarddiskIdentifier(PCHAR Identifier,
-                      UCHAR DriveNumber)
-{
-    PMASTER_BOOT_RECORD Mbr;
-    PULONG Buffer;
-    ULONG i;
-    ULONG Checksum;
-    ULONG Signature;
-    CHAR ArcName[MAX_PATH];
-    PARTITION_TABLE_ENTRY PartitionTableEntry;
-
-    /* Read the MBR */
-    if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
-    {
-        ERR("Reading MBR failed\n");
-        return;
-    }
-
-    Buffer = (ULONG*)DiskReadBuffer;
-    Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
-
-    Signature = Mbr->Signature;
-    TRACE("Signature: %x\n", Signature);
-
-    /* Calculate the MBR checksum */
-    Checksum = 0;
-    for (i = 0; i < 512 / sizeof(ULONG); i++)
-    {
-        Checksum += Buffer[i];
-    }
-    Checksum = ~Checksum + 1;
-    TRACE("Checksum: %x\n", Checksum);
-
-    /* Fill out the ARC disk block */
-    reactos_arc_disk_info[reactos_disk_count].DiskSignature.Signature = Signature;
-    reactos_arc_disk_info[reactos_disk_count].DiskSignature.CheckSum = Checksum;
-    sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count);
-    strcpy(reactos_arc_disk_info[reactos_disk_count].ArcName, ArcName);
-    reactos_arc_disk_info[reactos_disk_count].DiskSignature.ArcName =
-        reactos_arc_disk_info[reactos_disk_count].ArcName;
-    reactos_disk_count++;
-
-    sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80);
-    FsRegisterDevice(ArcName, &DiskVtbl);
-
-    /* Add partitions */
-    i = 1;
-    DiskReportError(FALSE);
-    while (XboxDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
-    {
-        if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
-        {
-            sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - 0x80, i);
-            FsRegisterDevice(ArcName, &DiskVtbl);
-        }
-        i++;
-    }
-    DiskReportError(TRUE);
-
-    /* Convert checksum and signature to identifier string */
-    Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
-    Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
-    Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
-    Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
-    Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
-    Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
-    Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
-    Identifier[7] = Hex[Checksum & 0x0F];
-    Identifier[8] = '-';
-    Identifier[9] = Hex[(Signature >> 28) & 0x0F];
-    Identifier[10] = Hex[(Signature >> 24) & 0x0F];
-    Identifier[11] = Hex[(Signature >> 20) & 0x0F];
-    Identifier[12] = Hex[(Signature >> 16) & 0x0F];
-    Identifier[13] = Hex[(Signature >> 12) & 0x0F];
-    Identifier[14] = Hex[(Signature >> 8) & 0x0F];
-    Identifier[15] = Hex[(Signature >> 4) & 0x0F];
-    Identifier[16] = Hex[Signature & 0x0F];
-    Identifier[17] = '-';
-    Identifier[18] = 'A';
-    Identifier[19] = 0;
-    TRACE("Identifier: %s\n", Identifier);
-}
-
-static
-VOID
-DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
-                PCONFIGURATION_COMPONENT_DATA BusKey)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_INT13_DRIVE_PARAMETER Int13Drives;
-    GEOMETRY Geometry;
-    PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
-    UCHAR DiskCount;
-    ULONG i;
-    ULONG Size;
-    BOOLEAN Changed;
-
-    /* Count the number of visible drives */
-    DiskReportError(FALSE);
-    DiskCount = 0;
-
-    /* There are some really broken BIOSes out there. There are even BIOSes
-        * that happily report success when you ask them to read from non-existent
-        * harddisks. So, we set the buffer to known contents first, then try to
-        * read. If the BIOS reports success but the buffer contents haven't
-        * changed then we fail anyway */
-    memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
-    while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
-    {
-        Changed = FALSE;
-        for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
-        {
-            Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
-        }
-        if (! Changed)
-        {
-            TRACE("BIOS reports success for disk %d but data didn't change\n",
-                  (int)DiskCount);
-            break;
-        }
-        DiskCount++;
-        memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
-    }
-    DiskReportError(TRUE);
-    TRACE("BIOS reports %d harddisk%s\n",
-          (int)DiskCount, (DiskCount == 1) ? "" : "s");
-
-    //DetectBiosFloppyController(BusKey);
-
-    /* Allocate resource descriptor */
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
-           sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
-    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-    if (PartialResourceList == NULL)
-    {
-        ERR("Failed to allocate resource descriptor\n");
-        return;
-    }
-
-    /* Initialize resource descriptor */
-    memset(PartialResourceList, 0, Size);
-    PartialResourceList->Version = 1;
-    PartialResourceList->Revision = 1;
-    PartialResourceList->Count = 1;
-    PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific;
-    PartialResourceList->PartialDescriptors[0].ShareDisposition = 0;
-    PartialResourceList->PartialDescriptors[0].Flags = 0;
-    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
-        sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
-
-    /* Get harddisk Int13 geometry data */
-    Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
-    for (i = 0; i < DiskCount; i++)
-    {
-        if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
-        {
-            Int13Drives[i].DriveSelect = 0x80 + i;
-            Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
-            Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
-            Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
-            Int13Drives[i].NumberDrives = DiskCount;
-
-            TRACE(
-                "Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
-                0x80 + i,
-                Geometry.Cylinders - 1,
-                Geometry.Heads - 1,
-                Geometry.Sectors,
-                Geometry.BytesPerSector);
-        }
-    }
-
-    FldrCreateComponentKey(BusKey,
-                           ControllerClass,
-                           DiskController,
-                           Output | Input,
-                           0,
-                           0xFFFFFFFF,
-                           NULL,
-                           PartialResourceList,
-                           Size,
-                           &ControllerKey);
-    TRACE("Created key: DiskController\\0\n");
-
-    /* Create and fill subkey for each harddisk */
-    for (i = 0; i < DiskCount; i++)
-    {
-        CHAR Identifier[20];
-
-        /* Get disk values */
-        PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size);
-        GetHarddiskIdentifier(Identifier, 0x80 + i);
-
-        /* Create disk key */
-        FldrCreateComponentKey(ControllerKey,
-                               PeripheralClass,
-                               DiskPeripheral,
-                               Output | Input,
-                               0,
-                               0xFFFFFFFF,
-                               Identifier,
-                               PartialResourceList,
-                               Size,
-                               &DiskKey);
-    }
-}
-
-static
-VOID
-DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
-{
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCONFIGURATION_COMPONENT_DATA BusKey;
-    ULONG Size;
-
-    /* Set 'Configuration Data' value */
-    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
-           sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
-    if (PartialResourceList == NULL)
-    {
-        TRACE(
-            "Failed to allocate resource descriptor\n");
-        return;
-    }
-
-    /* Initialize resource descriptor */
-    memset(PartialResourceList, 0, Size);
-    PartialResourceList->Version = 1;
-    PartialResourceList->Revision = 1;
-    PartialResourceList->Count = 0;
-
-    /* Create new bus key */
-    FldrCreateComponentKey(SystemKey,
-                           AdapterClass,
-                           MultiFunctionAdapter,
-                           0x0,
-                           0x0,
-                           0xFFFFFFFF,
-                           "ISA",
-                           PartialResourceList,
-                           Size,
-                           &BusKey);
-
-    /* Increment bus number */
-    (*BusNumber)++;
-
-    /* Detect ISA/BIOS devices */
-    DetectBiosDisks(SystemKey, BusKey);
-
-
-    /* FIXME: Detect more ISA devices */
-}
-
-PCONFIGURATION_COMPONENT_DATA
-XboxHwDetect(VOID)
-{
-    PCONFIGURATION_COMPONENT_DATA SystemKey;
-    ULONG BusNumber = 0;
-
-    TRACE("DetectHardware()\n");
-
-    /* Create the 'System' key */
-    FldrCreateSystemKey(&SystemKey);
-
-    /* TODO: Build actual xbox's hardware configuration tree */
-    DetectIsaBios(SystemKey, &BusNumber);
-
-    TRACE("DetectHardware() Done\n");
-    return SystemKey;
-}
-
-BOOLEAN
-XboxInitializeBootDevices(VOID)
-{
-    // Emulate old behavior
-    return XboxHwDetect() != NULL;
-}
-
-VOID XboxHwIdle(VOID)
-{
-    /* UNIMPLEMENTED */
-}
-
-/* EOF */
index 4cdf12f..68218cf 100644 (file)
 
 #ifndef _M_ARM
 #include <freeldr.h>
+
+#define NDEBUG
 #include <debug.h>
 
 DBG_DEFAULT_CHANNEL(DISK);
 
 static BOOLEAN bReportError = TRUE;
 
-/////////////////////////////////////////////////////////////////////////////////////////////
-// FUNCTIONS
-/////////////////////////////////////////////////////////////////////////////////////////////
+/* FUNCTIONS *****************************************************************/
 
-VOID DiskReportError (BOOLEAN bError)
+VOID DiskReportError(BOOLEAN bError)
 {
     bReportError = bError;
 }
 
 VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
 {
-    CHAR    ErrorCodeString[200];
+    CHAR ErrorCodeString[200];
 
     if (bReportError == FALSE)
         return;
 
-    sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s", ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode));
+    sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s",
+            ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode));
 
     TRACE("%s\n", ErrorCodeString);
 
@@ -83,21 +84,17 @@ PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
     }
 }
 
-// This function is in arch/i386/i386disk.c
-//BOOLEAN DiskReadLogicalSectors(ULONG DriveNumber, U64 SectorNumber, ULONG SectorCount, PVOID Buffer)
-
 BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber)
 {
-    // Hard disks use drive numbers >= 0x80
-    // So if the drive number indicates a hard disk
-    // then return FALSE
-    // 0x49 is our magic ramdisk drive, so return FALSE for that too
+    /*
+     * Hard disks use drive numbers >= 0x80 . So if the drive number
+     * indicates a hard disk then return FALSE.
+     * 0x49 is our magic ramdisk drive, so return FALSE for that too.
+     */
     if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
-    {
         return FALSE;
-    }
 
-    // Drive is a floppy diskette so return TRUE
+    /* The drive is a floppy diskette so return TRUE */
     return TRUE;
 }
 
@@ -191,10 +188,4 @@ DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size)
     return TRUE;
 }
 
-// This function is in arch/i386/i386disk.c
-//VOID DiskStopFloppyMotor(VOID)
-
-// This function is in arch/i386/i386disk.c
-//ULONG DiskGetCacheableBlockCount(UCHAR DriveNumber)
-
 #endif
index 0ce2dbd..1df325b 100644 (file)
@@ -49,6 +49,9 @@ VOID PcPrepareForReactOS(IN BOOLEAN Setup);
 
 PFREELDR_MEMORY_DESCRIPTOR PcMemGetMemoryMap(ULONG *MemoryMapSize);
 
+BOOLEAN DiskResetController(UCHAR DriveNumber);
+BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);
+
 BOOLEAN PcDiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size);
 BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
 BOOLEAN PcDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
index 330fc21..7431755 100644 (file)
 
 typedef struct _GEOMETRY
 {
-    ULONG        Cylinders;                        // Number of cylinders on the disk
-    ULONG        Heads;                            // Number of heads on the disk
-    ULONG        Sectors;                        // Number of sectors per track
-    ULONG        BytesPerSector;                    // Number of bytes per sector
+    ULONG   Cylinders;      // Number of cylinders on the disk
+    ULONG   Heads;          // Number of heads on the disk
+    ULONG   Sectors;        // Number of sectors per track
+    ULONG   BytesPerSector; // Number of bytes per sector
 
 } GEOMETRY, *PGEOMETRY;
 
@@ -36,14 +36,15 @@ typedef struct _GEOMETRY
 #include <pshpack1.h>
 typedef struct _EXTENDED_GEOMETRY
 {
-    USHORT        Size;
-    USHORT        Flags;
-    ULONG        Cylinders;
-    ULONG        Heads;
-    ULONG        SectorsPerTrack;
-    ULONGLONG        Sectors;
-    USHORT        BytesPerSector;
-    ULONG        PDPTE;
+    USHORT      Size;
+    USHORT      Flags;
+    ULONG       Cylinders;
+    ULONG       Heads;
+    ULONG       SectorsPerTrack;
+    ULONGLONG   Sectors;
+    USHORT      BytesPerSector;
+    ULONG       PDPTE;
+
 } EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY;
 
 //
@@ -51,16 +52,17 @@ typedef struct _EXTENDED_GEOMETRY
 //
 typedef struct _PARTITION_TABLE_ENTRY
 {
-    UCHAR        BootIndicator;                    // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
-    UCHAR        StartHead;                        // Beginning head number
-    UCHAR        StartSector;                    // Beginning sector (2 high bits of cylinder #)
-    UCHAR        StartCylinder;                    // Beginning cylinder# (low order bits of cylinder #)
-    UCHAR        SystemIndicator;                // System indicator
-    UCHAR        EndHead;                        // Ending head number
-    UCHAR        EndSector;                        // Ending sector (2 high bits of cylinder #)
-    UCHAR        EndCylinder;                    // Ending cylinder# (low order bits of cylinder #)
-    ULONG        SectorCountBeforePartition;        // Number of sectors preceding the partition
-    ULONG        PartitionSectorCount;            // Number of sectors in the partition
+    UCHAR   BootIndicator;              // 0x00 - non-bootable partition,
+                                        // 0x80 - bootable partition (one partition only)
+    UCHAR   StartHead;                  // Beginning head number
+    UCHAR   StartSector;                // Beginning sector (2 high bits of cylinder #)
+    UCHAR   StartCylinder;              // Beginning cylinder# (low order bits of cylinder #)
+    UCHAR   SystemIndicator;            // System indicator
+    UCHAR   EndHead;                    // Ending head number
+    UCHAR   EndSector;                  // Ending sector (2 high bits of cylinder #)
+    UCHAR   EndCylinder;                // Ending cylinder# (low order bits of cylinder #)
+    ULONG   SectorCountBeforePartition; // Number of sectors preceding the partition
+    ULONG   PartitionSectorCount;       // Number of sectors in the partition
 
 } PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
 
@@ -69,11 +71,11 @@ typedef struct _PARTITION_TABLE_ENTRY
 //
 typedef struct _MASTER_BOOT_RECORD
 {
-    UCHAR            MasterBootRecordCodeAndData[0x1b8];    /* 0x000 */
-    ULONG            Signature;                /* 0x1B8 */
-    USHORT            Reserved;                /* 0x1BC */
-    PARTITION_TABLE_ENTRY    PartitionTable[4];            /* 0x1BE */
-    USHORT            MasterBootRecordMagic;            /* 0x1FE */
+    UCHAR   MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */
+    ULONG   Signature;                          /* 0x1B8 */
+    USHORT  Reserved;                           /* 0x1BC */
+    PARTITION_TABLE_ENTRY   PartitionTable[4];  /* 0x1BE */
+    USHORT  MasterBootRecordMagic;              /* 0x1FE */
 
 } MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
 #include <poppack.h>
@@ -107,16 +109,11 @@ typedef struct _MASTER_BOOT_RECORD
 
 ///////////////////////////////////////////////////////////////////////////////////////
 //
-// i386 BIOS Disk Functions (i386disk.c)
+// PC x86/64 BIOS Disk Functions (pcdisk.c)
 //
 ///////////////////////////////////////////////////////////////////////////////////////
 #if defined(__i386__) || defined(_M_AMD64)
-
-BOOLEAN    DiskResetController(UCHAR DriveNumber);
-BOOLEAN    DiskInt13ExtensionsSupported(UCHAR DriveNumber);
-//VOID    DiskStopFloppyMotor(VOID);
-BOOLEAN    DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);
-
+VOID DiskStopFloppyMotor(VOID);
 #endif // defined __i386__ || defined(_M_AMD64)
 
 ///////////////////////////////////////////////////////////////////////////////////////
@@ -124,12 +121,10 @@ BOOLEAN    DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHOR
 // FreeLoader Disk Functions
 //
 ///////////////////////////////////////////////////////////////////////////////////////
-VOID    DiskReportError (BOOLEAN bError);
-VOID    DiskError(PCSTR ErrorString, ULONG ErrorCode);
-PCSTR    DiskGetErrorCodeString(ULONG ErrorCode);
-BOOLEAN    DiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); // Implemented in i386disk.c
-BOOLEAN    DiskIsDriveRemovable(UCHAR DriveNumber);
-VOID    DiskStopFloppyMotor(VOID);    // Implemented in i386disk.c
+VOID DiskReportError (BOOLEAN bError);
+VOID DiskError(PCSTR ErrorString, ULONG ErrorCode);
+PCSTR DiskGetErrorCodeString(ULONG ErrorCode);
+BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
 extern UCHAR FrldrBootDrive;
 extern ULONG FrldrBootPartition;
 extern PVOID DiskReadBuffer;
@@ -143,10 +138,13 @@ BOOLEAN DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size);
 // Fixed Disk Partition Management Functions
 //
 ///////////////////////////////////////////////////////////////////////////////////////
-BOOLEAN    DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition);
-BOOLEAN    DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
-BOOLEAN    DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
-BOOLEAN    DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
-BOOLEAN    DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
+BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition);
+BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
 
+/*
+ * SCSI support (disk/scsiport.c)
+ */
 ULONG LoadBootDeviceDriver(VOID);