VGA text mode no longer flickers and it is much faster.
VGA text mode is now initialized earlier.
VGA text mode is now emulated even without console.

diff --git a/dlls/winedos/int10.c b/dlls/winedos/int10.c
index a0f3775..d634af8 100644
--- a/dlls/winedos/int10.c
+++ b/dlls/winedos/int10.c
@@ -48,6 +48,41 @@
   data->VideoCursorPos[page*2+1] = Y;
 }
 
+
+/**********************************************************************
+ *         DOSVM_InitializeVideoMode
+ *
+ * The first time this function is called VGA emulation is set to the
+ * default text mode.
+ */
+static void DOSVM_InitializeVideoMode( BIOSDATA *data )
+{
+  static BOOL already_initialized = FALSE;
+  unsigned    width;
+  unsigned    height;
+
+  if(already_initialized)
+    return;
+  already_initialized = TRUE;
+
+  VGA_InitAlphaMode(&width, &height);
+
+  /*
+   * FIXME: Add more mappings between initial size and
+   *        text modes.
+   */
+  if (width >= 80 && height >= 25) {
+    VGA_SetAlphaMode(80, 25);
+    data->VideoColumns = 80;
+    data->VideoMode = 0x02;
+  } else {
+    VGA_SetAlphaMode(40, 25);
+    data->VideoColumns = 40;
+    data->VideoMode = 0x01;
+  }
+}
+
+
 /**********************************************************************
  *	    DOSVM_Int10Handler (WPROCS.116)
  *	    DOSVM_Int10Handler (WINEDOS16.116)
@@ -340,6 +375,8 @@
 {
     BIOSDATA *data = BIOS_DATA;
 
+    DOSVM_InitializeVideoMode( data );
+
     switch(AH_reg(context)) {
 
     case 0x00: /* SET VIDEO MODE */
@@ -365,7 +402,6 @@
         switch (AL_reg(context)) {
             case 0x00: /* 40x25 */
             case 0x01:
-                VGA_Exit();
                 TRACE("Set Video Mode - Set to Text - 0x0%x\n",
                    AL_reg(context));
                 VGA_SetAlphaMode(40, 25);
@@ -374,7 +410,6 @@
             case 0x02:
             case 0x03:
             case 0x07:
-                VGA_Exit();
                 TRACE("Set Video Mode - Set to Text - 0x0%x\n",
                    AL_reg(context));
                 VGA_SetAlphaMode(80, 25);
@@ -492,10 +527,7 @@
            {
                 BYTE ascii, attr;
                 TRACE("Read Character and Attribute at Cursor Position\n");
-                if(!VGA_GetCharacterAtCursor(&ascii, &attr)) {
-                    ascii = 0;
-                    attr = 0;
-                }
+                VGA_GetCharacterAtCursor(&ascii, &attr);
                 SET_AL( context, ascii );
                 SET_AH( context, attr );
             }
@@ -824,8 +856,7 @@
 {
    if (!lines) /* Actually, clear the window */
    {
-       if(!VGA_ClearText(row1, col1, row2, col2, attribute))
-            ERR("VGA_ClearText failed!\n");
+       VGA_ClearText(row1, col1, row2, col2, attribute);
    }
    else if (direction == SCROLL_UP)
    {
@@ -837,20 +868,22 @@
    }
 }
 
-
 /**********************************************************************
  *         DOSVM_PutChar
  *
+ * Write single character to VGA console at the current 
+ * cursor position and updates the BIOS cursor position.
  */
-
-void WINAPI DOSVM_PutChar(BYTE ascii)
+void WINAPI DOSVM_PutChar( BYTE ascii )
 {
   BIOSDATA *data = BIOS_DATA;
   unsigned  xpos, ypos;
 
   TRACE("char: 0x%02x(%c)\n", ascii, ascii);
 
-  VGA_PutChar(ascii);
-  if(VGA_GetCursorPos(&xpos, &ypos))
-      BIOS_SetCursorPos(data, 0, xpos, ypos);
+  DOSVM_InitializeVideoMode( data );
+
+  VGA_PutChar( ascii );
+  VGA_GetCursorPos( &xpos, &ypos );
+  BIOS_SetCursorPos( data, 0, xpos, ypos );
 }
diff --git a/dlls/winedos/int33.c b/dlls/winedos/int33.c
index 9595d05..c0761a3 100644
--- a/dlls/winedos/int33.c
+++ b/dlls/winedos/int33.c
@@ -270,10 +270,9 @@
     mask |= 0x20;
   else if(!newMiddleButton && oldMiddleButton)
     mask |= 0x40;
-
-  VGA_GetAlphaMode(&Width, &Height);
-
-  QueueMouseRelay(640 / Width * record->dwMousePosition.X,
-                 200 / Height * record->dwMousePosition.Y,
-                 mask);
+  
+  if (VGA_GetAlphaMode(&Width, &Height))
+    QueueMouseRelay( 640 / Width * record->dwMousePosition.X,
+                     200 / Height * record->dwMousePosition.Y,
+                     mask );
 }
diff --git a/dlls/winedos/vga.c b/dlls/winedos/vga.c
index 30d85fc..663d713 100644
--- a/dlls/winedos/vga.c
+++ b/dlls/winedos/vga.c
@@ -36,7 +36,6 @@
 static IDirectDrawPalette *lpddpal;
 static DDSURFACEDESC sdesc;
 static LONG vga_refresh;
-static HANDLE poll_timer;
 
 /*
  * VGA controller memory is emulated using linear framebuffer.
@@ -77,8 +76,26 @@
 static void *vga_fb_data = 0;
 static int   vga_fb_window = 0;
 
-static BYTE vga_text_attr;
-static char *textbuf_old = NULL;
+/*
+ * VGA text mode data.
+ *
+ * vga_text_attr: Current active attribute.
+ * vga_text_old: Last data sent to console. 
+ *               This is used to optimize console updates.
+ * vga_text_width:  Width of the text display in characters.
+ * vga_text_height: Height of the text display in characters.
+ * vga_text_x: Current cursor X-position. Starts from zero.
+ * vga_text_y: Current cursor Y-position. Starts from zero.
+ * vga_text_console: TRUE if stdout is console, 
+ *                   FALSE if it is regular file.
+ */
+static BYTE  vga_text_attr;
+static char *vga_text_old = NULL;
+static BYTE  vga_text_width;
+static BYTE  vga_text_height;
+static BYTE  vga_text_x;
+static BYTE  vga_text_y;
+static BOOL  vga_text_console;
 
 /*
  * VGA controller ports 0x3c0, 0x3c4, 0x3ce and 0x3d4 are
@@ -98,8 +115,6 @@
 static BYTE vga_index_3d4;
 static BOOL vga_address_3c0 = TRUE;
 
-static BOOL vga_mode_initialized = FALSE;
-
 static CRITICAL_SECTION vga_lock = CRITICAL_SECTION_INIT("VGA");
 
 typedef HRESULT (WINAPI *DirectDrawCreateProc)(LPGUID,LPDIRECTDRAW *,LPUNKNOWN);
@@ -270,6 +285,11 @@
     QueueUserAPC( set_timer_rate, VGA_timer_thread, (ULONG_PTR)Rate );
 }
 
+static BOOL VGA_IsTimerRunning(void)
+{
+    return VGA_timer_thread ? TRUE : FALSE;
+}
+
 HANDLE VGA_AlphaConsole(void)
 {
     /* this assumes that no Win32 redirection has taken place, but then again,
@@ -410,8 +430,6 @@
 
     par.Depth = (Depth < 8) ? 8 : Depth;
 
-    vga_mode_initialized = TRUE;
-
     MZ_RunInThread(VGA_DoSetMode, (ULONG_PTR)&par);
     return par.ret;
 }
@@ -557,10 +575,14 @@
     char *p, *p2;
     int i;
 
-    textbuf_old = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, textbuf_old, Xres * Yres * 2); /* char + attr */
+    /*
+     * Allocate space for char + attr.
+     */
+    vga_text_old = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
+                                vga_text_old, Xres * Yres * 2 );
 
     p = VGA_AlphaBuffer();
-    p2 = textbuf_old;
+    p2 = vga_text_old;
 
     /* make sure the video mem copy contains the exact opposite of our
      * actual text mode memory area to make sure the screen
@@ -569,39 +591,80 @@
 	*p2++ ^= *p++; /* XOR it */
 }
 
-int VGA_SetAlphaMode(unsigned Xres,unsigned Yres)
+/**********************************************************************
+ *         VGA_SetAlphaMode
+ *
+ * Set VGA emulation to text mode.
+ */
+void VGA_SetAlphaMode(unsigned Xres,unsigned Yres)
 {
-    COORD siz;
-
-    if (lpddraw) VGA_Exit();
-
-    /* FIXME: Where to initialize text attributes? */
-    VGA_SetTextAttribute(0xf);
-
+    VGA_Exit();
+    VGA_DeinstallTimer();
+    
     VGA_PrepareVideoMemCopy(Xres, Yres);
+    vga_text_width = Xres;
+    vga_text_height = Yres;
 
-    /* poll every 30ms (33fps should provide adequate responsiveness) */
-    VGA_InstallTimer(30);
+    if (vga_text_x >= vga_text_width || vga_text_y >= vga_text_height)
+        VGA_SetCursorPos(0,0);
 
-    siz.X = Xres;
-    siz.Y = Yres;
-    SetConsoleScreenBufferSize(VGA_AlphaConsole(),siz);
-    return 0;
+    if(vga_text_console) {
+        COORD size;
+        size.X = Xres;
+        size.Y = Yres;
+        SetConsoleScreenBufferSize( VGA_AlphaConsole(), size );
+
+        /* poll every 30ms (33fps should provide adequate responsiveness) */
+        VGA_InstallTimer(30);
+    }
 }
 
-BOOL VGA_GetAlphaMode(unsigned*Xres,unsigned*Yres)
+/**********************************************************************
+ *         VGA_InitAlphaMode
+ *
+ * Initialize VGA text mode handling and return default text mode.
+ * This function does not set VGA emulation to text mode.
+ */
+void VGA_InitAlphaMode(unsigned*Xres,unsigned*Yres)
 {
     CONSOLE_SCREEN_BUFFER_INFO info;
-    if(!GetConsoleScreenBufferInfo(VGA_AlphaConsole(),&info))
+
+    if(GetConsoleScreenBufferInfo( VGA_AlphaConsole(), &info ))
     {
-        return FALSE;
-    } else {
-        if (Xres) *Xres=info.dwSize.X;
-        if (Yres) *Yres=info.dwSize.Y;
-        return TRUE;
+        vga_text_console = TRUE;
+        vga_text_x = info.dwCursorPosition.X;
+        vga_text_y = info.dwCursorPosition.Y;
+        vga_text_attr = info.wAttributes;
+        *Xres = info.dwSize.X;
+        *Yres = info.dwSize.Y;
+    } 
+    else
+    {
+        vga_text_console = FALSE;
+        vga_text_x = 0;
+        vga_text_y = 0;
+        vga_text_attr = 0x0f;
+        *Xres = 80;
+        *Yres = 25;
     }
 }
 
+/**********************************************************************
+ *         VGA_GetAlphaMode
+ *
+ * Get current text mode. Returns TRUE and sets resolution if
+ * any VGA text mode has been initialized.
+ */
+BOOL VGA_GetAlphaMode(unsigned*Xres,unsigned*Yres)
+{
+    if (vga_text_width != 0 && vga_text_height != 0) {
+        *Xres = vga_text_width;
+        *Yres = vga_text_height;
+        return TRUE;
+    } else
+        return FALSE;
+}
+
 void VGA_SetCursorShape(unsigned char start_options, unsigned char end)
 {
     CONSOLE_CURSOR_INFO cci;
@@ -619,25 +682,34 @@
 
 void VGA_SetCursorPos(unsigned X,unsigned Y)
 {
-    COORD pos;
+    vga_text_x = X;
+    vga_text_y = Y;
 
-    if (!poll_timer) VGA_SetAlphaMode(80, 25);
-    pos.X = X;
-    pos.Y = Y;
-    SetConsoleCursorPosition(VGA_AlphaConsole(),pos);
+    if (vga_text_console) {
+        COORD pos;
+        pos.X = X;
+        pos.Y = Y;
+        SetConsoleCursorPosition(VGA_AlphaConsole(),pos);
+    }
 }
 
-BOOL VGA_GetCursorPos(unsigned*X,unsigned*Y)
+void VGA_GetCursorPos(unsigned*X,unsigned*Y)
 {
-    CONSOLE_SCREEN_BUFFER_INFO info;
-    if(!GetConsoleScreenBufferInfo(VGA_AlphaConsole(),&info))
-    {
-        return FALSE;
-    } else {
-        if (X) *X=info.dwCursorPosition.X;
-        if (Y) *Y=info.dwCursorPosition.Y;
-        return TRUE;
-    }
+    if (X) *X = vga_text_x;
+    if (Y) *Y = vga_text_y;
+}
+
+static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, BYTE attr)
+{
+    char *dat;
+
+    dat = VGA_AlphaBuffer() + ((vga_text_width * y + x) * 2);
+    dat[0] = ascii;
+    dat[1] = attr;
+    
+    dat = vga_text_old + ((vga_text_width * y + x) * 2);
+    dat[0] = ascii;
+    dat[1] = attr;
 }
 
 void VGA_WriteChars(unsigned X,unsigned Y,unsigned ch,int attr,int count)
@@ -645,11 +717,6 @@
     CHAR_INFO info;
     COORD siz, off;
     SMALL_RECT dest;
-    unsigned XR, YR;
-    char *dat;
-
-    if(!VGA_GetAlphaMode(&XR, &YR))
-        return;
 
     EnterCriticalSection(&vga_lock);
 
@@ -662,73 +729,57 @@
     dest.Top=Y;
     dest.Bottom=Y;
 
-    dat = VGA_AlphaBuffer() + ((XR*Y + X) * 2);
     while (count--) {
-        dest.Left = X + count;
-       dest.Right = X + count;
+        BYTE realattr;
 
-        *dat++ = ch;
-        if (attr>=0)
-         *dat = attr;
-       else
-         info.Attributes = *dat;
-        dat++;
+        if (attr < 0) {
+            char *dat = VGA_AlphaBuffer() + ((vga_text_width * Y + X + count) * 2);
+            realattr = dat[1];
+        } else
+            realattr = attr;
 
-       WriteConsoleOutputA(VGA_AlphaConsole(), &info, siz, off, &dest);
+        VGA_PutCharAt(X + count, Y, ch, realattr);
+
+        if (vga_text_console) {
+            dest.Left = X + count;
+            dest.Right = X + count;
+            info.Attributes= realattr;
+            WriteConsoleOutputA(VGA_AlphaConsole(), &info, siz, off, &dest);
+        }
     }
 
     LeaveCriticalSection(&vga_lock);
 }
 
-static void VGA_PutCharAt(BYTE ascii, unsigned x, unsigned y)
-{
-    unsigned width, height;
-    char *dat;
-
-    VGA_GetAlphaMode(&width, &height);
-    dat = VGA_AlphaBuffer() + ((width*y + x) * 2);
-    dat[0] = ascii;
-    dat[1] = vga_text_attr;
-}
-
 void VGA_PutChar(BYTE ascii)
 {
-    unsigned width, height, x, y, nx, ny;
-
-    if(!VGA_GetAlphaMode(&width, &height)) {
-        WriteFile(VGA_AlphaConsole(), &ascii, 1, NULL, NULL);
-        return;
-    }
-
     EnterCriticalSection(&vga_lock);
 
-    VGA_GetCursorPos(&x, &y);
-
     switch(ascii) {
     case '\b':
-        VGA_PutCharAt(' ', x, y);
-       x--;
+       VGA_PutCharAt(vga_text_x, vga_text_y, ' ', vga_text_attr);
+       vga_text_x--;
        break;
 
     case '\t':
-       x += ((x + 8) & ~7) - x;
+       vga_text_x += ((vga_text_x + 8) & ~7) - vga_text_x;
        break;
 
     case '\n':
-        y++;
-       x = 0;
+       vga_text_y++;
+       vga_text_x = 0;
        break;
 
     case '\a':
         break;
 
     case '\r':
-        x = 0;
-       break;
+        vga_text_x = 0;
+        break;
 
     default:
-        VGA_PutCharAt(ascii, x, y);
-       x++;
+        VGA_PutCharAt(vga_text_x, vga_text_y, ascii, vga_text_attr);
+        vga_text_x++;
     }
 
     /*
@@ -740,9 +791,14 @@
     /*
      * The following is just a sanity check.
      */
-    VGA_GetCursorPos(&nx, &ny);
-    if(nx != x || ny != y)
-      WARN("VGA emulator and text console have become unsynchronized.\n");
+    if(vga_text_console) {
+        CONSOLE_SCREEN_BUFFER_INFO info;
+        GetConsoleScreenBufferInfo( VGA_AlphaConsole(), &info );
+
+        if( info.dwCursorPosition.X != vga_text_x || 
+            info.dwCursorPosition.Y != vga_text_y)
+            WARN("VGA emulator and text console have become unsynchronized.\n");
+    }
 
     LeaveCriticalSection(&vga_lock);
 }
@@ -750,42 +806,34 @@
 void VGA_SetTextAttribute(BYTE attr)
 {
     vga_text_attr = attr;
-    SetConsoleTextAttribute(VGA_AlphaConsole(), attr);
+    if(vga_text_console)
+        SetConsoleTextAttribute(VGA_AlphaConsole(), attr);
 }
 
-BOOL VGA_ClearText(unsigned row1, unsigned col1,
+void VGA_ClearText(unsigned row1, unsigned col1,
                   unsigned row2, unsigned col2,
                   BYTE attr)
 {
-    unsigned width, height, x, y;
-    COORD off;
-    char *dat = VGA_AlphaBuffer();
-    HANDLE con = VGA_AlphaConsole();
-
-    /* return if we fail to get the height and width of the window */
-    if(!VGA_GetAlphaMode(&width, &height))
-        return FALSE;
-
-    TRACE("dat = %p, width = %d, height = %d\n", dat, width, height);
+    unsigned x, y;
 
     EnterCriticalSection(&vga_lock);
 
     for(y=row1; y<=row2; y++) {
-        off.X = col1;
-       off.Y = y;
-       FillConsoleOutputCharacterA(con, ' ', col2-col1+1, off, NULL);
-       FillConsoleOutputAttribute(con, attr, col2-col1+1, off, NULL);
+        if(vga_text_console) {
+            HANDLE con = VGA_AlphaConsole();
+            COORD off;
 
-       for(x=col1; x<=col2; x++) {
-           char *ptr = dat + ((width*y + x) * 2);
-           ptr[0] = ' ';
-           ptr[1] = attr;
-       }
+            off.X = col1;
+            off.Y = y;        
+            FillConsoleOutputCharacterA(con, ' ', col2-col1+1, off, NULL);
+            FillConsoleOutputAttribute(con, attr, col2-col1+1, off, NULL);
+        }
+
+        for(x=col1; x<=col2; x++)
+            VGA_PutCharAt(x, y, ' ', attr);
     }
 
     LeaveCriticalSection(&vga_lock);
-
-    return TRUE;
 }
 
 void VGA_ScrollUpText(unsigned row1, unsigned col1,
@@ -802,20 +850,14 @@
     FIXME("not implemented\n");
 }
 
-BOOL VGA_GetCharacterAtCursor(BYTE *ascii, BYTE *attr)
+void VGA_GetCharacterAtCursor(BYTE *ascii, BYTE *attr)
 {
-    unsigned width, height, x, y;
     char *dat;
 
-    if(!VGA_GetAlphaMode(&width, &height) || !VGA_GetCursorPos(&x, &y))
-        return FALSE;
-
-    dat = VGA_AlphaBuffer() + ((width*y + x) * 2);
+    dat = VGA_AlphaBuffer() + ((vga_text_width * vga_text_y + vga_text_x) * 2);
 
     *ascii = dat[0];
     *attr = dat[1];
-
-    return TRUE;
 }
 
 
@@ -861,26 +903,25 @@
 static void VGA_Poll_Text(void)
 {
     char *dat, *old, *p_line;
-    unsigned int Height,Width,Y,X;
+    unsigned int X, Y;
     CHAR_INFO ch[256]; /* that should suffice for the largest text width */
     COORD siz, off;
     SMALL_RECT dest;
     HANDLE con = VGA_AlphaConsole();
     BOOL linechanged = FALSE; /* video memory area differs from stored copy ? */
 
-    VGA_GetAlphaMode(&Width,&Height);
     dat = VGA_AlphaBuffer();
-    old = textbuf_old; /* pointer to stored video mem copy */
-    siz.X = Width; siz.Y = 1;
+    old = vga_text_old; /* pointer to stored video mem copy */
+    siz.X = vga_text_width; siz.Y = 1;
     off.X = 0; off.Y = 0;
     /* copy from virtual VGA frame buffer to console */
-    for (Y=0; Y<Height; Y++) {
-	linechanged = memcmp(dat, old, Width*2);
+    for (Y=0; Y<vga_text_height; Y++) {
+	linechanged = memcmp(dat, old, vga_text_width*2);
 	if (linechanged)
 	{
 	    /*TRACE("line %d changed\n", Y);*/
 	    p_line = dat;
-            for (X=0; X<Width; X++) {
+            for (X=0; X<vga_text_width; X++) {
                 ch[X].Char.AsciiChar = *p_line++;
                 /* WriteConsoleOutputA doesn't like "dead" chars */
                 if (ch[X].Char.AsciiChar == '\0')
@@ -888,13 +929,13 @@
                 ch[X].Attributes = *p_line++;
             }
             dest.Top=Y; dest.Bottom=Y;
-            dest.Left=0; dest.Right=Width+1;
+            dest.Left=0; dest.Right=vga_text_width+1;
             WriteConsoleOutputA(con, ch, siz, off, &dest);
-	    memcpy(old, dat, Width*2);
+	    memcpy(old, dat, vga_text_width*2);
 	}
 	/* advance to next text line */
-	dat += Width*2;
-	old += Width*2;
+	dat += vga_text_width*2;
+	old += vga_text_width*2;
     }
 }
 
@@ -1009,7 +1050,7 @@
             /* since we don't (yet?) serve DOS VM requests while VGA_Poll is running,
                we need to fake the occurrence of the vertical refresh */
             ret=vga_refresh?0x00:0x0b; /* toggle video RAM and lightpen and VGA refresh bits ! */
-            if (vga_mode_initialized)
+            if (VGA_IsTimerRunning())
                 vga_refresh=0;
             else
                 /* Also fake the occurence of the vertical refresh when no graphic
diff --git a/dlls/winedos/vga.h b/dlls/winedos/vga.h
index e687a7e..2cddec8 100644
--- a/dlls/winedos/vga.h
+++ b/dlls/winedos/vga.h
@@ -27,7 +27,6 @@
 /* graphics mode */
 int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth);
 int VGA_GetMode(unsigned*Height,unsigned*Width,unsigned*Depth);
-void VGA_Exit(void);
 void VGA_SetPalette(PALETTEENTRY*pal,int start,int len);
 void VGA_SetColor16(int reg,int color);
 char VGA_GetColor16(int reg);
@@ -40,15 +39,16 @@
 int  VGA_GetWindowStart();
 
 /* text mode */
-int VGA_SetAlphaMode(unsigned Xres,unsigned Yres);
+void VGA_InitAlphaMode(unsigned*Xres,unsigned*Yres);
+void VGA_SetAlphaMode(unsigned Xres,unsigned Yres);
 BOOL VGA_GetAlphaMode(unsigned*Xres,unsigned*Yres);
 void VGA_SetCursorShape(unsigned char start_options,unsigned char end);
 void VGA_SetCursorPos(unsigned X,unsigned Y);
-BOOL VGA_GetCursorPos(unsigned*X,unsigned*Y);
+void VGA_GetCursorPos(unsigned*X,unsigned*Y);
 void VGA_WriteChars(unsigned X,unsigned Y,unsigned ch,int attr,int count);
 void VGA_PutChar(BYTE ascii);
 void VGA_SetTextAttribute(BYTE attr);
-BOOL VGA_ClearText(unsigned row1, unsigned col1,
+void VGA_ClearText(unsigned row1, unsigned col1,
                   unsigned row2, unsigned col2,
                   BYTE attr);
 void VGA_ScrollUpText(unsigned row1, unsigned col1,
@@ -57,7 +57,7 @@
 void VGA_ScrollDownText(unsigned row1, unsigned col1,
                        unsigned row2, unsigned col2,
                        unsigned lines, BYTE attr);
-BOOL VGA_GetCharacterAtCursor(BYTE *ascii, BYTE *attr);
+void VGA_GetCharacterAtCursor(BYTE *ascii, BYTE *attr);
 
 /* control */
 void VGA_ioport_out(WORD port, BYTE val);