static CALLBACK16 __BiosContext;
PBIOS_DATA_AREA Bda;
+PBIOS_CONFIG_TABLE Bct;
/* PRIVATE FUNCTIONS **********************************************************/
/* Disable interrupts */
setIF(0);
- /* Initialize the BDA pointer */
- Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
+ /* Initialize the BDA and the BCT pointers */
+ Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0x0000);
+ // The BCT is found at F000:E6F5 for 100% compatible BIOSes.
+ Bct = (PBIOS_CONFIG_TABLE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE6F5);
/* Register the BIOS support BOPs */
RegisterBop(BOP_BIOSINIT , BiosInitBop);
#define BIOS_EQUIPMENT_LIST 0x2C // HACK: Disable FPU for now
+#pragma pack(push, 1)
+
/*
* BIOS Data Area at 0040:XXXX
*
* and: http://www.bioscentral.com/misc/bda.htm
* for more information.
*/
-#pragma pack(push, 1)
typedef struct
{
WORD SerialPorts[4]; // 0x00
BYTE Reserved17[15]; // 0x121
BYTE Reserved18[3]; // 0x130
} BIOS_DATA_AREA, *PBIOS_DATA_AREA;
-#pragma pack(pop)
-
C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
+/*
+ * BIOS Configuration Table at F000:E6F5 for 100% compatible BIOSes.
+ *
+ * See: http://www.ctyme.com/intr/rb-1594.htm
+ * for more information.
+ */
+typedef struct _BIOS_CONFIG_TABLE
+{
+ WORD Length; // 0x00
+ BYTE Model; // 0x02
+ BYTE SubModel; // 0x03
+ BYTE BiosRevision; // 0x04
+ BYTE BiosFeature[5]; // 0x05 -- 0x09
+ // Other BIOSes may extend this table. We don't.
+} BIOS_CONFIG_TABLE, *PBIOS_CONFIG_TABLE;
+
+#pragma pack(pop)
+
/* FUNCTIONS ******************************************************************/
extern PBIOS_DATA_AREA Bda;
+extern PBIOS_CONFIG_TABLE Bct;
VOID WINAPI BiosEquipmentService(LPWORD Stack);
VOID WINAPI BiosGetMemorySize(LPWORD Stack);
break;
}
+ /* Get Configuration */
+ case 0xC0:
+ {
+ /* Return the BIOS ROM Configuration Table address in ES:BX */
+ setES(HIWORD(Bct));
+ setBX(LOWORD(Bct));
+
+ /* Call successful; clear CF */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+
+ break;
+ }
+
default:
{
DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n",
((PULONG)BaseAddress)[0x49] = (ULONG)NULL;
}
+static VOID InitializeBiosInfo(VOID)
+{
+ Bct->Length = sizeof(*Bct);
+ Bct->Model = 0xFC; // PC-AT; see http://www.ctyme.com/intr/rb-1594.htm#Table515
+ Bct->SubModel = 0x00;
+ Bct->BiosRevision = 0x01;
+ Bct->BiosFeature[0] = 0x64; // At the moment we don't support "INT 15/AH=4Fh called upon INT 09h" nor "wait for external event (INT 15/AH=41h) supported"; see http://www.ctyme.com/intr/rb-1594.htm#Table510
+ Bct->BiosFeature[1] = 0x00; // We don't support anything from here; see http://www.ctyme.com/intr/rb-1594.htm#Table511
+ Bct->BiosFeature[2] = 0x00;
+ Bct->BiosFeature[3] = 0x00;
+ Bct->BiosFeature[4] = 0x00;
+}
+
+static VOID InitializeBiosData(VOID)
+{
+ UCHAR Low, High;
+
+ /* Initialize the BDA contents */
+ Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
+
+ /*
+ * Retrieve the conventional memory size
+ * in kB from CMOS, typically 640 kB.
+ */
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
+ Low = IOReadB(CMOS_DATA_PORT);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
+ High = IOReadB(CMOS_DATA_PORT);
+ Bda->MemorySize = MAKEWORD(Low, High);
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*
BOOLEAN Bios32Initialize(VOID)
{
BOOLEAN Success;
- UCHAR Low, High;
/* Initialize the stack */
// That's what says IBM... (stack at 30:00FF going downwards)
/* Set data segment */
setDS(BDA_SEGMENT);
- /* Initialize the BDA contents */
- Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
-
- /*
- * Retrieve the conventional memory size
- * in kB from CMOS, typically 640 kB.
- */
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
- Low = IOReadB(CMOS_DATA_PORT);
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
- High = IOReadB(CMOS_DATA_PORT);
- Bda->MemorySize = MAKEWORD(Low, High);
+ /* Initialize the BDA and the BIOS ROM Information */
+ InitializeBiosData();
+ InitializeBiosInfo();
/* Register the BIOS 32-bit Interrupts */
InitializeBiosInt32();