Synchronize with trunk to fix spec2def issue.
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 10 Aug 2013 17:06:04 +0000 (17:06 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 10 Aug 2013 17:06:04 +0000 (17:06 +0000)
[NTVDM]
Implement write modes and latch register for VGA.

svn path=/branches/ntvdm/; revision=59687

dll/win32/samsrv/samsrv.h
dll/win32/samsrv/setup.c
subsystems/ntvdm/CMakeLists.txt
subsystems/ntvdm/vga.c

index 8a63f72..a9f2f2d 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <limits.h>
 #define WIN32_NO_STATUS
 #define _INC_WINDOWS
 #define COM_NO_WINDOWS_H
index 7f1465a..b265dbb 100644 (file)
@@ -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;
index 2007beb..5be07e4 100644 (file)
@@ -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)
index 4522a86..4eef0ef 100644 (file)
@@ -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);
         }
     }
 }