diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86/interface/pcbios/vesafb.c | 233 |
1 files changed, 195 insertions, 38 deletions
diff --git a/src/arch/x86/interface/pcbios/vesafb.c b/src/arch/x86/interface/pcbios/vesafb.c index 86edbda4..3ca15271 100644 --- a/src/arch/x86/interface/pcbios/vesafb.c +++ b/src/arch/x86/interface/pcbios/vesafb.c @@ -151,8 +151,140 @@ static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) { /* ASCII character: use corresponding glyph */ index = character; } else { - /* Non-ASCII character: use "unknown" glyph */ - index = VESAFB_UNKNOWN; + switch ( character ) { + /* above ASCII */ + case 0xc7: index = 0x80; break; + case 0xfc: index = 0x81; break; + case 0xe9: index = 0x82; break; + case 0xe2: index = 0x83; break; + case 0xe4: index = 0x84; break; + case 0xe0: index = 0x85; break; + case 0xe5: index = 0x86; break; + case 0xe7: index = 0x87; break; + case 0xea: index = 0x88; break; + case 0xeb: index = 0x89; break; + case 0xe8: index = 0x8a; break; + case 0xef: index = 0x8b; break; + case 0xee: index = 0x8c; break; + case 0xec: index = 0x8d; break; + case 0xc4: index = 0x8e; break; + case 0xc5: index = 0x8f; break; + case 0xc9: index = 0x90; break; + case 0xe6: index = 0x91; break; + case 0xc6: index = 0x92; break; + case 0xf4: index = 0x93; break; + case 0xf6: index = 0x94; break; + case 0xf2: index = 0x95; break; + case 0xfb: index = 0x96; break; + case 0xf9: index = 0x97; break; + case 0xff: index = 0x98; break; + case 0xd6: index = 0x99; break; + case 0xdc: index = 0x9a; break; + case 0xa2: index = 0x9b; break; + case 0xa3: index = 0x9c; break; + case 0xa5: index = 0x9d; break; + case 0x20a7: index = 0x9e; break; + case 0x192: index = 0x9f; break; + case 0xe1: index = 0xa0; break; + case 0xed: index = 0xa1; break; + case 0xf3: index = 0xa2; break; + case 0xfa: index = 0xa3; break; + case 0xf1: index = 0xa4; break; + case 0xd1: index = 0xa5; break; + case 0xaa: index = 0xa6; break; + case 0xba: index = 0xa7; break; + case 0xbf: index = 0xa8; break; + case 0x2310: index = 0xa9; break; + case 0xac: index = 0xaa; break; + case 0xbd: index = 0xab; break; + case 0xbc: index = 0xac; break; + case 0xa1: index = 0xad; break; + case 0xab: index = 0xae; break; + case 0xbb: index = 0xaf; break; + case 0x2591: index = 0xb0; break; + case 0x2592: index = 0xb1; break; + case 0x2593: index = 0xb2; break; + case 0x2502: index = 0xb3; break; + case 0x2524: index = 0xb4; break; + case 0x2561: index = 0xb5; break; + case 0x2562: index = 0xb6; break; + case 0x2556: index = 0xb7; break; + case 0x2555: index = 0xb8; break; + case 0x2563: index = 0xb9; break; + case 0x2551: index = 0xba; break; + case 0x2557: index = 0xbb; break; + case 0x255d: index = 0xbc; break; + case 0x255c: index = 0xbd; break; + case 0x255b: index = 0xbe; break; + case 0x2510: index = 0xbf; break; + case 0x2514: index = 0xc0; break; + case 0x2534: index = 0xc1; break; + case 0x252c: index = 0xc2; break; + case 0x251c: index = 0xc3; break; + case 0x2500: index = 0xc4; break; + case 0x253c: index = 0xc5; break; + case 0x255e: index = 0xc6; break; + case 0x255f: index = 0xc7; break; + case 0x255a: index = 0xc8; break; + case 0x2554: index = 0xc9; break; + case 0x2569: index = 0xca; break; + case 0x2566: index = 0xcb; break; + case 0x2560: index = 0xcc; break; + case 0x2550: index = 0xcd; break; + case 0x256c: index = 0xce; break; + case 0x2567: index = 0xcf; break; + case 0x2568: index = 0xd0; break; + case 0x2564: index = 0xd1; break; + case 0x2565: index = 0xd2; break; + case 0x2559: index = 0xd3; break; + case 0x2558: index = 0xd4; break; + case 0x2552: index = 0xd5; break; + case 0x2553: index = 0xd6; break; + case 0x256b: index = 0xd7; break; + case 0x256a: index = 0xd8; break; + case 0x2518: index = 0xd9; break; + case 0x250c: index = 0xda; break; + case 0x2588: index = 0xdb; break; + case 0x2584: index = 0xdc; break; + case 0x258c: index = 0xdd; break; + case 0x2590: index = 0xde; break; + case 0x2580: index = 0xdf; break; + case 0x3b1: index = 0xe0; break; + case 0xdf: index = 0xe1; break; + case 0x393: index = 0xe2; break; + case 0x3c0: index = 0xe3; break; + case 0x3a3: index = 0xe4; break; + case 0x3c3: index = 0xe5; break; + case 0xb5: index = 0xe6; break; + case 0x3c4: index = 0xe7; break; + case 0x3a6: index = 0xe8; break; + case 0x398: index = 0xe9; break; + case 0x3a9: index = 0xea; break; + case 0x3b4: index = 0xeb; break; + case 0x221e: index = 0xec; break; + case 0x3c6: index = 0xed; break; + case 0x3b5: index = 0xee; break; + case 0x2229: index = 0xef; break; + case 0x2261: index = 0xf0; break; + case 0xb1: index = 0xf1; break; + case 0x2265: index = 0xf2; break; + case 0x2264: index = 0xf3; break; + case 0x2320: index = 0xf4; break; + case 0x2321: index = 0xf5; break; + case 0xf7: index = 0xf6; break; + case 0x2248: index = 0xf7; break; + case 0xb0: index = 0xf8; break; + case 0x2219: index = 0xf9; break; + case 0xb7: index = 0xfa; break; + case 0x221a: index = 0xfb; break; + case 0x207f: index = 0xfc; break; + case 0xb2: index = 0xfd; break; + case 0x25a0: index = 0xfe; break; + case 0xa0: index = 0xff; break; + default: + /* Non-CP437 character: use "unknown" glyph */ + index = VESAFB_UNKNOWN; + } } /* Copy glyph from BIOS font table */ @@ -443,34 +575,36 @@ static void vesafb_restore ( void ) { */ static int vesafb_init ( struct console_configuration *config ) { uint32_t discard_b; - uint16_t *mode_numbers; + uint16_t *mode_numbers = NULL; int mode_number; int rc; - /* Record current VGA mode */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x10" ) - : "=a" ( vesafb.saved_mode ), "=b" ( discard_b ) - : "a" ( VBE_GET_VGA_MODE ) ); - DBGC ( &vbe_buf, "VESAFB saved VGA mode %#02x\n", vesafb.saved_mode ); - - /* Get VESA mode list */ - if ( ( rc = vesafb_mode_list ( &mode_numbers ) ) != 0 ) - goto err_mode_list; - - /* Select mode */ - if ( ( mode_number = vesafb_select_mode ( mode_numbers, config->width, - config->height, - config->depth ) ) < 0 ) { - rc = mode_number; - goto err_select_mode; - } + if ( ! config->lazy_update ) { + /* Record current VGA mode */ + __asm__ __volatile__ ( REAL_CODE ( "int $0x10" ) + : "=a" ( vesafb.saved_mode ), "=b" ( discard_b ) + : "a" ( VBE_GET_VGA_MODE ) ); + DBGC ( &vbe_buf, "VESAFB saved VGA mode %#02x\n", vesafb.saved_mode ); + + /* Get VESA mode list */ + if ( ( rc = vesafb_mode_list ( &mode_numbers ) ) != 0 ) + goto err_mode_list; + + /* Select mode */ + if ( ( mode_number = vesafb_select_mode ( mode_numbers, config->width, + config->height, + config->depth ) ) < 0 ) { + rc = mode_number; + goto err_select_mode; + } - /* Set mode */ - if ( ( rc = vesafb_set_mode ( mode_number ) ) != 0 ) - goto err_set_mode; + /* Set mode */ + if ( ( rc = vesafb_set_mode ( mode_number ) ) != 0 ) + goto err_set_mode; - /* Get font data */ - vesafb_font(); + /* Get font data */ + vesafb_font(); + } /* Initialise frame buffer console */ if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ), @@ -523,17 +657,38 @@ static void vesafb_putchar ( int character ) { static int vesafb_configure ( struct console_configuration *config ) { int rc; - /* Reset console, if applicable */ - if ( ! vesafb_console.disabled ) { - vesafb_fini(); - bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT; - ansicol_reset_magic(); + if ( config && config->lazy_update ) { + if ( vesafb_console.disabled ) { + /* --update mode with disabled console -> nothing to do */ + return 0; + } + /* No width/height given, use current so we can update the border */ + if ( ( config->width == 0 ) || ( config->height == 0 ) ) { + if ( ( vesafb.pixel.width == 0 ) || ( vesafb.pixel.height == 0 ) ) { + return -EINVAL; + } + config->width = vesafb.pixel.width; + config->height = vesafb.pixel.height; + } else { + /* Otherwise make sure the new dimensions match the old ones */ + if ( ( vesafb.pixel.width != config->width ) || + ( vesafb.pixel.height != config->height ) ) { + return -EINVAL; + } + } + } else { + /* Reset console, if applicable */ + if ( ! vesafb_console.disabled ) { + vesafb_fini(); + bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT; + ansicol_reset_magic(); + } + vesafb_console.disabled = CONSOLE_DISABLED; } - vesafb_console.disabled = CONSOLE_DISABLED; /* Do nothing more unless we have a usable configuration */ if ( ( config == NULL ) || - ( config->width == 0 ) || ( config->height == 0 ) ) { + ( config->width == 0 ) || ( config->height == 0 ) ) { return 0; } @@ -541,13 +696,15 @@ static int vesafb_configure ( struct console_configuration *config ) { if ( ( rc = vesafb_init ( config ) ) != 0 ) return rc; - /* Mark console as enabled */ - vesafb_console.disabled = 0; - bios_console.disabled |= CONSOLE_DISABLED_OUTPUT; + if ( ! config->lazy_update ) { + /* Mark console as enabled */ + vesafb_console.disabled = 0; + bios_console.disabled |= CONSOLE_DISABLED_OUTPUT; - /* Set magic colour to transparent if we have a background picture */ - if ( config->pixbuf ) - ansicol_set_magic_transparent(); + /* Set magic colour to transparent if we have a background picture */ + if ( config->pixbuf ) + ansicol_set_magic_transparent(); + } return 0; } |