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.
2279 lines
61 KiB
2279 lines
61 KiB
/*++
|
|
|
|
Copyright (c) 1990-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
jazzg364.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the code that implements the Jazz kernel
|
|
video driver.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "dderror.h"
|
|
#include "devioctl.h"
|
|
#include "miniport.h"
|
|
|
|
#include "ntddvdeo.h"
|
|
#include "video.h"
|
|
#include "jazzvdeo.h"
|
|
|
|
|
|
//
|
|
// Define macros to access video control, video memory, and cursor control
|
|
// addresses.
|
|
//
|
|
|
|
#define VIDEO_CONTROL ((PG364_VIDEO_REGISTERS)(hwDeviceExtension->VideoAddress))
|
|
|
|
//
|
|
// Defines used to determine which version of the device is present.
|
|
// This is stored inthe DeviceTypeIdentifier in the device extension.
|
|
//
|
|
|
|
#define JAZZG364 1
|
|
#define MIPSG364 2
|
|
#define OLIVETTIG364 3
|
|
|
|
//
|
|
// defines used to determine which string must be found for the device
|
|
//
|
|
|
|
#define JAZZG364_NAME L"Jazz G364"
|
|
#define MIPSG364_NAME L"Mips G364"
|
|
#define OLIVETTIG364_NAME L"OLIVETTI_G364"
|
|
|
|
#define JAZZG364_NAME_LENGTH 20
|
|
#define MIPSG364_NAME_LENGTH 20
|
|
#define OLIVETTIG364_NAME_LENGTH 28
|
|
|
|
#define G364_CURSOR_MINIMUM_POS -64
|
|
|
|
|
|
//
|
|
// Define device extension structure.
|
|
//
|
|
|
|
typedef struct _HW_DEVICE_EXTENSION {
|
|
ULONG DeviceTypeIdentifier;
|
|
PVOID RomAddress;
|
|
PVOID MonitorIdAddress;
|
|
PVOID ResetRegisterAddress;
|
|
PVOID VideoAddress;
|
|
PVOID FrameAddress;
|
|
PHYSICAL_ADDRESS PhysicalFrameAddress;
|
|
ULONG FrameLength;
|
|
PVIDEO_CLUT SynchronizeClutBuffer;
|
|
PVIDEO_POINTER_ATTRIBUTES SynchronizePointerAttributes;
|
|
PVIDEO_POINTER_POSITION SynchronizePointerPosition;
|
|
union {
|
|
VIDEO_CLUTDATA RgbData;
|
|
ULONG RgbLong;
|
|
} ColorMap[NUMBER_OF_COLORS];
|
|
USHORT FirstEntry;
|
|
USHORT LastEntry;
|
|
USHORT CursorControlOn;
|
|
USHORT CursorControlOff;
|
|
USHORT CursorWidth;
|
|
USHORT CursorHeight;
|
|
SHORT CursorColumn;
|
|
SHORT CursorRow;
|
|
union {
|
|
VIDEO_CLUTDATA RgbData;
|
|
ULONG RgbLong;
|
|
} CursorColorMap[3];
|
|
USHORT CursorPixels[CURSOR_MAXIMUM];
|
|
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;
|
|
} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
|
|
|
|
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
// Functions that start with 'G364' are entry points for the OS port driver.
|
|
//
|
|
|
|
VP_STATUS
|
|
G364FindAdapter(
|
|
PVOID HwDeviceExtension,
|
|
PVOID HwContext,
|
|
PWSTR ArgumentString,
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|
PUCHAR Again
|
|
);
|
|
|
|
BOOLEAN
|
|
G364Initialize(
|
|
PVOID HwDeviceExtension
|
|
);
|
|
|
|
BOOLEAN
|
|
G364InterruptService (
|
|
PVOID HwDeviceExtension
|
|
);
|
|
|
|
BOOLEAN
|
|
G364StartIO(
|
|
PVOID HwDeviceExtension,
|
|
PVIDEO_REQUEST_PACKET RequestPacket
|
|
);
|
|
|
|
//
|
|
// Define device driver procedure prototypes.
|
|
//
|
|
|
|
VP_STATUS
|
|
G364GetDeviceDataCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
PVOID Identifier,
|
|
ULONG IdentifierLength,
|
|
PVOID ConfigurationData,
|
|
ULONG ConfigurationDataLength,
|
|
PVOID ComponentInformation,
|
|
ULONG ComponentInformationLength
|
|
);
|
|
|
|
BOOLEAN
|
|
G364SetColorRegisters(
|
|
PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
G364EnablePointer(
|
|
PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
G364DisablePointer(
|
|
PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
G364SetPointerPosition(
|
|
PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
G364SetPointer(
|
|
PVOID Context
|
|
);
|
|
|
|
VOID
|
|
G364AttributesSetup (
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
VOID
|
|
G364ControllerSetup (
|
|
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 = G364FindAdapter;
|
|
hwInitData.HwInitialize = G364Initialize;
|
|
hwInitData.HwInterrupt = G364InterruptService;
|
|
hwInitData.HwStartIO = G364StartIO;
|
|
|
|
//
|
|
// 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
|
|
G364FindAdapter(
|
|
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,
|
|
&G364GetDeviceDataCallback,
|
|
ConfigInfo)) {
|
|
|
|
VideoDebugPrint((2, "G364: VideoPort get controller info failed\n"));
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
if (VideoPortGetDeviceData(hwDeviceExtension,
|
|
VpMonitorData,
|
|
&G364GetDeviceDataCallback,
|
|
NULL)) {
|
|
|
|
VideoDebugPrint((2, "G364: 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 G364FindAdapter()
|
|
|
|
VP_STATUS
|
|
G364GetDeviceDataCallback(
|
|
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 g364ConfigData = ConfigurationData;
|
|
PMONITOR_CONFIG_DATA monitorConfigData = ConfigurationData;
|
|
VIDEO_ACCESS_RANGE accessRanges[3];
|
|
VP_STATUS status;
|
|
|
|
switch (DeviceDataType) {
|
|
|
|
case VpControllerData:
|
|
|
|
VideoDebugPrint((2, "G364: getting controller information\n"));
|
|
|
|
VideoDebugPrint((2, "G364: controller identifier is %ws\n", Identifier));
|
|
|
|
//
|
|
// 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 ( OLIVETTIG364_NAME_LENGTH ==
|
|
VideoPortCompareMemory(identifier,
|
|
OLIVETTIG364_NAME,
|
|
OLIVETTIG364_NAME_LENGTH)) {
|
|
|
|
hwDeviceExtension->DeviceTypeIdentifier = OLIVETTIG364;
|
|
|
|
} else {
|
|
|
|
if ( JAZZG364_NAME_LENGTH ==
|
|
VideoPortCompareMemory(identifier,
|
|
JAZZG364_NAME,
|
|
JAZZG364_NAME_LENGTH)) {
|
|
|
|
hwDeviceExtension->DeviceTypeIdentifier = JAZZG364;
|
|
|
|
} else {
|
|
|
|
if ( MIPSG364_NAME_LENGTH ==
|
|
VideoPortCompareMemory(identifier,
|
|
MIPSG364_NAME,
|
|
MIPSG364_NAME_LENGTH)) {
|
|
|
|
hwDeviceExtension->DeviceTypeIdentifier = MIPSG364;
|
|
|
|
} else {
|
|
|
|
return ERROR_DEV_NOT_EXIST;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fill up the device extension and the configuration information
|
|
// with the appropriate data.
|
|
//
|
|
|
|
ConfigInfo->BusInterruptLevel = g364ConfigData->Irql;
|
|
ConfigInfo->BusInterruptVector = g364ConfigData->Vector;
|
|
|
|
//
|
|
// Save the ranges in the range buffer allocated for us.
|
|
//
|
|
|
|
accessRanges[0].RangeStart.HighPart = 0;
|
|
accessRanges[0].RangeStart.LowPart = 0x60080000; //g364ConfigData->ControlBase;
|
|
accessRanges[0].RangeLength = 0x00002000; //g364ConfigData->ControlSize;
|
|
accessRanges[0].RangeInIoSpace = 0;
|
|
accessRanges[0].RangeVisible = 0;
|
|
accessRanges[0].RangeShareable = 0;
|
|
|
|
accessRanges[1].RangeStart.HighPart = 0;
|
|
accessRanges[1].RangeStart.LowPart = 0x60180000; // g364ConfigData->ResetRegister;
|
|
accessRanges[1].RangeLength = 8 ; // g364ConfigData->ResetSize;
|
|
accessRanges[1].RangeInIoSpace = 0;
|
|
accessRanges[1].RangeVisible = 0;
|
|
accessRanges[1].RangeShareable = 0;
|
|
|
|
accessRanges[2].RangeStart.HighPart = 0;
|
|
accessRanges[2].RangeStart.LowPart = 0x40000000; // g364ConfigData->FrameBase;
|
|
accessRanges[2].RangeLength = 0x00200000; // g364ConfigData->FrameSize;
|
|
accessRanges[2].RangeInIoSpace = 0;
|
|
accessRanges[2].RangeVisible = 0;
|
|
accessRanges[2].RangeShareable = 0;
|
|
|
|
//
|
|
// Check to see if there is a hardware resource conflict.
|
|
//
|
|
|
|
status = VideoPortVerifyAccessRanges(HwDeviceExtension,
|
|
3,
|
|
accessRanges);
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
//
|
|
// Frame buffer information
|
|
//
|
|
|
|
hwDeviceExtension->PhysicalFrameAddress.HighPart = 0;
|
|
hwDeviceExtension->PhysicalFrameAddress.LowPart = 0x40000000; // g364ConfigData->FrameBase;
|
|
hwDeviceExtension->FrameLength = 0x00200000; // g364ConfigData->FrameSize;
|
|
|
|
|
|
//
|
|
// Map the video controller into the system virtual address space.
|
|
//
|
|
|
|
if ( (hwDeviceExtension->VideoAddress =
|
|
VideoPortGetDeviceBase(hwDeviceExtension,
|
|
accessRanges[0].RangeStart, // Control
|
|
accessRanges[0].RangeLength,
|
|
FALSE)) == NULL) {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
//
|
|
// Map the cursor memory into the system virtual address space so we
|
|
// can talk to it.
|
|
//
|
|
|
|
if ( (hwDeviceExtension->ResetRegisterAddress =
|
|
VideoPortGetDeviceBase(hwDeviceExtension,
|
|
accessRanges[1].RangeStart, // cursor
|
|
accessRanges[1].RangeLength,
|
|
FALSE)) == NULL) {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
//
|
|
// Map the video memory into the system virtual address space so we
|
|
// can clear it out.
|
|
//
|
|
|
|
if ( (hwDeviceExtension->FrameAddress =
|
|
VideoPortGetDeviceBase(hwDeviceExtension,
|
|
accessRanges[2].RangeStart, // Frame
|
|
accessRanges[2].RangeLength,
|
|
FALSE)) == NULL) {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
return NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case VpMonitorData:
|
|
|
|
VideoDebugPrint((2, "G364: 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:
|
|
|
|
VideoDebugPrint((2, "G364: callback has bad device type\n"));
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
} //end G364GetDeviceDataCallback()
|
|
|
|
BOOLEAN
|
|
G364Initialize(
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
G364AttributesSetup((PHW_DEVICE_EXTENSION) HwDeviceExtension);
|
|
|
|
G364ControllerSetup((PHW_DEVICE_EXTENSION) HwDeviceExtension);
|
|
|
|
return TRUE;
|
|
|
|
} // end G364Initialize()
|
|
|
|
BOOLEAN
|
|
G364StartIO(
|
|
PVOID HwDeviceExtension,
|
|
PVIDEO_REQUEST_PACKET RequestPacket
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the main execution routine for the miniport driver. It
|
|
acceptss 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;
|
|
PVIDEO_MODE_INFORMATION modeInformation;
|
|
PVIDEO_MEMORY_INFORMATION memoryInformation;
|
|
PVIDEO_POINTER_ATTRIBUTES pointerAttributes;
|
|
PVIDEO_POINTER_POSITION pointerPosition;
|
|
PVIDEO_CLUT clutBuffer;
|
|
ULONG index1;
|
|
ULONG index2;
|
|
PUCHAR pixelDestination;
|
|
ULONG pixelIndex;
|
|
ULONG pixelShift;
|
|
PUCHAR pixelSource;
|
|
UCHAR pixelValue;
|
|
PVIDEO_SHARE_MEMORY pShareMemory;
|
|
PVIDEO_SHARE_MEMORY_INFORMATION pShareMemoryInformation;
|
|
PHYSICAL_ADDRESS shareAddress;
|
|
PVOID virtualAddress;
|
|
ULONG sharedViewSize;
|
|
|
|
//
|
|
// Switch on the IoContolCode in the RequestPacket. It indicates which
|
|
// function must be performed by the driver.
|
|
//
|
|
|
|
switch (RequestPacket->IoControlCode) {
|
|
|
|
|
|
case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
|
|
|
|
VideoDebugPrint((2, "DGXStartIO - ShareVideoMemory\n"));
|
|
|
|
if ( (RequestPacket->OutputBufferLength < sizeof(VIDEO_SHARE_MEMORY_INFORMATION)) ||
|
|
(RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
|
|
}
|
|
|
|
pShareMemory = RequestPacket->InputBuffer;
|
|
|
|
if ( (pShareMemory->ViewOffset > hwDeviceExtension->FrameLength) ||
|
|
((pShareMemory->ViewOffset + pShareMemory->ViewSize) >
|
|
hwDeviceExtension->FrameLength) ) {
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
|
|
}
|
|
|
|
RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_SHARE_MEMORY_INFORMATION);
|
|
|
|
//
|
|
// Beware: the input buffer and the output buffer are the same
|
|
// buffer, and therefore data should not be copied from one to the
|
|
// other
|
|
//
|
|
|
|
virtualAddress = pShareMemory->ProcessHandle;
|
|
sharedViewSize = pShareMemory->ViewSize;
|
|
|
|
inIoSpace = 0;
|
|
|
|
//
|
|
// NOTE: we are ignoring ViewOffset
|
|
//
|
|
|
|
shareAddress.QuadPart =
|
|
hwDeviceExtension->PhysicalFrameAddress.QuadPart;
|
|
|
|
status = VideoPortMapMemory(hwDeviceExtension,
|
|
shareAddress,
|
|
&sharedViewSize,
|
|
&inIoSpace,
|
|
&virtualAddress);
|
|
|
|
pShareMemoryInformation = RequestPacket->OutputBuffer;
|
|
|
|
pShareMemoryInformation->SharedViewOffset = pShareMemory->ViewOffset;
|
|
pShareMemoryInformation->VirtualAddress = virtualAddress;
|
|
pShareMemoryInformation->SharedViewSize = sharedViewSize;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
|
|
|
|
VideoDebugPrint((2, "G300StartIO - UnshareVideoMemory\n"));
|
|
|
|
if (RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY)) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
|
|
}
|
|
|
|
pShareMemory = RequestPacket->InputBuffer;
|
|
|
|
status = VideoPortUnmapMemory(hwDeviceExtension,
|
|
pShareMemory->RequestedVirtualAddress,
|
|
pShareMemory->ProcessHandle);
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - MapVideoMemory\n"));
|
|
|
|
if ( (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_MEMORY_INFORMATION))) ||
|
|
(RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
memoryInformation = RequestPacket->OutputBuffer;
|
|
|
|
memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
|
|
(RequestPacket->InputBuffer))->RequestedVirtualAddress;
|
|
|
|
memoryInformation->VideoRamLength =
|
|
hwDeviceExtension->FrameLength;
|
|
|
|
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, "G364StartIO - UnMapVideoMemory\n"));
|
|
|
|
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
status = VideoPortUnmapMemory(hwDeviceExtension,
|
|
((PVIDEO_MEMORY)
|
|
(RequestPacket->InputBuffer))->
|
|
RequestedVirtualAddress,
|
|
0);
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
|
|
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - Query(Available/Current)Modes\n"));
|
|
|
|
modeInformation = RequestPacket->OutputBuffer;
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_MODE_INFORMATION)) ) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
modeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
|
|
modeInformation->ModeIndex = 0;
|
|
|
|
modeInformation->VisScreenWidth =
|
|
modeInformation->ScreenStride = hwDeviceExtension->HorizontalResolution;
|
|
modeInformation->VisScreenHeight = hwDeviceExtension->VerticalResolution;
|
|
|
|
|
|
modeInformation->NumberOfPlanes = 1;
|
|
modeInformation->BitsPerPlane = DISPLAY_BITS_PER_PIXEL;
|
|
|
|
modeInformation->XMillimeter = 320;
|
|
modeInformation->YMillimeter = 240;
|
|
modeInformation->Frequency = 1;
|
|
|
|
modeInformation->NumberRedBits = 8;
|
|
modeInformation->NumberGreenBits = 8;
|
|
modeInformation->NumberBlueBits = 8;
|
|
|
|
modeInformation->RedMask = 0;
|
|
modeInformation->GreenMask = 0;
|
|
modeInformation->BlueMask = 0;
|
|
|
|
modeInformation->AttributeFlags = VIDEO_MODE_COLOR |
|
|
VIDEO_MODE_GRAPHICS | VIDEO_MODE_PALETTE_DRIVEN |
|
|
VIDEO_MODE_MANAGED_PALETTE;
|
|
|
|
status = NO_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - 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 = 1;
|
|
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
|
|
sizeof(VIDEO_MODE_INFORMATION);
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_CURRENT_MODE:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - SetCurrentMode\n"));
|
|
|
|
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_SET_PALETTE_REGISTERS:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - SetPaletteRegs\n"));
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - 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)) ) ) {
|
|
|
|
ASSERT(FALSE);
|
|
|
|
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) ) {
|
|
ASSERT(FALSE);
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
|
|
}
|
|
|
|
hwDeviceExtension->SynchronizeClutBuffer = clutBuffer;
|
|
|
|
if (VideoPortSynchronizeExecution(hwDeviceExtension,
|
|
VpMediumPriority,
|
|
(PMINIPORT_SYNCHRONIZE_ROUTINE)
|
|
G364SetColorRegisters,
|
|
hwDeviceExtension)) {
|
|
|
|
status = NO_ERROR;
|
|
|
|
} else {
|
|
|
|
ASSERT(FALSE);
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
|
|
|
|
{
|
|
|
|
PVIDEO_POINTER_CAPABILITIES VideoPointerCapabilities;
|
|
|
|
VideoDebugPrint((2,"JazzG364 IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES\n"));
|
|
|
|
//
|
|
// 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 = CURSOR_WIDTH;
|
|
VideoPointerCapabilities->MaxHeight = CURSOR_HEIGHT;
|
|
VideoPointerCapabilities->HWPtrBitmapStart = 0xffffffff;
|
|
VideoPointerCapabilities->HWPtrBitmapEnd = 0xffffffff;
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_ENABLE_POINTER:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - EnablePointer\n"));
|
|
|
|
VideoPortSynchronizeExecution(hwDeviceExtension,
|
|
VpMediumPriority,
|
|
(PMINIPORT_SYNCHRONIZE_ROUTINE)
|
|
G364EnablePointer,
|
|
hwDeviceExtension);
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_DISABLE_POINTER:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - DisablePointer\n"));
|
|
|
|
VideoPortSynchronizeExecution(hwDeviceExtension,
|
|
VpMediumPriority,
|
|
(PMINIPORT_SYNCHRONIZE_ROUTINE)
|
|
G364DisablePointer,
|
|
hwDeviceExtension);
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_POINTER_POSITION:
|
|
|
|
VideoDebugPrint((2,"G364StartIO - SetPointerPosition\n"));
|
|
|
|
pointerPosition = RequestPacket->InputBuffer;
|
|
|
|
//
|
|
// 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 if (hwDeviceExtension->HorizontalResolution == 800) {
|
|
|
|
//
|
|
// hw cursor is broken at 800x600 resolution, fail call
|
|
//
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Capture the hardware cursor column and height values.
|
|
//
|
|
|
|
|
|
hwDeviceExtension->SynchronizePointerPosition = pointerPosition;
|
|
|
|
VideoPortSynchronizeExecution(hwDeviceExtension,
|
|
VpMediumPriority,
|
|
(PMINIPORT_SYNCHRONIZE_ROUTINE)
|
|
G364SetPointerPosition,
|
|
hwDeviceExtension);
|
|
|
|
|
|
status = NO_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_POINTER_POSITION:
|
|
|
|
VideoDebugPrint((2, "G364StartIO - QueryPointerPosition\n"));
|
|
|
|
pointerPosition = RequestPacket->OutputBuffer;
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
pointerPosition->Column = hwDeviceExtension->CursorColumn;
|
|
pointerPosition->Row = hwDeviceExtension->CursorRow;
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_POINTER_ATTR:
|
|
{
|
|
|
|
ULONG Index;
|
|
ULONG NumDwords;
|
|
PULONG pAnd;
|
|
PULONG pXor;
|
|
|
|
VideoDebugPrint((2, "G364StartIO - SetPointerAttributes\n"));
|
|
|
|
status = NO_ERROR;
|
|
|
|
pointerAttributes = RequestPacket->InputBuffer;
|
|
|
|
//
|
|
// Check if the size of the data in the input buffer is large enough.
|
|
//
|
|
|
|
if (RequestPacket->InputBufferLength <
|
|
(sizeof(VIDEO_POINTER_ATTRIBUTES) + ((sizeof(UCHAR) *
|
|
(CURSOR_WIDTH/8) * CURSOR_HEIGHT) * 2))) {
|
|
|
|
|
|
VideoDebugPrint((2, "SetPointerAttributes ERROR_INSUFFICIENT_BUFFER\n"));
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// hw cursor is broken at 800x600 resolution, fail call
|
|
//
|
|
|
|
if (hwDeviceExtension->HorizontalResolution == 800) {
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If the specified cursor width or height is not valid, then
|
|
// return an invalid parameter error.
|
|
//
|
|
|
|
if ((pointerAttributes->Width > CURSOR_WIDTH) ||
|
|
(pointerAttributes->Height > CURSOR_HEIGHT)) {
|
|
|
|
VideoDebugPrint((2, "SetPointerAttributes ERROR_INVALID_PARAMETER\n"));
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
// The G364 does not support XOR cursor, scan the input data
|
|
// for the cursor shape and look for any pixels that require
|
|
// XOR ie: AND = 1, XOR = 1
|
|
//
|
|
|
|
NumDwords = (CURSOR_WIDTH/32) * CURSOR_HEIGHT;
|
|
pAnd = (PULONG)pointerAttributes->Pixels;
|
|
pXor = (PULONG)(pAnd + NumDwords);
|
|
|
|
for (Index=0;Index<NumDwords;Index++) {
|
|
|
|
if (*pAnd & *pXor) {
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
pAnd++;
|
|
pXor++;
|
|
}
|
|
|
|
//
|
|
// If this cursor is supported, copy the cursor data into
|
|
// the device extension synchronized with the interrupt routine
|
|
//
|
|
|
|
if (status == NO_ERROR) {
|
|
|
|
hwDeviceExtension->SynchronizePointerAttributes = pointerAttributes;
|
|
|
|
VideoPortSynchronizeExecution(hwDeviceExtension,
|
|
VpMediumPriority,
|
|
(PMINIPORT_SYNCHRONIZE_ROUTINE)
|
|
G364SetPointer,
|
|
hwDeviceExtension);
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
//
|
|
// if we get here, an invalid IoControlCode was specified.
|
|
//
|
|
|
|
default:
|
|
|
|
VideoDebugPrint((1, "Fell through G364 startIO routine - invalid command\n"));
|
|
|
|
status = ERROR_INVALID_FUNCTION;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
RequestPacket->StatusBlock->Status = status;
|
|
|
|
return TRUE;
|
|
|
|
} // end G364StartIO()
|
|
|
|
BOOLEAN
|
|
G364SetColorRegisters(
|
|
PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is synchronized with the interrupt service routine.
|
|
|
|
Arguments:
|
|
|
|
Context - Pointer to a context parameter.
|
|
|
|
Return Value:
|
|
|
|
TRUE.
|
|
|
|
--*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = Context;
|
|
PVIDEO_CLUT clutBuffer = hwDeviceExtension->SynchronizeClutBuffer;
|
|
ULONG index1;
|
|
PULONG colorSource;
|
|
PVIDEO_CLUTDATA colorDest;
|
|
|
|
|
|
VideoDebugPrint((2,"JazzG364 SetColorRegisters\n"));
|
|
|
|
index1 = clutBuffer->FirstEntry;
|
|
hwDeviceExtension->FirstEntry = (USHORT)index1;
|
|
hwDeviceExtension->LastEntry = (USHORT)(index1 + clutBuffer->NumEntries);
|
|
colorSource = (PULONG)&(clutBuffer->LookupTable[0]);
|
|
|
|
while (index1 < hwDeviceExtension->LastEntry) {
|
|
|
|
colorDest = (PVIDEO_CLUTDATA)
|
|
&(hwDeviceExtension->ColorMap[index1++].RgbLong);
|
|
|
|
//
|
|
// Inverse the colors since this device is BGR
|
|
//
|
|
|
|
colorDest->Red = ((PVIDEO_CLUTDATA)colorSource)->Blue;
|
|
colorDest->Green = ((PVIDEO_CLUTDATA)colorSource)->Green;
|
|
colorDest->Blue = ((PVIDEO_CLUTDATA)colorSource)->Red;
|
|
|
|
colorSource++;
|
|
}
|
|
|
|
//
|
|
// Enable the verticle retrace interrupt to perform the update.
|
|
//
|
|
|
|
hwDeviceExtension->UpdateColorMap = TRUE;
|
|
|
|
VideoPortEnableInterrupt(hwDeviceExtension);
|
|
|
|
return TRUE;
|
|
|
|
} // end G364SetColorRegisters()
|
|
|
|
BOOLEAN
|
|
G364EnablePointer(
|
|
PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is synchronized with the interrupt service routine.
|
|
It enable the cursor in the device extension.
|
|
|
|
Arguments:
|
|
|
|
Context - Pointer to a context parameter.
|
|
|
|
Return Value:
|
|
|
|
TRUE.
|
|
|
|
--*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = Context;
|
|
|
|
//
|
|
// If the hardware pointer is currently disabled, then enable
|
|
// it and update the pointer position and pointer ram memory.
|
|
//
|
|
// N.B. Explicit synchronization is required since the enable,
|
|
// update pointer position, and update pointer pixels parameters
|
|
// must all be atomically written.
|
|
//
|
|
|
|
//
|
|
// Enable the verticle retrace interrupt to perform the update.
|
|
//
|
|
|
|
VideoDebugPrint((2,"JazzG364 EnablePointer\n"));
|
|
|
|
if (hwDeviceExtension->CursorEnable == FALSE) {
|
|
|
|
hwDeviceExtension->CursorEnable = TRUE;
|
|
hwDeviceExtension->UpdateCursorPixels = TRUE;
|
|
hwDeviceExtension->UpdateCursorPosition = TRUE;
|
|
VideoPortEnableInterrupt(hwDeviceExtension);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // end G364EnablePointer()
|
|
|
|
BOOLEAN
|
|
G364DisablePointer(
|
|
PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is synchronized with the interrupt service routine.
|
|
It enables the pointer in the device extension.
|
|
|
|
Arguments:
|
|
|
|
Context - Pointer to a context parameter.
|
|
|
|
Return Value:
|
|
|
|
TRUE.
|
|
|
|
--*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = Context;
|
|
|
|
VideoDebugPrint((2,"JazzG364 DisablePointer\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;
|
|
VideoPortEnableInterrupt(hwDeviceExtension);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // end G364DisablePointer()
|
|
|
|
BOOLEAN
|
|
G364SetPointerPosition(
|
|
PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is synchronized with the interrupt service routine.
|
|
It set the position of the pointer in the device extension.
|
|
|
|
Arguments:
|
|
|
|
Context - Pointer to a context parameter.
|
|
|
|
Return Value:
|
|
|
|
TRUE.
|
|
|
|
--*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = Context;
|
|
PVIDEO_POINTER_POSITION pPointerPosition = hwDeviceExtension->SynchronizePointerPosition;
|
|
|
|
//
|
|
// N.B. Explicit synchronization is required since both the enable
|
|
// and update cursor position parameters must be atomically
|
|
// written.
|
|
//
|
|
|
|
// DbgPrint("Miniport set pointer Pos : pos = %li,%li\n",pPointerPosition->Column,pPointerPosition->Row);
|
|
|
|
hwDeviceExtension->CursorColumn = pPointerPosition->Column;
|
|
hwDeviceExtension->CursorRow = pPointerPosition->Row;
|
|
|
|
if (pPointerPosition->Column == -1) {
|
|
|
|
//
|
|
// cursor is being temporarily disabled, move off screen
|
|
//
|
|
|
|
hwDeviceExtension->CursorColumn = G364_CURSOR_MINIMUM_POS;
|
|
hwDeviceExtension->CursorRow = G364_CURSOR_MINIMUM_POS;
|
|
|
|
}
|
|
|
|
hwDeviceExtension->UpdateCursorPosition = TRUE;
|
|
|
|
//
|
|
// Enable the verticle retrace interrupt to perform the update.
|
|
//
|
|
|
|
VideoPortEnableInterrupt(hwDeviceExtension);
|
|
|
|
|
|
return TRUE;
|
|
|
|
} // end G364SetPointerPosition()
|
|
|
|
BOOLEAN
|
|
G364SetPointer(
|
|
PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is synchronized with the interrupt service routine.
|
|
It sets in the device extension.
|
|
|
|
Arguments:
|
|
|
|
Context - Pointer to a context parameter.
|
|
|
|
Return Value:
|
|
|
|
TRUE.
|
|
|
|
--*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = Context;
|
|
|
|
PVIDEO_POINTER_ATTRIBUTES pointerAttributes =
|
|
hwDeviceExtension->SynchronizePointerAttributes;
|
|
ULONG index1;
|
|
ULONG index2;
|
|
PUCHAR pixelDestination;
|
|
ULONG pixelIndex;
|
|
ULONG pixelShift;
|
|
PUCHAR pAndSrc;
|
|
PUCHAR pXorSrc;
|
|
UCHAR AndSrc;
|
|
UCHAR XorSrc;
|
|
USHORT PixelValue;
|
|
|
|
VideoDebugPrint((2,"SetPointer\n"));
|
|
|
|
//
|
|
// Capture the hardware cursor width, height, column, and row
|
|
// values.
|
|
//
|
|
|
|
//DbgPrint("Miniport set pointer attr: pos = %li,%li\n",pointerAttributes->Column,pointerAttributes->Row);
|
|
|
|
hwDeviceExtension->CursorWidth = (USHORT)pointerAttributes->Width;
|
|
hwDeviceExtension->CursorHeight = (USHORT)pointerAttributes->Height;
|
|
hwDeviceExtension->CursorColumn = pointerAttributes->Column;
|
|
hwDeviceExtension->CursorRow = pointerAttributes->Row;
|
|
|
|
if ((hwDeviceExtension->CursorColumn == -1) && (hwDeviceExtension->CursorRow == -1)) {
|
|
|
|
//
|
|
// Move the pointer off screen, so it is not visible
|
|
//
|
|
|
|
hwDeviceExtension->CursorColumn = G364_CURSOR_MINIMUM_POS;
|
|
hwDeviceExtension->CursorRow = G364_CURSOR_MINIMUM_POS;
|
|
|
|
}
|
|
|
|
//
|
|
// Capture the hardware cursor pixel values and setup the
|
|
// hardware cursor ram memory. This requires a transformation
|
|
// of the pixels into a format that is understood by hardware.
|
|
//
|
|
// The software pixel values are defined as:
|
|
//
|
|
// 0 = transparent, i.e., don't display
|
|
// 1 = pointer color 0
|
|
// 2 = pointer color 1
|
|
//
|
|
// Each software pixel value is stored in a byte.
|
|
//
|
|
// Each hardware pixel requires two bits of information. One
|
|
// bit is the actual pixel value and the other bit is the pixel
|
|
// display enable. The hardware cursor parts store 8 pixels per
|
|
// cursor ram entry. The low order byte of the entry contains
|
|
// all the display enable bits and the high order byte contains
|
|
// the pixel values.
|
|
//
|
|
// Clear the device extension copy of the hardware cursor ram
|
|
// memory.
|
|
//
|
|
|
|
for (index1 = 0; index1 < CURSOR_MAXIMUM; index1++) {
|
|
hwDeviceExtension->CursorPixels[index1] = 0x0000;
|
|
}
|
|
|
|
//
|
|
// Compute the actual pixel values and insert them into the
|
|
// device extension copy of the hardware cursor ram memory.
|
|
//
|
|
// Convert And and Xor Masks
|
|
//
|
|
// 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
// ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
// ³A7 A6 A5 A4 A3 A2 A1 A0³ ³X7 X6 X5 X4 X3 X2 X1 X0³
|
|
// ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
//
|
|
// into the hw Cursor USHORT, stored as
|
|
//
|
|
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
|
// ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
// ³X0 A0 X1 A1 X2 A2 X3 A3 X4 A4 X5 A5 X6 A6 X7 A7 ³
|
|
// ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
//
|
|
|
|
pAndSrc = (PUCHAR)pointerAttributes->Pixels;
|
|
pXorSrc = (PUCHAR)(pAndSrc + (CURSOR_WIDTH / 8) * CURSOR_HEIGHT);
|
|
|
|
for (index1 = 0; index1 < CURSOR_MAXIMUM; index1++) {
|
|
|
|
AndSrc = ~(*pAndSrc);
|
|
XorSrc = *pXorSrc;
|
|
PixelValue = 0;
|
|
|
|
for (index2 = 0; index2 < 8; index2++) {
|
|
|
|
PixelValue <<= 2;
|
|
|
|
PixelValue |= (USHORT)((XorSrc & 0x01) << 1);
|
|
|
|
PixelValue |= (USHORT)(AndSrc & 0x01);
|
|
|
|
|
|
AndSrc >>= 1;
|
|
XorSrc >>= 1;
|
|
|
|
}
|
|
|
|
hwDeviceExtension->CursorPixels[index1] = PixelValue;
|
|
pAndSrc++;
|
|
pXorSrc++;
|
|
|
|
}
|
|
|
|
//
|
|
// Enable the verticle 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.
|
|
//
|
|
|
|
//
|
|
// NOTE: Disable interrupt driven update and do it immediately
|
|
//
|
|
// This routine sets the cursor shape, there is a large delay between each setting
|
|
// because the G364 cursor gets corrupted if writes happen too fast! This was removed
|
|
// from the interrupt routine to allow this delay!
|
|
//
|
|
|
|
//
|
|
//hwDeviceExtension->UpdateCursorPixels = TRUE;
|
|
//
|
|
//
|
|
|
|
{
|
|
|
|
ULONG index;
|
|
ULONG dataLong;
|
|
|
|
//
|
|
// Don't turn off CURSOR, this will cause animated cursors to flicker.
|
|
// Ignore AMINATE_UPDATE flag and just don't turn off any cursor shape update.
|
|
//
|
|
//
|
|
// Turn off cursor:
|
|
// Read-modify-write to set cursor disable bit in control register
|
|
//
|
|
//
|
|
//dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->Parameters.Long);
|
|
//
|
|
//((PG364_VIDEO_PARAMETERS)(&dataLong))->DisableCursor = 1;
|
|
//
|
|
//VideoPortWriteRegisterUlong(&VIDEO_CONTROL->Parameters.Long,
|
|
// dataLong);
|
|
//
|
|
//
|
|
// update the pixels SLOWLY
|
|
//
|
|
|
|
for (index = 0; index < CURSOR_MAXIMUM; index++) {
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorMemory[index].Long,
|
|
hwDeviceExtension->CursorPixels[index]);
|
|
|
|
//
|
|
// delay to eliminate cursor corruption on some cards, the cursor
|
|
// gets damaged if writes to cursor store happen too fast! This delay
|
|
// was determined experimentally
|
|
//
|
|
|
|
VideoPortStallExecution(40);
|
|
}
|
|
|
|
//
|
|
// set cursor colors
|
|
//
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPalette[0].Long,
|
|
hwDeviceExtension->CursorColorMap[0].RgbLong);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPalette[1].Long,
|
|
hwDeviceExtension->CursorColorMap[1].RgbLong);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPalette[2].Long,
|
|
hwDeviceExtension->CursorColorMap[2].RgbLong);
|
|
}
|
|
|
|
//
|
|
// re-enable the cursor at the next vertical interrupt
|
|
//
|
|
|
|
hwDeviceExtension->CursorEnable = (UCHAR) pointerAttributes->Enable;
|
|
hwDeviceExtension->UpdateCursorPosition = TRUE;
|
|
VideoPortEnableInterrupt(hwDeviceExtension);
|
|
|
|
return TRUE;
|
|
|
|
} // end JazzG364SetPointer()
|
|
|
|
BOOLEAN
|
|
G364InterruptService(
|
|
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;
|
|
ULONG dataLong;
|
|
SHORT x;
|
|
SHORT y;
|
|
PG364_VIDEO_REGISTERS videoRegisters = hwDeviceExtension->VideoAddress;
|
|
|
|
//
|
|
// Disable the verticle retrace interrupt.
|
|
//
|
|
|
|
VideoPortDisableInterrupt(hwDeviceExtension);
|
|
|
|
//
|
|
// If the color map should be updated, then load the color map into the
|
|
// G364B Display controller.
|
|
//
|
|
|
|
if (hwDeviceExtension->UpdateColorMap != FALSE) {
|
|
|
|
for (index = hwDeviceExtension->FirstEntry;
|
|
index < hwDeviceExtension->LastEntry; index += 1) {
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->ColorMapData[index].Long,
|
|
hwDeviceExtension->ColorMap[index].RgbLong);
|
|
|
|
}
|
|
|
|
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 (hwDeviceExtension->CursorEnable != FALSE) {
|
|
|
|
//
|
|
// Store position in g364 part. The register stores
|
|
// x location in bits [23:12], y location in [11:00]
|
|
// x and y values can be 2's complement negative numbers.
|
|
//
|
|
|
|
x = hwDeviceExtension->CursorColumn +
|
|
hwDeviceExtension->CursorXOrigin;
|
|
y = hwDeviceExtension->CursorRow +
|
|
hwDeviceExtension->CursorYOrigin;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPosition.Long,
|
|
((ULONG)x << 12) | ((ULONG)y & 0xFFF));
|
|
//
|
|
// Read-modify-write to reset cursor disable bit in control
|
|
// register
|
|
//
|
|
|
|
dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->Parameters.Long);
|
|
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->DisableCursor = 0;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->Parameters.Long,
|
|
dataLong);
|
|
|
|
} else {
|
|
|
|
//
|
|
// set the cursor to the FAR lower right
|
|
//
|
|
|
|
x = G364_CURSOR_MINIMUM_POS;
|
|
y = G364_CURSOR_MINIMUM_POS;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPosition.Long,
|
|
((ULONG)x << 12) | ((ULONG)y & 0xFFF));
|
|
|
|
//
|
|
// Read-modify-write to set cursor disable bit in control register
|
|
//
|
|
|
|
dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->Parameters.Long);
|
|
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->DisableCursor = 1;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->Parameters.Long,
|
|
dataLong);
|
|
|
|
}
|
|
|
|
hwDeviceExtension->UpdateCursorPosition = FALSE;
|
|
}
|
|
|
|
//
|
|
// If the hardware cursor pixels should be updated, then load the cursor
|
|
// ram into the cursor memory of the g364.
|
|
//
|
|
|
|
if (hwDeviceExtension->UpdateCursorPixels != FALSE) {
|
|
|
|
//for (index = 0; index < CURSOR_MAXIMUM; index++) {
|
|
//
|
|
// VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorMemory[index].Long,
|
|
// hwDeviceExtension->CursorPixels[index]);
|
|
//
|
|
// //
|
|
// // delay to eliminate cursor corruption on some cards, the cursor
|
|
// // gets damaged if writes to cursor store happen too fast! This delay
|
|
// // was determined experimentally
|
|
// //
|
|
//
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
// dataLong = VideoPortReadRegisterUlong(&VIDEO_CONTROL->ColorMapData[0].Long);
|
|
//
|
|
//}
|
|
//
|
|
////
|
|
//// Set color of cursor.
|
|
////
|
|
//
|
|
//VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPalette[0].Long,
|
|
// hwDeviceExtension->CursorColorMap[0].RgbLong);
|
|
//
|
|
//VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPalette[1].Long,
|
|
// hwDeviceExtension->CursorColorMap[1].RgbLong);
|
|
//
|
|
//VideoPortWriteRegisterUlong(&VIDEO_CONTROL->CursorPalette[2].Long,
|
|
// hwDeviceExtension->CursorColorMap[2].RgbLong);
|
|
//
|
|
|
|
hwDeviceExtension->UpdateCursorPixels = FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // end G364InterruptService()
|
|
|
|
VOID
|
|
G364AttributesSetup(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the color map and the hardware cursor.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PULONG buffer;
|
|
ULONG index;
|
|
ULONG limit;
|
|
|
|
VideoDebugPrint((2,"G364AttributesSetup\n"));
|
|
|
|
//
|
|
// Set the hardware cursor width, height, column, and row values.
|
|
//
|
|
|
|
HwDeviceExtension->CursorWidth = CURSOR_WIDTH;
|
|
HwDeviceExtension->CursorHeight = CURSOR_HEIGHT;
|
|
HwDeviceExtension->CursorColumn = 0;
|
|
HwDeviceExtension->CursorRow = 0;
|
|
|
|
//
|
|
// Set the device extension copy of the hardware cursor ram memory.
|
|
//
|
|
|
|
for (index = 0; index < CURSOR_MAXIMUM; index++) {
|
|
HwDeviceExtension->CursorPixels[index] = 0x0000;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
// set the cursor color map
|
|
//
|
|
|
|
HwDeviceExtension->CursorColorMap[0].RgbLong = 0x000000;
|
|
HwDeviceExtension->CursorColorMap[1].RgbLong = 0xff0000;
|
|
HwDeviceExtension->CursorColorMap[2].RgbLong = 0xffffff;
|
|
|
|
//
|
|
// Enable the vertical retrace interrupt to set up color map.
|
|
//
|
|
|
|
/* VideoPortEnableInterrupt(HwDeviceExtension); */
|
|
|
|
return;
|
|
|
|
} // end G364AttributesSetup()
|
|
|
|
VOID
|
|
G364ControllerSetup(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the G364B display controller chip.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG videoClock;
|
|
ULONG videoPeriod;
|
|
ULONG backPorch;
|
|
ULONG dataLong;
|
|
USHORT dataShort;
|
|
ULONG frontPorch;
|
|
ULONG halfLineTime;
|
|
ULONG halfSync;
|
|
ULONG index;
|
|
ULONG multiplierValue;
|
|
ULONG screenUnitRate;
|
|
ULONG shortDisplay;
|
|
ULONG transferDelay;
|
|
ULONG verticalBlank;
|
|
|
|
//
|
|
// Reset the G364 display controller.
|
|
//
|
|
|
|
VideoPortWriteRegisterUlong(hwDeviceExtension->ResetRegisterAddress,
|
|
0);
|
|
|
|
//
|
|
// Initialize the G364 boot register value.
|
|
//
|
|
|
|
if (hwDeviceExtension->DeviceTypeIdentifier == MIPSG364) {
|
|
|
|
videoClock = 5000000;
|
|
|
|
} else {
|
|
|
|
videoClock = 8000000;
|
|
|
|
}
|
|
|
|
videoPeriod = 1000000000 / (videoClock / 1000);
|
|
|
|
screenUnitRate = (hwDeviceExtension->HorizontalDisplayTime * 1000 * 4) /
|
|
(hwDeviceExtension->HorizontalResolution);
|
|
|
|
multiplierValue = videoPeriod / (screenUnitRate / 4);
|
|
|
|
dataLong = 0;
|
|
((PG364_VIDEO_BOOT)(&dataLong))->Multiplier = multiplierValue;
|
|
((PG364_VIDEO_BOOT)(&dataLong))->ClockSelect = 1;
|
|
((PG364_VIDEO_BOOT)(&dataLong))->MicroPort64Bits = 1;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->Boot.Long,
|
|
dataLong);
|
|
|
|
//
|
|
// Wait for phase locked loop to stablize.
|
|
//
|
|
|
|
VideoPortStallExecution(50);
|
|
|
|
//
|
|
// Initialize the G364 control parameters.
|
|
//
|
|
|
|
dataLong = 0;
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->DelaySync = G364_DELAY_SYNC_CYCLES;
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->BitsPerPixel = EIGHT_BITS_PER_PIXEL;
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->AddressStep = G364_ADDRESS_STEP_INCREMENT;
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->DisableCursor = 1;
|
|
|
|
if (hwDeviceExtension->DeviceTypeIdentifier == OLIVETTIG364) {
|
|
|
|
//
|
|
// Initialize the G364 control parameters for VDR1 with patch for HSync
|
|
// problem during the VBlank. The control register is set to 0xB03041
|
|
// according to the hardware specs. @msu, Olivetti, 5/14/92
|
|
//
|
|
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->VideoOnly = 1;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Only set tesselated sync in non-olivetti G364 cards when
|
|
// vertical frontporch is set to 1
|
|
//
|
|
|
|
if (hwDeviceExtension->VerticalFrontPorch != 1) {
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->PlainSync = 1;
|
|
}
|
|
}
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->Parameters.Long,
|
|
dataLong);
|
|
|
|
//
|
|
// Initialize the G364 operational values.
|
|
//
|
|
|
|
halfSync = (hwDeviceExtension->HorizontalSync * 1000) / screenUnitRate / 2;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->HorizontalSync.Long,
|
|
halfSync);
|
|
|
|
backPorch = (hwDeviceExtension->HorizontalBackPorch * 1000) / screenUnitRate;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->BackPorch.Long,
|
|
backPorch);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->Display.Long,
|
|
hwDeviceExtension->HorizontalResolution / 4);
|
|
|
|
halfLineTime = ((hwDeviceExtension->HorizontalSync +
|
|
hwDeviceExtension->HorizontalFrontPorch +
|
|
hwDeviceExtension->HorizontalBackPorch +
|
|
hwDeviceExtension->HorizontalDisplayTime) * 1000) /
|
|
screenUnitRate / 2;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->LineTime.Long,
|
|
halfLineTime * 2);
|
|
|
|
frontPorch = (hwDeviceExtension->HorizontalFrontPorch * 1000) /
|
|
screenUnitRate;
|
|
|
|
shortDisplay = halfLineTime - ((halfSync * 2) + backPorch + frontPorch);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->ShortDisplay.Long,
|
|
shortDisplay);
|
|
|
|
if (hwDeviceExtension->DeviceTypeIdentifier == OLIVETTIG364) {
|
|
|
|
//
|
|
// Initialize Broad Pulse, Vertical PreEqualize and Vertical
|
|
// PostEqualize registers to work with Olivetti monitors.
|
|
// @msu, Olivetti, 5/14/92
|
|
//
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->BroadPulse.Long,
|
|
0x30);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->VerticalPreEqualize.Long,
|
|
2);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->VerticalPostEqualize.Long,
|
|
2);
|
|
|
|
} else {
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->BroadPulse.Long,
|
|
halfLineTime - frontPorch);
|
|
|
|
// NOTE: changed the order to simplify if statement .
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->VerticalPreEqualize.Long,
|
|
hwDeviceExtension->VerticalFrontPorch * 2);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->VerticalPostEqualize.Long,
|
|
2);
|
|
|
|
}
|
|
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->VerticalSync.Long,
|
|
hwDeviceExtension->VerticalSync * 2);
|
|
|
|
verticalBlank = (hwDeviceExtension->VerticalBackPorch - 1) * 2;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->VerticalBlank.Long,
|
|
verticalBlank);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->VerticalDisplay.Long,
|
|
hwDeviceExtension->VerticalResolution * 2);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->LineStart.Long,
|
|
LINE_START_VALUE);
|
|
|
|
if (hwDeviceExtension->DeviceTypeIdentifier == OLIVETTIG364) {
|
|
|
|
//
|
|
// Fixes for Olivetti monitors, @msu, Olivetti
|
|
//
|
|
|
|
transferDelay = 30; // @msu
|
|
|
|
} else {
|
|
|
|
if (backPorch < shortDisplay) {
|
|
transferDelay = backPorch - 1;
|
|
} else {
|
|
transferDelay = shortDisplay - 4;
|
|
}
|
|
}
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->TransferDelay.Long,
|
|
transferDelay);
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->DmaDisplay.Long,
|
|
1024 - transferDelay);
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->PixelMask.Long,
|
|
0xFFFFFF);
|
|
|
|
//
|
|
// Enable video
|
|
//
|
|
|
|
((PG364_VIDEO_PARAMETERS)(&dataLong))->EnableVideo = 1;
|
|
|
|
VideoPortWriteRegisterUlong(&VIDEO_CONTROL->Parameters.Long,
|
|
dataLong);
|
|
|
|
//
|
|
// Compute the X and Y origin values for the cursor.
|
|
//
|
|
|
|
hwDeviceExtension->CursorXOrigin = 0;
|
|
hwDeviceExtension->CursorYOrigin = 0;
|
|
|
|
return;
|
|
|
|
} // end G364ControllerSetup()
|