From bf2731fb9fab59f159ce96ff8bf6803c2063d0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 10 Nov 2013 13:12:02 +0000 Subject: [PATCH] =?UTF-8?q?[NTVDM]=20-=20BIOS:=20Reorganize=20a=20bit=20th?= =?UTF-8?q?e=20header,=20and=20close=20the=20input=20thread=20before=20clo?= =?UTF-8?q?sing=20the=20input=20handle=20(and=20not=20after).=20-=20INT32:?= =?UTF-8?q?=20Fix=20a=20comment.=20-=20CMOS:=20Put=20CMOS=20data=20into=20?= =?UTF-8?q?a=20structure=20called=20CMOS=5FMEMORY,=20introduce=20READ/WRIT?= =?UTF-8?q?E=5FCMOS=5FDATA=20macros=20for=20simplifying=20code.=20Save=20C?= =?UTF-8?q?MOS=20memory=20into=20a=20file=20(=C3=A0=20la=20Windows'=20NTVD?= =?UTF-8?q?M),=20which=20is=20loaded=20at=20startup.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/branches/ntvdm/; revision=60913 --- subsystems/ntvdm/bios.c | 6 +- subsystems/ntvdm/bios.h | 18 +-- subsystems/ntvdm/cmos.c | 261 ++++++++++++++++++------------------ subsystems/ntvdm/cmos.h | 69 +++++++++- subsystems/ntvdm/emulator.c | 2 +- subsystems/ntvdm/int32.c | 2 +- subsystems/ntvdm/ntvdm.c | 10 +- 7 files changed, 221 insertions(+), 147 deletions(-) diff --git a/subsystems/ntvdm/bios.c b/subsystems/ntvdm/bios.c index 6f026e61af1..2363e5ba00f 100644 --- a/subsystems/ntvdm/bios.c +++ b/subsystems/ntvdm/bios.c @@ -568,6 +568,9 @@ BOOLEAN BiosInitialize(VOID) VOID BiosCleanup(VOID) { + /* Close the input thread handle */ + if (InputThread != NULL) CloseHandle(InputThread); + /* Restore the old screen buffer */ SetConsoleActiveScreenBuffer(BiosConsoleOutput); @@ -577,9 +580,6 @@ VOID BiosCleanup(VOID) /* 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) diff --git a/subsystems/ntvdm/bios.h b/subsystems/ntvdm/bios.h index e89292d0c2f..7ca303c99f3 100644 --- a/subsystems/ntvdm/bios.h +++ b/subsystems/ntvdm/bios.h @@ -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 @@ enum SCROLL_DIRECTION_RIGHT }; -#pragma pack(push, 1) - /* * BIOS Data Area at 0040:XXXX * @@ -76,6 +76,7 @@ enum * and: http://www.bioscentral.com/misc/bda.htm * for more information. */ +#pragma pack(push, 1) typedef struct { WORD SerialPorts[4]; // 0x00 @@ -142,11 +143,10 @@ typedef struct 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 ******************************************************************/ extern PBIOS_DATA_AREA Bda; diff --git a/subsystems/ntvdm/cmos.c b/subsystems/ntvdm/cmos.c index be67438018d..f982bb3ac84 100644 --- a/subsystems/ntvdm/cmos.c +++ b/subsystems/ntvdm/cmos.c @@ -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 @@ BYTE CmosReadData(VOID) 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 @@ BYTE CmosReadData(VOID) case CMOS_REG_ALARM_HRS: { BOOLEAN Afternoon = FALSE; - BYTE Value = AlarmHour; + BYTE Value = CmosMemory.AlarmHour; - 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; @@ -125,70 +108,42 @@ BYTE CmosReadData(VOID) } 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 @@ VOID CmosWriteData(BYTE Value) 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 @@ VOID CmosWriteData(BYTE Value) 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 @@ VOID CmosWriteData(BYTE Value) { 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 @@ VOID CmosWriteData(BYTE Value) 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 @@ VOID CmosWriteData(BYTE Value) /* 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; + 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 @@ VOID CmosWriteData(BYTE Value) DWORD RtcGetTicksPerSecond(VOID) { - BYTE RateSelect = StatusRegB & 0x0F; + BYTE RateSelect = CmosMemory.StatusRegB & 0x0F; if (RateSelect == 0) { @@ -373,12 +311,12 @@ DWORD RtcGetTicksPerSecond(VOID) 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) + if (CmosMemory.StatusRegB & CMOS_STB_INT_PERIODIC) { - StatusRegC |= CMOS_STC_IRQF; + CmosMemory.StatusRegC |= CMOS_STC_IRQF; /* Interrupt! */ PicInterruptRequest(RTC_IRQ_NUMBER); @@ -394,26 +332,91 @@ VOID RtcTimeUpdate(VOID) 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 (CmosMemory.StatusRegB & CMOS_STB_INT_ON_UPDATE) CmosMemory.StatusRegC |= CMOS_STC_IRQF; - if (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 */ diff --git a/subsystems/ntvdm/cmos.h b/subsystems/ntvdm/cmos.h index 5f7f63236ae..6caec7b01f1 100644 --- a/subsystems/ntvdm/cmos.h +++ b/subsystems/ntvdm/cmos.h @@ -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 */ @@ -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,9 +66,63 @@ typedef enum _CMOS_REGISTERS 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-123.asp + * 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); BYTE CmosReadData(VOID); @@ -70,7 +130,10 @@ VOID CmosWriteData(BYTE Value); DWORD RtcGetTicksPerSecond(VOID); VOID RtcPeriodicTick(VOID); VOID RtcTimeUpdate(VOID); - + +BOOLEAN CmosInitialize(VOID); +VOID CmosCleanup(VOID); + #endif // _CMOS_H_ /* EOF */ diff --git a/subsystems/ntvdm/emulator.c b/subsystems/ntvdm/emulator.c index 742112c4cbe..94e0f0a9b38 100644 --- a/subsystems/ntvdm/emulator.c +++ b/subsystems/ntvdm/emulator.c @@ -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 **********************************************************/ diff --git a/subsystems/ntvdm/int32.c b/subsystems/ntvdm/int32.c index 8916b5b0f02..9fcf573f7fe 100644 --- a/subsystems/ntvdm/int32.c +++ b/subsystems/ntvdm/int32.c @@ -163,7 +163,7 @@ VOID WINAPI InitializeInt32(WORD BiosSegment) // 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: diff --git a/subsystems/ntvdm/ntvdm.c b/subsystems/ntvdm/ntvdm.c index a26f08fb678..974559df74c 100644 --- a/subsystems/ntvdm/ntvdm.c +++ b/subsystems/ntvdm/ntvdm.c @@ -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 @@ INT wmain(INT argc, WCHAR *argv[]) 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 @@ INT wmain(INT argc, WCHAR *argv[]) Cleanup: SpeakerCleanup(); BiosCleanup(); + CmosCleanup(); EmulatorCleanup(); DPRINT1("\n\n\nNTVDM - Exiting...\n\n\n");