|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1990-1992 Microsoft Corporation
4:
5: Module Name:
6:
7: jzvxl484.c
8:
9: Abstract:
10:
11: This module contains the code that implements the Jazz kernel
12: video driver for the VXL graphics accelerator board.
13:
14: Environment:
15:
16: Kernel mode
17:
18: Revision History:
19:
20: --*/
21:
22: #include "dderror.h"
23: #include "devioctl.h"
24: #include "miniport.h"
25:
26: #include "ntddvdeo.h"
27: #include "video.h"
28:
29: #include "jaginit.h"
30: #include "jzvxldat.h"
31:
32: #include "jazzvdeo.h"
33: #include "jzvxl484.h"
34:
35: #define VXL_NAME L"VXL"
36: #define VXL_NAME_LENGTH 8
37:
38: //
39: // Define macros to access video memory, jaguar base registers, jaguar fifo registers,
40: // the Bt484, ICS1494 clock chip and Board ROM.
41: //
42:
43: #define VXL_JAGUAR_BASE ((PJAGUAR_REGISTERS)((ULONG)hwDeviceExtension->VideoAddress + VXL_JAGUAR_BASE_OFFSET))
44: #define VXL_FIFO_BASE ((PJAGUAR_FIFO)((ULONG)hwDeviceExtension->FrameAddress + VXL_FIFO_BASE_OFFSET))
45: #define VXL_BT484_BASE ((PBT484_REGISTERS)((ULONG)hwDeviceExtension->VideoAddress + VXL_BT484_BASE_OFFSET))
46: #define VXL_CLOCK_BASE ((PVXL_BYTE_REGISTER)((ULONG)hwDeviceExtension->VideoAddress + VXL_CLOCK_BASE_OFFSET))
47:
48:
49: //
50: // Define device extension structure.
51: //
52:
53: typedef struct _HW_DEVICE_EXTENSION {
54: PHYSICAL_ADDRESS PhysicalFrameAddress;
55: PHYSICAL_ADDRESS PhysicalFifoAddress;
56: ULONG PhysicalFifoLength;
57: PHYSICAL_ADDRESS PhysicalControlAddress;
58: union {
59: VIDEO_CLUTDATA RgbData;
60: ULONG RgbLong;
61: } ColorMap[NUMBER_OF_COLORS];
62: PVOID VideoAddress;
63: PVOID FrameAddress;
64: ULONG FrameLength;
65: ULONG PhysicalControlLength;
66: USHORT FirstEntry;
67: USHORT LastEntry;
68: USHORT CursorControlOn;
69: USHORT CursorControlOff;
70: USHORT CursorWidth;
71: USHORT CursorHeight;
72: SHORT CursorColumn;
73: SHORT CursorRow;
74: USHORT CursorPixels[VXL_CURSOR_NUMBER_OF_BYTES];
75: USHORT CursorXOrigin;
76: USHORT CursorYOrigin;
77: USHORT HorizontalResolution;
78: USHORT HorizontalDisplayTime;
79: USHORT HorizontalBackPorch;
80: USHORT HorizontalFrontPorch;
81: USHORT HorizontalSync;
82: USHORT HorizontalScreenSize;
83: USHORT VerticalResolution;
84: USHORT VerticalBackPorch;
85: USHORT VerticalFrontPorch;
86: USHORT VerticalSync;
87: USHORT VerticalScreenSize;
88: UCHAR CursorEnable;
89: UCHAR UpdateColorMap;
90: UCHAR UpdateCursorPosition;
91: UCHAR UpdateCursorPixels;
92: UCHAR UpdateController;
93: ULONG ModeNumber;
94: ULONG NumAvailableModes;
95: ULONG BoardType;
96: PVOID QueueAddress;
97: PVOID QueueSystemAddress;
98: ULONG QueueSize;
99: ULONG QueueNumberOfEntries;
100: HANDLE QueueFrameSection;
101: ULONG QueueReadPointer;
102: } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
103:
104:
105:
106: //
107: // Function Prototypes
108: //
109:
110: VP_STATUS
111: VxlFindAdapter(
112: PVOID HwDeviceExtension,
113: PVOID HwContext,
114: PWSTR ArgumentString,
115: PVIDEO_PORT_CONFIG_INFO ConfigInfo,
116: PUCHAR Again
117: );
118:
119: BOOLEAN
120: VxlInitialize(
121: PVOID HwDeviceExtension
122: );
123:
124: BOOLEAN
125: VxlInterruptService (
126: PVOID HwDeviceExtension
127: );
128:
129: BOOLEAN
130: VxlStartIO(
131: PVOID HwDeviceExtension,
132: PVIDEO_REQUEST_PACKET RequestPacket
133: );
134:
135: //
136: // Define device driver procedure prototypes.
137: //
138:
139: VP_STATUS
140: VxlGetDeviceDataCallback(
141: PVOID HwDeviceExtension,
142: PVOID Context,
143: VIDEO_DEVICE_DATA_TYPE DeviceDataType,
144: PVOID Identifier,
145: ULONG IdentifierLength,
146: PVOID ConfigurationData,
147: ULONG ConfigurationDataLength,
148: PVOID ComponentInformation,
149: ULONG ComponentInformationLength
150: );
151:
152: VOID
153: VxlSetMode(
154: PHW_DEVICE_EXTENSION hwDeviceExtension
155: );
156:
157:
158: ULONG
159: DriverEntry (
160: PVOID Context1,
161: PVOID Context2
162: )
163:
164: /*++
165:
166: Routine Description:
167:
168: Installable driver initialization entry point.
169: This entry point is called directly by the I/O system.
170:
171: Arguments:
172:
173: Context1 - First context value passed by the operating system. This is
174: the value with which the miniport driver calls VideoPortInitialize().
175:
176: Context2 - Second context value passed by the operating system. This is
177: the value with which the miniport driver calls VideoPortInitialize().
178:
179: Return Value:
180:
181: Status from VideoPortInitialize()
182:
183: --*/
184:
185: {
186:
187: VIDEO_HW_INITIALIZATION_DATA hwInitData;
188:
189: //
190: // Zero out structure.
191: //
192:
193: VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
194:
195: //
196: // Specify sizes of structure and extension.
197: //
198:
199: hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
200:
201: //
202: // Set entry points.
203: //
204:
205: hwInitData.HwFindAdapter = VxlFindAdapter;
206: hwInitData.HwInitialize = VxlInitialize;
207: hwInitData.HwInterrupt = VxlInterruptService;
208: hwInitData.HwStartIO = VxlStartIO;
209:
210: //
211: // Determine the size we require for the device extension.
212: //
213:
214: hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
215:
216: //
217: // Always start with parameters for device0 in this case.
218: //
219:
220: // hwInitData.StartingDeviceNumber = 0;
221:
222: //
223: // This device only supports the internal bus type. So return the status
224: // value directly to the operating system.
225: //
226:
227: hwInitData.AdapterInterfaceType = Internal;
228:
229: return VideoPortInitialize(Context1,
230: Context2,
231: &hwInitData,
232: NULL);
233:
234: } // end DriverEntry()
235:
236: VP_STATUS
237: VxlFindAdapter(
238: PVOID HwDeviceExtension,
239: PVOID HwContext,
240: PWSTR ArgumentString,
241: PVIDEO_PORT_CONFIG_INFO ConfigInfo,
242: PUCHAR Again
243: )
244:
245: /*++
246:
247: Routine Description:
248:
249: This routine is called to determine if the adapter for this driver
250: is present in the system.
251: If it is present, the function fills out some information describing
252: the adapter.
253:
254: Arguments:
255:
256: HwDeviceExtension - Supplies the miniport driver's adapter storage. This
257: storage is initialized to zero before this call.
258:
259: HwContext - Supplies the context value which was passed to
260: VideoPortInitialize().
261:
262: ArgumentString - Suuplies a NULL terminated ASCII string. This string
263: originates from the user.
264:
265: ConfigInfo - Returns the configuration information structure which is
266: filled by the miniport driver. This structure is initialized with
267: any knwon configuration information (such as SystemIoBusNumber) by
268: the port driver. Where possible, drivers should have one set of
269: defaults which do not require any supplied configuration information.
270:
271: Again - Indicates if the miniport driver wants the port driver to call
272: its VIDEO_HW_FIND_ADAPTER function again with a new device extension
273: and the same config info. This is used by the miniport drivers which
274: can search for several adapters on a bus.
275:
276: Return Value:
277:
278: This routine must return:
279:
280: NO_ERROR - Indicates a host adapter was found and the
281: configuration information was successfully determined.
282:
283: ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
284: error obtaining the configuration information. If possible an error
285: should be logged.
286:
287: ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
288: supplied configuration information.
289:
290: --*/
291:
292: {
293:
294: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
295:
296: //
297: // Make sure the size of the structure is at least as large as what we
298: // are expecting (check version of the config info structure).
299: //
300:
301:
302:
303: if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
304:
305: return ERROR_INVALID_PARAMETER;
306:
307: }
308:
309: if (VideoPortGetDeviceData(hwDeviceExtension,
310: VpControllerData,
311: &VxlGetDeviceDataCallback,
312: ConfigInfo)) {
313:
314: VideoDebugPrint((2, "Vxl: VideoPort get controller info failed\n"));
315:
316: return ERROR_INVALID_PARAMETER;
317:
318: }
319:
320: if (VideoPortGetDeviceData(hwDeviceExtension,
321: VpMonitorData,
322: &VxlGetDeviceDataCallback,
323: NULL)) {
324:
325: VideoDebugPrint((2, "Vxl: VideoPort get monitor info failed\n"));
326:
327: return ERROR_INVALID_PARAMETER;
328:
329: }
330:
331: //
332: // Clear out the Emulator entries and the state size since this driver
333: // does not support them.
334: //
335:
336: ConfigInfo->NumEmulatorAccessEntries = 0;
337: ConfigInfo->EmulatorAccessEntries = NULL;
338: ConfigInfo->EmulatorAccessEntriesContext = 0;
339:
340: ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
341: ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
342: ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
343:
344: ConfigInfo->HardwareStateSize = 0;
345:
346: //
347: // Initialize the color map update information.
348: //
349:
350: hwDeviceExtension->FirstEntry = 0;
351: hwDeviceExtension->LastEntry = 0;
352: hwDeviceExtension->UpdateController = FALSE;
353:
354: //
355: // Set cursor enable FALSE.
356: //
357:
358: hwDeviceExtension->CursorEnable = FALSE;
359:
360: //
361: // Indicate we do not wish to be called over
362: //
363:
364: *Again = 0;
365:
366: //
367: // Indicate a successful completion status.
368: //
369:
370: return NO_ERROR;
371:
372: } // end VxlFindAdapter()
373:
374: VP_STATUS
375: VxlGetDeviceDataCallback(
376: PVOID HwDeviceExtension,
377: PVOID Context,
378: VIDEO_DEVICE_DATA_TYPE DeviceDataType,
379: PVOID Identifier,
380: ULONG IdentifierLength,
381: PVOID ConfigurationData,
382: ULONG ConfigurationDataLength,
383: PVOID ComponentInformation,
384: ULONG ComponentInformationLength
385: )
386:
387: /*++
388:
389: Routine Description:
390:
391: Callback routine for the VideoPortGetDeviceData function.
392:
393: Arguments:
394:
395: HwDeviceExtension - Pointer to the miniport drivers device extension.
396:
397: Context - Context value passed to the VideoPortGetDeviceData function.
398:
399: DeviceDataType - The type of data that was requested in
400: VideoPortGetDeviceData.
401:
402: Identifier - Pointer to a string that contains the name of the device,
403: as setup by the ROM or ntdetect.
404:
405: IdentifierLength - Length of the Identifier string.
406:
407: ConfigurationData - Pointer to the configuration data for the device or
408: BUS.
409:
410: ConfigurationDataLength - Length of the data in the configurationData
411: field.
412:
413: ComponentInformation - Undefined.
414:
415: ComponentInformationLength - Undefined.
416:
417: Return Value:
418:
419: Returns NO_ERROR if the function completed properly.
420: Returns ERROR_DEV_NOT_EXIST if we did not find the device.
421: Returns ERROR_INVALID_PARAMETER otherwise.
422:
423: --*/
424:
425: {
426: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
427: PVIDEO_PORT_CONFIG_INFO ConfigInfo = Context;
428: PWCHAR identifier = Identifier;
429: PJAZZ_Vxl_CONFIGURATION_DATA VxlConfigData = ConfigurationData;
430: PMONITOR_CONFIG_DATA monitorConfigData = ConfigurationData;
431: VIDEO_ACCESS_RANGE accessRanges[2];
432: VP_STATUS status;
433: ULONG NameLength;
434:
435:
436: switch (DeviceDataType) {
437:
438: case VpControllerData:
439:
440: //
441: // BUGBUG because we had a RESOURCE LIST header at the top.
442: // + 8 should be the offset of the paertial resource descriptor
443: // in a full resource descriptor.
444: //
445:
446: VxlConfigData = (PJAZZ_Vxl_CONFIGURATION_DATA)(((PUCHAR)VxlConfigData) + 8);
447:
448: //
449: // Compare the name to what is should be. If it is wrong, then return
450: // an error and initialization will fail.
451: // What is the right way of doing this??
452: //
453:
454:
455: if ( VXL_NAME_LENGTH != VideoPortCompareMemory(identifier,
456: VXL_NAME,
457: VXL_NAME_LENGTH)) {
458:
459: return ERROR_DEV_NOT_EXIST;
460: }
461:
462: //
463: // Fill up the device extension and the configuration information
464: // with the appropriate data.
465: //
466:
467:
468: ConfigInfo->BusInterruptLevel = VxlConfigData->Irql;
469: ConfigInfo->BusInterruptVector = VxlConfigData->Vector;
470:
471: //
472: // Map in 4MB access ranges for VXL control and 4MB + 1 Page for
473: // Video Memory.
474: //
475:
476: accessRanges[0].RangeStart.HighPart = 0;
477: accessRanges[0].RangeStart.LowPart = 0x60000000;
478: accessRanges[0].RangeLength = 0x00400000;
479: accessRanges[0].RangeInIoSpace = 0;
480: accessRanges[0].RangeVisible = 0;
481: accessRanges[0].RangeShareable = 0;
482:
483: accessRanges[1].RangeStart.HighPart = 0;
484: accessRanges[1].RangeStart.LowPart = 0x40000000;
485: accessRanges[1].RangeLength = 0x00401000;
486: accessRanges[1].RangeInIoSpace = 0;
487: accessRanges[1].RangeVisible = 0;
488: accessRanges[1].RangeShareable = 0;
489:
490: //
491: // Check to see if there is a hardware resource conflict.
492: //
493:
494: status = VideoPortVerifyAccessRanges(HwDeviceExtension,
495: 2,
496: accessRanges);
497:
498: if (status != NO_ERROR) {
499:
500: return status;
501:
502: }
503:
504: //
505: // Save in device extension
506: //
507:
508: hwDeviceExtension->PhysicalFrameAddress.HighPart = 0;
509: hwDeviceExtension->PhysicalFrameAddress.LowPart = 0x40000000;
510: hwDeviceExtension->FrameLength = 0x00400000;
511:
512: hwDeviceExtension->PhysicalFifoAddress.HighPart = 0;
513: hwDeviceExtension->PhysicalFifoAddress.LowPart = 0x40400000;
514: hwDeviceExtension->PhysicalFifoLength = 0x1000;
515:
516: hwDeviceExtension->PhysicalControlAddress.HighPart = 0;
517: hwDeviceExtension->PhysicalControlAddress.LowPart = 0x60300000;
518: hwDeviceExtension->PhysicalControlLength = 0x1000;
519:
520: //
521: // Map the video controller into the system virtual address space.
522: //
523:
524: if ( (hwDeviceExtension->VideoAddress =
525: VideoPortGetDeviceBase(hwDeviceExtension,
526: accessRanges[0].RangeStart, // Control
527: accessRanges[0].RangeLength,
528: FALSE)) == NULL) {
529:
530: return ERROR_INVALID_PARAMETER;
531:
532: }
533:
534: //
535: // Map the video memory into the system virtual address space so we
536: // can clear it out.
537: //
538:
539: if ( (hwDeviceExtension->FrameAddress =
540: VideoPortGetDeviceBase(hwDeviceExtension,
541: accessRanges[1].RangeStart, // Frame
542: accessRanges[1].RangeLength,
543: FALSE)) == NULL) {
544:
545: return ERROR_INVALID_PARAMETER;
546:
547: }
548:
549: return NO_ERROR;
550:
551: break;
552:
553:
554: case VpMonitorData:
555:
556: VideoDebugPrint((2, "Vxl: getting monitor information\n"));
557:
558: //
559: // BUGBUG because we had a RESOURCE LIST header at the top.
560: // + 8 should be the offset of the paertial resource descriptor
561: // in a full resource descriptor.
562: //
563:
564: monitorConfigData = (PMONITOR_CONFIG_DATA)(((PUCHAR)monitorConfigData) + 8);
565:
566: //
567: // Initialize the monitor parameters.
568: //
569:
570: hwDeviceExtension->HorizontalResolution =
571: monitorConfigData->HorizontalResolution;
572:
573: hwDeviceExtension->HorizontalDisplayTime =
574: monitorConfigData->HorizontalDisplayTime;
575:
576: hwDeviceExtension->HorizontalBackPorch =
577: monitorConfigData->HorizontalBackPorch;
578:
579: hwDeviceExtension->HorizontalFrontPorch =
580: monitorConfigData->HorizontalFrontPorch;
581:
582: hwDeviceExtension->HorizontalSync =
583: monitorConfigData->HorizontalSync;
584:
585: hwDeviceExtension->HorizontalScreenSize =
586: monitorConfigData->HorizontalScreenSize;
587:
588: hwDeviceExtension->VerticalResolution =
589: monitorConfigData->VerticalResolution;
590:
591: hwDeviceExtension->VerticalBackPorch =
592: monitorConfigData->VerticalBackPorch;
593:
594: hwDeviceExtension->VerticalFrontPorch =
595: monitorConfigData->VerticalFrontPorch;
596:
597: hwDeviceExtension->VerticalSync =
598: monitorConfigData->VerticalSync;
599:
600: hwDeviceExtension->VerticalScreenSize =
601: monitorConfigData->VerticalScreenSize;
602:
603:
604: return NO_ERROR;
605:
606: break;
607:
608: default:
609:
610: return ERROR_INVALID_PARAMETER;
611:
612: }
613:
614: } //end VxlGetDeviceDataCallback()
615:
616: BOOLEAN
617: VxlInitialize(
618: PVOID HwDeviceExtension
619: )
620:
621: /*++
622:
623: Routine Description:
624:
625: This routine does one time initialization of the device.
626:
627: Arguments:
628:
629: HwDeviceExtension - Supplies a pointer to the miniport's device extension.
630:
631: Return Value:
632:
633: Always returns TRUE since this routine can never fail.
634:
635: --*/
636:
637: {
638:
639: PULONG buffer;
640: ULONG index,i;
641: ULONG limit;
642: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
643: UCHAR DataChar;
644: PBT484_REGISTERS Bt484 = VXL_BT484_BASE;
645:
646: //
647: // Determine if this is a Bt484 or Bt485 board. To do this write a 1 to
648: // command register bit 07 then write 01 to the address register 0. This
649: // will enable read/writes to command register 3 on a Bt485 but not on a
650: // Bt484. Clear Command register 3 then read it back. On a Bt485 the
651: // return value will be 0x00, on a Bt484 it will be 0x40.
652: //
653:
654: //
655: // Get the value in command register 0, then set bit 07
656: //
657:
658: DataChar = VideoPortReadRegisterUchar(&Bt484->Command0.Byte);
659: DataChar |= 0x80;
660: VideoPortWriteRegisterUchar(&Bt484->Command0.Byte,DataChar);
661:
662: //
663: // Write 0x01 to the address register
664: //
665:
666: VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0x01);
667:
668: //
669: // Clear command register 3
670: //
671:
672: VideoPortWriteRegisterUchar(&Bt484->Status.Byte,0x00);
673:
674: //
675: // Read Command Register 3 back and compare
676: //
677:
678: DataChar = VideoPortReadRegisterUchar(&Bt484->Status.Byte);
679:
680: if (DataChar == 0x00) {
681:
682: //
683: // This is a Bt485
684: //
685:
686: hwDeviceExtension->BoardType = BOARD_TYPE_BT485;
687:
688: } else {
689:
690: //
691: // This is a Bt484
692: //
693:
694: hwDeviceExtension->BoardType = BOARD_TYPE_BT484;
695:
696: }
697:
698: //
699: // Calculated the number of valid modes
700: //
701:
702: hwDeviceExtension->NumAvailableModes = 0;
703:
704: for (i = 0; i < JAG_MAX_MODE; i++) {
705:
706: if (JagModes[i].SupportedBoard & hwDeviceExtension->BoardType) {
707:
708: hwDeviceExtension->NumAvailableModes++;
709:
710: }
711: }
712:
713: //
714: // Initialize the color map copy in the device extension.
715: //
716:
717: for (index = 0; index < NUMBER_OF_COLORS; index++) {
718:
719: hwDeviceExtension->ColorMap[index].RgbData.Red =
720: ((index & 0x7) << 2) | ((index & 0x7) << 5);
721: hwDeviceExtension->ColorMap[index].RgbData.Green =
722: ((index & 0x38) >> 1) | ((index & 0x38) << 2);
723: hwDeviceExtension->ColorMap[index].RgbData.Blue =
724: ((index & 0xc0) >> 6) | ((index & 0xc0) >> 4) |
725: ((index & 0xc0) >> 2) | (index & 0xc0);
726: }
727:
728: //
729: // Set colors for map entries 0 and 1 which are used by text output
730: // and the hardware cursor.
731: //
732:
733: hwDeviceExtension->ColorMap[0].RgbData.Red = 255;
734: hwDeviceExtension->ColorMap[0].RgbData.Green = 255;
735: hwDeviceExtension->ColorMap[0].RgbData.Blue = 255;
736: hwDeviceExtension->ColorMap[1].RgbData.Red = 0;
737: hwDeviceExtension->ColorMap[1].RgbData.Green = 0;
738: hwDeviceExtension->ColorMap[1].RgbData.Blue = 0x90;
739:
740: //
741: // Set color map update parameters and enable update on next vertical
742: // retrace interrupt.
743: //
744:
745: hwDeviceExtension->FirstEntry = 0;
746: hwDeviceExtension->LastEntry = NUMBER_OF_COLORS - 1;
747: hwDeviceExtension->UpdateColorMap = TRUE;
748:
749: //
750: // Set the hardware cursor width, height, column, and row values.
751: //
752:
753: hwDeviceExtension->CursorWidth = VXL_CURSOR_WIDTH;
754: hwDeviceExtension->CursorHeight = VXL_CURSOR_HEIGHT;
755: hwDeviceExtension->CursorColumn = 0;
756: hwDeviceExtension->CursorRow = 0;
757:
758: //
759: // Set the cursor offsets
760: //
761:
762:
763: hwDeviceExtension->CursorXOrigin = 32;
764: hwDeviceExtension->CursorYOrigin = 32;
765:
766: //
767: // Set the device extension copy of the hardware cursor ram memory.
768: //
769:
770: for (index = 0; index < VXL_CURSOR_NUMBER_OF_BYTES ; index++) {
771: hwDeviceExtension->CursorPixels[index] = 0x00ff;
772: }
773:
774: //
775: // Leave the cursor disabled until it is explicitly enabled
776: // attributes. This is the default values in the device extension.
777: //
778: // hwDeviceExtension->CursorEnable = FALSE;
779: // hwDeviceExtension->UpdateCursorPixels = FALSE;
780: // hwDeviceExtension->UpdateCursorPosition = FALSE;
781: //
782:
783: //
784: // Enable the vertical retrace interrupt to set up color map.
785: //
786:
787: VideoPortEnableInterrupt(hwDeviceExtension);
788: VideoPortWriteRegisterUchar(&VXL_JAGUAR_BASE->InterruptEnable.Byte,
789: VXL_INTERRUPT_VERTICAL_RETRACE);
790:
791:
792: return TRUE;
793:
794: } // end VxlInitialize()
795:
796: BOOLEAN
797: VxlStartIO(
798: PVOID HwDeviceExtension,
799: PVIDEO_REQUEST_PACKET RequestPacket
800: )
801:
802: /*++
803:
804: Routine Description:
805:
806: This routine is the main execution routine for the miniport driver. It
807: accepts0s a Video Request Packet, performs the request, and then returns
808: with the appropriate status.
809:
810: Arguments:
811:
812: HwDeviceExtension - Supplies a pointer to the miniport's device extension.
813:
814: RequestPacket - Pointer to the video request packet. This structure
815: contains all the parameters passed to the VideoIoControl function.
816:
817: Return Value:
818:
819:
820: --*/
821:
822: {
823: VP_STATUS status;
824: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
825: ULONG inIoSpace;
826: PULONG colorSource;
827: PVIDEO_MODE_INFORMATION modeInformation;
828: PVIDEO_POINTER_ATTRIBUTES pointerAttributes;
829: PVIDEO_MEMORY_INFORMATION memoryInformation;
830: PVIDEO_POINTER_CAPABILITIES VideoPointerCapabilities;
831: PVIDEO_POINTER_POSITION pointerPostion;
832: PVIDEO_CLUT clutBuffer;
833: ULONG index1;
834: ULONG index2;
835: ULONG CursorMaskSize;
836: PUCHAR pixelDestination;
837: ULONG pixelIndex;
838: ULONG pixelShift;
839: PUCHAR pixelSource;
840: UCHAR pixelValue;
841: UCHAR turnOnInterrupts = FALSE;
842: ULONG i;
843:
844: //
845: // Switch on the IoContolCode in the RequestPacket. It indicates which
846: // function must be performed by the driver.
847: //
848:
849: switch (RequestPacket->IoControlCode) {
850:
851:
852: case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
853:
854: VideoDebugPrint((2, "VxlStartIO - MapVideoMemory\n"));
855:
856: if ( (RequestPacket->OutputBufferLength <
857: (RequestPacket->StatusBlock->Information =
858: sizeof(VIDEO_MEMORY_INFORMATION))) ||
859: (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
860:
861: status = ERROR_INSUFFICIENT_BUFFER;
862:
863: } else {
864:
865: memoryInformation = RequestPacket->OutputBuffer;
866:
867: memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
868: (RequestPacket->InputBuffer))->RequestedVirtualAddress;
869:
870: memoryInformation->VideoRamLength =
871: hwDeviceExtension->FrameLength;
872:
873: inIoSpace = 0;
874:
875: status = VideoPortMapMemory(hwDeviceExtension,
876: hwDeviceExtension->PhysicalFrameAddress,
877: &(memoryInformation->VideoRamLength),
878: &inIoSpace,
879: &(memoryInformation->VideoRamBase));
880:
881: //
882: // The frame buffer and virtual memory and equivalent in this
883: // case.
884: //
885:
886: memoryInformation->FrameBufferBase =
887: memoryInformation->VideoRamBase;
888:
889: memoryInformation->FrameBufferLength =
890: memoryInformation->VideoRamLength;
891: }
892:
893: break;
894:
895:
896: case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
897:
898: VideoDebugPrint((2, "VxlStartIO - UnMapVideoMemory\n"));
899:
900: if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
901:
902: status = ERROR_INSUFFICIENT_BUFFER;
903: } else {
904:
905: status = VideoPortUnmapMemory(hwDeviceExtension,
906: ((PVIDEO_MEMORY)
907: (RequestPacket->InputBuffer))->
908: RequestedVirtualAddress,
909: 0);
910: }
911:
912: break;
913:
914:
915: case IOCTL_VIDEO_QUERY_AVAIL_MODES:
916:
917: VideoDebugPrint((2, "VxlStartIO - QueryAvailableModes\n"));
918:
919: if (RequestPacket->OutputBufferLength <
920: (RequestPacket->StatusBlock->Information =
921: hwDeviceExtension->NumAvailableModes *
922: sizeof(VIDEO_MODE_INFORMATION)) ) {
923:
924: status = ERROR_INSUFFICIENT_BUFFER;
925:
926: } else {
927:
928: modeInformation = RequestPacket->OutputBuffer;
929:
930: for (i = 0; i < JAG_MAX_MODE; i++) {
931:
932: if (JagModes[i].SupportedBoard & hwDeviceExtension->BoardType) {
933:
934: *modeInformation = JagModes[i].modeInformation;
935: modeInformation++;
936:
937: }
938: }
939:
940: status = NO_ERROR;
941: }
942:
943: break;
944:
945:
946: case IOCTL_VIDEO_QUERY_CURRENT_MODE:
947:
948: VideoDebugPrint((2, "VxlStartIO - Query(Available/Current)Modes\n"));
949:
950: if (RequestPacket->OutputBufferLength <
951: (RequestPacket->StatusBlock->Information =
952: sizeof(VIDEO_MODE_INFORMATION)) ) {
953:
954: status = ERROR_INSUFFICIENT_BUFFER;
955:
956: } else {
957:
958: *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
959: JagModes[hwDeviceExtension->ModeNumber].modeInformation;
960:
961: status = NO_ERROR;
962:
963: }
964:
965: break;
966:
967:
968: case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
969:
970:
971: VideoDebugPrint((2, "VxlStartIO - QueryNumAvailableModes\n"));
972:
973: //
974: // Find out the size of the data to be put in the the buffer and
975: // return that in the status information (whether or not the
976: // information is there). If the buffer passed in is not large
977: // enough return an appropriate error code.
978: //
979:
980: if (RequestPacket->OutputBufferLength <
981: (RequestPacket->StatusBlock->Information =
982: sizeof(VIDEO_NUM_MODES)) ) {
983:
984: status = ERROR_INSUFFICIENT_BUFFER;
985:
986: } else {
987:
988: ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
989: hwDeviceExtension->NumAvailableModes;
990:
991: ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
992: sizeof(VIDEO_MODE_INFORMATION);
993:
994: status = NO_ERROR;
995: }
996:
997: break;
998:
999:
1000: case IOCTL_VIDEO_SET_CURRENT_MODE:
1001:
1002:
1003: VideoDebugPrint((2, "VxlStartIO - SetCurrentMode\n"));
1004:
1005: if (*(ULONG *)(RequestPacket->InputBuffer) >= JAG_MAX_MODE) {
1006: status = ERROR_INVALID_PARAMETER;
1007: break;
1008: }
1009:
1010: hwDeviceExtension->ModeNumber = *(ULONG *)(RequestPacket->InputBuffer);
1011:
1012: VxlSetMode(hwDeviceExtension);
1013:
1014: status = NO_ERROR;
1015:
1016: break;
1017:
1018:
1019: case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
1020:
1021:
1022: VideoDebugPrint((2, "VxlStartIO - SetPaletteRegs\n"));
1023:
1024: status = NO_ERROR;
1025:
1026: break;
1027:
1028:
1029: case IOCTL_VIDEO_SET_COLOR_REGISTERS:
1030:
1031:
1032:
1033: VideoDebugPrint((2, "VxlStartIO - SetColorRegs\n"));
1034:
1035: clutBuffer = RequestPacket->InputBuffer;
1036:
1037: //
1038: // Check if the size of the data in the input buffer is large enough.
1039: //
1040:
1041: if ( (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) -
1042: sizeof(ULONG)) ||
1043: (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) +
1044: (sizeof(ULONG) * (clutBuffer->NumEntries - 1)) ) ) {
1045:
1046: status = ERROR_INSUFFICIENT_BUFFER;
1047: break;
1048:
1049: }
1050:
1051: //
1052: // Check to see if the parameters are valid.
1053: //
1054:
1055: if ( (clutBuffer->NumEntries == 0) ||
1056: (clutBuffer->FirstEntry > NUMBER_OF_COLORS) ||
1057: (clutBuffer->FirstEntry + clutBuffer->NumEntries >
1058: NUMBER_OF_COLORS + 1) ) {
1059:
1060: status = ERROR_INVALID_PARAMETER;
1061: break;
1062:
1063: }
1064:
1065: index1 = clutBuffer->FirstEntry;
1066: hwDeviceExtension->FirstEntry = index1;
1067: hwDeviceExtension->LastEntry = index1 + clutBuffer->NumEntries;
1068: colorSource = (PULONG)&(clutBuffer->LookupTable[0]);
1069:
1070: while (index1 < hwDeviceExtension->LastEntry) {
1071:
1072: hwDeviceExtension->ColorMap[index1++].RgbLong = *colorSource++;
1073:
1074: }
1075:
1076: //
1077: // Enable the verticle retrace interrupt to perform the update.
1078: //
1079:
1080: hwDeviceExtension->UpdateColorMap = TRUE;
1081: turnOnInterrupts = TRUE;
1082:
1083: status = NO_ERROR;
1084:
1085: break;
1086:
1087:
1088:
1089: case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
1090:
1091: //
1092: // return type of pointer supported: assyncronous monochrome
1093: //
1094:
1095:
1096: VideoPointerCapabilities = RequestPacket->OutputBuffer;
1097:
1098: if (RequestPacket->OutputBufferLength <
1099: (RequestPacket->StatusBlock->Information =
1100: sizeof(VIDEO_POINTER_CAPABILITIES)) ) {
1101:
1102: status = ERROR_INSUFFICIENT_BUFFER;
1103:
1104: } else {
1105: VideoPointerCapabilities->Flags = (VIDEO_MODE_ASYNC_POINTER |
1106: VIDEO_MODE_MONO_POINTER);
1107: VideoPointerCapabilities->MaxWidth = VXL_CURSOR_WIDTH;
1108: VideoPointerCapabilities->MaxHeight = VXL_CURSOR_HEIGHT;
1109: VideoPointerCapabilities->HWPtrBitmapStart = -1;
1110: VideoPointerCapabilities->HWPtrBitmapEnd = -1;
1111:
1112: status = NO_ERROR;
1113: }
1114:
1115: break;
1116:
1117: case IOCTL_VIDEO_ENABLE_POINTER:
1118:
1119: //
1120: // If the hardware cursor is currently disabled, then enable
1121: // it and update the cursor position and cursor ram memory.
1122: //
1123: // N.B. Explicit synchronization is required since the enable,
1124: // update cursor position, and update cursor pixels parameters
1125: // must all be atomically written.
1126: //
1127: //
1128: // Enable the verticle retrace interrupt to perform the update.
1129: //
1130:
1131: if (hwDeviceExtension->CursorEnable == FALSE) {
1132:
1133: hwDeviceExtension->CursorEnable = TRUE;
1134: hwDeviceExtension->UpdateCursorPixels = TRUE;
1135: hwDeviceExtension->UpdateCursorPosition = TRUE;
1136: turnOnInterrupts = TRUE;
1137: }
1138:
1139: status = NO_ERROR;
1140:
1141: break;
1142:
1143:
1144: case IOCTL_VIDEO_DISABLE_POINTER:
1145:
1146: VideoDebugPrint((2, "VxlStartIO - DisableCursor\n"));
1147:
1148: // If the hardware cursor is currently enabled, then disable
1149: // it and update the cursor position.
1150: //
1151: // N.B. Explicit synchronization is required since both the enable
1152: // and update cursor position parameters must be atomically
1153: // written.
1154: //
1155:
1156: //
1157: // Enable the verticle retrace interrupt to perform the update.
1158: //
1159:
1160: if (hwDeviceExtension->CursorEnable != FALSE) {
1161:
1162: hwDeviceExtension->CursorEnable = FALSE;
1163: hwDeviceExtension->UpdateCursorPosition = TRUE;
1164: turnOnInterrupts = TRUE;
1165:
1166: }
1167:
1168: status = NO_ERROR;
1169:
1170: break;
1171:
1172:
1173: case IOCTL_VIDEO_SET_POINTER_POSITION:
1174:
1175: VideoDebugPrint((2, "VxlStartIO - SetpointerPostion\n"));
1176:
1177: //
1178: // Check if the size of the data in the input buffer is large enough.
1179: //
1180:
1181: if (RequestPacket->InputBufferLength < sizeof(VIDEO_POINTER_POSITION)) {
1182:
1183: status = ERROR_INSUFFICIENT_BUFFER;
1184:
1185: } else {
1186:
1187: //
1188: // Capture the hardware cursor column and height values.
1189: //
1190:
1191: pointerPostion = RequestPacket->InputBuffer;
1192:
1193: hwDeviceExtension->CursorColumn = pointerPostion->Column;
1194: hwDeviceExtension->CursorRow = pointerPostion->Row;
1195:
1196: //
1197: // If the hardware cursor is not disabled, then update the
1198: // hardware cursor position.
1199: //
1200: // N.B. No explicit synchronization is required since only
1201: // the update cursor parameter needs to be written.
1202: //
1203:
1204: //
1205: // Enable the verticle retrace interrupt to perform the update.
1206: //
1207:
1208: hwDeviceExtension->UpdateCursorPosition = TRUE;
1209: turnOnInterrupts = TRUE;
1210:
1211: status = NO_ERROR;
1212:
1213: }
1214:
1215: break;
1216:
1217:
1218: case IOCTL_VIDEO_QUERY_POINTER_POSITION:
1219:
1220:
1221: //
1222: // Find out the size of the data to be put in the the buffer and
1223: // return that in the status information (whether or not the
1224: // information is there). If the buffer passed in is not large
1225: // enough return an appropriate error code.
1226: //
1227:
1228: if (RequestPacket->OutputBufferLength <
1229: (RequestPacket->StatusBlock->Information =
1230: sizeof(VIDEO_POINTER_POSITION)) ) {
1231:
1232: status = ERROR_INSUFFICIENT_BUFFER;
1233:
1234: } else {
1235:
1236: //
1237: // Return the current hardware cursor column and row values.
1238: //
1239:
1240: pointerPostion = RequestPacket->OutputBuffer;
1241:
1242: pointerPostion->Column = hwDeviceExtension->CursorColumn;
1243: pointerPostion->Row = hwDeviceExtension->CursorRow;
1244:
1245: status = NO_ERROR;
1246: }
1247:
1248: break;
1249:
1250:
1251: case IOCTL_VIDEO_SET_POINTER_ATTR:
1252:
1253: pointerAttributes = RequestPacket->InputBuffer;
1254:
1255: //
1256: // Check if the size of the data in the input buffer is large enough.
1257: //
1258:
1259: if ( (RequestPacket->InputBufferLength <
1260: (sizeof(VXL_POINTER_ATTRIBUTES)))) {
1261:
1262: status = ERROR_INSUFFICIENT_BUFFER;
1263: break;
1264: }
1265:
1266: //
1267: // Make sure the cursor size is correct: WidthInBytes = 4,
1268: // Height = 32
1269: //
1270:
1271: if ((pointerAttributes->WidthInBytes != 4) ||
1272: (pointerAttributes->Height != 32)) {
1273:
1274: //
1275: // We must return an error here but I'm not sure which code!
1276: //
1277:
1278: status = ERROR_INSUFFICIENT_BUFFER;
1279: break;
1280:
1281: }
1282:
1283: //
1284: // Capture the hardware cursor column, and row values.
1285: //
1286:
1287: hwDeviceExtension->CursorColumn = pointerAttributes->Column;
1288: hwDeviceExtension->CursorRow = pointerAttributes->Row;
1289:
1290: //
1291: // The cursor shape is passed as a AND MASK and an XOR MASK. These
1292: // MASKS are 1bpp, width = pointerAttributes->WidthInBytes, each
1293: // height = pointerAttributes->Height. First copy the XOR mask to
1294: // the hwDeviceExtension structure then the AND mask since this
1295: // is the order needed by the Bt484.
1296: //
1297:
1298: //
1299: // calculate the size in bytes of 1 mask
1300: //
1301:
1302: CursorMaskSize = pointerAttributes->WidthInBytes * pointerAttributes->Height;
1303:
1304: //
1305: // copy the xor mask to the first plane for the Bt484
1306: //
1307:
1308: for (index1=0;index1<CursorMaskSize;index1++) {
1309:
1310: hwDeviceExtension->CursorPixels[index1] =
1311: pointerAttributes->Pixels[index1 + CursorMaskSize];
1312: }
1313:
1314:
1315: //
1316: // copy the and mask to the second plane for the Bt484
1317: //
1318:
1319: for (index1=0;index1<CursorMaskSize;index1++) {
1320:
1321: hwDeviceExtension->CursorPixels[index1 + CursorMaskSize] =
1322: pointerAttributes->Pixels[index1];
1323: }
1324:
1325:
1326: //
1327: // Enable the vertical retrace interrupt to perform the update.
1328: //
1329: // N.B. Explicit synchronization is required since if the enable is
1330: // set, the update cursor position and update cursor pixels
1331: // parameters must all be atomically written.
1332: //
1333:
1334: if ( (hwDeviceExtension->CursorEnable =
1335: (UCHAR) pointerAttributes->Enable) == TRUE) {
1336:
1337: hwDeviceExtension->UpdateCursorPixels = TRUE;
1338:
1339: }
1340:
1341: hwDeviceExtension->UpdateCursorPosition = TRUE;
1342: turnOnInterrupts = TRUE;
1343:
1344: status = NO_ERROR;
1345:
1346: break;
1347:
1348:
1349: case IOCTL_VIDEO_QUERY_POINTER_ATTR:
1350:
1351: //
1352: // Find out the size of the data to be put in the the buffer and
1353: // return that in the status information (whether or not the
1354: // information is there). If the buffer passed in is not large
1355: // enough return an appropriate error code.
1356: //
1357:
1358: pointerAttributes = RequestPacket->OutputBuffer;
1359:
1360: if (RequestPacket->OutputBufferLength <
1361: (RequestPacket->StatusBlock->Information =
1362: sizeof(VXL_POINTER_ATTRIBUTES))) {
1363:
1364: status = ERROR_INSUFFICIENT_BUFFER;
1365:
1366: } else {
1367:
1368: //
1369: // Return the current hardware cursor width, height, column,
1370: // row and enable values.
1371: //
1372:
1373: pointerAttributes->Column = hwDeviceExtension->CursorColumn;
1374: pointerAttributes->Row = hwDeviceExtension->CursorRow;
1375: pointerAttributes->Enable = hwDeviceExtension->CursorEnable;
1376: pointerAttributes->WidthInBytes = 4;
1377: pointerAttributes->Width = 32;
1378: pointerAttributes->Height = 32;
1379:
1380: //
1381: // Return the hardware pixel values.
1382: //
1383:
1384: //
1385: // calculate the size in bytes of 1 mask
1386: //
1387:
1388: CursorMaskSize = pointerAttributes->WidthInBytes * pointerAttributes->Height;
1389:
1390: //
1391: // copy the xor mask to the first plane for the Bt484
1392: //
1393:
1394: for (index1=0;index1<CursorMaskSize;index1++) {
1395:
1396: pointerAttributes->Pixels[index1 + CursorMaskSize] =
1397: hwDeviceExtension->CursorPixels[index1];
1398: }
1399:
1400:
1401: //
1402: // copy the and mask to the second plane for the Bt484
1403: //
1404:
1405: for (index1=0;index1<CursorMaskSize;index1++) {
1406:
1407: pointerAttributes->Pixels[index1] =
1408: hwDeviceExtension->CursorPixels[index1 + CursorMaskSize];
1409: }
1410:
1411: status = NO_ERROR;
1412:
1413: }
1414:
1415: break;
1416:
1417: case IOCTL_VIDEO_QUERY_JAGUAR:
1418:
1419: //
1420: // Map 1 page for jaguar registers into user address space.
1421: // Map 1 page for Jagaur FIFO into user address space.
1422: // Determin the amount of video memory installed.
1423: // return this information
1424: //
1425:
1426: if (RequestPacket->OutputBufferLength <
1427: (RequestPacket->StatusBlock->Information = sizeof(VIDEO_JAGUAR_INFO)) ) {
1428:
1429: status = ERROR_INSUFFICIENT_BUFFER;
1430:
1431: } else {
1432:
1433: PVOID UserVirtualAddress;
1434: ULONG AddressLength;
1435:
1436: //
1437: // Map the jagaur registers into user virual address space
1438: //
1439:
1440: UserVirtualAddress = NULL;
1441: AddressLength = hwDeviceExtension->PhysicalControlLength;
1442:
1443: //
1444: // Map this address range into user address space
1445: //
1446:
1447: inIoSpace = 0;
1448:
1449: status = VideoPortMapMemory(hwDeviceExtension,
1450: hwDeviceExtension->PhysicalControlAddress,
1451: &AddressLength,
1452: &inIoSpace,
1453: &UserVirtualAddress);
1454:
1455: if (status != NO_ERROR) {
1456: break;
1457: }
1458:
1459:
1460: //
1461: // Copy the address to the output buffer
1462: //
1463:
1464: ((PVIDEO_JAGUAR_INFO)RequestPacket->OutputBuffer)->VideoControlVirtualBase =
1465: UserVirtualAddress;
1466:
1467:
1468: //
1469: // Map the jaguar fifo regs into user address space
1470: //
1471:
1472: UserVirtualAddress = NULL;
1473: AddressLength = hwDeviceExtension->PhysicalFifoLength;
1474:
1475: inIoSpace = 0;
1476:
1477: status = VideoPortMapMemory(hwDeviceExtension,
1478: hwDeviceExtension->PhysicalFifoAddress,
1479: &AddressLength,
1480: &inIoSpace,
1481: &UserVirtualAddress);
1482:
1483: //
1484: // Copy the address to the output buffer
1485: //
1486:
1487: ((PVIDEO_JAGUAR_INFO)RequestPacket->OutputBuffer)->FifoVirtualBase =
1488: UserVirtualAddress;
1489:
1490: //
1491: // Determine the length of video memory (if a second 2MB bank has been installed)
1492: //
1493:
1494: {
1495: ULONG TestValue;
1496: PULONG TestAddress;
1497:
1498: TestAddress = (PULONG)((PUCHAR)hwDeviceExtension->FrameAddress + 0x00200000);
1499: TestValue = 0xdeadbeef;
1500: VideoPortWriteRegisterUlong(TestAddress,TestValue);
1501:
1502: if (TestValue == VideoPortReadRegisterUlong(TestAddress)) {
1503: ((PVIDEO_JAGUAR_INFO)RequestPacket->OutputBuffer)->VideoMemoryLength = 0x00400000;
1504: } else {
1505: ((PVIDEO_JAGUAR_INFO)RequestPacket->OutputBuffer)->VideoMemoryLength = 0x00200000;
1506: }
1507:
1508: }
1509:
1510:
1511: }
1512:
1513: break ;
1514:
1515: //
1516: // if we get here, an invalid IoControlCode was specified.
1517: //
1518:
1519: default:
1520:
1521: status = ERROR_INVALID_FUNCTION;
1522:
1523: break;
1524:
1525: }
1526:
1527: if (turnOnInterrupts) {
1528:
1529: VideoPortWriteRegisterUchar(&VXL_JAGUAR_BASE->InterruptEnable.Byte,
1530: VXL_INTERRUPT_VERTICAL_RETRACE);
1531:
1532: }
1533:
1534:
1535:
1536: RequestPacket->StatusBlock->Status = status;
1537:
1538: return TRUE;
1539:
1540: } // end VxlStartIO()
1541:
1542: BOOLEAN
1543: VxlInterruptService(
1544: PVOID HwDeviceExtension
1545: )
1546:
1547: /*++
1548:
1549: Routine Description:
1550:
1551: This routine is the interrupt service routine for the Jazz kernel video
1552: driver.
1553:
1554: Arguments:
1555:
1556: HwDeviceExtension - Pointer to the miniport driver's adapter information.
1557:
1558: Return Value:
1559:
1560: TRUE since the interrupt is always serviced.
1561:
1562: --*/
1563:
1564: {
1565:
1566: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
1567: ULONG index;
1568: SHORT x;
1569: SHORT y;
1570: UCHAR InterruptSource;
1571: UCHAR PaletteData;
1572: ULONG Index;
1573: PBT484_REGISTERS Bt484 = VXL_BT484_BASE;
1574:
1575: //
1576: // Disable the verticle retrace interrupt.
1577: //
1578:
1579: //
1580: // Read the interrupt source before disabling interrupts
1581: //
1582:
1583: InterruptSource =
1584: VideoPortReadRegisterUchar(&VXL_JAGUAR_BASE->InterruptSource.Byte);
1585:
1586: VideoPortWriteRegisterUchar(&VXL_JAGUAR_BASE->InterruptEnable.Byte, 0);
1587:
1588: // VideoPortDisableInterrupt(hwDeviceExtension);
1589:
1590: //
1591: // Determin whether this is a vertical retrace interrupt, a JAGUAR command FIFO interrupt or
1592: // a writeable GDI interrupt.
1593: //
1594:
1595:
1596: //
1597: // Clear all but lower three bits
1598: //
1599:
1600: InterruptSource &= 0x07;
1601:
1602: //
1603: // Only the vertical retrace bit should be set, any other condition is an error
1604: //
1605:
1606: if (InterruptSource == VXL_INTERRUPT_VERTICAL_RETRACE) {
1607:
1608: //
1609: // Clear this interrupt in the JAGUAR interrupt source register
1610: //
1611:
1612: VideoPortWriteRegisterUchar(&VXL_JAGUAR_BASE->InterruptSource.Byte,InterruptSource);
1613:
1614: //
1615: // If the color map should be updated, then load the color map into the
1616: // Bt484 Display controller.
1617: //
1618:
1619: if (hwDeviceExtension->UpdateColorMap != FALSE) {
1620:
1621: //
1622: // Init the Bt484 Palette Write Address register to the first
1623: // palette location to be updated.
1624: //
1625:
1626: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->PaletteCursorWrAddress.Byte,
1627: (UCHAR)(hwDeviceExtension->FirstEntry & 0xff));
1628:
1629: //
1630: // Update all entries by performing three writes to each location, R,G,B
1631: //
1632:
1633: for (index = hwDeviceExtension->FirstEntry;
1634: index < hwDeviceExtension->LastEntry; index += 1) {
1635:
1636: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->PaletteColor.Byte,
1637: hwDeviceExtension->ColorMap[index].RgbData.Red);
1638:
1639: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->PaletteColor.Byte,
1640: hwDeviceExtension->ColorMap[index].RgbData.Green);
1641:
1642: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->PaletteColor.Byte,
1643: hwDeviceExtension->ColorMap[index].RgbData.Blue);
1644:
1645: }
1646:
1647: hwDeviceExtension->UpdateColorMap = FALSE;
1648: }
1649:
1650: //
1651: // If the hardware cursor position and/or enable control information
1652: // should be updated, then write the appropriate control registers.
1653: //
1654:
1655: if (hwDeviceExtension->UpdateCursorPosition != FALSE) {
1656:
1657: //
1658: // If the hardware cursor is enabled, then set the appropriate
1659: // control information and update the column and row position.
1660: // Otherwise, clear the appropriate control information.
1661: //
1662:
1663: if (hwDeviceExtension->CursorEnable != FALSE) {
1664:
1665: //
1666: // Update the CURSOR Location
1667: //
1668:
1669: x = hwDeviceExtension->CursorColumn +
1670: hwDeviceExtension->CursorXOrigin;
1671: y = hwDeviceExtension->CursorRow +
1672: hwDeviceExtension->CursorYOrigin;
1673:
1674: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->CursorXLow.Byte,
1675: (x & 0xff));
1676:
1677: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->CursorXHigh.Byte,
1678: ((x & 0xff00) >> 8));
1679:
1680: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->CursorYLow.Byte,
1681: (y & 0xff));
1682:
1683: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->CursorYHigh.Byte,
1684: ((y & 0xff00) >> 8));
1685:
1686: } else {
1687:
1688: //
1689: // Initialize cursor RAM
1690: //
1691: // Set address pointer to base of ram.
1692: // Set both planes to transparent (cursor disabled)
1693: //
1694:
1695: VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0);
1696:
1697: //
1698: // Plane 0 = 0
1699: //
1700:
1701: for (Index=0; Index < (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index++) {
1702: VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,0);
1703: }
1704:
1705: //
1706: // Plane 1 = 1
1707: //
1708:
1709: for (Index= (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index < VXL_CURSOR_NUMBER_OF_BYTES ; Index++) {
1710: VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,0xff);
1711: }
1712:
1713:
1714: }
1715:
1716: hwDeviceExtension->UpdateCursorPosition = FALSE;
1717: }
1718:
1719: //
1720: // If the hardware cursor pixels should be updated, then load the cursor
1721: // ram into the Bt484 cursor.
1722: //
1723:
1724: if (hwDeviceExtension->UpdateCursorPixels != FALSE) {
1725:
1726: //
1727: // only change to the new shape if the cursor is enabled
1728: //
1729:
1730: if (hwDeviceExtension->CursorEnable != FALSE) {
1731:
1732: //
1733: // Set the cursor RAM address pointer to location 0
1734: //
1735:
1736: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->PaletteCursorWrAddress.Byte,0);
1737:
1738: //
1739: // Update both cursor planes.
1740: //
1741:
1742: for (index = 0; index < VXL_CURSOR_NUMBER_OF_BYTES ; index++) {
1743:
1744: VideoPortWriteRegisterUchar(&VXL_BT484_BASE->CursorRam.Byte,
1745: hwDeviceExtension->CursorPixels[index]);
1746:
1747: }
1748:
1749: hwDeviceExtension->UpdateCursorPixels = FALSE;
1750: }
1751: }
1752:
1753: return TRUE;
1754:
1755: } else {
1756:
1757: //
1758: // Illegal type of video interrupt was received...
1759: //
1760:
1761: return FALSE;
1762:
1763: }
1764:
1765:
1766: } // end VxlInterruptService()
1767:
1768:
1769: VOID
1770: VxlSetMode(
1771: PHW_DEVICE_EXTENSION hwDeviceExtension
1772: )
1773:
1774: /*++
1775:
1776: Routine Description:
1777:
1778: Set the current mode based on the video mode number selected in the device extension.
1779:
1780: Arguments:
1781:
1782: HwDeviceExtension - Supplies a pointer to the miniport's device extension.
1783:
1784: Return Value:
1785:
1786: None.
1787:
1788: --*/
1789:
1790: {
1791: ULONG Index;
1792: PJAGUAR_REGISTERS Jaguar = VXL_JAGUAR_BASE;
1793: PBT484_REGISTERS Bt484 = VXL_BT484_BASE;
1794: PUCHAR Clock = (PUCHAR)VXL_CLOCK_BASE;
1795: UCHAR DataChar,CmdReg0,CmdReg1;
1796:
1797: //
1798: // The mode information is stored in
1799: // JagModes[hwDeviceExtension->ModeNumber].pJagInitData
1800: //
1801:
1802: PJAGUAR_REG_INIT JaguarInitData = (PVOID)
1803: (JagModes[hwDeviceExtension->ModeNumber].ModeSetTable);
1804:
1805: //
1806: //
1807: // Start ICS Clock pll and stabilize.
1808: //
1809:
1810: VideoPortWriteRegisterUchar(Clock, JaguarInitData->ClockFreq);
1811:
1812: //
1813: // Wait 10 uS for PLL clock to stabilize on the video board
1814: //
1815:
1816: VideoPortStallExecution(10);
1817:
1818: //
1819: // Initialize Bt484 Command Register 0 to:
1820: //
1821: // 8 Bit DAC Resolution
1822: //
1823:
1824: CmdReg0 = 0;
1825: ((PBT484_COMMAND0)(&CmdReg0))->DacResolution = 1;
1826: ((PBT484_COMMAND0)(&CmdReg0))->GreenSyncEnable = 1;
1827: ((PBT484_COMMAND0)(&CmdReg0))->SetupEnable = 1;
1828: VideoPortWriteRegisterUchar(&Bt484->Command0.Byte,CmdReg0);
1829:
1830: //
1831: // Initialize Command Register 1 to:
1832: //
1833:
1834: CmdReg1 = 0;
1835:
1836: switch (JagModes[hwDeviceExtension->ModeNumber].modeInformation.BitsPerPlane) {
1837:
1838: case 24:
1839: ((PBT484_COMMAND1)(&CmdReg1))->BitsPerPixel = VXL_THIRTYTWO_BITS_PER_PIXEL;
1840: ((PBT484_COMMAND1)(&CmdReg1))->TrueColorBypass = 0;
1841: break;
1842:
1843: case 16:
1844:
1845: ((PBT484_COMMAND1)(&CmdReg1))->BitsPerPixel = VXL_SIXTEEN_BITS_PER_PIXEL;
1846: ((PBT484_COMMAND1)(&CmdReg1))->TrueColorBypass = 0;
1847: break;
1848:
1849: case 8:
1850:
1851: ((PBT484_COMMAND1)(&CmdReg1))->BitsPerPixel = VXL_EIGHT_BITS_PER_PIXEL;
1852: break;
1853:
1854: }
1855:
1856: VideoPortWriteRegisterUchar(&Bt484->Command1.Byte,CmdReg1);
1857:
1858: //
1859: // Initialize Command Register 2 to:
1860: //
1861: // SCLK Enabled
1862: // TestMode disabled
1863: // PortselMask Non Masked
1864: // PCLK 1
1865: // NonInterlaced
1866: //
1867:
1868: DataChar = 0;
1869: ((PBT484_COMMAND2)(&DataChar))->SclkDisable = 0;
1870: ((PBT484_COMMAND2)(&DataChar))->TestEnable = 0;
1871: ((PBT484_COMMAND2)(&DataChar))->PortselMask = 1;
1872: ((PBT484_COMMAND2)(&DataChar))->PclkSelect = 1;
1873: ((PBT484_COMMAND2)(&DataChar))->InterlacedDisplay = 0;
1874: ((PBT484_COMMAND2)(&DataChar))->PaletteIndexing = CONTIGUOUS_PALETTE;
1875: ((PBT484_COMMAND2)(&DataChar))->CursorMode = BT_CURSOR_WINDOWS;
1876:
1877: VideoPortWriteRegisterUchar(&Bt484->Command2.Byte,DataChar);
1878:
1879:
1880: //
1881: // If the mode is set to 1 and the Bt485 flag is set then set the internal
1882: // 2x multiplier inside the Bt485. All other init steps are identical for the
1883: // Bt484 and Bt485.
1884: //
1885:
1886:
1887: if (JaguarInitData->Bt485Multiply == 1) {
1888:
1889: //
1890: // To access cmd register 3, first set bit CR17 in command register 0
1891: //
1892:
1893: CmdReg0 |= 0x80;
1894: VideoPortWriteRegisterUchar(&Bt484->Command0.Byte,CmdReg0);
1895:
1896: //
1897: // Write a 0x01 to Address register
1898: //
1899:
1900: VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0x01);
1901:
1902: //
1903: // Write to cmd register 3 in the status register location. Cmd3 is initialized
1904: // to turn on the 2x clock multiplier.
1905: //
1906:
1907: DataChar = 0;
1908: ((PBT484_COMMAND3)(&DataChar))->ClockMultiplier = 1;
1909:
1910: VideoPortWriteRegisterUchar(&Bt484->Status.Byte,DataChar);
1911:
1912: //
1913: // Allow 10 uS for the 2x multiplier to stabilize
1914: //
1915:
1916: VideoPortStallExecution(10);
1917:
1918: }
1919: //
1920: // Initialize Cursor and Overscan color.
1921: //
1922: // Set address pointer base.
1923: // Zero 4 entries.
1924: //
1925:
1926: VideoPortWriteRegisterUchar(&Bt484->CursorColorWrAddress.Byte,0);
1927:
1928: //
1929: // Zero overlay color
1930: //
1931:
1932: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
1933: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
1934: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
1935:
1936: //
1937: // Set cursor color 1 to black
1938: //
1939:
1940: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
1941: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
1942: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
1943:
1944: //
1945: // Set cursor color 2 to white
1946: //
1947:
1948: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
1949: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
1950: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
1951:
1952: //
1953: // Set Cursor color 3 to red (error)
1954: //
1955:
1956: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
1957: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0x00);
1958: VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0x00);
1959:
1960: //
1961: // Initialize cursor RAM
1962: //
1963: // Set address pointer to base of ram.
1964: // Set both planes to transparent (cursor disabled)
1965: //
1966:
1967: VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0);
1968:
1969: //
1970: // Plane 0 = 0
1971: //
1972:
1973: for (Index=0; Index < (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index++) {
1974: VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,0);
1975: }
1976:
1977: //
1978: // Plane 1 = 1
1979: //
1980:
1981: for (Index= (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index < VXL_CURSOR_NUMBER_OF_BYTES ; Index++) {
1982: VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,1);
1983: }
1984:
1985: //
1986: // Initialize cursor position registers--cursor off.
1987: //
1988:
1989: VideoPortWriteRegisterUchar(&Bt484->CursorXLow.Byte,0);
1990: VideoPortWriteRegisterUchar(&Bt484->CursorXHigh.Byte,0);
1991: VideoPortWriteRegisterUchar(&Bt484->CursorYLow.Byte,0);
1992: VideoPortWriteRegisterUchar(&Bt484->CursorYHigh.Byte,0);
1993:
1994: //
1995: // Initialize pixel mask.
1996: //
1997:
1998: VideoPortWriteRegisterUchar(&Bt484->PixelMask.Byte,0xFF);
1999:
2000: //
2001: // Init Jaguar Registers
2002: //
2003:
2004: //DbgPrint("Init Timing registers:\n");
2005:
2006: VideoPortWriteRegisterUshort(&Jaguar->TopOfScreen.Short,
2007: JaguarInitData->TopOfScreen);
2008: //DbgPrint("TopOfScreen %lx\n",JaguarInitData->TopOfScreen);
2009:
2010: VideoPortWriteRegisterUshort(&Jaguar->HorizontalBlank.Short,
2011: JaguarInitData->HorizontalBlank);
2012: //DbgPrint("HorizontalBlank %lx\n",JaguarInitData->HorizontalBlank);
2013:
2014: VideoPortWriteRegisterUshort(&Jaguar->HorizontalBeginSync.Short,
2015: JaguarInitData->HorizontalBeginSync);
2016: //DbgPrint("HorizontalBeginSync %lx\n",JaguarInitData->HorizontalBeginSync);
2017:
2018: VideoPortWriteRegisterUshort(&Jaguar->HorizontalEndSync.Short,
2019: JaguarInitData->HorizontalEndSync);
2020: //DbgPrint("HorizontalEndSync %lx\n",JaguarInitData->HorizontalEndSync);
2021:
2022: VideoPortWriteRegisterUshort(&Jaguar->HorizontalLine.Short,
2023: JaguarInitData->HorizontalLine);
2024: //DbgPrint("HorizontalLine %lx\n",JaguarInitData->HorizontalLine);
2025:
2026: VideoPortWriteRegisterUshort(&Jaguar->VerticalBlank.Short,
2027: JaguarInitData->VerticalBlank);
2028: //DbgPrint("VerticalBlank %lx\n",JaguarInitData->VerticalBlank);
2029:
2030: VideoPortWriteRegisterUshort(&Jaguar->VerticalBeginSync.Short,
2031: JaguarInitData->VerticalBeginSync);
2032: //DbgPrint("VerticalBeginSync %lx\n",JaguarInitData->VerticalBeginSync);
2033:
2034: VideoPortWriteRegisterUshort(&Jaguar->VerticalEndSync.Short,
2035: JaguarInitData->VerticalEndSync);
2036: //DbgPrint("VerticalEndSync %lx\n",JaguarInitData->VerticalEndSync);
2037:
2038: VideoPortWriteRegisterUshort(&Jaguar->VerticalLine.Short,
2039: JaguarInitData->VerticalLine);
2040: //DbgPrint("VerticalLine %lx\n",JaguarInitData->VerticalLine);
2041:
2042: VideoPortWriteRegisterUshort(&Jaguar->XferLength.Short,
2043: JaguarInitData->XferLength);
2044: //DbgPrint("XferLength %lx\n",JaguarInitData->XferLength);
2045:
2046: VideoPortWriteRegisterUshort(&Jaguar->VerticalInterruptLine.Short,
2047: JaguarInitData->VerticalInterruptLine);
2048: //DbgPrint("VerticalInterruptLine %lx\n",JaguarInitData->VerticalInterruptLine);
2049:
2050: VideoPortWriteRegisterUshort(&Jaguar->HorizontalDisplay.Short,
2051: JaguarInitData->HorizontalDisplay);
2052: //DbgPrint("HorizontalDisplay %lx\n",JaguarInitData->HorizontalDisplay);
2053:
2054: VideoPortWriteRegisterUchar(&Jaguar->BitBltControl.Byte,
2055: JaguarInitData->BitBltControl);
2056: //DbgPrint("BitBltControl %lx\n",JaguarInitData->BitBltControl);
2057:
2058: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.