[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