Author: hbelusca
Date: Fri May 8 19:26:46 2015
New Revision: 67601
URL:
http://svn.reactos.org/svn/reactos?rev=67601&view=rev
Log:
[NTVDM]: Implement PC reset handling in the BIOS. Used by some apps for switching from
protected mode back to real mode the 286 way (see:
http://www.rcollins.org/articles/pmbasics/ for more details).
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
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] Fri May 8 19:26:46 2015
@@ -74,7 +74,13 @@
WORD CrtBasePort; // 0x63
BYTE CrtModeControl; // 0x65
BYTE CrtColorPaletteMask; // 0x66
- BYTE CassetteData[5]; // 0x67
+
+ union // 0x67
+ {
+ BYTE CassetteData[5]; // Cassette tape control (unused)
+ DWORD ResumeEntryPoint; // CS:IP for 286 return from Protected Mode
+ };
+
DWORD TickCounter; // 0x6c
BYTE MidnightPassed; // 0x70
BYTE BreakFlag; // 0x71
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] Fri May 8
19:26:46 2015
@@ -31,6 +31,7 @@
#include "hardware/cmos.h"
#include "hardware/pic.h"
#include "hardware/pit.h"
+#include "hardware/ps2.h"
/* PRIVATE VARIABLES **********************************************************/
@@ -131,7 +132,7 @@
static BYTE PostCode[] =
{
LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_RESET, // Call BIOS POST
- 0xCD, 0x19, // INT 0x19, the bootstrap
loader interrupt
+ 0xCD, BIOS_BOOTSTRAP_LOADER, // INT 0x19
// LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_UNSIMULATE
};
@@ -233,9 +234,9 @@
* Return the (usable) extended memory (after 1 MB)
* size in kB from CMOS.
*/
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_LOW);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_LOW |
CMOS_DISABLE_NMI);
Low = IOReadB(CMOS_DATA_PORT);
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_HIGH);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_HIGH |
CMOS_DISABLE_NMI);
High = IOReadB(CMOS_DATA_PORT);
setAX(MAKEWORD(Low, High));
@@ -607,9 +608,9 @@
* Retrieve the conventional memory size
* in kB from CMOS, typically 640 kB.
*/
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW | CMOS_DISABLE_NMI);
Low = IOReadB(CMOS_DATA_PORT);
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH | CMOS_DISABLE_NMI);
High = IOReadB(CMOS_DATA_PORT);
Bda->MemorySize = MAKEWORD(Low, High);
}
@@ -640,6 +641,7 @@
#if 0
BOOLEAN Success;
#endif
+ BYTE ShutdownStatus;
DPRINT("Bios32Post\n");
@@ -654,12 +656,80 @@
setDS(BDA_SEGMENT);
/*
+ * Perform early CMOS shutdown status checks
+ */
+
+ /* Read the CMOS shutdown status byte and reset it */
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_SHUTDOWN_STATUS | CMOS_DISABLE_NMI);
+ ShutdownStatus = IOReadB(CMOS_DATA_PORT);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_SHUTDOWN_STATUS | CMOS_DISABLE_NMI);
+ IOWriteB(CMOS_DATA_PORT, 0x00);
+
+ DPRINT1("Bda->SoftReset = 0x%04X ; ShutdownStatus = 0x%02X\n",
+ Bda->SoftReset, ShutdownStatus);
+
+ switch (ShutdownStatus)
+ {
+ /* Shutdown after Memory Tests (unsupported) */
+ case 0x01: case 0x02: case 0x03:
+ /* Shutdown after Protected Mode Tests (unsupported) */
+ case 0x06: case 0x07: case 0x08:
+ /* Shutdown after Block Move Test (unsupported) */
+ case 0x09:
+ {
+ DisplayMessage(L"Unsupported CMOS Shutdown Status value 0x%02X. The VDM
is stopping...", ShutdownStatus);
+ EmulatorTerminate();
+ return;
+ }
+
+ /* Shutdown to Boot Loader */
+ case 0x04:
+ {
+ DPRINT1("Fast restart to Bootstrap Loader...\n");
+ return;
+ }
+
+ /* Flush keyboard, issue an EOI... */
+ case 0x05:
+ {
+ IOReadB(PS2_DATA_PORT);
+
+ /* Send EOI */
+ IOWriteB(PIC_SLAVE_CMD , PIC_OCW2_EOI);
+ IOWriteB(PIC_MASTER_CMD, PIC_OCW2_EOI);
+
+ // Fall back
+ }
+
+ /*
+ * ... and far JMP to user-specified location at 0040:0067
+ * (Bda->ResumeEntryPoint) with interrupts and NMI disabled.
+ */
+ case 0x0A:
+ {
+ DPRINT1("Bda->ResumeEntryPoint = %04X:%04X\n",
+ HIWORD(Bda->ResumeEntryPoint),
+ LOWORD(Bda->ResumeEntryPoint));
+
+ /* Position execution pointers to Bda->ResumeEntryPoint and return */
+ setCS(HIWORD(Bda->ResumeEntryPoint));
+ setIP(LOWORD(Bda->ResumeEntryPoint));
+ return;
+ }
+
+ /* Soft reset or unexpected shutdown... */
+ case 0x00:
+ /* ... or other possible shutdown codes: just continue the POST */
+ default:
+ break;
+ }
+
+ /*
+ * FIXME: UNIMPLEMENTED!
* Check the word at 0040h:0072h (Bda->SoftReset) and do one of the
* following actions:
* - 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.
- * In case we do a warm reboot, we need to check for the CMOS shutdown flag
- * and take a suitable action.
*/
// FIXME: This is a debug temporary check: