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