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 */
{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 */

View File

@ -53,6 +53,12 @@ static BOOL vga_retrace_horizontal;
#define VGA_WINDOW_SIZE (64 * 1024)
#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
@ -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.
@ -158,6 +166,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,7 +730,13 @@ static void WINAPI VGA_DoSetMode(ULONG_PTR arg)
lpddraw=NULL;
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);
}
if (res != S_OK) {
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;
}
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;
@ -1251,10 +1291,34 @@ static void VGA_Poll_Graphics(void)
if (vga_fb_window != -1)
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];