mirror of
https://github.com/reactos/reactos.git
synced 2025-07-24 15:13:36 +00:00
freeldr: Remove duplicated / unused files for amd64 architecture
See issue #4672 for more details. svn path=/trunk/; revision=41834
This commit is contained in:
parent
e99d1fe3f9
commit
2d834b1bdd
13 changed files with 0 additions and 4901 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,5 +0,0 @@
|
|||
/* No need to duplicate code ; import the i386 version */
|
||||
|
||||
#include "../i386/hwacpi.c"
|
||||
|
||||
/* EOF */
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 2004 Eric Kohl
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static BOOLEAN
|
||||
FindApmBios(VOID)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
RegsIn.b.ah = 0x53;
|
||||
RegsIn.b.al = 0x00;
|
||||
RegsIn.w.bx = 0x0000;
|
||||
|
||||
Int386(0x15, &RegsIn, &RegsOut);
|
||||
|
||||
if (INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Found APM BIOS\n"));
|
||||
DbgPrint((DPRINT_HWDETECT, "AH: %x\n", RegsOut.b.ah));
|
||||
DbgPrint((DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al));
|
||||
DbgPrint((DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh));
|
||||
DbgPrint((DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl));
|
||||
DbgPrint((DPRINT_HWDETECT, "CX: %x\n", RegsOut.w.cx));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT, "No APM BIOS found\n"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
DetectApmBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
||||
{
|
||||
PCONFIGURATION_COMPONENT_DATA BiosKey;
|
||||
CM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||
|
||||
if (FindApmBios())
|
||||
{
|
||||
/* Create new bus key */
|
||||
FldrCreateComponentKey(SystemKey,
|
||||
L"MultifunctionAdapter",
|
||||
*BusNumber,
|
||||
AdapterClass,
|
||||
MultiFunctionAdapter,
|
||||
&BiosKey);
|
||||
|
||||
/* Set 'Component Information' */
|
||||
FldrSetComponentInformation(BiosKey,
|
||||
0x0,
|
||||
0x0,
|
||||
0xFFFFFFFF);
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
memset(&PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST));
|
||||
PartialResourceList.Version = 0;
|
||||
PartialResourceList.Revision = 0;
|
||||
PartialResourceList.Count = 0;
|
||||
FldrSetConfigurationData(BiosKey,
|
||||
&PartialResourceList,
|
||||
sizeof(CM_PARTIAL_RESOURCE_LIST) -
|
||||
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
|
||||
|
||||
/* Increment bus number */
|
||||
(*BusNumber)++;
|
||||
|
||||
/* Set 'Identifier' value */
|
||||
FldrSetIdentifier(BiosKey, "APM");
|
||||
}
|
||||
|
||||
/* FIXME: Add configuration data */
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,346 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 2004 Eric Kohl
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct _ROUTING_SLOT
|
||||
{
|
||||
UCHAR BusNumber;
|
||||
UCHAR DeviceNumber;
|
||||
UCHAR LinkA;
|
||||
USHORT BitmapA;
|
||||
UCHAR LinkB;
|
||||
USHORT BitmapB;
|
||||
UCHAR LinkC;
|
||||
USHORT BitmapC;
|
||||
UCHAR LinkD;
|
||||
USHORT BitmapD;
|
||||
UCHAR SlotNumber;
|
||||
UCHAR Reserved;
|
||||
} __attribute__((packed)) ROUTING_SLOT, *PROUTING_SLOT;
|
||||
|
||||
typedef struct _PCI_IRQ_ROUTING_TABLE
|
||||
{
|
||||
ULONG Signature;
|
||||
USHORT Version;
|
||||
USHORT Size;
|
||||
UCHAR RouterBus;
|
||||
UCHAR RouterSlot;
|
||||
USHORT ExclusiveIRQs;
|
||||
ULONG CompatibleRouter;
|
||||
ULONG MiniportData;
|
||||
UCHAR Reserved[11];
|
||||
UCHAR Checksum;
|
||||
ROUTING_SLOT Slot[1];
|
||||
} __attribute__((packed)) PCI_IRQ_ROUTING_TABLE, *PPCI_IRQ_ROUTING_TABLE;
|
||||
|
||||
typedef struct _PCI_REGISTRY_INFO
|
||||
{
|
||||
UCHAR MajorRevision;
|
||||
UCHAR MinorRevision;
|
||||
UCHAR NoBuses;
|
||||
UCHAR HardwareMechanism;
|
||||
} PCI_REGISTRY_INFO, *PPCI_REGISTRY_INFO;
|
||||
|
||||
static PPCI_IRQ_ROUTING_TABLE
|
||||
GetPciIrqRoutingTable(VOID)
|
||||
{
|
||||
PPCI_IRQ_ROUTING_TABLE Table;
|
||||
PUCHAR Ptr;
|
||||
ULONG Sum;
|
||||
ULONG i;
|
||||
|
||||
Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
|
||||
while ((ULONG_PTR)Table < 0x100000)
|
||||
{
|
||||
if (Table->Signature == 0x52495024)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Found signature\n"));
|
||||
|
||||
Ptr = (PUCHAR)Table;
|
||||
Sum = 0;
|
||||
for (i = 0; i < Table->Size; i++)
|
||||
{
|
||||
Sum += Ptr[i];
|
||||
}
|
||||
|
||||
if ((Sum & 0xFF) != 0)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Invalid routing table\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Valid checksum\n"));
|
||||
|
||||
return Table;
|
||||
}
|
||||
|
||||
Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG_PTR)Table + 0x10);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
FindPciBios(PPCI_REGISTRY_INFO BusData)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
RegsIn.b.ah = 0xB1; /* Subfunction B1h */
|
||||
RegsIn.b.al = 0x01; /* PCI BIOS present */
|
||||
|
||||
Int386(0x1A, &RegsIn, &RegsOut);
|
||||
|
||||
if (INT386_SUCCESS(RegsOut) && RegsOut.d.edx == 0x20494350 && RegsOut.b.ah == 0)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Found PCI bios\n"));
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al));
|
||||
DbgPrint((DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh));
|
||||
DbgPrint((DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl));
|
||||
DbgPrint((DPRINT_HWDETECT, "CL: %x\n", RegsOut.b.cl));
|
||||
|
||||
BusData->NoBuses = RegsOut.b.cl + 1;
|
||||
BusData->MajorRevision = RegsOut.b.bh;
|
||||
BusData->MinorRevision = RegsOut.b.bl;
|
||||
BusData->HardwareMechanism = RegsOut.b.cl;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT, "No PCI bios found\n"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey)
|
||||
{
|
||||
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
||||
PPCI_IRQ_ROUTING_TABLE Table;
|
||||
PCONFIGURATION_COMPONENT_DATA TableKey;
|
||||
ULONG Size;
|
||||
|
||||
Table = GetPciIrqRoutingTable();
|
||||
if (Table != NULL)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Table size: %u\n", Table->Size));
|
||||
|
||||
FldrCreateComponentKey(BusKey,
|
||||
L"RealModeIrqRoutingTable",
|
||||
0,
|
||||
PeripheralClass,
|
||||
RealModeIrqRoutingTable,
|
||||
&TableKey);
|
||||
|
||||
/* Set 'Component Information' */
|
||||
FldrSetComponentInformation(TableKey,
|
||||
0x0,
|
||||
0x0,
|
||||
0xFFFFFFFF);
|
||||
|
||||
/* Set 'Identifier' value */
|
||||
FldrSetIdentifier(TableKey, "PCI Real-mode IRQ Routing Table");
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
|
||||
2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + Table->Size;
|
||||
PartialResourceList = MmAllocateMemory(Size);
|
||||
if (PartialResourceList == NULL)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Failed to allocate resource descriptor\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize resource descriptor */
|
||||
memset(PartialResourceList, 0, Size);
|
||||
PartialResourceList->Version = 1;
|
||||
PartialResourceList->Revision = 1;
|
||||
PartialResourceList->Count = 2;
|
||||
|
||||
PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
|
||||
PartialDescriptor->Type = CmResourceTypeBusNumber;
|
||||
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
||||
PartialDescriptor->u.BusNumber.Start = 0;
|
||||
PartialDescriptor->u.BusNumber.Length = 1;
|
||||
|
||||
PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
|
||||
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
|
||||
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
|
||||
PartialDescriptor->u.DeviceSpecificData.DataSize = Table->Size;
|
||||
|
||||
memcpy(&PartialResourceList->PartialDescriptors[2],
|
||||
Table, Table->Size);
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
FldrSetConfigurationData(TableKey, PartialResourceList, Size);
|
||||
MmFreeMemory(PartialResourceList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
||||
{
|
||||
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
||||
PCI_REGISTRY_INFO BusData;
|
||||
PCONFIGURATION_COMPONENT_DATA BiosKey;
|
||||
ULONG Size;
|
||||
PCONFIGURATION_COMPONENT_DATA BusKey;
|
||||
ULONG i;
|
||||
CHAR szPci[] = "PCI";
|
||||
|
||||
/* Report the PCI BIOS */
|
||||
if (FindPciBios(&BusData))
|
||||
{
|
||||
/* Create new bus key */
|
||||
FldrCreateComponentKey(SystemKey,
|
||||
L"MultifunctionAdapter",
|
||||
*BusNumber,
|
||||
AdapterClass,
|
||||
MultiFunctionAdapter,
|
||||
&BiosKey);
|
||||
|
||||
/* Set 'Component Information' */
|
||||
FldrSetComponentInformation(BiosKey,
|
||||
0x0,
|
||||
0x0,
|
||||
0xFFFFFFFF);
|
||||
|
||||
/* Increment bus number */
|
||||
(*BusNumber)++;
|
||||
|
||||
/* Set 'Identifier' value */
|
||||
FldrSetIdentifier(BiosKey, "PCI BIOS");
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
|
||||
PartialDescriptors);
|
||||
PartialResourceList = MmAllocateMemory(Size);
|
||||
if (PartialResourceList == NULL)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Failed to allocate resource descriptor\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize resource descriptor */
|
||||
memset(PartialResourceList, 0, Size);
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
FldrSetConfigurationData(BiosKey, PartialResourceList, Size);
|
||||
MmFreeMemory(PartialResourceList);
|
||||
|
||||
DetectPciIrqRoutingTable(BiosKey);
|
||||
|
||||
/* Report PCI buses */
|
||||
for (i = 0; i < (ULONG)BusData.NoBuses; i++)
|
||||
{
|
||||
/* Create the bus key */
|
||||
FldrCreateComponentKey(SystemKey,
|
||||
L"MultifunctionAdapter",
|
||||
*BusNumber,
|
||||
AdapterClass,
|
||||
MultiFunctionAdapter,
|
||||
&BusKey);
|
||||
|
||||
/* Set 'Component Information' */
|
||||
FldrSetComponentInformation(BusKey,
|
||||
0x0,
|
||||
0x0,
|
||||
0xFFFFFFFF);
|
||||
|
||||
/* Check if this is the first bus */
|
||||
if (i == 0)
|
||||
{
|
||||
/* Set 'Configuration Data' value */
|
||||
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
|
||||
PartialDescriptors) +
|
||||
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
|
||||
sizeof(PCI_REGISTRY_INFO);
|
||||
PartialResourceList = MmAllocateMemory(Size);
|
||||
if (!PartialResourceList)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"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(PCI_REGISTRY_INFO);
|
||||
memcpy(&PartialResourceList->PartialDescriptors[1],
|
||||
&BusData,
|
||||
sizeof(PCI_REGISTRY_INFO));
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
FldrSetConfigurationData(BusKey, PartialResourceList, Size);
|
||||
MmFreeMemory(PartialResourceList);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set 'Configuration Data' value */
|
||||
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
|
||||
PartialDescriptors);
|
||||
PartialResourceList = MmAllocateMemory(Size);
|
||||
if (!PartialResourceList)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Failed to allocate resource descriptor\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize resource descriptor */
|
||||
memset(PartialResourceList, 0, Size);
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
FldrSetConfigurationData(BusKey, PartialResourceList, Size);
|
||||
MmFreeMemory(PartialResourceList);
|
||||
}
|
||||
|
||||
/* Increment bus number */
|
||||
(*BusNumber)++;
|
||||
|
||||
/* Set 'Identifier' value */
|
||||
FldrSetIdentifier(BusKey, szPci);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,199 +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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOLEAN DiskResetController(ULONG DriveNumber)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "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(ULONG DriveNumber)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskInt13ExtensionsSupported()\n"));
|
||||
|
||||
// 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)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (RegsOut.w.bx != 0xAA55)
|
||||
{
|
||||
// BX = AA55h if installed
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Note:
|
||||
// The original check is too strict because some BIOSes report that
|
||||
// extended disk access functions are not suported when booting
|
||||
// from a CD (e.g. Phoenix BIOS v6.00PG). Argh!
|
||||
#if 0
|
||||
if (!(RegsOut.w.cx & 0x0001))
|
||||
{
|
||||
// CX = API subset support bitmap
|
||||
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Use this relaxed check instead
|
||||
if (RegsOut.w.cx == 0x0000)
|
||||
{
|
||||
// CX = API subset support bitmap
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID DiskStopFloppyMotor(VOID)
|
||||
{
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
|
||||
}
|
||||
|
||||
BOOLEAN DiskGetExtendedDriveParameters(ULONG DriveNumber, PVOID Buffer, USHORT BufferSize)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER);
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskGetExtendedDriveParameters()\n"));
|
||||
|
||||
// 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);
|
||||
|
||||
DbgPrint((DPRINT_DISK, "size of buffer: %x\n", Ptr[0]));
|
||||
DbgPrint((DPRINT_DISK, "information flags: %x\n", Ptr[1]));
|
||||
DbgPrint((DPRINT_DISK, "number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]));
|
||||
DbgPrint((DPRINT_DISK, "number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]));
|
||||
DbgPrint((DPRINT_DISK, "number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]));
|
||||
DbgPrint((DPRINT_DISK, "total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]));
|
||||
DbgPrint((DPRINT_DISK, "bytes per sector: %u\n", Ptr[12]));
|
||||
if (Ptr[0] >= 0x1e)
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "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]);
|
||||
DbgPrint((DPRINT_DISK, "SpecPtr: %x\n", SpecPtr));
|
||||
DbgPrint((DPRINT_DISK, "physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]));
|
||||
DbgPrint((DPRINT_DISK, "disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]));
|
||||
DbgPrint((DPRINT_DISK, "drive flags: %x\n", SpecPtr[4]));
|
||||
DbgPrint((DPRINT_DISK, "proprietary information: %x\n", SpecPtr[5]));
|
||||
DbgPrint((DPRINT_DISK, "IRQ for drive: %u\n", SpecPtr[6]));
|
||||
DbgPrint((DPRINT_DISK, "sector count for multi-sector transfers: %u\n", SpecPtr[7]));
|
||||
DbgPrint((DPRINT_DISK, "DMA control: %x\n", SpecPtr[8]));
|
||||
DbgPrint((DPRINT_DISK, "programmed I/O control: %x\n", SpecPtr[9]));
|
||||
DbgPrint((DPRINT_DISK, "drive options: %x\n", *(PUSHORT)&SpecPtr[10]));
|
||||
}
|
||||
}
|
||||
if (Ptr[0] >= 0x42)
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "signature: %x\n", Ptr[15]));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,87 +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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
void PcBeep(void)
|
||||
{
|
||||
sound(700);
|
||||
delay(200);
|
||||
sound(0);
|
||||
}
|
||||
|
||||
void delay(unsigned msec)
|
||||
{
|
||||
REGS Regs;
|
||||
unsigned usec;
|
||||
unsigned msec_this;
|
||||
|
||||
// Int 15h AH=86h
|
||||
// BIOS - WAIT (AT,PS)
|
||||
//
|
||||
// AH = 86h
|
||||
// CX:DX = interval in microseconds
|
||||
// Return:
|
||||
// CF clear if successful (wait interval elapsed)
|
||||
// CF set on error or AH=83h wait already in progress
|
||||
// AH = status (see #00496)
|
||||
|
||||
// Note: The resolution of the wait period is 977 microseconds on
|
||||
// many systems because many BIOSes use the 1/1024 second fast
|
||||
// interrupt from the AT real-time clock chip which is available on INT 70;
|
||||
// because newer BIOSes may have much more precise timers available, it is
|
||||
// not possible to use this function accurately for very short delays unless
|
||||
// the precise behavior of the BIOS is known (or found through testing)
|
||||
|
||||
while (msec)
|
||||
{
|
||||
msec_this = msec;
|
||||
|
||||
if (msec_this > 4000)
|
||||
{
|
||||
msec_this = 4000;
|
||||
}
|
||||
|
||||
usec = msec_this * 1000;
|
||||
|
||||
Regs.b.ah = 0x86;
|
||||
Regs.w.cx = usec >> 16;
|
||||
Regs.w.dx = usec & 0xffff;
|
||||
Int386(0x15, &Regs, &Regs);
|
||||
|
||||
msec -= msec_this;
|
||||
}
|
||||
}
|
||||
|
||||
void sound(int freq)
|
||||
{
|
||||
int scale;
|
||||
|
||||
if (freq == 0)
|
||||
{
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) & ~3);
|
||||
return;
|
||||
}
|
||||
|
||||
scale = 1193046 / freq;
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x43, 0xb6);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x42, scale & 0xff);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x42, scale >> 8);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) | 3);
|
||||
}
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
* Portions from Linux video.S - Display adapter & video mode setup, version 2.13 (14-May-99)
|
||||
* Copyright (C) 1995 -- 1999 Martin Mares <mj@ucw.cz>
|
||||
* Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UCHAR Signature[4]; // (ret) signature ("VESA")
|
||||
// (call) VESA 2.0 request signature ("VBE2"), required to receive
|
||||
// version 2.0 info
|
||||
USHORT VesaVersion; // VESA version number (one-digit minor version -- 0102h = v1.2)
|
||||
ULONG OemNamePtr; // pointer to OEM name
|
||||
// "761295520" for ATI
|
||||
ULONG Capabilities; // capabilities flags (see #00078)
|
||||
ULONG SupportedModeListPtr; // pointer to list of supported VESA and OEM video modes
|
||||
// (list of words terminated with FFFFh)
|
||||
USHORT TotalVideoMemory; // total amount of video memory in 64K blocks
|
||||
|
||||
// ---VBE v1.x ---
|
||||
//UCHAR Reserved[236];
|
||||
|
||||
// ---VBE v2.0 ---
|
||||
USHORT OemSoftwareVersion; // OEM software version (BCD, high byte = major, low byte = minor)
|
||||
ULONG VendorNamePtr; // pointer to vendor name
|
||||
ULONG ProductNamePtr; // pointer to product name
|
||||
ULONG ProductRevisionStringPtr; // pointer to product revision string
|
||||
USHORT VBE_AF_Version; // (if capabilities bit 3 set) VBE/AF version (BCD)
|
||||
// 0100h for v1.0P
|
||||
ULONG AcceleratedModeListPtr; // (if capabilities bit 3 set) pointer to list of supported
|
||||
// accelerated video modes (list of words terminated with FFFFh)
|
||||
UCHAR Reserved[216]; // reserved for VBE implementation
|
||||
UCHAR ScratchPad[256]; // OEM scratchpad (for OEM strings, etc.)
|
||||
} PACKED VESA_SVGA_INFO, *PVESA_SVGA_INFO;
|
||||
|
||||
// Bitfields for VESA capabilities:
|
||||
//
|
||||
// Bit(s) Description (Table 00078)
|
||||
// 0 DAC can be switched into 8-bit mode
|
||||
// 1 non-VGA controller
|
||||
// 2 programmed DAC with blank bit (i.e. only during blanking interval)
|
||||
// 3 (VBE v3.0) controller supports hardware stereoscopic signalling
|
||||
// 3 controller supports VBE/AF v1.0P extensions
|
||||
// 4 (VBE v3.0) if bit 3 set:
|
||||
// =0 stereo signalling via external VESA stereo connector
|
||||
// =1 stereo signalling via VESA EVC connector
|
||||
// 4 (VBE/AF v1.0P) must call EnableDirectAccess to access framebuffer
|
||||
// 5 (VBE/AF v1.0P) controller supports hardware mouse cursor
|
||||
// 6 (VBE/AF v1.0P) controller supports hardware clipping
|
||||
// 7 (VBE/AF v1.0P) controller supports transparent BitBLT
|
||||
// 8-31 reserved (0)
|
||||
|
||||
// Notes: The list of supported video modes is stored in the reserved
|
||||
// portion of the SuperVGA information record by some implementations,
|
||||
// and it may thus be necessary to either copy the mode list or use a
|
||||
// different buffer for all subsequent VESA calls. Not all of the video
|
||||
// modes in the list of mode numbers may be supported, e.g. if they require
|
||||
// more memory than currently installed or are not supported by the
|
||||
// attached monitor. Check any mode you intend to use through AX=4F01h first..
|
||||
// The 1.1 VESA document specifies 242 reserved bytes at the end, so the
|
||||
// buffer should be 262 bytes to ensure that it is not overrun; for v2.0,
|
||||
// the buffer should be 512 bytes. The S3 specific video modes will most
|
||||
// likely follow the FFFFh terminator at the end of the standard modes.
|
||||
// A search must then be made to find them, FFFFh will also terminate this
|
||||
// second list. In some cases, only a "stub" VBE may be present, supporting
|
||||
// only AX=4F00h; this case may be assumed if the list of supported video modes
|
||||
// is empty (consisting of a single word of FFFFh)
|
||||
#if 0
|
||||
static VOID BiosSetVideoFont8x16(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=1114h
|
||||
// VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
|
||||
//
|
||||
// AX = 1114h
|
||||
// BL = block to load
|
||||
// Return:
|
||||
// Nothing
|
||||
Regs.w.ax = 0x1114;
|
||||
Regs.b.bl = 0;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
static VOID VideoSetTextCursorPosition(ULONG X, ULONG Y)
|
||||
{
|
||||
}
|
||||
|
||||
static ULONG VideoGetTextCursorPositionX(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=03h
|
||||
// VIDEO - GET CURSOR POSITION AND SIZE
|
||||
//
|
||||
// AH = 03h
|
||||
// BH = page number
|
||||
// 0-3 in modes 2&3
|
||||
// 0-7 in modes 0&1
|
||||
// 0 in graphics modes
|
||||
// Return:
|
||||
// AX = 0000h (Phoenix BIOS)
|
||||
// CH = start scan line
|
||||
// CL = end scan line
|
||||
// DH = row (00h is top)
|
||||
// DL = column (00h is left)
|
||||
Regs.b.ah = 0x03;
|
||||
Regs.b.bh = 0x00;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
return Regs.b.dl;
|
||||
}
|
||||
|
||||
static ULONG VideoGetTextCursorPositionY(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=03h
|
||||
// VIDEO - GET CURSOR POSITION AND SIZE
|
||||
//
|
||||
// AH = 03h
|
||||
// BH = page number
|
||||
// 0-3 in modes 2&3
|
||||
// 0-7 in modes 0&1
|
||||
// 0 in graphics modes
|
||||
// Return:
|
||||
// AX = 0000h (Phoenix BIOS)
|
||||
// CH = start scan line
|
||||
// CL = end scan line
|
||||
// DH = row (00h is top)
|
||||
// DL = column (00h is left)
|
||||
Regs.b.ah = 0x03;
|
||||
Regs.b.bh = 0x00;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
return Regs.b.dh;
|
||||
}
|
||||
#endif
|
||||
|
||||
USHORT BiosIsVesaSupported(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
PVESA_SVGA_INFO SvgaInfo = (PVESA_SVGA_INFO)BIOSCALLBUFFER;
|
||||
//USHORT* VideoModes;
|
||||
//USHORT Index;
|
||||
|
||||
DbgPrint((DPRINT_UI, "BiosIsVesaSupported()\n"));
|
||||
|
||||
RtlZeroMemory(SvgaInfo, sizeof(VESA_SVGA_INFO));
|
||||
|
||||
// Make sure we receive version 2.0 info
|
||||
SvgaInfo->Signature[0] = 'V';
|
||||
SvgaInfo->Signature[1] = 'B';
|
||||
SvgaInfo->Signature[2] = 'E';
|
||||
SvgaInfo->Signature[3] = '2';
|
||||
|
||||
// Int 10h AX=4F00h
|
||||
// VESA SuperVGA BIOS (VBE) - GET SuperVGA INFORMATION
|
||||
//
|
||||
// AX = 4F00h
|
||||
// ES:DI -> buffer for SuperVGA information (see #00077)
|
||||
// Return:
|
||||
// AL = 4Fh if function supported
|
||||
// AH = status
|
||||
// 00h successful
|
||||
// ES:DI buffer filled
|
||||
// 01h failed
|
||||
// ---VBE v2.0---
|
||||
// 02h function not supported by current hardware configuration
|
||||
// 03h function invalid in current video mode
|
||||
//
|
||||
// Determine whether VESA BIOS extensions are present and the
|
||||
// capabilities supported by the display adapter
|
||||
//
|
||||
// Installation check;VESA SuperVGA
|
||||
Regs.w.ax = 0x4F00;
|
||||
Regs.w.es = BIOSCALLBUFSEGMENT;
|
||||
Regs.w.di = BIOSCALLBUFOFFSET;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
DbgPrint((DPRINT_UI, "AL = 0x%x\n", Regs.b.al));
|
||||
DbgPrint((DPRINT_UI, "AH = 0x%x\n", Regs.b.ah));
|
||||
|
||||
if (Regs.w.ax != 0x004F)
|
||||
{
|
||||
DbgPrint((DPRINT_UI, "Failed.\n"));
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_UI, "Supported.\n"));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->Signature[4] = %c%c%c%c\n", SvgaInfo->Signature[0], SvgaInfo->Signature[1], SvgaInfo->Signature[2], SvgaInfo->Signature[3]));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VesaVersion = v%d.%d\n", ((SvgaInfo->VesaVersion >> 8) & 0xFF), (SvgaInfo->VesaVersion & 0xFF)));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->OemNamePtr = 0x%x\n", SvgaInfo->OemNamePtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->Capabilities = 0x%x\n", SvgaInfo->Capabilities));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VideoMemory = %dK\n", SvgaInfo->TotalVideoMemory * 64));
|
||||
DbgPrint((DPRINT_UI, "---VBE v2.0 ---\n"));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->OemSoftwareVersion = v%d.%d\n", ((SvgaInfo->OemSoftwareVersion >> 8) & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 12) & 0x0F) * 10), (SvgaInfo->OemSoftwareVersion & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 4) & 0x0F) * 10)));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VendorNamePtr = 0x%x\n", SvgaInfo->VendorNamePtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->ProductNamePtr = 0x%x\n", SvgaInfo->ProductNamePtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->ProductRevisionStringPtr = 0x%x\n", SvgaInfo->ProductRevisionStringPtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VBE/AF Version = 0x%x (BCD WORD)\n", SvgaInfo->VBE_AF_Version));
|
||||
|
||||
//DbgPrint((DPRINT_UI, "\nSupported VESA and OEM video modes:\n"));
|
||||
//VideoModes = (USHORT*)SvgaInfo->SupportedModeListPtr;
|
||||
//for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
|
||||
//{
|
||||
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
|
||||
//}
|
||||
|
||||
//if (SvgaInfo->VesaVersion >= 0x0200)
|
||||
//{
|
||||
// DbgPrint((DPRINT_UI, "\nSupported accelerated video modes (VESA v2.0):\n"));
|
||||
// VideoModes = (USHORT*)SvgaInfo->AcceleratedModeListPtr;
|
||||
// for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
|
||||
// {
|
||||
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
|
||||
// }
|
||||
//}
|
||||
|
||||
DbgPrint((DPRINT_UI, "\n"));
|
||||
|
||||
return SvgaInfo->VesaVersion;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/* $Id: machpc.c 32173 2008-02-07 00:43:09Z ros-arm-bringup $
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
VOID
|
||||
MachInit(const char *CmdLine)
|
||||
{
|
||||
// EnableA20();
|
||||
//DbgPrint((DPRINT_MEMORY, "MachInit.\n"));
|
||||
/* Setup vtbl */
|
||||
MachVtbl.ConsPutChar = PcConsPutChar;
|
||||
MachVtbl.ConsKbHit = PcConsKbHit;
|
||||
MachVtbl.ConsGetCh = PcConsGetCh;
|
||||
MachVtbl.VideoClearScreen = PcVideoClearScreen;
|
||||
MachVtbl.VideoSetDisplayMode = PcVideoSetDisplayMode;
|
||||
MachVtbl.VideoGetDisplaySize = PcVideoGetDisplaySize;
|
||||
MachVtbl.VideoGetBufferSize = PcVideoGetBufferSize;
|
||||
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
|
||||
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
|
||||
MachVtbl.VideoHideShowTextCursor = PcVideoHideShowTextCursor;
|
||||
MachVtbl.VideoPutChar = PcVideoPutChar;
|
||||
MachVtbl.VideoCopyOffScreenBufferToVRAM = PcVideoCopyOffScreenBufferToVRAM;
|
||||
MachVtbl.VideoIsPaletteFixed = PcVideoIsPaletteFixed;
|
||||
MachVtbl.VideoSetPaletteColor = PcVideoSetPaletteColor;
|
||||
MachVtbl.VideoGetPaletteColor = PcVideoGetPaletteColor;
|
||||
MachVtbl.VideoSync = PcVideoSync;
|
||||
MachVtbl.Beep = PcBeep;
|
||||
MachVtbl.PrepareForReactOS = PcPrepareForReactOS;
|
||||
MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
|
||||
MachVtbl.DiskGetBootVolume = DiskGetBootVolume;
|
||||
MachVtbl.DiskGetSystemVolume = DiskGetSystemVolume;
|
||||
MachVtbl.DiskGetBootPath = DiskGetBootPath;
|
||||
MachVtbl.DiskGetBootDevice = DiskGetBootDevice;
|
||||
MachVtbl.DiskBootingFromFloppy = DiskBootingFromFloppy;
|
||||
MachVtbl.DiskNormalizeSystemPath = DiskNormalizeSystemPath;
|
||||
MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
|
||||
MachVtbl.DiskGetPartitionEntry = DiskGetPartitionEntry;
|
||||
MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry;
|
||||
MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount;
|
||||
MachVtbl.GetTime = PcGetTime;
|
||||
MachVtbl.HwDetect = PcHwDetect;
|
||||
}
|
||||
|
||||
VOID
|
||||
PcPrepareForReactOS(IN BOOLEAN Setup)
|
||||
{
|
||||
//
|
||||
// On PC, prepare video and turn off the floppy motor
|
||||
//
|
||||
// PcVideoPrepareForReactOS(Setup);
|
||||
// DiskStopFloppyMotor();
|
||||
}
|
||||
/* EOF */
|
|
@ -1,128 +0,0 @@
|
|||
/* $Id: pccons.c 21917 2006-05-16 23:09:41Z hpoussin $
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#define TEXTMODE_BUFFER 0xb8000
|
||||
#define TEXTMODE_BUFFER_SIZE 0x8000
|
||||
|
||||
#define TEXT_COLS 80
|
||||
#define TEXT_LINES 25
|
||||
|
||||
VOID
|
||||
PcConsPutChar(int Ch)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
/* If we are displaying a CR '\n' then do a LF also */
|
||||
if ('\n' == Ch)
|
||||
{
|
||||
/* Display the LF */
|
||||
PcConsPutChar('\r');
|
||||
}
|
||||
|
||||
/* If we are displaying a TAB '\t' then display 8 spaces ' ' */
|
||||
if ('\t' == Ch)
|
||||
{
|
||||
/* Display the 8 spaces ' ' */
|
||||
PcConsPutChar(' ');
|
||||
PcConsPutChar(' ');
|
||||
PcConsPutChar(' ');
|
||||
PcConsPutChar(' ');
|
||||
PcConsPutChar(' ');
|
||||
PcConsPutChar(' ');
|
||||
PcConsPutChar(' ');
|
||||
PcConsPutChar(' ');
|
||||
return;
|
||||
}
|
||||
|
||||
/* Int 10h AH=0Eh
|
||||
* VIDEO - TELETYPE OUTPUT
|
||||
*
|
||||
* AH = 0Eh
|
||||
* AL = character to write
|
||||
* BH = page number
|
||||
* BL = foreground color (graphics modes only)
|
||||
*/
|
||||
Regs.b.ah = 0x0E;
|
||||
Regs.b.al = Ch;
|
||||
Regs.w.bx = 1;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
PcConsKbHit(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
/* Int 16h AH=01h
|
||||
* KEYBOARD - CHECK FOR KEYSTROKE
|
||||
*
|
||||
* AH = 01h
|
||||
* Return:
|
||||
* ZF set if no keystroke available
|
||||
* ZF clear if keystroke available
|
||||
* AH = BIOS scan code
|
||||
* AL = ASCII character
|
||||
*/
|
||||
Regs.b.ah = 0x01;
|
||||
Int386(0x16, &Regs, &Regs);
|
||||
|
||||
return 0 == (Regs.x.eflags & I386FLAG_ZF);
|
||||
}
|
||||
|
||||
int
|
||||
PcConsGetCh(void)
|
||||
{
|
||||
REGS Regs;
|
||||
static BOOLEAN ExtendedKey = FALSE;
|
||||
static char ExtendedScanCode = 0;
|
||||
|
||||
/* If the last time we were called an
|
||||
* extended key was pressed then return
|
||||
* that keys scan code. */
|
||||
if (ExtendedKey)
|
||||
{
|
||||
ExtendedKey = FALSE;
|
||||
return ExtendedScanCode;
|
||||
}
|
||||
|
||||
/* Int 16h AH=00h
|
||||
* KEYBOARD - GET KEYSTROKE
|
||||
*
|
||||
* AH = 00h
|
||||
* Return:
|
||||
* AH = BIOS scan code
|
||||
* AL = ASCII character
|
||||
*/
|
||||
Regs.b.ah = 0x00;
|
||||
Int386(0x16, &Regs, &Regs);
|
||||
|
||||
/* Check for an extended keystroke */
|
||||
if (0 == Regs.b.al)
|
||||
{
|
||||
ExtendedKey = TRUE;
|
||||
ExtendedScanCode = Regs.b.ah;
|
||||
}
|
||||
|
||||
/* Return keystroke */
|
||||
return Regs.b.al;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,455 +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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.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
|
||||
} PACKED I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static BOOLEAN PcDiskResetController(ULONG DriveNumber)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "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
|
||||
RegsIn.b.ah = 0x00;
|
||||
RegsIn.b.dl = DriveNumber;
|
||||
|
||||
// Reset the disk controller
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
return INT386_SUCCESS(RegsOut);
|
||||
}
|
||||
|
||||
static BOOLEAN PcDiskReadLogicalSectorsLBA(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
ULONG RetryCount;
|
||||
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
|
||||
|
||||
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
|
||||
|
||||
// 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);
|
||||
Packet->Reserved = 0;
|
||||
Packet->LBABlockCount = SectorCount;
|
||||
Packet->TransferBufferOffset = ((ULONG_PTR)Buffer) & 0x0F;
|
||||
Packet->TransferBufferSegment = ((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
|
||||
|
||||
// Retry 3 times
|
||||
for (RetryCount=0; RetryCount<3; RetryCount++)
|
||||
{
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
// If it worked return TRUE
|
||||
if (INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
// If it was a corrected ECC error then the data is still good
|
||||
else if (RegsOut.b.ah == 0x11)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
// If it failed the do the next retry
|
||||
else
|
||||
{
|
||||
PcDiskResetController(DriveNumber);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here then the read failed
|
||||
DiskError("Disk Read Failed in LBA mode", RegsOut.b.ah);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN PcDiskReadLogicalSectorsCHS(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
|
||||
{
|
||||
ULONG PhysicalSector;
|
||||
ULONG PhysicalHead;
|
||||
ULONG PhysicalTrack;
|
||||
GEOMETRY DriveGeometry;
|
||||
ULONG NumberOfSectorsToRead;
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
ULONG RetryCount;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsCHS()\n"));
|
||||
|
||||
//
|
||||
// Get the drive geometry
|
||||
//
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
|
||||
DriveGeometry.Sectors == 0 ||
|
||||
DriveGeometry.Heads == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (SectorCount)
|
||||
{
|
||||
|
||||
//
|
||||
// Calculate the physical disk offsets
|
||||
//
|
||||
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
|
||||
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
|
||||
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
|
||||
|
||||
//
|
||||
// Calculate how many sectors we need to read this round
|
||||
//
|
||||
if (PhysicalSector > 1)
|
||||
{
|
||||
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
|
||||
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
|
||||
else
|
||||
NumberOfSectorsToRead = SectorCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SectorCount >= DriveGeometry.Sectors)
|
||||
NumberOfSectorsToRead = DriveGeometry.Sectors;
|
||||
else
|
||||
NumberOfSectorsToRead = SectorCount;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure the read is within the geometry boundaries
|
||||
//
|
||||
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
||||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
||||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
|
||||
(PhysicalSector > DriveGeometry.Sectors))
|
||||
{
|
||||
DiskError("Disk read exceeds drive geometry limits.", 0);
|
||||
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)
|
||||
RegsIn.b.ah = 0x02;
|
||||
RegsIn.b.al = NumberOfSectorsToRead;
|
||||
RegsIn.b.ch = (PhysicalTrack & 0xFF);
|
||||
RegsIn.b.cl = (PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
|
||||
RegsIn.b.dh = PhysicalHead;
|
||||
RegsIn.b.dl = DriveNumber;
|
||||
RegsIn.w.es = ((ULONG_PTR)Buffer) >> 4;
|
||||
RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
|
||||
|
||||
//
|
||||
// Perform the read
|
||||
// Retry 3 times
|
||||
//
|
||||
for (RetryCount=0; RetryCount<3; RetryCount++)
|
||||
{
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
// If it worked break out
|
||||
if (INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
break;
|
||||
}
|
||||
// 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
|
||||
else
|
||||
{
|
||||
PcDiskResetController(DriveNumber);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we retried 3 times then fail
|
||||
if (RetryCount >= 3)
|
||||
{
|
||||
DiskError("Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.b.ah);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 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
|
||||
// on the carry flag being set on error
|
||||
|
||||
Buffer = (PVOID)((ULONG_PTR)Buffer + (NumberOfSectorsToRead * DriveGeometry.BytesPerSector));
|
||||
SectorCount -= NumberOfSectorsToRead;
|
||||
SectorNumber += NumberOfSectorsToRead;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN PcDiskInt13ExtensionsSupported(ULONG DriveNumber)
|
||||
{
|
||||
static ULONG LastDriveNumber = 0xffffffff;
|
||||
static BOOLEAN LastSupported;
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"));
|
||||
|
||||
if (DriveNumber == LastDriveNumber)
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "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 >= 0x90. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
|
||||
if (DriveNumber >= 0x90)
|
||||
{
|
||||
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
|
||||
printf("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(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
|
||||
{
|
||||
|
||||
DbgPrint((DPRINT_DISK, "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
|
||||
//
|
||||
if ((DriveNumber >= 0x80) && PcDiskInt13ExtensionsSupported(DriveNumber))
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. PcDiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, PcDiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
|
||||
|
||||
//
|
||||
// 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
|
||||
return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
PcDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY Geometry)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
ULONG Cylinders;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskGetDriveGeometry()\n"));
|
||||
|
||||
/* 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))
|
||||
{
|
||||
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(ULONG DriveNumber)
|
||||
{
|
||||
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))
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
/* Get the disk geometry
|
||||
* If this fails then we will just return 1 sector to be safe */
|
||||
else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Geometry.Sectors;
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,249 +0,0 @@
|
|||
/* $Id: pcmem.c 24238 2006-09-23 16:50:39Z fireball $
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Note: Most of this code comes from the old file "i386mem.c", which
|
||||
* was Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static ULONG
|
||||
PcMemGetExtendedMemorySize(VOID)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
ULONG MemorySize;
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "GetExtendedMemorySize()\n"));
|
||||
|
||||
/* Int 15h AX=E801h
|
||||
* Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
|
||||
*
|
||||
* AX = E801h
|
||||
* Return:
|
||||
* CF clear if successful
|
||||
* AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
|
||||
* BX = extended memory above 16M, in 64K blocks
|
||||
* CX = configured memory 1M to 16M, in K
|
||||
* DX = configured memory above 16M, in 64K blocks
|
||||
* CF set on error
|
||||
*/
|
||||
RegsIn.w.ax = 0xE801;
|
||||
Int386(0x15, &RegsIn, &RegsOut);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h AX=E801h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
|
||||
DbgPrint((DPRINT_MEMORY, "BX = 0x%x\n", RegsOut.w.bx));
|
||||
DbgPrint((DPRINT_MEMORY, "CX = 0x%x\n", RegsOut.w.cx));
|
||||
DbgPrint((DPRINT_MEMORY, "DX = 0x%x\n", RegsOut.w.dx));
|
||||
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
|
||||
|
||||
if (INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
/* If AX=BX=0000h the use CX and DX */
|
||||
if (RegsOut.w.ax == 0)
|
||||
{
|
||||
/* Return extended memory size in K */
|
||||
MemorySize = RegsOut.w.dx * 64;
|
||||
MemorySize += RegsOut.w.cx;
|
||||
return MemorySize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return extended memory size in K */
|
||||
MemorySize = RegsOut.w.bx * 64;
|
||||
MemorySize += RegsOut.w.ax;
|
||||
return MemorySize;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we get here then Int15 Func E801h didn't work */
|
||||
/* So try Int15 Func 88h */
|
||||
|
||||
/* Int 15h AH=88h
|
||||
* SYSTEM - GET EXTENDED MEMORY SIZE (286+)
|
||||
*
|
||||
* AH = 88h
|
||||
* Return:
|
||||
* CF clear if successful
|
||||
* AX = number of contiguous KB starting at absolute address 100000h
|
||||
* CF set on error
|
||||
* AH = status
|
||||
* 80h invalid command (PC,PCjr)
|
||||
* 86h unsupported function (XT,PS30)
|
||||
*/
|
||||
RegsIn.b.ah = 0x88;
|
||||
Int386(0x15, &RegsIn, &RegsOut);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h AH=88h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
|
||||
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
|
||||
|
||||
if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
|
||||
{
|
||||
MemorySize = RegsOut.w.ax;
|
||||
return MemorySize;
|
||||
}
|
||||
|
||||
/* If we get here then Int15 Func 88h didn't work */
|
||||
/* So try reading the CMOS */
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
|
||||
MemorySize = READ_PORT_UCHAR((PUCHAR)0x71);
|
||||
MemorySize = (MemorySize & 0xFFFF);
|
||||
MemorySize = (MemorySize << 8);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h Failed\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "CMOS reports: 0x%x\n", MemorySize));
|
||||
|
||||
return MemorySize;
|
||||
}
|
||||
|
||||
static ULONG
|
||||
PcMemGetConventionalMemorySize(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "GetConventionalMemorySize()\n"));
|
||||
|
||||
/* Int 12h
|
||||
* BIOS - GET MEMORY SIZE
|
||||
*
|
||||
* Return:
|
||||
* AX = kilobytes of contiguous memory starting at absolute address 00000h
|
||||
*
|
||||
* This call returns the contents of the word at 0040h:0013h;
|
||||
* in PC and XT, this value is set from the switches on the motherboard
|
||||
*/
|
||||
Regs.w.ax = 0;
|
||||
Int386(0x12, &Regs, &Regs);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int12h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n\n", Regs.w.ax));
|
||||
|
||||
return (ULONG)Regs.w.ax;
|
||||
}
|
||||
|
||||
static ULONG
|
||||
PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
|
||||
{
|
||||
REGS Regs;
|
||||
ULONG MapCount;
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "GetBiosMemoryMap()\n"));
|
||||
|
||||
/* Int 15h AX=E820h
|
||||
* Newer BIOSes - GET SYSTEM MEMORY MAP
|
||||
*
|
||||
* AX = E820h
|
||||
* EAX = 0000E820h
|
||||
* EDX = 534D4150h ('SMAP')
|
||||
* EBX = continuation value or 00000000h to start at beginning of map
|
||||
* ECX = size of buffer for result, in bytes (should be >= 20 bytes)
|
||||
* ES:DI -> buffer for result
|
||||
* Return:
|
||||
* CF clear if successful
|
||||
* EAX = 534D4150h ('SMAP')
|
||||
* ES:DI buffer filled
|
||||
* EBX = next offset from which to copy or 00000000h if all done
|
||||
* ECX = actual length returned in bytes
|
||||
* CF set on error
|
||||
* AH = error code (86h)
|
||||
*/
|
||||
Regs.x.eax = 0x0000E820;
|
||||
Regs.x.edx = 0x534D4150; /* ('SMAP') */
|
||||
Regs.x.ebx = 0x00000000;
|
||||
Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
|
||||
Regs.w.es = BIOSCALLBUFSEGMENT;
|
||||
Regs.w.di = BIOSCALLBUFOFFSET;
|
||||
for (MapCount = 0; MapCount < MaxMemoryMapSize; MapCount++)
|
||||
{
|
||||
Int386(0x15, &Regs, &Regs);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Memory Map Entry %d\n", MapCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h AX=E820h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "EAX = 0x%x\n", Regs.x.eax));
|
||||
DbgPrint((DPRINT_MEMORY, "EBX = 0x%x\n", Regs.x.ebx));
|
||||
DbgPrint((DPRINT_MEMORY, "ECX = 0x%x\n", Regs.x.ecx));
|
||||
DbgPrint((DPRINT_MEMORY, "CF set = %s\n", (Regs.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
|
||||
|
||||
/* If the BIOS didn't return 'SMAP' in EAX then
|
||||
* it doesn't support this call */
|
||||
if (Regs.x.eax != 0x534D4150)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy data to caller's buffer */
|
||||
RtlCopyMemory(&BiosMemoryMap[MapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "BaseAddress: 0x%p\n", (PVOID)BiosMemoryMap[MapCount].BaseAddress));
|
||||
DbgPrint((DPRINT_MEMORY, "Length: 0x%p\n", (PVOID)BiosMemoryMap[MapCount].Length));
|
||||
DbgPrint((DPRINT_MEMORY, "Type: 0x%x\n", BiosMemoryMap[MapCount].Type));
|
||||
DbgPrint((DPRINT_MEMORY, "Reserved: 0x%x\n", BiosMemoryMap[MapCount].Reserved));
|
||||
DbgPrint((DPRINT_MEMORY, "\n"));
|
||||
|
||||
/* If the continuation value is zero or the
|
||||
* carry flag is set then this was
|
||||
* the last entry so we're done */
|
||||
if (Regs.x.ebx == 0x00000000 || !INT386_SUCCESS(Regs))
|
||||
{
|
||||
MapCount++;
|
||||
DbgPrint((DPRINT_MEMORY, "End Of System Memory Map!\n\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Setup the registers for the next call */
|
||||
Regs.x.eax = 0x0000E820;
|
||||
Regs.x.edx = 0x534D4150; /* ('SMAP') */
|
||||
/* Regs.x.ebx = 0x00000001; Continuation value already set by the BIOS */
|
||||
Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
|
||||
Regs.w.es = BIOSCALLBUFSEGMENT;
|
||||
Regs.w.di = BIOSCALLBUFOFFSET;
|
||||
}
|
||||
|
||||
return MapCount;
|
||||
}
|
||||
|
||||
ULONG
|
||||
PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
|
||||
{
|
||||
ULONG EntryCount;
|
||||
|
||||
EntryCount = PcMemGetBiosMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
|
||||
|
||||
/* If the BIOS didn't provide a memory map, synthesize one */
|
||||
if (0 == EntryCount && 2 <= MaxMemoryMapSize)
|
||||
{
|
||||
/* Conventional memory */
|
||||
BiosMemoryMap[0].BaseAddress = 0;
|
||||
BiosMemoryMap[0].Length = PcMemGetConventionalMemorySize() * 1024;
|
||||
BiosMemoryMap[0].Type = BiosMemoryUsable;
|
||||
/* Extended memory */
|
||||
BiosMemoryMap[1].BaseAddress = 1024 * 1024;
|
||||
BiosMemoryMap[1].Length = PcMemGetExtendedMemorySize() * 1024;
|
||||
BiosMemoryMap[1].Type = BiosMemoryUsable;
|
||||
EntryCount = 2;
|
||||
}
|
||||
|
||||
return EntryCount;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,5 +0,0 @@
|
|||
/* No need to duplicate code ; import the i386 version */
|
||||
|
||||
#include "../i386/pcrtc.c"
|
||||
|
||||
/* EOF */
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue