|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: hardware.c
3: *
4: * Hardware dependent initialization
5: *
6: * Copyright (c) 1992 Microsoft Corporation
7: *
8: \**************************************************************************/
9:
10:
11: #include "driver.h"
12:
13:
14: /******************************Module*Header*******************************\
15: * Color tables
16: *
17: \**************************************************************************/
18:
19: // Values for the internal, EGA-compatible palette.
20:
21: static WORD PaletteBuffer[] = {
22:
23: 16, // 16 entries
24: 0, // start with first palette register
25:
26: // On the VGA, the palette contains indices into the array of color DACs.
27: // Since we can program the DACs as we please, we'll just put all the indices
28: // down at the beginning of the DAC array (that is, pass pixel values through
29: // the internal palette unchanged).
30:
31: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
32: };
33:
34:
35: // These are the values for the first 16 DAC registers, the only ones we'll
36: // work with. These correspond to the RGB colors (6 bits for each primary, with
37: // the fourth entry unused) for pixel values 0-15.
38:
39: static BYTE ColorBuffer[] = {
40:
41: 16, // 16 entries
42: 0,
43: 0,
44: 0, // start with first palette register
45: 0x00, 0x00, 0x00, 0x00, // black
46: 0x2A, 0x00, 0x15, 0x00, // red
47: 0x00, 0x2A, 0x15, 0x00, // green
48: 0x2A, 0x2A, 0x15, 0x00, // mustard/brown
49: 0x00, 0x00, 0x2A, 0x00, // blue
50: 0x2A, 0x15, 0x2A, 0x00, // magenta
51: 0x15, 0x2A, 0x2A, 0x00, // cyan
52: 0x21, 0x22, 0x23, 0x00, // dark gray 2A
53: 0x30, 0x31, 0x32, 0x00, // light gray 39
54: 0x3F, 0x00, 0x00, 0x00, // bright red
55: 0x00, 0x3F, 0x00, 0x00, // bright green
56: 0x3F, 0x3F, 0x00, 0x00, // bright yellow
57: 0x00, 0x00, 0x3F, 0x00, // bright blue
58: 0x3F, 0x00, 0x3F, 0x00, // bright magenta
59: 0x00, 0x3F, 0x3F, 0x00, // bright cyan
60: 0x3F, 0x3F, 0x3F, 0x00 // bright white
61: };
62:
63: /******************************Public*Routine******************************\
64: * bInitPDEV
65: *
66: * Determine the mode we should be in based on the DEVMODE passed in.
67: * Query mini-port to get information needed to fill in the DevInfo and the
68: * GdiInfo .
69: *
70: \**************************************************************************/
71:
72: BOOL bInitPDEV(
73: PPDEV ppdev,
74: DEVMODEW *pDevMode,
75: GDIINFO *pGdiInfo,
76: DEVINFO *pDevInfo)
77: {
78: ULONG cModes;
79: PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
80: VIDEO_COLOR_CAPABILITIES colorCapabilities;
81: ULONG ulTemp;
82: BOOL bSelectDefault;
83: ULONG cbModeSize;
84:
85: //
86: // calls the miniport to get mode information.
87: //
88:
89: cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
90:
91: if (cModes == 0)
92: {
93: DISPDBG((0, "DISP VGA: no available modes\n"));
94: return(FALSE);
95: }
96:
97: //
98: // Determine if we are looking for a default mode.
99: //
100:
101: if ( ((pDevMode->dmPelsWidth) ||
102: (pDevMode->dmPelsHeight) ||
103: (pDevMode->dmBitsPerPel) ||
104: (pDevMode->dmDisplayFlags) ||
105: (pDevMode->dmDisplayFrequency)) == 0)
106: {
107: bSelectDefault = TRUE;
108: }
109: else
110: {
111: bSelectDefault = FALSE;
112: }
113:
114: //
115: // Now see if the requested mode has a match in that table.
116: //
117:
118: pVideoModeSelected = NULL;
119: pVideoTemp = pVideoBuffer;
120:
121: //
122: // Note: Not all vga minports support the frequency field. Those
123: // that do not support fill it in with zero. Also, if the registry
124: // entry is set to 0, we will ignore the freq.
125: //
126:
127: while (cModes--)
128: {
129: if (pVideoTemp->Length != 0)
130: {
131: if (bSelectDefault ||
132: ((pVideoTemp->VisScreenWidth == pDevMode->dmPelsWidth) &&
133: (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
134: (pVideoTemp->BitsPerPlane *
135: pVideoTemp->NumberOfPlanes == pDevMode->dmBitsPerPel) &&
136: ((pVideoTemp->Frequency == pDevMode->dmDisplayFrequency) ||
137: (pDevMode->dmDisplayFrequency == 0)) &&
138: (((pVideoTemp->AttributeFlags &
139: VIDEO_MODE_INTERLACED) ? 1:0) ==
140: ((pDevMode->dmDisplayFlags & DM_INTERLACED) ? 1:0)) ) )
141:
142: {
143: pVideoModeSelected = pVideoTemp;
144: DISPDBG((1, "VGA: Found a match\n")) ;
145: break;
146: }
147: }
148:
149: pVideoTemp = (PVIDEO_MODE_INFORMATION)
150: (((PUCHAR)pVideoTemp) + cbModeSize);
151: }
152:
153: //
154: // If no mode has been found, return an error
155: //
156:
157: if (pVideoModeSelected == NULL)
158: {
159: DISPDBG((0, "DISP VGA: no valid modes\n"));
160: LocalFree(pVideoBuffer);
161: return(FALSE);
162: }
163:
164: //
165: // Save the mode number we selected
166: //
167:
168: ppdev->ulModeNum = pVideoModeSelected->ModeIndex;
169:
170: //
171: // Set the displayed surface dimensions from the DEVMODE
172: //
173:
174: ppdev->sizlSurf.cx = pVideoModeSelected->VisScreenWidth;
175: ppdev->sizlSurf.cy = pVideoModeSelected->VisScreenHeight;
176:
177: //
178: // Set the GDI info that varies with resolution
179: //
180:
181: pGdiInfo->ulHorzRes = pVideoModeSelected->VisScreenWidth;
182: pGdiInfo->ulVertRes = pVideoModeSelected->VisScreenHeight;
183: pGdiInfo->ulDevicePelsDPI = (pVideoModeSelected->VisScreenWidth * 254)/2400;
184:
185: pGdiInfo->ulLogPixelsX = 96;
186: pGdiInfo->ulLogPixelsY = 96;
187:
188: if (!(pVideoModeSelected->AttributeFlags & VIDEO_MODE_NO_OFF_SCREEN))
189: {
190: ppdev->fl |= DRIVER_USE_OFFSCREEN;
191: }
192:
193: LocalFree(pVideoBuffer);
194: return TRUE;
195: }
196:
197: /******************************Public*Routine******************************\
198: * PBYTE pjInitVGA(PPDEV ppdev)
199: *
200: * Initializes the VGA display to the mode specified in the ppdev
201: * If
202: *
203: \**************************************************************************/
204:
205: BOOL bInitVGA(PPDEV ppdev, BOOL bFirst)
206: {
207: VIDEO_MEMORY VideoMemory;
208: VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
209: UINT ReturnedDataLength;
210:
211: //
212: // Set the desired mode. (Must come before IOCTL_VIDEO_MAP_VIDEO_MEMORY;
213: // that IOCTL returns information for the current mode, so there must be a
214: // current mode for which to return information.)
215: //
216:
217: if (!DeviceIoControl(ppdev->hDriver,
218: IOCTL_VIDEO_SET_CURRENT_MODE,
219: &ppdev->ulModeNum, // input buffer
220: sizeof(VIDEO_MODE),
221: NULL,
222: 0,
223: &ReturnedDataLength,
224: NULL)) {
225:
226: return(FALSE);
227:
228: }
229:
230: //
231: // Set up the internal palette.
232: //
233:
234: if (!DeviceIoControl(ppdev->hDriver,
235: IOCTL_VIDEO_SET_PALETTE_REGISTERS,
236: (PVOID) PaletteBuffer, // input buffer
237: sizeof (PaletteBuffer),
238: NULL, // output buffer
239: 0,
240: &ReturnedDataLength,
241: NULL)) {
242:
243: return(FALSE);
244:
245: }
246:
247: //
248: // Set up the DAC.
249: //
250:
251: if (!DeviceIoControl(ppdev->hDriver,
252: IOCTL_VIDEO_SET_COLOR_REGISTERS,
253: (PVOID) ColorBuffer, // input buffer
254: sizeof (ColorBuffer),
255: NULL, // output buffer
256: 0,
257: &ReturnedDataLength,
258: NULL)) {
259:
260: return(FALSE);
261:
262: }
263:
264:
265:
266: if (bFirst) {
267:
268: //
269: // Map video memory into virtual memory.
270: //
271:
272: VideoMemory.RequestedVirtualAddress = NULL;
273:
274: if (!DeviceIoControl(ppdev->hDriver,
275: IOCTL_VIDEO_MAP_VIDEO_MEMORY,
276: (PVOID) &VideoMemory, // input buffer
277: sizeof (VIDEO_MEMORY),
278: (PVOID) &VideoMemoryInfo, // output buffer
279: sizeof (VideoMemoryInfo),
280: &ReturnedDataLength,
281: NULL)) {
282:
283: DISPDBG((0, "Win32 Status = %x\n", GetLastError() ));
284: RIP("VGA.DLL: Initialization error-Map buffer address");
285: return (FALSE);
286:
287: }
288:
289: ppdev->pjScreen = VideoMemoryInfo.FrameBufferBase;
290:
291: }
292:
293: //
294: // Initialize the VGA/EGA sequencer and graphics controller to their
295: // default states, so that we can be sure of drawing properly even if the
296: // miniport didn't happen to set these registers the way we like them.
297: //
298:
299: vInitRegs();
300:
301:
302: return(TRUE);
303: }
304:
305:
306: /******************************Public*Routine******************************\
307: * getAvailableModes
308: *
309: * Calls the miniport to get the list of modes supported by the kernel driver,
310: * and returns the list of modes supported by the diplay driver among those
311: *
312: * returns the number of entries in the videomode buffer.
313: * 0 means no modes are supported by the miniport or that an error occured.
314: *
315: * NOTE: the buffer must be freed up by the caller.
316: *
317: \**************************************************************************/
318:
319: DWORD getAvailableModes(
320: HANDLE hDriver,
321: PVIDEO_MODE_INFORMATION *modeInformation,
322: DWORD *cbModeSize)
323: {
324: ULONG ulTemp;
325: VIDEO_NUM_MODES modes;
326: PVIDEO_MODE_INFORMATION pVideoTemp;
327:
328: //
329: // Get the number of modes supported by the mini-port
330: //
331:
332: if (!DeviceIoControl(hDriver,
333: IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
334: NULL,
335: 0,
336: &modes,
337: sizeof(VIDEO_NUM_MODES),
338: &ulTemp,
339: NULL))
340: {
341: DISPDBG((0, "vga.dll getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
342: DISPDBG((0, "Win32 Status = %x\n", GetLastError() ));
343: return(0);
344: }
345:
346: *cbModeSize = modes.ModeInformationLength;
347:
348: //
349: // Allocate the buffer for the mini-port to write the modes in.
350: //
351:
352: *modeInformation = (PVIDEO_MODE_INFORMATION)
353: LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
354: modes.NumModes *
355: modes.ModeInformationLength);
356:
357: if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
358: {
359: DISPDBG((0, "vga.dll getAvailableModes failed LocalAlloc\n"));
360:
361: return 0;
362: }
363:
364: //
365: // Ask the mini-port to fill in the available modes.
366: //
367:
368: if (!DeviceIoControl(hDriver,
369: IOCTL_VIDEO_QUERY_AVAIL_MODES,
370: NULL,
371: 0,
372: *modeInformation,
373: modes.NumModes * modes.ModeInformationLength,
374: &ulTemp,
375: NULL))
376: {
377:
378: DISPDBG((0, "vga.dll getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
379: DISPDBG((0, "Win32 Status = %x\n", GetLastError() ));
380:
381: LocalFree(*modeInformation);
382: *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
383:
384: return(0);
385: }
386:
387: //
388: // Now see which of these modes are supported by the display driver.
389: // As an internal mechanism, set the length to 0 for the modes we
390: // DO NOT support.
391: //
392:
393: ulTemp = modes.NumModes;
394: pVideoTemp = *modeInformation;
395:
396: //
397: // Mode is rejected if it is not 4 planes, or not graphics, or is not
398: // one of 1 bits per pel.
399: //
400:
401: while (ulTemp--)
402: {
403: if ((pVideoTemp->NumberOfPlanes != 4 ) ||
404: !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
405: (pVideoTemp->BitsPerPlane != 1))
406: {
407: pVideoTemp->Length = 0;
408: }
409:
410: pVideoTemp = (PVIDEO_MODE_INFORMATION)
411: (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
412: }
413:
414: return modes.NumModes;
415:
416: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.