[3/3] Extend VGA write text support to CGA and all 256 color modes

Jeremiah Flerchinger jeremiah.flerchinger at gmail.com
Fri Apr 17 23:22:18 CDT 2009


Made VGA VESA BIOS Interrupt 10 write text support dependent on write
pixel function. Made write pixel function work with all CGA and 256
color modes. Improved color & page param handling for text in graphics
modes.
---
 dlls/winedos/int10.c |   11 +++-----
 dlls/winedos/vga.c   |   70 +++++++++++++++++++++++++++----------------------
 dlls/winedos/vga.h   |    4 +-
 3 files changed, 45 insertions(+), 40 deletions(-)

diff --git a/dlls/winedos/int10.c b/dlls/winedos/int10.c
index 583927d..3a4e836 100644
--- a/dlls/winedos/int10.c
+++ b/dlls/winedos/int10.c
@@ -1113,6 +1113,7 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
            INT10_GetCursorPos(data,BH_reg(context),&col,&row);
            VGA_WriteChars(col, row,
                           AL_reg(context),
+                          BH_reg(context),
                           (AH_reg(context) == 0x09) ? BL_reg(context) : -1,
                           CX_reg(context));
            if (CX_reg(context) > 1)
@@ -1169,12 +1170,8 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
 
     case 0x0c: /* WRITE GRAPHICS PIXEL */
 
-        /* Only supported in CGA mode for now */
-        if(data->VideoMode >= 4 && data->VideoMode <= 6)
-        {
-          VGA_WritePixel(AL_reg(context), BH_reg(context), CX_reg(context), DX_reg(context));
-        }
-        else FIXME("Write pixel not implemented for current mode\n");
+        /* The VGA subsystem will handle modes */
+        VGA_WritePixel(AL_reg(context), BH_reg(context), CX_reg(context), DX_reg(context));
         break;
 
     case 0x0d: /* READ GRAPHICS PIXEL */
@@ -1460,7 +1457,7 @@ void WINAPI DOSVM_PutChar( BYTE ascii )
 
   INT10_InitializeVideoMode( data );
 
-  VGA_PutChar( ascii );
+  VGA_PutChar( ascii, 0, 0xff );
   VGA_GetCursorPos( &xpos, &ypos );
   INT10_SetCursorPos( data, 0, xpos, ypos );
 }
diff --git a/dlls/winedos/vga.c b/dlls/winedos/vga.c
index d077e60..622d24e 100644
--- a/dlls/winedos/vga.c
+++ b/dlls/winedos/vga.c
@@ -166,12 +166,12 @@ const VGA_MODE VGA_modelist[] =
     {0x0004,          CGA, 0xb8000, 40, 25,  8,  8,  320,  200,  2,   4, 1, TRUE},   /* VGA/CGA graphics mode 4 */
     {0x0005,          CGA, 0xb8000, 40, 25,  8,  8,  320,  200,  2,   4, 1, TRUE},   /* VGA/CGA graphics mode 5 */
     {0x0006,          CGA, 0xb8000, 80, 25,  8,  8,  640,  200,  1,   2, 1, TRUE},   /* VGA/CGA graphics mode 6 */
-    {0x0007,         TEXT, 0xb0000, 80, 25,  9, 16,  720,  400,  0,   0, 8, TRUE},   /* VGA text mode 7 */
-    {0x000d,     PLANAR_4, 0xa0000, 40, 25,  8,  8,  320,  200,  4,  16, 8, FALSE},   /* VGA graphics mode 13 */
-    {0x000e,     PLANAR_4, 0xa0000, 80, 25,  8,  8,  640,  200,  4,  16, 4, FALSE},   /* VGA graphics mode 14 */
-    {0x000f, PACKED_PIXEL, 0xa0000, 80, 25,  8, 14,  640,  350,  0,   0, 2, TRUE},   /* VGA graphics mode 15 */
-    {0x0010,     PLANAR_4, 0xa0000, 80, 25,  8, 14,  640,  350,  4,  16, 2, FALSE},   /* VGA graphics mode 16 */
-    {0x0012, PACKED_PIXEL, 0xa0000, 80, 30,  8, 16,  640,  480,  1,   2, 1, TRUE},   /* VGA graphics mode 17 */
+    {0x0007,         TEXT, 0xb0000, 80, 25,  9, 16,  720,  400,  0,   0, 8, TRUE},   /* VGA/MDA text mode 7 */
+    {0x000d,     PLANAR_4, 0xa0000, 40, 25,  8,  8,  320,  200,  4,  16, 8, FALSE},   /* VGA/EGA graphics mode 13 */
+    {0x000e,     PLANAR_4, 0xa0000, 80, 25,  8,  8,  640,  200,  4,  16, 4, FALSE},   /* VGA/EGA graphics mode 14 */
+    {0x000f,     PLANAR_4, 0xa0000, 80, 25,  8, 14,  640,  350,  0,   0, 2, FALSE},   /* VGA/EGA graphics mode 15 - 16 shades grey */
+    {0x0010,     PLANAR_4, 0xa0000, 80, 25,  8, 14,  640,  350,  4,  16, 2, FALSE},   /* VGA/EGA graphics mode 16 */
+    {0x0012,     PLANAR_4, 0xa0000, 80, 30,  8, 16,  640,  480,  1,   2, 1, FALSE},   /* VGA graphics mode 17 - 16 shades grey */
     {0x0012,     PLANAR_4, 0xa0000, 80, 30,  8, 16,  640,  480,  4,  16, 1, FALSE},   /* VGA graphics mode 18 */
     {0x0013, PACKED_PIXEL, 0xa0000, 40, 25,  8,  8,  320,  200,  8, 256, 1, TRUE},   /* VGA graphics mode 19 */
     /* VESA 7-bit modes */
@@ -1245,10 +1245,14 @@ void VGA_WritePixel(unsigned color, unsigned page, unsigned col, unsigned row)
   int bits;
   int pos;
 
+  if (page)
+  {
+    FIXME("VGA_WritePixel only supports first-page writes. \n");
+  }
+  char *data = vga_fb_window_data;
   if (CurrentMode.ModeType == CGA)
   {
     /* Calculate CGA byte offset */
-    char *data = vga_fb_window_data;
     off = row & 1 ? (8 * 1024) : 0;
     off += (80 * (row/2));
     off += col/4;
@@ -1264,6 +1268,10 @@ void VGA_WritePixel(unsigned color, unsigned page, unsigned col, unsigned row)
     bits = color << pos;
     data[off] |= bits;
   }
+  else if(CurrentMode.ModeType == PACKED_PIXEL)
+  {
+    data[row*CurrentMode.Width+col] = color;
+  }
   else
   {
     FIXME("VGA_WritePixel is missing mode %i support. \n", CurrentMode.Mode);
@@ -1400,7 +1408,7 @@ void VGA_GetCursorPos(unsigned*X,unsigned*Y)
     if (Y) *Y = vga_text_y;
 }
 
-static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, int attr)
+static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, unsigned page, int attr)
 {
     int DrawTextHeight;
     RECT rect;
@@ -1410,8 +1418,6 @@ static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, int attr)
     HFONT IBM_hFont;
     LOGFONTA IBM_lFont;
     HFONT ModIBM_hFont;
-    int fgColor;
-    int bgColor;
     char *dat;
     int ih;
     int iw;
@@ -1427,8 +1433,6 @@ static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, int attr)
     else
     {
        dat = vga_fb_window_data;
-       fgColor = attr & 0x0F;
-       bgColor = (attr & 0x70)>>4;
        hDC = CreateCompatibleDC(NULL);
        if (hDC == 0)
        {
@@ -1457,8 +1461,8 @@ static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, int attr)
        }
        SelectObject(hDC, hTempBmp);
        SelectObject(hDC, ModIBM_hFont);
-       SetTextColor(hDC, fgColor<<16); /* set text color 0x00bbggrr */
-       SetBkColor(hDC, bgColor<<16);  /* set text color 0x00bbggrr */
+       SetTextColor(hDC, 0x00ffffff); /* set text color 0x00bbggrr */
+       SetBkColor(hDC, 0x00000000);  /* set text color 0x00bbggrr */
        rect.left = 0;
        rect.top = 0;
        rect.bottom = CurrentMode.CharHeight-1;
@@ -1478,15 +1482,16 @@ static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, int attr)
        {
          for (iw = 0; iw < CurrentMode.CharWidth; iw = iw+1)
          {
-            if (CurrentMode.ModeType == PACKED_PIXEL)
-            {
-               dat[(y+ih)*CurrentMode.Width + (x+iw)] =  (*( pSrcData + iw + ih*CurrentMode.CharWidth )) &  0x000000ff;
-            }
-            else
-            {
-               FIXME("Write '%c' in color %X on %X at (%i,%i) - not yet fully supported in graphic modes.\n", (char)ascii, fgColor, bgColor, x, y);
-               FIXME("Only Packed Pixel, aka Linear, Memory models, such as in mode 19, are supported. \n");
-            }
+           if ( *(pSrcData + iw + ih*CurrentMode.CharWidth) )
+           {
+             /* write pixel of foreground char */
+             VGA_WritePixel(attr & 0x0F, page, x+iw, y+ih);
+           }
+           else
+           {
+             /* write pixel of background char */
+             VGA_WritePixel((attr & 0x70)>>4, page, x+iw, y+ih);
+           }
          }
        }
        DeleteObject(hTempBmp);
@@ -1495,17 +1500,17 @@ static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, int attr)
     }
 }
 
-void VGA_WriteChars(unsigned X,unsigned Y,unsigned ch,int attr,int count)
+void VGA_WriteChars(unsigned X,unsigned Y,unsigned ch,unsigned page,int attr,int count)
 {
     EnterCriticalSection(&vga_lock);
 
     while (count--) 
-        VGA_PutCharAt(X + count, Y, ch, attr);
+        VGA_PutCharAt(X + count, Y, ch, page, attr);
 
     LeaveCriticalSection(&vga_lock);
 }
 
-void VGA_PutChar(BYTE ascii)
+void VGA_PutChar(BYTE ascii,unsigned page,int attr)
 {
     DWORD w;
 
@@ -1516,7 +1521,7 @@ void VGA_PutChar(BYTE ascii)
         if (vga_text_x)
         {
             vga_text_x--;
-            VGA_PutCharAt(vga_text_x, vga_text_y, ' ', 0);
+            VGA_PutCharAt(vga_text_x, vga_text_y, ' ', page, 0);
         }
         break;
 
@@ -1537,7 +1542,10 @@ void VGA_PutChar(BYTE ascii)
         break;
 
     default:
-        VGA_PutCharAt(vga_text_x, vga_text_y, ascii, vga_text_attr);
+        if (attr == 0xff)
+            VGA_PutCharAt(vga_text_x, vga_text_y, ascii, page, vga_text_attr);
+        else
+            VGA_PutCharAt(vga_text_x, vga_text_y, ascii, page, attr);
         vga_text_x++;
     }
 
@@ -1574,7 +1582,7 @@ void VGA_ClearText(unsigned row1, unsigned col1,
 
     for(y=row1; y<=row2; y++)
         for(x=col1; x<=col2; x++)
-            VGA_PutCharAt(x, y, 0x20, attr);
+            VGA_PutCharAt(x, y, 0x20, 0, attr);
 
     LeaveCriticalSection(&vga_lock);
 }
@@ -1600,7 +1608,7 @@ void VGA_ScrollUpText(unsigned row1,  unsigned col1,
      * Fill exposed lines.
      */
     for (y = max(row1, row2 - lines + 1); y <= row2; y++)
-        VGA_WriteChars( col1, y, ' ', attr, col2 - col1 + 1 );
+        VGA_WriteChars( col1, y, ' ', 0, attr, col2 - col1 + 1 );
 
     LeaveCriticalSection(&vga_lock);
 }
@@ -1626,7 +1634,7 @@ void VGA_ScrollDownText(unsigned row1,  unsigned col1,
      * Fill exposed lines.
      */
     for (y = row1; y <= min(row1 + lines - 1, row2); y++)
-        VGA_WriteChars( col1, y, ' ', attr, col2 - col1 + 1 );
+        VGA_WriteChars( col1, y, ' ', 0, attr, col2 - col1 + 1 );
 
     LeaveCriticalSection(&vga_lock);
 }
diff --git a/dlls/winedos/vga.h b/dlls/winedos/vga.h
index 559aa57..509b17d 100644
--- a/dlls/winedos/vga.h
+++ b/dlls/winedos/vga.h
@@ -78,8 +78,8 @@ BOOL VGA_GetAlphaMode(unsigned*Xres,unsigned*Yres);
 void VGA_SetCursorShape(unsigned char start_options,unsigned char end);
 void VGA_SetCursorPos(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_WriteChars(unsigned X,unsigned Y,unsigned ch,unsigned page,int attr,int count);
+void VGA_PutChar(BYTE ascii,unsigned page,int attr);
 void VGA_ClearText(unsigned row1, unsigned col1,
                   unsigned row2, unsigned col2,
                   BYTE attr);
-- 
1.5.6.3




More information about the wine-patches mailing list