📄 s1d13706_16bit.c
字号:
else
{
printf("Begin Full Screen Color Test, Press any key to go to next color, \'x\' to end.\n");
while(1){
// fill the frame buffer with incrementing color values
for (x = 0; x < 16; x++){
switch (sed_color_depth){
case 4: wr16 = x | x << 4 | x << 8 | x << 12; break;
case 8: wr16 = x | x << 8; break;
default: wr16 = vga_lookup[x]; break; // 16-bits bypasses the lookup table
}
for (i = 0; i < SED_FB_SIZE(sed_color_depth); i += 2){
WR_FB16(i, wr16);
}
if (no_wait == 0){
c = getchar();
if (c == 'x') goto sed_tst_next;
}
} // for x
} // while
} // else no keycheck test
sed_tst_next:
sed135x_off();
sed135x_init();
sed135x_on();
return 0;
}
// sed_scroll()
//
// Because we are most likely running out of FLASH and probably also with
// cache disabled, a brute force memcpy of the whole screen would be very
// slow, even with reduced color depths. Instead, we define a frame buffer
// that is twice the size of our actual display. This does limit us to a
// 1Mbyte active display size, but 640 x 480 @ 16-bits/pixel = 614K so it
// works just fine. 800 x 600 can be had by reducing the color depth to
// 8-bits/pixel and using the look up tables.
//
// With the double buffering, we always write to the first buffer, even
// when the second buffer is active. This allows us to scroll by adjusting
// the starting and ending addresses in the SED135x by one row. When we
// reach the end of our virtual buffer, we reset the starting and ending
// addresses to the first buffer. Note that we can not adjust the SED135x
// registers until it is in vertical retrace. That means we have to wait
// until it is in active display, then goes to non-display, unless the
// screen is blanked, in which case we can update immediately.
//
void
sed_scroll()
{
sed_row++;
// clear the new row(s)
sed_clr_row(sed_row);
if (sed_row > (ROWS_PER_SCREEN - 1)){
sed_clr_row(sed_row - ROWS_PER_SCREEN);
}
// when sed_y_pos is greater than ROWS_PER_SCREEN we just adjust the
// start and end addresses in the SED135x. If it is equal to 2 *
// ROWS_PER_SCREEN, we reset the start and end addresses to SED_MEM_BASE.
if (sed_row > (ROWS_PER_SCREEN - 1))
{
if (sed_row > ((ROWS_PER_SCREEN * 2) - 1))
{
sed_fb_offset = 0x00;
sed_row = ROWS_PER_SCREEN - 1;
}
else
{
// calculate the new offset address of the frame buffer in words
sed_fb_offset += (SED_GET_ADD(1, 0, sed_color_depth) / 2);
}
// write the new sed_fb_offset value
if (sed_disp_mode_crt){
// before we change the address offset, wait for the display to
// go from active to non-active, unless the display is not enabled
if (SED1356_REG_DISP_MODE & H2S1D(SED1356_DISP_MODE_CRT)){ // CRT is on
while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2S1D(SED1356_VER_NONDISP)) == 0){}
while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2S1D(SED1356_VER_NONDISP)) == 1){}
}
SED1356_REG_CRT_DISP_START_LO_and_MID = H2S1D(((sed_fb_offset & 0x00ffff) >> 0));
SED1356_REG_CRT_DISP_START_HI = H2S1D(((sed_fb_offset & 0x030000) >> 16));
}
else // LCD
{
if (SED1356_REG_DISP_MODE & H2S1D(SED1356_DISP_MODE_LCD)){ // LCD is on
while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2S1D(SED1356_VER_NONDISP)) == 0){}
while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2S1D(SED1356_VER_NONDISP)) == 1){}
}
SED1356_REG_LCD_DISP_START_LO_and_MID = H2S1D(((sed_fb_offset & 0x00ffff) >> 0));
SED1356_REG_LCD_DISP_START_HI = H2S1D(((sed_fb_offset & 0x030000) >> 16));
}
} // if (sed_row > (ROWS_PER_SCREEN - 1))
return;
} //
//--------------------------------------------------------------------------
// sed_clr_row()
//
// This routine writes the background color to the font row specified
// printable character
//
void sed_clr_row(int char_row){
ulong sed_mem_add;
int i;
ushort wr16;
// clear the desired row
sed_mem_add = SED_GET_ADD(char_row, 0, sed_color_depth);
#ifdef SED_DBG
sed135x_tst = 1;
printf("SED Clear Row %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", char_row, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add));
sed135x_tst = 0;
#endif
switch (sed_color_depth)
{
case 4:
wr16 = ((sed_bg_color << 12) | (sed_bg_color << 8) | (sed_bg_color << 4) | (sed_bg_color << 0));
#ifdef SED_DBG
sed135x_tst = 1;
printf("SED Clear Row %d, FB Add 0x%08lx to 0x%08lx.\n ", char_row, sed_mem_add, sed_mem_add + ((PIXELS_PER_ROW * FONT_HEIGHT) / 2));
sed135x_tst = 0;
#endif
for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) / 2); i += 2){
WR_FB16(sed_mem_add, wr16);
sed_mem_add += 2;
} // for font_row
break;
case 8:
wr16 = ((sed_bg_color << 12) | (sed_bg_color << 8) | (sed_bg_color << 4) | (sed_bg_color << 0));
for (i = 0; i < (PIXELS_PER_ROW * FONT_HEIGHT); i += 2){
WR_FB16(sed_mem_add, wr16);
sed_mem_add += 2;
} // for font_row
break;
case 16:
wr16 = ((sed_bg_color << 12) | (sed_bg_color << 8) | (sed_bg_color << 4) | (sed_bg_color << 0));
for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) * 2); i += 2){
WR_FB16(sed_mem_add, wr16);
sed_mem_add += 2;
} // for font_row
break;
} // switch sed_color_depth
} // sed_clr_row
//--------------------------------------------------------------------------
// sed_putchar()
//
// This routine parses the character and calls sed_writechar if it is a
// printable character
//
void sed_putchar(char c){
if ((sed135x_ok == 0) || (sed135x_tst == 1)) return;
// First parse the character to see if it printable or an acceptable control
switch (c) {
case '\r':
sed_col = 0;
return;
case '\n':
sed_scroll();
return;
case '\b':
sed_col--;
if (sed_col < 0)
{
sed_row--;
if (sed_row < 0) sed_row = 0;
sed_col = COLS_PER_SCREEN - 1;
}
c = 0; // erase the character
sed_writechar(c);
break;
default:
if (((uchar)c < FIRST_CHAR) || ((uchar)c > LAST_CHAR)) return; // drop anything we can't print
c -= FIRST_CHAR; // get aligned to the first printable character
sed_writechar(c);
// advance to next column
sed_col++;
if (sed_col == COLS_PER_SCREEN)
{
sed_col = 0;
sed_scroll();
}
break;
}
} // sed_putchar()
//--------------------------------------------------------------------------
// sed_writechar()
//
// This routine writes the character to the screen at the current cursor
// location.
//
void sed_writechar(uchar c) {
ulong sed_mem_add;
int font_row, font_col;
uchar font_data8;
ushort wr16;
// Convert the current row,col and color depth values
// into an address
sed_mem_add = SED_GET_ADD(sed_row, sed_col, sed_color_depth);
#ifdef SED_DBG
sed135x_tst = 1;
printf("SED writechar at row %d, col %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", sed_row, sed_col, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add));
sed135x_tst = 0;
#endif
if (FONT_WIDTH == 8)
{
switch (sed_color_depth){
case 4:
// Now render the font by painting one font row at a time
for (font_row = 0; font_row < FONT_HEIGHT; font_row++){
// get the font row of data
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
for (font_col = 0; font_col < 8; font_col += 4)
{
// get a words worth of pixels
wr16 = (((font_data8 & 0x80) ? sed_fg_color << 12 : sed_bg_color << 12)
| ((font_data8 & 0x40) ? sed_fg_color << 8 : sed_bg_color << 8)
| ((font_data8 & 0x20) ? sed_fg_color << 4 : sed_bg_color << 4)
| ((font_data8 & 0x10) ? sed_fg_color << 0 : sed_bg_color << 0));
font_data8 = font_data8 << 4;
WR_FB16(sed_mem_add, wr16);
// if we are in the 2nd frame buffer, write to the 1st frame buffer also
if (sed_row > (ROWS_PER_SCREEN - 1)){
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
}
sed_mem_add += 2;
} // for font_col
// go to the next pixel row
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
} // for font_row
break;
case 8:
// Now render the font by painting one font row at a time
for (font_row = 0; font_row < FONT_HEIGHT; font_row++){
// get the font row of data
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
for (font_col = 0; font_col < 8; font_col += 2)
{
// get a words worth of pixels
wr16 = (((font_data8 & 0x80) ? sed_fg_color << 8 : sed_bg_color << 8)
| ((font_data8 & 0x40) ? sed_fg_color << 0 : sed_bg_color << 0));
font_data8 = font_data8 << 2;
WR_FB16(sed_mem_add, wr16);
// if we are in the 2nd frame buffer, write to the 1st frame buffer also
if (sed_row > (ROWS_PER_SCREEN - 1)){
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
}
sed_mem_add += 2;
} // for font_col
// go to the next pixel row
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
} // for font_row
break;
case 16:
// Now render the font by painting one font row at a time
for (font_row = 0; font_row < FONT_HEIGHT; font_row++){
// get the font row of data
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
for (font_col = 0; font_col < 8; font_col++)
{
// get a words worth of pixels
wr16 = ((font_data8 & 0x80) ? sed_fg_color : sed_bg_color);
font_data8 = font_data8 << 1;
WR_FB16(sed_mem_add, wr16);
// if we are in the 2nd frame buffer, write to the 1st frame buffer also
if (sed_row > (ROWS_PER_SCREEN - 1)){
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
}
sed_mem_add += 2;
} // for font_col
// go to the next pixel row
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
} // for font_row
break;
} // switch sed_color depth
} // FONT_WIDTH == 8
else
{
return;
}
} // sed_writechar()
//--------------------------------------------------------------------------
// sed_tst()
//
// This test will initialize the SED135x, do a frame buffer
// test and then display 16 VGA colors full screen until stopped.
//
char *sedHelp[] = {
" This command allows the user to set",
" options for the S1D13506 Video Controller",
" found on some Cogent Single Boards.",
" The user may set the mode to CRT or LCD, ",
" set the color depth to run at, and set",
" the foreground and background colors.",
" Note that all but the foreground and",
" background options will cause the",
" S1D1350x to be re-initialized.\n",
" Usage:",
" sed -[c,l,f,b,d:[4,8,16]]",
" Options...",
" -c force display to CRT mode, overrides auto detect",
" -l force display to LCD mode, overrides auto detect",
" -fx set foreground color to x (VGA 16 Color Pallette 0-15)",
" -bx set background color to x (VGA 16 Color Pallette 0-15)",
" -d4 set a depth of 4-bits/pixel: Power-On Default",
" -d8 set a depth of 8-bits/pixel",
" -d16 set a depth of 16-bits/pixel",
" No options will return current status",
0
};
int
sed(int argc,char *argv[])
{
int opt, reinit;
if (sed135x_ok == 0){
printf("S1D13506 Not Found!\n");
return -1;
}
reinit = 0;
if (argc == 1) {
printf("S1D13506 @ 0x%08lx, ", (ulong)SED_REG_BASE);
if(sed_disp_mode_crt) printf("CRT Mode, ");
else printf("LCD Mode, ");
printf("Color Depth = %d,\n", sed_color_depth);
printf("Foreground Color = %d, ", sed_fg_color);
printf("Background Color = %d, \n", sed_bg_color);
return(0);
}
while ((opt=getopt(argc,argv,"clf:b:d:")) != -1) {
switch(opt) {
case 'l': // Override sed_disp_mode_crt, Run Test in LCD Mode
sed_disp_mode_crt = 0;
reinit = 1;
printf("Setting LCD Mode!\n");
break;
case 'c': // Override sed_disp_mode_crt, Run Test in CRT Mode
sed_disp_mode_crt = 1;
reinit = 1;
printf("Setting CRT Mode!\n");
break;
case 'd': // set the color depth
switch(*optarg) {
case '4':
sed_color_depth = 4;
printf("Setting 4bpp Mode!\n");
reinit = 1;
break;
case '8':
sed_color_depth = 8;
printf("Setting 8bpp Mode!\n");
reinit = 1;
break;
case '1':
sed_color_depth = 16;
printf("Setting 16bpp Mode!\n");
reinit = 1;
break;
default: // test with current depth
printf("Unsupported Color Depth, Use 4, 8 or 16!\n");
break;
}
break;
case 'f': // set foreground color
sed_fg_color = atoi(optarg);
printf("New Foreground Color = %d.\n", sed_fg_color);
break;
case 'b': // set foreground color
sed_bg_color = atoi(optarg);
printf("New Background Color = %d.\n", sed_bg_color);
break;
default:
break;
}
}
if (reinit){
printf("Re-initializing S1D13506.\n");
sed135x_off();
sed135x_init();
sed135x_on();
}
return 0;
} // sed()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -