📄 dispdrvr.c
字号:
gCursorRect.left = (DispDrvr_cxScreen - CURSOR_XSIZE) >> 1;
gCursorRect.right = gCursorRect.left + CURSOR_XSIZE;
gCursorRect.top = (DispDrvr_cyScreen - CURSOR_YSIZE) >> 1;
gCursorRect.bottom = gCursorRect.top + CURSOR_YSIZE;
gxHot = gyHot = 0;
// Hide the cursor for now.
memset (gCursorMask, 0xFF, sizeof(gCursorMask));
// Turn debug message volume to 0
#ifdef DEBUG
dpCurSettings.ulZoneMask &= 0;
#endif
return;
error_return:
if ( v_pvScreen ) {
VirtualFree((PVOID)v_pvScreen, 0, MEM_RELEASE);
}
v_pvScreen = NULL;
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("DispDrvrInitialize error return. \r\n")));
// Turn debug message volume to 0
#ifdef DEBUG
dpCurSettings.ulZoneMask &= 0;
#endif
return;
}
// Initialize the MPC821 LCD controller
BOOL CPM_LCD_Init(LCD_Info_Type LCD_Info)
{
ADDRESSES immr_values;
int i; // used for looping
UINT temp_sdcr;
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("CPM_LCD_Init \r\n")));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
if (! KernelIoControl(
(DWORD) OEM_IOCTL_GET_IMMR,
NOTUSED,
NOTUSED,
(LPVOID)&immr_values,
NOTUSED,
NOTUSED
)) {
DEBUGMSG( GPE_ZONE_ERROR, ( TEXT("********** OEM_IOCTL_GET_IMMR FAILED !!! *********\n\r") ) );
goto error_return;
}
immr = VirtualAlloc(0, sizeof(PDA), MEM_RESERVE,PAGE_NOACCESS);
if (immr == NULL) {
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("DispDrvrInitialize: Could not allocate the immr!\r\n")));
goto error_return;
}
if (!VirtualCopy(immr,immr_values.VirtualAddress,sizeof(PDA), PAGE_READWRITE|
PAGE_NOCACHE)) {
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("DispDrvrInitialize: immr copy failed!\r\n")));
goto error_return;
}
/* Setup the CPM LCD control register. */
immr->lcd_lccr = ((LCD_Info.Columns * LCD_Info.Rows * LCD_Info.Bits_per_pixel / 128) << 17) | BPIX | COLOR | TFT;
/* Setup the frame-buffer(s) in the CPM using physical addresses. */
immr->lcd_lcfaa = (unsigned int) VTOP(LCD_Info.Frame_buffer_addr);
immr->lcd_lcfba = (UINT) 0;
// Vertical
immr->lcd_lcvcr = (LCD_Info.Vertical_sync_pulse << 28) | (LCD_Info.Rows << 11) | (LCD_Info.Wait_between_frames);
// Horizontal.
immr->lcd_lchcr = BO_AT_SETTING | (LCD_Info.Columns << 10) | (LCD_Info.Wait_between_lines);
/* Now setup the color RAM table. */
/* NOTE:
* We are operating in True Little Endian Mode (LES in DCTL set & LE bits in MSR clear),
* addresses to the internal dual port RAM are (32-bit) munged !!! This means that
* operands shorter than 32 bits must "PRE-munge" their addresses for data to appear
* in the dual port RAM where normally expected.
*/
DEBUGMSG(GPE_ZONE_INIT, (TEXT("Setting up color RAM table for 8bpp.\r\n")));
for (i = 0; i < LCD_NBR_COLOR_RAM_ENTRIES; i++ ) {
if ((i%2) == 0) { //even entry gets the content of the next odd entry
immr->lcda_lcolr[i] = (((unsigned short) (_rgbIdentity[i+1].peRed &0xf0)) << 4) |
(((unsigned short) (_rgbIdentity[i+1].peGreen & 0xf0))) |
(((unsigned short) (_rgbIdentity[i+1].peBlue & 0xf0)) >> 4);
} else { // odd entry gets the content of the previous even entry
immr->lcda_lcolr[i] = (((unsigned short) (_rgbIdentity[i-1].peRed & 0xf0)) << 4) |
(((unsigned short) (_rgbIdentity[i-1].peGreen & 0xf0))) |
(((unsigned short) (_rgbIdentity[i-1].peBlue & 0xf0)) >> 4);
}
// DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT(" immr->lcda_lcolr[%d] = %x\r\n"), i, immr->lcda_lcolr[i]));
}
/* Setup the port D register */
#define PD6_LAC_LOE 0x0200 /* set for GPIO control of LCD Enable */
// don't set these bits
#define REV_B_RESERVED_BITS 0xE000
#define VALID_LCD_BITS (0xFFFF & ~REV_B_RESERVED_BITS)
/* Assuming number of data bits are 8 (no support for 9). */
/* Enable LCD signal functions - except for LAC function on
PD6 (tied to LCD ENABLE) */
immr->pio_pdpar = (unsigned short)(~PD6_LAC_LOE & VALID_LCD_BITS);
immr->pio_pddir |= VALID_LCD_BITS; /* Set Port D pins for output
Use DR6 as Display Enable */
/* Disable display */
immr->pio_pddat &= (unsigned short)(~PD6_LAC_LOE & VALID_LCD_BITS);
// Enable LCD controller
immr->lcd_lccr |= LCD_TURN_PANEL_ON;
// delay 100 ms
KernelIoControl( OEM_IOCTL_BUSY_STALL, 0, 100000, 0, 0, 0 );
// Turn off LAM prior to disabling LCD controller - else it may lock CPU
#define REV_B_AGRESSIVE_MODE (0x00000040)
temp_sdcr = immr->dma_sdcr & ~REV_B_AGRESSIVE_MODE;
immr->dma_sdcr = temp_sdcr;
// Disable LCD controller
immr->lcd_lccr &= (~LCD_TURN_PANEL_ON);
// delay 100 ms
KernelIoControl( OEM_IOCTL_BUSY_STALL, 0, 100000, 0, 0, 0 );
// Although its name implies that this bit should not be set if
// running on a Rev A chip, it doesn't cause any problems to do so.
// NOTE: If either LAID or RAID field is set non-zero, ie, either LCD or
// SDMA is not at priority 6, cannot use REV_B_AGGRESSIVE_MODE.
if ((temp_sdcr & 0xf) == 0)
temp_sdcr |= REV_B_AGRESSIVE_MODE;
immr->dma_sdcr = temp_sdcr;
// Enable LCD controller
immr->lcd_lccr |= LCD_TURN_PANEL_ON;
/* Enable the Display panel */
immr->pio_pddat |= PD6_LAC_LOE;
DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT("immr->lccr: %x \r\n"),immr->lcd_lccr));
DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT(" immr->lcd_lcfaa: %x\r\n"), immr->lcd_lcfaa));
DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT(" immr->lcd_lcfba: %x\r\n"), immr->lcd_lcfba));
DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT(" immr->lcd_lcvcr: %x\r\n"), immr->lcd_lcvcr));
DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT(" immr->lcd_lchcr: %x\r\n"), immr->lcd_lchcr));
DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT(" immr->pio_pdpar: %x\r\n"), immr->pio_pdpar));
DEBUGMSG(GPE_ZONE_REGISTERS, (TEXT(" immr->pio_pddir: %x\r\n"), immr->pio_pddir));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
return (TRUE);
error_return:
if ( immr ) {
VirtualFree((PVOID)immr, 0, MEM_RELEASE);
}
immr = NULL;
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("CPM_LCD_Init error return. %x\r\n")));
return (FALSE);
}
void DispDrvrPowerHandler(BOOL bOff)
{
#ifdef POWER_MANAGEMENT_ENABLED
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPowerHandler \r\n")));
if (bOff == TRUE) {
// Workaround for errata G5 in MPC 821, rev B3 errata listing
// dated January 26, 1999.
// Problem: LCD Controller Off Sequence When LAM Bit is Set
// May Cause the CPU to Lockup
// Workaround: Clear the LAM bit of the SDCR before turning
// the LCD Controller off.
// Start workaround
// Turn off LAM prior to disabling LCD controller - else it may lock CPU
#define REV_B_AGRESSIVE_MODE (0x00000040)
temp_sdcr = immr->dma_sdcr & ~REV_B_AGRESSIVE_MODE;
immr->dma_sdcr = temp_sdcr;
// Although its name implies that this bit should not be set if
// running on a Rev A chip, it doesn't cause any problems to do so.
// NOTE: If either LAID or RAID field is set non-zero, ie, either LCD or
// SDMA is not at priority 6, cannot use REV_B_AGGRESSIVE_MODE.
if ((temp_sdcr & 0xf) == 0)
temp_sdcr |= REV_B_AGRESSIVE_MODE;
immr->dma_sdcr = temp_sdcr;
// End of workaround
/* Disable the LCD controller via the LCCR register. */
immr->lcd_lccr &= (~LCD_TURN_PANEL_ON);
/* Need to test if it saves power ...*/
} else {
// Workaround for errata G6 in MPC 821, rev B3 errata listing
// dated January 26, 1999.
// Problem: LCD Off then On Sequence With a Pending SDMA Cycle
// Causes Wrong Data Fetch
// Workaround: Ensure that the pending SDMA cycle is completed
// before turning on the LCD Controller. This can
// be done by performing an access to external memory
// before turning the LCD Controller on.
// Start workaround
// Use frame buffer (defined in dma.h) created in DispDrvrInitialize()
// to gain access to external memory, since this is set up not to be
// cached.
char somechar;
somechar = *v_pvScreen; /* Read character from frame buffer */
// End of workaround
immr->lcd_lccr |= LCD_TURN_PANEL_ON;
/* Might have to restore more attributes. */
}
#endif
}
// In our case, no support for software contrast control.
BOOL
DispDrvrContrastControl(
int Cmd,
DWORD *pValue
)
{
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrContrastControl \r\n")));
return FALSE;
}
void DispDrvrMoveCursor(INT32 xLocation, INT32 yLocation)
{
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrMoveCursor \r\n")));
#if (defined(MOUSE_CURSOR_ON) || defined(TOUCH_CURSOR_ON))
// First clear the cursor's old location
gDrawCursorFlag = FALSE;
DispDrvrDirtyRectDump(&gCursorRect);
// Now set the new location of the cursor and redraw
gCursorRect.left = xLocation - gxHot;
if (gCursorRect.left < 0) {
gCursorRect.left = 0;
}
gCursorRect.top = yLocation - gyHot;
if (gCursorRect.top < 0) {
gCursorRect.top = 0;
}
gCursorRect.right = xLocation - gxHot + CURSOR_XSIZE;
gCursorRect.bottom = yLocation - gyHot + CURSOR_YSIZE;
// Align cursor to nearest DWORD boundary
gCursorRect.left &= 0xFFFFFFFC;
gDrawCursorFlag = TRUE;
DispDrvrDirtyRectDump(&gCursorRect);
#else
return;
#endif
}
/*
* LCD_Init_Test() -- Draw 4 color stripes: Red, Green, Yellow, Blue
*/
void
LCD_Init_Test(LCD_Info_Type LCD_Info)
{
unsigned char *dp;
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("Checkerbrd: %x \r\n"),v_pvScreen));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
for (dp=(unsigned char *)v_pvScreen;dp<((unsigned char *)v_pvScreen+((LCD_Info.Columns * LCD_Info.Rows * LCD_Info.Bits_per_pixel/8)/4));dp++) {
*dp=0x01;
}
for (;dp<((unsigned char *)v_pvScreen+((LCD_Info.Columns * LCD_Info.Rows * LCD_Info.Bits_per_pixel/8)/2));dp++) {
*dp=0x02;
}
for (;dp<((unsigned char *)v_pvScreen+((LCD_Info.Columns * LCD_Info.Rows * LCD_Info.Bits_per_pixel/8)*3/4));dp++) {
*dp=0x03;
}
for (;dp<((unsigned char *)v_pvScreen+((LCD_Info.Columns * LCD_Info.Rows * LCD_Info.Bits_per_pixel/8)));dp++) {
*dp=0x04;
}
DEBUGMSG(GPE_ZONE_INIT, (TEXT("frame buffer cleared %x\r\n"), v_pvScreen));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer %x\r\n"), DispDrvrPhysicalFrameBuffer));
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("DispDrvrPhysicalFrameBuffer Pointer %x\r\n"), &DispDrvrPhysicalFrameBuffer));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -