📄 cim_gp.c
字号:
WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
}
else
{
WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset | gp3_pat_origin);
WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
}
WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, srcoffset);
WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
}
/* START THE BLT */
WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
gp3_cmd_current = gp3_cmd_next;
}
/*---------------------------------------------------------------------------
* gp_screen_to_screen_convert
*
* This routine is called to color-convert a rectangular region of the frame
* buffer into the current BPP. The format of the source region is programmed
* by gp_set_source_format.
*-------------------------------------------------------------------------*/
void gp_screen_to_screen_convert (unsigned long dstoffset, unsigned long srcoffset,
unsigned long width, unsigned long height, int nibble)
{
unsigned long size = ((width << 16) | height);
unsigned long ch3_offset = srcoffset & 0x3FFFFF;
unsigned long ch3_size, base;
base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
((gp3_fb_base << 4) + ((srcoffset & 0xFFC00000) >> 20)) |
(gp3_base_register & GP3_BASE_OFFSET_SRCMASK);
/* SET NIBBLE FOR 4BPP */
/* 4BPP is a special case in that it requires subpixel addressing. The */
/* user must supply this information via the nibble parameter. This */
/* parameter is ignored for every other source format. */
ch3_size = size;
if (gp3_src_pix_shift == 3)
ch3_offset |= ((nibble & 1) << 25);
else if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
ch3_size = ((((width * 3) + 3) >> 2) << 16) | height;
/* SET APPROPRIATE ENABLES */
gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE |
GP3_BLT_HDR_WIDHI_ENABLE |
GP3_BLT_HDR_CH3_OFF_ENABLE |
GP3_BLT_HDR_CH3_STR_ENABLE |
GP3_BLT_HDR_CH3_WIDHI_ENABLE |
GP3_BLT_HDR_BASE_OFFSET_ENABLE |
GP3_BLT_HDR_BLT_MODE_ENABLE;
/* WRITE ALL BLT REGISTERS */
WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
GP3_CH3_C3EN |
GP3_CH3_REPLACE_SOURCE |
gp3_src_format |
((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20) |
((gp3_blt_flags & CIMGP_ENABLE_PREFETCH) << 17) |
gp3_src_stride);
WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
/* START THE BLT */
WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
gp3_cmd_current = gp3_cmd_next;
}
/*---------------------------------------------------------------------------
* gp_color_bitmap_to_screen_blt
*
* This routine is called to BLT data from system memory into the frame buffer.
* 'srcy' is deliberately omitted to prevent extra calculations for simple
* applications that have no source indexes.
*-------------------------------------------------------------------------*/
void gp_color_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
unsigned long width, unsigned long height, unsigned char *data, long pitch)
{
unsigned long indent, temp;
unsigned long total_dwords, size_dwords;
unsigned long dword_count, byte_count;
unsigned long size = ((width << 16) | height);
unsigned long srcoffset;
/* ASSUME BITMAPS ARE DWORD ALIGNED */
/* We will offset into the source data in DWORD increments. We */
/* set the source index to the remaining byte offset and */
/* increment the size of each line to account for the dont-care */
/* pixel(s). */
indent = srcx << gp3_pix_shift;
srcoffset = (indent & ~3L);
indent &= 3;
/* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS */
/* We assume that a color pattern is being ROPed with source */
/* data if the pattern type is color and the preserve pattern */
/* was set. */
gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
GP3_BLT_HDR_DST_OFF_ENABLE |
GP3_BLT_HDR_WIDHI_ENABLE |
GP3_BLT_HDR_CH3_STR_ENABLE |
GP3_BLT_HDR_BASE_OFFSET_ENABLE |
GP3_BLT_HDR_BLT_MODE_ENABLE;
if (gp3_ch3_pat)
{
gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
}
else
{
WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
}
WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, indent);
WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET,
((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)));
WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_HOST);
/* START THE BLT */
WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
gp3_cmd_current = gp3_cmd_next;
/* CALCULATE THE SIZE OF ONE LINE */
size = (width << gp3_pix_shift) + indent;
total_dwords = (size + 3) >> 2;
size_dwords = (total_dwords << 2) + 8;
dword_count = (size >> 2);
byte_count = (size & 3);
/* CHECK FOR SMALL BLT CASE */
if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
(gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
{
/* UPDATE THE COMMAND POINTER */
cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
/* CHECK IF A WRAP WILL BE NEEDED */
gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
{
gp3_cmd_next = gp3_cmd_top;
GP3_WAIT_WRAP(temp);
WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
GP3_DATA_LOAD_HDR_ENABLE);
}
else
{
GP3_WAIT_PRIMITIVE(temp);
WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
}
/* WRITE DWORD COUNT */
WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | (total_dwords * height));
while (height--)
{
/* WRITE DATA */
WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
srcoffset + (dword_count << 2), byte_count);
srcoffset += pitch;
cim_cmd_ptr += total_dwords << 2;
}
WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
gp3_cmd_current = gp3_cmd_next;
}
else
{
/* WRITE DATA LINE BY LINE */
/* Each line will be created as a separate command buffer entry to allow */
/* line-by-line wrapping and to allow simultaneous rendering by the HW. */
while (height--)
{
/* UPDATE THE COMMAND POINTER */
/* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
/* This is created by adding gp3_cmd_current to the base pointer. */
cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
/* CHECK IF A WRAP WILL BE NEEDED */
gp3_cmd_next = gp3_cmd_current + size_dwords;
if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
{
gp3_cmd_next = gp3_cmd_top;
/* WAIT FOR HARDWARE */
GP3_WAIT_WRAP(temp);
WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
GP3_DATA_LOAD_HDR_ENABLE);
}
else
{
/* WAIT FOR AVAILABLE SPACE */
GP3_WAIT_PRIMITIVE(temp);
WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
}
/* WRITE DWORD COUNT */
WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | total_dwords);
/* WRITE DATA */
WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
srcoffset + (dword_count << 2), byte_count);
/* UPDATE POINTERS */
srcoffset += pitch;
WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
gp3_cmd_current = gp3_cmd_next;
}
}
}
/*---------------------------------------------------------------------------
* gp_color_convert_blt
*
* This routine is called to convert data that is stored in system memory
* into the current graphics BPP. The source format is programmed in
* gp_set_source_format.
*-------------------------------------------------------------------------*/
void gp_color_convert_blt (unsigned long dstoffset, unsigned long srcx,
unsigned long width, unsigned long height, unsigned char *data, long pitch)
{
unsigned long indent, temp;
unsigned long total_dwords, size_dwords;
unsigned long dword_count, byte_count;
unsigned long size = ((width << 16) | height);
unsigned long ch3_size;
unsigned long ch3_offset, srcoffset;
unsigned long base;
/* ASSUME BITMAPS ARE DWORD ALIGNED */
/* We will offset into the source data in DWORD increments. We */
/* set the source index to the remaining byte offset and */
/* increment the size of each line to account for the dont-care */
/* pixel(s). For 4BPP source data, we also set the appropriate */
/* nibble index. */
/* CALCULATE THE SIZE OF ONE LINE */
if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
{
/* HANDLE 24BPP */
/* Note that we do not do anything to guarantee that the source data */
/* is DWORD aligned. The logic here is that the source data will be */
/* cacheable, in which case Geode LX will not lose any clocks for unaligned */
/* moves. Also note that the channel 3 width is programmed as the */
/* number of dwords, while the normal width is programmed as the number */
/* of pixels. */
srcoffset = srcx * 3;
ch3_offset = 0;
temp = width * 3;
ch3_size = (((temp + 3) >> 2) << 16) | height;
}
else
{
ch3_size = size;
if (gp3_src_pix_shift == 3)
{
/* CALCULATE INDENT AND SOURCE OFFSET */
indent = (srcx >> 1);
srcoffset = (indent & ~3L);
indent &= 3;
ch3_offset = indent | ((srcx & 1) << 25);
temp = ((width + (srcx & 1) + 1) >> 1) + indent;
}
else
{
indent = (srcx << gp3_src_pix_shift);
srcoffset = (indent & ~3L);
indent &= 3;
ch3_offset = indent;
temp = (width << gp3_src_pix_shift) + indent;
}
}
total_dwords = (temp + 3) >> 2;
size_dwords = (total_dwords << 2) + 8;
dword_count = (temp >> 2);
byte_count = (temp & 3);
base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
(gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
/* SET APPROPRIATE ENABLES */
gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE |
GP3_BLT_HDR_WIDHI_ENABLE |
GP3_BLT_HDR_CH3_STR_ENABLE |
GP3_BLT_HDR_CH3_OFF_ENABLE |
GP3_BLT_HDR_CH3_WIDHI_ENABLE |
GP3_BLT_HDR_BASE_OFFSET_ENABLE |
GP3_BLT_HDR_BLT_MODE_ENABLE;
WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
GP3_CH3_C3EN |
GP3_CH3_REPLACE_SOURCE |
GP3_CH3_HST_SRC_ENABLE |
gp3_src_format |
((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
/* START THE BLT */
WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
gp3_cmd_current = gp3_cmd_next;
if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
(gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
{
/* UPDATE THE COMMAND POINTER */
cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
/* CHECK IF A WRAP WILL BE NEEDED */
gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -