Peter Dons Tychsen : winedos: Add support for decoding and displaying the 4 bit CGA framebuffer.
Alexandre Julliard
julliard at winehq.org
Mon Nov 10 07:43:53 CST 2008
Module: wine
Branch: master
Commit: e0b91a7aa78cdfe6b3fddb42d4d23a235ad977c1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e0b91a7aa78cdfe6b3fddb42d4d23a235ad977c1
Author: Peter Dons Tychsen <donpedro at tdcadsl.dk>
Date: Sat Nov 8 16:21:03 2008 +0100
winedos: Add support for decoding and displaying the 4 bit CGA framebuffer.
---
dlls/winedos/int10.c | 2 +-
dlls/winedos/vga.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 73 insertions(+), 9 deletions(-)
diff --git a/dlls/winedos/int10.c b/dlls/winedos/int10.c
index 952212f..c1ec98b 100644
--- a/dlls/winedos/int10.c
+++ b/dlls/winedos/int10.c
@@ -171,7 +171,7 @@ static const INT10_MODE INT10_modelist[] =
{0x0001, TEXT, 40, 25, 9, 16, 360, 400, 0, 16, 8, TRUE}, /* VGA text mode 1 */
{0x0002, TEXT, 80, 25, 9, 16, 360, 400, 0, 16, 8, TRUE}, /* VGA text mode 2 */
{0x0003, TEXT, 80, 25, 9, 16, 360, 400, 0, 16, 8, TRUE}, /* VGA text mode 3 */
- {0x0004, GRAPHIC, 40, 25, 8, 8, 320, 200, 2, 4, 1, FALSE}, /* VGA graphics mode 4 */
+ {0x0004, GRAPHIC, 40, 25, 8, 8, 320, 200, 2, 4, 1, TRUE}, /* VGA graphics mode 4 */
{0x0005, GRAPHIC, 40, 25, 8, 8, 320, 200, 2, 4, 1, FALSE}, /* VGA graphics mode 5 */
{0x0006, GRAPHIC, 80, 25, 8, 8, 640, 200, 1, 2, 1, FALSE}, /* VGA graphics mode 6 */
{0x0007, TEXT, 80, 25, 9, 16, 720, 400, 0, 0, 8, FALSE}, /* VGA text mode 7 - FIXME bad default address */
diff --git a/dlls/winedos/vga.c b/dlls/winedos/vga.c
index a5298e0..6a94d32 100644
--- a/dlls/winedos/vga.c
+++ b/dlls/winedos/vga.c
@@ -54,6 +54,12 @@ static BOOL vga_retrace_horizontal;
#define VGA_WINDOW_START ((char *)0xa0000)
/*
+ * Size and location of CGA controller window to framebuffer.
+ */
+#define CGA_WINDOW_SIZE (32 * 1024)
+#define CGA_WINDOW_START ((char *)0xb8000)
+
+/*
* VGA controller memory is emulated using linear framebuffer.
* This frambuffer also acts as an interface
* between VGA controller emulation and DirectDraw.
@@ -91,6 +97,8 @@ static int vga_fb_offset;
static int vga_fb_size = 0;
static char *vga_fb_data = 0;
static int vga_fb_window = 0;
+static int vga_fb_window_size;
+static char *vga_fb_window_data;
/*
* VGA text mode data.
@@ -159,6 +167,16 @@ static void CALLBACK VGA_Poll( LPVOID arg, DWORD low, DWORD high );
static HWND vga_hwnd = NULL;
/*
+ * CGA palette 1
+ */
+static PALETTEENTRY cga_palette1[] = {
+ {0x00, 0x00, 0x00}, /* 0 - Black */
+ {0x00, 0x80, 0x80}, /* 1 - Cyan */
+ {0x80, 0x00, 0x80}, /* 2 - Magenta */
+ {0xFF, 0xFF, 0xFF} /* 3 - White */
+};
+
+/*
* VGA Palette Registers, in actual 18 bit color
* port 3C0H - 6 bit rgbRGB format
*
@@ -627,20 +645,20 @@ typedef struct {
*/
static void VGA_SyncWindow( BOOL target_is_fb )
{
- int size = VGA_WINDOW_SIZE;
+ int size = vga_fb_window_size;
/* Window does not overlap framebuffer. */
if (vga_fb_window >= vga_fb_size)
return;
/* Check if window overlaps framebuffer only partially. */
- if (vga_fb_size - vga_fb_window < VGA_WINDOW_SIZE)
+ if (vga_fb_size - vga_fb_window < vga_fb_window_size)
size = vga_fb_size - vga_fb_window;
if (target_is_fb)
- memmove( vga_fb_data + vga_fb_window, VGA_WINDOW_START, size );
+ memmove( vga_fb_data + vga_fb_window, vga_fb_window_data, size );
else
- memmove( VGA_WINDOW_START, vga_fb_data + vga_fb_window, size );
+ memmove( vga_fb_window_data, vga_fb_data + vga_fb_window, size );
}
@@ -712,9 +730,15 @@ static void WINAPI VGA_DoSetMode(ULONG_PTR arg)
lpddraw=NULL;
return;
}
- res=IDirectDrawPalette_SetEntries(lpddpal,0,0,256,vga_def_palette);
+
+ if(vga_fb_depth == 2){
+ res=IDirectDrawPalette_SetEntries(lpddpal,0,0,4,cga_palette1);
+ }
+ else{
+ res=IDirectDrawPalette_SetEntries(lpddpal,0,0,256,vga_def_palette);
+ }
if (res != S_OK) {
- ERR("Could not set default palette entries (res = 0x%x)\n", res);
+ ERR("Could not set default palette entries (res = 0x%x)\n", res);
}
memset(&sdesc,0,sizeof(sdesc));
@@ -766,7 +790,23 @@ int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth)
par.Yres = 480;
}
- VGA_SetWindowStart((Depth < 8) ? -1 : 0);
+ /* Setup window */
+ if(vga_fb_depth >= 8)
+ {
+ vga_fb_window_data = VGA_WINDOW_START;
+ vga_fb_window_size = VGA_WINDOW_SIZE;
+ }
+ else
+ {
+ vga_fb_window_data = CGA_WINDOW_START;
+ vga_fb_window_size = CGA_WINDOW_SIZE;
+ }
+
+ /* Clean the HW buffer */
+ memset(vga_fb_window_data, 0x00, vga_fb_window_size);
+
+ /* Reset window start */
+ VGA_SetWindowStart(0);
par.Depth = (Depth < 8) ? 8 : Depth;
@@ -1252,9 +1292,33 @@ static void VGA_Poll_Graphics(void)
VGA_SyncWindow( TRUE );
/*
+ * CGA framebuffer
+ */
+ if(vga_fb_depth == 2 && vga_fb_width == 320 && vga_fb_height == 200){
+ WORD off = 0;
+ BYTE bits = 6;
+ BYTE value;
+ /* Go thru rows */
+ for(Y=0; Y<vga_fb_height; Y++, surf+=(Pitch*2)){
+ for(X=0; X<vga_fb_width; X++){
+ off = Y & 1 ? (8 * 1024) : 0;
+ off += (80 * (Y/2));
+ off += X/4;
+ value = (dat[off] >> bits) & 0x3;
+ surf[(X*2)] = value;
+ surf[(X*2)+1] = value;
+ surf[(X*2)+Pitch] = value;
+ surf[(X*2)+Pitch+1] = value;
+ bits -= 2;
+ bits &= 7;
+ }
+ }
+ }
+
+ /*
* Double VGA framebuffer (320x200 -> 640x400), if needed.
*/
- if(Height >= 2 * vga_fb_height && Width >= 2 * vga_fb_width && bpp == 1)
+ else if(Height >= 2 * vga_fb_height && Width >= 2 * vga_fb_width && bpp == 1)
for (Y=0; Y<vga_fb_height; Y++,surf+=Pitch*2,dat+=vga_fb_pitch)
for (X=0; X<vga_fb_width; X++) {
BYTE value = dat[X];
More information about the wine-cvs
mailing list