📄 hal_blt.c
字号:
/************************************************************************
; HAL_BLT.C
;
; The routines in this file comprise the blt 2D Acceleration
;
; The Function is basic operation of LCDC
;
; Copyright (c) 2002 Epson Research and Development, Inc.
;
; All Rights Reserved.
; 2002.11.12 D Eric Start.
;
;************************************************************************/
#include "sysLCDC.h"
/************* internal function declaration ***************/
// 2D bitblt operation is started
#define StartBitblt() halWriteReg16( REG8000_BLT_CTRL, 0x1 )
// terminate 2D bitblt operation
#define CloseBitblt() halWriteReg16( REG8000_BLT_CTRL, 0 )
// BITBLT_STATUSBUSY / BITBLT_STATUSCOMP
// ---------------------------------------------------------------------------------
//| 15-------7(n/a)| FIFO NOT EMPTY | FIFO HALF FULL|3---1(N/A)| BITBLT BUSY STATUS |
// ---------------------------------------------------------------------------------
#define GetBitbltStatus() halReadReg16( REG8004_BLT_STATUS )
// loop to wait the blt operation over
#define WaitForBltEnd() while(halReadReg16(REG8004_BLT_STATUS) & 0x0001)
/****************************************************************************
; Function:
; Input :
; Output :
;***************************************************************************/
static char RectOverlap(LPBLT_INFO lpBlt)
{
int Sx0,Sx1,Dx0,Dx1,Sy0,Sy1,Dy0,Dy1;
Sx0 = lpBlt->SrcLeft;
Sx1 = Sx0 + lpBlt->SrcWidth;
Dx0 = lpBlt->DstLeft;
Dx1 = Dx0 + lpBlt->DstWidth;
Sy0 = lpBlt->SrcTop;
Sy1 = Sy0 + lpBlt->SrcHeight;
Dy0 = lpBlt->DstTop;
Dy1 = Dy0 + lpBlt->DstHeight;
if (Dx0 > Sx1 || Dy0 > Sy1 || Dx1 < Sx0 || Dy1 < Sy0)
return 0;
return 1;
}
/****************************************************************************
; Function:
; Input :
; Output :
;***************************************************************************/
void LCDCDrawRect( short x, short y, short width,short height, unsigned int color)
{
BLT_INFO Blt;
BLTCTRL_INFO CtrlInfo;
Blt.DstWidth = width;
Blt.DstHeight = height;
Blt.DstTop = y;
Blt.DstLeft = x;
Blt.Attribute = 0;
Blt.ColorFg = color;
InitModeInfo( &CtrlInfo );
//ClearMainWindowMemory( &CtrlInfo );
SolidFillBlt( &Blt, &CtrlInfo );
return;
}
/****************************************************************************
; Function:
; Input :
; Output :
;***************************************************************************
void HalInitBitblt( LPBLT_INFO pBltInfo )
{
// 初始化结构
// bit 2 bit 1 bit0
___________________________________________
| Color Format | Dest Linear| Source Linear |
| Select | Select | Select |
--------------------------------------------
// 0:8bpp,1:16bpp
if( pBltInfo->bpp = BPP_8BIT )
halWriteReg16( REG8002_BLT_CTRL, 0X4 );
else
halWriteReg16( REG8002_BLT_CTRL, 0X0 );
return;
}
*/
/****************************************************************************
; Function:
; Input :
; Output :
;***************************************************************************/
void InitModeInfo(LPBLTCTRL_INFO lpCtrlInfo)
{
lpCtrlInfo->TotalVmem =
((halReadReg16(REG0000_PRODUCT_INFORMATION) >> 8) & 0x00FF) * 4096L;
// Crack the active display
// ????????
lpCtrlInfo->Width = (halReadReg16(REG0042_LCD1_HDP) + 1) * 2;
lpCtrlInfo->Height = halReadReg16(REG004C_LCD1_VDP) + 1;
// window stride
lpCtrlInfo->Stride = halReadReg16(REG0216_MWIN_LINE_ADDR_OFFSET) & 0x0FFF;
//
lpCtrlInfo->Swivel = ((halReadReg16(REG0202_DISPLAY_MODE_SETTING1)&0x0003)) * 90;
switch( halReadReg16(REG0200_DISPLAY_MODE_SETTING0)&0x0003 )
{
case 0:
lpCtrlInfo->Bpp = 8;
// ????
lpCtrlInfo->Reg8000MSW = 0x0000; // Color format select = 0
lpCtrlInfo->BytesPerPixel = 1;
break;
case 1:
lpCtrlInfo->Bpp = 16;
// ?????
lpCtrlInfo->Reg8000MSW = 0x0004; // Color format select = 1
lpCtrlInfo->BytesPerPixel = 2;
break;
default:
return;
}
if ( (halReadReg16(REG0216_MWIN_LINE_ADDR_OFFSET)&0x1000) )
lpCtrlInfo->Width /= 2; // Horizontal pixel doubling
if ( (halReadReg16(REG0216_MWIN_LINE_ADDR_OFFSET)&0x2000) )
lpCtrlInfo->Height /= 2; // Vertical pixel doubling
if ( lpCtrlInfo->Swivel==90 || lpCtrlInfo->Swivel==270 )
{
short swap = lpCtrlInfo->Width;
lpCtrlInfo->Width = lpCtrlInfo->Height;
lpCtrlInfo->Height = swap;
}
halWriteReg16(REG8002_BLT_CTRL, lpCtrlInfo->Reg8000MSW);
// ???????
// Clip screen height to max VRAM less room for 256 byte pattern (16 character color expansion).
if (lpCtrlInfo->Height > (lpCtrlInfo->TotalVmem - 256)/lpCtrlInfo->Stride)
lpCtrlInfo->Height = (lpCtrlInfo->TotalVmem - 256)/lpCtrlInfo->Stride;
// offset
lpCtrlInfo->OffscreenOffset = (unsigned long)lpCtrlInfo->Height * lpCtrlInfo->Stride;
return;
}
/****************************************************************************
; Function: Performs Solid Fill Blit (Color in lpBlt->ColorFg)
; Input :
; Output :
;****************************************************************************/
void SolidFillBlt(LPBLT_INFO lpBlt,
LPBLTCTRL_INFO lpCtrlInfo )
{
unsigned long dstAddr;
//unsigned short i = 0;
// wait for any pending blits to end
WaitForBltEnd();
// ( bit[3:0] set 2D operation to be performaed )
// set Fill Blt
halWriteReg16(REG8008_BLT_COMMAND, 0x000C);
// rop
halWriteReg16(REG800A_BLT_COMMAND, 0x0000);
// 11-bit address offset from the starting word
// of line n to the starting word of line n+1
// ( memory address offset register )
halWriteReg16(REG8014_BLT_MEM_ADDR_OFFSET,
(unsigned short)(lpCtrlInfo->Stride >> 1) );
// set destination start address
// ?????????????????
//dstAddr = (unsigned long)lpBlt->DstLeft*lpCtrlInfo->BytesPerPixel +
// (unsigned long)lpBlt->DstTop * lpCtrlInfo->Stride;
dstAddr = MAIN_WINDOW_ADDRESS + (unsigned long)lpBlt->DstLeft*lpCtrlInfo->BytesPerPixel +
(unsigned long)lpBlt->DstTop * lpCtrlInfo->Stride;
halWriteReg16(REG8010_BLT_DEST_START_ADDR0, (unsigned short)dstAddr);
halWriteReg16(REG8012_BLT_DEST_START_ADDR1, (unsigned short)(dstAddr>>16));
// set bitblt width
halWriteReg16(REG8018_BLT_WIDTH, (unsigned short)(lpBlt->DstWidth - 1));
halWriteReg16(REG801C_BLT_HEIGHT,(unsigned short)(lpBlt->DstHeight - 1));
halWriteReg16(REG8024_BLT_FOREGROUND_COLOR, (unsigned short)lpBlt->ColorFg);
// Engage the blt engine.
// bits
halWriteReg16(REG8002_BLT_CTRL, lpCtrlInfo->Reg8000MSW);
halWriteReg16(REG8000_BLT_CTRL, 0x0001);
// 等待操作结束
//while(halReadReg16(REG8004_BLT_STATUS) & 0x0001)
// i ++;
// REG800C_BLT_SOURCE_START_ADDR0
// REG8010_BLT_DEST_START_ADDR0
// REG8020_BLT_BACKGROUND_COLOR
//
return;
//return i;
}
/****************************************************************************
; Function: Performs Read Blit.
; Input :
; Output :
;****************************************************************************/
void ReadBlt( LPBLT_INFO lpBlt,
LPBLTCTRL_INFO lpCtrlInfo,
unsigned long memaddress) // pointer to memory to store the ReadBlt bitmap.
{
unsigned long srcAddr;
long nTotalWords,nWords,phase;
unsigned short *dst16;
unsigned short *w16;
phase = memaddress & 1;
// wait to complete
WaitForBltEnd();
// read bitblt operation
halWriteReg16(REG8008_BLT_COMMAND, 0x0001);
srcAddr = MAIN_WINDOW_ADDRESS + (unsigned long)lpBlt->SrcLeft*lpCtrlInfo->BytesPerPixel +
(unsigned long)lpBlt->SrcTop * lpCtrlInfo->Stride;
// source address
halWriteReg16(REG800C_BLT_SOURCE_START_ADDR0, (unsigned short)srcAddr);
halWriteReg16(REG800E_BLT_SOURCE_START_ADDR1, (unsigned short)(srcAddr>>16));
// destination address
// ??????????
halWriteReg16( REG8010_BLT_DEST_START_ADDR0, (unsigned short)phase);
//
halWriteReg16( REG8014_BLT_MEM_ADDR_OFFSET, (unsigned short)(lpCtrlInfo->Stride>>1));
// program the BLT rect dimensions
halWriteReg16(REG8018_BLT_WIDTH, (unsigned short)(lpBlt->DstWidth-1));
halWriteReg16(REG801C_BLT_HEIGHT, (unsigned short)(lpBlt->DstHeight-1));
// Engage the blt engine.
// 强制为线性输出 ???????????
halWriteReg16(REG8002_BLT_CTRL, 0x06);
//halWriteReg16(REG8002_BLT_CTRL, lpCtrlInfo->Reg8000MSW);
// start operation
halWriteReg16(REG8000_BLT_CTRL, 0x0001);
// wait to complete
while( !(halReadReg16(REG8004_BLT_STATUS) & 0x0001) );
// calculate the address of the BLT aperture
// MAIN_WINDOW_ADDRESS ??????????
dst16 = (unsigned short *)(HalInfo.dwMemoryAddress);
#ifdef BITBLT_BPP16
nWords = lpBlt->SrcWidth;
#else
nWords = (lpBlt->SrcWidth + 1 + phase)/2;
#endif
// Word aligned
w16 = (unsigned short *)(memaddress & 0xFFFFFFFE);
nTotalWords = nWords*lpBlt->SrcHeight;
while(nTotalWords > 0)
{
// wait for the FIFO not empty
// ?????????
*w16 ++ = *dst16 ++;
nTotalWords --;
}
return;
}
/****************************************************************************
; Function: move pixel data from CPU to display memory
; Input :
; Output :
; notes: Performs Rectangular Write Blit.
;****************************************************************************/
void WriteBlt( LPBLT_INFO lpBlt, //
LPBLTCTRL_INFO lpCtrlInfo,
unsigned long memaddress )// pointer to memory bitmap
{
unsigned long dstAddr;
long nTotalWords,nWords,phase,stride;
unsigned short *dst;
unsigned short *w16;
stride = lpCtrlInfo->Stride;
dstAddr = MAIN_WINDOW_ADDRESS + (unsigned long)lpBlt->DstLeft*lpCtrlInfo->BytesPerPixel
+ (unsigned long)lpBlt->DstTop * stride;
phase = memaddress & 1;
// Wait for any pending blits to finish ...
WaitForBltEnd();
if (lpBlt->Attribute & ATTR_TRANSPARENT )
{
halWriteReg16(REG8020_BLT_BACKGROUND_COLOR, (unsigned short)lpBlt->ColorBg);
// transparent write bitblt
halWriteReg16(REG8008_BLT_COMMAND, 0x0004);
halWriteReg16(REG800A_BLT_COMMAND, 0x0000);
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -