📄 video.c
字号:
#endif
// Generate and make active a new video mode
PRINTD("\n[VIDEO CTRL] Generating video mode...");
video_mode_generate ();
// Start of frame buffer (even and odd frame, to make it working with
// any selected active set)
PRINTD("\n[VIDEO CTRL] Setting frame address...");
immap->im_vid.vid_vfaa1 =
immap->im_vid.vid_vfaa0 = (u32) video_fb_address ;
immap->im_vid.vid_vfba1 =
immap->im_vid.vid_vfba0 = (u32) video_fb_address + VIDEO_LINE_LEN ;
// YUV, Big endian, SHIFT/CLK/CLK input (BEFORE ENABLING 27MHZ EXT CLOCK)
PRINTD("\n[VIDEO CTRL] Setting pixel mode and clocks...");
immap->im_vid.vid_vccr = 0x2042;
// Configure port pins
PRINTD("\n[VIDEO CTRL] Configuring input/ouput pins...");
immap->im_ioport.iop_pdpar = 0x1fff;
immap->im_ioport.iop_pddir = 0x0000;
#ifdef CONFIG_FADS
// Turn on Video Port Clock - ONLY AFTER SET VCCR TO ENABLE EXTERNAL CLOCK
PRINTD("\n[VIDEO CTRL] Turning on video clock...");
SETBIT(*(int *)BCSR4, VIDEO_BCSR4_EXTCLK_BIT, 1);
// Turn on Video Port LED
PRINTD("\n[VIDEO CTRL] Turning on video port led...");
SETBIT(*(int *)BCSR4, VIDEO_BCSR4_VIDLED_BIT, 0);
#endif
// Blanking the screen.
PRINTD("\n[VIDEO CTRL] Blanking the screen...");
video_fill(VIDEO_BG_COL);
// Turns on Aggressive Mode. Normally, turning on the caches will cause
// the screen to flicker when the caches try to fill. This gives the
// FIFO's for the Video Controller higher priority and prevents flickering
// because of underrun. This may still be an issue when using FLASH, since
// accessing data from Flash is so slow.
PRINTD("\n[VIDEO CTRL] Turning on aggressive mode...");
immap->im_siu_conf.sc_sdcr = 0x40;
// Turn on video controller
PRINTD("\n[VIDEO CTRL] Turning on video controller...");
SETBIT(immap->im_vid.vid_vccr, VIDEO_VCCR_VON, 1) ;
// Show the display
PRINTD("\n[VIDEO CTRL] Enabling the video...");
SETBIT(immap->im_vid.vid_vcmr, VIDEO_VCMR_BD, 0);
}
// ***********************************************************************
// ** CONSOLE FUNCTIONS
// ***********************************************************************
static void console_scrollup(void)
{
// Copy up rows ignoring the first one
memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE >> 2);
// Clear the last one
memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, VIDEO_BG_COL);
}
static inline void console_back (void)
{
console_col -- ;
if (console_col < 0)
{
console_col = CONSOLE_COLS-1 ;
console_row -- ;
if (console_row < 0)
console_row = 0;
}
video_putchar (console_col * VIDEO_FONT_WIDTH, console_row * VIDEO_FONT_HEIGHT, ' ');
}
static inline void console_newline (void)
{
console_row ++ ;
console_col = 0 ;
// Check if we need to scroll the terminal
if (console_row >= CONSOLE_ROWS)
{
// Scroll everything up
console_scrollup () ;
// Decrement row number
console_row -- ;
}
}
void video_putc(const char c)
{
if (!video_enable)
{
serial_putc(c);
return ;
}
switch (c){
case 13: // Simply ignore this
break;
case '\n': // Next line, please
console_newline();
break;
case 9: // Tab (8 chars alignment)
console_col |= 0x0008 ; // Next 8 chars boundary
console_col &= ~0x0007 ; // Set this bit to zero
if (console_col >= CONSOLE_COLS)
console_newline();
break;
case 8: // Eat last character
console_back();
break;
default: // Add to the console
video_putchar (console_col * VIDEO_FONT_WIDTH,
console_row * VIDEO_FONT_HEIGHT, c);
console_col++ ;
// Check if we need to go to next row
if (console_col >= CONSOLE_COLS)
console_newline();
}
}
void video_puts (const char *s)
{
int count = strlen(s);
if (!video_enable)
while(count--)
serial_putc(*s++);
else
while(count--)
video_putc(*s++);
}
// ***********************************************************************
// ** CURSOR BLINKING FUNCTIONS
// ***********************************************************************
#ifdef VIDEO_BLINK
#define BLINK_TIMER_ID 0
#define BLINK_TIMER_HZ 2
static unsigned char blink_enabled = 0;
static timer_t blink_timer ;
static void blink_update (void)
{
static int blink_row = -1, blink_col = -1, blink_old = 0;
// Check if we have a new position to invert
if ((console_row != blink_row) || (console_col != blink_col))
{
// Check if we need to reverse last character
if (blink_old)
video_revchar (blink_col * VIDEO_FONT_WIDTH,
(blink_row
#ifdef CONFIG_VIDEO_LOGO
+ VIDEO_LOGO_HEIGHT
#endif
)* VIDEO_FONT_HEIGHT);
// Update values
blink_row = console_row ;
blink_col = console_col ;
blink_old = 0 ;
}
// Reverse this character
blink_old = !blink_old ;
video_revchar (console_col * VIDEO_FONT_WIDTH, (console_row
#ifdef CONFIG_VIDEO_LOGO
+VIDEO_LOGO_HEIGHT
#endif
) * VIDEO_FONT_HEIGHT);
}
/*
* Handler for blinking cursor
*/
static void blink_handler (void *arg)
{
// Blink
blink_update();
// Ack the timer
timer_ack (&blink_timer);
}
int blink_set (int blink)
{
int ret = blink_enabled ;
if (blink)
timer_enable (&blink_timer);
else
timer_disable (&blink_timer);
blink_enabled = blink ;
return ret ;
}
static inline void blink_close (void)
{
timer_close (&blink_timer);
}
static inline void blink_init (void)
{
timer_init (&blink_timer, BLINK_TIMER_ID, BLINK_TIMER_HZ, blink_handler);
}
#endif
// ***********************************************************************
// ** LOGO PLOTTING FUNCTIONS
// ***********************************************************************
#ifdef CONFIG_VIDEO_LOGO
void easylogo_plot (fastimage_t *image, void *screen, int width, int x, int y)
{
int skip = width - image->width,
xcount,
ycount = image->height;
#ifdef VIDEO_MODE_YUYV
unsigned short
*source = (unsigned short *) image->data,
*dest = (unsigned short *) screen + y * width + x;
while (ycount--)
{
xcount = image->width ;
while (xcount--)
*dest++ = *source++;
dest += skip ;
}
#endif
#ifdef VIDEO_MODE_RGB
unsigned char
*source = (unsigned short *) image->data,
*dest = (unsigned short *) screen + ((y * width) + x)*3;
while (ycount--)
{
xcount = image->width * 3 ;
memcpy(dest, source, xcount);
source += xcount ;
dest += ycount ;
}
#endif
}
static void *video_logo (void)
{
u16 *screen = video_fb_address, width = VIDEO_COLS ;
char info[80];
easylogo_plot (VIDEO_LOGO_ADDR, screen, width, 0, 0);
#ifdef VIDEO_INFO
sprintf(info, "%s (%s - %s) ",PPCBOOT_VERSION,__DATE__,__TIME__);
video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, info);
#ifdef CONFIG_FADS
sprintf(info, "MPC823 CPU at 50 Mhz on FADS823 board");
video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y + VIDEO_FONT_HEIGHT, info);
sprintf(info, "2Mb FLASH - 8Mb DRAM - 4Mb SRAM");
video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y + VIDEO_FONT_HEIGHT*2, info);
#endif
#endif
return video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN ;
}
#endif
// ***********************************************************************
// ** VIDEO HIGH-LEVEL FUNCTIONS
// ***********************************************************************
static int video_init(void *videobase)
{
// Initialize the encoder
PRINTD("\n[VIDEO] Initializing video encoder...");
video_encoder_init();
// Initialize the video controller
#if VIDEO_DEBUG_STEP == 1
printf("\n[VIDEO] Initializing video controller at %08x...", (int)videobase);
#endif
video_ctrl_init(videobase);
// Setting the palette
video_setpalette (CONSOLE_COLOR_BLACK , 0, 0, 0) ;
video_setpalette (CONSOLE_COLOR_WHITE , 0xff, 0xff, 0xff) ;
video_setpalette (CONSOLE_COLOR_GRAY , 0xaa, 0xaa, 0xaa) ;
video_setbgcolor (CONSOLE_COLOR_BLACK ) ;
video_setfgcolor (CONSOLE_COLOR_GRAY ) ;
#ifdef CONFIG_VIDEO_LOGO
// Paint the logo and retrieve tv base address
PRINTD("\n[VIDEO] Drawing the logo...");
video_console_address = video_logo();
#else
video_console_address = video_fb_address;
#endif
#ifdef VIDEO_BLINK
// Enable the blinking (under construction)
blink_init ();
blink_set (0); // To Fix!
#endif
// Initialize the console
console_col = 0;
console_row = 0;
video_enable = 1 ;
/*
// Showing some information
printf("%s %dx%dx%d (%s) on %s - console %dx%d\n",
#ifdef VIDEO_MODE_PAL
"PAL",
#endif
#ifdef VIDEO_MODE_NTSC
"NTSC",
#endif
VIDEO_COLS, VIDEO_ROWS, VIDEO_MODE_BPP,
#ifdef VIDEO_MODE_YUYV
"YCbYCr",
#endif
#ifdef VIDEO_MODE_RGB
"RGB",
#endif
VIDEO_ENCODER_NAME,
CONSOLE_COLS,
CONSOLE_ROWS
);
*/
return 0 ;
}
int drv_video_init (void)
{
int error, devices = 1 ;
device_t videodev ;
video_init((void *)CONFIG_VIDEO_ADDR); // Video initialization
// Device initialization
memset (&videodev, 0, sizeof(videodev));
strcpy(videodev.name, "video");
videodev.ext = DEV_EXT_VIDEO ; // Video extensions
videodev.flags = DEV_FLAGS_OUTPUT; // Output only
videodev.putc = video_putc ; // 'putc' function
videodev.puts = video_puts ; // 'puts' function
error = device_register (&videodev);
return (error == 0) ? devices : error ;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -