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