osdcore.c
来自「一个不错的硬盘播放器程序,包含VFD显示程序,红外线遥控程序,硬盘读写程序,及解」· C语言 代码 · 共 280 行
C
280 行
/* Copyright 1996, ESS Technology, Inc. */
/* SCCSID @(#)osdcore.c 1.26 2/24/98 */
/*
* $Log$
*/
#include "common.h"
#include "const.h"
#include "display.h"
#include "fsosd.h"
#include "util.h"
#include "mvd.h"
#include "vcd.h"
#define EPRINTF(a)
#ifdef OSD_COMPRESS
extern void OSD_decompression (int, unsigned char *, unsigned char *,
unsigned char *, unsigned short *, int);
#endif /* OSD_COMPRESS */
/*
* The following OSD routine is marginally time critical, so it can
* either be in SRAM or ROM. If there is still space in SRAM, then it
* should be included in SRAM; otherwise, it can sit in ROM.
*/
/*
* Actual updating of DRAM for OSD data.
*
* Input:
* clean_up:
* 0 = Normal OSD operation.
* 1 = Flag to use OSD_new to clear DRAM for Time/Track.
* -1 = Flag to use OSD_blink_msg to simulate blinking.
*/
void OSD_copy_data(int clean_up)
{
int pos, dest;
OSD_Region *osd_region;
unsigned short region_mask;
int count, end, region, size;
unsigned char *current, *osd_new;
int big; /* Is the font single/big */
unsigned int head; /* Region offset (in byte) */
int offset; /* Position offset in a region. */
while (OSD_update_regions)
{
if ((OSD_update_regions & (OSD_TIME_REGION_MASK|OSD_TRACK_REGION_MASK))
)
{
if (OSD_update_regions & OSD_TIME_REGION_MASK) {
region = OSD_TIME_REGION;
region_mask = OSD_TIME_REGION_MASK;
osd_new = OSD_new_time;
size = OSD_TIME_SIZE;
}
else { /* Track region */
region = OSD_TRACK_REGION;
region_mask = OSD_TRACK_REGION_MASK;
osd_new = OSD_new_track;
size = OSD_TRACK_SIZE;
}
current = OSD_lines[OSD_LINE_NUM(region)];
osd_region = &(OSD_regions[region - 1]);
if (clean_up == 1) {
end = OSD_MAX_CHAR; /* we're in clearAllOsd() */
osd_new = OSD_new; /* use 'blanks' */
}
else
end = osd_region->end = osd_region->start + size;
OSD_update_regions &= ~region_mask;
}
else
{ /* let's find region that needs updating */
for (region = 0; region < OSD_MAX_REGIONS; region++)
{
region_mask = ptrLshift[region];
if (OSD_update_regions & region_mask)
{
OSD_update_regions &= ~region_mask;
break;
}
}
osd_region = &(OSD_regions[region]);
region++; /* now holds region number..previously held index */
end = (int)(osd_region->end);
current = OSD_lines[OSD_LINE_NUM(region)];
osd_new = OSD_new;
}
/*
* pos: Character position in current[]
* count: Character position in osd_new[]
* offset: offset*6 is OSD offset (in bytes) w.r.t.
* the beginning of the specific OSD line.
* head: DRAM offset for between of OSD (in DWORD)
* big: "Big" character (i.e. each of them is twice
* the size of small character)
* odd: If "offset" is odd
*/
offset = pos = (int)(osd_region->start);
head = (OSD_DRAM_START +
OSD_LINE_NUM(region) * OSD_DRAM_DX*OSD_MAX_CHAR/2 *
OSD_CHAR_HEIGHT/2) << 2;
for (count = 0; offset < end; ) {
unsigned int ctmp = osd_new[count];
big = (ctmp >= FONT_CSTART);
if (current[pos] != ctmp) {
/* Starting data offset (in byte); i.e. head+offset*6 */
dest = head + (offset << 2) + (offset << 1);
OSD_copy_one_char(ctmp, big, dest,
OSD_DRAM_DX*(OSD_MAX_CHAR/2));
current[pos] = ctmp;
}
count++; pos++; offset++;
if (big) {
current[pos] = osd_new[count];
count++;
offset++;
pos++;
}
}
}
}
/*
* Put the given character (ctmp) into the destination DRAM (dest).
*
* Inputs:
* ctmp: Target character
* big: Is it a big (double width) or small (single width) character
* dest: Destination DRAM offset (byte offset)
* width: Width of a OSD line (in DWORDS)
*/
void OSD_copy_one_char(ctmp, big, dest, width)
unsigned int ctmp;
int big, dest, width;
{
int tmp;
unsigned short *srcptr;
unsigned int *lptr;
unsigned int * dptr;
unsigned int odd; /* Is it odd/even WORD boundary? */
unsigned int mem; /* Memory data (on DWORD access) */
#ifdef OSD_COMPRESS
int new = 1; /* A new character */
unsigned char scratch_buf[24]; /* To store decompressed data */
unsigned short *bufend = (unsigned short *) &scratch_buf[24];
#endif
/*
* Look up from small (English) font or big (Chinese) font
* table?
*/
#ifdef OSD_COMPRESS
/*
* For compressed data, "small" & "big" are contained in the same table.
*
* Set ctmp to the offset of T_osd_offset_tbl.
*/
ctmp -= FONT_START;
#else
if (ctmp < FONT_CSTART) {
tmp = ctmp - FONT_START;
tmp *= (OSD_CHAR_HEIGHT/2) * OSD_SM_WIDTH;
srcptr = &osd_font[tmp];
} else {
tmp = ctmp - FONT_CSTART;
tmp *= (OSD_CHAR_HEIGHT/2) * OSD_LG_WIDTH;
srcptr = &osd_cfont[tmp];
}
#endif /* OSD_COMPRESS */
/*
* If the offset is in WORD boundary (instead of DWORD
* boundary), then drop the last 2b, so it is always
* DWORD aligned from here.
*/
odd = 0;
if (dest & 0x2) {
odd = 1;
dest &= ~2;
}
/* Translate it to non-cachable DRAM offset */
dptr = (int *) (x12000000 + dest);
#ifdef OSD_COMPRESS
srcptr = bufend;
#endif
/* Write one small/big character at a time */
for (tmp = 0; tmp < (OSD_CHAR_HEIGHT/2); tmp++) {
#ifdef OSD_COMPRESS
if (srcptr >= bufend) {
/* Decompress 24B into scratch_buf */
OSD_decompression(ctmp, scratch_buf, T_osd_code_book,
T_osd_comp_font, T_osd_offset_tbl, new);
srcptr = (unsigned short *)scratch_buf;
new = 0; /* Next 24B are no longer from a new character */
}
#endif /* OSD_COMPRESS */
if (odd) {
/* Target DRAM starts from WORD boundary */
mem = *dptr & 0xffff0000;
*dptr = *srcptr | mem;
*(dptr+1) = *(srcptr+1) << 16 | *(srcptr+2);
if (big) {
*(dptr+2) = *(srcptr+3) << 16 | *(srcptr+4);
mem = *(dptr+3) & 0xffff;
*(dptr+3) = *(srcptr+5) << 16 | mem;
srcptr += 3;
}
} else {
/* Target DRAM starts from DWORD boundary */
if (big) {
lptr = (unsigned int *) srcptr;
*dptr = *lptr;
*(dptr+1) = *(lptr+1);
*(dptr+2) = *(lptr+2);
srcptr += 3;
} else {
*dptr = (*srcptr << 16) | *(srcptr+1);
mem = *(dptr+1) & 0xffff;
*(dptr+1) = (*(srcptr+2) << 16) | mem;
}
}
srcptr += 3;
dptr += width;
}
}
/*
* OSD_clear_all():
* This function is used to clear all of the OSD regions at once.
* Calling this function is much more efficient than clearing fifteen
* regions with repeated calls to OSD_clear_region().
*/
void
OSD_clear_all(void)
{
int i, j;
{
dram_clear(OSD_DRAM_START, OSD_DRAM_SIZE);
}
/* Establish difference so that OSD_copy_data() will update */
for (i = 0; i < OSD_MAX_LINES; i++)
{
for (j = 0; j < OSD_MAX_CHAR; j ++)
{
OSD_lines[i][j] = FONT_SPACE;
}
}
/* Clearing status bits */
OSD_displayed_regions =
OSD_scheduled_regions =
OSD_update_regions =
OSD_suppressed_regions = 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?