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 } 568