mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2128 lines
58 KiB
2128 lines
58 KiB
/*++
|
|
|
|
Copyright (c) 1990-1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
jzvxl484.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the code that implements the Jazz kernel
|
|
video driver for the VXL graphics accelerator board.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "dderror.h"
|
|
#include "devioctl.h"
|
|
#include "miniport.h"
|
|
|
|
#include "ntddvdeo.h"
|
|
#include "video.h"
|
|
|
|
#include "jazzvdeo.h"
|
|
#include "jzvxl484.h"
|
|
#include "jzvxldat.h"
|
|
|
|
#define VXL_NAME L"VXL"
|
|
#define VXL_NAME_LENGTH 8
|
|
|
|
//
|
|
// Define macros to access video memory, jaguar base registers, jaguar fifo registers,
|
|
// the Bt484, ICS1494 clock chip and Board ROM.
|
|
//
|
|
|
|
#define VXL_CURSOR_MIN_POS -32
|
|
|
|
|
|
//
|
|
// Define device extension structure.
|
|
//
|
|
|
|
typedef struct _HW_DEVICE_EXTENSION {
|
|
PHYSICAL_ADDRESS PhysicalFrameAddress;
|
|
PHYSICAL_ADDRESS PhysicalFifoAddress;
|
|
ULONG PhysicalFrameLength;
|
|
ULONG PhysicalFifoLength;
|
|
PHYSICAL_ADDRESS PhysicalControlAddress;
|
|
union {
|
|
VIDEO_CLUTDATA RgbData;
|
|
ULONG RgbLong;
|
|
} ColorMap[NUMBER_OF_COLORS];
|
|
PJAGUAR_REGISTERS VxlJaguarBase;
|
|
PBT484_REGISTERS VxlBT484Base;
|
|
PVXL_BYTE_REGISTER VxlClockBase;
|
|
ULONG PhysicalControlLength;
|
|
USHORT FirstEntry;
|
|
USHORT LastEntry;
|
|
USHORT CursorControlOn;
|
|
USHORT CursorControlOff;
|
|
USHORT CursorWidth;
|
|
USHORT CursorHeight;
|
|
SHORT CursorColumn;
|
|
SHORT CursorRow;
|
|
USHORT CursorPixels[VXL_CURSOR_NUMBER_OF_BYTES];
|
|
USHORT CursorXOrigin;
|
|
USHORT CursorYOrigin;
|
|
USHORT HorizontalResolution;
|
|
USHORT HorizontalDisplayTime;
|
|
USHORT HorizontalBackPorch;
|
|
USHORT HorizontalFrontPorch;
|
|
USHORT HorizontalSync;
|
|
USHORT HorizontalScreenSize;
|
|
USHORT VerticalResolution;
|
|
USHORT VerticalBackPorch;
|
|
USHORT VerticalFrontPorch;
|
|
USHORT VerticalSync;
|
|
USHORT VerticalScreenSize;
|
|
UCHAR CursorEnable;
|
|
UCHAR UpdateColorMap;
|
|
UCHAR UpdateCursorPosition;
|
|
UCHAR UpdateCursorPixels;
|
|
UCHAR UpdateController;
|
|
ULONG ModeNumber;
|
|
ULONG NumAvailableModes;
|
|
ULONG BoardType;
|
|
PVOID QueueAddress;
|
|
PVOID QueueSystemAddress;
|
|
ULONG QueueSize;
|
|
ULONG QueueNumberOfEntries;
|
|
HANDLE QueueFrameSection;
|
|
ULONG QueueReadPointer;
|
|
} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
|
|
|
|
|
|
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
|
|
VP_STATUS
|
|
VxlFindAdapter(
|
|
PVOID HwDeviceExtension,
|
|
PVOID HwContext,
|
|
PWSTR ArgumentString,
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|
PUCHAR Again
|
|
);
|
|
|
|
BOOLEAN
|
|
VxlInitialize(
|
|
PVOID HwDeviceExtension
|
|
);
|
|
|
|
BOOLEAN
|
|
VxlInterruptService (
|
|
PVOID HwDeviceExtension
|
|
);
|
|
|
|
BOOLEAN
|
|
VxlStartIO(
|
|
PVOID HwDeviceExtension,
|
|
PVIDEO_REQUEST_PACKET RequestPacket
|
|
);
|
|
|
|
//
|
|
// Define device driver procedure prototypes.
|
|
//
|
|
|
|
VP_STATUS
|
|
VxlGetDeviceDataCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
PVOID Identifier,
|
|
ULONG IdentifierLength,
|
|
PVOID ConfigurationData,
|
|
ULONG ConfigurationDataLength,
|
|
PVOID ComponentInformation,
|
|
ULONG ComponentInformationLength
|
|
);
|
|
|
|
VOID
|
|
VxlSetMode(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension
|
|
);
|
|
|
|
|
|
ULONG
|
|
DriverEntry (
|
|
PVOID Context1,
|
|
PVOID Context2
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Installable driver initialization entry point.
|
|
This entry point is called directly by the I/O system.
|
|
|
|
Arguments:
|
|
|
|
Context1 - First context value passed by the operating system. This is
|
|
the value with which the miniport driver calls VideoPortInitialize().
|
|
|
|
Context2 - Second context value passed by the operating system. This is
|
|
the value with which the miniport driver calls VideoPortInitialize().
|
|
|
|
Return Value:
|
|
|
|
Status from VideoPortInitialize()
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
VIDEO_HW_INITIALIZATION_DATA hwInitData;
|
|
|
|
//
|
|
// Zero out structure.
|
|
//
|
|
|
|
VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
|
|
|
|
//
|
|
// Specify sizes of structure and extension.
|
|
//
|
|
|
|
hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
|
|
|
|
//
|
|
// Set entry points.
|
|
//
|
|
|
|
hwInitData.HwFindAdapter = VxlFindAdapter;
|
|
hwInitData.HwInitialize = VxlInitialize;
|
|
hwInitData.HwInterrupt = VxlInterruptService;
|
|
hwInitData.HwStartIO = VxlStartIO;
|
|
|
|
//
|
|
// Determine the size we require for the device extension.
|
|
//
|
|
|
|
hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
|
|
|
|
//
|
|
// Always start with parameters for device0 in this case.
|
|
//
|
|
|
|
// hwInitData.StartingDeviceNumber = 0;
|
|
|
|
//
|
|
// This device only supports the internal bus type. So return the status
|
|
// value directly to the operating system.
|
|
//
|
|
|
|
hwInitData.AdapterInterfaceType = Internal;
|
|
|
|
return VideoPortInitialize(Context1,
|
|
Context2,
|
|
&hwInitData,
|
|
NULL);
|
|
|
|
} // end DriverEntry()
|
|
|
|
VP_STATUS
|
|
VxlFindAdapter(
|
|
PVOID HwDeviceExtension,
|
|
PVOID HwContext,
|
|
PWSTR ArgumentString,
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|
PUCHAR Again
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called to determine if the adapter for this driver
|
|
is present in the system.
|
|
If it is present, the function fills out some information describing
|
|
the adapter.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Supplies the miniport driver's adapter storage. This
|
|
storage is initialized to zero before this call.
|
|
|
|
HwContext - Supplies the context value which was passed to
|
|
VideoPortInitialize().
|
|
|
|
ArgumentString - Suuplies a NULL terminated ASCII string. This string
|
|
originates from the user.
|
|
|
|
ConfigInfo - Returns the configuration information structure which is
|
|
filled by the miniport driver. This structure is initialized with
|
|
any knwon configuration information (such as SystemIoBusNumber) by
|
|
the port driver. Where possible, drivers should have one set of
|
|
defaults which do not require any supplied configuration information.
|
|
|
|
Again - Indicates if the miniport driver wants the port driver to call
|
|
its VIDEO_HW_FIND_ADAPTER function again with a new device extension
|
|
and the same config info. This is used by the miniport drivers which
|
|
can search for several adapters on a bus.
|
|
|
|
Return Value:
|
|
|
|
This routine must return:
|
|
|
|
NO_ERROR - Indicates a host adapter was found and the
|
|
configuration information was successfully determined.
|
|
|
|
ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
|
|
error obtaining the configuration information. If possible an error
|
|
should be logged.
|
|
|
|
ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
|
|
supplied configuration information.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
|
|
//
|
|
// Make sure the size of the structure is at least as large as what we
|
|
// are expecting (check version of the config info structure).
|
|
//
|
|
|
|
|
|
|
|
if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
if (VideoPortGetDeviceData(hwDeviceExtension,
|
|
VpControllerData,
|
|
&VxlGetDeviceDataCallback,
|
|
ConfigInfo)) {
|
|
|
|
VideoDebugPrint((2, "Vxl: VideoPort get controller info failed\n"));
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
if (VideoPortGetDeviceData(hwDeviceExtension,
|
|
VpMonitorData,
|
|
&VxlGetDeviceDataCallback,
|
|
NULL)) {
|
|
|
|
VideoDebugPrint((2, "Vxl: VideoPort get monitor info failed\n"));
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
//
|
|
// Clear out the Emulator entries and the state size since this driver
|
|
// does not support them.
|
|
//
|
|
|
|
ConfigInfo->NumEmulatorAccessEntries = 0;
|
|
ConfigInfo->EmulatorAccessEntries = NULL;
|
|
ConfigInfo->EmulatorAccessEntriesContext = 0;
|
|
|
|
ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
|
|
ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
|
|
ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
|
|
|
|
ConfigInfo->HardwareStateSize = 0;
|
|
|
|
//
|
|
// Initialize the color map update information.
|
|
//
|
|
|
|
hwDeviceExtension->FirstEntry = 0;
|
|
hwDeviceExtension->LastEntry = 0;
|
|
hwDeviceExtension->UpdateController = FALSE;
|
|
|
|
//
|
|
// Set cursor enable FALSE.
|
|
//
|
|
|
|
hwDeviceExtension->CursorEnable = FALSE;
|
|
|
|
//
|
|
// Indicate we do not wish to be called over
|
|
//
|
|
|
|
*Again = 0;
|
|
|
|
//
|
|
// Indicate a successful completion status.
|
|
//
|
|
|
|
return NO_ERROR;
|
|
|
|
} // end VxlFindAdapter()
|
|
|
|
VP_STATUS
|
|
VxlGetDeviceDataCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
PVOID Identifier,
|
|
ULONG IdentifierLength,
|
|
PVOID ConfigurationData,
|
|
ULONG ConfigurationDataLength,
|
|
PVOID ComponentInformation,
|
|
ULONG ComponentInformationLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Callback routine for the VideoPortGetDeviceData function.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Pointer to the miniport drivers device extension.
|
|
|
|
Context - Context value passed to the VideoPortGetDeviceData function.
|
|
|
|
DeviceDataType - The type of data that was requested in
|
|
VideoPortGetDeviceData.
|
|
|
|
Identifier - Pointer to a string that contains the name of the device,
|
|
as setup by the ROM or ntdetect.
|
|
|
|
IdentifierLength - Length of the Identifier string.
|
|
|
|
ConfigurationData - Pointer to the configuration data for the device or
|
|
BUS.
|
|
|
|
ConfigurationDataLength - Length of the data in the configurationData
|
|
field.
|
|
|
|
ComponentInformation - Undefined.
|
|
|
|
ComponentInformationLength - Undefined.
|
|
|
|
Return Value:
|
|
|
|
Returns NO_ERROR if the function completed properly.
|
|
Returns ERROR_DEV_NOT_EXIST if we did not find the device.
|
|
Returns ERROR_INVALID_PARAMETER otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo = Context;
|
|
PWCHAR identifier = Identifier;
|
|
PVIDEO_HARDWARE_CONFIGURATION_DATA VxlConfigData = ConfigurationData;
|
|
PMONITOR_CONFIG_DATA monitorConfigData = ConfigurationData;
|
|
VIDEO_ACCESS_RANGE accessRanges[2];
|
|
VP_STATUS status;
|
|
|
|
PUCHAR FrameAddress;
|
|
PHYSICAL_ADDRESS mapAddress;
|
|
|
|
|
|
switch (DeviceDataType) {
|
|
|
|
case VpControllerData:
|
|
|
|
//
|
|
// Compare the name to what is should be. If it is wrong, then return
|
|
// an error and initialization will fail.
|
|
// What is the right way of doing this??
|
|
//
|
|
|
|
|
|
if ( VXL_NAME_LENGTH != VideoPortCompareMemory(identifier,
|
|
VXL_NAME,
|
|
VXL_NAME_LENGTH)) {
|
|
|
|
return ERROR_DEV_NOT_EXIST;
|
|
}
|
|
|
|
//
|
|
// Fill up the device extension and the configuration information
|
|
// with the appropriate data.
|
|
//
|
|
|
|
|
|
ConfigInfo->BusInterruptLevel = VxlConfigData->Irql;
|
|
ConfigInfo->BusInterruptVector = VxlConfigData->Vector;
|
|
|
|
//
|
|
// Map in 4MB access ranges for VXL control and 4MB + 1 Page for
|
|
// Video Memory.
|
|
//
|
|
|
|
accessRanges[0].RangeStart.HighPart = 0;
|
|
accessRanges[0].RangeStart.LowPart = 0x60000000;
|
|
accessRanges[0].RangeLength = 0x00400000;
|
|
accessRanges[0].RangeInIoSpace = 0;
|
|
accessRanges[0].RangeVisible = 0;
|
|
accessRanges[0].RangeShareable = 0;
|
|
|
|
accessRanges[1].RangeStart.HighPart = 0;
|
|
accessRanges[1].RangeStart.LowPart = 0x40000000;
|
|
accessRanges[1].RangeLength = 0x00401000;
|
|
accessRanges[1].RangeInIoSpace = 0;
|
|
accessRanges[1].RangeVisible = 0;
|
|
accessRanges[1].RangeShareable = 0;
|
|
|
|
//
|
|
// Check to see if there is a hardware resource conflict.
|
|
//
|
|
|
|
status = VideoPortVerifyAccessRanges(HwDeviceExtension,
|
|
2,
|
|
accessRanges);
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
//
|
|
// Save in device extension
|
|
//
|
|
|
|
hwDeviceExtension->PhysicalFrameAddress.HighPart = 0;
|
|
hwDeviceExtension->PhysicalFrameAddress.LowPart = 0x40000000;
|
|
|
|
hwDeviceExtension->PhysicalFifoAddress.HighPart = 0;
|
|
hwDeviceExtension->PhysicalFifoAddress.LowPart = 0x40400000;
|
|
hwDeviceExtension->PhysicalFifoLength = 0x1000;
|
|
|
|
hwDeviceExtension->PhysicalControlAddress.HighPart = 0;
|
|
hwDeviceExtension->PhysicalControlAddress.LowPart = 0x60300000;
|
|
hwDeviceExtension->PhysicalControlLength = 0x1000;
|
|
|
|
//
|
|
// Map the video controller registers into the system virtual address
|
|
// space.
|
|
//
|
|
|
|
mapAddress.QuadPart = accessRanges[0].RangeStart.QuadPart +
|
|
VXL_JAGUAR_BASE_OFFSET;
|
|
|
|
if ( (hwDeviceExtension->VxlJaguarBase =
|
|
VideoPortGetDeviceBase(hwDeviceExtension,
|
|
mapAddress,
|
|
sizeof(JAGUAR_REGISTERS),
|
|
FALSE)) == NULL) {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
mapAddress.QuadPart = accessRanges[0].RangeStart.QuadPart +
|
|
VXL_BT484_BASE_OFFSET;
|
|
|
|
if ( (hwDeviceExtension->VxlBT484Base =
|
|
VideoPortGetDeviceBase(hwDeviceExtension,
|
|
mapAddress,
|
|
sizeof(BT484_REGISTERS),
|
|
FALSE)) == NULL) {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
mapAddress.QuadPart = accessRanges[0].RangeStart.QuadPart +
|
|
VXL_CLOCK_BASE_OFFSET;
|
|
|
|
if ( (hwDeviceExtension->VxlClockBase =
|
|
VideoPortGetDeviceBase(hwDeviceExtension,
|
|
mapAddress,
|
|
256,
|
|
FALSE)) == NULL) {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
//
|
|
// Map the video memory into the system virtual address space so we
|
|
// can clear it out.
|
|
//
|
|
|
|
FrameAddress = VideoPortGetDeviceBase(hwDeviceExtension,
|
|
accessRanges[1].RangeStart,
|
|
accessRanges[1].RangeLength,
|
|
FALSE);
|
|
|
|
if (FrameAddress) {
|
|
|
|
//
|
|
// Determine the length of video memory
|
|
// (if a second 2MB bank has been installed)
|
|
//
|
|
|
|
ULONG TestValue;
|
|
PULONG TestAddress;
|
|
|
|
TestAddress = (PULONG) (FrameAddress + 0x00200000);
|
|
TestValue = 0xdeadbeef;
|
|
|
|
VideoPortWriteRegisterUlong(TestAddress, TestValue);
|
|
|
|
if (TestValue == VideoPortReadRegisterUlong(TestAddress)) {
|
|
hwDeviceExtension->PhysicalFrameLength = 0x00400000;
|
|
} else {
|
|
hwDeviceExtension->PhysicalFrameLength = 0x00200000;
|
|
}
|
|
|
|
VideoPortFreeDeviceBase(hwDeviceExtension,
|
|
FrameAddress);
|
|
|
|
} else {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
return NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case VpMonitorData:
|
|
|
|
VideoDebugPrint((2, "Vxl: getting monitor information\n"));
|
|
|
|
//
|
|
// NOTE: because we had a RESOURCE LIST header at the top.
|
|
// + 8 should be the offset of the paertial resource descriptor
|
|
// in a full resource descriptor.
|
|
//
|
|
|
|
monitorConfigData = (PMONITOR_CONFIG_DATA)
|
|
( ((PUCHAR)monitorConfigData) + 8);
|
|
|
|
//
|
|
// Initialize the monitor parameters.
|
|
//
|
|
|
|
hwDeviceExtension->HorizontalResolution =
|
|
monitorConfigData->HorizontalResolution;
|
|
|
|
hwDeviceExtension->HorizontalDisplayTime =
|
|
monitorConfigData->HorizontalDisplayTime;
|
|
|
|
hwDeviceExtension->HorizontalBackPorch =
|
|
monitorConfigData->HorizontalBackPorch;
|
|
|
|
hwDeviceExtension->HorizontalFrontPorch =
|
|
monitorConfigData->HorizontalFrontPorch;
|
|
|
|
hwDeviceExtension->HorizontalSync =
|
|
monitorConfigData->HorizontalSync;
|
|
|
|
hwDeviceExtension->HorizontalScreenSize =
|
|
monitorConfigData->HorizontalScreenSize;
|
|
|
|
hwDeviceExtension->VerticalResolution =
|
|
monitorConfigData->VerticalResolution;
|
|
|
|
hwDeviceExtension->VerticalBackPorch =
|
|
monitorConfigData->VerticalBackPorch;
|
|
|
|
hwDeviceExtension->VerticalFrontPorch =
|
|
monitorConfigData->VerticalFrontPorch;
|
|
|
|
hwDeviceExtension->VerticalSync =
|
|
monitorConfigData->VerticalSync;
|
|
|
|
hwDeviceExtension->VerticalScreenSize =
|
|
monitorConfigData->VerticalScreenSize;
|
|
|
|
return NO_ERROR;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
} //end VxlGetDeviceDataCallback()
|
|
|
|
BOOLEAN
|
|
VxlInitialize(
|
|
PVOID HwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine does one time initialization of the device.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
|
|
|
|
Return Value:
|
|
|
|
Always returns TRUE since this routine can never fail.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
ULONG index;
|
|
ULONG i;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
UCHAR DataChar;
|
|
PBT484_REGISTERS Bt484 = hwDeviceExtension->VxlBT484Base;
|
|
|
|
//
|
|
// Determine if this is a Bt484 or Bt485 board. To do this write a 1 to
|
|
// command register bit 07 then write 01 to the address register 0. This
|
|
// will enable read/writes to command register 3 on a Bt485 but not on a
|
|
// Bt484. Clear Command register 3 then read it back. On a Bt485 the
|
|
// return value will be 0x00, on a Bt484 it will be 0x40.
|
|
//
|
|
|
|
//
|
|
// Get the value in command register 0, then set bit 07
|
|
//
|
|
|
|
DataChar = VideoPortReadRegisterUchar(&Bt484->Command0.Byte);
|
|
DataChar |= 0x80;
|
|
VideoPortWriteRegisterUchar(&Bt484->Command0.Byte,DataChar);
|
|
|
|
//
|
|
// Write 0x01 to the address register
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0x01);
|
|
|
|
//
|
|
// Clear command register 3
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->Status.Byte,0x00);
|
|
|
|
//
|
|
// Read Command Register 3 back and compare
|
|
//
|
|
|
|
DataChar = VideoPortReadRegisterUchar(&Bt484->Status.Byte);
|
|
|
|
if (DataChar == 0x00) {
|
|
|
|
//
|
|
// This is a Bt485
|
|
//
|
|
|
|
hwDeviceExtension->BoardType = BOARD_TYPE_BT485;
|
|
|
|
} else {
|
|
|
|
//
|
|
// This is a Bt484
|
|
//
|
|
|
|
hwDeviceExtension->BoardType = BOARD_TYPE_BT484;
|
|
|
|
}
|
|
|
|
//
|
|
// Calculated the number of valid modes
|
|
//
|
|
|
|
hwDeviceExtension->NumAvailableModes = 0;
|
|
|
|
for (i = 0; i < NumModes; i++) {
|
|
|
|
JagModes[i].modeInformation.ModeIndex = i;
|
|
|
|
if (JagModes[i].SupportedBoard & hwDeviceExtension->BoardType) {
|
|
|
|
hwDeviceExtension->NumAvailableModes++;
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initialize the color map copy in the device extension.
|
|
//
|
|
|
|
for (index = 0; index < NUMBER_OF_COLORS; index++) {
|
|
|
|
hwDeviceExtension->ColorMap[index].RgbData.Red =
|
|
(UCHAR)(((index & 0x7) << 2) | ((index & 0x7) << 5));
|
|
hwDeviceExtension->ColorMap[index].RgbData.Green =
|
|
(UCHAR)(((index & 0x38) >> 1) | ((index & 0x38) << 2));
|
|
hwDeviceExtension->ColorMap[index].RgbData.Blue =
|
|
(UCHAR)(((index & 0xc0) >> 6) | ((index & 0xc0) >> 4) |
|
|
((index & 0xc0) >> 2) | (index & 0xc0));
|
|
}
|
|
|
|
//
|
|
// Set colors for map entries 0 and 1 which are used by text output
|
|
// and the hardware cursor.
|
|
//
|
|
|
|
hwDeviceExtension->ColorMap[0].RgbData.Red = 255;
|
|
hwDeviceExtension->ColorMap[0].RgbData.Green = 255;
|
|
hwDeviceExtension->ColorMap[0].RgbData.Blue = 255;
|
|
hwDeviceExtension->ColorMap[1].RgbData.Red = 0;
|
|
hwDeviceExtension->ColorMap[1].RgbData.Green = 0;
|
|
hwDeviceExtension->ColorMap[1].RgbData.Blue = 0x90;
|
|
|
|
//
|
|
// Set color map update parameters and enable update on next vertical
|
|
// retrace interrupt.
|
|
//
|
|
|
|
hwDeviceExtension->FirstEntry = 0;
|
|
hwDeviceExtension->LastEntry = NUMBER_OF_COLORS - 1;
|
|
hwDeviceExtension->UpdateColorMap = TRUE;
|
|
|
|
//
|
|
// Set the hardware cursor width, height, column, and row values.
|
|
//
|
|
|
|
hwDeviceExtension->CursorWidth = VXL_CURSOR_WIDTH;
|
|
hwDeviceExtension->CursorHeight = VXL_CURSOR_HEIGHT;
|
|
hwDeviceExtension->CursorColumn = 0;
|
|
hwDeviceExtension->CursorRow = 0;
|
|
|
|
//
|
|
// Set the cursor offsets
|
|
//
|
|
|
|
|
|
hwDeviceExtension->CursorXOrigin = 32;
|
|
hwDeviceExtension->CursorYOrigin = 32;
|
|
|
|
//
|
|
// Set the device extension copy of the hardware cursor ram memory.
|
|
//
|
|
|
|
for (index = 0; index < VXL_CURSOR_NUMBER_OF_BYTES ; index++) {
|
|
hwDeviceExtension->CursorPixels[index] = 0x00ff;
|
|
}
|
|
|
|
//
|
|
// Leave the cursor disabled until it is explicitly enabled
|
|
// attributes. This is the default values in the device extension.
|
|
//
|
|
// hwDeviceExtension->CursorEnable = FALSE;
|
|
// hwDeviceExtension->UpdateCursorPixels = FALSE;
|
|
// hwDeviceExtension->UpdateCursorPosition = FALSE;
|
|
//
|
|
|
|
//
|
|
// Enable the vertical retrace interrupt to set up color map.
|
|
//
|
|
|
|
VideoPortEnableInterrupt(hwDeviceExtension);
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlJaguarBase->InterruptEnable.Byte,
|
|
VXL_INTERRUPT_VERTICAL_RETRACE);
|
|
|
|
|
|
return TRUE;
|
|
|
|
} // end VxlInitialize()
|
|
|
|
BOOLEAN
|
|
VxlStartIO(
|
|
PVOID HwDeviceExtension,
|
|
PVIDEO_REQUEST_PACKET RequestPacket
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the main execution routine for the miniport driver. It
|
|
accepts0s a Video Request Packet, performs the request, and then returns
|
|
with the appropriate status.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
|
|
|
|
RequestPacket - Pointer to the video request packet. This structure
|
|
contains all the parameters passed to the VideoIoControl function.
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
VP_STATUS status;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG inIoSpace;
|
|
PULONG colorSource;
|
|
PVIDEO_MODE_INFORMATION modeInformation;
|
|
PVIDEO_POINTER_ATTRIBUTES pointerAttributes;
|
|
PVIDEO_MEMORY_INFORMATION memoryInformation;
|
|
PVIDEO_POINTER_CAPABILITIES VideoPointerCapabilities;
|
|
PVIDEO_POINTER_POSITION pointerPostion;
|
|
PVIDEO_CLUT clutBuffer;
|
|
USHORT index1;
|
|
ULONG CursorMaskSize;
|
|
UCHAR turnOnInterrupts = FALSE;
|
|
ULONG i;
|
|
|
|
//
|
|
// Switch on the IoContolCode in the RequestPacket. It indicates which
|
|
// function must be performed by the driver.
|
|
//
|
|
|
|
switch (RequestPacket->IoControlCode) {
|
|
|
|
|
|
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - MapVideoMemory\n"));
|
|
|
|
if ( (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_MEMORY_INFORMATION))) ||
|
|
(RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
memoryInformation = RequestPacket->OutputBuffer;
|
|
|
|
memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
|
|
(RequestPacket->InputBuffer))->RequestedVirtualAddress;
|
|
|
|
memoryInformation->VideoRamLength =
|
|
hwDeviceExtension->PhysicalFrameLength;
|
|
|
|
inIoSpace = 0;
|
|
|
|
status = VideoPortMapMemory(hwDeviceExtension,
|
|
hwDeviceExtension->PhysicalFrameAddress,
|
|
&(memoryInformation->VideoRamLength),
|
|
&inIoSpace,
|
|
&(memoryInformation->VideoRamBase));
|
|
|
|
//
|
|
// The frame buffer and virtual memory and equivalent in this
|
|
// case.
|
|
//
|
|
|
|
memoryInformation->FrameBufferBase =
|
|
memoryInformation->VideoRamBase;
|
|
|
|
memoryInformation->FrameBufferLength =
|
|
memoryInformation->VideoRamLength;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - UnMapVideoMemory\n"));
|
|
|
|
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
} else {
|
|
|
|
status = VideoPortUnmapMemory(hwDeviceExtension,
|
|
((PVIDEO_MEMORY)
|
|
(RequestPacket->InputBuffer))->
|
|
RequestedVirtualAddress,
|
|
0);
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - QueryAvailableModes\n"));
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
hwDeviceExtension->NumAvailableModes *
|
|
sizeof(VIDEO_MODE_INFORMATION)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
modeInformation = RequestPacket->OutputBuffer;
|
|
|
|
for (i = 0; i < NumModes; i++) {
|
|
|
|
if (JagModes[i].SupportedBoard & hwDeviceExtension->BoardType) {
|
|
|
|
*modeInformation = JagModes[i].modeInformation;
|
|
modeInformation++;
|
|
|
|
}
|
|
}
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - Query(Available/Current)Modes\n"));
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_MODE_INFORMATION)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
*((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
|
|
JagModes[hwDeviceExtension->ModeNumber].modeInformation;
|
|
|
|
status = NO_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
|
|
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - QueryNumAvailableModes\n"));
|
|
|
|
//
|
|
// Find out the size of the data to be put in the the buffer and
|
|
// return that in the status information (whether or not the
|
|
// information is there). If the buffer passed in is not large
|
|
// enough return an appropriate error code.
|
|
//
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_NUM_MODES)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
|
|
hwDeviceExtension->NumAvailableModes;
|
|
|
|
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
|
|
sizeof(VIDEO_MODE_INFORMATION);
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_CURRENT_MODE:
|
|
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - SetCurrentMode\n"));
|
|
|
|
if (*(ULONG *)(RequestPacket->InputBuffer) >= NumModes) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
hwDeviceExtension->ModeNumber = *(ULONG *)(RequestPacket->InputBuffer);
|
|
|
|
VxlSetMode(hwDeviceExtension);
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
|
|
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - SetPaletteRegs\n"));
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
|
|
|
|
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - SetColorRegs\n"));
|
|
|
|
clutBuffer = RequestPacket->InputBuffer;
|
|
|
|
//
|
|
// Check if the size of the data in the input buffer is large enough.
|
|
//
|
|
|
|
if ( (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) -
|
|
sizeof(ULONG)) ||
|
|
(RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) +
|
|
(sizeof(ULONG) * (clutBuffer->NumEntries - 1)) ) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
// Check to see if the parameters are valid.
|
|
//
|
|
|
|
if ( (clutBuffer->NumEntries == 0) ||
|
|
(clutBuffer->FirstEntry > NUMBER_OF_COLORS) ||
|
|
(clutBuffer->FirstEntry + clutBuffer->NumEntries >
|
|
NUMBER_OF_COLORS + 1) ) {
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
|
|
}
|
|
|
|
index1 = clutBuffer->FirstEntry;
|
|
hwDeviceExtension->FirstEntry = index1;
|
|
hwDeviceExtension->LastEntry = index1 + clutBuffer->NumEntries;
|
|
colorSource = (PULONG)&(clutBuffer->LookupTable[0]);
|
|
|
|
while (index1 < hwDeviceExtension->LastEntry) {
|
|
|
|
hwDeviceExtension->ColorMap[index1++].RgbLong = *colorSource++;
|
|
|
|
}
|
|
|
|
//
|
|
// Enable the verticle retrace interrupt to perform the update.
|
|
//
|
|
|
|
hwDeviceExtension->UpdateColorMap = TRUE;
|
|
turnOnInterrupts = TRUE;
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
|
|
|
|
//
|
|
// return type of pointer supported: assyncronous monochrome
|
|
//
|
|
|
|
|
|
VideoPointerCapabilities = RequestPacket->OutputBuffer;
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_POINTER_CAPABILITIES)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
VideoPointerCapabilities->Flags = (VIDEO_MODE_ASYNC_POINTER |
|
|
VIDEO_MODE_MONO_POINTER);
|
|
VideoPointerCapabilities->MaxWidth = VXL_CURSOR_WIDTH;
|
|
VideoPointerCapabilities->MaxHeight = VXL_CURSOR_HEIGHT;
|
|
VideoPointerCapabilities->HWPtrBitmapStart = 0xffffffff;
|
|
VideoPointerCapabilities->HWPtrBitmapEnd = 0xffffffff;
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
case IOCTL_VIDEO_ENABLE_POINTER:
|
|
|
|
//
|
|
// If the hardware cursor is currently disabled, then enable
|
|
// it and update the cursor position and cursor ram memory.
|
|
//
|
|
// N.B. Explicit synchronization is required since the enable,
|
|
// update cursor position, and update cursor pixels parameters
|
|
// must all be atomically written.
|
|
//
|
|
//
|
|
// Enable the verticle retrace interrupt to perform the update.
|
|
//
|
|
|
|
if (hwDeviceExtension->CursorEnable == FALSE) {
|
|
|
|
hwDeviceExtension->CursorEnable = TRUE;
|
|
hwDeviceExtension->UpdateCursorPixels = TRUE;
|
|
hwDeviceExtension->UpdateCursorPosition = TRUE;
|
|
turnOnInterrupts = TRUE;
|
|
}
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_DISABLE_POINTER:
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - DisableCursor\n"));
|
|
|
|
// If the hardware cursor is currently enabled, then disable
|
|
// it and update the cursor position.
|
|
//
|
|
// N.B. Explicit synchronization is required since both the enable
|
|
// and update cursor position parameters must be atomically
|
|
// written.
|
|
//
|
|
|
|
//
|
|
// Enable the verticle retrace interrupt to perform the update.
|
|
//
|
|
|
|
if (hwDeviceExtension->CursorEnable != FALSE) {
|
|
|
|
hwDeviceExtension->CursorEnable = FALSE;
|
|
hwDeviceExtension->UpdateCursorPosition = TRUE;
|
|
turnOnInterrupts = TRUE;
|
|
|
|
}
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_POINTER_POSITION:
|
|
|
|
VideoDebugPrint((2, "VxlStartIO - SetpointerPostion\n"));
|
|
|
|
//
|
|
// Check if the size of the data in the input buffer is large enough.
|
|
//
|
|
|
|
if (RequestPacket->InputBufferLength < sizeof(VIDEO_POINTER_POSITION)) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Capture the hardware cursor column and height values.
|
|
//
|
|
|
|
pointerPostion = RequestPacket->InputBuffer;
|
|
|
|
hwDeviceExtension->CursorColumn = pointerPostion->Column;
|
|
hwDeviceExtension->CursorRow = pointerPostion->Row;
|
|
|
|
//
|
|
// If the column is -1, this indicates the cursor should be hidden,
|
|
// move it off the screen
|
|
//
|
|
|
|
if (hwDeviceExtension->CursorColumn == -1) {
|
|
hwDeviceExtension->CursorColumn = VXL_CURSOR_MIN_POS;
|
|
hwDeviceExtension->CursorRow = VXL_CURSOR_MIN_POS;
|
|
}
|
|
|
|
//
|
|
// If the hardware cursor is not disabled, then update the
|
|
// hardware cursor position.
|
|
//
|
|
// N.B. No explicit synchronization is required since only
|
|
// the update cursor parameter needs to be written.
|
|
//
|
|
|
|
//
|
|
// Enable the verticle retrace interrupt to perform the update.
|
|
//
|
|
|
|
hwDeviceExtension->UpdateCursorPosition = TRUE;
|
|
turnOnInterrupts = TRUE;
|
|
|
|
status = NO_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_POINTER_POSITION:
|
|
|
|
|
|
//
|
|
// Find out the size of the data to be put in the the buffer and
|
|
// return that in the status information (whether or not the
|
|
// information is there). If the buffer passed in is not large
|
|
// enough return an appropriate error code.
|
|
//
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_POINTER_POSITION)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Return the current hardware cursor column and row values.
|
|
//
|
|
|
|
pointerPostion = RequestPacket->OutputBuffer;
|
|
|
|
pointerPostion->Column = hwDeviceExtension->CursorColumn;
|
|
pointerPostion->Row = hwDeviceExtension->CursorRow;
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_POINTER_ATTR:
|
|
|
|
pointerAttributes = RequestPacket->InputBuffer;
|
|
|
|
//
|
|
// Check if the size of the data in the input buffer is large enough.
|
|
//
|
|
|
|
if ( (RequestPacket->InputBufferLength <
|
|
(sizeof(VXL_POINTER_ATTRIBUTES)))) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Make sure the cursor size is correct: WidthInBytes = 4,
|
|
// Height = 32
|
|
//
|
|
|
|
if ((pointerAttributes->WidthInBytes != 4) ||
|
|
(pointerAttributes->Height != 32)) {
|
|
|
|
//
|
|
// We must return an error here but I'm not sure which code!
|
|
//
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
// Capture the hardware cursor column, and row values.
|
|
//
|
|
|
|
hwDeviceExtension->CursorColumn = pointerAttributes->Column;
|
|
hwDeviceExtension->CursorRow = pointerAttributes->Row;
|
|
|
|
//
|
|
// if pos = -1,-1 then move totally off screen
|
|
//
|
|
|
|
if ((hwDeviceExtension->CursorRow == -1) && (hwDeviceExtension->CursorColumn)) {
|
|
hwDeviceExtension->CursorColumn = VXL_CURSOR_MIN_POS;
|
|
hwDeviceExtension->CursorRow = VXL_CURSOR_MIN_POS;
|
|
}
|
|
|
|
//
|
|
// The cursor shape is passed as a AND MASK and an XOR MASK. These
|
|
// MASKS are 1bpp, width = pointerAttributes->WidthInBytes, each
|
|
// height = pointerAttributes->Height. First copy the XOR mask to
|
|
// the hwDeviceExtension structure then the AND mask since this
|
|
// is the order needed by the Bt484.
|
|
//
|
|
|
|
//
|
|
// calculate the size in bytes of 1 mask
|
|
//
|
|
|
|
CursorMaskSize = pointerAttributes->WidthInBytes * pointerAttributes->Height;
|
|
|
|
//
|
|
// copy the xor mask to the first plane for the Bt484
|
|
//
|
|
|
|
for (index1=0;index1<CursorMaskSize;index1++) {
|
|
|
|
hwDeviceExtension->CursorPixels[index1] =
|
|
pointerAttributes->Pixels[index1 + CursorMaskSize];
|
|
}
|
|
|
|
|
|
//
|
|
// copy the and mask to the second plane for the Bt484
|
|
//
|
|
|
|
for (index1=0;index1<CursorMaskSize;index1++) {
|
|
|
|
hwDeviceExtension->CursorPixels[index1 + CursorMaskSize] =
|
|
pointerAttributes->Pixels[index1];
|
|
}
|
|
|
|
|
|
//
|
|
// Enable the vertical retrace interrupt to perform the update.
|
|
//
|
|
// N.B. Explicit synchronization is required since if the enable is
|
|
// set, the update cursor position and update cursor pixels
|
|
// parameters must all be atomically written.
|
|
//
|
|
|
|
if ( (hwDeviceExtension->CursorEnable =
|
|
(UCHAR) pointerAttributes->Enable) == TRUE) {
|
|
|
|
hwDeviceExtension->UpdateCursorPixels = TRUE;
|
|
|
|
}
|
|
|
|
hwDeviceExtension->UpdateCursorPosition = TRUE;
|
|
turnOnInterrupts = TRUE;
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_RESET_DEVICE:
|
|
|
|
//
|
|
// Just make sure we return success for this IOCTL so we do not
|
|
// fail it, and display driver does no break on failiure.
|
|
//
|
|
// This IOCTL does not do anything on this machine because there
|
|
// is no basic mode to return to ...
|
|
//
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_POINTER_ATTR:
|
|
|
|
//
|
|
// Find out the size of the data to be put in the the buffer and
|
|
// return that in the status information (whether or not the
|
|
// information is there). If the buffer passed in is not large
|
|
// enough return an appropriate error code.
|
|
//
|
|
|
|
pointerAttributes = RequestPacket->OutputBuffer;
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VXL_POINTER_ATTRIBUTES))) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Return the current hardware cursor width, height, column,
|
|
// row and enable values.
|
|
//
|
|
|
|
pointerAttributes->Column = hwDeviceExtension->CursorColumn;
|
|
pointerAttributes->Row = hwDeviceExtension->CursorRow;
|
|
pointerAttributes->Enable = hwDeviceExtension->CursorEnable;
|
|
pointerAttributes->WidthInBytes = 4;
|
|
pointerAttributes->Width = 32;
|
|
pointerAttributes->Height = 32;
|
|
|
|
//
|
|
// Return the hardware pixel values.
|
|
//
|
|
|
|
//
|
|
// calculate the size in bytes of 1 mask
|
|
//
|
|
|
|
CursorMaskSize = pointerAttributes->WidthInBytes * pointerAttributes->Height;
|
|
|
|
//
|
|
// copy the xor mask to the first plane for the Bt484
|
|
//
|
|
|
|
for (index1=0;index1<CursorMaskSize;index1++) {
|
|
|
|
pointerAttributes->Pixels[index1 + CursorMaskSize] =
|
|
(UCHAR)hwDeviceExtension->CursorPixels[index1];
|
|
}
|
|
|
|
|
|
//
|
|
// copy the and mask to the second plane for the Bt484
|
|
//
|
|
|
|
for (index1=0;index1<CursorMaskSize;index1++) {
|
|
|
|
pointerAttributes->Pixels[index1] =
|
|
(UCHAR)hwDeviceExtension->CursorPixels[index1 + CursorMaskSize];
|
|
}
|
|
|
|
status = NO_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case IOCTL_VIDEO_QUERY_JAGUAR:
|
|
|
|
//
|
|
// Map 1 page for jaguar registers into user address space.
|
|
// Map 1 page for Jagaur FIFO into user address space.
|
|
// Determin the amount of video memory installed.
|
|
// return this information
|
|
//
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information = sizeof(VIDEO_JAGUAR_INFO)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
PVOID UserVirtualAddress;
|
|
ULONG AddressLength;
|
|
|
|
//
|
|
// Map the jagaur registers into user virual address space
|
|
//
|
|
|
|
UserVirtualAddress = NULL;
|
|
AddressLength = hwDeviceExtension->PhysicalControlLength;
|
|
|
|
//
|
|
// Map this address range into user address space
|
|
//
|
|
|
|
inIoSpace = 0;
|
|
|
|
status = VideoPortMapMemory(hwDeviceExtension,
|
|
hwDeviceExtension->PhysicalControlAddress,
|
|
&AddressLength,
|
|
&inIoSpace,
|
|
&UserVirtualAddress);
|
|
|
|
if (status != NO_ERROR) {
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Copy the address to the output buffer
|
|
//
|
|
|
|
((PVIDEO_JAGUAR_INFO)RequestPacket->OutputBuffer)->VideoControlVirtualBase =
|
|
UserVirtualAddress;
|
|
|
|
|
|
//
|
|
// Map the jaguar fifo regs into user address space
|
|
//
|
|
|
|
UserVirtualAddress = NULL;
|
|
AddressLength = hwDeviceExtension->PhysicalFifoLength;
|
|
|
|
inIoSpace = 0;
|
|
|
|
status = VideoPortMapMemory(hwDeviceExtension,
|
|
hwDeviceExtension->PhysicalFifoAddress,
|
|
&AddressLength,
|
|
&inIoSpace,
|
|
&UserVirtualAddress);
|
|
|
|
//
|
|
// Copy the address to the output buffer
|
|
//
|
|
|
|
((PVIDEO_JAGUAR_INFO)RequestPacket->OutputBuffer)->FifoVirtualBase =
|
|
UserVirtualAddress;
|
|
|
|
}
|
|
|
|
break ;
|
|
|
|
//
|
|
// if we get here, an invalid IoControlCode was specified.
|
|
//
|
|
|
|
default:
|
|
|
|
status = ERROR_INVALID_FUNCTION;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (turnOnInterrupts) {
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlJaguarBase->InterruptEnable.Byte,
|
|
VXL_INTERRUPT_VERTICAL_RETRACE);
|
|
|
|
}
|
|
|
|
|
|
|
|
RequestPacket->StatusBlock->Status = status;
|
|
|
|
return TRUE;
|
|
|
|
} // end VxlStartIO()
|
|
|
|
BOOLEAN
|
|
VxlInterruptService(
|
|
PVOID HwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the interrupt service routine for the Jazz kernel video
|
|
driver.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Pointer to the miniport driver's adapter information.
|
|
|
|
Return Value:
|
|
|
|
TRUE since the interrupt is always serviced.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG index;
|
|
SHORT x;
|
|
SHORT y;
|
|
UCHAR InterruptSource;
|
|
ULONG Index;
|
|
PBT484_REGISTERS Bt484 = hwDeviceExtension->VxlBT484Base;
|
|
|
|
//
|
|
// Disable the verticle retrace interrupt.
|
|
//
|
|
|
|
//
|
|
// Read the interrupt source before disabling interrupts
|
|
//
|
|
|
|
InterruptSource =
|
|
VideoPortReadRegisterUchar(&hwDeviceExtension->VxlJaguarBase->InterruptSource.Byte);
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlJaguarBase->InterruptEnable.Byte, 0);
|
|
|
|
// VideoPortDisableInterrupt(hwDeviceExtension);
|
|
|
|
//
|
|
// Determin whether this is a vertical retrace interrupt, a JAGUAR command FIFO interrupt or
|
|
// a writeable GDI interrupt.
|
|
//
|
|
|
|
|
|
//
|
|
// Clear all but lower three bits
|
|
//
|
|
|
|
InterruptSource &= 0x07;
|
|
|
|
//
|
|
// Only the vertical retrace bit should be set, any other condition is an error
|
|
//
|
|
|
|
if (InterruptSource == VXL_INTERRUPT_VERTICAL_RETRACE) {
|
|
|
|
//
|
|
// Clear this interrupt in the JAGUAR interrupt source register
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlJaguarBase->InterruptSource.Byte,InterruptSource);
|
|
|
|
//
|
|
// If the color map should be updated, then load the color map into the
|
|
// Bt484 Display controller.
|
|
//
|
|
|
|
if (hwDeviceExtension->UpdateColorMap != FALSE) {
|
|
|
|
//
|
|
// Init the Bt484 Palette Write Address register to the first
|
|
// palette location to be updated.
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->PaletteCursorWrAddress.Byte,
|
|
(UCHAR)(hwDeviceExtension->FirstEntry & 0xff));
|
|
|
|
//
|
|
// Update all entries by performing three writes to each location, R,G,B
|
|
//
|
|
|
|
for (index = hwDeviceExtension->FirstEntry;
|
|
index < hwDeviceExtension->LastEntry; index += 1) {
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->PaletteColor.Byte,
|
|
hwDeviceExtension->ColorMap[index].RgbData.Red);
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->PaletteColor.Byte,
|
|
hwDeviceExtension->ColorMap[index].RgbData.Green);
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->PaletteColor.Byte,
|
|
hwDeviceExtension->ColorMap[index].RgbData.Blue);
|
|
|
|
}
|
|
|
|
hwDeviceExtension->UpdateColorMap = FALSE;
|
|
}
|
|
|
|
//
|
|
// If the hardware cursor position and/or enable control information
|
|
// should be updated, then write the appropriate control registers.
|
|
//
|
|
|
|
if (hwDeviceExtension->UpdateCursorPosition != FALSE) {
|
|
|
|
//
|
|
// If the hardware cursor is enabled, then set the appropriate
|
|
// control information and update the column and row position.
|
|
// Otherwise, clear the appropriate control information.
|
|
//
|
|
|
|
if (hwDeviceExtension->CursorEnable != FALSE) {
|
|
|
|
//
|
|
// Update the CURSOR Location
|
|
//
|
|
|
|
x = hwDeviceExtension->CursorColumn +
|
|
hwDeviceExtension->CursorXOrigin;
|
|
y = hwDeviceExtension->CursorRow +
|
|
hwDeviceExtension->CursorYOrigin;
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorXLow.Byte,
|
|
(x & 0xff));
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorXHigh.Byte,
|
|
((x & 0xff00) >> 8));
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorYLow.Byte,
|
|
(y & 0xff));
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorYHigh.Byte,
|
|
((y & 0xff00) >> 8));
|
|
|
|
} else {
|
|
|
|
//
|
|
// Initialize cursor RAM
|
|
//
|
|
// Set address pointer to base of ram.
|
|
// Set both planes to transparent (cursor disabled)
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0);
|
|
|
|
//
|
|
// Plane 0 = 0
|
|
//
|
|
|
|
for (Index=0; Index < (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index++) {
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,0);
|
|
}
|
|
|
|
//
|
|
// Plane 1 = 1
|
|
//
|
|
|
|
for (Index= (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index < VXL_CURSOR_NUMBER_OF_BYTES ; Index++) {
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,0xff);
|
|
}
|
|
|
|
//
|
|
// Move the cursor off screen to avoid flash when re-enabling
|
|
//
|
|
|
|
x = 0;
|
|
y = 0;
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorXLow.Byte,
|
|
(x & 0xff));
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorXHigh.Byte,
|
|
((x & 0xff00) >> 8));
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorYLow.Byte,
|
|
(y & 0xff));
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorYHigh.Byte,
|
|
((y & 0xff00) >> 8));
|
|
|
|
|
|
}
|
|
|
|
hwDeviceExtension->UpdateCursorPosition = FALSE;
|
|
}
|
|
|
|
//
|
|
// If the hardware cursor pixels should be updated, then load the cursor
|
|
// ram into the Bt484 cursor.
|
|
//
|
|
|
|
if (hwDeviceExtension->UpdateCursorPixels != FALSE) {
|
|
|
|
//
|
|
// only change to the new shape if the cursor is enabled
|
|
//
|
|
|
|
if (hwDeviceExtension->CursorEnable != FALSE) {
|
|
|
|
//
|
|
// Set the cursor RAM address pointer to location 0
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->PaletteCursorWrAddress.Byte,0);
|
|
|
|
//
|
|
// Update both cursor planes.
|
|
//
|
|
|
|
for (index = 0; index < VXL_CURSOR_NUMBER_OF_BYTES ; index++) {
|
|
|
|
VideoPortWriteRegisterUchar(&hwDeviceExtension->VxlBT484Base->CursorRam.Byte,
|
|
(UCHAR)hwDeviceExtension->CursorPixels[index]);
|
|
|
|
}
|
|
|
|
hwDeviceExtension->UpdateCursorPixels = FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Illegal type of video interrupt was received...
|
|
//
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
} // end VxlInterruptService()
|
|
|
|
|
|
VOID
|
|
VxlSetMode(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set the current mode based on the video mode number selected in the device extension.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Index;
|
|
PJAGUAR_REGISTERS Jaguar = hwDeviceExtension->VxlJaguarBase;
|
|
PBT484_REGISTERS Bt484 = hwDeviceExtension->VxlBT484Base;
|
|
PUCHAR Clock = (PUCHAR)hwDeviceExtension->VxlClockBase;
|
|
UCHAR DataChar,CmdReg0,CmdReg1;
|
|
|
|
//
|
|
// The mode information is stored in
|
|
// JagModes[hwDeviceExtension->ModeNumber].pJagInitData
|
|
//
|
|
|
|
PJAGUAR_REG_INIT JaguarInitData = (PVOID)
|
|
(JagModes[hwDeviceExtension->ModeNumber].ModeSetTable);
|
|
|
|
//
|
|
//
|
|
// Start ICS Clock pll and stabilize.
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(Clock, JaguarInitData->ClockFreq);
|
|
|
|
//
|
|
// Wait 10 uS for PLL clock to stabilize on the video board
|
|
//
|
|
|
|
VideoPortStallExecution(10);
|
|
|
|
//
|
|
// Initialize Bt484 Command Register 0 to:
|
|
//
|
|
// 8 Bit DAC Resolution
|
|
//
|
|
|
|
CmdReg0 = 0;
|
|
((PBT484_COMMAND0)(&CmdReg0))->DacResolution = 1;
|
|
((PBT484_COMMAND0)(&CmdReg0))->GreenSyncEnable = 1;
|
|
((PBT484_COMMAND0)(&CmdReg0))->SetupEnable = 1;
|
|
VideoPortWriteRegisterUchar(&Bt484->Command0.Byte,CmdReg0);
|
|
|
|
//
|
|
// Initialize Command Register 1 to:
|
|
//
|
|
|
|
CmdReg1 = 0;
|
|
|
|
switch (JagModes[hwDeviceExtension->ModeNumber].modeInformation.BitsPerPlane) {
|
|
|
|
case 24:
|
|
((PBT484_COMMAND1)(&CmdReg1))->BitsPerPixel = VXL_THIRTYTWO_BITS_PER_PIXEL;
|
|
((PBT484_COMMAND1)(&CmdReg1))->TrueColorBypass = 1;
|
|
break;
|
|
|
|
case 16:
|
|
|
|
((PBT484_COMMAND1)(&CmdReg1))->BitsPerPixel = VXL_SIXTEEN_BITS_PER_PIXEL;
|
|
((PBT484_COMMAND1)(&CmdReg1))->TrueColorBypass = 1;
|
|
break;
|
|
|
|
case 8:
|
|
|
|
((PBT484_COMMAND1)(&CmdReg1))->BitsPerPixel = VXL_EIGHT_BITS_PER_PIXEL;
|
|
break;
|
|
|
|
}
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->Command1.Byte,CmdReg1);
|
|
|
|
//
|
|
// Initialize Command Register 2 to:
|
|
//
|
|
// SCLK Enabled
|
|
// TestMode disabled
|
|
// PortselMask Non Masked
|
|
// PCLK 1
|
|
// NonInterlaced
|
|
//
|
|
|
|
DataChar = 0;
|
|
((PBT484_COMMAND2)(&DataChar))->SclkDisable = 0;
|
|
((PBT484_COMMAND2)(&DataChar))->TestEnable = 0;
|
|
((PBT484_COMMAND2)(&DataChar))->PortselMask = 1;
|
|
((PBT484_COMMAND2)(&DataChar))->PclkSelect = 1;
|
|
((PBT484_COMMAND2)(&DataChar))->InterlacedDisplay = 0;
|
|
((PBT484_COMMAND2)(&DataChar))->PaletteIndexing = CONTIGUOUS_PALETTE;
|
|
((PBT484_COMMAND2)(&DataChar))->CursorMode = BT_CURSOR_WINDOWS;
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->Command2.Byte,DataChar);
|
|
|
|
|
|
//
|
|
// If the mode is set to 1 and the Bt485 flag is set then set the internal
|
|
// 2x multiplier inside the Bt485. All other init steps are identical for the
|
|
// Bt484 and Bt485.
|
|
//
|
|
|
|
|
|
if (JaguarInitData->Bt485Multiply == 1) {
|
|
|
|
//
|
|
// To access cmd register 3, first set bit CR17 in command register 0
|
|
//
|
|
|
|
CmdReg0 |= 0x80;
|
|
VideoPortWriteRegisterUchar(&Bt484->Command0.Byte,CmdReg0);
|
|
|
|
//
|
|
// Write a 0x01 to Address register
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0x01);
|
|
|
|
//
|
|
// Write to cmd register 3 in the status register location. Cmd3 is initialized
|
|
// to turn on the 2x clock multiplier.
|
|
//
|
|
|
|
DataChar = 0;
|
|
((PBT484_COMMAND3)(&DataChar))->ClockMultiplier = 1;
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->Status.Byte,DataChar);
|
|
|
|
//
|
|
// Allow 10 uS for the 2x multiplier to stabilize
|
|
//
|
|
|
|
VideoPortStallExecution(10);
|
|
|
|
}
|
|
//
|
|
// Initialize Cursor and Overscan color.
|
|
//
|
|
// Set address pointer base.
|
|
// Zero 4 entries.
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColorWrAddress.Byte,0);
|
|
|
|
//
|
|
// Zero overlay color
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
|
|
|
|
//
|
|
// Set cursor color 1 to black
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0);
|
|
|
|
//
|
|
// Set cursor color 2 to white
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
|
|
|
|
//
|
|
// Set Cursor color 3 to red (error)
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0xff);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0x00);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorColor.Byte,0x00);
|
|
|
|
//
|
|
// Initialize cursor RAM
|
|
//
|
|
// Set address pointer to base of ram.
|
|
// Set both planes to transparent (cursor disabled)
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->PaletteCursorWrAddress.Byte,0);
|
|
|
|
//
|
|
// Plane 0 = 0
|
|
//
|
|
|
|
for (Index=0; Index < (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index++) {
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,0);
|
|
}
|
|
|
|
//
|
|
// Plane 1 = 1
|
|
//
|
|
|
|
for (Index= (VXL_CURSOR_NUMBER_OF_BYTES / 2); Index < VXL_CURSOR_NUMBER_OF_BYTES ; Index++) {
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorRam.Byte,1);
|
|
}
|
|
|
|
//
|
|
// Initialize cursor position registers--cursor off.
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorXLow.Byte,0);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorXHigh.Byte,0);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorYLow.Byte,0);
|
|
VideoPortWriteRegisterUchar(&Bt484->CursorYHigh.Byte,0);
|
|
|
|
//
|
|
// Initialize pixel mask.
|
|
//
|
|
|
|
VideoPortWriteRegisterUchar(&Bt484->PixelMask.Byte,0xFF);
|
|
|
|
//
|
|
// Init Jaguar Registers
|
|
//
|
|
|
|
//DbgPrint("Init Timing registers:\n");
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->TopOfScreen.Short,
|
|
JaguarInitData->TopOfScreen);
|
|
//DbgPrint("TopOfScreen %lx\n",JaguarInitData->TopOfScreen);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->HorizontalBlank.Short,
|
|
JaguarInitData->HorizontalBlank);
|
|
//DbgPrint("HorizontalBlank %lx\n",JaguarInitData->HorizontalBlank);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->HorizontalBeginSync.Short,
|
|
JaguarInitData->HorizontalBeginSync);
|
|
//DbgPrint("HorizontalBeginSync %lx\n",JaguarInitData->HorizontalBeginSync);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->HorizontalEndSync.Short,
|
|
JaguarInitData->HorizontalEndSync);
|
|
//DbgPrint("HorizontalEndSync %lx\n",JaguarInitData->HorizontalEndSync);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->HorizontalLine.Short,
|
|
JaguarInitData->HorizontalLine);
|
|
//DbgPrint("HorizontalLine %lx\n",JaguarInitData->HorizontalLine);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->VerticalBlank.Short,
|
|
JaguarInitData->VerticalBlank);
|
|
//DbgPrint("VerticalBlank %lx\n",JaguarInitData->VerticalBlank);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->VerticalBeginSync.Short,
|
|
JaguarInitData->VerticalBeginSync);
|
|
//DbgPrint("VerticalBeginSync %lx\n",JaguarInitData->VerticalBeginSync);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->VerticalEndSync.Short,
|
|
JaguarInitData->VerticalEndSync);
|
|
//DbgPrint("VerticalEndSync %lx\n",JaguarInitData->VerticalEndSync);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->VerticalLine.Short,
|
|
JaguarInitData->VerticalLine);
|
|
//DbgPrint("VerticalLine %lx\n",JaguarInitData->VerticalLine);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->XferLength.Short,
|
|
JaguarInitData->XferLength);
|
|
//DbgPrint("XferLength %lx\n",JaguarInitData->XferLength);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->VerticalInterruptLine.Short,
|
|
JaguarInitData->VerticalInterruptLine);
|
|
//DbgPrint("VerticalInterruptLine %lx\n",JaguarInitData->VerticalInterruptLine);
|
|
|
|
VideoPortWriteRegisterUshort(&Jaguar->HorizontalDisplay.Short,
|
|
JaguarInitData->HorizontalDisplay);
|
|
//DbgPrint("HorizontalDisplay %lx\n",JaguarInitData->HorizontalDisplay);
|
|
|
|
VideoPortWriteRegisterUchar(&Jaguar->BitBltControl.Byte,
|
|
JaguarInitData->BitBltControl);
|
|
//DbgPrint("BitBltControl %lx\n",JaguarInitData->BitBltControl);
|
|
|
|
}
|