4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <cportlib/cportlib.h>
23 DBG_DEFAULT_CHANNEL(HWDETECT
);
26 /* Maximum number of COM and LPT ports */
27 #define MAX_COM_PORTS 4
28 #define MAX_LPT_PORTS 3
31 #define MOUSE_TYPE_NONE 0
32 /* Microsoft Mouse with 2 buttons */
33 #define MOUSE_TYPE_MICROSOFT 1
34 /* Logitech Mouse with 3 buttons */
35 #define MOUSE_TYPE_LOGITECH 2
36 /* Microsoft Wheel Mouse (aka Z Mouse) */
37 #define MOUSE_TYPE_WHEELZ 3
38 /* Mouse Systems Mouse */
39 #define MOUSE_TYPE_MOUSESYSTEMS 4
44 /* Controller registers. */
45 #define CONTROLLER_REGISTER_STATUS 0x64
46 #define CONTROLLER_REGISTER_CONTROL 0x64
47 #define CONTROLLER_REGISTER_DATA 0x60
49 /* Controller commands. */
50 #define CONTROLLER_COMMAND_READ_MODE 0x20
51 #define CONTROLLER_COMMAND_WRITE_MODE 0x60
52 #define CONTROLLER_COMMAND_GET_VERSION 0xA1
53 #define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
54 #define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
55 #define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
56 #define CONTROLLER_COMMAND_SELF_TEST 0xAA
57 #define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
58 #define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
59 #define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
60 #define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
61 #define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
63 /* Controller status */
64 #define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
65 #define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
66 #define CONTROLLER_STATUS_SELF_TEST 0x04
67 #define CONTROLLER_STATUS_COMMAND 0x08
68 #define CONTROLLER_STATUS_UNLOCKED 0x10
69 #define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
70 #define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
71 #define CONTROLLER_STATUS_PARITY_ERROR 0x80
72 #define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
73 CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
75 /* Timeout in ms for sending to keyboard controller. */
76 #define CONTROLLER_TIMEOUT 250
80 PcGetExtendedBIOSData(PULONG ExtendedBIOSDataArea
, PULONG ExtendedBIOSDataSize
)
84 /* Get address and size of the extended BIOS data area */
85 BiosRegs
.d
.eax
= 0xC100;
86 Int386(0x15, &BiosRegs
, &BiosRegs
);
87 if (INT386_SUCCESS(BiosRegs
))
89 *ExtendedBIOSDataArea
= BiosRegs
.w
.es
<< 4;
90 *ExtendedBIOSDataSize
= 1024;
94 WARN("Int 15h AH=C1h call failed\n");
95 *ExtendedBIOSDataArea
= 0;
96 *ExtendedBIOSDataSize
= 0;
100 // NOTE: Similar to machxbox.c!XboxGetHarddiskConfigurationData(),
101 // but with extended geometry support.
103 PCM_PARTIAL_RESOURCE_LIST
104 PcGetHarddiskConfigurationData(UCHAR DriveNumber
, ULONG
* pSize
)
106 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
107 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
108 // EXTENDED_GEOMETRY ExtGeometry;
113 // Initialize returned size
117 /* Set 'Configuration Data' value */
118 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
119 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
120 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
121 if (PartialResourceList
== NULL
)
123 ERR("Failed to allocate resource descriptor\n");
127 memset(PartialResourceList
, 0, Size
);
128 PartialResourceList
->Version
= 1;
129 PartialResourceList
->Revision
= 1;
130 PartialResourceList
->Count
= 1;
131 PartialResourceList
->PartialDescriptors
[0].Type
=
132 CmResourceTypeDeviceSpecific
;
133 // PartialResourceList->PartialDescriptors[0].ShareDisposition =
134 // PartialResourceList->PartialDescriptors[0].Flags =
135 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
136 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
138 /* Get pointer to geometry data */
139 DiskGeometry
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
141 /* Get the disk geometry */
142 #if 0 // This is somehow replaced by what PcDiskGetDriveGeometry() does internally.
143 ExtGeometry
.Size
= sizeof(EXTENDED_GEOMETRY
);
144 if (DiskGetExtendedDriveParameters(DriveNumber
, &ExtGeometry
, ExtGeometry
.Size
))
146 DiskGeometry
->BytesPerSector
= ExtGeometry
.BytesPerSector
;
147 DiskGeometry
->NumberOfCylinders
= ExtGeometry
.Cylinders
;
148 DiskGeometry
->SectorsPerTrack
= ExtGeometry
.SectorsPerTrack
;
149 DiskGeometry
->NumberOfHeads
= ExtGeometry
.Heads
;
153 if (PcDiskGetDriveGeometry(DriveNumber
, &Geometry
))
155 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
156 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
157 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
158 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
162 TRACE("Reading disk geometry failed\n");
163 FrLdrHeapFree(PartialResourceList
, TAG_HW_RESOURCE_LIST
);
166 TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
168 DiskGeometry
->NumberOfCylinders
,
169 DiskGeometry
->NumberOfHeads
,
170 DiskGeometry
->SectorsPerTrack
,
171 DiskGeometry
->BytesPerSector
);
174 // Return configuration data
177 return PartialResourceList
;
182 DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
184 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
185 PCM_PNP_BIOS_DEVICE_NODE DeviceNode
;
186 PCM_PNP_BIOS_INSTALLATION_CHECK InstData
;
187 PCONFIGURATION_COMPONENT_DATA BusKey
;
192 ULONG FoundNodeCount
;
195 ULONG PnpBufferSizeLimit
;
199 InstData
= (PCM_PNP_BIOS_INSTALLATION_CHECK
)PnpBiosSupported();
200 if (InstData
== NULL
|| strncmp((CHAR
*)InstData
->Signature
, "$PnP", 4))
202 TRACE("PnP-BIOS not supported\n");
206 TRACE("PnP-BIOS supported\n");
207 TRACE("Signature '%c%c%c%c'\n",
208 InstData
->Signature
[0], InstData
->Signature
[1],
209 InstData
->Signature
[2], InstData
->Signature
[3]);
211 x
= PnpBiosGetDeviceNodeCount(&NodeSize
, &NodeCount
);
214 TRACE("PnP-BIOS function 'Get Number of System Device Nodes' not supported\n");
218 NodeCount
&= 0xFF; // needed since some fscked up BIOSes return
219 // wrong info (e.g. Mac Virtual PC)
220 // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c
221 if (x
!= 0 || NodeSize
== 0 || NodeCount
== 0)
223 ERR("PnP-BIOS failed to enumerate device nodes\n");
226 TRACE("MaxNodeSize %u NodeCount %u\n", NodeSize
, NodeCount
);
227 TRACE("Estimated buffer size %u\n", NodeSize
* NodeCount
);
229 /* Set 'Configuration Data' value */
230 PnpBufferSizeLimit
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
)
231 + (NodeSize
* NodeCount
);
232 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) + PnpBufferSizeLimit
;
233 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
234 if (PartialResourceList
== NULL
)
236 ERR("Failed to allocate resource descriptor\n");
239 memset(PartialResourceList
, 0, Size
);
241 /* Initialize resource descriptor */
242 PartialResourceList
->Version
= 1;
243 PartialResourceList
->Revision
= 1;
244 PartialResourceList
->Count
= 1;
245 PartialResourceList
->PartialDescriptors
[0].Type
=
246 CmResourceTypeDeviceSpecific
;
247 PartialResourceList
->PartialDescriptors
[0].ShareDisposition
=
248 CmResourceShareUndetermined
;
250 /* The buffer starts after PartialResourceList->PartialDescriptors[0] */
251 Ptr
= (char *)(PartialResourceList
+ 1);
253 /* Set installation check data */
254 memcpy (Ptr
, InstData
, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
));
255 Ptr
+= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
256 PnpBufferSize
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
258 /* Copy device nodes */
260 for (i
= 0; i
< 0xFF; i
++)
262 NodeNumber
= (UCHAR
)i
;
264 x
= PnpBiosGetDeviceNode(&NodeNumber
, DiskReadBuffer
);
267 DeviceNode
= (PCM_PNP_BIOS_DEVICE_NODE
)DiskReadBuffer
;
269 TRACE("Node: %u Size %u (0x%x)\n",
274 if (PnpBufferSize
+ DeviceNode
->Size
> PnpBufferSizeLimit
)
276 ERR("Buffer too small! Ignoring remaining device nodes. (i = %d)\n", i
);
280 memcpy(Ptr
, DeviceNode
, DeviceNode
->Size
);
282 Ptr
+= DeviceNode
->Size
;
283 PnpBufferSize
+= DeviceNode
->Size
;
286 if (FoundNodeCount
>= NodeCount
)
291 /* Set real data size */
292 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
294 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) + PnpBufferSize
;
296 TRACE("Real buffer size: %u\n", PnpBufferSize
);
297 TRACE("Resource size: %u\n", Size
);
299 /* Create component key */
300 FldrCreateComponentKey(SystemKey
,
302 MultiFunctionAdapter
,
316 InitializeSerialPort(PUCHAR Port
,
319 WRITE_PORT_UCHAR(Port
+ 3, 0x80); /* set DLAB on */
320 WRITE_PORT_UCHAR(Port
, 0x60); /* speed LO byte */
321 WRITE_PORT_UCHAR(Port
+ 1, 0); /* speed HI byte */
322 WRITE_PORT_UCHAR(Port
+ 3, LineControl
);
323 WRITE_PORT_UCHAR(Port
+ 1, 0); /* set comm and DLAB to 0 */
324 WRITE_PORT_UCHAR(Port
+ 4, 0x09); /* DR int enable */
325 READ_PORT_UCHAR(Port
+ 5); /* clear error bits */
330 DetectSerialMouse(PUCHAR Port
)
337 /* Shutdown mouse or something like that */
338 LineControl
= READ_PORT_UCHAR(Port
+ 4);
339 WRITE_PORT_UCHAR(Port
+ 4, (LineControl
& ~0x02) | 0x01);
340 StallExecutionProcessor(100000);
344 * Maybe there is no serial port although BIOS reported one (this
345 * is the case on Apple hardware), or the serial port is misbehaving,
346 * therefore we must give up after some time.
349 while (READ_PORT_UCHAR(Port
+ 5) & 0x01)
352 return MOUSE_TYPE_NONE
;
353 READ_PORT_UCHAR(Port
);
357 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
358 * 'Output Line 2' message. This enables mouse to identify.
360 WRITE_PORT_UCHAR(Port
+ 4, 0x0b);
362 /* Wait 10 milliseconds for the mouse getting ready */
363 StallExecutionProcessor(10000);
365 /* Read first four bytes, which contains Microsoft Mouse signs */
367 for (i
= 0; i
< 4; i
++)
369 while ((READ_PORT_UCHAR(Port
+ 5) & 1) == 0)
371 StallExecutionProcessor(100);
374 return MOUSE_TYPE_NONE
;
376 Buffer
[i
] = READ_PORT_UCHAR(Port
);
379 TRACE("Mouse data: %x %x %x %x\n",
380 Buffer
[0], Buffer
[1], Buffer
[2], Buffer
[3]);
382 /* Check that four bytes for signs */
383 for (i
= 0; i
< 4; ++i
)
385 if (Buffer
[i
] == 'B')
387 /* Sign for Microsoft Ballpoint */
388 // DbgPrint("Microsoft Ballpoint device detected\n");
389 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
390 return MOUSE_TYPE_NONE
;
392 else if (Buffer
[i
] == 'M')
394 /* Sign for Microsoft Mouse protocol followed by button specifier */
398 return MOUSE_TYPE_NONE
;
401 switch (Buffer
[i
+ 1])
404 TRACE("Microsoft Mouse with 3-buttons detected\n");
405 return MOUSE_TYPE_LOGITECH
;
408 TRACE("Microsoft Wheel Mouse detected\n");
409 return MOUSE_TYPE_WHEELZ
;
413 TRACE("Microsoft Mouse with 2-buttons detected\n");
414 return MOUSE_TYPE_MICROSOFT
;
419 return MOUSE_TYPE_NONE
;
423 GetSerialMousePnpId(PUCHAR Port
, char *Buffer
)
430 WRITE_PORT_UCHAR(Port
+ 4, 0x09);
432 /* Wait 10 milliseconds for the mouse getting ready */
433 StallExecutionProcessor(10000);
435 WRITE_PORT_UCHAR(Port
+ 4, 0x0b);
437 StallExecutionProcessor(10000);
442 while (((READ_PORT_UCHAR(Port
+ 5) & 1) == 0) && (TimeOut
> 0))
444 StallExecutionProcessor(1000);
452 c
= READ_PORT_UCHAR(Port
);
453 if (c
== 0x08 || c
== 0x28)
463 while (((READ_PORT_UCHAR(Port
+ 5) & 1) == 0) && (TimeOut
> 0))
465 StallExecutionProcessor(1000);
470 c
= READ_PORT_UCHAR(Port
);
483 DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
,
486 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
488 CHAR Identifier
[256];
489 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
496 TRACE("DetectSerialPointerPeripheral()\n");
500 InitializeSerialPort(Base
, 2);
501 MouseType
= DetectSerialMouse(Base
);
503 if (MouseType
!= MOUSE_TYPE_NONE
)
505 Length
= GetSerialMousePnpId(Base
, Buffer
);
506 TRACE( "PnP ID length: %u\n", Length
);
510 /* Convert PnP sting to ASCII */
511 if (Buffer
[0] == 0x08)
513 for (i
= 0; i
< Length
; i
++)
518 TRACE("PnP ID string: %s\n", Buffer
);
520 /* Copy PnpId string */
521 for (i
= 0; i
< 7; i
++)
523 Identifier
[i
] = Buffer
[3 + i
];
525 memcpy(&Identifier
[7],
529 /* Skip device serial number */
531 if (Buffer
[i
] == '\\')
533 for (j
= ++i
; i
< Length
; ++i
)
535 if (Buffer
[i
] == '\\')
543 if (Buffer
[i
] == '\\')
545 for (j
= ++i
; i
< Length
; ++i
)
547 if (Buffer
[i
] == '\\')
555 /* Skip compatible PnP Id */
556 if (Buffer
[i
] == '\\')
558 for (j
= ++i
; i
< Length
; ++i
)
560 if (Buffer
[i
] == '\\')
563 if (Buffer
[j
] == '*')
569 /* Get product description */
570 if (Buffer
[i
] == '\\')
572 for (j
= ++i
; i
< Length
; ++i
)
574 if (Buffer
[i
] == ';')
581 for (k
= 0; k
< i
- j
; k
++)
583 Identifier
[k
+ 10] = Buffer
[k
+ j
];
585 Identifier
[10 + (i
- j
)] = 0;
589 TRACE("Identifier string: %s\n", Identifier
);
592 if (Length
== 0 || strlen(Identifier
) < 11)
596 case MOUSE_TYPE_LOGITECH
:
597 strcpy(Identifier
, "LOGITECH SERIAL MOUSE");
600 case MOUSE_TYPE_WHEELZ
:
601 strcpy(Identifier
, "MICROSOFT SERIAL MOUSE WITH WHEEL");
604 case MOUSE_TYPE_MICROSOFT
:
606 strcpy(Identifier
, "MICROSOFT SERIAL MOUSE");
611 /* Set 'Configuration Data' value */
612 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) -
613 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
614 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
615 if (PartialResourceList
== NULL
)
617 ERR("Failed to allocate resource descriptor\n");
620 memset(PartialResourceList
, 0, Size
);
621 PartialResourceList
->Version
= 1;
622 PartialResourceList
->Revision
= 1;
623 PartialResourceList
->Count
= 0;
625 /* Create 'PointerPeripheral' key */
626 FldrCreateComponentKey(ControllerKey
,
637 TRACE("Created key: PointerPeripheral\\0\n");
642 PcGetSerialPort(ULONG Index
, PULONG Irq
)
644 static const ULONG PcIrq
[MAX_COM_PORTS
] = {4, 3, 4, 3};
648 * The BIOS data area 0x400 holds the address of the first valid COM port.
649 * Each COM port address is stored in a 2-byte field.
650 * Infos at: http://www.bioscentral.com/misc/bda.htm
652 BasePtr
= (PUSHORT
)0x400;
655 return (ULONG
) *(BasePtr
+ Index
);
659 DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey
, GET_SERIAL_PORT MachGetSerialPort
, ULONG Count
)
661 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
662 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
663 PCM_SERIAL_DEVICE_DATA SerialDeviceData
;
667 ULONG ControllerNumber
= 0;
668 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
672 TRACE("DetectSerialPorts()\n");
674 for (i
= 0; i
< Count
; i
++)
676 Base
= MachGetSerialPort(i
, &Irq
);
677 if ((Base
== 0) || !CpDoesPortExist(UlongToPtr(Base
)))
680 TRACE("Found COM%u port at 0x%x\n", i
+ 1, Base
);
682 /* Set 'Identifier' value */
683 sprintf(Buffer
, "COM%ld", i
+ 1);
685 /* Build full device descriptor */
686 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
687 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
688 sizeof(CM_SERIAL_DEVICE_DATA
);
689 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
690 if (PartialResourceList
== NULL
)
692 ERR("Failed to allocate resource descriptor\n");
695 memset(PartialResourceList
, 0, Size
);
697 /* Initialize resource descriptor */
698 PartialResourceList
->Version
= 1;
699 PartialResourceList
->Revision
= 1;
700 PartialResourceList
->Count
= 3;
703 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
704 PartialDescriptor
->Type
= CmResourceTypePort
;
705 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
706 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
707 PartialDescriptor
->u
.Port
.Start
.LowPart
= Base
;
708 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
709 PartialDescriptor
->u
.Port
.Length
= 8;
712 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
713 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
714 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
715 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
716 PartialDescriptor
->u
.Interrupt
.Level
= Irq
;
717 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
;
718 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
720 /* Set serial data (device specific) */
721 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
722 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
723 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
724 PartialDescriptor
->Flags
= 0;
725 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_SERIAL_DEVICE_DATA
);
728 (PCM_SERIAL_DEVICE_DATA
)&PartialResourceList
->PartialDescriptors
[3];
729 SerialDeviceData
->BaudClock
= 1843200; /* UART Clock frequency (Hertz) */
731 /* Create controller key */
732 FldrCreateComponentKey(BusKey
,
735 Output
| Input
| ConsoleIn
| ConsoleOut
,
743 if (!Rs232PortInUse(UlongToPtr(Base
)))
745 /* Detect serial mouse */
746 DetectSerialPointerPeripheral(ControllerKey
, UlongToPtr(Base
));
754 DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey
)
756 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
757 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
758 ULONG Irq
[MAX_LPT_PORTS
] = {7, 5, (ULONG
) - 1};
760 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
763 ULONG ControllerNumber
= 0;
767 TRACE("DetectParallelPorts() called\n");
770 * The BIOS data area 0x408 holds the address of the first valid LPT port.
771 * Each LPT port address is stored in a 2-byte field.
772 * Infos at: http://www.bioscentral.com/misc/bda.htm
774 BasePtr
= (PUSHORT
)0x408;
776 for (i
= 0; i
< MAX_LPT_PORTS
; i
++, BasePtr
++)
778 Base
= (ULONG
) * BasePtr
;
782 TRACE("Parallel port %u: %x\n", ControllerNumber
, Base
);
784 /* Set 'Identifier' value */
785 sprintf(Buffer
, "PARALLEL%ld", i
+ 1);
787 /* Build full device descriptor */
788 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
);
789 if (Irq
[i
] != (ULONG
) - 1)
790 Size
+= sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
792 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
793 if (PartialResourceList
== NULL
)
795 ERR("Failed to allocate resource descriptor\n");
798 memset(PartialResourceList
, 0, Size
);
800 /* Initialize resource descriptor */
801 PartialResourceList
->Version
= 1;
802 PartialResourceList
->Revision
= 1;
803 PartialResourceList
->Count
= (Irq
[i
] != (ULONG
) - 1) ? 2 : 1;
806 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
807 PartialDescriptor
->Type
= CmResourceTypePort
;
808 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
809 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
810 PartialDescriptor
->u
.Port
.Start
.LowPart
= Base
;
811 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
812 PartialDescriptor
->u
.Port
.Length
= 3;
815 if (Irq
[i
] != (ULONG
) - 1)
817 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
818 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
819 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
820 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
821 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
822 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
[i
];
823 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
826 /* Create controller key */
827 FldrCreateComponentKey(BusKey
,
841 TRACE("DetectParallelPorts() done\n");
846 DetectKeyboardDevice(VOID
)
851 BOOLEAN Result
= TRUE
;
853 /* Identify device */
854 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
, 0xF2);
857 for (Loops
= 0; Loops
< 100; Loops
++)
859 StallExecutionProcessor(10000);
860 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
861 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
865 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
867 /* PC/XT keyboard or no keyboard */
871 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
872 if (Scancode
!= 0xFA)
874 /* No ACK received */
878 StallExecutionProcessor(10000);
880 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
881 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
883 /* Found AT keyboard */
887 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
888 if (Scancode
!= 0xAB)
890 /* No 0xAB received */
894 StallExecutionProcessor(10000);
896 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
897 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
899 /* No byte in buffer */
903 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
904 if (Scancode
!= 0x41)
906 /* No 0x41 received */
910 /* Found MF-II keyboard */
915 DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
)
917 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
918 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
919 PCM_KEYBOARD_DEVICE_DATA KeyboardData
;
920 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
924 /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2
925 if (DetectKeyboardDevice()) */
927 /* Set 'Configuration Data' value */
928 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
929 sizeof(CM_KEYBOARD_DEVICE_DATA
);
930 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
931 if (PartialResourceList
== NULL
)
933 ERR("Failed to allocate resource descriptor\n");
937 /* Initialize resource descriptor */
938 memset(PartialResourceList
, 0, Size
);
939 PartialResourceList
->Version
= 1;
940 PartialResourceList
->Revision
= 1;
941 PartialResourceList
->Count
= 1;
943 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
944 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
945 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
946 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_KEYBOARD_DEVICE_DATA
);
949 * KEYBOARD - GET SHIFT FLAGS
955 Int386(0x16, &Regs
, &Regs
);
957 KeyboardData
= (PCM_KEYBOARD_DEVICE_DATA
)(PartialDescriptor
+ 1);
958 KeyboardData
->Version
= 1;
959 KeyboardData
->Revision
= 1;
960 KeyboardData
->Type
= 4;
961 KeyboardData
->Subtype
= 0;
962 KeyboardData
->KeyboardFlags
= Regs
.b
.al
;
964 /* Create controller key */
965 FldrCreateComponentKey(ControllerKey
,
975 TRACE("Created key: KeyboardPeripheral\\0\n");
981 DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey
)
983 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
984 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
985 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
988 /* Set 'Configuration Data' value */
989 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
990 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
991 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
992 if (PartialResourceList
== NULL
)
994 ERR("Failed to allocate resource descriptor\n");
998 /* Initialize resource descriptor */
999 memset(PartialResourceList
, 0, Size
);
1000 PartialResourceList
->Version
= 1;
1001 PartialResourceList
->Revision
= 1;
1002 PartialResourceList
->Count
= 3;
1005 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1006 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1007 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1008 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1009 PartialDescriptor
->u
.Interrupt
.Level
= 1;
1010 PartialDescriptor
->u
.Interrupt
.Vector
= 1;
1011 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1013 /* Set IO Port 0x60 */
1014 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
1015 PartialDescriptor
->Type
= CmResourceTypePort
;
1016 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1017 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1018 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x60;
1019 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1020 PartialDescriptor
->u
.Port
.Length
= 1;
1022 /* Set IO Port 0x64 */
1023 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
1024 PartialDescriptor
->Type
= CmResourceTypePort
;
1025 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1026 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1027 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x64;
1028 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1029 PartialDescriptor
->u
.Port
.Length
= 1;
1031 /* Create controller key */
1032 FldrCreateComponentKey(BusKey
,
1039 PartialResourceList
,
1042 TRACE("Created key: KeyboardController\\0\n");
1044 DetectKeyboardPeripheral(ControllerKey
);
1049 PS2ControllerWait(VOID
)
1054 for (Timeout
= 0; Timeout
< CONTROLLER_TIMEOUT
; Timeout
++)
1056 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1057 if ((Status
& CONTROLLER_STATUS_INPUT_BUFFER_FULL
) == 0)
1060 /* Sleep for one millisecond */
1061 StallExecutionProcessor(1000);
1067 DetectPS2AuxPort(VOID
)
1070 /* Current detection is too unreliable. Just do as if
1071 * the PS/2 aux port is always present
1078 /* Put the value 0x5A in the output buffer using the
1079 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1080 * Poll the Status Register for a while to see if the value really turns up
1081 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1082 * to 1 in the Status Register, we assume this controller has an
1083 * Auxiliary Port (a.k.a. Mouse Port).
1085 PS2ControllerWait();
1086 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1087 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER
);
1088 PS2ControllerWait();
1090 /* 0x5A is a random dummy value */
1091 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1094 for (Loops
= 0; Loops
< 10; Loops
++)
1096 StallExecutionProcessor(10000);
1097 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1098 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1102 READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1104 return (Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
);
1110 DetectPS2AuxDevice(VOID
)
1115 BOOLEAN Result
= TRUE
;
1117 PS2ControllerWait();
1118 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1119 CONTROLLER_COMMAND_WRITE_MOUSE
);
1120 PS2ControllerWait();
1122 /* Identify device */
1123 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
, 0xF2);
1125 /* Wait for reply */
1126 for (Loops
= 0; Loops
< 100; Loops
++)
1128 StallExecutionProcessor(10000);
1129 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1130 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1134 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1135 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1138 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1139 if (Scancode
!= 0xFA)
1142 StallExecutionProcessor(10000);
1144 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1145 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1148 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1149 if (Scancode
!= 0x00)
1155 // FIXME: Missing: DetectPS2Peripheral!! (for corresponding 'PointerPeripheral')
1159 DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey
)
1161 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1162 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1163 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
1166 if (DetectPS2AuxPort())
1168 TRACE("Detected PS2 port\n");
1170 PartialResourceList
= FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST
), TAG_HW_RESOURCE_LIST
);
1171 if (PartialResourceList
== NULL
)
1173 ERR("Failed to allocate resource descriptor\n");
1176 memset(PartialResourceList
, 0, sizeof(CM_PARTIAL_RESOURCE_LIST
));
1178 /* Initialize resource descriptor */
1179 PartialResourceList
->Version
= 1;
1180 PartialResourceList
->Revision
= 1;
1181 PartialResourceList
->Count
= 1;
1184 PartialResourceList
->PartialDescriptors
[0].Type
= CmResourceTypeInterrupt
;
1185 PartialResourceList
->PartialDescriptors
[0].ShareDisposition
= CmResourceShareUndetermined
;
1186 PartialResourceList
->PartialDescriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1187 PartialResourceList
->PartialDescriptors
[0].u
.Interrupt
.Level
= 12;
1188 PartialResourceList
->PartialDescriptors
[0].u
.Interrupt
.Vector
= 12;
1189 PartialResourceList
->PartialDescriptors
[0].u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1191 /* Create controller key */
1192 FldrCreateComponentKey(BusKey
,
1199 PartialResourceList
,
1200 sizeof(CM_PARTIAL_RESOURCE_LIST
),
1202 TRACE("Created key: PointerController\\0\n");
1204 if (DetectPS2AuxDevice())
1206 TRACE("Detected PS2 mouse\n");
1208 /* Initialize resource descriptor */
1209 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1210 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1211 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
1212 if (PartialResourceList
== NULL
)
1214 ERR("Failed to allocate resource descriptor\n");
1217 memset(PartialResourceList
, 0, Size
);
1218 PartialResourceList
->Version
= 1;
1219 PartialResourceList
->Revision
= 1;
1220 PartialResourceList
->Count
= 0;
1222 /* Create peripheral key */
1223 FldrCreateComponentKey(ControllerKey
,
1229 "MICROSOFT PS2 MOUSE",
1230 PartialResourceList
,
1233 TRACE("Created key: PointerPeripheral\\0\n");
1239 // Implemented in pcvesa.c, returns the VESA version
1240 USHORT
BiosIsVesaSupported(VOID
);
1241 BOOLEAN
BiosIsVesaDdcSupported(VOID
);
1242 BOOLEAN
BiosVesaReadEdid(VOID
);
1245 DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey
)
1248 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1251 /* FIXME: Set 'ComponentInformation' value */
1253 VesaVersion
= BiosIsVesaSupported();
1254 if (VesaVersion
!= 0)
1256 TRACE("VESA version %c.%c\n",
1257 (VesaVersion
>> 8) + '0',
1258 (VesaVersion
& 0xFF) + '0');
1262 TRACE("VESA not supported\n");
1265 if (VesaVersion
>= 0x0200)
1267 strcpy(Buffer
, "VBE Display");
1271 strcpy(Buffer
, "VGA Display");
1274 FldrCreateComponentKey(BusKey
,
1284 TRACE("Created key: DisplayController\\0\n");
1286 /* FIXME: Add display peripheral (monitor) data */
1287 if (VesaVersion
!= 0)
1289 if (BiosIsVesaDdcSupported())
1291 TRACE("VESA/DDC supported!\n");
1292 if (BiosVesaReadEdid())
1294 TRACE("EDID data read successfully!\n");
1303 DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
1305 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1306 PCONFIGURATION_COMPONENT_DATA BusKey
;
1309 /* Set 'Configuration Data' value */
1310 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1311 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1312 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
1313 if (PartialResourceList
== NULL
)
1315 ERR("Failed to allocate resource descriptor\n");
1319 /* Initialize resource descriptor */
1320 memset(PartialResourceList
, 0, Size
);
1321 PartialResourceList
->Version
= 1;
1322 PartialResourceList
->Revision
= 1;
1323 PartialResourceList
->Count
= 0;
1325 /* Create new bus key */
1326 FldrCreateComponentKey(SystemKey
,
1328 MultiFunctionAdapter
,
1333 PartialResourceList
,
1337 /* Increment bus number */
1340 /* Detect ISA/BIOS devices */
1341 DetectBiosDisks(SystemKey
, BusKey
);
1342 DetectSerialPorts(BusKey
, PcGetSerialPort
, MAX_COM_PORTS
);
1343 DetectParallelPorts(BusKey
);
1344 DetectKeyboardController(BusKey
);
1345 DetectPS2Mouse(BusKey
);
1346 DetectDisplayController(BusKey
);
1348 /* FIXME: Detect more ISA devices */
1351 /* FIXME: Abstract things better so we don't need to place define here */
1352 #if !defined(SARCH_XBOX)
1355 PcGetFloppyCount(VOID
)
1359 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
1360 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
1362 return ((Data
& 0xF0) ? 1 : 0) + ((Data
& 0x0F) ? 1 : 0);
1366 PCONFIGURATION_COMPONENT_DATA
1369 PCONFIGURATION_COMPONENT_DATA SystemKey
;
1370 ULONG BusNumber
= 0;
1372 TRACE("DetectHardware()\n");
1374 /* Create the 'System' key */
1375 FldrCreateSystemKey(&SystemKey
);
1376 // TODO: Discover and set the other machine types
1377 FldrSetIdentifier(SystemKey
, "AT/AT COMPATIBLE");
1379 GetHarddiskConfigurationData
= PcGetHarddiskConfigurationData
;
1380 FindPciBios
= PcFindPciBios
;
1383 DetectPciBios(SystemKey
, &BusNumber
);
1384 DetectApmBios(SystemKey
, &BusNumber
);
1385 DetectPnpBios(SystemKey
, &BusNumber
);
1386 DetectIsaBios(SystemKey
, &BusNumber
); // TODO: Detect first EISA or MCA, before ISA
1387 DetectAcpiBios(SystemKey
, &BusNumber
);
1389 // TODO: Collect the ROM blocks from 0xC0000 to 0xF0000 and append their
1390 // CM_ROM_BLOCK data into the 'System' key's configuration data.
1392 TRACE("DetectHardware() Done\n");
1401 /* Select APM 1.0+ function */
1404 /* Function 05h: CPU idle */
1408 Int386(0x15, &Regs
, &Regs
);
1410 /* Check if successfull (CF set on error) */
1411 if (INT386_SUCCESS(Regs
))
1415 * No futher processing here.
1416 * Optionally implement HLT instruction handling.
1420 VOID __cdecl
ChainLoadBiosBootSectorCode(
1421 IN UCHAR BootDrive OPTIONAL
,
1422 IN ULONG BootPartition OPTIONAL
)
1426 RtlZeroMemory(&Regs
, sizeof(Regs
));
1428 /* Set the boot drive and the boot partition */
1429 Regs
.b
.dl
= (UCHAR
)(BootDrive
? BootDrive
: FrldrBootDrive
);
1430 Regs
.b
.dh
= (UCHAR
)(BootPartition
? BootPartition
: FrldrBootPartition
);
1433 * Don't stop the floppy drive motor when we are just booting a bootsector,
1434 * a drive, or a partition. If we were to stop the floppy motor, the BIOS
1435 * wouldn't be informed and if the next read is to a floppy then the BIOS
1436 * will still think the motor is on and this will result in a read error.
1438 // DiskStopFloppyMotor();
1440 Relocator16Boot(&Regs
,
1441 /* Stack segment:pointer */
1443 /* Code segment:pointer */
1447 /******************************************************************************/
1449 /* FIXME: Abstract things better so we don't need to place define here */
1450 #if !defined(SARCH_XBOX)
1452 MachInit(const char *CmdLine
)
1454 memset(&MachVtbl
, 0, sizeof(MACHVTBL
));
1457 MachVtbl
.ConsPutChar
= PcConsPutChar
;
1458 MachVtbl
.ConsKbHit
= PcConsKbHit
;
1459 MachVtbl
.ConsGetCh
= PcConsGetCh
;
1460 MachVtbl
.VideoClearScreen
= PcVideoClearScreen
;
1461 MachVtbl
.VideoSetDisplayMode
= PcVideoSetDisplayMode
;
1462 MachVtbl
.VideoGetDisplaySize
= PcVideoGetDisplaySize
;
1463 MachVtbl
.VideoGetBufferSize
= PcVideoGetBufferSize
;
1464 MachVtbl
.VideoGetFontsFromFirmware
= PcVideoGetFontsFromFirmware
;
1465 MachVtbl
.VideoSetTextCursorPosition
= PcVideoSetTextCursorPosition
;
1466 MachVtbl
.VideoHideShowTextCursor
= PcVideoHideShowTextCursor
;
1467 MachVtbl
.VideoPutChar
= PcVideoPutChar
;
1468 MachVtbl
.VideoCopyOffScreenBufferToVRAM
= PcVideoCopyOffScreenBufferToVRAM
;
1469 MachVtbl
.VideoIsPaletteFixed
= PcVideoIsPaletteFixed
;
1470 MachVtbl
.VideoSetPaletteColor
= PcVideoSetPaletteColor
;
1471 MachVtbl
.VideoGetPaletteColor
= PcVideoGetPaletteColor
;
1472 MachVtbl
.VideoSync
= PcVideoSync
;
1473 MachVtbl
.Beep
= PcBeep
;
1474 MachVtbl
.PrepareForReactOS
= PcPrepareForReactOS
;
1475 MachVtbl
.GetMemoryMap
= PcMemGetMemoryMap
;
1476 MachVtbl
.GetExtendedBIOSData
= PcGetExtendedBIOSData
;
1477 MachVtbl
.GetFloppyCount
= PcGetFloppyCount
;
1478 MachVtbl
.DiskReadLogicalSectors
= PcDiskReadLogicalSectors
;
1479 MachVtbl
.DiskGetDriveGeometry
= PcDiskGetDriveGeometry
;
1480 MachVtbl
.DiskGetCacheableBlockCount
= PcDiskGetCacheableBlockCount
;
1481 MachVtbl
.GetTime
= PcGetTime
;
1482 MachVtbl
.InitializeBootDevices
= PcInitializeBootDevices
;
1483 MachVtbl
.HwDetect
= PcHwDetect
;
1484 MachVtbl
.HwIdle
= PcHwIdle
;
1486 HalpCalibrateStallExecution();
1490 PcPrepareForReactOS(VOID
)
1492 /* On PC, prepare video and turn off the floppy motor */
1493 PcVideoPrepareForReactOS();
1494 DiskStopFloppyMotor();