Add support for moving VGA controller window in framebuffer using SVGA
interrupts. Detect correctly color plane modes and linear modes, including Mode-X. Moved VESA interrupts into separate function and implemented few more stubs.
This commit is contained in:
parent
c963d90f50
commit
77c239979a
|
@ -82,17 +82,17 @@ static void BIOS_SetCursorPos(BIOSDATA*data,unsigned page,unsigned X,unsigned Y)
|
|||
* Added additional vga graphic support - 3/99
|
||||
*/
|
||||
|
||||
void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
|
||||
static void DOSVM_Int10Handler_VESA( CONTEXT86 *context )
|
||||
{
|
||||
BIOSDATA *data = DOSMEM_BiosData();
|
||||
|
||||
if(AH_reg(context) == 0x4F) { /* VESA functions */
|
||||
switch(AL_reg(context)) {
|
||||
|
||||
case 0x00: /* GET SuperVGA INFORMATION */
|
||||
TRACE("VESA GET SuperVGA INFORMATION\n");
|
||||
memcpy(CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edi),
|
||||
DOSMEM_BiosSys()+DOSMEM_GetBiosSysStructOffset(OFF_VESAINFO),sizeof(VESAINFO));
|
||||
DOSMEM_BiosSys()+DOSMEM_GetBiosSysStructOffset(OFF_VESAINFO),
|
||||
sizeof(VESAINFO));
|
||||
AL_reg(context) = 0x4f;
|
||||
AH_reg(context) = 0x00; /* 0x00 = successful 0x01 = failed */
|
||||
break;
|
||||
|
@ -102,6 +102,7 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
|
|||
AL_reg(context) = 0x4f;
|
||||
AH_reg(context) = 0x01; /* 0x00 = successful 0x01 = failed */
|
||||
break;
|
||||
|
||||
case 0x02: /* SET SuperVGA VIDEO MODE */
|
||||
switch(BX_reg(context)) {
|
||||
/* OEM Video Modes */
|
||||
|
@ -242,59 +243,100 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
|
|||
AL_reg(context) = 0x4f;
|
||||
AH_reg(context) = 0x00;
|
||||
break;
|
||||
|
||||
case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
|
||||
AL_reg(context) = 0x4f;
|
||||
AH_reg(context) = 0x00; /* should probly check if a vesa mode has ben set */
|
||||
BX_reg(context) = data->VideoMode;
|
||||
break;
|
||||
|
||||
case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
|
||||
ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
|
||||
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
|
||||
/* maybe we should do this instead ? */
|
||||
/* AH_reg(context = 0x01; not implemented so just fail */
|
||||
break;
|
||||
|
||||
case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
|
||||
ERR("VESA CPU VIDEO MEMORY CONTROL\n");
|
||||
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
|
||||
/* maybe we should do this instead ? */
|
||||
/* AH_reg(context = 0x001; not implemented so just fail */
|
||||
/*
|
||||
* This subfunction supports only Window A (BL_reg == 0) and
|
||||
* is assumes that window granularity is 64k.
|
||||
*/
|
||||
switch(BH_reg(context)) {
|
||||
case 0x00: /* select video memory window */
|
||||
AL_reg(context) = 0x4f; /* function supported */
|
||||
if(BL_reg(context) == 0) {
|
||||
VGA_SetWindowStart(DX_reg(context) * 64 * 1024);
|
||||
AH_reg(context) = 0x00; /* status: successful */
|
||||
} else
|
||||
AH_reg(context) = 0x01; /* status: failed */
|
||||
break;
|
||||
case 0x01: /* get video memory window */
|
||||
AL_reg(context) = 0x4f; /* function supported */
|
||||
if(BL_reg(context) == 0) {
|
||||
DX_reg(context) = VGA_GetWindowStart() / 64 / 1024;
|
||||
AH_reg(context) = 0x00; /* status: successful */
|
||||
} else
|
||||
AH_reg(context) = 0x01; /* status: failed */
|
||||
break;
|
||||
default:
|
||||
INT_BARF( context, 0x10 );
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
|
||||
ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
|
||||
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
|
||||
/* maybe we should do this instead ? */
|
||||
/* AH_reg(context = 0x001; not implemented so just fail */
|
||||
break;
|
||||
|
||||
case 0x07: /* GET/SET DISPLAY START */
|
||||
ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
|
||||
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
|
||||
/* maybe we should do this instead ? */
|
||||
/* AH_reg(context = 0x001; not implemented so just fail */
|
||||
break;
|
||||
|
||||
case 0x08: /* GET/SET DAC PALETTE CONTROL */
|
||||
ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
|
||||
/* AL_reg(context) = 0x4f; = supported so not set since not implemented */
|
||||
/* maybe we should do this instead ? */
|
||||
/* AH_reg(context = 0x001; not implemented so just fail */
|
||||
break;
|
||||
|
||||
case 0x09: /* SET PALETTE ENTRIES */
|
||||
FIXME("VESA Set palette entries - not implemented\n");
|
||||
break;
|
||||
|
||||
case 0x0a: /* GET PROTECTED-MODE CODE */
|
||||
FIXME("VESA Get protected-mode code - not implemented\n");
|
||||
break;
|
||||
|
||||
case 0x10: /* Display Power Management Extensions */
|
||||
FIXME("VESA Display Power Management Extensions - not implemented\n");
|
||||
break;
|
||||
|
||||
case 0xef: /* get video mode for hercules-compatibles */
|
||||
/* There's no reason to really support this */
|
||||
/* is there?....................(A.C.) */
|
||||
TRACE("Just report the video not hercules compatible\n");
|
||||
DX_reg(context) = 0xffff;
|
||||
break;
|
||||
|
||||
case 0xff: /* Turn VESA ON/OFF */
|
||||
/* i dont know what to do */
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
|
||||
void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
|
||||
{
|
||||
BIOSDATA *data = DOSMEM_BiosData();
|
||||
|
||||
switch(AH_reg(context)) {
|
||||
|
||||
|
@ -364,7 +406,10 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
|
|||
break;
|
||||
|
||||
case 0x01: /* SET CURSOR SHAPE */
|
||||
TRACE("Set Cursor Shape start %d end %d options %d\n", CH_reg(context) & 0x1f, CL_reg(context) & 0x1f, CH_reg(context) & 0xe0);
|
||||
TRACE("Set Cursor Shape start %d end %d options %d\n",
|
||||
CH_reg(context) & 0x1f,
|
||||
CL_reg(context) & 0x1f,
|
||||
CH_reg(context) & 0xe0);
|
||||
data->VideoCursorType = CX_reg(context); /* direct copy */
|
||||
VGA_SetCursorShape(CH_reg(context), CL_reg(context));
|
||||
break;
|
||||
|
@ -757,11 +802,15 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
|
|||
TRACE("Just report the video not hercules compatible\n");
|
||||
DX_reg(context) = 0xffff;
|
||||
break;
|
||||
|
||||
case 0x4f: /* VESA */
|
||||
DOSVM_Int10Handler_VESA(context);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unknown - 0x%x\n", AH_reg(context));
|
||||
INT_BARF( context, 0x10 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void scroll_window(int direction, char lines, char row1,
|
||||
|
|
|
@ -62,6 +62,11 @@ static HANDLE poll_timer;
|
|||
* VGA framebuffers are always larger than display size and
|
||||
* SVGA framebuffers may also be.
|
||||
* vga_fb_data: Pointer to framebuffer start.
|
||||
* vga_fb_window: Offset of 64k window 0xa0000 in bytes from framebuffer start.
|
||||
* This value is >= 0, if mode uses linear framebuffer and
|
||||
* -1, if mode uses color planes. This value is fixed
|
||||
* in all modes except 0x13 (256 color VGA) where
|
||||
* 0 means normal mode and -1 means Mode-X (unchained mode).
|
||||
*/
|
||||
static int vga_fb_width;
|
||||
static int vga_fb_height;
|
||||
|
@ -70,6 +75,7 @@ static int vga_fb_pitch;
|
|||
static int vga_fb_offset;
|
||||
static int vga_fb_size = 0;
|
||||
static void *vga_fb_data = 0;
|
||||
static int vga_fb_window = 0;
|
||||
|
||||
static BYTE vga_text_attr;
|
||||
static char *textbuf_old = NULL;
|
||||
|
@ -400,6 +406,8 @@ int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth)
|
|||
par.Yres = 480;
|
||||
}
|
||||
|
||||
VGA_SetWindowStart((Depth < 8) ? -1 : 0);
|
||||
|
||||
par.Depth = (Depth < 8) ? 8 : Depth;
|
||||
|
||||
vga_mode_initialized = TRUE;
|
||||
|
@ -508,6 +516,38 @@ void VGA_Unlock(void)
|
|||
IDirectDrawSurface_Unlock(lpddsurf,sdesc.lpSurface);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set start of 64k window at 0xa0000 in bytes.
|
||||
* If value is -1, initialize color plane support.
|
||||
* If value is >= 0, window contains direct copy of framebuffer.
|
||||
*/
|
||||
void VGA_SetWindowStart(int start)
|
||||
{
|
||||
if(start == vga_fb_window)
|
||||
return;
|
||||
|
||||
if(vga_fb_window == -1)
|
||||
FIXME("Remove VGA memory emulation.\n");
|
||||
else
|
||||
memmove(vga_fb_data + vga_fb_window, DOSMEM_MapDosToLinear(0xa0000), 64 * 1024);
|
||||
|
||||
vga_fb_window = start;
|
||||
|
||||
if(vga_fb_window == -1)
|
||||
FIXME("Install VGA memory emulation.\n");
|
||||
else
|
||||
memmove(DOSMEM_MapDosToLinear(0xa0000), vga_fb_data + vga_fb_window, 64 * 1024);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get start of 64k window at 0xa0000 in bytes.
|
||||
* Value is -1 in color plane modes.
|
||||
*/
|
||||
int VGA_GetWindowStart()
|
||||
{
|
||||
return vga_fb_window;
|
||||
}
|
||||
|
||||
/*** TEXT MODE ***/
|
||||
|
||||
/* prepare the text mode video memory copy that is used to only
|
||||
|
@ -770,24 +810,6 @@ void VGA_GetCharacterAtCursor(BYTE *ascii, BYTE *attr)
|
|||
|
||||
/*** CONTROL ***/
|
||||
|
||||
/*
|
||||
* Copy part of VGA framebuffer to VGA window.
|
||||
*/
|
||||
static void VGA_CopyFrameToWindow(void)
|
||||
{
|
||||
/* FIXME: add implementation */
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy contents of VGA window to VGA framebuffer.
|
||||
*/
|
||||
static void VGA_CopyWindowToFrame(void)
|
||||
{
|
||||
/* FIXME: fix implementation */
|
||||
char *dat = DOSMEM_MapDosToLinear(0xa0000);
|
||||
memmove(vga_fb_data, dat, 65536);
|
||||
}
|
||||
|
||||
/* FIXME: optimize by doing this only if the data has actually changed
|
||||
* (in a way similar to DIBSection, perhaps) */
|
||||
static void VGA_Poll_Graphics(void)
|
||||
|
@ -803,7 +825,8 @@ static void VGA_Poll_Graphics(void)
|
|||
/*
|
||||
* Synchronize framebuffer contents.
|
||||
*/
|
||||
VGA_CopyWindowToFrame();
|
||||
if(vga_fb_window != -1)
|
||||
memmove(vga_fb_data + vga_fb_window, DOSMEM_MapDosToLinear(0xa0000), 64 * 1024);
|
||||
|
||||
/*
|
||||
* Double VGA framebuffer (320x200 -> 640x400), if needed.
|
||||
|
@ -897,6 +920,19 @@ void VGA_ioport_out( WORD port, BYTE val )
|
|||
vga_index_3c4 = val;
|
||||
break;
|
||||
case 0x3c5:
|
||||
switch(vga_index_3c4) {
|
||||
case 0x04: /* Sequencer: Memory Mode Register */
|
||||
if(vga_fb_depth == 8)
|
||||
VGA_SetWindowStart((val & 8) ? 0 : -1);
|
||||
else
|
||||
FIXME("Memory Mode Register not supported in this mode.\n");
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported index, register 0x3c4: 0x%02x (value 0x%02x)\n",
|
||||
vga_index_3c4, val);
|
||||
}
|
||||
break;
|
||||
|
||||
FIXME("Unsupported index, register 0x3c4: 0x%02x (value 0x%02x)\n",
|
||||
vga_index_3c4, val);
|
||||
break;
|
||||
|
@ -938,9 +974,14 @@ BYTE VGA_ioport_in( WORD port )
|
|||
vga_index_3c0);
|
||||
return 0xff;
|
||||
case 0x3c5:
|
||||
switch(vga_index_3c4) {
|
||||
case 0x04: /* Sequencer: Memory Mode Register */
|
||||
return (VGA_GetWindowStart() == -1) ? 0xf7 : 0xff;
|
||||
default:
|
||||
FIXME("Unsupported index, register 0x3c4: 0x%02x\n",
|
||||
vga_index_3c4);
|
||||
return 0xff;
|
||||
}
|
||||
case 0x3cf:
|
||||
FIXME("Unsupported index, register 0x3ce: 0x%02x\n",
|
||||
vga_index_3ce);
|
||||
|
|
|
@ -36,6 +36,8 @@ void VGA_Get16Palette(char *Table);
|
|||
void VGA_SetQuadPalette(RGBQUAD*color,int start,int len);
|
||||
LPSTR VGA_Lock(unsigned*Pitch,unsigned*Height,unsigned*Width,unsigned*Depth);
|
||||
void VGA_Unlock(void);
|
||||
void VGA_SetWindowStart(int start);
|
||||
int VGA_GetWindowStart();
|
||||
|
||||
/* text mode */
|
||||
int VGA_SetAlphaMode(unsigned Xres,unsigned Yres);
|
||||
|
|
Loading…
Reference in New Issue