--- drivers/char/i386/display.c.orig Tue Feb 24 17:10:12 1998 +++ drivers/char/i386/display.c Fri Mar 6 19:11:20 1998 @@ -249,10 +249,320 @@ curr_col[i] = def_col[i]; } set_col(); } + + +/****************************** + *** *** + *** Diederen's GGI Logo *** + *** *** + ******************************/ + +/* NOTE: + * Damien Diederen is the creator of the logo, but Andrew Apted is + * the miscreant responsible for this code. Blame him if it all + * goes fubar ! + */ + +#define DEF_LINES_PER_CHAR 16 /* i.e. char height in 80x25 mode */ + +static int logo_x=0, logo_y=0, logo_drawn=0; + +#define LOGO_DX 13 +#define LOGO_DY 1 + + +#define DIEDEREN_HT 6 +#define DIEDEREN_WD 29 + +static uint16 diederen_logo_attr[DIEDEREN_HT*DIEDEREN_WD] = +{ + 0x0e44, 0x0e69, 0x0e73, 0x0e70, 0x0e6c, 0x0e61, 0x0e79, 0x0e20, + 0x0e50, 0x0e6f, 0x0e77, 0x0e65, 0x0e72, 0x0e65, 0x0e64, 0x0e20, + 0x0e42, 0x0e79, 0x0e3a, 0x0e20, 0x0e20, 0x0e20, 0x0e20, 0x0e20, + 0x0e20, 0x0e20, 0x0e20, 0x0e20, 0x0e20, + + 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, + 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, + 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, 0x70df, + 0x70df, 0x70df, 0x0720, 0x0720, 0x0720, + + 0x7020, 0x7020, 0x7020, 0x7020, 0x7020, 0x70c0, 0x70c3, 0x70c6, + 0x70c7, 0x70c8, 0x70c9, 0x70cc, 0x70d3, 0x70d4, 0x70d5, 0x70d6, + 0x70da, 0x70c1, 0x70c2, 0x70c4, 0x7020, 0x7020, 0x7020, 0x7020, + 0x7020, 0x7020, 0x0720, 0x0720, 0x0720, + + 0x7020, 0x7020, 0x7020, 0x7020, 0x7020, 0x70c5, 0x70ca, 0x70cb, + 0x70cd, 0x70ce, 0x70cf, 0x70d0, 0x70d1, 0x70d2, 0x70d7, 0x70d8, + 0x70db, 0x70dc, 0x70dd, 0x70de, 0x7020, 0x7020, 0x7020, 0x7020, + 0x7020, 0x7020, 0x0720, 0x0720, 0x0720, + + 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, + 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, + 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, 0x07df, + 0x07df, 0x07df, 0x0720, 0x0720, 0x0720, + + 0x0c47, 0x0c65, 0x0c6e, 0x0c65, 0x0c72, 0x0c61, 0x0c6c, 0x0c20, + 0x0a47, 0x0a72, 0x0a61, 0x0a70, 0x0a68, 0x0a69, 0x0a63, 0x0a73, + 0x0a20, 0x0949, 0x096e, 0x0974, 0x0965, 0x0972, 0x0966, 0x0961, + 0x0963, 0x0965, 0x0920, 0x0920, 0x0920, +}; + +#define DIEDEREN_FIRST 192 +#define DIEDEREN_LAST 222 + +static uint8 diederen_logo_data[(DIEDEREN_LAST-DIEDEREN_FIRST+1)*16] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0x3f, 0x3f, 0x78, 0x70, 0x70, 0x30, + 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x00, 0x18, + 0x7e, 0x7e, 0x7e, 0x3c, 0x80, 0xe6, 0xfe, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, + 0x00, 0x60, 0x7f, 0x7f, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe1, 0xe3, 0x63, 0x07, 0x07, 0x07, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfc, 0x0c, 0x04, + 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x18, 0x00, + 0x18, 0x0f, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x0f, + 0x3f, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xf0, 0xf0, + 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x78, 0xff, + 0xff, 0xff, 0xff, 0x9f, 0x01, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x80, + 0xe0, 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0x01, 0xfd, + 0x00, 0x00, 0x00, 0xe0, 0xf8, 0xfb, 0x0f, 0x0f, + 0x08, 0x08, 0x08, 0x08, 0x10, 0xe0, 0xe0, 0x70, + 0xc7, 0xc7, 0xc7, 0xc7, 0x83, 0x81, 0x80, 0x80, + 0x80, 0x80, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xf0, 0xf8, 0xfc, 0xff, 0xff, 0xff, 0x7f, + 0x1f, 0x03, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x3f, 0xff, 0xf8, 0x00, + 0x07, 0x1f, 0x3f, 0x7f, 0x7f, 0xff, 0xfe, 0xfe, + 0x3f, 0x3f, 0x3f, 0x03, 0x07, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, + 0xfd, 0xfd, 0xfc, 0xfe, 0xfe, 0xfc, 0xf8, 0xf0, + 0xc0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x30, 0xf0, 0xe0, 0x20, 0x24, 0x26, 0x2e, 0x3f, + 0x27, 0x27, 0x23, 0x23, 0xe1, 0x01, 0x00, 0x00, + 0xfc, 0xfe, 0xfe, 0xff, 0x7f, 0x3f, 0x1f, 0x0f, + 0x03, 0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xef, 0x78, + 0x07, 0x07, 0x07, 0x00, 0xc0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf8, 0x80, 0x00, + 0xff, 0xff, 0xcf, 0x3f, 0xff, 0xff, 0xff, 0xfe, + 0xf8, 0xc0, 0x0f, 0xf8, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x1f, 0xff, 0xf8, 0x80, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x01, 0x0f, + 0x1e, 0xff, 0xfc, 0x80, 0x00, 0x00, 0x00, 0xe0, + 0xf8, 0xfe, 0xff, 0xfc, 0x60, 0x0f, 0xff, 0xff, + 0x00, 0x80, 0x80, 0xc0, 0x40, 0x60, 0x20, 0x3f, + 0x1f, 0x1c, 0x08, 0x00, 0x00, 0xe2, 0xe3, 0xe3, + 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x70, 0x70, 0x70, + 0xe0, 0x60, 0x20, 0x10, 0x1f, 0x23, 0xc3, 0x83, + 0xe1, 0xe1, 0xe0, 0xc0, 0xc0, 0x80, 0x00, 0x00, + 0x07, 0x7d, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, + 0xc7, 0xff, 0xff, 0xc0, 0x40, 0x60, 0x20, 0x60, + 0xc0, 0xc0, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0x03, 0x00, 0x00, + 0x02, 0x02, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x30, 0xf0, 0xf0, 0xf0, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x30, 0x20, 0xe0, 0x00, 0x00, +}; + +static uint8 previous_font_chars[DIEDEREN_LAST-DIEDEREN_FIRST+1][32]; + + +/* This font code is from the IBM vga driver */ + +#include +#include + +typedef struct text16_font_reg_s { + uchar SR2,SR4; + uchar GR4,GR5,GR6; +} text16_font_reg; + +static inline void text16_font_enter(text16_font_reg *regs) +{ + IS_CRITICAL; + + ENTER_CRITICAL; + { + regs->SR2 = inbSEQ(0x02); + regs->SR4 = inbSEQ(0x04); /* save register state */ + regs->GR4 = inbGRC(0x04); + regs->GR5 = inbGRC(0x05); + regs->GR6 = inbGRC(0x06); + + outbSEQ(SR02_PLANE2, 0x02); /* font data goes to plane 2 */ + outbSEQ(SR04_256K_ACCESS | SR04_NO_ODDEVEN, 0x04); + + outbGRC(2, 0x04); /* read plane 2 */ + outbGRC(GR5_WRITEMODE0, 0x05); + outbGRC(GR6_MAP_A0_64, 0x06); + } + LEAVE_CRITICAL; +} + +static void inline text16_font_leave(text16_font_reg *regs) +{ + IS_CRITICAL; + + ENTER_CRITICAL; + { + outbSEQ(regs->SR2, 0x02); + outbSEQ(regs->SR4, 0x04); /* restore registers */ + outbGRC(regs->GR4, 0x04); + outbGRC(regs->GR5, 0x05); + outbGRC(regs->GR6, 0x06); + } + LEAVE_CRITICAL; +} + +static inline void direct_text16_font_read(int ch, uint8 *charcell) +{ + memcpy(charcell,(uint8 *)(phys_to_virt(0xA0000))+(ch<<5),32); +} + +static inline void direct_text16_font_write(int ch, uint8 *charcell) +{ + memcpy((uint8 *)(phys_to_virt(0xA0000))+(ch<<5),charcell,32); +} + +static void set_logo_font(uint sizey) +{ + /* sizey is the font height */ + + int i, y; + + text16_font_reg regs; + + text16_font_enter(®s); + + for (i=DIEDEREN_FIRST; i <= DIEDEREN_LAST; i++) { + + uint8 charcell[32]; + + direct_text16_font_read(i, + & previous_font_chars[i-DIEDEREN_FIRST][0]); + + for (y=0; y < 32; y++) { + + int row = y * 16 / sizey; + + charcell[y] = (row >= 16) ? 0 : + diederen_logo_data[(i-DIEDEREN_FIRST)*16+row]; + } + + direct_text16_font_write(i, charcell); + } + + text16_font_leave(®s); +} + +static void reset_logo_font(void) +{ + int i; + + text16_font_reg regs; + + text16_font_enter(®s); + + for (i=DIEDEREN_FIRST; i <= DIEDEREN_LAST; i++) { + + direct_text16_font_write(i, + & previous_font_chars[i-DIEDEREN_FIRST][0]); + } + + text16_font_leave(®s); +} + +static void poll_wait_one_screen(void) +{ + while ( (inb_p(0x3DA) & 8)); + while (! (inb_p(0x3DA) & 8)); +} + +static void pause_dd_logo(void) +{ + int i; + + if (logo_drawn < DIEDEREN_HT*DIEDEREN_WD) { + return; + } + + for (i = 0; i < 15; i++) { + poll_wait_one_screen(); + } +} + +static void show_logo_char(uint16 *fb, uint sizex) +{ + int x; + + fb[logo_y*sizex + logo_x] = + diederen_logo_attr[logo_y*DIEDEREN_WD + logo_x]; + + /* clear area to the right of the logo */ + + for (x = logo_x+DIEDEREN_WD; x < sizex; x += DIEDEREN_WD) { + fb[logo_y*sizex + x] = 0x0720; + } + + logo_x = (logo_x + LOGO_DX) % DIEDEREN_WD; + logo_y = (logo_y + LOGO_DY) % DIEDEREN_HT; + + poll_wait_one_screen(); +} + +static void show_dd_logo(uint16 *fb, uint sizex, uint sizey) +{ + int row = 0; + int firstcol = 0; + + for (row=0; row < DIEDEREN_HT; row++) { + + int col; + uint16 *p = fb + firstcol; + + for (col = 0; col < sizex; col++) { + *p++ = (col >= DIEDEREN_WD) ? 0x0720 : + diederen_logo_attr[row*DIEDEREN_WD+col]; + } + + fb += sizex; + } +} + +static void clear_dd_logo(uint16 *fb, uint sizex, uint sizey) +{ + int row = 0; + int firstcol = 0; + + for (row=0; row < DIEDEREN_HT; row++) { + + int col; + uint16 *p = fb + firstcol; + + for (col = 0; col < sizex; col++) { + *p++ = 0x0720; + } + + fb += sizex; + } +} + #endif /* #ifdef TELL_THE_TRUTH */ /* ----------------------------------------------------------------------------- ** generic text16-framebuffer-only display driver ** ----------------------------------------------------------------------------- @@ -789,40 +1099,27 @@ { if (ORIG_Y+1 == ORIG_VIDEO_LINES) { int cnt = ORIG_VIDEO_COLS*(ORIG_VIDEO_LINES - 1); - #ifdef TELL_THE_TRUTH - - ushort *d = boot_fb; - ushort *s = boot_fb+ORIG_VIDEO_COLS; - - while (cnt--) { - - *d = (*d & 0xFF00) | (*s & 0x00FF); - d++; s++; - } - - cnt = ORIG_VIDEO_COLS; - while (cnt--) { - - *(d++) &= 0xFF00; - } - - #else - memcpy(boot_fb, boot_fb + ORIG_VIDEO_COLS, cnt*2); memset(boot_fb + cnt, 0, ORIG_VIDEO_COLS*2); + #ifdef TELL_THE_TRUTH + + show_dd_logo(boot_fb, ORIG_VIDEO_COLS, + ORIG_VIDEO_LINES); #endif } else { ORIG_Y++; boot_pos += ORIG_VIDEO_COLS; } + pause_dd_logo(); + boot_need_wrap = 0; } #if LINUX_VERSION_CODE < LinuxVersionCode(2,1,0) static void boot_console_printk(const char *s) @@ -860,29 +1157,27 @@ s++; continue; } } - #ifdef TELL_THE_TRUTH - - boot_fb[boot_pos] = *s | (boot_fb[boot_pos] & 0xFF00); + boot_fb[boot_pos] = *s | boot_attr; - /* slow down to be able to read early boot messages - ** even when they scroll up. - */ - if (ORIG_VIDEO_ISVGA && !(boot_pos & 0x3)) { + #ifdef TELL_THE_TRUTH - while (inb(0x3DA) & 8); - while (!(inb(0x3DA) & 8)); - } + if (logo_drawn < DIEDEREN_HT*DIEDEREN_WD) { - #else + /* good thing total is divisible by 3 */ - boot_fb[boot_pos] = *s | boot_attr; + show_logo_char(boot_fb, ORIG_VIDEO_COLS); + show_logo_char(boot_fb, ORIG_VIDEO_COLS); + show_logo_char(boot_fb, ORIG_VIDEO_COLS); + logo_drawn += 3; + } #endif + s++; boot_pos++; ORIG_X++; if ((boot_need_wrap = (ORIG_X == ORIG_VIDEO_COLS))) { @@ -954,11 +1249,16 @@ #ifdef TELL_THE_TRUTH if (ORIG_VIDEO_ISVGA) { - show_msg(boot_fb, ORIG_VIDEO_COLS, ORIG_VIDEO_LINES); + set_logo_font(DEF_LINES_PER_CHAR); + + if (ORIG_Y < DIEDEREN_HT) { + ORIG_Y = DIEDEREN_HT; + boot_pos = ORIG_Y*ORIG_VIDEO_COLS + ORIG_X; + } } #endif #if LINUX_VERSION_CODE < LinuxVersionCode(2,1,0) @@ -1013,22 +1313,10 @@ int display_init(void) { int dpys = 0; struct kgi_display *dpy; - #ifdef TELL_THE_TRUTH - - /* This will be undefined if CONFIG_VT_CONSOLE is - ** undefined. - */ - - if (ORIG_VIDEO_ISVGA) { - - hide_msg(boot_fb, ORIG_VIDEO_COLS, ORIG_VIDEO_LINES); - } - #endif - if (detect(COLOR_CRTC)) { printk(KERN_INFO "color display detected.\n"); dpy = text16_malloc_display(COLOR_FB, 80,25, 8,16, COLOR); @@ -1050,8 +1338,23 @@ } dpys++; } printk(KERN_INFO "display_init(): %i displays detected.\n", dpys); + + #ifdef TELL_THE_TRUTH + + /* This will be undefined if CONFIG_VT_CONSOLE is + ** undefined. + */ + + if (ORIG_VIDEO_ISVGA) { + + clear_dd_logo(boot_fb, ORIG_VIDEO_COLS, + ORIG_VIDEO_LINES); + + reset_logo_font(); + } + #endif return dpys; }