From 7b2978c43feaa2405c636fbc83a40f02ebdd10cc Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Sat, 10 Aug 2013 17:06:04 +0000 Subject: [PATCH] Synchronize with trunk to fix spec2def issue. [NTVDM] Implement write modes and latch register for VGA. svn path=/branches/ntvdm/; revision=59687 --- dll/win32/samsrv/samsrv.h | 1 + dll/win32/samsrv/setup.c | 2 +- subsystems/ntvdm/CMakeLists.txt | 4 +- subsystems/ntvdm/vga.c | 69 ++++++++++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/dll/win32/samsrv/samsrv.h b/dll/win32/samsrv/samsrv.h index 8a63f72f517..a9f2f2ddde7 100644 --- a/dll/win32/samsrv/samsrv.h +++ b/dll/win32/samsrv/samsrv.h @@ -9,6 +9,7 @@ #include #include +#include #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H diff --git a/dll/win32/samsrv/setup.c b/dll/win32/samsrv/setup.c index 7f1465a429a..b265dbbdec9 100644 --- a/dll/win32/samsrv/setup.c +++ b/dll/win32/samsrv/setup.c @@ -577,7 +577,7 @@ SampSetupCreateDomain(IN HANDLE hServerKey, FixedData.DomainModifiedCount.QuadPart = 0; FixedData.MaxPasswordAge.QuadPart = -(6LL * 7LL * 24LL * 60LL * 60LL * TICKS_PER_SECOND); /* 6 weeks */ FixedData.MinPasswordAge.QuadPart = 0; /* right now */ -// FixedData.ForceLogoff.QuadPart = // very far in the future aka never + FixedData.ForceLogoff.QuadPart = LLONG_MAX; /* very far in the future aka never */ FixedData.LockoutDuration.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND); /* 30 minutes */ FixedData.LockoutObservationWindow.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND); /* 30 minutes */ FixedData.ModifiedCountAtLastPromotion.QuadPart = 0; diff --git a/subsystems/ntvdm/CMakeLists.txt b/subsystems/ntvdm/CMakeLists.txt index 2007beba91b..5be07e44a9e 100644 --- a/subsystems/ntvdm/CMakeLists.txt +++ b/subsystems/ntvdm/CMakeLists.txt @@ -13,8 +13,8 @@ list(APPEND SOURCE ps2.c vga.c ntvdm.c - ntvdm.rc) -# ${CMAKE_CURRENT_BINARY_DIR}/ntvdm.def + ntvdm.rc + ${CMAKE_CURRENT_BINARY_DIR}/ntvdm.def) add_executable(ntvdm ${SOURCE}) set_module_type(ntvdm win32cui UNICODE) diff --git a/subsystems/ntvdm/vga.c b/subsystems/ntvdm/vga.c index 4522a86109d..4eef0ef1819 100644 --- a/subsystems/ntvdm/vga.c +++ b/subsystems/ntvdm/vga.c @@ -19,6 +19,7 @@ static CONST DWORD MemoryBase[] = { 0xA0000, 0xA0000, 0xB0000, 0xB8000 }; static CONST DWORD MemoryLimit[] = { 0xAFFFF, 0xAFFFF, 0xB7FFF, 0xBFFFF }; static BYTE VgaMemory[VGA_NUM_BANKS * VGA_BANK_SIZE]; +static BYTE VgaLatchRegisters[VGA_NUM_BANKS] = {0, 0, 0, 0}; static BYTE VgaMiscRegister; static BYTE VgaSeqIndex = VGA_SEQ_RESET_REG; static BYTE VgaSeqRegisters[VGA_SEQ_MAX_REG]; @@ -117,6 +118,66 @@ static inline DWORD VgaTranslateWriteAddress(DWORD Address) return Offset; } +static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane) +{ + BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 3; + BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3; + BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7; + BYTE BitMask = VgaGcRegisters[VGA_GC_BITMASK_REG]; + + if (WriteMode == 1) + { + /* In write mode 1 just return the latch register */ + return VgaLatchRegisters[Plane]; + } + + if (WriteMode != 2) + { + /* Write modes 0 and 3 rotate the data to the right first */ + Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 - RotateCount))); + } + else + { + /* Write mode 2 expands the appropriate bit to all 8 bits */ + Data = (Data & (1 << Plane)) ? 0xFF : 0x00; + } + + if (WriteMode == 0) + { + /* + * In write mode 0, the enable set/reset register decides if the + * set/reset bit should be expanded to all 8 bits. + */ + if (VgaGcRegisters[VGA_GC_ENABLE_RESET_REG] & (1 << Plane)) + { + /* Copy the bit from the set/reset register to all 8 bits */ + Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 0x00; + } + } + + if (WriteMode != 3) + { + /* Write modes 0 and 2 then perform a logical operation on the data and latch */ + if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane]; + else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane]; + else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane]; + } + else + { + /* For write mode 3, we AND the bitmask with the data, which is used as the new bitmask */ + BitMask &= Data; + + /* Then we expand the bit in the set/reset field */ + Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 0x00; + } + + /* Bits cleared in the bitmask are replaced with latch register bits */ + Data = (Data & BitMask) | (VgaLatchRegisters[Plane] & (~BitMask)); + + /* Return the byte */ + return Data; +} + static inline VOID VgaMarkForUpdate(SHORT Row, SHORT Column) { DPRINT("VgaMarkForUpdate: Row %d, Column %d\n", Row, Column); @@ -694,6 +755,12 @@ VOID VgaReadMemory(DWORD Address, LPBYTE Buffer, DWORD Size) { VideoAddress = VgaTranslateReadAddress(Address + i); + /* Load the latch registers */ + VgaLatchRegisters[0] = VgaMemory[LOWORD(VideoAddress)]; + VgaLatchRegisters[1] = VgaMemory[VGA_BANK_SIZE + LOWORD(VideoAddress)]; + VgaLatchRegisters[2] = VgaMemory[(2 * VGA_BANK_SIZE) + LOWORD(VideoAddress)]; + VgaLatchRegisters[3] = VgaMemory[(3 * VGA_BANK_SIZE) + LOWORD(VideoAddress)]; + /* Copy the value to the buffer */ Buffer[i] = VgaMemory[VideoAddress]; } @@ -745,7 +812,7 @@ VOID VgaWriteMemory(DWORD Address, LPBYTE Buffer, DWORD Size) } /* Copy the value to the VGA memory */ - VgaMemory[VideoAddress + j * VGA_BANK_SIZE] = Buffer[i]; + VgaMemory[VideoAddress + j * VGA_BANK_SIZE] = VgaTranslateByteForWriting(Buffer[i], j); } } }