aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2024-02-01 23:21:30 +0100
committerJaroslav Hensl <jara@hensl.cz>2024-02-01 23:21:30 +0100
commitc8fa3c1ff1a18a6013d927e4b14f82bae343adbb (patch)
tree6f997132c8c7d65952a56d57c948a8a481c1ab23
parentcf7b049839923f86fed97cfe7d8c17952a3fe79a (diff)
downloadvmdisp9x-c8fa3c1ff1a18a6013d927e4b14f82bae343adbb.tar.gz
driver code refactoring / PART2: vboxvga+qemu code
-rw-r--r--3d_accel.h39
-rw-r--r--init.c163
-rw-r--r--init_qemu.c2
-rw-r--r--init_svga.c2
-rw-r--r--makefile96
-rw-r--r--minidrv.h5
-rw-r--r--modes.c86
-rw-r--r--modes_qemu.c2
-rw-r--r--pm16_calls.c105
-rw-r--r--scrsw.c16
-rw-r--r--vmdisp9x.inf4
-rw-r--r--vxd.h3
-rw-r--r--vxd_fbhda.c4
-rw-r--r--vxd_main.c180
-rw-r--r--vxd_strings.h8
-rw-r--r--vxd_vbe.c321
-rw-r--r--vxd_vbe_qemu.c2
-rw-r--r--vxd_vdd.c46
-rw-r--r--vxd_vdd.h24
-rw-r--r--vxd_vdd_list.h4
20 files changed, 790 insertions, 322 deletions
diff --git a/3d_accel.h b/3d_accel.h
index b7e3c5a..d61a95c 100644
--- a/3d_accel.h
+++ b/3d_accel.h
@@ -63,8 +63,10 @@ THE SOFTWARE.
#define OP_VBE_VALID 0x3000 /* VXD, DRV */
#define OP_VBE_SETMODE 0x3001 /* DRV */
#define OP_VBE_VALIDMODE 0x3002 /* DRV */
-#define OP_VBE_HW_ENABLE 0x3003 /* DRV */
-#define OP_VBE_HW_DISABLE 0x3004 /* DRV */
+
+#define OP_VESA_VALID 0x4000 /* VXD, DRV */
+#define OP_VESA_SETMODE 0x4001 /* DRV */
+#define OP_VESA_VALIDMODE 0x4002 /* DRV */
#define OP_MOUSE_LOAD 0x1F00 /* DRV */
#define OP_MOUSE_MOVE 0x1F01 /* DRV */
@@ -141,6 +143,9 @@ void mouse_load(void FBPTR mouse_data);
void mouse_move(DWORD x, DWORD y);
void mouse_reset();
+/*
+ * VMWare SVGA-II API
+ */
#ifdef SVGA
typedef struct SVGA_region_info
@@ -268,6 +273,36 @@ SVGA_OT_info_entry_t *SVGA_OT_setup();
#endif /* SVGA */
+/*
+ * Bochs VBE Extensions API
+ */
+#ifdef VBE
+
+BOOL VBE_init_hw(); /* internal for VXD only */
+
+void VBE_HW_enable();
+void VBE_HW_disable();
+BOOL VBE_valid();
+BOOL VBE_validmode(DWORD w, DWORD h, DWORD bpp);
+BOOL VBE_setmode(DWORD w, DWORD h, DWORD bpp);
+
+#endif /* VBE */
+
+/*
+ * VESA Video API
+ */
+#ifdef VESA
+
+BOOL VESA_init_hw(); /* internal for VXD only */
+
+void VESA_HW_enable();
+void VESA_HW_disable();
+BOOL VESA_valid();
+BOOL VESA_validmode(DWORD w, DWORD h, DWORD bpp);
+BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp);
+
+#endif
+
#pragma pack(pop)
#endif /* __3D_ACCEL_H__ */
diff --git a/init.c b/init.c
index 8a66f1e..72d304d 100644
--- a/init.c
+++ b/init.c
@@ -47,10 +47,6 @@ WORD wPalettized = 0; /* Non-zero if palettized. */
WORD OurVMHandle = 0; /* The current VM's ID. */
DWORD VDDEntryPoint = 0; /* The VDD entry point. */
-#ifdef QEMU
-DWORD ConfigMGEntryPoint = 0; /* The configuration manager entry point. */
-DWORD LfbBase = 0; /* The physical base address of the linear framebuffer. */
-#endif
/* On Entry:
* EAX = Function code (VDD_GET_DISPLAY_CONFIG)
@@ -79,66 +75,10 @@ extern DWORD CallVDDGetDispConf( WORD Function, WORD wDInfSize, LPVOID pDInf );
*/
#pragma code_seg( _INIT )
-#ifdef QEMU
-/* Get the first logical configuration for a devnode.
- */
-CONFIGRET static _near _cdecl CM_Get_First_Log_Conf(
- PLOG_CONF plcLogConf,
- DEVNODE dnDevNode,
- ULONG ulFlags)
-{
- WORD wRc = 0;
-
- _asm { mov eax, 01Ah }; /* CM_GET_FIRST_LOG_CONF */
- _asm { call ConfigMGEntryPoint };
- _asm { mov wRc, ax };
-
- return( wRc );
-}
-
-/* Get the next resource descriptor of a given type.
- */
-CONFIGRET static _near _cdecl CM_Get_Next_Res_Des(
- PRES_DES prdResDes,
- RES_DES CurrentResDesOrLogConf,
- RESOURCEID ForResource,
- PRESOURCEID pResourceID,
- ULONG ulFlags)
-{
- WORD wRc = 0;
-
- _asm { mov eax, 01Fh }; /* CM_GET_NEXT_RES_DES */
- _asm { call ConfigMGEntryPoint };
- _asm { mov wRc, ax };
-
- return( wRc );
-}
-
-/* Get the data for a resource descriptor.
-*/
-CONFIGRET static _near _cdecl CM_Get_Res_Des_Data(
- RES_DES rdResDes,
- PFARVOID Buffer,
- ULONG BufferLen,
- ULONG ulFlags)
-{
- WORD wRc = 0;
-
- _asm { mov eax, 022h }; /* CM_GET_RES_DES_DATA */
- _asm { call ConfigMGEntryPoint };
- _asm { mov wRc, ax };
-
- return( wRc );
-}
-#endif
/* Read the display settings from SYSTEM.INI or Registry.
*/
-#ifdef QEMU
-DEVNODE ReadDisplayConfig( void )
-#else
void ReadDisplayConfig( void )
-#endif
{
WORD wX, wY;
UINT bIgnoreRegistry;
@@ -164,29 +104,6 @@ void ReadDisplayConfig( void )
bIgnoreRegistry = GetPrivateProfileInt( "display", "IgnoreRegistry", 0, "system.ini" );
-#ifdef QEMU
- dwRc = CallVDDGetDispConf( VDD_GET_DISPLAY_CONFIG, sizeof( DispInfo ), &DispInfo );
- if( (dwRc != VDD_GET_DISPLAY_CONFIG) && !dwRc ) {
- devNode = (DEVNODE)DispInfo.diDevNodeHandle;
-
- /* Call succeeded, use the data. */
- if (!bIgnoreRegistry)
- {
- wScrX = DispInfo.diXRes;
- wScrY = DispInfo.diYRes;
- wBpp = DispInfo.diBpp;
-
- dbg_printf( "Registry: %ux%u %ubpp %udpi\n", DispInfo.diXRes, DispInfo.diYRes, DispInfo.diBpp, DispInfo.diDPI );
-
- /* DPI might not be set, careful. */
- if( DispInfo.diDPI )
- wDpi = DispInfo.diDPI;
- }
- } else {
- dbg_printf( "VDD_GET_DISPLAY_CONFIG failed, dwRc=%lX\n",dwRc );
- devNode = 0;
- }
-#else
if( !bIgnoreRegistry ) {
DISPLAYINFO DispInfo;
DWORD dwRc;
@@ -207,7 +124,6 @@ void ReadDisplayConfig( void )
dbg_printf( "VDD_GET_DISPLAY_CONFIG failed, dwRc=%lX\n",dwRc );
}
}
-#endif
mode.xRes = wScrX;
mode.yRes = wScrY;
@@ -229,10 +145,6 @@ void ReadDisplayConfig( void )
wPalettized = GetPrivateProfileInt( "display", "palettized", 1, "system.ini" );
else
wPalettized = 0;
-
-#ifdef QEMU
- return( devNode );
-#endif
}
#define VDD_ID 10 /* Virtual Display Driver ID. */
@@ -259,80 +171,6 @@ extern char __based( __segname( "_TEXT" ) ) *pText;
#pragma aux DriverInit parm [cx] [di] [es si]
-#ifdef QEMU
-UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
-{
- DEVNODE devNode;
-
- /* Lock the code segment. */
- GlobalSmartPageLock( (__segment)pText );
-
- /* Query the entry point of the Virtual Display Device. */
- VDDEntryPoint = (DWORD)int_2F_GetEP( 0x1684, VDD_ID );
-
- /* Obtain the "magic number" needed for VDD calls. */
- OurVMHandle = int_2F_GetVMID( 0x1683 );
-
- dbg_printf( "DriverInit: VDDEntryPoint=%WP, OurVMHandle=%x\n", VDDEntryPoint, OurVMHandle );
-
- /* Read the display configuration before doing anything else. */
- LfbBase = 0;
- devNode = ReadDisplayConfig();
-
- /* Use the Configuration Manager to locate the base address of the linear framebuffer. */
- if( devNode ) {
- RES_DES rd;
-
- ConfigMGEntryPoint = (DWORD)int_2F_GetEP( 0x1684, CONFIGMG_ID );
-
- if( CM_Get_First_Log_Conf( &rd, devNode, ALLOC_LOG_CONF ) == CR_SUCCESS ) {
- ULONG cbAllocMax = 0;
-
- /* Take the largest physical memory range in use by this device
- * and store it into LfbBase. */
- while( CM_Get_Next_Res_Des( &rd, rd, ResType_Mem, NULL, 0 ) == CR_SUCCESS ) {
-
- /* Experimentally, no MEM_RES was found to be larger than 0x28 bytes
- * with the QEMU VGA adapter, so this buffer is static, but it would
- * be better to query the size (with CM_Get_Res_Des_Data_Size) and
- * then use alloca here. */
- char memRes[0x28];
-
- if( CM_Get_Res_Des_Data( rd, memRes, sizeof(memRes), 0 ) == CR_SUCCESS ) {
- PMEM_DES pMemDes = (PMEM_DES)memRes;
- ULONG cbAlloc = pMemDes->MD_Alloc_End - pMemDes->MD_Alloc_Base + 1;
-
- if( cbAlloc > cbAllocMax ) {
- cbAllocMax = cbAlloc;
- LfbBase = pMemDes->MD_Alloc_Base;
- }
- }
- }
- }
- }
-
- dbg_printf("DriverInit: LfbBase is %lX\n", LfbBase);
-
- /* connect to 32bit RING-0 driver */
- if(!VXD_VM_connect())
- {
- dbg_printf("VXD connect failure!\n");
- return 0;
- }
-
- dbg_printf("VXD connect success!\n");
- FBHDA_setup(&hda, &hda_linear);
-
- if(hda == NULL)
- {
- dbg_printf("DriverInit: failed to get FBHDA!\n");
- return 0;
- }
-
- /* Return 1 (success) iff we located the physical address of the linear framebuffer. */
- return ( !!LfbBase );
-}
-#else
UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
{
/* Lock the code segment. */
@@ -367,4 +205,3 @@ UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
return( 1 ); /* Success. */
}
-#endif
diff --git a/init_qemu.c b/init_qemu.c
deleted file mode 100644
index 8b4a983..0000000
--- a/init_qemu.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define QEMU
-#include "init.c"
diff --git a/init_svga.c b/init_svga.c
deleted file mode 100644
index 2c6640f..0000000
--- a/init_svga.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SVGA
-#include "init.c"
diff --git a/makefile b/makefile
index f310c06..217714f 100644
--- a/makefile
+++ b/makefile
@@ -1,13 +1,13 @@
OBJS = &
boxv.obj boxv_qemu.obj dbgprint.obj dibcall.obj &
- dibthunk.obj dddrv.obj drvlib.obj enable.obj init.obj init_qemu.obj init_svga.obj &
+ dibthunk.obj dddrv.obj drvlib.obj enable.obj init.obj &
control.obj pm16_calls.obj pm16_calls_svga.obj pm16_calls_qemu.obj &
- palette.obj sswhook.obj modes.obj modes_svga.obj modes_qemu.obj scrsw.obj scrsw_svga.obj &
+ palette.obj sswhook.obj modes.obj modes_svga.obj scrsw.obj scrsw_svga.obj &
OBJS += &
dbgprint32.obj svga.obj pci.obj vxd_fbhda.obj vxd_lib.obj vxd_main.obj &
vxd_main_qemu.obj vxd_main_svga.obj vxd_svga.obj vxd_vdd.obj vxd_vdd_qemu.obj &
- vxd_vdd_svga.obj
+ vxd_vdd_svga.obj vxd_vbe.obj vxd_vbe_qemu.obj
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
@@ -21,7 +21,7 @@ FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
#FLAGS += -DVRAM256MB
# Set DBGPRINT to add debug printf logging.
-DBGPRINT = 1
+#DBGPRINT = 1
!ifdef DBGPRINT
FLAGS += -DDBGPRINT
@@ -44,7 +44,7 @@ CFLAGS32 += -DCOM2
!endif
#all : boxvmini.drv vmwsmini.drv qemumini.drv vmwsmini.vxd qemumini.vxd
-all : vmwsmini.drv vmwsmini.vxd
+all : vmwsmini.drv vmwsmini.vxd qemumini.drv qemumini.vxd boxvmini.drv boxvmini.vxd
# Object files: PM16 RING-3
boxv.obj : boxv.c .autodepend
@@ -73,12 +73,6 @@ enable.obj : enable.c .autodepend
init.obj : init.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
-init_qemu.obj : init_qemu.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
-init_svga.obj : init_svga.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
control.obj : control.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
@@ -104,9 +98,6 @@ modes.obj : modes.c .autodepend
modes_svga.obj : modes_svga.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-modes_qemu.obj : modes_qemu.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
scrsw.obj : scrsw.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
@@ -142,6 +133,12 @@ vxd_main_svga.obj : vxd_main_svga.c .autodepend
vxd_svga.obj : vxd_svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_vbe.obj : vxd_vbe.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
+vxd_vbe_qemu.obj : vxd_vbe_qemu.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
vxd_vdd.obj : vxd_vdd.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
@@ -187,19 +184,18 @@ dibeng.lib : ddk/dibeng.lbc
boxvmini.drv : $(OBJS) boxvmini.res dibeng.lib
wlink op quiet, start=DriverInit_ disable 2055 $(DBGFILE) @<<boxvmini.lnk
system windows dll initglobal
-file dibthunk.obj
file dibcall.obj
+file dibthunk.obj
+file dddrv.obj
file drvlib.obj
-file enable.obj
+file enable.obj
file init.obj
+file control.obj
+file pm16_calls.obj
file palette.obj
-file scrsw.obj
file sswhook.obj
file modes.obj
-file boxv.obj
-file control.obj
-file dddrv.obj
-file swcursor.obj
+file scrsw.obj
name boxvmini.drv
option map=boxvmini.map
library dibeng.lib
@@ -260,7 +256,7 @@ file dibthunk.obj
file dddrv.obj
file drvlib.obj
file enable.obj
-file init_svga.obj
+file init.obj
file control.obj
file pm16_calls_svga.obj
file palette.obj
@@ -320,22 +316,20 @@ import GlobalSmartPageLock KERNEL.230
wrc -q vmwsmini.res $@
qemumini.drv : $(OBJS) qemumini.res dibeng.lib
- wlink op quiet, start=DriverInit_ disable 2055 $(DBGFILE) @<<boxvmini.lnk
+ wlink op quiet, start=DriverInit_ disable 2055 $(DBGFILE) @<<qemumini.lnk
system windows dll initglobal
-file dibthunk.obj
file dibcall.obj
+file dibthunk.obj
+file dddrv.obj
file drvlib.obj
-file enable.obj
-file init_qemu.obj
+file enable.obj
+file init.obj
+file control.obj
+file pm16_calls_qemu.obj
file palette.obj
-file scrsw.obj
file sswhook.obj
-file modes_qemu.obj
-file boxv_qemu.obj
-file control_qemu.obj
-file vxdcall_qemu.obj
-file dddrv.obj
-file swcursor.obj
+file modes.obj
+file scrsw.obj
name qemumini.drv
option map=qemumini.map
library dibeng.lib
@@ -404,24 +398,46 @@ file vxd_vdd_svga.obj
segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
-export VMWS_DDB.1
+export VXD_DDB.1
<<
# not working now
# wrc -q vmws_vxd.res $@
-qemumini.vxd : $(OBJS) vmws_vxd.res
+qemumini.vxd : $(OBJS)
wlink op quiet $(DBGFILE32) @<<qemumini.lnk
system win_vxd dynamic
-option map=qemuvxd.map
+option map=qemumini.map
option nodefaultlibs
name qemumini.vxd
-file qemuvxd.obj
-file minivdd_qemu.obj
-segment '_LTEXT' PRELOAD NONDISCARDABLE
+file vxd_main_qemu.obj
+file pci.obj
+file vxd_fbhda.obj
+file vxd_lib.obj
+file vxd_vbe_qemu.obj
+file vxd_vdd_qemu.obj
+segment '_LTEXT' PRELOAD NONDISCARDABLE
+segment '_TEXT' PRELOAD NONDISCARDABLE
+segment '_DATA' PRELOAD NONDISCARDABLE
+export VXD_DDB.1
+<<
+
+boxvmini.vxd : $(OBJS)
+ wlink op quiet $(DBGFILE32) @<<boxvmini.lnk
+system win_vxd dynamic
+option map=boxvmini.map
+option nodefaultlibs
+name boxvmini.vxd
+file vxd_main.obj
+file pci.obj
+file vxd_fbhda.obj
+file vxd_vbe.obj
+file vxd_lib.obj
+file vxd_vdd.obj
+segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
-export QEMU_DDB.1
+export VXD_DDB.1
<<
# Cleanup
diff --git a/minidrv.h b/minidrv.h
index 6194938..d85bf8f 100644
--- a/minidrv.h
+++ b/minidrv.h
@@ -136,8 +136,3 @@ BOOL DDCreateDriverObject(int bReset);
#else
# define MAX_VRAM 0x08000000UL /* 128 MB */
#endif
-
-#ifdef SVGA
-#define SVGA_PARTIAL_UPDATE_MAX 16
-extern void SVGA_UpdateRect(LONG x, LONG y, LONG w, LONG h);
-#endif
diff --git a/modes.c b/modes.c
index 21aa9f9..1e379dd 100644
--- a/modes.c
+++ b/modes.c
@@ -26,6 +26,12 @@ THE SOFTWARE.
/* Display driver mode management. */
+#ifndef SVGA
+#ifndef VESA
+#define VBE
+#endif
+#endif
+
#include "winhack.h"
#include <gdidefs.h>
#include <dibeng.h>
@@ -117,20 +123,6 @@ WORD FixModeInfo( LPMODEDESC lpMode )
rc = 0; /* Mode wasn't valid. */
}
-#if 0
- /* Clip the resolution to something that probably won't make
- * Windows have a cow.
- */
- if( lpMode->xRes > RES_MAX_X ) {
- lpMode->xRes = RES_MAX_X;
- rc = 0;
- }
- if( lpMode->yRes > RES_MAX_Y ) {
- lpMode->yRes = RES_MAX_Y;
- rc = 0;
- }
-#endif
-
return( rc );
}
@@ -170,6 +162,13 @@ static int IsModeOK( WORD wXRes, WORD wYRes, WORD wBpp )
}
#endif
+#ifdef VBE
+ if(!VBE_validmode(wXRes, wYRes, wBpp))
+ {
+ return 0;
+ }
+#endif
+
return( 1 );
}
@@ -200,8 +199,13 @@ static int SetDisplayMode( WORD wXRes, WORD wYRes, int bFullSet )
{
return 0;
}
-#else
- BOXV_ext_mode_set( 0, wXRes, wYRes, wBpp, wXRes, wYRes );
+#endif
+
+#ifdef VBE
+ if(!VBE_setmode(wXRes, wYRes, wBpp))
+ {
+ return 0;
+ }
#endif
if( bFullSet ) {
@@ -232,25 +236,6 @@ int PhysicalEnable( void )
if( !ScreenSelector ) {
dwVideoMemorySize = hda->vram_size;
-#ifndef SVGA
- {
- /* Extra work if driver hasn't yet been initialized. */
- int iChipID;
- iChipID = BOXV_detect( 0, &dwVideoMemorySize );
- if( !iChipID ) {
- return( 0 );
- }
-
-#if 0
-# ifdef QEMU
- dwPhysVRAM = LfbBase;
-# else
- dwPhysVRAM = BOXV_get_lfb_base( 0 );
-# endif
-#endif
- }
-#endif
-
dbg_printf( "PhysicalEnable: Hardware detected, dwVideoMemorySize=%lX\n", dwVideoMemorySize );
}
@@ -302,6 +287,10 @@ int PhysicalEnable( void )
SVGA_setmode(wScrX, wScrY, wBpp);
#endif
+#ifdef VBE
+ VBE_setmode(wScrX, wScrY, wBpp);
+#endif
+
/* Let the VDD know that the mode changed. */
CallVDD( VDD_POST_MODE_CHANGE );
CallVDD( VDD_SAVE_DRIVER_STATE );
@@ -332,26 +321,17 @@ UINT WINAPI __loadds ValidateMode( DISPVALMODE FAR *lpValMode )
rc = VALMODE_NO_WRONGDRV;
break;
}
-
- dwVideoMemorySize = hda->vram_size;
-#else
- int iChipID;
-
- /* Additional checks if driver isn't running. */
- iChipID = BOXV_detect( 0, &dwVideoMemorySize );
- if( !iChipID ) {
- rc = VALMODE_NO_WRONGDRV;
- break;
- }
-#if 0 /* TODO move VXD */
-# ifdef QEMU
- dwPhysVRAM = LfbBase;
-# else
- dwPhysVRAM = BOXV_get_lfb_base( 0 );
-# endif
- dbg_printf( "ValidateMode: Hardware detected, dwVideoMemorySize=%lX dwPhysVRAM=%lX\n", dwVideoMemorySize, dwPhysVRAM );
#endif
+
+#ifdef VBE
+ /* Check if we have Boschs VBE card */
+ if(!VBE_valid())
+ {
+ rc = VALMODE_NO_WRONGDRV;
+ break;
+ }
#endif
+ dwVideoMemorySize = hda->vram_size;
}
if( !IsModeOK( lpValMode->dvmXRes, lpValMode->dvmYRes, lpValMode->dvmBpp ) ) {
diff --git a/modes_qemu.c b/modes_qemu.c
deleted file mode 100644
index 3a1ff0b..0000000
--- a/modes_qemu.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define QEMU
-#include "modes.c"
diff --git a/pm16_calls.c b/pm16_calls.c
index 147bee8..9f6bc0c 100644
--- a/pm16_calls.c
+++ b/pm16_calls.c
@@ -40,6 +40,12 @@ extern void dbg_printf( const char *s, ... );
#define dbg_printf(...)
#endif
+#ifndef SVGA
+# ifndef VESA
+# define VBE
+# endif
+#endif
+
static DWORD VXD_VM = 0;
#pragma code_seg( _INIT )
@@ -385,3 +391,102 @@ void SVGA_HW_disable()
}
}
#endif
+
+#ifdef VBE
+BOOL VBE_valid()
+{
+ static BOOL status;
+ status = FALSE;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_VBE_VALID
+ call dword ptr [VXD_VM]
+ mov [status], cx
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+BOOL VBE_setmode(DWORD w, DWORD h, DWORD bpp)
+{
+ static BOOL status;
+ static DWORD sw, sh, sbpp;
+
+ status = FALSE;
+ sw = w;
+ sh = h;
+ sbpp = bpp;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+ push esi
+ push edi
+
+ mov edx, OP_VBE_SETMODE
+ mov ecx, [bpp]
+ mov esi, [w]
+ mov edi, [h]
+ call dword ptr [VXD_VM]
+ mov [status], cx
+
+ pop edi
+ pop esi
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+BOOL VBE_validmode(DWORD w, DWORD h, DWORD bpp)
+{
+ static BOOL status;
+ static DWORD sw, sh, sbpp;
+
+ status = FALSE;
+ sw = w;
+ sh = h;
+ sbpp = bpp;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+ push esi
+ push edi
+
+ mov edx, OP_VBE_VALIDMODE
+ mov ecx, [bpp]
+ mov esi, [w]
+ mov edi, [h]
+ call dword ptr [VXD_VM]
+ mov [status], cx
+
+ pop edi
+ pop esi
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+#endif /* VBE */
diff --git a/scrsw.c b/scrsw.c
index 412131b..638aa0e 100644
--- a/scrsw.c
+++ b/scrsw.c
@@ -122,18 +122,6 @@ void UnhookInt2Fh( void )
}
}
-#ifdef SVGA
-static void __far __loadds SVGA_background()
-{
- SVGA_HW_disable();
-}
-
-static void __far __loadds SVGA_foreground()
-{
- SVGA_HW_enable();
-}
-#endif /* SVGA */
-
#pragma code_seg( _TEXT )
/* Repaint screen or postpone for later.
@@ -176,7 +164,7 @@ void SwitchToBgnd( void )
{
dbg_printf( "SwitchToBgnd\n" );
#ifdef SVGA
- SVGA_background();
+ SVGA_HW_disable();
#endif
lpDriverPDevice->deFlags |= BUSY; /// @todo Does this need to be a locked op?
@@ -191,7 +179,7 @@ void SwitchToFgnd( void )
{
dbg_printf( "SwitchToFgnd\n" );
#ifdef SVGA
- SVGA_foreground();
+ SVGA_HW_enable();
#endif
/* If the PDevice is busy, we need to reset the display mode. */
diff --git a/vmdisp9x.inf b/vmdisp9x.inf
index 6391191..b0b4380 100644
--- a/vmdisp9x.inf
+++ b/vmdisp9x.inf
@@ -25,6 +25,7 @@ DX.CopyBackup=10,SYSBCKUP
[SourceDisksFiles]
boxvmini.drv=1
+boxvmini.vxd=1
vmwsmini.drv=1
vmwsmini.vxd=1
qemumini.drv=1
@@ -77,6 +78,7 @@ AddReg=VMSvga.AddReg,VM.AddReg,DX.addReg
[VBox.Copy]
boxvmini.drv,,,0x00000004
+boxvmini.vxd,,,0x00000004
;mesa:mesa3d.dll,,,0x00000004
;vmhal:vmhal9x.dll,,,0x00000004
@@ -121,7 +123,7 @@ HKR,DEFAULT,Mode,,"8,640,480"
[VBox.AddReg]
HKR,DEFAULT,drv,,boxvmini.drv
-;HKR,DEFAULT,minivdd,,boxvmini.vxd
+HKR,DEFAULT,minivdd,,boxvmini.vxd
HKR,DEFAULT,Mode,,"8,640,480"
[VMSvga.AddReg]
diff --git a/vxd.h b/vxd.h
index 5a55fa6..49b0632 100644
--- a/vxd.h
+++ b/vxd.h
@@ -11,10 +11,13 @@
#if defined(SVGA)
#define VXD_DEVICE_ID VXD_DEVICE_SVGA_ID
+#define VXD_DEVICE_NAME "VMWSVXD"
#elif defined(QEMU)
#define VXD_DEVICE_ID VXD_DEVICE_QEMU_ID
+#define VXD_DEVICE_NAME "QEMUVXD"
#else
#define VXD_DEVICE_ID VXD_DEVICE_VBE_ID
+#define VXD_DEVICE_NAME "VBE_VXD"
#endif
#define VXD_MAJOR_VER 4 /* should be 4 for windows 95 and newer */
diff --git a/vxd_fbhda.c b/vxd_fbhda.c
index 2a258bc..d47129f 100644
--- a/vxd_fbhda.c
+++ b/vxd_fbhda.c
@@ -35,6 +35,8 @@ FBHDA_t *hda = NULL;
ULONG hda_sem = 0;
LONG fb_lock_cnt = 0;
+#include "vxd_strings.h"
+
BOOL FBHDA_init_hw()
{
hda = (FBHDA_t *)_PageAllocate(RoundToPages(sizeof(FBHDA_t)), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
@@ -72,6 +74,8 @@ void FBHDA_release_hw()
FBHDA_t *FBHDA_setup()
{
+ dbg_printf(dbg_fbhda_setup);
+
return hda;
}
diff --git a/vxd_main.c b/vxd_main.c
index c95a881..6923869 100644
--- a/vxd_main.c
+++ b/vxd_main.c
@@ -22,12 +22,22 @@ THE SOFTWARE.
*****************************************************************************/
+/*
+ * Code for QEMU is inspired by boxvmini.asm by Philip Kelley
+ */
+
#ifndef VXD32
#error VXD32 not defined!
#endif
#define VXD_MAIN
+#ifndef SVGA
+# ifndef VESA
+# define VBE
+# endif
+#endif
+
#include "winhack.h"
#include "vmm.h"
#include "vxd.h"
@@ -44,29 +54,30 @@ THE SOFTWARE.
#include "code32.h"
-void VMWS_control();
-void VMWS_API_entry();
+void VXD_control();
+void VXD_API_entry();
void Device_Init_proc();
void __stdcall Device_Dynamic_Init_proc(DWORD VM);
void __stdcall Device_Exit_proc(DWORD VM);
+void __stdcall Device_Init_Complete(DWORD VM);
/*
VXD structure
this variable must be in first address in code segment.
In other cases VXD isn't loadable (WLINK bug?)
*/
-DDB VMWS_DDB = {
+DDB VXD_DDB = {
NULL, // must be NULL
DDK_VERSION, // DDK_Version
VXD_DEVICE_ID, // Device ID
VXD_MAJOR_VER, // Major Version
VXD_MINOR_VER, // Minor Version
NULL,
- "VMWSVXD",
+ VXD_DEVICE_NAME,
VDD_Init_Order, //Undefined_Init_Order,
- (DWORD)VMWS_control,
- (DWORD)VMWS_API_entry,
- (DWORD)VMWS_API_entry,
+ (DWORD)VXD_control,
+ (DWORD)VXD_API_entry,
+ (DWORD)VXD_API_entry,
NULL,
NULL,
NULL,
@@ -83,6 +94,59 @@ DWORD *DispatchTable = 0;
DWORD DispatchTableLength = 0;
DWORD ThisVM = 0;
+#ifdef QEMU
+void Install_IO_Handler(DWORD port, DWORD callback)
+{
+ static DWORD sPort = 0;
+ static DWORD sCallback = 0;
+
+ sPort = port;
+ sCallback = callback;
+
+/*
+ * esi <- IOCallback
+ * edx <- I/O port numbers
+ */
+ _asm
+ {
+ push esi
+ push edx
+ mov esi, [sCallback]
+ mov edx, [sPort]
+ }
+ VMMCall(Install_IO_Handler);
+ _asm
+ {
+ pop edx
+ pop esi
+ }
+}
+
+/**
+ * This is fix of broken screen when open DOS window
+ *
+ **/
+void __declspec(naked) virtual_0x1ce()
+{
+/*
+ * AX/AL contains the value to be read or written on the port.
+ * EBX contains the handle of the VM accessing the port.
+ * ECX contains the direction (in/out) and size (byte/word) of the operation.
+ * EDX contains the port number, which for us will either be 1CEh or 1CFh.
+ */
+ VxDCall(VDD, Get_VM_Info); // esi = result
+ _asm{
+ cmp edi, ThisVM ; Is the CRTC controlled by Windows?
+ jne _Virtual1CEPhysical ; If not, we should allow the I/O
+ cmp ebx, edi ; Is the calling VM Windows?
+ je _Virtual1CEPhysical ; If not, we should eat the I/O
+ ret
+ _Virtual1CEPhysical:
+ }
+ VxDJmp(VDD, Do_Physical_IO);
+}
+#endif /* QEMU */
+
/**
* VDD calls wrapers
**/
@@ -120,7 +184,7 @@ void __declspec(naked) Device_IO_Control_entry()
* service module calls (init, exit, deviceIoControl, ...)
* clear carry if succes (this is always success)
*/
-void __declspec(naked) VMWS_control()
+void __declspec(naked) VXD_control()
{
// eax = 0x00 - Sys Critical Init
// eax = 0x01 - sys dynamic init
@@ -144,35 +208,44 @@ void __declspec(naked) VMWS_control()
clc
ret
control_2:
- cmp eax,0x1B
+ cmp eax,Init_Complete
jnz control_3
pushad
push ebx ; VM handle
+ call Device_Init_Complete
+ popad
+ clc
+ ret
+ control_3:
+ cmp eax,0x1B
+ jnz control_4
+ pushad
+ push ebx ; VM handle
call Device_Dynamic_Init_proc
popad
clc
ret
- control_3:
+ control_4:
cmp eax,W32_DEVICEIOCONTROL
- jnz control_4
+ jnz control_5
jmp Device_IO_Control_entry
- control_4:
+ control_5:
cmp eax,System_Exit
- jnz control_5
+ jnz control_6
pushad
push ebx ; VM handle
call Device_Exit_proc
popad
clc
ret
- control_5:
+ control_6:
clc
ret
};
}
/* process V86/PM16 calls */
-WORD __stdcall VMWS_API_Proc(PCRS_32 state)
+WORD __stdcall VXD_API_Proc(PCRS_32 state)
{
WORD rc = 0xFFFF;
WORD service = state->Client_EDX & 0xFFFF;
@@ -261,6 +334,34 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
rc = 1;
break;
#endif
+
+#ifdef VBE
+ case OP_VBE_VALID:
+ {
+ BOOL rs;
+ rs = VBE_valid();
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_VBE_SETMODE:
+ {
+ BOOL rs;
+ rs = VBE_setmode(state->Client_ESI, state->Client_EDI, state->Client_ECX);
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_VBE_VALIDMODE:
+ {
+ BOOL rs;
+ rs = VBE_validmode(state->Client_ESI, state->Client_EDI, state->Client_ECX);
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+#endif
+
}
if(rc == 0xFFFF)
@@ -278,15 +379,15 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
/*
* Service calls from protected mode (usually 16 bit) and virtual 86 mode
* CPU state before call is already on stack (EBP points it).
- * Converts the call to __stdcall and call 'VMWS_API_Proc', result of this
+ * Converts the call to __stdcall and call 'VXD_API_Proc', result of this
* function is placed to saved AX register.
*
*/
-void __declspec(naked) VMWS_API_entry()
+void __declspec(naked) VXD_API_entry()
{
_asm {
push ebp
- call VMWS_API_Proc
+ call VXD_API_Proc
mov [ebp+1Ch], ax
retn
}
@@ -314,7 +415,18 @@ void Device_Dynamic_Init_proc(DWORD VM)
#ifdef SVGA
SVGA_init_hw();
#endif
-
+
+#ifdef VBE
+ VBE_init_hw();
+#endif
+
+#ifdef QEMU
+ Install_IO_Handler(0x1ce, (DWORD)virtual_0x1ce);
+ Disable_Global_Trapping(0x1ce);
+ Install_IO_Handler(0x1cf, (DWORD)virtual_0x1ce);
+ Disable_Global_Trapping(0x1cf);
+#endif
+
/* register miniVDD functions */
VDD_Get_Mini_Dispatch_Table();
if(DispatchTableLength >= 0x31)
@@ -429,14 +541,40 @@ void Device_Init_proc()
/* nop */
}
+void Device_Init_Complete(DWORD VM)
+{
+#ifdef QEMU
+/*
+ * At Windows shutdown time, the display driver calls VDD_DRIVER_UNREGISTER,
+ * which calls our DisplayDriverDisabling callback, and soon thereafter
+ * does an INT 10h (AH=0) to mode 3 (and then 13) in V86 mode. However, the
+ * memory ranges for display memory are not always mapped!
+ *
+ * If the VGA ROM BIOS, during execution of such a set video mode call, tries to
+ * clear the screen, and the appropriate memory range isn't mapped, then we end
+ * up in a page fault handler, which I guess maps the memory and then resumes
+ * execution in V86 mode. But strangely, in QEMU, this fault & resume mechanism
+ * does not work with KVM or WHPX assist, at least on Intel. The machine hangs
+ * instead (I have not root caused why).
+ *
+ * We can dodge this problem by setting up real mappings up front.
+ *
+ * At entry, EBX contains a Windows VM handle.
+ *
+ */
+ _PhysIntoV86(0xA0, VM, 0xA0, 16, 0);
+ _PhysIntoV86(0xB8, VM, 0xB8, 8, 0);
+#endif
+}
+
/* shutdown procedure */
void Device_Exit_proc(DWORD VM)
{
- dbg_printf(dbg_destroy);
-
#ifdef SVGA
SVGA_HW_disable();
#endif
+
+ dbg_printf(dbg_destroy);
// TODO: free memory
}
diff --git a/vxd_strings.h b/vxd_strings.h
index 7dca2e4..20ce5fb 100644
--- a/vxd_strings.h
+++ b/vxd_strings.h
@@ -81,6 +81,14 @@ DSTR(dbg_fence_overflow, "fence overflow\n");
DSTR(dbg_pagefree, "_PageFree: %X\n");
+DSTR(dbg_vbe_fail, "Bochs VBE detection failure!\n");
+
+DSTR(dbg_vbe_init, "Bochs VBE: vram: %X, size: %ld\n");
+
+DSTR(dbg_vbe_lfb, "LFB at %X\n");
+
+DSTR(dbg_fbhda_setup, "FBHDA_setup()\n");
+
#undef DSTR
#endif
diff --git a/vxd_vbe.c b/vxd_vbe.c
new file mode 100644
index 0000000..adb5ccd
--- /dev/null
+++ b/vxd_vbe.c
@@ -0,0 +1,321 @@
+/**************************************************************************
+
+Copyright (c) 2024 Jaroslav Hensl <emulator@emulace.cz>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+#define VBE
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+
+#include "vxd_lib.h"
+#include "3d_accel.h"
+
+#include "boxvint.h"
+
+#include "pci.h" /* re-use PCI functions from SVGA */
+
+#include "code32.h"
+
+#define IO_IN16
+#define IO_OUT16
+#define IO_IN8
+#define IO_OUT8
+#ifndef QEMU
+# define IO_IN32
+#endif
+#include "io32.h"
+
+#define PCI_VENDOR_ID_INNOTEK 0x80EE
+#define PCI_DEVICE_ID_VBOX_VGA 0xBEEF
+#define PCI_VENDOR_ID_BOCHSVBE 0x1234
+#define PCI_DEVICE_ID_BOCHSVBE 0x1111
+
+/* (max) 256MB VRAM: max 8K in 16:10 */
+#define RES_MAX_X 8192
+#define RES_MAX_Y 5120
+
+#define ISA_LFB 0xE0000000UL
+
+static BOOL vbe_is_valid = FALSE;
+extern FBHDA_t *hda;
+extern LONG fb_lock_cnt;
+WORD vbe_chip_id = 0;
+
+#ifdef QEMU
+static char vbe_vxd_name[] = "qemumini.vxd";
+#else
+static char vbe_vxd_name[] = "boxvmini.vxd";
+#endif
+
+#include "vxd_strings.h"
+
+static inline void wridx(unsigned short idx_reg, unsigned char idx, unsigned char data)
+{
+ outpw(idx_reg, (unsigned short)idx | (((unsigned short)data) << 8));
+}
+
+static WORD VBE_detect(DWORD *vram_size)
+{
+ WORD chip_id;
+
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
+
+ chip_id = inpw(VBE_DISPI_IOPORT_DATA);
+#ifdef QEMU
+ if(chip_id < VBE_DISPI_ID0 || chip_id > VBE_DISPI_ID6)
+ return 0;
+
+ if(vram_size)
+ {
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
+ *vram_size = ((DWORD)inpw(VBE_DISPI_IOPORT_DATA)) << 16;
+ }
+
+ return chip_id;
+#else
+ if(vram_size)
+ {
+ *vram_size = inpd(VBE_DISPI_IOPORT_DATA);
+ }
+
+ if(chip_id >= VBE_DISPI_ID0 && chip_id <= VBE_DISPI_ID4)
+ return chip_id;
+
+ return 0;
+#endif
+}
+
+DWORD VBE_get_LFB()
+{
+ PCIAddress pciAddr;
+
+ /* virtualbox */
+ if(PCI_FindDevice(PCI_VENDOR_ID_INNOTEK, PCI_DEVICE_ID_VBOX_VGA, &pciAddr))
+ {
+ PCI_SetMemEnable(&pciAddr, TRUE);
+ return PCI_GetBARAddr(&pciAddr, 0);
+ }
+
+ /* qemu */
+ if(PCI_FindDevice(PCI_VENDOR_ID_BOCHSVBE, PCI_DEVICE_ID_BOCHSVBE, &pciAddr))
+ {
+ PCI_SetMemEnable(&pciAddr, TRUE);
+ return PCI_GetBARAddr(&pciAddr, 0);
+ }
+
+ /* try failback */
+ return ISA_LFB;
+}
+
+BOOL VBE_init_hw()
+{
+ DWORD vram_size;
+ DWORD vram_phy;
+
+ vbe_chip_id = VBE_detect(&vram_size);
+ if(vbe_chip_id == 0)
+ {
+ dbg_printf(dbg_vbe_fail);
+ return FALSE;
+ }
+
+ vram_phy = VBE_get_LFB();
+
+ if(!FBHDA_init_hw())
+ {
+ return FALSE;
+ }
+
+ dbg_printf(dbg_vbe_init, vram_phy, vram_size);
+
+ hda->vram_size = vram_size;
+ hda->vram_pm32 = (void*)_MapPhysToLinear(vram_phy, vram_size, 0);
+ hda->flags |= FB_SUPPORT_FLIPING;
+
+ memcpy(hda->vxdname, vbe_vxd_name, sizeof(vbe_vxd_name));
+
+ dbg_printf(dbg_vbe_lfb, hda->vram_pm32);
+
+ if(hda->vram_pm32 != NULL)
+ {
+ vbe_is_valid = TRUE;
+ }
+
+ return TRUE;
+}
+
+BOOL VBE_valid()
+{
+ return vbe_is_valid;
+}
+
+static DWORD VBE_pitch(DWORD width, DWORD bpp)
+{
+ DWORD bp = (bpp + 7) / 8;
+ return (bp * width + 3) & 0xFFFFFFFC;
+}
+
+BOOL VBE_validmode(DWORD w, DWORD h, DWORD bpp)
+{
+ switch(bpp)
+ {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ return FALSE;
+ }
+
+ if(w <= RES_MAX_X)
+ {
+ if(h <= RES_MAX_Y)
+ {
+ DWORD size = VBE_pitch(w, bpp) * h;
+ if(size < hda->vram_size)
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL VBE_setmode(DWORD w, DWORD h, DWORD bpp)
+{
+ if(!VBE_validmode(w, h, bpp)) return FALSE;
+
+ /* Put the hardware into a state where the mode can be safely set. */
+ inp(VGA_STAT_ADDR); /* Reset flip-flop. */
+ outp(VGA_ATTR_W, 0); /* Disable palette. */
+ wridx(VGA_SEQUENCER, VGA_SR_RESET, VGA_SR_RESET);
+
+ /* Disable the extended display registers. */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
+ outpw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED);
+
+ /* Program the extended non-VGA registers. */
+
+ /* Set X resoultion. */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
+ outpw(VBE_DISPI_IOPORT_DATA, (WORD)w);
+ /* Set Y resoultion. */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
+ outpw(VBE_DISPI_IOPORT_DATA, (WORD)h);
+ /* Set bits per pixel. */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
+ outpw(VBE_DISPI_IOPORT_DATA, (WORD)bpp);
+ /* Set the virtual resolution. (same as FB resolution) */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH);
+ outpw(VBE_DISPI_IOPORT_DATA, (WORD)w);
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_HEIGHT);
+ outpw(VBE_DISPI_IOPORT_DATA, (WORD)h);
+ /* Reset the current bank. */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BANK);
+ outpw(VBE_DISPI_IOPORT_DATA, 0);
+ /* Set the X and Y display offset to 0. */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_X_OFFSET);
+ outpw(VBE_DISPI_IOPORT_DATA, 0);
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_Y_OFFSET);
+ outpw(VBE_DISPI_IOPORT_DATA, 0);
+ /* Enable the extended display registers. */
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
+#ifdef QEMU
+ outpw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC | VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM);
+#else
+ outpw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC);
+#endif
+
+ /* Re-enable the sequencer. */
+ wridx(VGA_SEQUENCER, VGA_SR_RESET, VGA_SR0_NORESET);
+
+ /* Reset flip-flop again and re-enable palette. */
+ inp(VGA_STAT_ADDR);
+ outp(VGA_ATTR_W, 0x20);
+
+ hda->width = w;
+ hda->height = h;
+ hda->bpp = bpp;
+ hda->pitch = VBE_pitch(w, bpp);
+ hda->surface = 0;
+ hda->stride = h * hda->bpp;
+
+ return TRUE;
+}
+
+void FBHDA_palette_set(unsigned char index, DWORD rgb)
+{
+ outp(VGA_DAC_W_INDEX, index); /* Set starting index. */
+ outp(VGA_DAC_DATA, (rgb >> 16) & 0xFF);
+ outp(VGA_DAC_DATA, (rgb >> 8) & 0xFF);
+ outp(VGA_DAC_DATA, rgb & 0xFF);
+}
+
+DWORD FBHDA_palette_get(unsigned char index)
+{
+ DWORD r, g, b;
+
+ outp(VGA_DAC_W_INDEX, index);
+ r = inp(VGA_DAC_DATA);
+ g = inp(VGA_DAC_DATA);
+ b = inp(VGA_DAC_DATA);
+
+ return (r << 16) | (g << 8) | b;
+}
+
+
+BOOL FBHDA_swap(DWORD offset)
+{
+ DWORD ps = ((hda->bpp+7)/8);
+ DWORD offset_y = offset/hda->pitch;
+ DWORD offset_x = (offset % hda->pitch)/ps;
+ DWORD surface = offset/hda->stride;
+
+ if(offset + hda->stride > hda->vram_size) return FALSE; /* if exceed VRAM */
+
+ if(surface == 0 && offset != 0) return FALSE; /* forbind move of half screen */
+
+ hda->surface = surface;
+
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_Y_OFFSET);
+ outpw(VBE_DISPI_IOPORT_DATA, (WORD)offset_y);
+ outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_X_OFFSET);
+ outpw(VBE_DISPI_IOPORT_DATA, (WORD)offset_x);
+
+ return TRUE;
+}
+
+void FBHDA_access_end(DWORD flags)
+{
+ fb_lock_cnt--;
+ if(fb_lock_cnt < 0) fb_lock_cnt = 0;
+
+ if(fb_lock_cnt == 0)
+ {
+ // cursor
+ }
+
+ //Signal_Semaphore(hda_sem);
+}
diff --git a/vxd_vbe_qemu.c b/vxd_vbe_qemu.c
new file mode 100644
index 0000000..b45c376
--- /dev/null
+++ b/vxd_vbe_qemu.c
@@ -0,0 +1,2 @@
+#define QEMU
+#include "vxd_vbe.c"
diff --git a/vxd_vdd.c b/vxd_vdd.c
index aca9793..e82a091 100644
--- a/vxd_vdd.c
+++ b/vxd_vdd.c
@@ -21,6 +21,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*****************************************************************************/
+
+#ifndef SVGA
+# ifndef VESA
+# define VBE
+# endif
+#endif
+
+
#include "winhack.h"
#include "vmm.h"
@@ -31,9 +39,17 @@ THE SOFTWARE.
#include "svga_all.h"
#endif
+#include "3d_accel.h"
+
/* code and data is same segment */
#include "code32.h"
+extern FBHDA_t *hda;
+
+#ifdef VBE
+extern WORD vbe_chip_id;
+#endif
+
/*
You can implement all the VESA support entirely in your mini-VDD. Doing so will
cause VESA applications to run more efficiently since all of the VESA support is
@@ -112,10 +128,25 @@ VDDPROC(GET_CHIP_ID, get_chip_id)
{
uint32 chip_id = (((uint32)gSVGA.vendorId) << 16) || ((uint32)gSVGA.deviceId);
state->Client_EAX = chip_id;
+ VDD_CY;
return;
}
state->Client_EAX = 0;
#endif
+
+#ifdef VBE
+ if(VBE_valid())
+ {
+ state->Client_EAX = vbe_chip_id;
+ VDD_CY;
+ }
+ else
+ {
+ state->Client_EAX = 0;
+ VDD_NC;
+ }
+#endif
+
}
/**
@@ -210,19 +241,8 @@ For performance reasons, you should implement this function.
**/
VDDPROC(GET_TOTAL_VRAM_SIZE, get_total_vram_size)
{
-#ifdef SVGA
- if(SVGA_valid())
- {
- uint32 vram_size = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
- state->Client_ECX = vram_size;
-
- VDD_CY;
- return;
- }
-
- state->Client_ECX = 0;
- VDD_NC;
-#endif
+ state->Client_ECX = hda->vram_size;
+ VDD_CY;
}
/**
diff --git a/vxd_vdd.h b/vxd_vdd.h
index 54dcd43..428a5fb 100644
--- a/vxd_vdd.h
+++ b/vxd_vdd.h
@@ -109,4 +109,28 @@ void dbg_printf( const char *s, ... );
#define VDD_CY state->Client_EFlags |= 0x1
#define VDD_NC state->Client_EFlags &= 0xFFFFFFFEUL
+typedef struct {
+ WORD diHdrSize;
+ WORD diInfoFlags;
+ DWORD diDevNodeHandle;
+ char diDriverName[16];
+ WORD diXRes;
+ WORD diYRes;
+ WORD diDPI;
+ BYTE diPlanes;
+ BYTE diBpp;
+ WORD diRefreshRateMax;
+ WORD diRefreshRateMin;
+ WORD diLowHorz;
+ WORD diHighHorz;
+ WORD diLowVert;
+ WORD diHighVert;
+ DWORD diMonitorDevNodeHandle;
+ BYTE diHorzSyncPolarity;
+ BYTE diVertSyncPolarity;
+} DISPLAYINFO;
+
+void Enable_Global_Trapping(DWORD port);
+void Disable_Global_Trapping(DWORD port);
+
#endif /* __VXD_VDD_H__INCLUDED__ */
diff --git a/vxd_vdd_list.h b/vxd_vdd_list.h
index cf67e02..9155921 100644
--- a/vxd_vdd_list.h
+++ b/vxd_vdd_list.h
@@ -46,17 +46,13 @@ VDDFUNC(DISPLAY_DRIVER_DISABLING, display_driver_disabling)
//VDDFUNC(GET_CURRENT_BANK_READ, get_current_bank_read)
///! VDDFUNC(SET_BANK, set_bank)
//VDDFUNC(CHECK_HIRES_MODE, check_hires_mode)
-#ifdef SVGA
VDDFUNC(GET_TOTAL_VRAM_SIZE, get_total_vram_size)
-#endif
///! VDDFUNC(GET_BANK_SIZE, get_bank_size)
///! VDDFUNC(SET_HIRES_MODE, set_hires_mode)
///! VDDFUNC(PRE_HIRES_SAVE_RESTORE, pre_hires_save_restore)
///! VDDFUNC(POST_HIRES_SAVE_RESTORE, post_hires_save_restore)
///! VDDFUNC(VESA_SUPPORT, vesa_support)
-#ifdef SVGA
VDDFUNC(GET_CHIP_ID, get_chip_id)
-#endif
///! VDDFUNC(CHECK_SCREEN_SWITCH_OK, check_screen_switch_ok)
//VDDFUNC(VIRTUALIZE_BLTER_IO, virtualize_blter_io)
//VDDFUNC(SAVE_MESSAGE_MODE_STATE, save_message_mode_state)