diff options
author | Jaroslav Hensl <emulator@emulace.cz> | 2023-09-07 14:34:12 +0200 |
---|---|---|
committer | Jaroslav Hensl <emulator@emulace.cz> | 2023-09-07 14:34:12 +0200 |
commit | acde242b61c662d3f234fc051f059fa58875f5fd (patch) | |
tree | 63b6a12899bcd6acc4fe64c6b1b1915b87c7df12 | |
parent | 6eb9ffbc6cf3141d59220fee159786f186b65041 (diff) | |
download | vmdisp9x-acde242b61c662d3f234fc051f059fa58875f5fd.tar.gz |
SVGA: config in registry, better locking, HW cursor off by defaultv1.2023.0.24
-rw-r--r-- | control.c | 11 | ||||
-rw-r--r-- | dibcall.c | 11 | ||||
-rw-r--r-- | makefile | 4 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rw-r--r-- | vmware/svga.c | 11 | ||||
-rw-r--r-- | vmware/svga.h | 2 | ||||
-rw-r--r-- | vmware/svga_reg.h | 2 | ||||
-rw-r--r-- | vmwsvxd.c | 244 |
8 files changed, 244 insertions, 43 deletions
@@ -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));
@@ -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
@@ -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
@@ -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 @@ -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
+}
|