1 /*
2  * PROJECT:         ReactOS VGA display driver
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            win32ss/drivers/displays/vga/objects/screen.c
5  * PURPOSE:
6  * PROGRAMMERS:
7  */
8 
9 #include <vgaddi.h>
10 
11 static WORD PaletteBuffer[] = {
12     16, 0, // 16 entries, start with 0
13     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
14 };
15 
16 static BYTE ColorBuffer[] = {
17     16, // 16 entries
18     0, 0,
19     0,  // start with 0
20     0x00, 0x00, 0x00, 0x00, // black
21     0x2A, 0x00, 0x15, 0x00, // red
22     0x00, 0x2A, 0x15, 0x00, // green
23     0x2A, 0x2A, 0x15, 0x00, // brown
24     0x00, 0x00, 0x2A, 0x00, // blue
25     0x2A, 0x15, 0x2A, 0x00, // magenta
26     0x15, 0x2A, 0x2A, 0x00, // cyan
27     0x21, 0x22, 0x23, 0x00, // dark gray
28     0x30, 0x31, 0x32, 0x00, // light gray
29     0x3F, 0x00, 0x00, 0x00, // bright red
30     0x00, 0x3F, 0x00, 0x00, // bright green
31     0x3F, 0x3F, 0x00, 0x00, // bright yellow
32     0x00, 0x00, 0x3F, 0x00, // bright blue
33     0x3F, 0x00, 0x3F, 0x00, // bright magenta
34     0x00, 0x3F, 0x3F, 0x00, // bright cyan
35     0x3F, 0x3F, 0x3F, 0x00  // bright white
36 };
37 
getAvailableModes(IN HANDLE Driver,OUT PVIDEO_MODE_INFORMATION * modeInformation,OUT DWORD * ModeSize)38 DWORD getAvailableModes(
39     IN HANDLE Driver,
40     OUT PVIDEO_MODE_INFORMATION *modeInformation,
41     OUT DWORD *ModeSize)
42 {
43     ULONG Temp;
44     VIDEO_NUM_MODES modes;
45     PVIDEO_MODE_INFORMATION VideoTemp;
46 
47     /* get number of modes supported */
48     if (EngDeviceIoControl(Driver,
49                            IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
50                            NULL,
51                            0,
52                            &modes,
53                            sizeof(VIDEO_NUM_MODES),
54                            &Temp))
55     {
56         /* get modes failed */
57         return 0;
58     }
59 
60     *ModeSize = modes.ModeInformationLength;
61 
62     /* allocate buffer for the mini-port to write the modes in */
63     *modeInformation = (PVIDEO_MODE_INFORMATION)
64                         EngAllocMem(0, modes.NumModes *
65                                     modes.ModeInformationLength, ALLOC_TAG);
66 
67     if (*modeInformation == NULL)
68     {
69         /* couldn't allocate buffer */
70         return 0;
71     }
72 
73     /* Ask the mini-port to fill in the available modes. */
74     if (EngDeviceIoControl(Driver,
75                            IOCTL_VIDEO_QUERY_AVAIL_MODES,
76                            NULL,
77                            0,
78                            *modeInformation,
79                            modes.NumModes * modes.ModeInformationLength,
80                            &Temp))
81     {
82         /* failed to query modes */
83         EngFreeMem(*modeInformation);
84         *modeInformation = NULL;
85 
86         return 0;
87     }
88 
89     /* Which modes supported by miniport driver are also suppoted by us, the
90      * display driver */
91 
92     Temp = modes.NumModes;
93     VideoTemp = *modeInformation;
94 
95     /* Reject mode if it's not 4 planes or not graphic or not 1 bits per pel */
96     while (Temp--)
97     {
98         if ((VideoTemp->NumberOfPlanes != 4 ) ||
99             !(VideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
100             (VideoTemp->BitsPerPlane != 1) ||
101             BROKEN_RASTERS(VideoTemp->ScreenStride, VideoTemp->VisScreenHeight))
102         {
103             VideoTemp->Length = 0;
104         }
105 
106         VideoTemp = (PVIDEO_MODE_INFORMATION)(((PUCHAR)VideoTemp) + modes.ModeInformationLength);
107     }
108 
109     return modes.NumModes;
110 }
111 
DeinitVGA(PPDEV ppdev)112 BOOL DeinitVGA(PPDEV ppdev)
113 {
114     VIDEO_MEMORY VideoMemory;
115     ULONG ReturnedDataLength;
116 
117     VideoMemory.RequestedVirtualAddress = (PVOID)ppdev->fbScreen;
118 
119     if (EngDeviceIoControl(ppdev->KMDriver,
120                            IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
121                            (PVOID)&VideoMemory,
122                            sizeof(VIDEO_MEMORY),
123                            NULL,
124                            0,
125                            &ReturnedDataLength))
126     {
127         DPRINT1("Failed to unmap video memory.\n");
128         EngDebugBreak();
129         return FALSE;
130     }
131     return TRUE;
132 }
133 
InitVGA(PPDEV ppdev,BOOL bFirst)134 BOOL InitVGA(PPDEV ppdev, BOOL bFirst)
135 {
136     ULONG ReturnedDataLength;
137     VIDEO_MEMORY VideoMemory;
138     VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
139 
140     ppdev->sizeSurf.cx = 640;
141     ppdev->sizeSurf.cy = 480;
142     ppdev->ModeNum = 2;
143 
144     /* Set the mode that was requested */
145     if (EngDeviceIoControl(ppdev->KMDriver,
146                            IOCTL_VIDEO_SET_CURRENT_MODE,
147                            &ppdev->ModeNum,
148                            sizeof(VIDEO_MODE),
149                            NULL,
150                            0,
151                            &ReturnedDataLength))
152     {
153         return FALSE;
154     }
155 
156     /* set up internal palette */
157     if (EngDeviceIoControl(ppdev->KMDriver,
158                            IOCTL_VIDEO_SET_PALETTE_REGISTERS,
159                            (PVOID) PaletteBuffer,
160                            sizeof (PaletteBuffer),
161                            NULL,
162                            0,
163                            &ReturnedDataLength))
164     {
165        return FALSE;
166     }
167 
168     /* set up the DAC */
169     if (EngDeviceIoControl(ppdev->KMDriver,
170                            IOCTL_VIDEO_SET_COLOR_REGISTERS,
171                            (PVOID) ColorBuffer,
172                            sizeof (ColorBuffer),
173                            NULL,
174                            0,
175                            &ReturnedDataLength))
176     {
177         return FALSE;
178     }
179 
180     if (bFirst)
181     {
182         /* map video memory into virtual memory */
183         VideoMemory.RequestedVirtualAddress = NULL;
184 
185         if (EngDeviceIoControl(ppdev->KMDriver,
186                                IOCTL_VIDEO_MAP_VIDEO_MEMORY,
187                                (PVOID) &VideoMemory,
188                                sizeof (VIDEO_MEMORY),
189                                (PVOID) &VideoMemoryInfo,
190                                sizeof (VideoMemoryInfo),
191                                &ReturnedDataLength))
192         {
193             /* Failed to map to virtual memory */
194             return FALSE;
195         }
196 
197         ppdev->fbScreen = VideoMemoryInfo.FrameBufferBase;
198         vidmem = (PUCHAR)ppdev->fbScreen;
199     }
200 
201     return TRUE;
202 }
203