Author: hbelusca
Date: Sun Nov 10 13:12:02 2013
New Revision: 60913
URL:
http://svn.reactos.org/svn/reactos?rev=60913&view=rev
Log:
[NTVDM]
- BIOS: Reorganize a bit the header, and close the input thread before closing the input
handle (and not after).
- INT32: Fix a comment.
- CMOS: Put CMOS data into a structure called CMOS_MEMORY, introduce READ/WRITE_CMOS_DATA
macros for simplifying code. Save CMOS memory into a file (à la Windows' NTVDM), which
is loaded at startup.
Modified:
branches/ntvdm/subsystems/ntvdm/bios.c
branches/ntvdm/subsystems/ntvdm/bios.h
branches/ntvdm/subsystems/ntvdm/cmos.c
branches/ntvdm/subsystems/ntvdm/cmos.h
branches/ntvdm/subsystems/ntvdm/emulator.c
branches/ntvdm/subsystems/ntvdm/int32.c
branches/ntvdm/subsystems/ntvdm/ntvdm.c
Modified: branches/ntvdm/subsystems/ntvdm/bios.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Sun Nov 10 13:12:02 2013
@@ -568,6 +568,9 @@
VOID BiosCleanup(VOID)
{
+ /* Close the input thread handle */
+ if (InputThread != NULL) CloseHandle(InputThread);
+
/* Restore the old screen buffer */
SetConsoleActiveScreenBuffer(BiosConsoleOutput);
@@ -577,9 +580,6 @@
/* Close the console handles */
if (BiosConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleOutput);
if (BiosConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleInput);
-
- /* Close the input thread handle */
- if (InputThread != NULL) CloseHandle(InputThread);
}
WORD BiosPeekCharacter(VOID)
Modified: branches/ntvdm/subsystems/ntvdm/bios.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.h?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] Sun Nov 10 13:12:02 2013
@@ -15,8 +15,8 @@
/* DEFINES ********************************************************************/
-#define ROM_AREA_START 0xE0000
-#define ROM_AREA_END 0xFFFFF
+#define ROM_AREA_START 0xE0000
+#define ROM_AREA_END 0xFFFFF
#define BDA_SEGMENT 0x40
#define BIOS_SEGMENT 0xF000
@@ -34,13 +34,15 @@
#define CONSOLE_FONT_HEIGHT 8
#define BIOS_KBD_BUFFER_SIZE 16
#define BIOS_EQUIPMENT_LIST 0x2C // HACK: Disable FPU for now
+
#define BIOS_DEFAULT_VIDEO_MODE 0x03
#define BIOS_MAX_PAGES 8
#define BIOS_PAGE_SIZE 0x1000
#define BIOS_MAX_VIDEO_MODE 0x13
-#define DEFAULT_ATTRIBUTE 0x07
-#define GRAPHICS_VIDEO_SEG 0xA000
-#define TEXT_VIDEO_SEG 0xB800
+#define DEFAULT_ATTRIBUTE 0x07
+
+#define GRAPHICS_VIDEO_SEG 0xA000
+#define TEXT_VIDEO_SEG 0xB800
#define BDA_KBDFLAG_RSHIFT (1 << 0)
#define BDA_KBDFLAG_LSHIFT (1 << 1)
@@ -67,8 +69,6 @@
SCROLL_DIRECTION_RIGHT
};
-#pragma pack(push, 1)
-
/*
* BIOS Data Area at 0040:XXXX
*
@@ -76,6 +76,7 @@
* and:
http://www.bioscentral.com/misc/bda.htm
* for more information.
*/
+#pragma pack(push, 1)
typedef struct
{
WORD SerialPorts[4]; // 0x00
@@ -142,10 +143,9 @@
BYTE Reserved17[15]; // 0x121
BYTE Reserved18[3]; // 0x130
} BIOS_DATA_AREA, *PBIOS_DATA_AREA;
+#pragma pack(pop)
C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
-
-#pragma pack(pop)
/* FUNCTIONS ******************************************************************/
Modified: branches/ntvdm/subsystems/ntvdm/cmos.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/cmos.c?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/cmos.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/cmos.c [iso-8859-1] Sun Nov 10 13:12:02 2013
@@ -15,11 +15,10 @@
/* PRIVATE VARIABLES **********************************************************/
+static HANDLE hCmosRam = INVALID_HANDLE_VALUE;
+static CMOS_MEMORY CmosMemory;
+
static BOOLEAN NmiEnabled = TRUE;
-static BYTE StatusRegA = CMOS_DEFAULT_STA;
-static BYTE StatusRegB = CMOS_DEFAULT_STB;
-static BYTE StatusRegC = 0;
-static BYTE AlarmHour, AlarmMinute, AlarmSecond;
static CMOS_REGISTERS SelectedRegister = CMOS_REG_STATUS_D;
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -59,45 +58,29 @@
switch (SelectedRegister)
{
case CMOS_REG_SECONDS:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? CurrentTime.wSecond
- : BINARY_TO_BCD(CurrentTime.wSecond);
- }
+ return READ_CMOS_DATA(CmosMemory, CurrentTime.wSecond);
case CMOS_REG_ALARM_SEC:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? AlarmSecond
- : BINARY_TO_BCD(AlarmSecond);
- }
+ return READ_CMOS_DATA(CmosMemory, CmosMemory.AlarmSecond);
case CMOS_REG_MINUTES:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? CurrentTime.wMinute
- : BINARY_TO_BCD(CurrentTime.wMinute);
- }
+ return READ_CMOS_DATA(CmosMemory, CurrentTime.wMinute);
case CMOS_REG_ALARM_MIN:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? AlarmMinute
- : BINARY_TO_BCD(AlarmMinute);
- }
+ return READ_CMOS_DATA(CmosMemory, CmosMemory.AlarmMinute);
case CMOS_REG_HOURS:
{
BOOLEAN Afternoon = FALSE;
BYTE Value = CurrentTime.wHour;
- if (!(StatusRegB & CMOS_STB_24HOUR) && (Value >= 12))
+ if (!(CmosMemory.StatusRegB & CMOS_STB_24HOUR) && (Value >=
12))
{
Value -= 12;
Afternoon = TRUE;
}
- if (!(StatusRegB & CMOS_STB_BINARY)) Value = BINARY_TO_BCD(Value);
+ Value = READ_CMOS_DATA(CmosMemory, Value);
/* Convert to 12-hour */
if (Afternoon) Value |= 0x80;
@@ -108,15 +91,15 @@
case CMOS_REG_ALARM_HRS:
{
BOOLEAN Afternoon = FALSE;
- BYTE Value = AlarmHour;
-
- if (!(StatusRegB & CMOS_STB_24HOUR) && (Value >= 12))
+ BYTE Value = CmosMemory.AlarmHour;
+
+ if (!(CmosMemory.StatusRegB & CMOS_STB_24HOUR) && (Value >=
12))
{
Value -= 12;
Afternoon = TRUE;
}
- if (!(StatusRegB & CMOS_STB_BINARY)) Value = BINARY_TO_BCD(Value);
+ Value = READ_CMOS_DATA(CmosMemory, Value);
/* Convert to 12-hour */
if (Afternoon) Value |= 0x80;
@@ -125,70 +108,42 @@
}
case CMOS_REG_DAY_OF_WEEK:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? CurrentTime.wDayOfWeek
- : BINARY_TO_BCD(CurrentTime.wDayOfWeek);
- }
+ /*
+ * The CMOS value is 1-based but the
+ * GetLocalTime API value is 0-based.
+ * Correct it.
+ */
+ return READ_CMOS_DATA(CmosMemory, CurrentTime.wDayOfWeek + 1);
case CMOS_REG_DAY:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? CurrentTime.wDay
- :BINARY_TO_BCD(CurrentTime.wDay);
- }
+ return READ_CMOS_DATA(CmosMemory, CurrentTime.wDay);
case CMOS_REG_MONTH:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? CurrentTime.wMonth
- : BINARY_TO_BCD(CurrentTime.wMonth);
- }
+ return READ_CMOS_DATA(CmosMemory, CurrentTime.wMonth);
case CMOS_REG_YEAR:
- {
- return (StatusRegB & CMOS_STB_BINARY)
- ? (CurrentTime.wYear % 100)
- : BINARY_TO_BCD(CurrentTime.wYear % 100);
- }
-
- case CMOS_REG_STATUS_A:
- {
- return StatusRegA;
- }
-
- case CMOS_REG_STATUS_B:
- {
- return StatusRegB;
- }
+ return READ_CMOS_DATA(CmosMemory, CurrentTime.wYear % 100);
case CMOS_REG_STATUS_C:
{
- BYTE Value = StatusRegC;
+ BYTE Value = CmosMemory.StatusRegC;
/* Clear status register C */
- StatusRegC = 0;
+ CmosMemory.StatusRegC = 0x00;
/* Return the old value */
return Value;
}
+ case CMOS_REG_STATUS_A:
+ case CMOS_REG_STATUS_B:
case CMOS_REG_STATUS_D:
- {
- /* Our CMOS battery works perfectly forever */
- return CMOS_BATTERY_OK;
- }
-
case CMOS_REG_DIAGNOSTICS:
- {
- /* Diagnostics found no errors */
- return 0;
- }
-
+ case CMOS_REG_SHUTDOWN_STATUS:
default:
{
- /* Read ignored */
- return 0;
+ // ASSERT(SelectedRegister < CMOS_REG_MAX);
+ return CmosMemory.Regs[SelectedRegister];
}
}
@@ -209,38 +164,26 @@
case CMOS_REG_SECONDS:
{
ChangeTime = TRUE;
- CurrentTime.wSecond = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ CurrentTime.wSecond = WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
case CMOS_REG_ALARM_SEC:
{
- AlarmSecond = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ CmosMemory.AlarmSecond = WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
case CMOS_REG_MINUTES:
{
ChangeTime = TRUE;
- CurrentTime.wMinute = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ CurrentTime.wMinute = WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
case CMOS_REG_ALARM_MIN:
{
- AlarmMinute = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ CmosMemory.AlarmMinute = WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
@@ -250,15 +193,13 @@
ChangeTime = TRUE;
- if (!(StatusRegB & CMOS_STB_24HOUR) && (Value & 0x80))
+ if (!(CmosMemory.StatusRegB & CMOS_STB_24HOUR) && (Value &
0x80))
{
Value &= ~0x80;
Afternoon = TRUE;
}
- CurrentTime.wHour = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
+ CurrentTime.wHour = WRITE_CMOS_DATA(CmosMemory, Value);
/* Convert to 24-hour format */
if (Afternoon) CurrentTime.wHour += 12;
@@ -270,18 +211,16 @@
{
BOOLEAN Afternoon = FALSE;
- if (!(StatusRegB & CMOS_STB_24HOUR) && (Value & 0x80))
+ if (!(CmosMemory.StatusRegB & CMOS_STB_24HOUR) && (Value &
0x80))
{
Value &= ~0x80;
Afternoon = TRUE;
}
- AlarmHour = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
+ CmosMemory.AlarmHour = WRITE_CMOS_DATA(CmosMemory, Value);
/* Convert to 24-hour format */
- if (Afternoon) AlarmHour += 12;
+ if (Afternoon) CmosMemory.AlarmHour += 12;
break;
}
@@ -289,30 +228,27 @@
case CMOS_REG_DAY_OF_WEEK:
{
ChangeTime = TRUE;
- CurrentTime.wDayOfWeek = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ /*
+ * The CMOS value is 1-based but the
+ * SetLocalTime API value is 0-based.
+ * Correct it.
+ */
+ Value -= 1;
+ CurrentTime.wDayOfWeek = WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
case CMOS_REG_DAY:
{
ChangeTime = TRUE;
- CurrentTime.wDay = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ CurrentTime.wDay = WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
case CMOS_REG_MONTH:
{
ChangeTime = TRUE;
- CurrentTime.wMonth = (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ CurrentTime.wMonth = WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
@@ -323,28 +259,30 @@
/* Clear everything except the century */
CurrentTime.wYear = (CurrentTime.wYear / 100) * 100;
- CurrentTime.wYear += (StatusRegB & CMOS_STB_BINARY)
- ? Value
- : BCD_TO_BINARY(Value);
-
+ CurrentTime.wYear += WRITE_CMOS_DATA(CmosMemory, Value);
break;
}
case CMOS_REG_STATUS_A:
{
- StatusRegA = Value;
+ CmosMemory.StatusRegA = Value & 0x7F; // Bit 7 is read-only
break;
}
case CMOS_REG_STATUS_B:
{
- StatusRegB = Value;
- break;
- }
+ CmosMemory.StatusRegB = Value;
+ break;
+ }
+
+ case CMOS_REG_STATUS_C:
+ case CMOS_REG_STATUS_D:
+ // Status registers C and D are read-only
+ break;
default:
{
- /* Write ignored */
+ CmosMemory.Regs[SelectedRegister] = Value;
}
}
@@ -356,7 +294,7 @@
DWORD RtcGetTicksPerSecond(VOID)
{
- BYTE RateSelect = StatusRegB & 0x0F;
+ BYTE RateSelect = CmosMemory.StatusRegB & 0x0F;
if (RateSelect == 0)
{
@@ -373,12 +311,12 @@
VOID RtcPeriodicTick(VOID)
{
/* Set PF */
- StatusRegC |= CMOS_STC_PF;
+ CmosMemory.StatusRegC |= CMOS_STC_PF;
/* Check if there should be an interrupt on a periodic timer tick */
- if (StatusRegB & CMOS_STB_INT_PERIODIC)
- {
- StatusRegC |= CMOS_STC_IRQF;
+ if (CmosMemory.StatusRegB & CMOS_STB_INT_PERIODIC)
+ {
+ CmosMemory.StatusRegC |= CMOS_STC_IRQF;
/* Interrupt! */
PicInterruptRequest(RTC_IRQ_NUMBER);
@@ -394,26 +332,91 @@
GetLocalTime(&CurrentTime);
/* Set UF */
- StatusRegC |= CMOS_STC_UF;
+ CmosMemory.StatusRegC |= CMOS_STC_UF;
/* Check if the time matches the alarm time */
- if ((CurrentTime.wHour == AlarmHour)
- && (CurrentTime.wMinute == AlarmMinute)
- && (CurrentTime.wSecond == AlarmSecond))
+ if ((CurrentTime.wHour == CmosMemory.AlarmHour ) &&
+ (CurrentTime.wMinute == CmosMemory.AlarmMinute) &&
+ (CurrentTime.wSecond == CmosMemory.AlarmSecond))
{
/* Set the alarm flag */
- StatusRegC |= CMOS_STC_AF;
+ CmosMemory.StatusRegC |= CMOS_STC_AF;
/* Set IRQF if there should be an interrupt */
- if (StatusRegB & CMOS_STB_INT_ON_ALARM) StatusRegC |= CMOS_STC_IRQF;
+ if (CmosMemory.StatusRegB & CMOS_STB_INT_ON_ALARM) CmosMemory.StatusRegC |=
CMOS_STC_IRQF;
}
/* Check if there should be an interrupt on update */
- if (StatusRegB & CMOS_STB_INT_ON_UPDATE) StatusRegC |= CMOS_STC_IRQF;
-
- if (StatusRegC & CMOS_STC_IRQF)
+ if (CmosMemory.StatusRegB & CMOS_STB_INT_ON_UPDATE) CmosMemory.StatusRegC |=
CMOS_STC_IRQF;
+
+ if (CmosMemory.StatusRegC & CMOS_STC_IRQF)
{
/* Interrupt! */
PicInterruptRequest(RTC_IRQ_NUMBER);
}
}
+
+BOOLEAN CmosInitialize(VOID)
+{
+ DWORD CmosSize = sizeof(CmosMemory);
+
+ /* File must not be opened before */
+ ASSERT(hCmosRam == INVALID_HANDLE_VALUE);
+
+ /* Clear the CMOS memory */
+ ZeroMemory(&CmosMemory, sizeof(CmosMemory));
+
+ /* Always open (and if needed, create) a RAM file with exclusive access */
+ SetLastError(0); // For debugging purposes
+ hCmosRam = CreateFileW(L"cmos.ram",
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ DPRINT1("CMOS opening %s ; GetLastError() = %u\n", hCmosRam !=
INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError());
+
+ if (hCmosRam != INVALID_HANDLE_VALUE)
+ {
+ BOOL Success = FALSE;
+
+ /* Attempt to fill the CMOS memory with the RAM file */
+ SetLastError(0); // For debugging purposes
+ Success = ReadFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL);
+ if (CmosSize != sizeof(CmosMemory))
+ {
+ /* Bad CMOS Ram file. Reinitialize the CMOS memory. */
+ DPRINT1("Invalid CMOS file, read bytes %u, expected bytes %u\n",
CmosSize, sizeof(CmosMemory));
+ ZeroMemory(&CmosMemory, sizeof(CmosMemory));
+ }
+ DPRINT1("CMOS loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
+ SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
+ }
+
+ /* Overwrite some registers with default values */
+ CmosMemory.StatusRegA = CMOS_DEFAULT_STA;
+ CmosMemory.StatusRegB = CMOS_DEFAULT_STB;
+ CmosMemory.StatusRegC = 0x00;
+ CmosMemory.StatusRegD = CMOS_BATTERY_OK; // Our CMOS battery works perfectly
forever.
+ CmosMemory.Diagnostics = 0x00; // Diagnostics must not find any
errors.
+ CmosMemory.ShutdownStatus = 0x00;
+
+ return TRUE;
+}
+
+VOID CmosCleanup(VOID)
+{
+ DWORD CmosSize = sizeof(CmosMemory);
+
+ if (hCmosRam == INVALID_HANDLE_VALUE) return;
+
+ /* Flush the CMOS memory back to the RAM file and close it */
+ SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
+ WriteFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL);
+
+ CloseHandle(hCmosRam);
+ hCmosRam = INVALID_HANDLE_VALUE;
+}
+
+/* EOF */
Modified: branches/ntvdm/subsystems/ntvdm/cmos.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/cmos.h?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/cmos.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/cmos.h [iso-8859-1] Sun Nov 10 13:12:02 2013
@@ -2,7 +2,7 @@
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: cmos.h
- * PURPOSE: Real Time Clock emulation (header file)
+ * PURPOSE: CMOS Real Time Clock emulation
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
@@ -43,6 +43,12 @@
#define BINARY_TO_BCD(x) (((x / 10) << 4) | (x % 10))
#define BCD_TO_BINARY(x) (((x >> 4) * 10) + (x & 0x0F))
+#define WRITE_CMOS_DATA(Cmos, Value) \
+ ((Cmos).StatusRegB & CMOS_STB_BINARY) ? (Value) : BCD_TO_BINARY(Value)
+
+#define READ_CMOS_DATA(Cmos, Value) \
+ ((Cmos).StatusRegB & CMOS_STB_BINARY) ? (Value) : BINARY_TO_BCD(Value)
+
typedef enum _CMOS_REGISTERS
{
CMOS_REG_SECONDS,
@@ -60,8 +66,62 @@
CMOS_REG_STATUS_C,
CMOS_REG_STATUS_D,
CMOS_REG_DIAGNOSTICS,
- CMOS_REG_MAX
+ CMOS_REG_SHUTDOWN_STATUS,
+ CMOS_REG_MAX = 0x40
} CMOS_REGISTERS, *PCMOS_REGISTERS;
+
+
+/*
+ * CMOS Memory Map
+ *
+ * See the following documentation for more information:
+ *
http://www.intel-assembler.it/portale/5/cmos-memory-map-123/cmos-memory-map…
+ *
http://wiki.osdev.org/CMOS
+ *
http://www.bioscentral.com/misc/cmosmap.htm
+ */
+#pragma pack(push, 1)
+typedef struct
+{
+ BYTE Second; // 0x00
+ BYTE AlarmSecond; // 0x01
+ BYTE Minute; // 0x02
+ BYTE AlarmMinute; // 0x03
+ BYTE Hour; // 0x04
+ BYTE AlarmHour; // 0x05
+ BYTE DayOfWeek; // 0x06
+ BYTE Day; // 0x07
+ BYTE Month; // 0x08
+ BYTE Year; // 0x09
+
+ BYTE StatusRegA; // 0x0a
+ BYTE StatusRegB; // 0x0b
+} CMOS_CLOCK, *PCMOS_CLOCK;
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ CMOS_CLOCK; // 0x00 - 0x0b
+ BYTE StatusRegC; // 0x0c
+ BYTE StatusRegD; // 0x0d
+ BYTE Diagnostics; // 0x0e
+ BYTE ShutdownStatus; // 0x0f
+ };
+ BYTE Regs1[0x10]; // 0x00 - 0x0f
+ BYTE Regs [0x40]; // 0x00 - 0x3f
+ };
+
+ /*
+ * Extended information 0x40 - 0x7f
+ */
+} CMOS_MEMORY, *PCMOS_MEMORY;
+#pragma pack(pop)
+
+C_ASSERT(sizeof(CMOS_MEMORY) == 0x40);
+
+/* FUNCTIONS ******************************************************************/
BOOLEAN IsNmiEnabled(VOID);
VOID CmosWriteAddress(BYTE Value);
@@ -70,7 +130,10 @@
DWORD RtcGetTicksPerSecond(VOID);
VOID RtcPeriodicTick(VOID);
VOID RtcTimeUpdate(VOID);
-
+
+BOOLEAN CmosInitialize(VOID);
+VOID CmosCleanup(VOID);
+
#endif // _CMOS_H_
/* EOF */
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Sun Nov 10 13:12:02 2013
@@ -11,6 +11,7 @@
#define NDEBUG
#include "emulator.h"
+#include "cmos.h"
#include "bios.h"
#include "bop.h"
#include "dos.h"
@@ -19,7 +20,6 @@
#include "pic.h"
#include "ps2.h"
#include "timer.h"
-#include "cmos.h"
/* PRIVATE VARIABLES **********************************************************/
Modified: branches/ntvdm/subsystems/ntvdm/int32.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/int32.c?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/int32.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/int32.c [iso-8859-1] Sun Nov 10 13:12:02 2013
@@ -163,7 +163,7 @@
// HACK: The following instruction should be HLT!
BiosCode[Offset++] = 0x90; // nop
- BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -10)
+ BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -11)
BiosCode[Offset++] = 0xF5;
// EXIT:
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] Sun Nov 10 13:12:02 2013
@@ -12,6 +12,7 @@
#include "ntvdm.h"
#include "emulator.h"
+#include "cmos.h"
#include "bios.h"
#include "speaker.h"
#include "vga.h"
@@ -19,7 +20,6 @@
#include "timer.h"
#include "pic.h"
#include "ps2.h"
-#include "cmos.h"
/*
* Activate this line if you want to be able to test NTVDM with:
@@ -117,6 +117,13 @@
goto Cleanup;
}
+ /* Initialize the CMOS */
+ if (!CmosInitialize())
+ {
+ wprintf(L"FATAL: Failed to initialize the VDM CMOS.\n");
+ goto Cleanup;
+ }
+
/* Initialize the system BIOS */
if (!BiosInitialize())
{
@@ -227,6 +234,7 @@
Cleanup:
SpeakerCleanup();
BiosCleanup();
+ CmosCleanup();
EmulatorCleanup();
DPRINT1("\n\n\nNTVDM - Exiting...\n\n\n");