aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <emulator@emulace.cz>2023-09-07 14:34:12 +0200
committerJaroslav Hensl <emulator@emulace.cz>2023-09-07 14:34:12 +0200
commitacde242b61c662d3f234fc051f059fa58875f5fd (patch)
tree63b6a12899bcd6acc4fe64c6b1b1915b87c7df12
parent6eb9ffbc6cf3141d59220fee159786f186b65041 (diff)
downloadvmdisp9x-acde242b61c662d3f234fc051f059fa58875f5fd.tar.gz
SVGA: config in registry, better locking, HW cursor off by defaultv1.2023.0.24
-rw-r--r--control.c11
-rw-r--r--dibcall.c11
-rw-r--r--makefile4
-rw-r--r--version.h2
-rw-r--r--vmware/svga.c11
-rw-r--r--vmware/svga.h2
-rw-r--r--vmware/svga_reg.h2
-rw-r--r--vmwsvxd.c244
8 files changed, 244 insertions, 43 deletions
diff --git a/control.c b/control.c
index 4eb9277..cdac8f2 100644
--- a/control.c
+++ b/control.c
@@ -193,6 +193,10 @@ typedef struct _svga_hda_t
#define ULF_PITCH 4
#define ULF_LOCK_UL 5
#define ULF_LOCK_FIFO 6
+#define ULF_LOCK_FB 7
+#define ULF_LOCK_CB 8
+#define ULF_LOCK_GMR 9
+#define ULF_CNT 10
#define GMR_INDEX_CNT 6
#define CTX_INDEX_CNT 2
@@ -346,8 +350,8 @@ void SVGAHDA_init()
{
_fmemset(&SVGAHDA, 0, sizeof(svga_hda_t));
- SVGAHDA.ul_flags_index = 0; // dirty, width, height, bpp, pitch, fifo_lock, ul_lock, fb_lock
- SVGAHDA.ul_fence_index = SVGAHDA.ul_flags_index + 8;
+ SVGAHDA.ul_flags_index = 0; // dirty, width, height, bpp, pitch, fifo_lock, ul_lock, fb_lock...
+ SVGAHDA.ul_fence_index = SVGAHDA.ul_flags_index + ULF_CNT;
SVGAHDA.ul_gmr_start = SVGAHDA.ul_fence_index + 1;
SVGAHDA.ul_gmr_count = SVGA_ReadReg(SVGA_REG_GMR_MAX_IDS);
//SVGAHDA.ul_gmr_count = SVGA3D_MAX_MOBS;
@@ -368,6 +372,9 @@ void SVGAHDA_init()
SVGAHDA.userlist_pm16[ULF_LOCK_UL] = 0;
SVGAHDA.userlist_pm16[ULF_LOCK_FIFO] = 0;
+ SVGAHDA.userlist_pm16[ULF_LOCK_FB] = 0;
+ SVGAHDA.userlist_pm16[ULF_LOCK_CB] = 0;
+ SVGAHDA.userlist_pm16[ULF_LOCK_GMR] = 0;
}
dbg_printf("SVGAHDA_init: %ld\n", SVGAHDA.userlist_length * sizeof(uint32_t));
diff --git a/dibcall.c b/dibcall.c
index bd37a2e..1ad2cfd 100644
--- a/dibcall.c
+++ b/dibcall.c
@@ -187,6 +187,10 @@ void WINAPI __loadds MoveCursor(WORD absX, WORD absY)
SVGA_MoveCursor(cursorVisible, absX, absY, 0);
SVGAHDA_unlock(LOCK_FIFO);
}
+
+ /* save last position */
+ cursorX = absX;
+ cursorY = absY;
}
else
{
@@ -281,6 +285,13 @@ WORD WINAPI __loadds SetCursor_driver(CURSORSHAPE __far *lpCursor)
}
}
+ /* move cursor to last known position */
+ if(SVGAHDA_trylock(LOCK_FIFO))
+ {
+ SVGA_MoveCursor(cursorVisible, cursorX, cursorY, 0);
+ SVGAHDA_unlock(LOCK_FIFO);
+ }
+
cursorVisible = TRUE;
}
else
diff --git a/makefile b/makefile
index 727a00b..77c552a 100644
--- a/makefile
+++ b/makefile
@@ -9,9 +9,9 @@ OBJS = dibthunk.obj dibcall.obj enable.obj init.obj palette.obj &
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 22
+VER_BUILD = 24
-FLAGS = -DDRV_VER_BUILD=$(VER_BUILD) -DCAP_R5G6B5_ALWAYS_WRONG
+FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
# Define HWBLT if BitBlt can be accelerated.
#FLAGS += -DHWBLT
diff --git a/version.h b/version.h
index b625f5d..947f4f5 100644
--- a/version.h
+++ b/version.h
@@ -5,7 +5,7 @@
#define DRV_STR(x) DRV_STR_(x)
/* DRV, VXD and DLL have to have the same */
-#define DRV_API_LEVEL 20230814UL
+#define DRV_API_LEVEL 20230907UL
/* on binaries equals 1 and for INF is 1 = separate driver, 2 = softgpu pack */
#define DRV_VER_MAJOR 1
diff --git a/vmware/svga.c b/vmware/svga.c
index aaa90fb..0f7b791 100644
--- a/vmware/svga.c
+++ b/vmware/svga.c
@@ -122,7 +122,11 @@ static char dbg_siz[] = "Size of gSVGA(1) = %d %d\n";
*/
int
+#ifndef VXD32
SVGA_Init(Bool enableFIFO)
+#else
+SVGA_Init(Bool enableFIFO, uint32 hwversion)
+#endif
{
int vga_found = 0;
@@ -189,8 +193,13 @@ SVGA_Init(Bool enableFIFO)
* a. If we read back the same value, this ID is supported. We're done.
* b. If not, decrement the ID and repeat.
*/
+
+ if(hwversion == 0)
+ {
+ hwversion = SVGA_VERSION_2;
+ }
- gSVGA.deviceVersionId = SVGA_ID_2;
+ gSVGA.deviceVersionId = SVGA_MAKE_ID(hwversion);
do {
SVGA_WriteReg(SVGA_REG_ID, gSVGA.deviceVersionId);
if (SVGA_ReadReg(SVGA_REG_ID) == gSVGA.deviceVersionId) {
diff --git a/vmware/svga.h b/vmware/svga.h
index 4408007..8a62800 100644
--- a/vmware/svga.h
+++ b/vmware/svga.h
@@ -128,7 +128,7 @@ extern SVGADevice gSVGA;
#ifndef VXD32
int __loadds SVGA_Init(Bool enableFIFO);
#else
-int SVGA_Init(Bool enableFIFO);
+int SVGA_Init(Bool enableFIFO, uint32 hwversion);
#endif
void SVGA_Enable(void);
void SVGA_SetMode(uint32 width, uint32 height, uint32 bpp);
diff --git a/vmware/svga_reg.h b/vmware/svga_reg.h
index 8c88121..0c2e13e 100644
--- a/vmware/svga_reg.h
+++ b/vmware/svga_reg.h
@@ -90,7 +90,7 @@ typedef struct uint64 {
#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver))
#define SVGA_VERSION_3 3
-#define SVGA_ID_3 SVGA_MAKE_ID(SVGA_VERSION_3)
+#define SVGA_ID_3 SVGA_MAKE_ID(SVGA_VERSION_3)
/* Version 2 let the address of the frame buffer be unsigned on Win32 */
#define SVGA_VERSION_2 2
diff --git a/vmwsvxd.c b/vmwsvxd.c
index 3140814..912aabd 100644
--- a/vmwsvxd.c
+++ b/vmwsvxd.c
@@ -35,6 +35,10 @@ THE SOFTWARE.
#include "version.h"
+#ifndef ERROR_SUCCESS
+#define ERROR_SUCCESS 0
+#endif
+
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
@@ -125,6 +129,7 @@ char dbg_region_info_2[] = "Region address = %lX, PPN = %lX, GMRBLK = %lX\n";
char dbg_mapping[] = "Memory mapping:\n";
char dbg_mapping_map[] = " %X -> %X\n";
+char dbg_destroy[] = "Driver destroyed\n";
static char dbg_siz[] = "Size of gSVGA(2) = %d %d\n";
@@ -180,6 +185,7 @@ otinfo_entry_t otable[SVGA_OTABLE_DX_MAX] = {
DWORD *DispatchTable = 0;
DWORD DispatchTableLength = 0;
+DWORD ThisVM = 0;
Bool svga_init_success = FALSE;
@@ -231,6 +237,32 @@ ULONG __declspec(naked) __cdecl _MapPhysToLinear(ULONG PhysAddr, ULONG nBytes, U
VMMJmp(_MapPhysToLinear);
}
+ULONG __declspec(naked) __cdecl GetNulPageHandle()
+{
+ VMMJmp(_MapPhysToLinear);
+}
+
+ULONG __declspec(naked) __cdecl _PhysIntoV86(ULONG PhysPage, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG flags)
+{
+ VMMJmp(_PhysIntoV86);
+}
+
+DWORD __declspec(naked) __cdecl _RegOpenKey(DWORD hKey, char *lpszSubKey, DWORD *lphKey)
+{
+ VMMJmp(_RegOpenKey);
+}
+
+DWORD __declspec(naked) __cdecl _RegCloseKey(DWORD hKey)
+{
+ VMMJmp(_RegCloseKey);
+}
+
+DWORD __declspec(naked) __cdecl _RegQueryValueEx(DWORD hKey, char *lpszValueName, DWORD *lpdwReserved, DWORD *lpdwType, BYTE *lpbData, DWORD *lpcbData)
+{
+ VMMJmp(_RegQueryValueEx);
+}
+
+
/**
* VDD calls wrapers
**/
@@ -280,6 +312,8 @@ void __declspec(naked) Device_IO_Control_proc()
}
void Device_Init_proc();
+void __stdcall Device_Dynamic_Init_proc(DWORD VM);
+void __stdcall Device_Exit_proc(DWORD VM);
/*
* service module calls (init, exit, deviceIoControl, ...)
@@ -304,7 +338,6 @@ void __declspec(naked) VMWS_Control()
control_1:
cmp eax,Device_Init
jnz control_2
- pushad
call Device_Init_proc
popad
clc
@@ -313,7 +346,8 @@ void __declspec(naked) VMWS_Control()
cmp eax,0x1B
jnz control_3
pushad
- call Device_Init_proc
+ push ebx ; VM handle
+ call Device_Dynamic_Init_proc
popad
clc
ret
@@ -322,6 +356,15 @@ void __declspec(naked) VMWS_Control()
jnz control_4
jmp Device_IO_Control_proc
control_4:
+ cmp eax,System_Exit
+ jnz control_5
+ pushad
+ push ebx ; VM handle
+ call Device_Exit_proc
+ popad
+ clc
+ ret
+ control_5:
clc
ret
};
@@ -436,7 +479,8 @@ static BOOL GMRAlloc(ULONG nPages, ULONG *outDataAddr, ULONG *outGMRAddr, ULONG
// add extra descriptors for pages edge
blk_pages = ((blocks+blk_pages+1)/(P_SIZE/sizeof(SVGAGuestMemDescriptor))) + 1;
- pgblk = _PageAllocate(blk_pages, PG_SYS, 0, 0, 0x0, 0x100000, &pgblk_phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+ //pgblk = _PageAllocate(blk_pages, PG_SYS, 0, 0, 0x0, 0x100000, &pgblk_phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+ pgblk = _PageAllocate(blk_pages, PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
if(pgblk)
{
desc = (SVGAGuestMemDescriptor*)pgblk;
@@ -478,37 +522,45 @@ static BOOL GMRAlloc(ULONG nPages, ULONG *outDataAddr, ULONG *outGMRAddr, ULONG
*outDataAddr = laddr;
*outGMRAddr = pgblk;
- *outPPN = (pgblk_phy/P_SIZE);
+ *outPPN = getPPN(pgblk); //(pgblk_phy/P_SIZE);
if(outMobAddr)
{
- DWORD mobphy;
- /* for simplicity we're always creating table of depth 2, first page is page of PPN pages */
- DWORD *mob = (DWORD *)_PageAllocate(1 + (nPages + PTONPAGE - 1)/PTONPAGE, PG_SYS, 0, 0, 0x0, 0x100000, &mobphy,
- PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
-
- if(mob)
+ if(gb_support) /* don't create MOBs for Gen9 */
{
- int i;
- /* dim 1 */
- for(i = 0; i < (nPages + PTONPAGE - 1)/PTONPAGE; i++)
+ DWORD mobphy;
+ /* for simplicity we're always creating table of depth 2, first page is page of PPN pages */
+ DWORD *mob = (DWORD *)_PageAllocate(1 + (nPages + PTONPAGE - 1)/PTONPAGE, PG_SYS, 0, 0, 0x0, 0x100000, &mobphy,
+ PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+
+ if(mob)
{
- mob[i] = (mobphy/PAGE_SIZE) + i + 1;
+ int i;
+ /* dim 1 */
+ for(i = 0; i < (nPages + PTONPAGE - 1)/PTONPAGE; i++)
+ {
+ mob[i] = (mobphy/PAGE_SIZE) + i + 1;
+ }
+
+ /* dim 2 */
+ for(i = 0; i < nPages; i++)
+ {
+ mob[PTONPAGE + i] = getPPN(laddr + i*PAGE_SIZE);
+ }
+
+ *outMobAddr = (DWORD)mob;
+ if(outMobPPN) *outMobPPN = mobphy/PAGE_SIZE;
}
-
- /* dim 2 */
- for(i = 0; i < nPages; i++)
+ else
{
- mob[PTONPAGE + i] = getPPN(laddr + i*PAGE_SIZE);
+ *outMobAddr = NULL;
+ if(outMobPPN) *outMobPPN = getPPN(laddr);
}
-
- *outMobAddr = (DWORD)mob;
- if(outMobPPN) *outMobPPN = mobphy/PAGE_SIZE;
}
else
{
*outMobAddr = NULL;
- if(outMobPPN) *outMobPPN = getPPN(laddr);
+ if(outMobPPN) *outMobPPN = NULL;
}
}
@@ -965,7 +1017,7 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
cbe->cmd = SVGA_DC_CMD_START_STOP_CONTEXT;
cbe->cbstart.enable = 0;
cbe->cbstart.context = SVGA_CB_CONTEXT_0;
- submitCB(cbe, SVGA_CB_CONTEXT_DEVICE, FALSE); // FALSE?
+ submitCB(cbe, SVGA_CB_CONTEXT_DEVICE, TRUE);
}
rc = 1;
break;
@@ -1108,30 +1160,113 @@ void __declspec(naked) VMWS_API_Entry()
#define VDDFUNC(id, procname) DispatchTable[id] = (DWORD)(procname ## _entry);
+union
+{
+ DWORD dw;
+ char str[64];
+} RegReadConfBuf = {0};
+
+char SVGA_conf_path[] = "Software\\SVGA";
+
+char SVGA_conf_hw_cursor[] = "hwcursor";
+char SVGA_conf_vram256[] = "vram256";
+char SVGA_conf_rgb565bug[] = "rgb565bug";
+char SVGA_conf_cb[] = "commandbuffers";
+char SVGA_conf_hw_version[] = "hwversion";
+
+BOOL RegReadConf(const char *value, DWORD *out)
+{
+ DWORD hKey;
+ DWORD type;
+ DWORD cbData = sizeof(RegReadConfBuf);
+ BOOL rv = FALSE;
+
+ if(_RegOpenKey(HKEY_LOCAL_MACHINE, SVGA_conf_path, &hKey) == ERROR_SUCCESS)
+ {
+ if(_RegQueryValueEx(hKey, (char*)value, 0, &type, &(RegReadConfBuf.str), &cbData) == ERROR_SUCCESS)
+ {
+ if(type == REG_SZ)
+ {
+ DWORD cdw = 0;
+ char *ptr = &(RegReadConfBuf.str);
+
+ while(*ptr == ' '){ptr++;}
+
+ while(*ptr >= '0' && *ptr <= '9')
+ {
+ cdw *= 10;
+ cdw += *ptr - '0';
+ ptr++;
+ }
+
+ *out = cdw;
+ }
+ else
+ {
+ *out = RegReadConfBuf.dw;
+ }
+
+ rv = TRUE;
+ }
+
+ _RegCloseKey(hKey);
+ }
+
+ return rv;
+}
+
/* init device and fill dispatch table */
-void Device_Init_proc()
+void Device_Dynamic_Init_proc(DWORD VM)
{
- dbg_printf(dbg_Device_Init_proc);
+ DWORD conf_hw_cursor = 0;
+ DWORD conf_vram256 = 0;
+ DWORD conf_rgb565bug = 1;
+ DWORD conf_cb = 1;
+ DWORD conf_hw_version = SVGA_VERSION_2;
+ dbg_printf(dbg_Device_Init_proc);
+
// VMMCall _Allocate_Device_CB_Area
-
- if(SVGA_Init(FALSE) == 0)
+ ThisVM = VM;
+
+ RegReadConf(SVGA_conf_hw_cursor, &conf_hw_cursor);
+ RegReadConf(SVGA_conf_vram256, &conf_vram256);
+ RegReadConf(SVGA_conf_rgb565bug, &conf_rgb565bug);
+ RegReadConf(SVGA_conf_cb, &conf_cb);
+ RegReadConf(SVGA_conf_hw_version, &conf_hw_version);
+
+
+ if(SVGA_Init(FALSE, conf_hw_version) == 0)
{
/* default flags */
- gSVGA.userFlags |= SVGA_USER_FLAGS_RGB565_BROKEN | SVGA_USER_FLAGS_128MB_MAX;
+ gSVGA.userFlags = 0;
+
+ if(conf_rgb565bug)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_RGB565_BROKEN;
+ }
+
+ if(SVGA_conf_vram256)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_128MB_MAX;
+ }
if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_CURSOR)
{
- gSVGA.userFlags |= SVGA_USER_FLAGS_HWCURSOR;
+ if(conf_hw_cursor)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_HWCURSOR;
+ }
}
if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_ALPHA_CURSOR)
{
- gSVGA.userFlags |= SVGA_USER_FLAGS_ALPHA_CUR;
+ if(conf_hw_cursor)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_ALPHA_CUR;
+ }
}
- // TODO: read config from registry
-
if(gSVGA.userFlags & SVGA_USER_FLAGS_128MB_MAX)
{
if(gSVGA.vramSize > 128*1024*1024)
@@ -1184,9 +1319,12 @@ void Device_Init_proc()
/* allocate command buffers if supported */
if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & (SVGA_CAP_COMMAND_BUFFERS | SVGA_CAP_CMD_BUFFERS_2))
{
- AllocateCB();
- cb_support = TRUE;
- dbg_printf(dbg_cb_on);
+ if(conf_cb)
+ {
+ AllocateCB();
+ cb_support = TRUE;
+ dbg_printf(dbg_cb_on);
+ }
}
/* register miniVDD functions */
@@ -1420,3 +1558,39 @@ DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params)
return 1;
}
+
+void Device_Init_proc()
+{
+ /* nop */
+}
+
+/* shutdown procedure */
+void Device_Exit_proc(DWORD VM)
+{
+ uint32 *screen_id;
+
+ dbg_printf(dbg_destroy);
+
+ /* stop context 0 */
+ if(cb_context0)
+ {
+ cb_enable_t *cbe;
+ cb_context0 = FALSE;
+
+ syncCB();
+ do
+ {
+ cbe = LockCB();
+ } while(cbe == NULL);
+ memset(cbe, 0, sizeof(cb_enable_t));
+ cbe->cbheader.length = sizeof(SVGADCCmdStartStop) + sizeof(uint32);
+ cbe->cmd = SVGA_DC_CMD_START_STOP_CONTEXT;
+ cbe->cbstart.enable = 0;
+ cbe->cbstart.context = SVGA_CB_CONTEXT_0;
+ submitCB(cbe, SVGA_CB_CONTEXT_DEVICE, TRUE);
+ }
+
+ SVGA_Disable();
+
+ // TODO: free memory
+}