summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/interface/pcbios/vesafb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/interface/pcbios/vesafb.c')
-rw-r--r--src/arch/x86/interface/pcbios/vesafb.c233
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;
}