[VGA/VGA_NEW]
[reactos.git] / reactos / win32ss / drivers / miniport / vga / vgamp.c
1 /*
2 * VGA.C - a generic VGA miniport driver
3 *
4 */
5
6 // ------------------------------------------------------- Includes
7
8 #include "vgamp.h"
9
10 // ------------------------------------------------------- Public Interface
11
12 // DriverEntry
13 //
14 // DESCRIPTION:
15 // This function initializes the driver.
16 //
17 // RUN LEVEL:
18 // PASSIVE_LEVEL
19 //
20 // ARGUMENTS:
21 // IN PVOID Context1 Context parameter to pass to VidPortInitialize
22 // IN PVOID Context2 Context parameter to pass to VidPortInitialize
23 // RETURNS:
24 // ULONG
25
26 ULONG NTAPI
27 DriverEntry(IN PVOID Context1,
28 IN PVOID Context2)
29 {
30 VIDEO_HW_INITIALIZATION_DATA InitData;
31
32 VideoPortZeroMemory(&InitData, sizeof InitData);
33
34 InitData.HwInitDataSize = sizeof(InitData);
35 /* FIXME: Fill in InitData members */
36 InitData.StartingDeviceNumber = 0;
37
38 /* Export driver entry points... */
39 InitData.HwFindAdapter = VGAFindAdapter;
40 InitData.HwInitialize = VGAInitialize;
41 InitData.HwStartIO = VGAStartIO;
42 /* InitData.HwInterrupt = VGAInterrupt; */
43 InitData.HwResetHw = VGAResetHw;
44 /* InitData.HwTimer = VGATimer; */
45
46 return VideoPortInitialize(Context1, Context2, &InitData, NULL);
47 }
48
49 // VGAFindAdapter
50 //
51 // DESCRIPTION:
52 // This routine is called by the videoport driver to find and allocate
53 // the adapter for a given bus. The miniport driver needs to do the
54 // following in this routine:
55 // - Determine if the adapter is present
56 // - Claim any necessary memory/IO resources for the adapter
57 // - Map resources into system memory for the adapter
58 // - fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer
59 // - update registry settings for adapter specifics.
60 // - Set 'Again' based on whether the function should be called again
61 // another adapter on the same bus.
62 //
63 // RUN LEVEL:
64 // PASSIVE_LEVEL
65 //
66 // ARGUMENTS:
67 // PVOID DeviceExtension
68 // PVOID Context
69 // PWSTR ArgumentString
70 // PVIDEO_PORT_CONFIG_INFO ConfigInfo
71 // PUCHAR Again
72 // RETURNS:
73 // VP_STATUS
74
75 VP_STATUS NTAPI
76 VGAFindAdapter(PVOID DeviceExtension,
77 PVOID Context,
78 PWSTR ArgumentString,
79 PVIDEO_PORT_CONFIG_INFO ConfigInfo,
80 PUCHAR Again)
81 {
82 /* FIXME: Determine if the adapter is present */
83 *Again = FALSE;
84
85 return NO_ERROR;
86
87 /* FIXME: Claim any necessary memory/IO resources for the adapter */
88 /* FIXME: Map resources into system memory for the adapter */
89 /* FIXME: Fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer */
90 /* FIXME: Update registry settings for adapter specifics. */
91 // return NO_ERROR;
92 }
93
94 // VGAInitialize
95 //
96 // DESCRIPTION:
97 // Perform initialization tasks, but leave the adapter in the same
98 // user visible state
99 //
100 // RUN LEVEL:
101 // PASSIVE_LEVEL
102 //
103 // ARGUMENTS:
104 // PVOID DeviceExtension
105 // RETURNS:
106 // BOOLEAN Success or failure
107 BOOLEAN NTAPI
108 VGAInitialize(PVOID DeviceExtension)
109 {
110 return TRUE;
111 }
112
113 // VGAStartIO
114 //
115 // DESCRIPTION:
116 // This function gets called in responce to GDI EngDeviceIoControl
117 // calls. Device requests are passed in VRPs.
118 // Required VRPs:
119 // IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
120 // IOCTL_VIDEO_QUERY_AVAIL_MODES
121 // IOCTL_VIDEO_QUERY_CURRENT_MODE
122 // IOCTL_VIDEO_SET_CURRENT_MODE
123 // IOCTL_VIDEO_RESET_DEVICE
124 // IOCTL_VIDEO_MAP_VIDEO_MEMORY
125 // IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
126 // IOCTL_VIDEO_SHARE_VIDEO_MEMORY
127 // IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
128 // Optional VRPs:
129 // IOCTL_VIDEO_GET_PUBLIC_ACCESS_RANGES
130 // IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
131 // IOCTL_VIDEO_GET_POWER_MANAGEMENT
132 // IOCTL_VIDEO_SET_POWER_MANAGEMENT
133 // IOCTL_QUERY_COLOR_CAPABILITIES
134 // IOCTL_VIDEO_SET_COLOR_REGISTERS (required if the device has a palette)
135 // IOCTL_VIDEO_DISABLE_POINTER
136 // IOCTL_VIDEO_ENABLE_POINTER
137 // IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
138 // IOCTL_VIDEO_QUERY_POINTER_ATTR
139 // IOCTL_VIDEO_SET_POINTER_ATTR
140 // IOCTL_VIDEO_QUERY_POINTER_POSITION
141 // IOCTL_VIDEO_SET_POINTER_POSITION
142 // IOCTL_VIDEO_SAVE_HARDWARE_STATE
143 // IOCTL_VIDEO_RESTORE_HARDWARE_STATE
144 // IOCTL_VIDEO_DISABLE_CURSOR
145 // IOCTL_VIDEO_ENABLE_CURSOR
146 // IOCTL_VIDEO_QUERY_CURSOR_ATTR
147 // IOCTL_VIDEO_SET_CURSOR_ATTR
148 // IOCTL_VIDEO_QUERY_CURSOR_POSITION
149 // IOCTL_VIDEO_SET_CURSOR_POSITION
150 // IOCTL_VIDEO_GET_BANK_SELECT_CODE
151 // IOCTL_VIDEO_SET_PALETTE_REGISTERS
152 // IOCTL_VIDEO_LOAD_AND_SET_FONT
153 //
154 // RUN LEVEL:
155 // PASSIVE_LEVEL
156 //
157 // ARGUMENTS:
158 // PVOID DeviceExtension
159 // PVIDEO_REQUEST_PACKET RequestPacket
160 // RETURNS:
161 // BOOLEAN This function must return TRUE, and complete the work or
162 // set an error status in the VRP.
163
164 BOOLEAN NTAPI
165 VGAStartIO(PVOID DeviceExtension,
166 PVIDEO_REQUEST_PACKET RequestPacket)
167 {
168 BOOLEAN Result;
169
170 RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
171
172 switch (RequestPacket->IoControlCode)
173 {
174 case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
175 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
176 RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
177 {
178 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
179 return TRUE;
180 }
181 Result = VGAMapVideoMemory(DeviceExtension,
182 (PVIDEO_MEMORY) RequestPacket->InputBuffer,
183 (PVIDEO_MEMORY_INFORMATION)
184 RequestPacket->OutputBuffer,
185 RequestPacket->StatusBlock);
186 break;
187
188 case IOCTL_VIDEO_QUERY_AVAIL_MODES:
189 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
190 {
191 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
192 return TRUE;
193 }
194 Result = VGAQueryAvailModes((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
195 RequestPacket->StatusBlock);
196 break;
197
198 case IOCTL_VIDEO_QUERY_CURRENT_MODE:
199 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
200 {
201 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
202 return TRUE;
203 }
204 Result = VGAQueryCurrentMode((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
205 RequestPacket->StatusBlock);
206 break;
207
208 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
209 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES))
210 {
211 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
212 return TRUE;
213 }
214 Result = VGAQueryNumAvailModes((PVIDEO_NUM_MODES) RequestPacket->OutputBuffer,
215 RequestPacket->StatusBlock);
216 break;
217
218 case IOCTL_VIDEO_RESET_DEVICE:
219 VGAResetDevice(RequestPacket->StatusBlock);
220 Result = TRUE;
221 break;
222
223 case IOCTL_VIDEO_SET_COLOR_REGISTERS:
224 if (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) ||
225 RequestPacket->InputBufferLength <
226 (((PVIDEO_CLUT)RequestPacket->InputBuffer)->NumEntries * sizeof(ULONG)) +
227 FIELD_OFFSET(VIDEO_CLUT, LookupTable))
228 {
229 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
230 return TRUE;
231 }
232 Result = VGASetColorRegisters((PVIDEO_CLUT) RequestPacket->InputBuffer,
233 RequestPacket->StatusBlock);
234 break;
235
236 case IOCTL_VIDEO_SET_CURRENT_MODE:
237 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
238 {
239 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
240 return TRUE;
241 }
242 Result = VGASetCurrentMode((PVIDEO_MODE) RequestPacket->InputBuffer,
243 RequestPacket->StatusBlock);
244 break;
245
246 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
247 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
248 RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY))
249 {
250 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
251 return TRUE;
252 }
253 Result = VGAShareVideoMemory((PVIDEO_SHARE_MEMORY) RequestPacket->InputBuffer,
254 (PVIDEO_MEMORY_INFORMATION) RequestPacket->OutputBuffer,
255 RequestPacket->StatusBlock);
256 break;
257
258 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
259 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
260 {
261 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
262 return TRUE;
263 }
264 Result = VGAUnmapVideoMemory(DeviceExtension,
265 (PVIDEO_MEMORY) RequestPacket->InputBuffer,
266 RequestPacket->StatusBlock);
267 break;
268
269 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
270 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
271 {
272 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
273 return TRUE;
274 }
275 Result = VGAUnshareVideoMemory((PVIDEO_MEMORY) RequestPacket->InputBuffer,
276 RequestPacket->StatusBlock);
277 break;
278 case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
279 Result = VGASetPaletteRegisters((PUSHORT) RequestPacket->InputBuffer,
280 RequestPacket->StatusBlock);
281 break;
282
283 #if 0
284 case IOCTL_VIDEO_DISABLE_CURSOR:
285 case IOCTL_VIDEO_DISABLE_POINTER:
286 case IOCTL_VIDEO_ENABLE_CURSOR:
287 case IOCTL_VIDEO_ENABLE_POINTER:
288
289 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
290 VGAFreePublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES)
291 RequestPacket->InputBuffer,
292 RequestPacket->StatusBlock);
293 break;
294
295 case IOCTL_VIDEO_GET_BANK_SELECT_CODE:
296 case IOCTL_VIDEO_GET_POWER_MANAGEMENT:
297 case IOCTL_VIDEO_LOAD_AND_SET_FONT:
298 case IOCTL_VIDEO_QUERY_CURSOR_POSITION:
299 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES:
300 case IOCTL_VIDEO_QUERY_CURSOR_ATTR:
301 case IOCTL_VIDEO_QUERY_POINTER_ATTR:
302 case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
303 case IOCTL_VIDEO_QUERY_POINTER_POSITION:
304
305 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
306 VGAQueryPublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES)
307 RequestPacket->OutputBuffer,
308 RequestPacket->StatusBlock);
309 break;
310
311 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
312 case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
313 case IOCTL_VIDEO_SET_CURSOR_ATTR:
314 case IOCTL_VIDEO_SET_CURSOR_POSITION:
315 case IOCTL_VIDEO_SET_POINTER_ATTR:
316 case IOCTL_VIDEO_SET_POINTER_POSITION:
317 case IOCTL_VIDEO_SET_POWER_MANAGEMENT:
318
319 #endif
320
321 default:
322 RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
323 return FALSE;
324 }
325
326 if (Result)
327 RequestPacket->StatusBlock->Status = NO_ERROR;
328
329 return TRUE;
330 }
331
332 #if 0
333 // VGAInterrupt
334 //
335 // DESCRIPTION:
336 // This function will be called upon receipt of a adapter generated
337 // interrupt when enabled.
338 //
339 // RUN LEVEL:
340 // IRQL
341 //
342 // ARGUMENTS:
343 // PVOID DeviceExtension
344 // RETURNS:
345 // BOOLEAN TRUE if the interrupt was handled by the routine
346
347 static BOOLEAN NTAPI
348 VGAInterrupt(PVOID DeviceExtension)
349 {
350 return(TRUE);
351 }
352 #endif
353
354 // VGAResetHw
355 //
356 // DESCRIPTION:
357 // This function is called to reset the hardware to a known state
358 // if calling a BIOS int 10 reset will not achieve this result.
359 //
360 // RUN LEVEL:
361 // PASSIVE_LEVEL
362 //
363 // ARGUMENTS:
364 // PVOID DeviceExtension
365 // ULONG Columns Columns and Rows specify the mode parameters
366 // ULONG Rows to reset to.
367 // RETURNS:
368 // BOOLEAN TRUE if no further action is necessary, FALSE if the system
369 // needs to still do a BIOS int 10 reset.
370
371 BOOLEAN NTAPI
372 VGAResetHw(PVOID DeviceExtension,
373 ULONG Columns,
374 ULONG Rows)
375 {
376 /* We don't anything to the vga that int10 can't cope with. */
377 return(FALSE);
378 }
379
380 #if 0
381 // VGATimer
382 //
383 // DESCRIPTION:
384 // This function will be called once a second when enabled
385 //
386 // RUN LEVEL:
387 // PASSIVE_LEVEL
388 //
389 // ARGUMENTS:
390 // PVOID DeviceExtension
391 // RETURNS:
392 // VOID
393
394 static VOID NTAPI
395 VGATimer(PVOID DeviceExtension)
396 {
397 }
398
399 #endif
400
401 BOOLEAN VGAMapVideoMemory(IN PVOID DeviceExtension,
402 IN PVIDEO_MEMORY RequestedAddress,
403 OUT PVIDEO_MEMORY_INFORMATION MapInformation,
404 OUT PSTATUS_BLOCK StatusBlock)
405 {
406 ULONG ReturnedLength;
407 PVOID ReturnedAddress;
408 ULONG IoSpace;
409 PHYSICAL_ADDRESS FrameBufferBase;
410 ReturnedAddress = RequestedAddress->RequestedVirtualAddress;
411 ReturnedLength = 256 * 1024;
412 FrameBufferBase.QuadPart = 0xA0000;
413 IoSpace = VIDEO_MEMORY_SPACE_MEMORY;
414 StatusBlock->Status = VideoPortMapMemory(DeviceExtension,
415 FrameBufferBase,
416 &ReturnedLength,
417 &IoSpace,
418 &ReturnedAddress);
419 if (StatusBlock->Status != 0)
420 {
421 StatusBlock->Information = 0;
422 return TRUE;
423 }
424 MapInformation->VideoRamBase = MapInformation->FrameBufferBase =
425 ReturnedAddress;
426 MapInformation->VideoRamLength = MapInformation->FrameBufferLength =
427 ReturnedLength;
428 StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
429 return TRUE;
430 }
431
432 BOOLEAN VGAQueryAvailModes(OUT PVIDEO_MODE_INFORMATION ReturnedModes,
433 OUT PSTATUS_BLOCK StatusBlock)
434 {
435 /* Only one mode exists in VGA (640x480), so use VGAQueryCurrentMode */
436 return VGAQueryCurrentMode(ReturnedModes, StatusBlock);
437 }
438
439 BOOLEAN VGAQueryCurrentMode(OUT PVIDEO_MODE_INFORMATION CurrentMode,
440 OUT PSTATUS_BLOCK StatusBlock)
441 {
442 CurrentMode->Length = sizeof(VIDEO_MODE_INFORMATION);
443 CurrentMode->ModeIndex = 2;
444 CurrentMode->VisScreenWidth = 640;
445 CurrentMode->VisScreenHeight = 480;
446 CurrentMode->ScreenStride = 80;
447 CurrentMode->NumberOfPlanes = 4;
448 CurrentMode->BitsPerPlane = 1;
449 CurrentMode->Frequency = 60;
450 CurrentMode->XMillimeter = 320;
451 CurrentMode->YMillimeter = 240;
452 CurrentMode->NumberRedBits =
453 CurrentMode->NumberGreenBits =
454 CurrentMode->NumberBlueBits = 6;
455 CurrentMode->RedMask =
456 CurrentMode->GreenMask =
457 CurrentMode->BlueMask = 0;
458 CurrentMode->VideoMemoryBitmapWidth = 640;
459 CurrentMode->VideoMemoryBitmapHeight = 480;
460 CurrentMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
461 VIDEO_MODE_NO_OFF_SCREEN;
462 CurrentMode->DriverSpecificAttributeFlags = 0;
463
464 StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);
465 return TRUE;
466 }
467
468 BOOLEAN VGAQueryNumAvailModes(OUT PVIDEO_NUM_MODES NumberOfModes,
469 OUT PSTATUS_BLOCK StatusBlock)
470 {
471 NumberOfModes->NumModes = 1;
472 NumberOfModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
473 StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
474 return TRUE;
475 }
476
477 BOOLEAN VGASetPaletteRegisters(IN PUSHORT PaletteRegisters,
478 OUT PSTATUS_BLOCK StatusBlock)
479 {
480 ;
481
482 /*
483 We don't need the following code because the palette registers are set correctly on VGA initialization.
484 Still, we may include\test this is in the future.
485
486 int i, j = 2;
487 char tmp, v;
488
489 tmp = VideoPortReadPortUchar(0x03da);
490 v = VideoPortReadPortUchar(0x03c0);
491
492 // Set the first 16 palette registers to map to the first 16 palette colors
493 for (i=PaletteRegisters[1]; i<PaletteRegisters[0]; i++)
494 {
495 tmp = VideoPortReadPortUchar(0x03da);
496 VideoPortWritePortUchar(0x03c0, i);
497 VideoPortWritePortUchar(0x03c0, PaletteRegisters[j++]);
498 }
499
500 tmp = VideoPortReadPortUchar(0x03da);
501 VideoPortWritePortUchar(0x03d0, v | 0x20);
502 */
503 return TRUE;
504 }
505
506 BOOLEAN VGASetColorRegisters(IN PVIDEO_CLUT ColorLookUpTable,
507 OUT PSTATUS_BLOCK StatusBlock)
508 {
509 int i;
510
511 for (i=ColorLookUpTable->FirstEntry; i<ColorLookUpTable->NumEntries; i++)
512 {
513 VideoPortWritePortUchar((PUCHAR)0x03c8, i);
514 VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Red);
515 VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Green);
516 VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Blue);
517 }
518
519 return TRUE;
520 }
521
522 BOOLEAN VGASetCurrentMode(IN PVIDEO_MODE RequestedMode,
523 OUT PSTATUS_BLOCK StatusBlock)
524 {
525 if(RequestedMode->RequestedMode == 12)
526 {
527 InitVGAMode();
528 return TRUE;
529 } else {
530 VideoPortDebugPrint(Warn, "Unrecognised mode for VGASetCurrentMode\n");
531 return FALSE;
532 }
533 }
534
535 BOOLEAN VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY RequestedMemory,
536 OUT PVIDEO_MEMORY_INFORMATION ReturnedMemory,
537 OUT PSTATUS_BLOCK StatusBlock)
538 {
539 UNIMPLEMENTED;
540
541 StatusBlock->Status = ERROR_INVALID_FUNCTION;
542 return FALSE;
543 }
544
545 BOOLEAN VGAUnmapVideoMemory(IN PVOID DeviceExtension,
546 IN PVIDEO_MEMORY MemoryToUnmap,
547 OUT PSTATUS_BLOCK StatusBlock)
548 {
549 if (VideoPortUnmapMemory(DeviceExtension,
550 MemoryToUnmap->RequestedVirtualAddress,
551 0) == NO_ERROR)
552 return TRUE;
553 else
554 return FALSE;
555 }
556
557 BOOLEAN VGAUnshareVideoMemory(IN PVIDEO_MEMORY MemoryToUnshare,
558 OUT PSTATUS_BLOCK StatusBlock)
559 {
560 UNIMPLEMENTED;
561
562 StatusBlock->Status = ERROR_INVALID_FUNCTION;
563 return FALSE;
564 }