Author: hbelusca
Date: Tue Aug 4 20:17:05 2015
New Revision: 68598
URL:
http://svn.reactos.org/svn/reactos?rev=68598&view=rev
Log:
[NTVDM]
- Add some level of "Advanced debugging" (see ntvdm.h) which one can adjust to
enable/disable debugging features inside NTVDM (this can be useful as long as NTVDM is
under heavy bugfixing. When it will be more perfect, this stuff will be removed).
- Add the possibility to load option ROMs at a given segment. Currently their list should
be specified from inside ntvdm.c (in the BiosInitialize call), but I plan to make it
available from a registry option (or via command-line for NTVDM-standalone mode).
- Start to separate the initialization of "static" BIOS data (stuff that lives
in ROM space) and initialization of "dynamic" BIOS data (eg. initializing the
interrupt vector table, the BIOS data area at segment 40h, ...) so that we may be able to
reuse part of our code to be able to more-or-less run external (16-bit) BIOSes, or the
Windows NTVDM BIOS that uses BOPs to run some of its stuff in ntvdm in 32-bit (as we do
for our 32-bit BIOS, except that *all* of our bios is 32-bit, not just some parts). Also,
some file reorganization will be in order there soon...
- Add video BIOS version information in memory so that tools such as Microsoft Diagnostics
can correctly recognize our video BIOS (btw, we try to emulate the functionality of
Cirrus' CL-GD5434).
- Correctly put video BIOS ROM header (+ checksum) in memory so that it is recognized as
such by diagnostics tools.
- During BIOS POST, scan for ROMs starting segment 0xC000 (where video ROMs reside).
- Store statically the BIOS configuration table.
- Fix INT 16h, AH=12h "Get extended shift states" so that it correctly returns
the state of right Ctrl and Alt keys.
- Fix bit-setting state; report that our keyboard is 101/102 enhanced keyboard.
- Correctly set the error return values (AH=86h and CF set) when a function of INT 15h is
unsupported.
- Implement INT 15h, AH=C9h "Get CPU Type and Mask Revision"; INT 1Ah, AH=02h
"Get Real-Time Clock Time" and Ah=04h "Get Real-Time Clock Date" by
reading the CMOS.
- Implement CMOS century register support.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.h
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.h
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/vidbios32.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/kbdbios.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.h
trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h
trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c
trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.h
trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.c
trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.h
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.c [iso-8859-1] Tue Aug 4 20:17:05 2015
@@ -23,12 +23,13 @@
#include "io.h"
#include "hardware/cmos.h"
+#include <stdlib.h>
+
/* DEFINES ********************************************************************/
/* BOP Identifiers */
#define BOP_RESET 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
- // to let the virtual machine initialize itself
- // the IVT and its hardware.
+ // to let the virtual machine perform the POST.
#define BOP_EQUIPLIST 0x11
#define BOP_GETMEMSIZE 0x12
@@ -43,94 +44,95 @@
/* PUBLIC FUNCTIONS ***********************************************************/
-VOID WINAPI BiosEquipmentService(LPWORD Stack)
+VOID WINAPI
+WinNtVdmBiosReset(LPWORD Stack)
{
- /* Return the equipment list */
- setAX(Bda->EquipmentList);
-}
+ DisplayMessage(L"You are loading Windows NTVDM BIOS!\n");
+ // Bios32Post(Stack);
-VOID WINAPI BiosGetMemorySize(LPWORD Stack)
-{
- /* Return the conventional memory size in kB, typically 640 kB */
- setAX(Bda->MemorySize);
+ DisplayMessage(L"ReactOS NTVDM doesn't support Windows NTVDM BIOS at the
moment. The VDM will shut down.");
+ EmulatorTerminate();
}
BOOLEAN
-BiosInitialize(IN LPCSTR BiosFileName)
+BiosInitialize(IN LPCSTR BiosFileName,
+ IN LPCSTR RomFiles OPTIONAL)
{
BOOLEAN Success = FALSE;
+ BOOLEAN Success2 = FALSE;
+ LPCSTR RomFile;
+ LPSTR ptr;
+ ULONG RomAddress;
+ CHAR RomFileName[MAX_PATH + 10 + 1];
/* Disable interrupts */
setIF(0);
/* Initialize the BDA and the BCT pointers */
- Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0x0000);
+ 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);
- /**** HACK! HACK! for Windows NTVDM BIOS ****/
- // WinNtVdmBiosSupportInitialize();
+ /* Register the BIOS support BOPs */
+ RegisterBop(BOP_RESET, WinNtVdmBiosReset); // Needed for Windows NTVDM
(SoftPC) BIOS.
+ RegisterBop(BOP_EQUIPLIST , BiosEquipmentService); // Needed by Windows NTVDM
(SoftPC) BIOS
+ RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize); // and also NTDOS!!
- // /* Register the BIOS support BOPs */
- // RegisterBop(BOP_EQUIPLIST , BiosEquipmentService);
- // RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize);
-
- if (BiosFileName && BiosFileName[0] != '\0')
+ if (BiosFileName == NULL)
+ {
+ Success = Bios32Loaded = Bios32Initialize();
+ }
+ else if (BiosFileName[0] != '\0')
{
PVOID BiosLocation = NULL;
- DWORD BiosSize = 0;
- Success = LoadBios(BiosFileName, &BiosLocation, &BiosSize);
- DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
-
- if (!Success) return FALSE;
-
- DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x
0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"
- L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
- BiosLocation,
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
-
- (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1),
- *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0));
-
- DisplayMessage(L"POST at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
- TO_LINEAR(getCS(), getIP()),
- *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 0),
- *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 1),
- *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 2),
- *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 3),
- *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 4));
-
- /* Boot it up */
-
- /*
- * The CPU is already in reset-mode so that
- * CS:IP points to F000:FFF0 as required.
- */
- DisplayMessage(L"CS=0x%p ; IP=0x%p", getCS(), getIP());
- // setCS(0xF000);
- // setIP(0xFFF0);
-
+ Success = LoadBios(BiosFileName, &BiosLocation, NULL);
+ DPRINT1("BIOS file '%s' loading %s at address 0x%08x; GetLastError()
= %u\n",
+ BiosFileName, Success ? "succeeded" : "failed",
BiosLocation, GetLastError());
+ }
+ else // if (BiosFileName[0] == '\0')
+ {
+ /* Do nothing */
Success = TRUE;
}
- else
+
+ /* Bail out now if we failed to load any BIOS file */
+ if (!Success) return FALSE;
+
+ /* Load optional ROMs */
+ if (RomFiles)
{
- WriteProtectRom((PVOID)ROM_AREA_START,
- ROM_AREA_END - ROM_AREA_START + 1);
+ RomFile = RomFiles;
+ while (*RomFile)
+ {
+ strncpy(RomFileName, RomFile, ARRAYSIZE(RomFileName));
+ RomFileName[ARRAYSIZE(RomFileName)-1] = '\0';
- Success = Bios32Loaded = Bios32Initialize();
+ ptr = strchr(RomFileName, '|'); // Since '|' is forbidden as
a valid file name, we use it as a separator for the ROM address.
+ if (!ptr) goto Skip;
+ *ptr++ = '\0';
+
+ RomAddress = strtoul(ptr, NULL, 0); // ROM segment
+ RomAddress <<= 4; // Convert to real address
+ if (RomAddress == 0) goto Skip;
+
+ Success2 = LoadRom(RomFileName, (PVOID)RomAddress, NULL);
+ DPRINT1("ROM file '%s' loading %s at address 0x%08x;
GetLastError() = %u\n",
+ RomFileName, Success2 ? "succeeded" : "failed",
RomAddress, GetLastError());
+
+Skip:
+ RomFile += strlen(RomFile) + 1;
+ }
}
+
+ /*
+ * Boot it up.
+ * The CPU is already in reset-mode so that
+ * CS:IP points to F000:FFF0 as required.
+ */
+ // DisplayMessage(L"CS:IP=%04X:%04X", getCS(), getIP());
+ // setCS(0xF000);
+ // setIP(0xFFF0);
// /* Enable interrupts */
// setIF(1);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h [iso-8859-1] Tue Aug 4 20:17:05 2015
@@ -18,8 +18,7 @@
/* BOP Identifiers */
#define BOP_RESET 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
- // to let the virtual machine initialize itself
- // the IVT and its hardware.
+ // to let the virtual machine perform the POST.
#define BOP_EQUIPLIST 0x11
#define BOP_GETMEMSIZE 0x12
@@ -29,10 +28,6 @@
#define BDA_SEGMENT 0x40
#define BIOS_SEGMENT 0xF000
-// HACK: Disable FPU for now because it is not fully ready yet for being used
-// by all applications (e.g. QBasic runtime would use the native FPU if the bit
-// is set, but then subsequently fails, unless the FPU bit is unset in that case
-// QBasic uses its emulated FPU).
#define BIOS_EQUIPMENT_LIST 0x2E // Bit1: FPU, Bit 2: Mouse
#pragma pack(push, 1)
@@ -104,7 +99,8 @@
BYTE Reserved5[2]; // 0x90
BYTE Reserved6[2]; // 0x92
BYTE Reserved7[2]; // 0x94
- WORD KeybdStatusFlags; // 0x96
+ BYTE KeybdStatusFlags; // 0x96
+ BYTE KeybdLedFlags; // 0x97
DWORD Reserved9; // 0x98
DWORD Reserved10; // 0x9c
DWORD Reserved11[2]; // 0xa0
@@ -165,7 +161,8 @@
VOID WINAPI BiosGetMemorySize(LPWORD Stack);
BOOLEAN
-BiosInitialize(IN LPCSTR BiosFileName);
+BiosInitialize(IN LPCSTR BiosFileName,
+ IN LPCSTR RomFiles OPTIONAL);
VOID
BiosCleanup(VOID);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] Tue Aug 4
20:17:05 2015
@@ -10,8 +10,9 @@
#define NDEBUG
-/* For BIOS Version number */
+/* BIOS Version number and Copyright */
#include <reactos/buildno.h>
+#include <reactos/version.h>
#include "ntvdm.h"
#include "emulator.h"
@@ -106,19 +107,39 @@
#define BIOS_REVISION 0x00
// FIXME: Find a nice PS/2 486 + 487 BIOS combination!
+static const BIOS_CONFIG_TABLE BiosConfigTable =
+{
+ sizeof(BIOS_CONFIG_TABLE), // Length
+
+ BIOS_MODEL, // BIOS Model
+ BIOS_SUBMODEL, // BIOS Sub-Model
+ BIOS_REVISION, // BIOS Revision
+
+ // Feature bytes
+ {
+ 0x78, // At the moment we don't have any Extended BIOS Area; see
http://www.ctyme.com/intr/rb-1594.htm#Table510
+ 0x00, // We don't support anything from here; see
http://www.ctyme.com/intr/rb-1594.htm#Table511
+ 0x10, // Bit 4: POST supports ROM-to-RAM enable/disable
+ 0x00,
+ 0x00
+ }
+};
+
+
/*
* WARNING! For compatibility purposes the string "IBM" should be at F000:E00E
.
- * Some programs alternatively look at "COPR. IBM" that is at F000:E008 .
+ * Some programs otherwise look for "COPR. IBM" at F000:E008 .
*/
-static const CHAR BiosCopyright[] = "0000000 NTVDM IBM Compatible 486 32-bit BIOS
Copyright (C) ReactOS Team 1996-2014";
-static const CHAR BiosVersion[] = "ReactOS NTVDM 32-bit BIOS
"KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")";
+static const CHAR BiosCopyright[] = "0000000 NTVDM IBM COMPATIBLE 486 BIOS COPYRIGHT
(C) ReactOS Team 1996-"COPYRIGHT_YEAR;
+static const CHAR BiosVersion[] = "ReactOS NTVDM 32-bit BIOS Version
"KERNEL_VERSION_STR"\0"
+ "BIOS32 Version "KERNEL_VERSION_STR"
(Build "KERNEL_VERSION_BUILD_STR")";
static const CHAR BiosDate[] = "06/17/13";
C_ASSERT(sizeof(BiosCopyright)-1 <= 0x5B); // Ensures that we won't overflow on
the POST Code starting at F000:E05B
C_ASSERT(sizeof(BiosDate)-1 == 0x08);
/* 16-bit bootstrap code at F000:FFF0 */
-static BYTE Bootstrap[] =
+static const BYTE Bootstrap[] =
{
0xEA, // jmp far ptr
0x5B, 0xE0, 0x00, 0xF0, // F000:E05B
@@ -128,7 +149,7 @@
* POST code at F000:E05B. All the POST is done in 32 bit
* and only at the end it calls the bootstrap interrupt.
*/
-static BYTE PostCode[] =
+static const BYTE PostCode[] =
{
LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_RESET, // Call BIOS POST
0xCD, BIOS_BOOTSTRAP_LOADER, // INT 0x19
@@ -143,6 +164,18 @@
/* Get the exception number and call the emulator API */
BYTE ExceptionNumber = LOBYTE(Stack[STACK_INT_NUM]);
EmulatorException(ExceptionNumber, Stack);
+}
+
+VOID WINAPI BiosEquipmentService(LPWORD Stack)
+{
+ /* Return the equipment list */
+ setAX(Bda->EquipmentList);
+}
+
+VOID WINAPI BiosGetMemorySize(LPWORD Stack)
+{
+ /* Return the conventional memory size in kB, typically 640 kB */
+ setAX(Bda->MemorySize);
}
static VOID WINAPI BiosMiscService(LPWORD Stack)
@@ -162,7 +195,7 @@
break;
}
- /* Wait On External Event */
+ /* Wait on External Event */
case 0x41:
{
BYTE Value;
@@ -242,7 +275,6 @@
/* Repeat the BOP if we shouldn't return */
setCF(!Return);
-
break;
}
@@ -272,7 +304,6 @@
/* Clear CF */
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
-
break;
}
@@ -325,7 +356,6 @@
/* Clear CF */
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
-
break;
}
@@ -335,7 +365,7 @@
DPRINT1("BIOS INT 15h, AH=89h \"Switch to Protected Mode\" is
UNIMPLEMENTED");
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- break;
+ goto Default;
}
/* Get Configuration */
@@ -349,28 +379,44 @@
/* Call successful; clear CF */
setAH(0x00);
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
-
break;
}
/* Return Extended-Bios Data-Area Segment Address (PS) */
case 0xC1:
{
- // Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- // setES(???);
-
+ /* We do not support EBDA yet */
UNIMPLEMENTED;
-
- /* We do not support EBDA yet */
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
-
- break;
+ goto Default;
}
/* Pointing Device BIOS Interface (PS) */
case 0xC2:
{
BiosMousePs2Interface(Stack);
+ UNIMPLEMENTED; // Remove it when BiosMousePs2Interface is implemented!
+ goto Default;
+ }
+
+ /* Get CPU Type and Mask Revision */
+ case 0xC9:
+ {
+ /*
+ * We can see this function as a CPUID replacement.
+ * See Ralf Brown:
http://www.ctyme.com/intr/rb-1613.htm
+ * for more information.
+ */
+
+ /*
+ * Fast486 is a 486DX with FPU included,
+ * but old enough to not support CPUID.
+ */
+ setCX(0x0400);
+
+ /* Call successful; clear CF */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
break;
}
@@ -437,10 +483,19 @@
break;
}
- default:
+ default: Default:
{
DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n",
getAH());
+
+ /*
+ * The original signification of the error code 0x86 is that
+ * no PC Cassette is present. The CF is also set in this case.
+ * To keep backward compatibility, newer BIOSes use this value
+ * to indicate an unimplemented call in INT 15h.
+ */
+ setAH(0x86);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
}
}
}
@@ -490,6 +545,7 @@
{
switch (getAH())
{
+ /* Get System Time */
case 0x00:
{
/* Set AL to 1 if midnight had passed, 0 otherwise */
@@ -505,6 +561,7 @@
break;
}
+ /* Set System Time */
case 0x01:
{
/* Set the tick count to CX:DX */
@@ -515,6 +572,62 @@
break;
}
+
+ /* Get Real-Time Clock Time */
+ case 0x02:
+ {
+ UCHAR StatusB;
+
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_HOURS);
+ setCH(IOReadB(CMOS_DATA_PORT));
+
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_MINUTES);
+ setCL(IOReadB(CMOS_DATA_PORT));
+
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_SECONDS);
+ setDH(IOReadB(CMOS_DATA_PORT));
+
+ /* Daylight Savings Time */
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_STATUS_B);
+ StatusB = IOReadB(CMOS_DATA_PORT);
+ setDL(StatusB & 0x01);
+
+ /* Clear CF */
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ // /* Set Real-Time Clock Time */
+ // case 0x03:
+ // {
+ // break;
+ // }
+
+ /* Get Real-Time Clock Date */
+ case 0x04:
+ {
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_CENTURY);
+ setCH(IOReadB(CMOS_DATA_PORT));
+
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_YEAR);
+ setCL(IOReadB(CMOS_DATA_PORT));
+
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_MONTH);
+ setDH(IOReadB(CMOS_DATA_PORT));
+
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_DAY);
+ setDL(IOReadB(CMOS_DATA_PORT));
+
+ /* Clear CF */
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ // /* Set Real-Time Clock Date */
+ // case 0x05:
+ // {
+ // break;
+ // }
default:
{
@@ -675,7 +788,7 @@
/* Zero out all of the IVT (0x00 -- 0xFF) */
RtlZeroMemory(BaseAddress, 0x0100 * sizeof(ULONG));
-#ifdef ADVANCED_DEBUGGING
+#if defined(ADVANCED_DEBUGGING) && (ADVANCED_DEBUGGING_LEVEL >= 3)
// Initialize all the interrupt vectors to the default one.
for (i = 0x00; i <= 0xFF; i++)
RegisterBiosInt32(i, NULL);
@@ -756,35 +869,20 @@
Bda->MemorySize = MAKEWORD(Low, High);
}
-static VOID InitializeBiosInfo(VOID)
-{
- RtlZeroMemory(Bct, sizeof(*Bct));
-
- Bct->Length = sizeof(*Bct);
- Bct->Model = BIOS_MODEL;
- Bct->SubModel = BIOS_SUBMODEL;
- Bct->Revision = BIOS_REVISION;
- Bct->Feature[0] = 0x70; // At the moment we don't support "wait for
external event (INT 15/AH=41h)", we also don't have any "extended BIOS area
allocated (usually at top of RAM)"; see
http://www.ctyme.com/intr/rb-1594.htm#Table510
- Bct->Feature[1] = 0x00; // We don't support anything from here; see
http://www.ctyme.com/intr/rb-1594.htm#Table511
- Bct->Feature[2] = 0x00;
- Bct->Feature[3] = 0x00;
- Bct->Feature[4] = 0x00;
-}
-
-
/*
* The BIOS POST (Power On-Self Test)
*/
-static VOID
+/*static*/ VOID
WINAPI
Bios32Post(LPWORD Stack)
{
static BOOLEAN FirstBoot = TRUE;
-#if 0
- BOOLEAN Success;
-#endif
BYTE ShutdownStatus;
+
+ /*
+ * Initialize BIOS/Keyboard/Video RAM dynamic data
+ */
DPRINT("Bios32Post\n");
@@ -879,7 +977,6 @@
* - if the word is 0000h, perform a cold reboot (aka. Reset). Everything gets
initialized.
* - if the word is 1234h, perform a warm reboot (aka. Ctrl-Alt-Del). Some stuff is
skipped.
*/
-
switch (Bda->SoftReset)
{
case 0x0000:
@@ -906,17 +1003,22 @@
FirstBoot = FALSE;
- /* Initialize the BDA and the BIOS ROM Information */
+ /* Initialize the BDA */
InitializeBiosData();
- InitializeBiosInfo();
/* Initialize the User Data Area at 0050:XXXX */
RtlZeroMemory(SEG_OFF_TO_PTR(0x50, 0x0000), sizeof(USER_DATA_AREA));
+
+
+
+ //////// NOTE: This is more or less bios-specific ////////
/*
* Initialize IVT and hardware
*/
+ // WriteUnProtectRom(...);
+
/* Register the BIOS 32-bit Interrupts */
InitializeBiosInt32();
@@ -924,30 +1026,15 @@
BiosHwSetup();
/* Initialize the Keyboard, Video and Mouse BIOS */
- if (!KbdBios32Initialize() || !VidBios32Initialize() || !MouseBios32Initialize())
- {
- /* Stop the VDM */
- EmulatorTerminate();
- return;
- }
-
-#if 0
- /* Initialize the Keyboard and Video BIOS */
- if (!KbdBiosInitialize() || !VidBiosInitialize())
- {
- /* Stop the VDM */
- EmulatorTerminate();
- return;
- }
-#endif
-
- ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! /////////////////////
-
-#if 0
- /* Load some ROMs */
- Success = LoadRom("boot.bin", (PVOID)0xE0000, NULL);
- DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
-#endif
+ KbdBios32Post();
+ VidBiosPost();
+ MouseBios32Post();
+
+ // WriteProtectRom(...);
+
+ //////// End of more or less bios-specific section ///////
+
+
SearchAndInitRoms(&BiosContext);
@@ -968,29 +1055,42 @@
BOOLEAN Bios32Initialize(VOID)
{
/*
- * Initialize BIOS32 static data
+ * Initialize BIOS/Keyboard/Video ROM static data
*/
+ /* System BIOS Copyright */
+ RtlCopyMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE000), BiosCopyright,
sizeof(BiosCopyright)-1);
+
+ /* System BIOS Version */
+ RtlCopyMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE070), BiosVersion,
sizeof(BiosVersion)-1);
+
+ /* System BIOS Date */
+ RtlCopyMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xFFF5), BiosDate, sizeof(BiosDate)-1);
+
/* Bootstrap code */
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE05B), PostCode , sizeof(PostCode ));
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xFFF0), Bootstrap, sizeof(Bootstrap));
-
- /* System BIOS Copyright */
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE000), BiosCopyright,
sizeof(BiosCopyright)-1);
-
- /* System BIOS Version */
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE080), BiosVersion, sizeof(BiosVersion)-1);
- // FIXME: or E061, or E100 ??
-
- /* System BIOS Date */
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xFFF5), BiosDate, sizeof(BiosDate)-1);
+ RtlCopyMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE05B), PostCode , sizeof(PostCode ));
+ RtlCopyMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xFFF0), Bootstrap, sizeof(Bootstrap));
+
+ /* BIOS ROM Information */
+ RtlCopyMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE6F5), &BiosConfigTable,
sizeof(BiosConfigTable));
/* System BIOS Model (same as Bct->Model) */
- *(PBYTE)(SEG_OFF_TO_PTR(0xF000, 0xFFFE)) = BIOS_MODEL;
+ *(PBYTE)(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xFFFE)) = BIOS_MODEL;
+
+ /* Initialize the Keyboard and Video BIOS */
+ if (!KbdBiosInitialize() || !VidBiosInitialize() || !MouseBiosInitialize())
+ {
+ /* Stop the VDM */
+ EmulatorTerminate();
+ return FALSE;
+ }
/* Redefine our POST function */
RegisterBop(BOP_RESET, Bios32Post);
+ WriteProtectRom((PVOID)TO_LINEAR(BIOS_SEGMENT, 0x0000),
+ ROM_AREA_END - TO_LINEAR(BIOS_SEGMENT, 0x0000) + 1);
+
/* We are done */
return TRUE;
}
@@ -999,7 +1099,7 @@
{
MouseBios32Cleanup();
VidBios32Cleanup();
- KbdBios32Cleanup();
+ KbdBiosCleanup();
}
/* EOF */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c [iso-8859-1] Tue Aug 4
20:17:05 2015
@@ -80,7 +80,8 @@
return TRUE;
}
-static VOID WINAPI BiosKeyboardService(LPWORD Stack)
+/* static */
+VOID WINAPI BiosKeyboardService(LPWORD Stack)
{
switch (getAH())
{
@@ -168,11 +169,16 @@
case 0x12:
{
/*
- * Be careful! The returned word is similar to Bda->KeybdShiftFlags
+ * Be careful! The returned word is similar to
'Bda->KeybdShiftFlags'
* but the high byte is organized differently:
- * the bytes 2 and 3 of the high byte are not the same...
+ * the bits 2 and 3 of the high byte are not the same:
+ * instead they correspond to the right CTRL and ALT keys as specified
+ * in bits 2 and 3 of LOBYTE(Bda->KeybdStatusFlags).
*/
- WORD KeybdShiftFlags = (Bda->KeybdShiftFlags & 0xF3FF);
+ // Bda->KeybdShiftFlags & 0xF3FF;
+ WORD KeybdShiftFlags = MAKEWORD(LOBYTE(Bda->KeybdShiftFlags),
+ (HIBYTE(Bda->KeybdShiftFlags ) &
0xF3) |
+ (LOBYTE(Bda->KeybdStatusFlags) &
0x0C));
/* Return the extended keyboard shift status word */
setAX(KeybdShiftFlags);
@@ -188,7 +194,8 @@
}
// Keyboard IRQ 1
-static VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
+/* static */
+VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
{
static BOOLEAN Extended = FALSE;
BOOLEAN SkipScanCode;
@@ -222,8 +229,13 @@
if (ScanCode == 0xE0)
{
Extended = TRUE;
+ Bda->KeybdStatusFlags |= 0x02;
goto Quit;
}
+
+ // FIXME: For diagnostic purposes. We should decide what to do then!!
+ if (ScanCode == 0xE1)
+ DPRINT1("BiosKeyboardIrq, ScanCode == 0xE1\n");
/* Check whether CF is clear. If so, skip the scan code. */
if (SkipScanCode) goto Quit;
@@ -249,10 +261,12 @@
break;
}
- case VK_CONTROL:
case VK_SHIFT:
case VK_LSHIFT:
case VK_RSHIFT:
+ case VK_CONTROL:
+ case VK_RCONTROL:
+ case VK_LCONTROL:
case VK_MENU:
case VK_LMENU:
case VK_RMENU:
@@ -288,19 +302,27 @@
/* Clear the keyboard flags */
Bda->KeybdShiftFlags = 0;
+ // Release right CTRL and ALT keys
+ Bda->KeybdStatusFlags &= ~(BDA_KBDFLAG_RCTRL | BDA_KBDFLAG_RALT);
/* Set the appropriate flags based on the state */
- if (BiosKeyboardMap[VK_SHIFT] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_LSHIFT;
+ // SHIFT
if (BiosKeyboardMap[VK_RSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_RSHIFT;
if (BiosKeyboardMap[VK_LSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_LSHIFT;
+ if (BiosKeyboardMap[VK_SHIFT] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_LSHIFT;
+ // CTRL
+ if (BiosKeyboardMap[VK_RCONTROL] & (1 << 7)) Bda->KeybdStatusFlags |=
BDA_KBDFLAG_RCTRL;
+ if (BiosKeyboardMap[VK_LCONTROL] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_LCTRL;
if (BiosKeyboardMap[VK_CONTROL] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_CTRL;
+ // ALT
+ if (BiosKeyboardMap[VK_RMENU] & (1 << 7)) Bda->KeybdStatusFlags |=
BDA_KBDFLAG_RALT;
+ if (BiosKeyboardMap[VK_LMENU] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_LALT;
if (BiosKeyboardMap[VK_MENU] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_ALT;
+ // Others
if (BiosKeyboardMap[VK_SCROLL] & (1 << 0)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_SCROLL_ON;
if (BiosKeyboardMap[VK_NUMLOCK] & (1 << 0)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_NUMLOCK_ON;
if (BiosKeyboardMap[VK_CAPITAL] & (1 << 0)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_CAPSLOCK_ON;
if (BiosKeyboardMap[VK_INSERT] & (1 << 0)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_INSERT_ON;
- if (BiosKeyboardMap[VK_RMENU] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_RALT;
- if (BiosKeyboardMap[VK_LMENU] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_LALT;
if (BiosKeyboardMap[VK_SNAPSHOT] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_SYSRQ;
if (BiosKeyboardMap[VK_PAUSE] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_PAUSE;
if (BiosKeyboardMap[VK_SCROLL] & (1 << 7)) Bda->KeybdShiftFlags |=
BDA_KBDFLAG_SCROLL;
@@ -310,6 +332,8 @@
/* Clear the extended key flag */
Extended = FALSE;
+ Bda->KeybdStatusFlags &= ~0x02; // Remove the 0xE0 code flag
+ // Bda->KeybdStatusFlags &= ~0x01; // Remove the 0xE1 code flag
DPRINT("BiosKeyboardIrq - Character = 0x%X, ScanCode = 0x%X, KeybdShiftFlags =
0x%X\n",
Character, ScanCode, Bda->KeybdShiftFlags);
@@ -320,11 +344,8 @@
/* PUBLIC FUNCTIONS ***********************************************************/
-BOOLEAN KbdBios32Initialize(VOID)
-{
- /* Initialize the common Keyboard BIOS Support Library */
- if (!KbdBiosInitialize()) return FALSE;
-
+VOID KbdBios32Post(VOID)
+{
/* Initialize the BDA */
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE *
sizeof(WORD);
@@ -333,6 +354,10 @@
// FIXME: Fill the keyboard buffer with invalid values for diagnostic purposes...
RtlFillMemory(((LPVOID)((ULONG_PTR)Bda + Bda->KeybdBufferStart)),
BIOS_KBD_BUFFER_SIZE * sizeof(WORD), 'A');
+
+ Bda->KeybdShiftFlags = 0;
+ Bda->KeybdStatusFlags = (1 << 4); // 101/102 enhanced keyboard installed
+ Bda->KeybdLedFlags = 0;
/*
* Register the BIOS 32-bit Interrupts:
@@ -341,14 +366,6 @@
*/
RegisterBiosInt32(BIOS_KBD_INTERRUPT, BiosKeyboardService);
EnableHwIRQ(1, BiosKeyboardIrq);
-
- return TRUE;
-}
-
-VOID KbdBios32Cleanup(VOID)
-{
- /* Cleanup the common Keyboard BIOS Support Library */
- KbdBiosCleanup();
}
/* EOF */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.h [iso-8859-1] Tue Aug 4
20:17:05 2015
@@ -18,12 +18,14 @@
#define BDA_KBDFLAG_RSHIFT (1 << 0)
#define BDA_KBDFLAG_LSHIFT (1 << 1)
#define BDA_KBDFLAG_CTRL (1 << 2)
+#define BDA_KBDFLAG_RCTRL (1 << 2) // Used for KeybdStatusFlags
#define BDA_KBDFLAG_ALT (1 << 3)
+#define BDA_KBDFLAG_RALT (1 << 3) // Used for KeybdStatusFlags
#define BDA_KBDFLAG_SCROLL_ON (1 << 4)
#define BDA_KBDFLAG_NUMLOCK_ON (1 << 5)
#define BDA_KBDFLAG_CAPSLOCK_ON (1 << 6)
#define BDA_KBDFLAG_INSERT_ON (1 << 7)
-#define BDA_KBDFLAG_RALT (1 << 8)
+#define BDA_KBDFLAG_LCTRL (1 << 8)
#define BDA_KBDFLAG_LALT (1 << 9)
#define BDA_KBDFLAG_SYSRQ (1 << 10)
#define BDA_KBDFLAG_PAUSE (1 << 11)
@@ -34,8 +36,7 @@
/* FUNCTIONS ******************************************************************/
-BOOLEAN KbdBios32Initialize(VOID);
-VOID KbdBios32Cleanup(VOID);
+VOID KbdBios32Post(VOID);
#endif /* _KBDBIOS32_H_ */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c [iso-8859-1] Tue Aug 4
20:17:05 2015
@@ -105,7 +105,7 @@
/* PUBLIC FUNCTIONS ***********************************************************/
-BOOLEAN MouseBios32Initialize(VOID)
+VOID MouseBios32Post(VOID)
{
BYTE ControllerConfig;
@@ -127,7 +127,10 @@
/* Set up the HW vector interrupts */
EnableHwIRQ(12, BiosMouseIrq);
+}
+BOOLEAN MouseBiosInitialize(VOID)
+{
return TRUE;
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.h [iso-8859-1] Tue Aug 4
20:17:05 2015
@@ -15,7 +15,8 @@
VOID BiosMousePs2Interface(LPWORD Stack);
-BOOLEAN MouseBios32Initialize(VOID);
+VOID MouseBios32Post(VOID);
+BOOLEAN MouseBiosInitialize(VOID);
VOID MouseBios32Cleanup(VOID);
#endif /* _MOUBIOS32_H_ */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/vidbios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/vidbios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/vidbios32.c [iso-8859-1] Tue Aug 4
20:17:05 2015
@@ -13,33 +13,59 @@
#define NDEBUG
#include "ntvdm.h"
+#include "emulator.h"
+#include "cpu/bop.h"
#include "int32.h"
#include "vidbios32.h"
#include <bios/vidbios.h>
#include "bios32p.h"
+/* DEFINES ********************************************************************/
+
+/* BOP Identifiers */
+#define BOP_VIDEO_INT 0x10
+
/* PUBLIC FUNCTIONS ***********************************************************/
+
+extern VOID WINAPI VidBiosVideoService(LPWORD Stack);
+static VOID WINAPI VidBiosINT(LPWORD Stack)
+{
+ /*
+ * Set up a false stack to hardwire the BOP function (that can directly
+ * manipulate CPU registers) to the 32-bit interrupt function (which uses
+ * the stack to be able to modify the original CS:IP and FLAGS).
+ *
+ * See int32.h stack codes.
+ */
+ WORD EmuStack[4];
+ DWORD Flags = getEFLAGS();
+
+ DPRINT1("Calling BOP VidBiosINT\n");
+
+ EmuStack[STACK_FLAGS] = LOWORD(Flags);
+ EmuStack[STACK_CS] = getCS();
+ EmuStack[STACK_IP] = getIP();
+ EmuStack[STACK_INT_NUM] = BOP_VIDEO_INT;
+
+ VidBiosVideoService(EmuStack);
+
+ setIP(EmuStack[STACK_IP]);
+ setCS(EmuStack[STACK_CS]);
+ setEFLAGS(MAKELONG(EmuStack[STACK_FLAGS], HIWORD(Flags)));
+}
BOOLEAN VidBios32Initialize(VOID)
{
- /* Initialize the common Video BIOS Support Library */
- if (!VidBiosInitialize()) return FALSE;
-
- /* Register the BIOS 32-bit Interrupts */
- RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
-
- /* Vectors that should be implemented */
- RegisterBiosInt32(0x42, NULL); // Relocated Default INT 10h Video Services
- RegisterBiosInt32(0x6D, NULL); // Video BIOS Entry Point
-
+ /* Register the BIOS support BOPs */
+ RegisterBop(BOP_VIDEO_INT, VidBiosINT);
return TRUE;
}
VOID VidBios32Cleanup(VOID)
{
- /* Cleanup the common Video BIOS Support Library */
- VidBiosCleanup();
+ /* Unregister the BIOS support BOPs */
+ RegisterBop(BOP_VIDEO_INT, NULL);
}
/* EOF */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/kbdbios.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/kbdbios.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/kbdbios.c [iso-8859-1] Tue Aug 4 20:17:05
2015
@@ -13,6 +13,7 @@
#include "ntvdm.h"
#include "emulator.h"
#include "cpu/bop.h"
+#include "int32.h"
#include "bios.h"
// #include "kbdbios.h"
@@ -25,27 +26,73 @@
/* PUBLIC FUNCTIONS ***********************************************************/
+extern VOID WINAPI BiosKeyboardIrq(LPWORD Stack);
static VOID WINAPI KbdBiosIRQ(LPWORD Stack)
{
- DPRINT1("KbdBiosIRQ is UNIMPLEMENTED\n");
+ /*
+ * Set up a false stack to hardwire the BOP function (that can directly
+ * manipulate CPU registers) to the 32-bit interrupt function (which uses
+ * the stack to be able to modify the original CS:IP and FLAGS).
+ *
+ * See int32.h stack codes.
+ */
+ WORD EmuStack[4];
+ DWORD Flags = getEFLAGS();
+
+ DPRINT1("Calling BOP KbdBiosIRQ\n");
+
+ EmuStack[STACK_FLAGS] = LOWORD(Flags);
+ EmuStack[STACK_CS] = getCS();
+ EmuStack[STACK_IP] = getIP();
+ EmuStack[STACK_INT_NUM] = BOP_KBD_IRQ;
+
+ BiosKeyboardIrq(EmuStack);
+
+ setIP(EmuStack[STACK_IP]);
+ setCS(EmuStack[STACK_CS]);
+ setEFLAGS(MAKELONG(EmuStack[STACK_FLAGS], HIWORD(Flags)));
}
+extern VOID WINAPI BiosKeyboardService(LPWORD Stack);
static VOID WINAPI KbdBiosINT(LPWORD Stack)
{
- DPRINT1("KbdBiosINT is UNIMPLEMENTED\n");
+ /*
+ * Set up a false stack to hardwire the BOP function (that can directly
+ * manipulate CPU registers) to the 32-bit interrupt function (which uses
+ * the stack to be able to modify the original CS:IP and FLAGS).
+ *
+ * See int32.h stack codes.
+ */
+ WORD EmuStack[4];
+ DWORD Flags = getEFLAGS();
+
+ DPRINT1("Calling BOP KbdBiosINT\n");
+
+ EmuStack[STACK_FLAGS] = LOWORD(Flags);
+ EmuStack[STACK_CS] = getCS();
+ EmuStack[STACK_IP] = getIP();
+ EmuStack[STACK_INT_NUM] = BOP_KBD_IRQ;
+
+ BiosKeyboardService(EmuStack);
+
+ setIP(EmuStack[STACK_IP]);
+ setCS(EmuStack[STACK_CS]);
+ setEFLAGS(MAKELONG(EmuStack[STACK_FLAGS], HIWORD(Flags)));
}
BOOLEAN KbdBiosInitialize(VOID)
{
/* Register the BIOS support BOPs */
- RegisterBop(BOP_KBD_IRQ, KbdBiosIRQ);
- RegisterBop(BOP_KBD_INT, KbdBiosINT);
-
+ RegisterBop(BOP_KBD_IRQ, KbdBiosIRQ); // BiosKeyboardIrq in kbdbios32.c
+ RegisterBop(BOP_KBD_INT, KbdBiosINT); // BiosKeyboardService in kbdbios32.c
return TRUE;
}
VOID KbdBiosCleanup(VOID)
{
+ /* Unregister the BIOS support BOPs */
+ RegisterBop(BOP_KBD_IRQ, NULL);
+ RegisterBop(BOP_KBD_INT, NULL);
}
/* EOF */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.c [iso-8859-1] Tue Aug 4 20:17:05 2015
@@ -81,22 +81,6 @@
BytesRead);
}
-static UCHAR
-ComputeChecksum(IN ULONG RomLocation,
- IN ULONG RomSize)
-{
- ULONG RomLastAddress = RomLocation + RomSize;
- UCHAR Sum = 0x00; // Using a UCHAR guarantees that we wrap at 0xFF i.e. we do a sum
modulo 0x100.
-
- while (RomLocation < RomLastAddress)
- {
- Sum += *(PUCHAR)REAL_TO_PHYS(RomLocation);
- ++RomLocation;
- }
-
- return Sum;
-}
-
static VOID
InitRomRange(IN PCALLBACK16 Context,
IN ULONG Start,
@@ -115,16 +99,16 @@
/* Check the control sum of the ROM */
/*
- * If this is an adapter ROM (Start: C8000, End: E0000), its
- * reported size is stored in byte 2 of the ROM.
+ * If this is an adapter ROM (Start: C8000, End: E0000),
+ * its reported size is stored in byte 2 of the ROM.
*
* If this is an expansion ROM (Start: E0000, End: F0000),
* its real length is 64kB.
*/
- RomSize = *(PUCHAR)REAL_TO_PHYS(Address + 2) * 512;
+ RomSize = *(PUCHAR)REAL_TO_PHYS(Address + 2) * 512; // Size in blocks of 512
bytes
if (Address >= 0xE0000) RomSize = 0x10000;
- Checksum = ComputeChecksum(Address, RomSize);
+ Checksum = CalcRomChecksum(Address, RomSize);
if (Checksum == 0x00)
{
EntryPoint = Address + 3;
@@ -157,6 +141,29 @@
}
BOOLEAN
+WriteUnProtectRom(IN PVOID RomLocation,
+ IN ULONG RomSize)
+{
+ return MemRemoveFastMemoryHook(RomLocation, RomSize);
+}
+
+UCHAR
+CalcRomChecksum(IN ULONG RomLocation,
+ IN ULONG RomSize)
+{
+ ULONG RomLastAddress = RomLocation + RomSize;
+ UCHAR Sum = 0x00; // Using a UCHAR guarantees that we wrap at 0xFF i.e. we do a sum
modulo 0x100.
+
+ while (RomLocation < RomLastAddress)
+ {
+ Sum += *(PUCHAR)REAL_TO_PHYS(RomLocation);
+ ++RomLocation;
+ }
+
+ return Sum;
+}
+
+BOOLEAN
LoadBios(IN PCSTR BiosFileName,
OUT PVOID* BiosLocation OPTIONAL,
OUT PULONG BiosSize OPTIONAL)
@@ -242,6 +249,9 @@
VOID
SearchAndInitRoms(IN PCALLBACK16 Context)
{
+ /* Video ROMs -- Start: C0000, End: C8000, 2kB blocks */
+ InitRomRange(Context, 0xC0000, 0xC8000, 0x0800);
+
/* Adapters ROMs -- Start: C8000, End: E0000, 2kB blocks */
InitRomRange(Context, 0xC8000, 0xE0000, 0x0800);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/rom.h [iso-8859-1] Tue Aug 4 20:17:05 2015
@@ -23,6 +23,14 @@
IN ULONG RomSize);
BOOLEAN
+WriteUnProtectRom(IN PVOID RomLocation,
+ IN ULONG RomSize);
+
+UCHAR
+CalcRomChecksum(IN ULONG RomLocation,
+ IN ULONG RomSize);
+
+BOOLEAN
LoadBios(IN PCSTR BiosFileName,
OUT PVOID* BiosLocation OPTIONAL,
OUT PULONG BiosSize OPTIONAL);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c [iso-8859-1] Tue Aug 4 20:17:05
2015
@@ -11,6 +11,10 @@
#define NDEBUG
+/* BIOS Version number and Copyright */
+#include <reactos/buildno.h>
+#include <reactos/version.h>
+
#include "ntvdm.h"
#include "emulator.h"
#include "cpu/cpu.h"
@@ -18,16 +22,14 @@
#include "memory.h"
#include "bios.h"
+#include "bios32/bios32p.h"
+#include "rom.h"
#include "bios32/vbe.h"
// #include "vidbios.h"
+#include "bios32/vidbios32.h"
#include "io.h"
#include "hardware/video/svga.h"
-
-/* DEFINES ********************************************************************/
-
-/* BOP Identifiers */
-#define BOP_VIDEO_INT 0x10
/* MACROS *********************************************************************/
@@ -40,6 +42,19 @@
#define VGA_CRTC_DATA Bda->CrtBasePort + 1 // VGA_CRTC_DATA_MONO or
VGA_CRTC_DATA_COLOR
/* PRIVATE VARIABLES **********************************************************/
+
+/*
+ * WARNING! For compatibility purposes the string "IBM" should be at
C000:001E.
+ */
+static const CHAR BiosInfo[] =
+ "00000000000 Emulation of IBM VGA Compatible ROM\0"
+ "CL-GD5434 VGA BIOS Version 1.41 \r\n"
+ "Copyright (C) ReactOS Team 1996-"COPYRIGHT_YEAR"\r\n"
+ "The original CL-GD5434 card was created by Cirrus Logic, Inc.\r\n\0"
+ "BIOS Date: 06/17/13\0";
+
+C_ASSERT(sizeof(BiosInfo)-1 <= 0xFF-0x05); // Ensures that we won't overflow on
the Video Code
+
/*
* VGA Register Configurations for BIOS Video Modes.
@@ -3862,8 +3877,12 @@
Attached = FALSE;
}
-BOOLEAN VidBiosInitialize(VOID)
-{
+VOID VidBiosPost(VOID)
+{
+ /*
+ * Initialize VGA BIOS32 RAM dynamic data
+ */
+
/* Some vectors are in fact addresses to tables */
((PULONG)BaseAddress)[0x1D] = (ULONG)NULL; // Video Parameter Tables
// Far pointer to the 8x8 graphics font for the 8x8 characters 80h-FFh
@@ -3875,6 +3894,56 @@
/* Relocated services by the BIOS (when needed) */
((PULONG)BaseAddress)[0x42] = (ULONG)NULL; // Relocated Default INT 10h Video
Services
((PULONG)BaseAddress)[0x6D] = (ULONG)NULL; // Video BIOS Entry Point
+
+ //
+ // FIXME: At the moment we always set a VGA mode. In the future,
+ // we should set this mode **only** when:
+ // - an app starts to use directly the video memory
+ // (that should be done in emulator.c)
+ // - or starts to use non-stream I/O interrupts
+ // (that should be done here, or maybe in VGA ??)
+ //
+
+ Bda->CrtModeControl = 0x00;
+ Bda->CrtColorPaletteMask = 0x00;
+ Bda->VGADccIDActive = 0x08; // VGA w/ color analog active display
+
+ /* Set the default video mode */
+ VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
+
+ /* Synchronize our cursor position with VGA */
+ VidBiosSyncCursorPosition();
+
+ /* Register the BIOS 32-bit Interrupts */
+ RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
+
+ /* Vectors that should be implemented */
+ RegisterBiosInt32(0x42, NULL); // Relocated Default INT 10h Video Services
+ RegisterBiosInt32(0x6D, NULL); // Video BIOS Entry Point
+
+ /* Initialize VBE */
+ VbeInitialized = VbeInitialize();
+ if (!VbeInitialized) DPRINT1("Couldn't initialize VBE!\n");
+}
+
+BOOLEAN VidBiosInitialize(VOID)
+{
+ UCHAR Checksum;
+
+ /*
+ * Initialize VGA BIOS32 static data
+ */
+
+ /* This is a ROM of size 'VIDEO_BIOS_ROM_SIZE' */
+ *(PWORD)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0000)) = 0xAA55;
+ *(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0002)) = VIDEO_BIOS_ROM_SIZE / 512; //
Size in blocks of 512 bytes
+
+ /* Bootstrap code */
+ *(PWORD)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0003)) = 0x90CB; // retf, nop
+ // RtlCopyMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0xFFF0), Bootstrap,
sizeof(Bootstrap));
+
+ /* Video BIOS Information */
+ RtlCopyMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0005), BiosInfo,
sizeof(BiosInfo)-1);
/* Initialize the VGA static function table */
VgaStaticFuncTable = SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_STATE_INFO_OFFSET);
@@ -3896,31 +3965,15 @@
RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x14_OFFSET),
Font8x14, sizeof(Font8x14));
- //
- // FIXME: At the moment we always set a VGA mode. In the future,
- // we should set this mode **only** when:
- // - an app starts to use directly the video memory
- // (that should be done in emulator.c)
- // - or starts to use non-stream I/O interrupts
- // (that should be done here, or maybe in VGA ??)
- //
-
- Bda->CrtModeControl = 0x00;
- Bda->CrtColorPaletteMask = 0x00;
- Bda->VGADccIDActive = 0x08; // VGA w/ color analog active display
-
- /* Set the default video mode */
- VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
-
- /* Synchronize our cursor position with VGA */
- VidBiosSyncCursorPosition();
-
- /* Register the BIOS support BOPs */
- RegisterBop(BOP_VIDEO_INT, VidBiosVideoService);
-
- /* Initialize VBE */
- VbeInitialized = VbeInitialize();
- if (!VbeInitialized) DPRINT1("Couldn't initialize VBE!\n");
+ VidBios32Initialize();
+
+ /* Compute the ROM checksum and store it */
+ *(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_BIOS_ROM_SIZE - 1)) = 0x00;
+ Checksum = CalcRomChecksum(TO_LINEAR(VIDEO_BIOS_DATA_SEG, 0x0000),
VIDEO_BIOS_ROM_SIZE);
+ *(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_BIOS_ROM_SIZE - 1)) = (0xFF -
Checksum + 1) & 0xFF;
+
+ WriteProtectRom((PVOID)TO_LINEAR(VIDEO_BIOS_DATA_SEG, 0x0000),
+ VIDEO_BIOS_ROM_SIZE);
return TRUE;
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h [iso-8859-1] Tue Aug 4 20:17:05
2015
@@ -26,12 +26,14 @@
#define CGA_ODD_VIDEO_SEG 0xBA00
#define VIDEO_BIOS_DATA_SEG 0xC000
-#define FONT_8x8_OFFSET 0x0000
-#define FONT_8x8_HIGH_OFFSET 0x0400
-#define FONT_8x16_OFFSET 0x0800
-#define FONT_8x14_OFFSET 0x1800
+#define FONT_8x8_OFFSET 0x0100
+#define FONT_8x8_HIGH_OFFSET 0x0500
+#define FONT_8x16_OFFSET 0x0900
+#define FONT_8x14_OFFSET 0x1900
-#define VIDEO_STATE_INFO_OFFSET 0x3000 // == 0x1800 + (sizeof(Font8x14) == 0x0E00) +
0x0A00 for padding
+#define VIDEO_STATE_INFO_OFFSET 0x3000 // == 0x1900 + (sizeof(Font8x14) == 0x0E00) +
0x0900 for padding
+
+#define VIDEO_BIOS_ROM_SIZE 0x4000
typedef enum
{
@@ -109,6 +111,7 @@
VOID VidBiosDetachFromConsole(VOID);
VOID VidBiosAttachToConsole(VOID);
+VOID VidBiosPost(VOID);
BOOLEAN VidBiosInitialize(VOID);
VOID VidBiosCleanup(VOID);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c [iso-8859-1] Tue Aug 4 20:17:05
2015
@@ -222,6 +222,12 @@
break;
}
+ case CMOS_REG_CENTURY:
+ {
+ Value = READ_CMOS_DATA(CmosMemory, CurrentTime.wYear / 100 + 19);
+ break;
+ }
+
case CMOS_REG_STATUS_C:
{
/* Return the old value */
@@ -360,6 +366,12 @@
CurrentTime.wYear = (CurrentTime.wYear / 100) * 100;
CurrentTime.wYear += WRITE_CMOS_DATA(CmosMemory, Value);
+ break;
+ }
+
+ case CMOS_REG_CENTURY:
+ {
+ UNIMPLEMENTED;
break;
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/cmos.h [iso-8859-1] Tue Aug 4 20:17:05
2015
@@ -18,22 +18,24 @@
#define CMOS_BATTERY_OK 0x80
/* Status Register B flags */
+#define CMOS_STB_DST (1 << 0)
#define CMOS_STB_24HOUR (1 << 1)
#define CMOS_STB_BINARY (1 << 2)
#define CMOS_STB_SQUARE_WAVE (1 << 3)
#define CMOS_STB_INT_ON_UPDATE (1 << 4)
#define CMOS_STB_INT_ON_ALARM (1 << 5)
#define CMOS_STB_INT_PERIODIC (1 << 6)
+#define CMOS_STB_UPDATE_CYCLE (1 << 7)
/* Status Register C flags */
-#define CMOS_STC_UF CMOS_STB_INT_ON_UPDATE
-#define CMOS_STC_AF CMOS_STB_INT_ON_ALARM
-#define CMOS_STC_PF CMOS_STB_INT_PERIODIC
+#define CMOS_STC_UF (1 << 4)
+#define CMOS_STC_AF (1 << 5)
+#define CMOS_STC_PF (1 << 6)
#define CMOS_STC_IRQF (1 << 7)
/* Default register values */
-#define CMOS_DEFAULT_STA 0x26
-#define CMOS_DEFAULT_STB CMOS_STB_24HOUR
+#define CMOS_DEFAULT_STA 0x26
+#define CMOS_DEFAULT_STB CMOS_STB_24HOUR
#define WRITE_CMOS_DATA(Cmos, Value) \
((Cmos).StatusRegB & CMOS_STB_BINARY) ? (Value) : BCD_TO_BINARY(Value)
@@ -65,6 +67,7 @@
CMOS_REG_EXT_MEMORY_HIGH = 0x18,
CMOS_REG_ACTUAL_EXT_MEMORY_LOW = 0x30,
CMOS_REG_ACTUAL_EXT_MEMORY_HIGH = 0x31,
+ CMOS_REG_CENTURY = 0x32,
CMOS_REG_MAX = 0x40
} CMOS_REGISTERS, *PCMOS_REGISTERS;
@@ -107,6 +110,8 @@
BYTE StatusRegD; // 0x0d
BYTE Diagnostics; // 0x0e
BYTE ShutdownStatus; // 0x0f
+ BYTE Padding[0x22]; // 0x10
+ BYTE Century; // 0x32
};
BYTE Regs1[0x10]; // 0x00 - 0x0f
BYTE Regs [0x40]; // 0x00 - 0x3f
Modified: trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/ntvd…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.c [iso-8859-1] Tue Aug 4 20:17:05 2015
@@ -526,6 +526,25 @@
#endif
+#ifdef ADVANCED_DEBUGGING
+ {
+ INT i = 20;
+
+ printf("Waiting for debugger (10 secs)..");
+ while (i--)
+ {
+ printf(".");
+ if (IsDebuggerPresent())
+ {
+ DbgBreakPoint();
+ break;
+ }
+ Sleep(500);
+ }
+ printf("Continue\n");
+ }
+#endif
+
/* Load global VDM settings */
LoadGlobalSettings();
@@ -549,8 +568,8 @@
goto Cleanup;
}
- /* Initialize the system BIOS */
- if (!BiosInitialize(NULL))
+ /* Initialize the system BIOS and option ROMs */
+ if (!BiosInitialize(NULL, NULL))
{
wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n");
goto Cleanup;
Modified: trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/ntvd…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/ntvdm.h [iso-8859-1] Tue Aug 4 20:17:05 2015
@@ -63,6 +63,10 @@
*/
// #define ADVANCED_DEBUGGING
+#ifdef ADVANCED_DEBUGGING
+#define ADVANCED_DEBUGGING_LEVEL 1
+#endif
+
/* FUNCTIONS ******************************************************************/
extern HANDLE VdmTaskEvent;