iPXE
video_subr.c
Go to the documentation of this file.
00001 /*
00002  *
00003  * modified from linuxbios code
00004  * by Cai Qiang <rimy2000@hotmail.com>
00005  *
00006  */
00007 
00008 #include "stddef.h"
00009 #include "string.h"
00010 #include <ipxe/io.h>
00011 #include <ipxe/console.h>
00012 #include <ipxe/init.h>
00013 #include "vga.h"
00014 #include <config/console.h>
00015 
00016 /* Set default console usage if applicable */
00017 #if ! ( defined ( CONSOLE_DIRECT_VGA ) && \
00018         CONSOLE_EXPLICIT ( CONSOLE_DIRECT_VGA ) )
00019 #undef CONSOLE_DIRECT_VGA
00020 #define CONSOLE_DIRECT_VGA ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
00021 #endif
00022 
00023 struct console_driver vga_console __console_driver;
00024 
00025 static char *vidmem;            /* The video buffer */
00026 static int video_line, video_col;
00027 
00028 #define VIDBUFFER 0xB8000       
00029 
00030 static void memsetw(void *s, int c, unsigned int n)
00031 {
00032         unsigned int i;
00033         u16 *ss = (u16 *) s;
00034 
00035         for (i = 0; i < n; i++) {
00036                 ss[i] = ( u16 ) c;
00037         }
00038 }
00039 
00040 static void video_init(void)
00041 {
00042         static int inited=0;
00043 
00044         vidmem = (char *)phys_to_virt(VIDBUFFER);
00045 
00046         if (!inited) {
00047                 video_line = 0;
00048                 video_col = 0;
00049         
00050                 memsetw(vidmem, VGA_ATTR_CLR_WHT, 2*1024); //
00051 
00052                 inited=1;
00053         }
00054 }
00055 
00056 static void video_scroll(void)
00057 {
00058         int i;
00059 
00060         memmove(vidmem, vidmem + COLS * 2, (LINES - 1) * COLS * 2);
00061         for (i = (LINES - 1) * COLS * 2; i < LINES * COLS * 2; i += 2)
00062                 vidmem[i] = ' ';
00063 }
00064 
00065 static void vga_putc(int byte)
00066 {
00067         if (byte == '\n') {
00068                 video_line++;
00069                 video_col = 0;
00070 
00071         } else if (byte == '\r') {
00072                 video_col = 0;
00073 
00074         } else if (byte == '\b') {
00075                 video_col--;
00076 
00077         } else if (byte == '\t') {
00078                 video_col += 4;
00079 
00080         } else if (byte == '\a') {
00081                 //beep
00082                 //beep(500);
00083 
00084         } else {
00085                 vidmem[((video_col + (video_line *COLS)) * 2)] = byte;
00086                 vidmem[((video_col + (video_line *COLS)) * 2) +1] = VGA_ATTR_CLR_WHT;
00087                 video_col++;
00088         }
00089         if (video_col < 0) {
00090                 video_col = 0;
00091         }
00092         if (video_col >= COLS) {
00093                 video_line++;
00094                 video_col = 0;
00095         }
00096         if (video_line >= LINES) {
00097                 video_scroll();
00098                 video_line--;
00099         }
00100         // move the cursor
00101         write_crtc((video_col + (video_line *COLS)) >> 8, CRTC_CURSOR_HI);
00102         write_crtc((video_col + (video_line *COLS)) & 0x0ff, CRTC_CURSOR_LO);
00103 }
00104 
00105 struct console_driver vga_console __console_driver = {
00106         .putchar = vga_putc,
00107         .disabled = CONSOLE_DISABLED,
00108         .usage = CONSOLE_DIRECT_VGA,
00109 };
00110 
00111 struct init_fn video_init_fn __init_fn ( INIT_EARLY ) = {
00112         .initialise = video_init,
00113 };