winedos: Add support for decoding and displaying the 4 bit CGA framebuffer.

This commit is contained in:
Peter Dons Tychsen 2008-11-08 16:21:03 +01:00 committed by Alexandre Julliard
parent f5b8bad2aa
commit e0b91a7aa7
2 changed files with 73 additions and 9 deletions

View File

@ -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 */ {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 */ {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 */ {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 */ {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 */ {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 */ {0x0007, TEXT, 80, 25, 9, 16, 720, 400, 0, 0, 8, FALSE}, /* VGA text mode 7 - FIXME bad default address */

View File

@ -53,6 +53,12 @@ static BOOL vga_retrace_horizontal;
#define VGA_WINDOW_SIZE (64 * 1024) #define VGA_WINDOW_SIZE (64 * 1024)
#define VGA_WINDOW_START ((char *)0xa0000) #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. * VGA controller memory is emulated using linear framebuffer.
* This frambuffer also acts as an interface * This frambuffer also acts as an interface
@ -91,6 +97,8 @@ static int vga_fb_offset;
static int vga_fb_size = 0; static int vga_fb_size = 0;
static char *vga_fb_data = 0; static char *vga_fb_data = 0;
static int vga_fb_window = 0; static int vga_fb_window = 0;
static int vga_fb_window_size;
static char *vga_fb_window_data;
/* /*
* VGA text mode data. * VGA text mode data.
@ -158,6 +166,16 @@ static void CALLBACK VGA_Poll( LPVOID arg, DWORD low, DWORD high );
static HWND vga_hwnd = NULL; 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 * VGA Palette Registers, in actual 18 bit color
* port 3C0H - 6 bit rgbRGB format * port 3C0H - 6 bit rgbRGB format
@ -627,20 +645,20 @@ typedef struct {
*/ */
static void VGA_SyncWindow( BOOL target_is_fb ) static void VGA_SyncWindow( BOOL target_is_fb )
{ {
int size = VGA_WINDOW_SIZE; int size = vga_fb_window_size;
/* Window does not overlap framebuffer. */ /* Window does not overlap framebuffer. */
if (vga_fb_window >= vga_fb_size) if (vga_fb_window >= vga_fb_size)
return; return;
/* Check if window overlaps framebuffer only partially. */ /* 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; size = vga_fb_size - vga_fb_window;
if (target_is_fb) 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 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,7 +730,13 @@ static void WINAPI VGA_DoSetMode(ULONG_PTR arg)
lpddraw=NULL; lpddraw=NULL;
return; return;
} }
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); res=IDirectDrawPalette_SetEntries(lpddpal,0,0,256,vga_def_palette);
}
if (res != S_OK) { 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);
} }
@ -766,7 +790,23 @@ int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth)
par.Yres = 480; 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; par.Depth = (Depth < 8) ? 8 : Depth;
@ -1251,10 +1291,34 @@ static void VGA_Poll_Graphics(void)
if (vga_fb_window != -1) if (vga_fb_window != -1)
VGA_SyncWindow( TRUE ); 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. * 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 (Y=0; Y<vga_fb_height; Y++,surf+=Pitch*2,dat+=vga_fb_pitch)
for (X=0; X<vga_fb_width; X++) { for (X=0; X<vga_fb_width; X++) {
BYTE value = dat[X]; BYTE value = dat[X];