aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2024-01-31 23:57:00 +0100
committerJaroslav Hensl <jara@hensl.cz>2024-01-31 23:57:00 +0100
commitcf7b049839923f86fed97cfe7d8c17952a3fe79a (patch)
tree70e5b14cbdcf92429a9608316768e7154e3a0b6f
parent4cc02044b5cd8d5a3791f847198b37817fc60b78 (diff)
downloadvmdisp9x-cf7b049839923f86fed97cfe7d8c17952a3fe79a.tar.gz
driver code refactoring / PART1: vmware code
-rw-r--r--3d_accel.h273
-rw-r--r--control.c765
-rw-r--r--control_qemu.c2
-rw-r--r--control_svga.c2
-rw-r--r--cursor.h17
-rw-r--r--dbgprint32.c1
-rw-r--r--dddrv.c5
-rw-r--r--dibcall.c57
-rw-r--r--dibcall_svga.c2
-rw-r--r--enable.c56
-rw-r--r--enable_svga.c2
-rw-r--r--hwcursor.c332
-rw-r--r--hwcursor.h10
-rw-r--r--init.c38
-rw-r--r--makefile139
-rw-r--r--minidrv.h39
-rw-r--r--minivdd_qemu.c3
-rw-r--r--minivdd_svga.c3
-rw-r--r--modes.c600
-rw-r--r--palette.c30
-rw-r--r--palette_svga.c2
-rw-r--r--pm16_calls.c387
-rw-r--r--pm16_calls.h10
-rw-r--r--pm16_calls_qemu.c2
-rw-r--r--pm16_calls_svga.c2
-rw-r--r--qemuvxd.c478
-rw-r--r--scrsw.c8
-rw-r--r--swcursor.c657
-rw-r--r--swcursor.h38
-rw-r--r--vmware/pci32.c2
-rw-r--r--vmware/svga.c227
-rw-r--r--vmware/svga.h2
-rw-r--r--vmware/svga32.c2
-rw-r--r--vmware/svga_reg.h6
-rw-r--r--vmwsmini.lst5338
-rw-r--r--vmwsvxd.c1613
-rw-r--r--vxd.h26
-rw-r--r--vxd_fbhda.c89
-rw-r--r--vxd_lib.c234
-rw-r--r--vxd_lib.h65
-rw-r--r--vxd_main.c442
-rw-r--r--vxd_main_qemu.c2
-rw-r--r--vxd_main_svga.c2
-rw-r--r--vxd_strings.h86
-rw-r--r--vxd_svga.c1431
-rw-r--r--vxd_vdd.c (renamed from minivdd.c)11
-rw-r--r--vxd_vdd.h (renamed from minivdd32.h)8
-rw-r--r--vxd_vdd_list.h (renamed from minivdd_func.h)0
-rw-r--r--vxd_vdd_qemu.c2
-rw-r--r--vxd_vdd_svga.c2
-rw-r--r--vxdcall.c394
-rw-r--r--vxdcall.h30
-rw-r--r--vxdcall_qemu.c2
-rw-r--r--vxdcall_svga.c2
-rw-r--r--vxdcodes.h40
55 files changed, 8733 insertions, 5285 deletions
diff --git a/3d_accel.h b/3d_accel.h
new file mode 100644
index 0000000..b7e3c5a
--- /dev/null
+++ b/3d_accel.h
@@ -0,0 +1,273 @@
+/*****************************************************************************
+
+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.
+
+*****************************************************************************/
+
+/* const and types for GPU acceleration */
+
+#ifndef __3D_ACCEL_H__
+#define __3D_ACCEL_H__
+
+#ifdef __WATCOMC__
+#ifndef VXD32
+#define FBHDA_SIXTEEN
+#endif
+#endif
+
+/* function codes */
+#define OP_FBHDA_SETUP 0x110B /* VXD, DRV, ExtEscape */
+#define OP_FBHDA_ACCESS_BEGIN 0x110C /* VXD, DRV */
+#define OP_FBHDA_ACCESS_END 0x110D /* VXD, DRV */
+#define OP_FBHDA_SWAP 0x110E /* VXD, DRV */
+#define OP_FBHDA_CLEAN 0x110F /* VXD, DRV */
+#define OP_FBHDA_PALETTE_SET 0x1110 /* VXD, DRV */
+#define OP_FBHDA_PALETTE_GET 0x1111 /* VXD, DRV */
+
+#define OP_SVGA_VALID 0x2000 /* VXD, DRV */
+#define OP_SVGA_SETMODE 0x2001 /* DRV */
+#define OP_SVGA_VALIDMODE 0x2002 /* DRV */
+#define OP_SVGA_HW_ENABLE 0x2003 /* DRV */
+#define OP_SVGA_HW_DISABLE 0x2004 /* DRV */
+#define OP_SVGA_CMB_ALLOC 0x2005 /* VXD, DRV */
+#define OP_SVGA_CMB_FREE 0x2006 /* VXD, DRV */
+#define OP_SVGA_CMB_SUBMIT 0x2007 /* VXD, DRV */
+#define OP_SVGA_FENCE_GET 0x2008 /* VXD */
+#define OP_SVGA_FENCE_QUERY 0x2009 /* VXD */
+#define OP_SVGA_FENCE_WAIT 0x200A /* VXD */
+#define OP_SVGA_REGION_CREATE 0x200B /* VXD */
+#define OP_SVGA_REGION_FREE 0x200C /* VXD */
+#define OP_SVGA_QUERY 0x200D /* VXD */
+#define OP_SVGA_QUERY_VECTOR 0x200E /* VXD */
+#define OP_SVGA_DB_SETUP 0x200F /* VXD */
+#define OP_SVGA_OT_SETUP 0x2010 /* VXD */
+
+#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_MOUSE_LOAD 0x1F00 /* DRV */
+#define OP_MOUSE_MOVE 0x1F01 /* DRV */
+#define OP_MOUSE_HIDE 0x1F02 /* DRV */
+#define OP_MOUSE_SHOW 0x1F03 /* DRV */
+#define OP_MOUSE_RESET 0x1F04 /* DRV */
+
+#pragma pack(push)
+#pragma pack(1)
+
+#ifdef FBHDA_SIXTEEN
+# define FBPTR __far*
+#else
+# define FBPTR *
+#endif
+
+typedef struct FBHDA
+{
+ DWORD cb;
+ DWORD flags;
+ volatile DWORD width;
+ volatile DWORD height;
+ volatile DWORD bpp;
+ volatile DWORD pitch;
+ volatile DWORD surface;
+ volatile DWORD stride;
+#ifndef FBHDA_SIXTEEN
+ void *vram_pm32;
+ DWORD vram_pm16;
+#else
+ DWORD vram_pm32;
+ void __far *vram_pm16;
+#endif
+ DWORD vram_size;
+ char vxdname[16];
+} FBHDA_t;
+
+#define FB_SUPPORT_FLIPING 1
+#define FB_ACCEL_VIRGE 2
+#define FB_ACCEL_CHROMIUM 4
+#define FB_ACCEL_QEMU3DFX 8
+#define FB_ACCEL_VMSVGA 16
+#define FB_ACCEL_VMSVGA3D 32
+#define FB_ACCEL_VMSVGA10 64
+
+#define FB_MOUSE_RESTORE 1
+
+/* for internal use in RING-0 by VXD only */
+BOOL FBHDA_init_hw();
+void FBHDA_release_hw();
+
+/* for internal use by RING-3 application/driver */
+void FBHDA_load();
+void FBHDA_free();
+
+#ifdef FBHDA_SIXTEEN
+ void FBHDA_setup(FBHDA_t __far* __far* FBHDA, DWORD __far* FBHDA_linear);
+#else
+ FBHDA_t *FBHDA_setup();
+#endif
+
+#define FBHDA_IGNORE_CURSOR 1
+
+void FBHDA_access_begin(DWORD flags);
+void FBHDA_access_end(DWORD flags);
+BOOL FBHDA_swap(DWORD offset);
+void FBHDA_clean();
+
+void FBHDA_palette_set(unsigned char index, DWORD rgb);
+DWORD FBHDA_palette_get(unsigned char index);
+
+/* mouse */
+void mouse_load(void FBPTR mouse_data);
+void mouse_move(DWORD x, DWORD y);
+void mouse_reset();
+
+#ifdef SVGA
+
+typedef struct SVGA_region_info
+{
+ DWORD region_id;
+ DWORD size;
+ void *address; /* user memory */
+ void *region_address;
+ DWORD region_ppn;
+ void* mob_address;
+ DWORD mob_ppn;
+ DWORD is_mob;
+} SVGA_region_info_t;
+
+typedef struct SVGA_CMB_status
+{
+ volatile DWORD *qStatus;
+ DWORD sStatus;
+ DWORD fifo_fence_used;
+ DWORD fifo_fence_last;
+} SVGA_CMB_status_t;
+
+#define SVGA_PROC_NONE 0
+#define SVGA_PROC_COMPLETED 1
+#define SVGA_PROC_ERROR 3
+#define SVGA_PROC_FENCE 0xFF
+
+typedef struct SVGA_DB_region
+{
+ DWORD pid;
+ SVGA_region_info_t info;
+} SVGA_DB_region_t;
+
+typedef struct SVGA_DB_context
+{
+ DWORD pid;
+ void *cotable;
+} SVGA_DB_context_t;
+
+typedef struct SVGA_DB_surface
+{
+ DWORD pid;
+ DWORD format; /* format of surface (SVGA3dSurfaceFormat) */
+ DWORD width;
+ DWORD height;
+ DWORD bpp;
+ DWORD gmrId; /* != 0 for GB surfaces */
+} SVGA_DB_surface_t;
+
+typedef struct SVGA_DB
+{
+ SVGA_DB_region_t *regions;
+ SVGA_DB_context_t *contexts;
+ SVGA_DB_surface_t *surfaces;
+ DWORD regions_cnt;
+ DWORD contexts_cnt;
+ DWORD surfaces_cnt;
+ char mutexname[64];
+} SVGA_DB_t;
+
+/* internal VXD only */
+BOOL SVGA_init_hw();
+
+BOOL SVGA_valid();
+
+#define SVGA_CB_USE_CONTEXT_DEVICE 0x80000000UL
+#define SVGA_CB_SYNC 0x40000000UL
+#define SVGA_CB_FORCE_FIFO 0x20000000UL
+#define SVGA_CB_FORCE_FENCE 0x10000000UL
+// SVGA_CB_FLAG_DX_CONTEXT
+
+BOOL SVGA_setmode(DWORD w, DWORD h, DWORD bpp);
+BOOL SVGA_validmode(DWORD w, DWORD h, DWORD bpp);
+#ifdef FBHDA_SIXTEEN
+ void SVGA_CMB_alloc(DWORD FBPTR cmb, DWORD cmb_linear);
+#else
+ DWORD FBPTR SVGA_CMB_alloc();
+#endif
+void SVGA_CMB_free(DWORD FBPTR cmb);
+
+/* for data exchange by DeviceIoControl */
+typedef struct SVGA_CMB_submit_io
+{
+ DWORD *cmb;
+ DWORD cmb_size;
+ DWORD flags;
+ DWORD DXCtxId;
+} SVGA_CMB_submit_io_t;
+
+void SVGA_CMB_submit(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_status_t FBPTR status, DWORD flags, DWORD DXCtxId);
+
+DWORD SVGA_fence_get();
+void SVGA_fence_query(DWORD FBPTR ptr_fence_passed, DWORD FBPTR ptr_fence_last);
+void SVGA_fence_wait(DWORD fence_id);
+BOOL SVGA_region_create(SVGA_region_info_t FBPTR rinfo);
+void SVGA_region_free(SVGA_region_info_t FBPTR rinfo);
+
+#define SVGA_QUERY_REGS 1
+#define SVGA_QUERY_FIFO 2
+#define SVGA_QUERY_CAPS 3
+
+DWORD SVGA_query(DWORD type, DWORD index);
+void SVGA_query_vector(DWORD type, DWORD index_start, DWORD count, DWORD *out);
+
+void SVGA_HW_enable();
+void SVGA_HW_disable();
+
+SVGA_DB_t *SVGA_DB_setup();
+
+void SVGA_DB_lock();
+void SVGA_DB_unlock();
+
+#define SVGA_OT_FLAG_ALLOCATED 1
+#define SVGA_OT_FLAG_ACTIVE 2
+
+typedef struct SVGA_OT_info_entry
+{
+ DWORD phy;
+ void *lin;
+ DWORD size;
+ DWORD flags;
+} SVGA_OT_info_entry_t;
+
+SVGA_OT_info_entry_t *SVGA_OT_setup();
+
+#endif /* SVGA */
+
+#pragma pack(pop)
+
+#endif /* __3D_ACCEL_H__ */
diff --git a/control.c b/control.c
index b07b6b8..0e1f24b 100644
--- a/control.c
+++ b/control.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2022-2023 Jaroslav Hensl <emulator@emulace.cz>
+Copyright (c) 2022-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
@@ -34,18 +34,7 @@ THE SOFTWARE.
#include <string.h> /* _fmemset */
#include "version.h"
-#include "swcursor.h"
-
-#ifdef SVGA
-# include "svga_all.h"
-# include "vxdcall.h"
-#else
-# include "boxv.h"
-#endif
-
-#ifdef QEMU
-# include "vxdcall.h"
-#endif
+#include "3d_accel.h"
/*
* MS supported functions
@@ -70,43 +59,6 @@ THE SOFTWARE.
#define MOUSETRAILS 39
-/*
- * new escape codes
- */
-
-/* all frame buffer devices */
-#define FBHDA_REQ 0x110A
-
-/* debug output from ring-3 application */
-#define SVGA_DBG 0x110B
-
-/* update buffer if 'need_call_update' is set */
-#define FBHDA_UPDATE 0x110C
-
-/* move framebuffer */
-#define FBHDA_FLIP 0x110D
-
-/* cursor swap */
-#define FBHDA_CTRL 0x110E
-
-#define FBHDA_CTRL_CUR_SHOW 1UL
-#define FBHDA_CTRL_CUR_HIDE 2UL
-
-/* check for drv <-> vxd <-> dll match */
-#define SVGA_API 0x110F
-
-/* VMWare SVGA II codes */
-#define SVGA_READ_REG 0x1110
-#define SVGA_HDA_REQ 0x1112
-#define SVGA_REGION_CREATE 0x1114
-#define SVGA_REGION_FREE 0x1115
-#define SVGA_SYNC 0x1116
-#define SVGA_RING 0x1117
-
-#define SVGA_HWINFO_REGS 0x1121
-#define SVGA_HWINFO_FIFO 0x1122
-#define SVGA_HWINFO_CAPS 0x1123
-
/**
* OpenGL ICD driver name (0x1101):
* -------------------------------------
@@ -143,16 +95,13 @@ const static opengl_icd_t software_icd = {
"SOFTWARE"
};
-#ifdef QEMU
/* Mesa3D SVGA3D OpengGL */
-const static opengl_icd_t qemu_icd = {
+const static opengl_icd_t qemu3dfx_icd = {
0x2,
0x1,
"QEMUFX"
};
-#endif
-#ifdef SVGA
/* Mesa3D SVGA3D OpengGL */
const static opengl_icd_t vmwsvga_icd = {
0x2,
@@ -160,418 +109,8 @@ const static opengl_icd_t vmwsvga_icd = {
"VMWSVGA"
};
-#pragma pack(push)
-#pragma pack(1)
-
-/* SVGA HDA = hardware direct access */
-typedef struct _svga_hda_t
-{
- uint32_t vram_linear; /* frame buffer address from PM32 (shared memory region, accesable with user space programs too) */
- uint8_t __far *vram_pm16; /* access from THIS code */
- uint32_t vram_physical; /* physical address only for drivers */
- uint32_t vram_size; /* video ram size */
-
- uint32_t fifo_linear;
- uint32_t __far *fifo_pm16;
- uint32_t fifo_physical;
- uint32_t fifo_size;
-
- uint32_t ul_flags_index;
- uint32_t ul_fence_index;
- uint32_t ul_gmr_start;
- uint32_t ul_gmr_count;
- uint32_t ul_ctx_start;
- uint32_t ul_ctx_count;
- uint32_t ul_surf_start;
- uint32_t ul_surf_count;
- uint32_t __far *userlist_pm16;
- uint32_t userlist_linear;
- uint32_t userlist_length;
-} svga_hda_t;
-
-#pragma pack(pop)
-
-#define ULF_DIRTY 0
-#define ULF_WIDTH 1
-#define ULF_HEIGHT 2
-#define ULF_BPP 3
-#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
-
-static svga_hda_t SVGAHDA;
-
-#endif /* SVGA only */
-
-/* from dibcall.c */
-extern LONG cursorX;
-extern LONG cursorY;
-
#pragma code_seg( _INIT )
-#ifdef SVGA
-uint32_t GetDevCap(uint32_t search_id);
-
-/*
- * Fix SVGA caps which are known as bad:
- * - VirtualBox returning A4R4G4B4 instead of R5G6B5,
- * try to guess it's value from X8R8G8B8.
- *
- */
-uint32_t FixDevCap(uint32_t cap_id, uint32_t cap_val)
-{
- switch(cap_id)
- {
- case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
- {
- if(gSVGA.userFlags & SVGA_USER_FLAGS_RGB565_BROKEN)
- {
- uint32_t xrgb8888 = GetDevCap(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
- xrgb8888 &= ~SVGA3DFORMAT_OP_SRGBWRITE; /* nvidia */
- return xrgb8888;
- }
- else
- {
- if(cap_val & SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET) /* VirtualBox BUG */
- {
- uint32_t xrgb8888 = GetDevCap(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
- xrgb8888 &= ~SVGA3DFORMAT_OP_SRGBWRITE; /* nvidia */
- return xrgb8888;
- }
-
- if((cap_val & SVGA3DFORMAT_OP_3DACCELERATION) == 0) /* VirtualBox BUG, older drivers */
- {
- uint32_t xrgb8888 = GetDevCap(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
- xrgb8888 &= ~SVGA3DFORMAT_OP_SRGBWRITE; /* nvidia */
- if(xrgb8888 & SVGA3DFORMAT_OP_3DACCELERATION)
- {
- return xrgb8888;
- }
- }
- }
- }
- break;
- }
-
- return cap_val;
-}
-
-/**
- * Read HW cap, supported old way (GPU gen9):
- * struct SVGA_FIFO_3D_CAPS in FIFO,
- * and new way (GPU gen10):
- * SVGA_REG_DEV_CAP HW register
- *
- **/
-uint32_t GetDevCap(uint32_t search_id)
-{
- if (gSVGA.capabilities & SVGA_CAP_GBOBJECTS)
- {
- /* new way to read device CAPS */
- SVGA_WriteReg(SVGA_REG_DEV_CAP, search_id);
- return FixDevCap(search_id, SVGA_ReadReg(SVGA_REG_DEV_CAP));
- }
- else
- {
- SVGA3dCapsRecord __far *pCaps = (SVGA3dCapsRecord __far *)&(gSVGA.fifoMem[SVGA_FIFO_3D_CAPS]);
- while(pCaps->header.length != 0)
- {
- if(pCaps->header.type == SVGA3DCAPS_RECORD_DEVCAPS)
- {
- uint32_t datalen = (pCaps->header.length - 2)/2;
- SVGA3dCapPair __far *pData = (SVGA3dCapPair __far *)(&pCaps->data);
- uint32_t i;
-
- for(i = 0; i < datalen; i++)
- {
- uint32_t id = pData[i][0];
- uint32_t val = pData[i][1];
-
- if(id == search_id)
- {
- return FixDevCap(search_id, val);
- }
- }
- }
- pCaps = (SVGA3dCapsRecord __far *)((uint32_t __far *)pCaps + pCaps->header.length);
- }
- }
-
- return 0;
-}
-
-/**
- * Check for 3D support:
- * - we need SVGA_FIFO_CAP_FENCE ans SVGA_FIFO_CAP_SCREEN_OBJECT
- * - SVGA3D_DEVCAP_3D is none zero
- * - at last SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 is accelerated (GPU gen9 feature,
- * GPU gen10 - eg. DirectX surfaces jet aren't supported)
- *
- **/
-WORD SVGA_3DSupport()
-{
- if(SVGA_HasFIFOCap(SVGA_FIFO_CAP_FENCE) && (SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT) || SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT_2)))
- {
- if(GetDevCap(SVGA3D_DEVCAP_3D)) /* is 3D enabled */
- {
- uint32_t cap_xgrb = GetDevCap(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
- uint32_t cap_dx_xgrb = GetDevCap(SVGA3D_DEVCAP_DXFMT_X8R8G8B8);
- if((cap_xgrb & SVGA3DFORMAT_OP_3DACCELERATION) != 0) /* at last X8R8G8B8 needs to be accelerated! */
- {
- return 1;
- }
- else if((cap_dx_xgrb & SVGA3DFORMAT_OP_TEXTURE) != 0) /* vGPU10 - DX11 mode */
- {
- return 1;
- }
- else
- {
- dbg_printf("no surface caps %lX %lX!\n", cap_xgrb, cap_dx_xgrb);
- }
- }
- else
- {
- dbg_printf("!GetDevCap(SVGA3D_DEVCAP_3D)\n");
- }
- }
- else
- {
- dbg_printf("no SVGA_FIFO_CAP_FENCE || SVGA_FIFO_CAP_SCREEN_OBJECT\n");
- }
-
- return 0;
-}
-
-#define SVGA3D_MAX_MOBS 33280UL /* SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS */
-
-/**
- * init SVGAHDA -> memory map between user space and (virtual) hardware memory
- *
- **/
-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 + 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;
- SVGAHDA.ul_ctx_start = SVGAHDA.ul_gmr_start + SVGAHDA.ul_gmr_count*GMR_INDEX_CNT;
- SVGAHDA.ul_ctx_count = GetDevCap(SVGA3D_DEVCAP_MAX_CONTEXT_IDS);
- SVGAHDA.ul_surf_start = SVGAHDA.ul_ctx_start + SVGAHDA.ul_ctx_count*CTX_INDEX_CNT;
- SVGAHDA.ul_surf_count = GetDevCap(SVGA3D_DEVCAP_MAX_SURFACE_IDS);
- SVGAHDA.userlist_length = SVGAHDA.ul_surf_start + SVGAHDA.ul_surf_count;
-
- SVGAHDA.userlist_pm16 = drv_malloc(SVGAHDA.userlist_length * sizeof(uint32_t), &SVGAHDA.userlist_linear);
-
- if(SVGAHDA.userlist_pm16)
- {
- SVGAHDA.userlist_pm16[ULF_DIRTY] = 0xFFFFFFFFUL;
-
- /* zero the memory, because is large than 64k, is much easier do it in PM32 */
- VXD_zeromem(SVGAHDA.userlist_linear, SVGAHDA.userlist_length * sizeof(uint32_t));
-
- 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));
-}
-
-/**
- * update frame buffer and fifo addresses in SVGAHDA from gSVGA
- *
- **/
-void SVGAHDA_setmode()
-{
- if(SVGAHDA.userlist_pm16)
- {
- SVGAHDA.vram_linear = gSVGA.fbLinear;
- SVGAHDA.vram_pm16 = gSVGA.fbMem;
- SVGAHDA.vram_physical = gSVGA.fbPhy;
- SVGAHDA.vram_size = gSVGA.vramSize;
-
- SVGAHDA.fifo_linear = gSVGA.fifoLinear;
- SVGAHDA.fifo_pm16 = gSVGA.fifoMem;
- SVGAHDA.fifo_physical = gSVGA.fifoPhy;
- SVGAHDA.fifo_size = gSVGA.fifoSize;
- }
-}
-
-/**
- * Lock resource
- *
- * Note: this is simple spinlock implementation because multitasking isn't
- * preemptive in Win9x this can lead to deadlock. Please use SVGAHDA_trylock
- * instead.
- *
- * Note: please call SVGAHDA_unlock every time after this function
- *
- **/
-BOOL SVGAHDA_lock(uint32_t lockid)
-{
- volatile uint32_t __far * ptr_lock = SVGAHDA.userlist_pm16 + lockid;
-
- if(SVGAHDA.userlist_pm16)
- {
- _asm
- {
- .386
- push eax
- push ebx
-
- spin_lock:
- mov eax, 1
- les bx, ptr_lock
- lock xchg eax, es:[bx]
- test eax, eax
- jnz spin_lock
-
- pop ebx
- pop eax
-
- };
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * Try to lock resource and return TRUE is success.
- *
- * Note: if is function successfull you must call SVGAHDA_unlock!
- *
- **/
-BOOL SVGAHDA_trylock(uint32_t lockid)
-{
- volatile uint32_t __far * ptr_lock = SVGAHDA.userlist_pm16 + lockid;
- BOOL locked = FALSE;
-
- if(SVGAHDA.userlist_pm16)
- {
- _asm
- {
- .386
- push eax
- push ebx
-
- mov eax, 1
- les bx, ptr_lock
- lock xchg eax, es:[bx]
- test eax, eax
- jnz lock_false
- mov locked, 1
- lock_false:
-
- pop ebx
- pop eax
-
- };
- }
-
- return locked;
-}
-
-/**
- * Unlock resource
- *
- **/
-void SVGAHDA_unlock(uint32_t lockid)
-{
- volatile uint32_t __far * ptr_lock = SVGAHDA.userlist_pm16 + lockid;
-
- if(SVGAHDA.userlist_pm16)
- {
- _asm
- {
- .386
- push eax
- push ebx
-
- xor eax, eax
- les bx, ptr_lock
- lock xchg eax, es:[bx]
-
- pop ebx
- pop eax
-
- };
- }
-}
-
-/**
- * This is called after every screen change
- **/
-void SVGAHDA_update(DWORD width, DWORD height, DWORD bpp, DWORD pitch)
-{
- if(SVGAHDA.userlist_pm16)
- {
- SVGAHDA.userlist_pm16[ULF_WIDTH] = width;
- SVGAHDA.userlist_pm16[ULF_HEIGHT] = height;
- SVGAHDA.userlist_pm16[ULF_BPP] = bpp;
- SVGAHDA.userlist_pm16[ULF_PITCH] = pitch;
- }
-}
-
-BOOL SVGA_hasAccelScreen();
-
-/* working only in VB and only on 32 bit,
- * ...
- */
-uint32 SVGA_Flip(uint32 offset)
-{
- if(SVGA_hasAccelScreen)
- {
- SVGAFifoCmdDefineScreen __far *screen;
-
- dbg_printf("SVGA_Flip\n");
-
- screen = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_SCREEN, sizeof(SVGAFifoCmdDefineScreen));
-
- if(screen)
- {
- _fmemset(screen, 0, sizeof(SVGAFifoCmdDefineScreen));
- screen->screen.structSize = sizeof(SVGAScreenObject);
- screen->screen.id = 0;
- screen->screen.flags = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
- screen->screen.size.width = wScrX;
- screen->screen.size.height = wScrY;
- screen->screen.root.x = 0;
- screen->screen.root.y = offset/wScreenPitchBytes;
- screen->screen.cloneCount = 0;
-
- screen->screen.backingStore.pitch = wScreenPitchBytes;
- screen->screen.backingStore.ptr.offset = offset;
- screen->screen.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
-
- SVGA_FIFOCommitAll();
- }
-
- SVGA_WriteReg(SVGA_SYNC, 1);
-
- dbg_printf("SVGA_Flip done\n");
-
- return offset;
- }
-
- return 0;
-}
-
-#endif /* SVGA only */
-
/**
* 2022:
* Control now serve system QUERYESCSUPPORT (0x8), OPENGL_ICD_DRIVER (0x1101),
@@ -595,6 +134,10 @@ uint32 SVGA_Flip(uint32 offset)
* 2023-II:
* Added DCICOMMAND to query DirectDraw/DirectX interface
*
+ * 2024:
+ * removed all VMWare SVGA II commands from here and move to VXD driver
+ * you can use DeviceIoControl to call them
+ *
**/
LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function,
LPVOID lpInput, LPVOID lpOutput)
@@ -610,36 +153,9 @@ LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function,
switch(function_code)
{
case OPENGL_GETINFO:
- case FBHDA_REQ:
- case FBHDA_UPDATE:
- case FBHDA_FLIP:
- case FBHDA_CTRL:
- case MOUSETRAILS:
-#ifdef SVGA
- case SVGA_API:
- /*
- * allow read HW registry/fifo registry and caps even if 3D is
- * disabled for diagnostic tool to check why is disabled
- */
- case SVGA_HWINFO_REGS:
- case SVGA_HWINFO_FIFO:
- case SVGA_HWINFO_CAPS:
-#endif
+ case OP_FBHDA_SETUP:
rc = 1;
break;
-#ifdef SVGA
- case SVGA_READ_REG:
- case SVGA_HDA_REQ:
- case SVGA_REGION_CREATE:
- case SVGA_REGION_FREE:
- case SVGA_SYNC:
- case SVGA_RING:
- if(wMesa3DEnabled)
- {
- rc = 1;
- }
- break;
-#endif
case DCICOMMAND:
rc = DD_HAL_VERSION;
break;
@@ -650,32 +166,21 @@ LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function,
dbg_printf("Control: function check for unknown: %x\n", function_code);
break;
}
-
}
else if(function == OPENGL_GETINFO) /* input: NULL, output: opengl_icd_t */
{
-#if defined(SVGA)
- if(wMesa3DEnabled == 0)
+ if(hda->flags & FB_ACCEL_VMSVGA3D)
+ {
+ _fmemcpy(lpOutput, &vmwsvga_icd, OPENGL_ICD_SIZE);
+ }
+ else if(hda->flags & FB_ACCEL_QEMU3DFX)
{
- _fmemcpy(lpOutput, &software_icd, OPENGL_ICD_SIZE); /* no 3D use software OPENGL */
+ _fmemcpy(lpOutput, &qemu3dfx_icd, OPENGL_ICD_SIZE);
}
else
{
- _fmemcpy(lpOutput, &vmwsvga_icd, OPENGL_ICD_SIZE); /* accelerated OPENGL */
+ _fmemcpy(lpOutput, &software_icd, OPENGL_ICD_SIZE);
}
-#elif defined(QEMU)
- if(VXD_QEMUFX_supported())
- {
- _fmemcpy(lpOutput, &qemu_icd, OPENGL_ICD_SIZE);
- }
- else
- {
- _fmemcpy(lpOutput, &software_icd, OPENGL_ICD_SIZE);
- }
-
-#else
- _fmemcpy(lpOutput, &software_icd, OPENGL_ICD_SIZE);
-#endif
rc = 1;
}
@@ -764,248 +269,14 @@ LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function,
//DIB_Control(lpDevice, MOUSETRAILS, lpInput, lpOutput);
rc = 1;
}
- else if(function == FBHDA_REQ) /* input: NULL, output: uint32 */
+ else if(function == OP_FBHDA_SETUP) /* input: NULL, output: uint32 */
{
uint32_t __far *lpOut = lpOutput;
- lpOut[0] = FBHDA_linear;
- dbg_printf("FBHDA request: %lX\n", FBHDA_linear);
-
- rc = 1;
- }
- else if(function == FBHDA_UPDATE) /* input RECT, output: NULL */
- {
-#ifdef SVGA
- longRECT __far *lpRECT = lpInput;
- SVGA_UpdateRect(lpRECT->left, lpRECT->top, lpRECT->right - lpRECT->left, lpRECT->bottom - lpRECT->top);
-#endif
- rc = 1;
- }
- else if(function == FBHDA_FLIP) /* input - offset from vram begin */
- {
- uint32_t __far *lpOffset = lpInput;
- uint32_t realOffset = 0;
-#ifdef SVGA
-#if 0
- realOffset = SVGA_Flip(*lpOffset);
- SVGA_UpdateRect(0, 0, wScrX, wScrY);
-#else
- (void)lpOffset;
-#endif
-#else
- realOffset = BOXV_set_offset(0, *lpOffset, wBpp, wScreenPitchBytes);
-#endif
+ lpOut[0] = hda_linear;
+ dbg_printf("FBHDA request: %lX\n", hda_linear);
- FBHDA_ptr->fb_pm32 = dwScreenFlatAddr + realOffset;
-
rc = 1;
}
- else if(function == FBHDA_CTRL)
- {
- uint32_t code = *((uint32_t __far *)lpInput);
-
- switch(code)
- {
- case FBHDA_CTRL_CUR_SHOW:
- cursor_unlock();
- cursor_blit(NULL);
- dbg_printf("FBHDA_CTRL_CUR_SHOW\n");
- break;
- case FBHDA_CTRL_CUR_HIDE:
- cursor_erase(NULL);
- cursor_lock();
- dbg_printf("FBHDA_CTRL_CUR_HIDE\n");
- break;
- }
-
- rc = 1;
- }
-#ifdef SVGA
- else if(function == SVGA_READ_REG) /* input: uint32_t, output: uint32_t */
- {
- unsigned long val;
- unsigned long regname = *((unsigned long __far *)lpInput);
-
- if(regname == SVGA_REG_ID)
- {
- val = gSVGA.deviceVersionId;
- }
- else if(regname == SVGA_REG_CAPABILITIES)
- {
- val = gSVGA.capabilities;
- }
- else
- {
- val = SVGA_ReadReg(regname);
- }
-
- *((unsigned long __far *)lpOutput) = val;
-
- rc = 1;
- }
- else if(function == SVGA_HDA_REQ) /* input: NULL, output: svga_hda_t */
- {
- svga_hda_t __far *lpHDA = lpOutput;
- _fmemcpy(lpHDA, &SVGAHDA, sizeof(svga_hda_t));
- rc = 1;
- }
- else if(function == SVGA_REGION_CREATE) /* input: 2*uint32_t, output: 2*uint32_t */
- {
- uint32_t __far *lpIn = lpInput;
- uint32_t __far *lpOut = lpOutput;
- uint32_t rid = lpIn[0];
-
- dbg_printf("Region id = %ld, max desc = %ld\n", rid, SVGA_ReadReg(SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH));
-
- if(rid)
- {
- uint32_t lAddr;
- uint32_t ppn;
- uint32_t pgblk;
-
- if(VXD_CreateRegion(lpIn[1], &lAddr, &ppn, &pgblk)) /* allocate physical memory */
- {
- dbg_printf("Region address = %lX, PPN = %lX, GMRBLK = %lX\n", lAddr, ppn, pgblk);
-
- SVGA_WriteReg(SVGA_REG_GMR_ID, rid);
- SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, ppn);
-
- /* refresh all register, so make sure that new commands will accepts this region */
- SVGA_Flush();
-
- lpOut[0] = rid;
- lpOut[1] = lAddr;
- lpOut[2] = pgblk;
- }
- else
- {
- lpOut[0] = 0;
- lpOut[1] = 0;
- lpOut[2] = 0;
- }
- }
-
- rc = 1;
- }
- else if(function == SVGA_REGION_FREE) /* input: 2*uint32_t, output: NULL */
- {
- uint32_t __far *lpin = lpInput;
- uint32_t id = lpin[0];
- uint32_t linear = lpin[1];
- uint32_t pgblk = lpin[2];
-
- /* flush all register inc. fifo so make sure, that all commands are processed */
- SVGA_Flush();
-
- SVGA_WriteReg(SVGA_REG_GMR_ID, id);
- SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, 0);
-
- /* sync again */
- SVGA_Flush();
-
- /* region physical delete */
- VXD_FreeRegion(linear, pgblk);
-
- rc = 1;
- }
- else if(function == SVGA_HWINFO_REGS) /* input: NULL, output: 256*uint32_t */
- {
- int i;
- uint32_t __far *lpreg = lpOutput;
- for(i = 0; i < 256; i++)
- {
- *lpreg = SVGA_ReadReg(i);
- lpreg++;
- }
-
- rc = 1;
- }
- else if(function == SVGA_HWINFO_FIFO) /* input: NULL, output: 1024*uint32_t */
- {
- int i;
- uint32_t __far *lpreg = lpOutput;
-
- for(i = 0; i < 1024; i++)
- {
- *lpreg = gSVGA.fifoMem[i];
- lpreg++;
- }
-
- rc = 1;
- }
- else if(function == SVGA_HWINFO_CAPS) /* input: NULL, output: 512*uint32_t */
- {
- int i;
- uint32_t __far *lpreg = lpOutput;
- SVGA3dCapsRecord __far *pCaps;
- SVGA3dCapPair __far *pData;
-
-
- if (gSVGA.capabilities & SVGA_CAP_GBOBJECTS)
- {
- /* new way to read device CAPS */
- for (i = 0; i < 512; i++)
- {
- SVGA_WriteReg(SVGA_REG_DEV_CAP, i);
- lpreg[i] = FixDevCap(i, SVGA_ReadReg(SVGA_REG_DEV_CAP));
- dbg_printf("VMSVGA3d_3: cap[%d]=0x%lX\n", i, lpreg[i]);
- }
- }
- else
- {
- /* old way to read device CAPS */
- pCaps = (SVGA3dCapsRecord __far *)&(gSVGA.fifoMem[SVGA_FIFO_3D_CAPS]);
-
- while(pCaps->header.length != 0)
- {
- dbg_printf("SVGA_FIFO_3D_CAPS: %ld, %ld\n", pCaps->header.type, pCaps->header.length);
- if(pCaps->header.type == SVGA3DCAPS_RECORD_DEVCAPS)
- {
- uint32_t datalen = (pCaps->header.length - 2)/2;
- pData = (SVGA3dCapPair __far *)(&pCaps->data);
- for(i = 0; i < datalen; i++)
- {
- uint32_t id = pData[i][0];
- uint32_t val = pData[i][1];
-
- if(id < 512)
- {
- lpreg[id] = FixDevCap(id, val);
- }
-
- dbg_printf("VMSVGA3d_2: cap[%ld]=0x%lX\n", id, val);
- }
- }
- dbg_printf("SVGA_FIFO_3D_CAPS: end\n");
-
- pCaps = (SVGA3dCapsRecord __far *)((uint32_t __far *)pCaps + pCaps->header.length);
- }
- }
-
- rc = 1;
- }
- else if(function == SVGA_SYNC) /* input: NULL, output: NULL */
- {
- SVGA_Flush();
-
- rc = 1;
- }
- else if(function == SVGA_RING) /* input: NULL, output: NULL */
- {
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
-
- rc = 1;
- }
- else if(function == SVGA_API) /* input: NULL, output: 2x DWORD */
- {
- uint32_t __far *lpver = lpOutput;
-
- lpver[0] = DRV_API_LEVEL;
-
- lpver[1] = VXD_apiver();
-
- rc = 1;
- }
-#endif /* SVGA only */
/* if command accepted, return */
if(rc >= 0)
diff --git a/control_qemu.c b/control_qemu.c
deleted file mode 100644
index 9bfc8a3..0000000
--- a/control_qemu.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define QEMU
-#include "control.c"
diff --git a/control_svga.c b/control_svga.c
deleted file mode 100644
index e9004cf..0000000
--- a/control_svga.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SVGA
-#include "control.c"
diff --git a/cursor.h b/cursor.h
new file mode 100644
index 0000000..99784f7
--- /dev/null
+++ b/cursor.h
@@ -0,0 +1,17 @@
+#ifndef __CURSOR_H__INCLUDED__
+#define __CURSOR_H__INCLUDED__
+
+/* from DDK98 */
+#pragma pack(push)
+#pragma pack(1)
+typedef struct _CURSORSHAPE
+{
+ int xHotSpot, yHotSpot;
+ int cx, cy;
+ int cbWidth;
+ BYTE Planes;
+ BYTE BitsPixel;
+} CURSORSHAPE;
+#pragma pack(pop)
+
+#endif /* __CURSOR_H__INCLUDED__ */
diff --git a/dbgprint32.c b/dbgprint32.c
index 3608351..1d81ce3 100644
--- a/dbgprint32.c
+++ b/dbgprint32.c
@@ -1,2 +1 @@
-#define VXD32
#include "dbgprint.c"
diff --git a/dddrv.c b/dddrv.c
index 5581510..eb9c530 100644
--- a/dddrv.c
+++ b/dddrv.c
@@ -34,6 +34,7 @@ THE SOFTWARE.
#include <string.h> /* _fmemset */
#include <stddef.h>
+#include "3d_accel.h"
#include "vmdahal.h"
const static DD32BITDRIVERDATA_t drv_bridge99 = {
@@ -551,8 +552,8 @@ BOOL DDCreateDriverObject(int bReset)
dbg_printf(" GetDriverInfo = %lX\n", hal->ddHALInfo.GetDriverInfo);
dbg_printf(" WaitForVerticalBlank = %lX\n\n", cbDDCallbacks.WaitForVerticalBlank);
- hal->pFBHDA32 = FBHDA_linear;
- hal->pFBHDA16 = FBHDA_ptr;
+ hal->pFBHDA32 = hda_linear;
+ hal->pFBHDA16 = hda;
hal->FBHDA_version = 2;
return lpDDHAL_SetInfo(&(hal->ddHALInfo), bReset);
diff --git a/dibcall.c b/dibcall.c
index 9b47da2..5ad5d7e 100644
--- a/dibcall.c
+++ b/dibcall.c
@@ -30,9 +30,7 @@ THE SOFTWARE.
#include <string.h>
#include "minidrv.h"
-#include "swcursor.h"
-#include "hwcursor.h"
-
+#include "cursor.h"
/*
* What's this all about? Most of the required exported driver functions can
@@ -49,76 +47,33 @@ THE SOFTWARE.
* are not hardware specific.
*/
-LONG cursorX = 0;
-LONG cursorY = 0;
-
#pragma code_seg( _TEXT )
void WINAPI __loadds MoveCursor(WORD absX, WORD absY)
{
if(wEnabled)
{
-#ifdef SVGA
- if(!hwcursor_move(absX, absY))
- {
-#endif // SVGA
- longRECT changes = {0,0,0,0};
- cursorX = absX;
- cursorY = absY;
- cursor_move(&changes);
-#ifdef SVGA
- SVGA_UpdateLongRect(&changes);
- }
-#endif // SVGA
+ DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
}
-
- //DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
}
WORD WINAPI __loadds SetCursor_driver(CURSORSHAPE __far *lpCursor)
{
- if(!sw_cursor)
- {
- cursor_init();
- }
-
if(wEnabled)
{
-#ifdef SVGA
- if(!hwcursor_load(lpCursor))
- {
-#endif // SVGA
- longRECT changes = {0,0,0,0};
-
- if(lpCursor)
- {
- cursor_load(lpCursor, &changes);
- }
- else
- {
- cursor_unload(&changes);
- }
-#ifdef SVGA
- SVGA_UpdateLongRect(&changes);
- }
-#endif // SVGA
-
- return 1;
+ DIB_SetCursorExt(lpCursor, lpDriverPDevice);
}
+
return 0;
}
/* Exported as DISPLAY.104 */
void WINAPI __loadds CheckCursor( void )
{
- if( wEnabled )
+ if(wEnabled)
{
-#ifdef SVGA
- hwcursor_update();
-#endif // SVGA
+ DIB_CheckCursorExt(lpDriverPDevice);
}
-
- //DIB_CheckCursorExt( lpDriverPDevice );
}
/* If there is no hardware screen-to-screen BitBlt, there's no point in
diff --git a/dibcall_svga.c b/dibcall_svga.c
deleted file mode 100644
index 3089eb8..0000000
--- a/dibcall_svga.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SVGA
-#include "dibcall.c"
diff --git a/enable.c b/enable.c
index 775da9a..405dcb9 100644
--- a/enable.c
+++ b/enable.c
@@ -30,14 +30,9 @@ THE SOFTWARE.
#include <minivdd.h>
#include "minidrv.h"
-#include "swcursor.h"
-#include "hwcursor.h"
-
#include <string.h>
-#ifdef SVGA
-# include "svga_all.h"
-#endif
+#include "3d_accel.h"
/* Pretend we have a 208 by 156 mm screen. */
#define DISPLAY_HORZ_MM 208
@@ -146,51 +141,30 @@ DWORD PASCAL CreateDIBPDeviceX( LPBITMAPINFO lpInfo, LPPDEVICE lpDevice, LPVOID
"shr eax, 16" \
"xchg ax, dx"
-
-static longRECT updateRect = {0, 0, 0, 0};
-
#pragma code_seg( _INIT )
-VOID WINAPI __loadds BeginAccess_DIB( LPPDEVICE lpDevice, WORD wLeft, WORD wTop, WORD wRight, WORD wBottom, WORD wFlags )
+VOID WINAPI __loadds BeginAccess_VXD( LPPDEVICE lpDevice, WORD wLeft, WORD wTop, WORD wRight, WORD wBottom, WORD wFlags )
{
- longRECT r;
-
-#ifdef SVGA
- if(!hwcursor_available())
+ DWORD dflags = 0;
+ if(!(wFlags & CURSOREXCLUDE))
{
-#endif
- updateRect.left = wLeft;
- updateRect.top = wTop;
- updateRect.right = wRight;
- updateRect.bottom = wBottom;
-
- cursor_erase(&r);
- cursor_lock();
- cursor_merge_rect(&updateRect, &r);
-#ifdef SVGA
+ dflags |= FBHDA_IGNORE_CURSOR;
}
-#endif
+ FBHDA_access_begin(dflags);
DIB_BeginAccess(lpDevice, wLeft, wTop, wRight, wBottom, wFlags);
}
-VOID WINAPI __loadds EndAccess_DIB( LPPDEVICE lpDevice, WORD wFlags )
+VOID WINAPI __loadds EndAccess_VXD( LPPDEVICE lpDevice, WORD wFlags )
{
- longRECT r;
- DIB_EndAccess(lpDevice, wFlags);
-
-#ifdef SVGA
- if(!hwcursor_available())
+ DWORD dflags = 0;
+ if(!(wFlags & CURSOREXCLUDE))
{
-#endif
- cursor_unlock();
- cursor_blit(&r);
- cursor_merge_rect(&updateRect, &r);
-#ifdef SVGA
+ dflags |= FBHDA_IGNORE_CURSOR;
}
- SVGA_UpdateRect(updateRect.left, updateRect.top,
- updateRect.right-updateRect.left, updateRect.bottom-updateRect.top);
-#endif
+
+ DIB_EndAccess(lpDevice, wFlags);
+ FBHDA_access_end(dflags);
}
@@ -290,8 +264,8 @@ UINT WINAPI __loadds Enable( LPVOID lpDevice, UINT style, LPSTR lpDeviceType,
dbg_printf( "Enable: CreateDIBPDevice returned %lX\n", dwRet );
/* Now fill out the begin/end access callbacks. */
- lpEng->deBeginAccess = BeginAccess_DIB;
- lpEng->deEndAccess = EndAccess_DIB;
+ lpEng->deBeginAccess = BeginAccess_VXD;
+ lpEng->deEndAccess = EndAccess_VXD;
/* Program the DAC in non-direct color modes. */
if( wBpp <= 8 ) {
diff --git a/enable_svga.c b/enable_svga.c
deleted file mode 100644
index 845c3fc..0000000
--- a/enable_svga.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SVGA
-#include "enable.c"
diff --git a/hwcursor.c b/hwcursor.c
deleted file mode 100644
index 7da8191..0000000
--- a/hwcursor.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2023 Jaroslav Hensl
-
-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 SVGA
-
-#include "winhack.h"
-#include <gdidefs.h>
-#include <dibeng.h>
-#include <minivdd.h>
-#include <string.h>
-
-#include "minidrv.h"
-#include "swcursor.h"
-#include "hwcursor.h"
-
-#include "svga_all.h"
-#include "vxdcall.h"
-
-/* from control.c */
-#define LOCK_FIFO 6
-BOOL SVGAHDA_trylock(DWORD lockid);
-void SVGAHDA_unlock(DWORD lockid);
-
-static BOOL cursorVisible = FALSE;
-
-static LONG cursorW = 0;
-static LONG cursorH = 0;
-static LONG cursorHX = 0;
-static LONG cursorHY = 0;
-
-#pragma code_seg( _TEXT )
-
-/*
- https://learn.microsoft.com/en-us/windows-hardware/drivers/display/drawing-monochrome-pointers
-*/
-static void CursorMonoToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
-{
- LONG __far *px = data;
- BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
- BYTE __far *xormask = andmask + lpCursor->cbWidth*lpCursor->cy;
- int xi, xj, y;
-
- dbg_printf("CursorMonoToAlpha\n");
-
- for(y = 0; y < lpCursor->cy; y++)
- {
- for(xj = 0; xj < (lpCursor->cbWidth); xj++)
- {
- BYTE a = andmask[lpCursor->cbWidth*y + xj];
- BYTE x = xormask[lpCursor->cbWidth*y + xj];
- for(xi = 7; xi >= 0; xi--)
- {
- BYTE mx = (((a >> xi) & 0x1) << 1) | ((x >> xi) & 0x1);
-
- switch(mx)
- {
- case 0:
- *px = 0xFF000000; // full black
- break;
- case 1:
- *px = 0xFFFFFFFF; // full white
- break;
- case 2:
- *px = 0x00000000; // transparent
- break;
- case 3:
- *px = 0xFF000000; // inverse = set black (used for example with type cursor)
- break;
- }
-
- px++;
- }
- }
- }
-}
-
-static void CursorColor32ToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
-{
- LONG __far *px = data;
- BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
- DWORD __far *xormask = (DWORD __far *)(andmask + lpCursor->cbWidth*lpCursor->cy);
- int xi, xj, y;
-
- dbg_printf("CursorColor32ToAlpha\n");
-
- for(y = 0; y < lpCursor->cy; y++)
- {
- for(xj = 0; xj < (lpCursor->cbWidth); xj++)
- {
- BYTE a = andmask[lpCursor->cbWidth*y + xj];
-
- for(xi = 7; xi >= 0; xi--)
- {
- DWORD x = xormask[lpCursor->cx*y + xj*8 + (7-xi)] & 0x00FFFFFFUL;
- BYTE ab = ((a >> xi) & 0x1);
-
- switch(ab)
- {
- case 0:
- *px = 0xFF000000UL | x;
- break;
- case 1:
- *px = 0x00000000UL | x;
- break;
- }
-
- px++;
- }
- }
- }
-}
-
-void SVGA_UpdateLongRect(longRECT __far *rect)
-{
- if(wBpp == 32)
- {
- long w = rect->right - rect->left;
- long h = rect->bottom - rect->top;
- if(w > 0)
- {
- SVGA_UpdateRect(rect->left, rect->top, w, h);
- }
- }
-}
-
-BOOL hwcursor_move(WORD absX, WORD absY)
-{
- if(wBpp != 32)
- {
- return FALSE;
- }
-
- if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
- {
- return FALSE;
- }
-
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_MoveCursor(cursorVisible, absX, absY, 0);
- SVGAHDA_unlock(LOCK_FIFO);
- }
-
- cursorX = absX;
- cursorY = absY;
-
- return TRUE;
-}
-
-BOOL hwcursor_load(CURSORSHAPE __far *lpCursor)
-{
- void __far* ANDMask = NULL;
- void __far* XORMask = NULL;
- void __far* AData = NULL;
- SVGAFifoCmdDefineCursor cur;
- SVGAFifoCmdDefineAlphaCursor acur;
-
- if(wBpp != 32)
- {
- return FALSE;
- }
-
- if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
- {
- return FALSE;
- }
-
- if(lpCursor != NULL)
- {
- dbg_printf("cx: %d, cy: %d, colors: %d\n", lpCursor->cx, lpCursor->cy, lpCursor->BitsPixel);
-
- dbg_printf("flags %lx\n", gSVGA.userFlags);
-
- if(gSVGA.userFlags & SVGA_USER_FLAGS_ALPHA_CUR)
- {
- acur.id = 0;
- acur.hotspotX = lpCursor->xHotSpot;
- acur.hotspotY = lpCursor->yHotSpot;
- acur.width = lpCursor->cx;
- acur.height = lpCursor->cy;
-
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_BeginDefineAlphaCursor(&acur, &AData);
- if(AData)
- {
- switch(lpCursor->BitsPixel)
- {
- case 1:
- CursorMonoToAlpha(lpCursor, AData);
- break;
- case 32:
- CursorColor32ToAlpha(lpCursor, AData);
- break;
- }
- }
- VXD_FIFOCommitAll();
- SVGAHDA_unlock(LOCK_FIFO);
- }
- }
- else
- {
- cur.id = 0;
- cur.hotspotX = lpCursor->xHotSpot;
- cur.hotspotY = lpCursor->yHotSpot;
- cur.width = lpCursor->cx;
- cur.height = lpCursor->cy;
- cur.andMaskDepth = 1;
- cur.xorMaskDepth = lpCursor->BitsPixel;
-
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
-
- if(ANDMask)
- {
- _fmemcpy(ANDMask, lpCursor+1, lpCursor->cbWidth*lpCursor->cy);
- }
-
- if(XORMask)
- {
- BYTE __far *ptr = (BYTE __far *)(lpCursor+1);
- ptr += lpCursor->cbWidth*lpCursor->cy;
-
- _fmemcpy(XORMask, ptr, lpCursor->cx*lpCursor->cy*((lpCursor->BitsPixel+7)/8));
- }
-
- VXD_FIFOCommitAll();
- SVGAHDA_unlock(LOCK_FIFO);
- }
- }
-
- /* move cursor to last known position */
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_MoveCursor(cursorVisible, cursorX, cursorY, 0);
- SVGAHDA_unlock(LOCK_FIFO);
- }
-
- cursorVisible = TRUE;
-
- cursorW = lpCursor->cx;
- cursorH = lpCursor->cy;
- cursorHX = lpCursor->xHotSpot;
- cursorHY = lpCursor->yHotSpot;
- }
- else
- {
- /* virtual box bug on SVGA_MoveCursor(FALSE, ...)
- * so if is cursor NULL, create empty
- */
- cur.id = 0;
- cur.hotspotX = 0;
- cur.hotspotY = 0;
- cur.width = 32;
- cur.height = 32;
- cur.andMaskDepth = 1;
- cur.xorMaskDepth = 1;
-
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
-
- if(ANDMask) _fmemset(ANDMask, 0xFF, 4*32);
- if(XORMask) _fmemset(XORMask, 0, 4*32);
-
- //SVGA_FIFOCommitAll();
- VXD_FIFOCommitAll();
-
- SVGA_MoveCursor(FALSE, 0, 0, 0);
-
- SVGAHDA_unlock(LOCK_FIFO);
- }
- cursorVisible = FALSE;
- }
-
- dbg_printf("hwcursor_load\n");
-
- return TRUE;
-}
-
-void hwcursor_update()
-{
- if(wBpp == 32)
- {
- if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) != 0)
- {
- LONG x = cursorX - cursorHX;
- LONG y = cursorY - cursorHY;
- LONG w = cursorW;
- LONG h = cursorH;
-
- SVGA_UpdateRect(x, y, w, h);
- }
- }
-}
-
-BOOL hwcursor_available()
-{
- if(wBpp != 32)
- {
- return FALSE;
- }
-
- if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
- {
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/hwcursor.h b/hwcursor.h
deleted file mode 100644
index 557c7d3..0000000
--- a/hwcursor.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __HWCURSOR_INCLUDED__
-#define __HWCURSOR_INCLUDED__
-
-void SVGA_UpdateLongRect(longRECT __far *rect);
-BOOL hwcursor_move(WORD absX, WORD absY);
-BOOL hwcursor_load(CURSORSHAPE __far *lpCursor);
-void hwcursor_update();
-BOOL hwcursor_available();
-
-#endif
diff --git a/init.c b/init.c
index 510a27f..8a66f1e 100644
--- a/init.c
+++ b/init.c
@@ -32,13 +32,8 @@ THE SOFTWARE.
#include "minidrv.h"
#include <configmg.h>
-#ifdef SVGA
-#include <stdint.h>
-#endif
-
-#if defined(SVGA) || defined(QEMU)
-# include "vxdcall.h"
-#endif
+#include "pm16_calls.h"
+#include "3d_accel.h"
/* GlobalSmartPageLock is a semi-undocumented function. Not officially
* documented but described in KB Article Q180586. */
@@ -318,9 +313,19 @@ UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
dbg_printf("DriverInit: LfbBase is %lX\n", LfbBase);
- if(!VXD_load())
+ /* connect to 32bit RING-0 driver */
+ if(!VXD_VM_connect())
{
- dbg_printf("VXD load failure!\n");
+ 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;
}
@@ -344,14 +349,21 @@ UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
/* Read the display configuration before doing anything else. */
ReadDisplayConfig();
-#ifdef SVGA
/* connect to 32bit RING-0 driver */
- if(!VXD_load())
+ if(!VXD_VM_connect())
{
- dbg_printf("VXD load failure!\n");
+ 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;
}
-#endif
return( 1 ); /* Success. */
}
diff --git a/makefile b/makefile
index 9297caa..f310c06 100644
--- a/makefile
+++ b/makefile
@@ -1,11 +1,13 @@
-OBJS = dibthunk.obj dibcall.obj enable.obj init.obj palette.obj &
- scrsw.obj sswhook.obj modes.obj boxv.obj control.obj &
- drvlib.obj vxdcall_svga.obj minivdd_svga.obj vmwsvxd.obj &
- scrsw_svga.obj control_svga.obj modes_svga.obj palette_svga.obj &
- pci.obj svga.obj svga3d.obj svga32.obj pci32.obj dddrv.obj &
- enable_svga.obj dibcall_svga.obj boxv_qemu.obj modes_qemu.obj &
- init_qemu.obj init_svga.obj qemuvxd.obj minivdd_qemu.obj &
- vxdcall_qemu.obj control_qemu.obj swcursor.obj hwcursor.obj
+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 &
+ 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 &
+
+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
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
@@ -19,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
@@ -32,7 +34,7 @@ DBGFILE =
DBGFILE32 =
!endif
CFLAGS = -q -wx -s -zu -zls -6 -fp6
-CFLAGS32 = -q -wx -s -zls -6s -fp6 -mf
+CFLAGS32 = -q -wx -s -zls -6s -fp6 -mf -DVXD32
CC = wcc
CC32 = wcc386
@@ -41,52 +43,32 @@ CC32 = wcc386
CFLAGS32 += -DCOM2
!endif
-all : boxvmini.drv vmwsmini.drv qemumini.drv vmwsmini.vxd qemumini.vxd
-
-# Object files
-drvlib.obj : drvlib.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+#all : boxvmini.drv vmwsmini.drv qemumini.drv vmwsmini.vxd qemumini.vxd
+all : vmwsmini.drv vmwsmini.vxd
+# Object files: PM16 RING-3
boxv.obj : boxv.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
boxv_qemu.obj : boxv_qemu.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-pci.obj : vmware/pci.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
-pci32.obj : vmware/pci32.c .autodepend
- $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
-
-svga.obj : vmware/svga.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
-svga32.obj : vmware/svga32.c .autodepend
- $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
-
-svga3d.obj : vmware/svga3d.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
dbgprint.obj : dbgprint.c .autodepend
$(CC) $(CFLAGS) -zW $(FLAGS) $<
-dbgprint32.obj : dbgprint32.c .autodepend
- $(CC32) $(CFLAGS32) $(FLAGS) $<
-
dibcall.obj : dibcall.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
-dibcall_svga.obj : dibcall_svga.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
dibthunk.obj : dibthunk.asm
wasm -q $(FLAGS) $<
-enable.obj : enable.c .autodepend
+dddrv.obj : dddrv.c .autodepend
+ $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+
+drvlib.obj: drvlib.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-enable_svga.obj : enable_svga.c .autodepend
+enable.obj : enable.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
init.obj : init.c .autodepend
@@ -101,24 +83,18 @@ init_svga.obj : init_svga.c .autodepend
control.obj : control.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-control_svga.obj : control_svga.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
-control_qemu.obj : control_qemu.c .autodepend
+pm16_calls.obj : pm16_calls.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-vxdcall_svga.obj : vxdcall_svga.c .autodepend
+pm16_calls_svga.obj : pm16_calls_svga.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-vxdcall_qemu.obj : vxdcall_qemu.c .autodepend
+pm16_calls_qemu.obj : pm16_calls_qemu.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
palette.obj : palette.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-palette_svga.obj : palette_svga.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-
sswhook.obj : sswhook.asm
wasm -q $(FLAGS) $<
@@ -137,26 +113,43 @@ scrsw.obj : scrsw.c .autodepend
scrsw_svga.obj : scrsw_svga.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
-vmwsvxd.obj : vmwsvxd.c .autodepend
- $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+# Object files: PM32 RING-0
+
+dbgprint32.obj : dbgprint32.c .autodepend
+ $(CC32) $(CFLAGS32) $(FLAGS) $<
-qemuvxd.obj : qemuvxd.c .autodepend
+svga.obj : vmware/svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
-minivdd_svga.obj : minivdd_svga.c .autodepend
+pci.obj : vmware/pci.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
-minivdd_qemu.obj : minivdd_qemu.c .autodepend
+vxd_fbhda.obj : vxd_fbhda.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
-dddrv.obj : dddrv.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+vxd_lib.obj : vxd_lib.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
-swcursor.obj: swcursor.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+vxd_main.obj : vxd_main.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
-hwcursor.obj: hwcursor.c .autodepend
- $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+vxd_main_qemu.obj : vxd_main_qemu.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
+vxd_main_svga.obj : vxd_main_svga.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
+vxd_svga.obj : vxd_svga.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
+vxd_vdd.obj : vxd_vdd.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
+vxd_vdd_qemu.obj : vxd_vdd_qemu.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
+vxd_vdd_svga.obj : vxd_vdd_svga.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
# Resources
boxvmini.res : res/boxvmini.rc res/colortab.bin res/config.bin res/fonts.bin res/fonts120.bin .autodepend
@@ -262,23 +255,18 @@ import GlobalSmartPageLock KERNEL.230
vmwsmini.drv : $(OBJS) vmwsmini.res dibeng.lib
wlink op quiet, start=DriverInit_ disable 2055 $(DBGFILE) @<<vmwsmini.lnk
system windows dll initglobal
+file dibcall.obj
file dibthunk.obj
-file dibcall_svga.obj
+file dddrv.obj
file drvlib.obj
-file enable_svga.obj
+file enable.obj
file init_svga.obj
-file palette_svga.obj
-file scrsw_svga.obj
+file control.obj
+file pm16_calls_svga.obj
+file palette.obj
file sswhook.obj
file modes_svga.obj
-file svga.obj
-file svga3d.obj
-file pci.obj
-file control_svga.obj
-file vxdcall_svga.obj
-file dddrv.obj
-file swcursor.obj
-file hwcursor.obj
+file scrsw_svga.obj
name vmwsmini.drv
option map=vmwsmini.map
library dibeng.lib
@@ -406,10 +394,13 @@ system win_vxd dynamic
option map=vmwsvxd.map
option nodefaultlibs
name vmwsmini.vxd
-file vmwsvxd.obj
-file minivdd_svga.obj
-file pci32.obj
-file svga32.obj
+file vxd_main_svga.obj
+file svga.obj
+file pci.obj
+file vxd_fbhda.obj
+file vxd_lib.obj
+file vxd_svga.obj
+file vxd_vdd_svga.obj
segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
diff --git a/minidrv.h b/minidrv.h
index 6ada593..6194938 100644
--- a/minidrv.h
+++ b/minidrv.h
@@ -90,8 +90,6 @@ extern WORD OurVMHandle;
extern DWORD LfbBase;
#endif
-extern WORD wMesa3DEnabled; /* Is possible to accelerate though Mesa3D SVGA */
-
WORD CalcPitch(WORD x, WORD bpp);
typedef void (__far * FastBitBlt_t) (unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h);
@@ -104,39 +102,10 @@ typedef struct _longRECT {
LONG bottom;
} longRECT;
-/*
- * frame buffer direct hadrware access, allow user space programs/drivers write
- * to device frame buffer directly
- */
-#pragma pack(push)
-#pragma pack(1)
-typedef struct _FBHDA
-{
- DWORD width;
- DWORD height;
- DWORD bpp;
- DWORD pitch;
- DWORD fb_pm32; /* eq. linear address, mapped to shared or kernel space*/
- void __far * fb_pm16; /* usable in this driver */
- DWORD flags;
- volatile DWORD lock; /* lock for framebuffer operations */
- DWORD vram_pm32;
- void __far * vram_pm16;
- DWORD vram_size;
-} FBHDA;
-
-#pragma pack(pop)
-
-#define FBHDA_SIZE 4096 /* alloc whole page */
-
-#define FBHDA_NEED_UPDATE 1
-#define FBHDA_LOCKING 2
-#define FBHDA_FLIPING 4
-#define FBHDA_SW_CURSOR 8
-//#define FBHDA_NO_CURSOR 16
-
-extern FBHDA __far * FBHDA_ptr;
-extern DWORD FBHDA_linear;
+typedef struct FBHDA FBHDA_t;
+
+extern FBHDA_t __far * hda;
+extern DWORD hda_linear;
/* Inlines needed in multiple modules. */
diff --git a/minivdd_qemu.c b/minivdd_qemu.c
deleted file mode 100644
index 2a30644..0000000
--- a/minivdd_qemu.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#define VXD32
-#define QEMU
-#include "minivdd.c"
diff --git a/minivdd_svga.c b/minivdd_svga.c
deleted file mode 100644
index 25ebaac..0000000
--- a/minivdd_svga.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#define VXD32
-#define SVGA
-#include "minivdd.c"
diff --git a/modes.c b/modes.c
index 42b3e45..21aa9f9 100644
--- a/modes.c
+++ b/modes.c
@@ -2,7 +2,7 @@
Copyright (c) 2022 Michal Necasek
2023 Philip Kelley
- 2023 Jaroslav Hensl
+ 2023-2024 Jaroslav Hensl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -35,13 +35,7 @@ THE SOFTWARE.
#include "minidrv.h"
#include "boxv.h"
-#ifdef SVGA
-# include "svga_all.h"
-#endif
-
-#if defined(SVGA) || defined(QEMU)
-# include "vxdcall.h"
-#endif
+#include "3d_accel.h"
#include "drvlib.h"
#include "dpmi.h"
@@ -49,45 +43,19 @@ THE SOFTWARE.
#include <string.h> /* _fmemset */
#include <stdlib.h> /* abs */
-/* Somewhat arbitrary max resolution. */
-#ifdef VRAM256MB
-/* (max) 256MB VRAM: max 8K in 16:10 */
-#define RES_MAX_X 8192
-#define RES_MAX_Y 5120
-#else
-/* (max) 128MB VRAM: max 5K in 5:4 */
-#define RES_MAX_X 5120
-#define RES_MAX_Y 4096
-#endif
-
-
WORD wScreenX = 0;
WORD wScreenY = 0;
WORD BitBltDevProc = 0;
WORD ScreenSelector = 0;
WORD wPDeviceFlags = 0;
-#ifdef SVGA
-WORD wMesa3DEnabled = 0; /* 3D is enabled (by hypervisor) */
-#endif
-
/* FBHDA structure pointers */
-FBHDA __far * FBHDA_ptr = NULL;
-
-DWORD FBHDA_linear = 0;
+FBHDA_t __far * hda = NULL;
+DWORD hda_linear = 0;
- DWORD dwScreenFlatAddr = 0; /* 32-bit flat address of VRAM. */
- DWORD dwVideoMemorySize = 0; /* Installed VRAM in bytes. */
- WORD wScreenPitchBytes = 0; /* Current scanline pitch. */
-#ifndef SVGA
-static DWORD dwPhysVRAM = 0; /* Physical LFB base address. */
-#endif
-
-/* These are currently calculated not needed in the absence of
- * offscreen video memory.
- */
-static WORD wMaxWidth = 0;
-static WORD wMaxHeight = 0;
+DWORD dwScreenFlatAddr = 0; /* 32-bit flat address of VRAM. */
+DWORD dwVideoMemorySize = 0; /* Installed VRAM in bytes. */
+ WORD wScreenPitchBytes = 0; /* Current scanline pitch. */
/* On Entry:
* EAX = Function code (VDD_DRIVER_REGISTER)
@@ -117,20 +85,6 @@ extern DWORD CallVDDRegister( WORD Function, WORD wPitch, WORD wHeight, void _fa
parm [bx] [ax] [dx] [es di];
-/* from control.c */
-#ifdef SVGA
-void SVGAHDA_init();
-void SVGAHDA_setmode();
-WORD SVGA_3DSupport();
-void SVGAHDA_update(DWORD width, DWORD height, DWORD bpp, DWORD pitch);
-BOOL SVGAHDA_lock(DWORD lockid);
-BOOL SVGAHDA_trylock(DWORD lockid);
-void SVGAHDA_unlock(DWORD lockid);
-
-#define LOCK_FIFO 6
-
-#endif
-
#pragma code_seg( _INIT );
/* Take a mode descriptor and change it to be a valid
@@ -163,6 +117,7 @@ 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.
*/
@@ -174,6 +129,7 @@ WORD FixModeInfo( LPMODEDESC lpMode )
lpMode->yRes = RES_MAX_Y;
rc = 0;
}
+#endif
return( rc );
}
@@ -198,7 +154,6 @@ WORD CalcPitch( WORD x, WORD bpp )
static int IsModeOK( WORD wXRes, WORD wYRes, WORD wBpp )
{
MODEDESC mode;
- DWORD dwModeMem;
mode.bpp = wBpp;
mode.xRes = wXRes;
@@ -208,35 +163,11 @@ static int IsModeOK( WORD wXRes, WORD wYRes, WORD wBpp )
if( !FixModeInfo( &mode ) )
return( 0 );
-#if defined(SVGA) || defined(QEMU)
- /* not working in vmware, in vbox is working without acceleration, so only confusing users */
- if(wBpp == 24)
- {
- return 0;
- }
-#endif
-
-#ifdef SVGA
- /* some implementations not support 8 and 16 bpp */
- if((gSVGA.userFlags & SVGA_USER_FLAGS_32BITONLY) && wBpp != 32)
- {
- return 0;
- }
-#endif
-
- /* Make sure there's enough VRAM for it. */
- dwModeMem = (DWORD)CalcPitch( wXRes, wBpp ) * wYRes;
- if( dwModeMem > dwVideoMemorySize )
- return( 0 );
-
#ifdef SVGA
- /* even if SVGA support other bpp, they are not usable
- if they're larger than traceable size */
- if(wBpp != 32)
- {
- if(dwModeMem > SVGA_FB_MAX_TRACEABLE_SIZE)
- return 0;
- }
+ if(!SVGA_validmode(wXRes, wYRes, wBpp))
+ {
+ return 0;
+ }
#endif
return( 1 );
@@ -248,293 +179,9 @@ static int IsModeOK( WORD wXRes, WORD wYRes, WORD wBpp )
*/
static void ClearVisibleScreen( void )
{
-#if 0
- LPDWORD lpScr;
- WORD wLines = wScreenY;
- WORD i;
-
- lpScr = ScreenSelector :> 0;
- while( wLines-- ) {
- for( i = 0; i < wScreenPitchBytes / 4; ++i )
- {
- lpScr[i] = 0;
- }
- lpScr += wScreenPitchBytes; // Scanline pitch.
- }
-#endif
-#ifdef SVGA
- DWORD dwPS = ((wBpp+7) >> 3);
- DWORD cb = ((DWORD)wScreenY)*((DWORD)wScreenX)*dwPS;
- VXD_zeromem(dwScreenFlatAddr, cb);
- SVGA_UpdateRect(0, 0, wScreenX, wScreenY);
-#else
- DWORD dwLinestart = 0;
- WORD wLines = wScreenY;
- WORD wPS = ((wBpp+7) >> 3);
-
- while(wLines--)
- {
- drv_memset_large(dwScreenFlatAddr, dwLinestart, 0, (DWORD)wScreenX*wPS);
-
- dwLinestart += (DWORD)wScreenPitchBytes;
- }
-#endif
-}
-
-#ifndef SVGA
-/* Map physical memory to memory space, lpLinAddress is option pointer to store
- * mapped linear address
- */
-static DWORD AllocLinearSelector(DWORD dwPhysAddr, DWORD dwSize, DWORD __far * lpLinAddress)
-{
- WORD wSel;
- DWORD dwLinear;
-
- wSel = DPMI_AllocLDTDesc( 1 ); /* One descriptor, please. */
- if( !wSel )
- return( 0 );
-
- /* Map the framebuffer physical memory. */
- dwLinear = DPMI_MapPhys( dwPhysAddr, dwSize );
-
- /* Now set the allocated selector to point to VRAM. */
- DPMI_SetSegBase( wSel, dwLinear );
- DPMI_SetSegLimit( wSel, dwSize - 1 );
-
- if(lpLinAddress != NULL)
- {
- *lpLinAddress = dwLinear;
- }
-
- return( wSel );
-}
-#endif
-
-#ifdef SVGA
-/*
- * Define the screen for accelerated rendering.
- * Color depth can by select by set: screen.backingStore.pitch
- */
-static void SVGA_defineScreen(unsigned wXRes, unsigned wYRes, unsigned wBpp)
-{
- SVGAFifoCmdDefineScreen __far *screen;
- SVGAFifoCmdDefineGMRFB __far *fbgmr;
-
- /* create screen 0 */
- screen = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_SCREEN, sizeof(SVGAFifoCmdDefineScreen));
-
- if(screen)
- {
- _fmemset(screen, 0, sizeof(SVGAFifoCmdDefineScreen));
- screen->screen.structSize = sizeof(SVGAScreenObject);
- screen->screen.id = 0;
- screen->screen.flags = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
- screen->screen.size.width = wXRes;
- screen->screen.size.height = wYRes;
- screen->screen.root.x = 0;
- screen->screen.root.y = 0;
- screen->screen.cloneCount = 0;
-
- if(wBpp < 32)
- {
- screen->screen.backingStore.pitch = CalcPitch(wXRes, wBpp);
- }
-
- screen->screen.backingStore.ptr.offset = 0;
- screen->screen.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
-
- //screen->screen.backingStore.pitch = CalcPitch(wXRes, wBpp);
-
- VXD_FIFOCommitAll();
- }
-
- /* set GMR to same location as screen */
- if(wBpp >= 15/* || wBpp < 32*/)
- {
- fbgmr = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_GMRFB, sizeof(SVGAFifoCmdDefineGMRFB));
-
- if(fbgmr)
- {
- fbgmr->ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
- fbgmr->ptr.offset = 0;
- fbgmr->bytesPerLine = CalcPitch(wXRes, wBpp);
- fbgmr->format.colorDepth = wBpp;
- if(wBpp >= 24)
- {
- fbgmr->format.bitsPerPixel = 32;
- fbgmr->format.colorDepth = 24;
- fbgmr->format.reserved = 0;
- }
- else
- {
- fbgmr->format.bitsPerPixel = 16;
- fbgmr->format.colorDepth = 16;
- fbgmr->format.reserved = 0;
- }
-
- VXD_FIFOCommitAll();
- }
- }
+ FBHDA_clean();
}
-/* Check if screen acceleration is available */
-BOOL SVGA_hasAccelScreen()
-{
- if(SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT | SVGA_FIFO_CAP_SCREEN_OBJECT_2))
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void VXD_Update(uint32 x, uint32 y, uint32 width, uint32 height)
-{
- SVGAFifoCmdUpdate FARP *cmd = SVGA_FIFOReserveCmd(SVGA_CMD_UPDATE, sizeof *cmd);
- cmd->x = x;
- cmd->y = y;
- cmd->width = width;
- cmd->height = height;
- VXD_FIFOCommitAll();
-}
-
-static DWORD SVGA_partial_update_cnt = 0;
-
-/* Update screen rect if its relevant */
-extern void __loadds SVGA_UpdateRect(LONG x, LONG y, LONG w, LONG h)
-{
- /* SVGA commands works only for 32 bpp surfaces */
- if(wBpp != 32)
- {
- return;
- }
-
- if(SVGA_partial_update_cnt++ > SVGA_PARTIAL_UPDATE_MAX)
- {
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- VXD_Update(0, 0, wScreenX, wScreenY);
- SVGAHDA_unlock(LOCK_FIFO);
- SVGA_partial_update_cnt = 0;
- }
- return;
- }
-
- if(x < 0) x = 0;
- if(y < 0) y = 0;
- if(x+w > wScreenX) w = wScreenX - x;
- if(y+h > wScreenY) y = wScreenY - h;
-
- if(w > 0 && h > 0)
- {
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- VXD_Update(x, y, w, h);
- SVGAHDA_unlock(LOCK_FIFO);
- }
- else
- {
- /* update full screen next time! */
- SVGA_partial_update_cnt = SVGA_PARTIAL_UPDATE_MAX+1;
- return;
- }
- }
-
- /* test if it's full update */
- if(x == 0 && y == 0 && w == wScreenX && h == wScreenY)
- {
- SVGA_partial_update_cnt = 0;
- }
-}
-
-void SVGA_MapIO()
-{
- DWORD bounce_sel = 0;
- DWORD fifo_base_sel = 0;
- DWORD rmmio_sel = 0;
-
- /* get system linear addresses from PM32 RING-0 driver */
- if(SVGA_IsSVGA3())
- {
- VXD_get_addr(&gSVGA.fbLinear, &gSVGA.rmmio_linear, &gSVGA.fifo.bounceLinear);
-
- dbg_printf("VXD (SVGA3): received %lX %lX (%lX) %lX\n",
- gSVGA.fbLinear,
- gSVGA.rmmio_linear,
- gSVGA.rmmio_size,
- gSVGA.fifo.bounceLinear);
-
- rmmio_sel = DPMI_AllocLDTDesc(1);
- if(rmmio_sel)
- {
- DPMI_SetSegLimit(rmmio_sel, gSVGA.rmmio_size);
- DPMI_SetSegBase(rmmio_sel, gSVGA.rmmio_linear);
-
- gSVGA.rmmio = rmmio_sel :> 0x0;
- }
-
- }
- else
- {
- VXD_get_addr(&gSVGA.fbLinear, &gSVGA.fifoLinear, &gSVGA.fifo.bounceLinear);
-
- dbg_printf("VXD: received %lX %lX %lX\n",
- gSVGA.fbLinear,
- gSVGA.fifoLinear,
- gSVGA.fifo.bounceLinear);
-
- /* map fifo to PM16 memory */
- fifo_base_sel = DPMI_AllocLDTDesc(1);
- if(fifo_base_sel)
- {
- DPMI_SetSegLimit(fifo_base_sel, 0xFFFF);
- DPMI_SetSegBase(fifo_base_sel, gSVGA.fifoLinear);
- gSVGA.fifoMem = fifo_base_sel :> 0x0;
- }
-
- /* from PM16 cannot be accesed full fifo buffer properly, so allocate selector to maping as 64K sector */
- gSVGA.fifoSel = DPMI_AllocLDTDesc(1);
- if(gSVGA.fifoSel)
- {
- DPMI_SetSegLimit(gSVGA.fifoSel, 0xFFFF);
- DPMI_SetSegBase(gSVGA.fifoSel, gSVGA.fifoLinear);
-
- gSVGA.fifoAct = 0;
- }
- }
-
- bounce_sel = DPMI_AllocLDTDesc(1);
- if(bounce_sel)
- {
- DPMI_SetSegLimit(bounce_sel, SVGA_BOUNCE_SIZE-1);
- DPMI_SetSegBase(bounce_sel, gSVGA.fifo.bounceLinear);
-
- gSVGA.fifo.bounceMem = bounce_sel :> 0x0;
- }
-}
-
-/* Initialize SVGA structure and map FIFO to memory */
-static int __loadds SVGA_full_init()
-{
- int rc = 0;
- dbg_printf("VMWare SVGA-II init\n");
-
- rc = SVGA_Init(FALSE);
-
- if(rc != 0)
- {
- return rc;
- }
-
- /* get user flags */
- VXD_get_flags(&gSVGA.userFlags);
-
- //SVGA_Enable();
-
- return 0;
-}
-#endif
-
/* Set the currently configured mode (wXRes/wYRes) in hardware.
* If bFullSet is non-zero, then also reinitialize globals.
* When re-establishing a previously set mode (e.g. coming
@@ -549,97 +196,18 @@ static int SetDisplayMode( WORD wXRes, WORD wYRes, int bFullSet )
CallVDD( VDD_PRE_MODE_CHANGE );
#ifdef SVGA
- /* lock FIFO to make sure, no one is filling it during mode change */
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- /* Make sure, that we drain full FIFO */
- SVGA_Flush();
-
- /* stop command buffer context 0 */
- CB_stop();
-
- SVGA_SetMode(wXRes, wYRes, wBpp); /* setup by legacy registry */
- SVGA_Flush(); /* make sure, that is really set */
- wMesa3DEnabled = 0;
- if(SVGA3D_Init())
- {
- wMesa3DEnabled = SVGA_3DSupport();
- }
-
- /* setting screen by fifo, this method is required in VB 6.1 */
- if(SVGA_hasAccelScreen())
- {
- SVGA_defineScreen(wXRes, wYRes, wBpp);
- SVGA_Flush();
- }
-
- /* start command buffer context 0 */
- CB_start();
-
- /*
- * JH: this is a bit stupid = all SVGA command cannot work with non 32 bpp.
- * SVGA_CMD_UPDATE included. So if we're working in 32 bpp, we'll disable
- * traces and updating framebuffer changes with SVGA_CMD_UPDATE.
- * On non 32 bpp we just enable SVGA_REG_TRACES.
- *
- * QEMU hasn't SVGA_REG_TRACES register and framebuffer cannot be se to
- * 16 or 8 bpp = we supporting only 32 bpp moders if we're running under it.
- */
- if(wBpp == 32)
- {
- SVGA_WriteReg(SVGA_REG_TRACES, FALSE);
- }
- else
- {
- SVGA_WriteReg(SVGA_REG_TRACES, TRUE);
- }
-
- SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
- SVGA_Flush();
-
- SVGAHDA_unlock(LOCK_FIFO);
- }
-
- dbg_printf("Pitch: %lu\n", SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE));
-
- SVGAHDA_update(wScrX, wScrY, wBpp, SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE));
+ if(!SVGA_setmode(wXRes, wYRes, wBpp))
+ {
+ return 0;
+ }
#else
BOXV_ext_mode_set( 0, wXRes, wYRes, wBpp, wXRes, wYRes );
-
#endif
- if(FBHDA_ptr)
- {
- FBHDA_ptr->width = wScrX;
- FBHDA_ptr->height = wScrY;
- FBHDA_ptr->bpp = wBpp;
- FBHDA_ptr->flags = FBHDA_LOCKING | FBHDA_SW_CURSOR;
- FBHDA_ptr->fb_pm32 = dwScreenFlatAddr; /* change mode reset FB offset */
-#ifdef SVGA
- FBHDA_ptr->pitch = SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE);
- if(wBpp == 32)
- {
- FBHDA_ptr->flags |= FBHDA_NEED_UPDATE;
-
- if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
- {
- FBHDA_ptr->flags ^= FBHDA_SW_CURSOR;
- }
- }
-#else
- FBHDA_ptr->pitch = CalcPitch( wScrX, wBpp );
- FBHDA_ptr->flags |= FBHDA_FLIPING;
-#endif
- }
-
if( bFullSet ) {
- wScreenX = wXRes;
- wScreenY = wYRes;
-#ifdef SVGA
- wScreenPitchBytes = SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE);
-#else
- wScreenPitchBytes = CalcPitch( wXRes, wBpp );
-#endif
+ wScreenX = hda->width;
+ wScreenY = hda->height;
+ wScreenPitchBytes = hda->pitch;
BitBltDevProc = NULL; /* No acceleration implemented. */
@@ -647,9 +215,6 @@ static int SetDisplayMode( WORD wXRes, WORD wYRes, int bFullSet )
if( wBpp == 16 ) {
wPDeviceFlags |= FIVE6FIVE; /* Needed for 16bpp modes. */
}
-
- wMaxWidth = wScreenPitchBytes / (wBpp / 8); /* We know bpp is a multiple of 8. */
- wMaxHeight = dwVideoMemorySize / wScreenPitchBytes;
/* Offscreen regions could be calculated here. We do not use those. */
}
@@ -665,49 +230,28 @@ int PhysicalEnable( void )
DWORD dwRegRet;
if( !ScreenSelector ) {
-#ifdef SVGA
- int rc = 0;
- dbg_printf("PhysicalEnable: entry mode %ux%u\n", wScrX, wScrY);
- rc = SVGA_full_init();
-
- /* Extra work if driver hasn't yet been initialized. */
- if(rc != 0)
- {
- dbg_printf("SVGA_Init() failure: %d, wrong device?\n", rc);
- return 0;
- }
-
- dwVideoMemorySize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
- //dwPhysVRAM = SVGA_ReadReg(SVGA_REG_FB_START);
-#else
- int iChipID;
+ 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
- /* limit vram size */
- if(dwVideoMemorySize > MAX_VRAM)
- {
- dwVideoMemorySize = MAX_VRAM;
- }
-
-#ifdef SVGA
- /* init here, there are locks for FIFO commands! */
- SVGAHDA_init();
- dbg_printf( "PhysicalEnable: Hardware detected, dwVideoMemorySize=%lX\n", dwVideoMemorySize );
-#else
- dbg_printf( "PhysicalEnable: Hardware detected, dwVideoMemorySize=%lX dwPhysVRAM=%lX\n", dwVideoMemorySize, dwPhysVRAM );
+ }
#endif
-
+ dbg_printf( "PhysicalEnable: Hardware detected, dwVideoMemorySize=%lX\n", dwVideoMemorySize );
}
dbg_printf("PhysicalEnable: continue with %ux%u\n", wScrX, wScrY);
@@ -725,27 +269,21 @@ int PhysicalEnable( void )
/* Allocate an LDT selector for the screen. */
if( !ScreenSelector ) {
-#ifndef SVGA
- //ScreenSelector = AllocLinearSelector( dwPhysVRAM, dwVideoMemorySize );
- ScreenSelector = AllocLinearSelector(dwPhysVRAM, dwVideoMemorySize, &dwScreenFlatAddr);
+ ScreenSelector = ((DWORD)hda->vram_pm16) >> 16;
+ if(ScreenSelector == 0)
+ {
+ ScreenSelector = DPMI_AllocLDTDesc(1);
+ DPMI_SetSegBase(ScreenSelector, hda->vram_pm32);
+ DPMI_SetSegLimit(ScreenSelector, hda->vram_size-1);
+
+ /* update pointer in HDA */
+ hda->vram_pm16 = ScreenSelector :> 0;
+ }
+
if( !ScreenSelector ) {
- dbg_printf( "PhysicalEnable: AllocScreenSelector failed!\n" );
+ dbg_printf( "PhysicalEnable: Invalid VRAM selector failed!\n" );
return( 0 );
}
-#else
- ScreenSelector = DPMI_AllocLDTDesc(1);
-
- dbg_printf("%lX, %lX %lX\n", gSVGA.fbPhy, SVGA_ReadReg(SVGA_REG_FB_START), SVGA_ReadReg(SVGA_REG_FB_SIZE));
-
- DPMI_SetSegBase(ScreenSelector, gSVGA.fbLinear);
- DPMI_SetSegLimit(ScreenSelector, dwVideoMemorySize-1);
-
- dwScreenFlatAddr = gSVGA.fbLinear;
- gSVGA.fbMem = ScreenSelector :> 0;
-
- /* update userspace hardware access */
- SVGAHDA_setmode();
-#endif
}
/* NB: Currently not used. DirectDraw would need the segment base. */
@@ -759,49 +297,9 @@ int PhysicalEnable( void )
/// @todo What can we do with the returned value?
}
- /* allocate and fill FBHDA */
- if(FBHDA_ptr == NULL)
- {
- FBHDA_ptr = drv_malloc(FBHDA_SIZE, &FBHDA_linear);
- if(FBHDA_ptr)
- {
- FBHDA_ptr->width = wScrX;
- FBHDA_ptr->height = wScrY;
- FBHDA_ptr->bpp = wBpp;
- FBHDA_ptr->pitch = wScreenPitchBytes;
- FBHDA_ptr->flags = FBHDA_LOCKING | FBHDA_SW_CURSOR;
-
- FBHDA_ptr->fb_pm32 = dwScreenFlatAddr;
- FBHDA_ptr->fb_pm16 = ScreenSelector :> 0;
-
- FBHDA_ptr->lock = 0;
-
- FBHDA_ptr->vram_pm32 = dwScreenFlatAddr;
- FBHDA_ptr->vram_pm16 = ScreenSelector :> 0;
- FBHDA_ptr->vram_size = dwVideoMemorySize;
-
-#ifdef SVGA
- if(wBpp == 32)
- {
- FBHDA_ptr->flags |= FBHDA_NEED_UPDATE;
- if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
- {
- FBHDA_ptr->flags ^= FBHDA_SW_CURSOR;
- }
- }
-#else
- FBHDA_ptr->flags |= FBHDA_FLIPING;
-#endif
- }
- else
- {
- dbg_printf( "FBHDA_ptr = drv_malloc FAIL\n" );
- }
- }
-
#ifdef SVGA
/* update SVGAHDA */
- SVGAHDA_update(wScrX, wScrY, wBpp, wScreenPitchBytes);
+ SVGA_setmode(wScrX, wScrY, wBpp);
#endif
/* Let the VDD know that the mode changed. */
@@ -828,17 +326,14 @@ UINT WINAPI __loadds ValidateMode( DISPVALMODE FAR *lpValMode )
do {
if( !ScreenSelector ) {
#ifdef SVGA
- int svga_rc = SVGA_Init(FALSE); /* only load registers but not enabling device yet */
-
- /* Extra work if driver hasn't yet been initialized. */
- if(svga_rc != 0)
+ /* Check if we have SVGA HW */
+ if(!SVGA_valid())
{
rc = VALMODE_NO_WRONGDRV;
break;
}
- dwVideoMemorySize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
- //dwPhysVRAM = SVGA_ReadReg(SVGA_REG_FB_START);
+ dwVideoMemorySize = hda->vram_size;
#else
int iChipID;
@@ -848,6 +343,7 @@ UINT WINAPI __loadds ValidateMode( DISPVALMODE FAR *lpValMode )
rc = VALMODE_NO_WRONGDRV;
break;
}
+#if 0 /* TODO move VXD */
# ifdef QEMU
dwPhysVRAM = LfbBase;
# else
@@ -855,6 +351,7 @@ UINT WINAPI __loadds ValidateMode( DISPVALMODE FAR *lpValMode )
# endif
dbg_printf( "ValidateMode: Hardware detected, dwVideoMemorySize=%lX dwPhysVRAM=%lX\n", dwVideoMemorySize, dwPhysVRAM );
#endif
+#endif
}
if( !IsModeOK( lpValMode->dvmXRes, lpValMode->dvmYRes, lpValMode->dvmBpp ) ) {
@@ -869,8 +366,7 @@ UINT WINAPI __loadds ValidateMode( DISPVALMODE FAR *lpValMode )
void PhysicalDisable(void)
{
#ifdef SVGA
- CB_stop();
- SVGA_Disable();
+ SVGA_HW_disable();
#endif
}
diff --git a/palette.c b/palette.c
index 9721f0c..ae32fcb 100644
--- a/palette.c
+++ b/palette.c
@@ -31,44 +31,28 @@ THE SOFTWARE.
#include <conio.h> /* For port I/O prototypes. */
#include "boxvint.h" /* For VGA register definitions. */
-#ifdef SVGA
-#include "svga_all.h"
+#include "3d_accel.h"
#pragma code_seg( _INIT )
-static void __loadds __far SetColor(unsigned index, unsigned char r, unsigned char g, unsigned char b)
+static void __loadds __far SetColor(unsigned index, DWORD rgb)
{
- UINT sIndex = SVGA_PALETTE_BASE + index*3;
-
- SVGA_WriteReg(sIndex+0, r);
- SVGA_WriteReg(sIndex+1, g);
- SVGA_WriteReg(sIndex+2, b);
+ FBHDA_palette_set(index, rgb);
}
-#endif
#pragma code_seg( _TEXT )
/* Load the VGA DAC with values from color table. */
static void SetRAMDAC( UINT bStart, UINT bCount, RGBQUAD FAR *lpPal )
{
-#ifdef SVGA
BYTE bIndex = bStart;
while( bCount-- ) {
- SetColor(bIndex++, lpPal[bIndex].rgbRed, lpPal[bIndex].rgbGreen, lpPal[bIndex].rgbBlue);
+ DWORD rgb = ((DWORD)lpPal[bIndex].rgbRed << 16) |
+ ((DWORD)lpPal[bIndex].rgbGreen << 8) | (DWORD)lpPal[bIndex].rgbBlue;
+
+ SetColor(bIndex++, rgb);
}
-#else
- BYTE bIndex = bStart;
-
- /* The data format is too weird for BOXV_dac_set(). Do it by hand. */
- outp( VGA_DAC_W_INDEX, bIndex ); /* Set starting index. */
- while( bCount-- ) {
- outp( VGA_DAC_DATA, lpPal[bIndex].rgbRed );
- outp( VGA_DAC_DATA, lpPal[bIndex].rgbGreen );
- outp( VGA_DAC_DATA, lpPal[bIndex].rgbBlue );
- ++bIndex;
- }
-#endif
}
/* Allow calls from the _INIT segment. */
diff --git a/palette_svga.c b/palette_svga.c
deleted file mode 100644
index b607145..0000000
--- a/palette_svga.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SVGA
-#include "palette.c"
diff --git a/pm16_calls.c b/pm16_calls.c
new file mode 100644
index 0000000..147bee8
--- /dev/null
+++ b/pm16_calls.c
@@ -0,0 +1,387 @@
+/*****************************************************************************
+
+Copyright (c) 2023 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.
+
+*****************************************************************************/
+/* Communication from ring3 PM16 -> ring0 PM32 */
+
+#include <wchar.h> /* wchar_t */
+#include <string.h> /* _fmemset */
+#include <stdint.h>
+#include "winhack.h" /* BOOL */
+
+#include "dpmi.h"
+
+#include "pm16_calls.h"
+#include "vxd.h"
+#include "3d_accel.h"
+
+#ifdef DBGPRINT
+extern void dbg_printf( const char *s, ... );
+#else
+#define dbg_printf(...)
+#endif
+
+static DWORD VXD_VM = 0;
+
+#pragma code_seg( _INIT )
+
+BOOL VXD_VM_connect()
+{
+ if(VXD_VM != 0)
+ {
+ return TRUE;
+ }
+
+ _asm{
+ push es
+ push ax
+ push dx
+ push bx
+ push di
+
+ xor di,di
+ mov es,di
+ mov ax, 1684H
+ mov bx, VXD_DEVICE_ID
+ int 2FH
+ mov word ptr [VXD_VM],di
+ mov word ptr [VXD_VM+2],es
+
+ pop di
+ pop bx
+ pop dx
+ pop ax
+ pop es
+ };
+
+ return VXD_VM != 0;
+}
+
+void FBHDA_setup(FBHDA_t __far* __far* FBHDA, DWORD __far* FBHDA_linear)
+{
+ static DWORD linear;
+ linear = 0;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_FBHDA_SETUP
+ call dword ptr [VXD_VM]
+ mov [linear], ecx
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ if(linear)
+ {
+ void __far *longptr = NULL;
+ WORD desc = DPMI_AllocLDTDesc(1);
+ DPMI_SetSegBase(desc, linear);
+ DPMI_SetSegLimit(desc, sizeof(FBHDA_t)-1);
+
+ longptr = desc :> 0;
+
+ *FBHDA = (FBHDA_t __far*)longptr;
+ *FBHDA_linear = linear;
+ }
+}
+
+void FBHDA_access_begin(DWORD flags)
+{
+ static DWORD sFlags;
+ sFlags = flags;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_FBHDA_ACCESS_BEGIN
+ mov ecx, [sFlags]
+ call dword ptr [VXD_VM]
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+}
+
+void FBHDA_access_end(DWORD flags)
+{
+ static DWORD sFlags;
+ sFlags = flags;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_FBHDA_ACCESS_END
+ mov ecx, [sFlags]
+ call dword ptr [VXD_VM]
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+}
+
+BOOL FBHDA_swap(DWORD offset)
+{
+ static DWORD sOffset;
+ static BOOL status;
+ sOffset = offset;
+ status = FALSE;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_FBHDA_SWAP
+ mov ecx, [sOffset]
+ call dword ptr [VXD_VM]
+ mov [status], cx
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+void FBHDA_clean()
+{
+ _asm
+ {
+ .386
+ push eax
+ push edx
+
+ mov edx, OP_FBHDA_CLEAN
+ call dword ptr [VXD_VM]
+
+ pop edx
+ pop eax
+ }
+}
+
+void FBHDA_palette_set(unsigned char index, DWORD rgb)
+{
+ static unsigned char sIndex;
+ static DWORD sRGB;
+
+ sIndex = index;
+ sRGB = rgb;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+ push edi
+
+ mov edx, OP_FBHDA_PALETTE_SET
+ mov cl, [index]
+ mov edi, [sRGB]
+ call dword ptr [VXD_VM]
+
+ pop edi
+ pop ecx
+ pop edx
+ pop eax
+ }
+}
+
+DWORD FBHDA_palette_get(unsigned char index)
+{
+ static unsigned char sIndex;
+ static DWORD sRGB;
+
+ sIndex = index;
+ sRGB = 0;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+ push edi
+
+ mov edx, OP_FBHDA_PALETTE_GET
+ mov cl, [index]
+ call dword ptr [VXD_VM]
+ mov [sRGB], edi
+
+ pop edi
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return sRGB;
+}
+
+#ifdef SVGA
+BOOL SVGA_valid()
+{
+ static BOOL status;
+ status = FALSE;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_SVGA_VALID
+ call dword ptr [VXD_VM]
+ mov [status], cx
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+BOOL SVGA_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_SVGA_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 SVGA_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_SVGA_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;
+}
+
+void SVGA_HW_enable()
+{
+ _asm
+ {
+ .386
+ push eax
+ push edx
+
+ mov edx, OP_SVGA_HW_ENABLE
+ call dword ptr [VXD_VM]
+
+ pop edx
+ pop eax
+ }
+}
+
+void SVGA_HW_disable()
+{
+ _asm
+ {
+ .386
+ push eax
+ push edx
+
+ mov edx, OP_SVGA_HW_DISABLE
+ call dword ptr [VXD_VM]
+
+ pop edx
+ pop eax
+ }
+}
+#endif
diff --git a/pm16_calls.h b/pm16_calls.h
new file mode 100644
index 0000000..d0e533c
--- /dev/null
+++ b/pm16_calls.h
@@ -0,0 +1,10 @@
+#ifndef __VXDCALL_H__INCLUDED__
+#define __VXDCALL_H__INCLUDED__
+
+BOOL VXD_VM_connect();
+
+#ifdef QEMU
+BOOL VXD_QEMUFX_supported();
+#endif
+
+#endif /* __VXDCALL_H__INCLUDED__ */
diff --git a/pm16_calls_qemu.c b/pm16_calls_qemu.c
new file mode 100644
index 0000000..f53fe28
--- /dev/null
+++ b/pm16_calls_qemu.c
@@ -0,0 +1,2 @@
+#define QEMU
+#include "pm16_calls.c"
diff --git a/pm16_calls_svga.c b/pm16_calls_svga.c
new file mode 100644
index 0000000..d3fdb59
--- /dev/null
+++ b/pm16_calls_svga.c
@@ -0,0 +1,2 @@
+#define SVGA
+#include "pm16_calls.c"
diff --git a/qemuvxd.c b/qemuvxd.c
deleted file mode 100644
index 6fa80c4..0000000
--- a/qemuvxd.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2023 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.
-
-*****************************************************************************/
-
-/*
- * This file is generally C port of boxvmini.asm by Philip Kelley
- */
-
-#define VXD32
-#define QEMU
-
-#include "winhack.h"
-#include "vmm.h"
-#include "vxdcodes.h"
-
-#include "svga_all.h"
-
-#include "minivdd32.h"
-
-#include "version.h"
-
-#include "code32.h"
-
-#ifndef ERROR_SUCCESS
-#define ERROR_SUCCESS 0
-#endif
-
-void QEMU_Control();
-void QEMU_API_Entry();
-
-/*
- VXD structure
- this variable must be in first address in code segment.
- In other cases VXD isn't loadable (WLINK bug?)
-*/
-DDB QEMU_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,
- "QEMU_VXD",
- VDD_Init_Order, //Undefined_Init_Order,
- (DWORD)QEMU_Control,
- (DWORD)QEMU_API_Entry,
- (DWORD)QEMU_API_Entry,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, // DDB_Win32_Service_Table
- NULL, // prev
- sizeof(DDB)
-};
-
-/* string tables */
-#ifdef DBGPRINT
-char dbg_hello[] = "Hello world!\n";
-char dbg_version[] = "VMM version: ";
-
-char dbg_Device_Init_proc[] = "Device_Init_proc\n";
-char dbg_Device_Init_proc_succ[] = "Device_Init_proc success\n";
-char dbg_dic_unknown[] = "DeviceIOControl: Unknown: %d\n";
-char dbg_dic_system[] = "DeviceIOControl: System code: %d\n";
-
-char dbg_str[] = "%s\n";
-
-char dbg_reg_open_suc[] = "_RegKeyOpen Success\n";
-char dbg_reg_open_fail[] = "_RegKeyOpen FAILED\n";
-char dbg_reg_query_fail[] = "_RegQueryValueEx FAILED - %ld\n";
-
-#endif
-
-DWORD *DispatchTable = 0;
-DWORD DispatchTableLength = 0;
-Bool svga_init_success = FALSE;
-
-/**
- * VMM calls wrapers
- **/
-DWORD Get_VMM_Version()
-{
- static WORD ver = 0;
-
- _asm push ecx
- _asm push eax
- _asm xor eax, eax
- VMMCall(Get_VMM_Version);
- _asm mov [ver],ax
- _asm pop ecx
- _asm pop eax
-
- return ver;
-}
-
-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
- }
-}
-
-ULONG __declspec(naked) __cdecl _PhysIntoV86(ULONG PhysPage, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG flags)
-{
- VMMJmp(_PhysIntoV86);
-}
-
-ULONG __declspec(naked) __cdecl _PageAllocate(ULONG nPages, ULONG pType, ULONG VM, ULONG AlignMask, ULONG minPhys, ULONG maxPhys, ULONG *PhysAddr, ULONG flags)
-{
- VMMJmp(_PageAllocate);
-}
-
-ULONG __declspec(naked) __cdecl _PageFree(PVOID hMem, DWORD flags)
-{
- VMMJmp(_PageFree);
-}
-
-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);
-}
-
-/* from minivdd.c */
-void Enable_Global_Trapping(DWORD port);
-void Disable_Global_Trapping(DWORD port);
-
-/**
- * VDD calls wrapers
- **/
-void VDD_Get_Mini_Dispatch_Table()
-{
- VxDCall(VDD, Get_Mini_Dispatch_Table);
- _asm mov [DispatchTable],edi
- _asm mov [DispatchTableLength],ecx
-}
-
-/**
- * Control Handles
- **/
-void Sys_Critical_Init_proc()
-{
- // nop
-}
-
-/*
- * 32-bit DeviceIoControl ends here
- * (not much to do now)
- *
- */
-DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params)
-{
- switch(params->dwIoControlCode)
- {
- case DIOC_OPEN:
- case DIOC_CLOSEHANDLE:
- dbg_printf(dbg_dic_system, params->dwIoControlCode);
- return 0;
- }
- dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
-
- return 1;
-}
-
-void __declspec(naked) Device_IO_Control_proc()
-{
- _asm {
- push esi /* struct DIOCParams */
- call Device_IO_Control_entry
- retn
- }
-}
-
-void Device_Init_proc();
-void __stdcall Device_Dynamic_Init_proc(DWORD WinVMHandle);
-void __stdcall Device_Init_Complete(DWORD VM);
-
-/*
- * service module calls (init, exit, deviceIoControl, ...)
- * clear carry if succes (this is always success)
- */
-void __declspec(naked) QEMU_Control()
-{
- // eax = 0x00 - Sys Critical Init
- // eax = 0x01 - sys dynamic init
- // eax = 0x1B - dynamic init
- // eax = 0x1C - dynamic exit
- // eax = 0x23 - device IO control
-
- _asm {
- cmp eax,Sys_Critical_Init
- jnz control_1
- pushad
- call Sys_Critical_Init_proc
- popad
- clc
- ret
- control_1:
- cmp eax,Device_Init
- jnz control_2
- pushad
- call Device_Init_proc
- popad
- clc
- ret
- control_2:
- cmp eax,Init_Complete
- jnz control_3
- pushad
- push ebx ; VM handle
- call Device_Init_Complete
- popad
- clc
- ret
- control_3:
- cmp eax,0x1B ; dynamic init
- jnz control_4
- pushad
- push ebx
- call Device_Dynamic_Init_proc
- popad
- clc
- ret
- control_4:
- cmp eax,W32_DEVICEIOCONTROL
- jnz control_5
- jmp Device_IO_Control_proc
- control_5:
- clc
- ret
- };
-}
-
-char icd_reg_path[] = "Software\\Microsoft\\Windows\\CurrentVersion\\OpenGLdrivers";
-char icd_drv_name[] = "QEMUFX";
-#define icd_reg_result_size 255
-char icd_reg_result[icd_reg_result_size] = {0};
-
-BOOL qemufx_supported()
-{
- DWORD icd_key = 0;
- BOOL result = FALSE;
-
- if(_RegOpenKey(HKEY_LOCAL_MACHINE, icd_reg_path, &icd_key) == ERROR_SUCCESS)
- {
- DWORD cbData = icd_reg_result_size;
- DWORD t;
- dbg_printf(dbg_reg_open_suc);
- t = _RegQueryValueEx(icd_key, icd_drv_name, NULL, NULL, icd_reg_result, &cbData);
- if(t == ERROR_SUCCESS)
- {
- if(cbData > 0)
- {
- dbg_printf(dbg_str, icd_reg_result);
- result = TRUE;
- }
- }
- else
- {
- dbg_printf(dbg_reg_query_fail, t);
- }
-
- _RegCloseKey(icd_key);
- }
- else
- {
- dbg_printf(dbg_reg_open_fail);
- }
-
- return result;
-}
-
-WORD __stdcall QEMU_API_Proc(PCRS_32 state)
-{
- WORD rc = 0xFFFF;
- WORD service = state->Client_EDX & 0xFFFF;
- switch(service)
- {
- case VXD_PM16_VERSION:
- rc = (VXD_MAJOR_VER << 8) | VXD_MINOR_VER;
- break;
- case VXD_PM16_VMM_VERSION:
- rc = Get_VMM_Version();
- break;
- case VXD_PM16_ZEROMEM:
- {
- ULONG i = 0;
- unsigned char *ptr = (unsigned char *)state->Client_ESI;
- for(i = 0; i < state->Client_ECX; i++)
- {
- ptr[i] = 0;
- }
- rc = 1;
- break;
- }
- case QEMUVXD_QEMUFX:
- {
- if(qemufx_supported())
- {
- state->Client_ECX = 1;
- }
- else
- {
- state->Client_ECX = 0;
- }
- rc = 1;
- break;
- }
- }
-
- if(rc == 0xFFFF)
- {
- state->Client_EFlags |= 0x1; // set carry
- }
- else
- {
- state->Client_EFlags &= 0xFFFFFFFEUL; // clear carry
- }
-
- return rc;
-}
-
-/*
- * 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
- * function is placed to saved AX register.
- *
- */
-void __declspec(naked) QEMU_API_Entry()
-{
- _asm {
- push ebp
- call QEMU_API_Proc
- mov [ebp+1Ch], ax
- retn
- }
-}
-
-static DWORD dwWindowsVMHandle = NULL;
-
-/**
- * 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, dwWindowsVMHandle ; 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);
-}
-
-/* generate all entry pro VDD function */
-#define VDDFUNC(_fnname, _procname) void __declspec(naked) _procname ## _entry() { \
- _asm { push ebp }; \
- _asm { call _procname ## _proc }; \
- _asm { retn }; \
- }
-#include "minivdd_func.h"
-#undef VDDFUNC
-
-#define VDDFUNC(id, procname) DispatchTable[id] = (DWORD)(procname ## _entry);
-
-/* init device and fill dispatch table */
-void Device_Dynamic_Init_proc(DWORD WinVMHandle)
-{
- dbg_printf(dbg_Device_Init_proc);
- //VMMCall(_Allocate_Device_CB_Area);
-
- VDD_Get_Mini_Dispatch_Table();
- if(DispatchTableLength >= 0x31)
- {
- #include "minivdd_func.h"
- }
-
- dwWindowsVMHandle = WinVMHandle;
-
- Install_IO_Handler(0x1ce, (DWORD)virtual_0x1ce);
- Disable_Global_Trapping(0x1ce);
- Install_IO_Handler(0x1cf, (DWORD)virtual_0x1ce);
- Disable_Global_Trapping(0x1cf);
-
- dbg_printf(dbg_Device_Init_proc_succ);
-}
-#undef VDDFUNC
-
-/*
- * 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.
- *
- */
-void Device_Init_Complete(DWORD VM)
-{
- _PhysIntoV86(0xA0, VM, 0xA0, 16, 0);
- _PhysIntoV86(0xB8, VM, 0xB8, 8, 0);
-}
-
-void Device_Init_proc()
-{
- /* NOP */
-}
diff --git a/scrsw.c b/scrsw.c
index 892b15d..412131b 100644
--- a/scrsw.c
+++ b/scrsw.c
@@ -28,9 +28,7 @@ THE SOFTWARE.
#include <gdidefs.h>
#include <dibeng.h>
#include "minidrv.h"
-#ifdef SVGA
-#include "svga_all.h"
-#endif
+#include "3d_accel.h"
/* SwitchFlags bits. */
#define PREVENT_SWITCH 0x80 /* Don't allow screen switching. */
@@ -127,12 +125,12 @@ void UnhookInt2Fh( void )
#ifdef SVGA
static void __far __loadds SVGA_background()
{
- SVGA_WriteReg(SVGA_REG_ENABLE, FALSE);
+ SVGA_HW_disable();
}
static void __far __loadds SVGA_foreground()
{
- SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
+ SVGA_HW_enable();
}
#endif /* SVGA */
diff --git a/swcursor.c b/swcursor.c
deleted file mode 100644
index 45c6617..0000000
--- a/swcursor.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2023 Jaroslav Hensl
-
-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.
-
-*****************************************************************************/
-
-#include "winhack.h"
-#include <gdidefs.h>
-#include <dibeng.h>
-#include <minivdd.h>
-#include <string.h>
-
-#include "minidrv.h"
-#include "dpmi.h"
-#include "drvlib.h"
-#include "swcursor.h"
-
-struct _SWCURSOR
-{
- long x; /* pointer X */
- long y; /* pointer Y */
- long offx;
- long offy;
- long w;
- long h;
- long hotx;
- long hoty;
- long lastx; /* blitted offx */
- long lasty; /* blitted offy */
- long lastw;
- long lasth;
- DWORD ps;
- DWORD state;
- long blitlock;
- BYTE data[1];
-};
-
-#define STATE_EMPTY 0
-#define STATE_BLITED 1
-#define STATE_ERASED 2
-
-BOOL sw_cursor_enabled = FALSE;
-SWCURSOR __far *sw_cursor = NULL;
-static BYTE __far *cursor_andmask = NULL;
-static BYTE __far *cursor_xormask = NULL;
-static BYTE __far *cursor_backdata = NULL;
-
-#define CURSOR_MAX_SIZE 65536
-
-static DWORD sw_cursor_lin = 0;
-static WORD fb_desc = 0;
-static DWORD fb_desc_base = 0;
-
-#pragma code_seg( _TEXT )
-
-static void __far *GetLinePtr(long y)
-{
- DWORD y_lin = dwScreenFlatAddr + (DWORD)wScreenPitchBytes*y;
- DWORD y_lin_max = y_lin + wScreenPitchBytes;
-
- if(fb_desc_base > y_lin ||
- y_lin-fb_desc_base > 65536 ||
- y_lin_max-fb_desc_base > 65536
- )
- {
- DPMI_SetSegBase(fb_desc, y_lin);
- fb_desc_base = y_lin;
- }
-
- return fb_desc :> (WORD)(y_lin - fb_desc_base);
-}
-
-void cursor_merge_rect(longRECT __far *r1, longRECT __far *r2)
-{
- if(r1->left == r1->right)
- {
- if(r2->left == r2->right)
- {
- return;
- }
-
- *r1 = *r2;
- return;
- }
-
- if(r2->left == r2->right)
- {
- return;
- }
-
- if(r2->left < r1->left)
- r1->left = r2->left;
-
- if(r2->top < r1->top)
- r1->top = r2->top;
-
- if(r2->right > r1->right)
- r1->right = r2->right;
-
- if(r2->bottom > r1->bottom)
- r1->bottom = r2->bottom;
-}
-
-static void cursor_cs_enter()
-{
- _asm
- {
- mov ax, 1681h
- int 2Fh
- };
-}
-
-static void cursor_cs_leave()
-{
- _asm
- {
- mov ax, 1682h
- int 2Fh
- };
-}
-
-
-BOOL cursor_init()
-{
- cursor_cs_enter();
-
- fb_desc = DPMI_AllocLDTDesc(1);
-
- if(fb_desc)
- {
- SWCURSOR __far *cur = drv_malloc(CURSOR_MAX_SIZE, &sw_cursor_lin);
- if(cur)
- {
- fb_desc_base = dwScreenFlatAddr;
- DPMI_SetSegBase(fb_desc, fb_desc_base);
- DPMI_SetSegLimit(fb_desc, CURSOR_MAX_SIZE-1);
- _fmemset(cur, 0, sizeof(SWCURSOR));
- cur->state = STATE_EMPTY;
-
- sw_cursor = cur;
- sw_cursor_enabled = TRUE;
-
- cursor_cs_leave();
- return TRUE;
- }
- }
-
- cursor_cs_leave();
- return FALSE;
-}
-
-#define EXPAND_BIT(_dsttype, _bit) (~(((_dsttype)(_bit))-1))
-//#define EXPAND_BIT(_dsttype, _bit) ((_bit) > 0 ? 0xFFFFFFFF : 0)
-
-/*
- * load cursor from CURSHAPE and convert it to display BPP
- */
-BOOL cursor_load(CURSORSHAPE __far *lpCursor, longRECT __far *changes)
-{
- //dbg_printf("cursor_load: %d\n", wBpp);
-
- if(sw_cursor)
- {
- unsigned int ps = (wBpp + 7)/8;
- const DWORD data_size = lpCursor->cx * lpCursor->cy * ps;
-
- BYTE __far *DstAndMask = &sw_cursor->data[0];
- BYTE __far *DstXorMask = &sw_cursor->data[data_size];
-
- BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
- BYTE __far *xormask = (BYTE __far *)(andmask + lpCursor->cbWidth*lpCursor->cy);
-
- longRECT r1 = {0, 0, 0, 0};
- longRECT r2 = {0, 0, 0, 0};
- BOOL is_blitted = FALSE;
-
- int xi, xj, y;
-
- /* maximum cursor size in 32bit mode is 64x64 px */
- if(data_size * 3 + sizeof(SWCURSOR) > CURSOR_MAX_SIZE)
- {
- return FALSE;
- }
-
- if(sw_cursor->state == STATE_BLITED)
- {
- is_blitted = TRUE;
- cursor_erase(&r1);
- }
-
- cursor_cs_enter();
-
- for(y = 0; y < lpCursor->cy; y++)
- {
- for(xj = 0; xj < lpCursor->cbWidth; xj++)
- {
- BYTE a = andmask[lpCursor->cbWidth*y + xj];
- BYTE x = xormask[lpCursor->cbWidth*y + xj];
-
- for(xi = 7; xi >= 0; xi--)
- {
- switch(wBpp)
- {
- case 8:
- {
- DstAndMask[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(BYTE, ((a >> xi) & 0x1));
- if(lpCursor->BitsPixel == 1)
- {
- DstXorMask[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(BYTE, ((x >> xi) & 0x1));
- }
- break;
- }
- case 16:
- {
- ((WORD __far*)DstAndMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(WORD, ((a >> xi) & 0x1));
- if(lpCursor->BitsPixel == 1)
- {
- ((WORD __far*)DstXorMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(WORD, ((x >> xi) & 0x1));
- }
- break;
- }
- case 24:
- {
- DWORD am = EXPAND_BIT(DWORD, ((a >> xi) & 0x1));
- DWORD xm = EXPAND_BIT(DWORD, ((x >> xi) & 0x1));
- WORD pos = (lpCursor->cx * y + xj*8 + (7-xi))*3;
-
- DstAndMask[pos] = am & 0xFF;
- DstAndMask[pos+1] = (am >> 8) & 0xFF;
- DstAndMask[pos+2] = (am >> 16) & 0xFF;
-
- if(lpCursor->BitsPixel == 1)
- {
- DstXorMask[pos] = xm & 0xFF;
- DstXorMask[pos+1] = (xm >> 8) & 0xFF;
- DstXorMask[pos+2] = (xm >> 16) & 0xFF;
- }
-
- break;
- }
- case 32:
- {
- ((DWORD __far*)DstAndMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(DWORD, ((a >> xi) & 0x1));
- if(lpCursor->BitsPixel == 1)
- {
- ((DWORD __far*)DstXorMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(DWORD, ((x >> xi) & 0x1));
- }
- break;
- }
- }
- }
- }
- }
-
- if(lpCursor->BitsPixel == wBpp)
- {
- _fmemcpy(DstXorMask, xormask, ps * lpCursor->cx * lpCursor->cy);
- }
- else if(lpCursor->BitsPixel != 1)
- {
- cursor_cs_leave();
- return FALSE;
- }
-
- sw_cursor->x = cursorX;
- sw_cursor->y = cursorY;
-
- sw_cursor->w = lpCursor->cx;
- sw_cursor->h = lpCursor->cy;
-
- sw_cursor->hotx = lpCursor->xHotSpot;
- sw_cursor->hoty = lpCursor->yHotSpot;
-
- sw_cursor->ps = ps;
- if(sw_cursor->state != STATE_BLITED)
- {
- sw_cursor->state = STATE_ERASED;
- }
-
- cursor_andmask = DstAndMask;
- cursor_xormask = DstXorMask;
- cursor_backdata = (BYTE __far *)sw_cursor + (CURSOR_MAX_SIZE - 64*64*4);//DstXorMask + data_size;
-
- cursor_cs_leave();
-
- if(is_blitted)
- {
- cursor_coordinates(cursorX, cursorY);
- cursor_blit(&r2);
- cursor_merge_rect(&r1, &r2);
- }
-
- if(changes)
- {
- *changes = r1;
- }
-
- return TRUE;
- }
- return FALSE;
-}
-
-void cursor_unload(longRECT __far *changes)
-{
- //dbg_printf("cursor_unload\n");
-
- if(sw_cursor)
- {
- longRECT r1 = {0,0,0,0};
-
- if(sw_cursor->state == STATE_BLITED)
- {
- cursor_erase(&r1);
- }
-
- sw_cursor->state = STATE_EMPTY;
-
- if(changes)
- {
- *changes = r1;
- }
- }
-}
-
-void cursor_coordinates(long curx, long cury)
-{
- if(sw_cursor)
- {
- cursor_cs_enter();
- if(sw_cursor->state != STATE_BLITED)
- {
- sw_cursor->x = curx;
- sw_cursor->y = cury;
- sw_cursor->offx = curx - sw_cursor->hotx;
- sw_cursor->offy = cury - sw_cursor->hoty;
- }
- cursor_cs_leave();
- }
-}
-
-void cursor_move(longRECT __far *changes)
-{
- if(sw_cursor)
- {
- if(sw_cursor->blitlock == 0)
- {
- longRECT r1 = {0, 0, 0, 0}, r2 = {0, 0, 0, 0};
- BOOL blitted = FALSE;
-
- if(sw_cursor->state == STATE_EMPTY)
- {
- return;
- }
-
- if(sw_cursor->state == STATE_BLITED)
- {
- cursor_erase(&r1);
- blitted = TRUE;
- }
-
- cursor_coordinates(cursorX, cursorY);
-
- if(blitted)
- {
- cursor_blit(&r2);
- }
-
- if(changes)
- {
- cursor_merge_rect(&r1, &r2);
- *changes = r1;
- }
- }
- }
-}
-
-void cursor_erase(longRECT __far *changes)
-{
- //dbg_printf("cursor_erase\n");
-
- if(sw_cursor)
- {
- long x, y;
-
- if(sw_cursor->ps != (wBpp + 7)/8)
- {
- return;
- }
-
- cursor_cs_enter();
- if(sw_cursor->state == STATE_BLITED && sw_cursor->blitlock == 0)
- {
- sw_cursor->blitlock++;
- switch(sw_cursor->ps)
- {
- case 1:
- {
- for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
- if(y >= 0 && y < wScrY){
- BYTE __far *dst = GetLinePtr(y);
- BYTE __far *src = cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w);
- for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
- if(x >= 0 && x < wScrX){
- dst[x] = *src;
- }
- src++;
- } } }
- break;
- }
- case 2:
- {
- for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
- if(y >= 0 && y < wScrY){
- WORD __far *dst = GetLinePtr(y);
- WORD __far *src = (WORD __far *)cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w);
- for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
- if(x >= 0 && x < wScrX){
- dst[x] = *src;
- }
- src++;
- } } }
- break;
- }
- case 3:
- {
- for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
- if(y >= 0 && y < wScrY){
- BYTE __far *dst = GetLinePtr(y);
- BYTE __far *src = cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w)*3;
- for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
- if(x >= 0 && x < wScrX){
- dst[x*3 ] = *src;
- dst[x*3+1] = *(src+1);
- dst[x*3+2] = *(src+2);
- }
- src += 3;
- } } }
- break;
- }
- case 4:
- {
- for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
- if(y >= 0 && y < wScrY){
- DWORD __far *dst = GetLinePtr(y);
- DWORD __far *src = (DWORD __far *)cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w);
- for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
- if(x >= 0 && x < wScrX){
- dst[x] = *src;
- }
- src++;
- } } }
- break;
- }
- } // switch bpp
-
- sw_cursor->state = STATE_ERASED;
-
- if(changes)
- {
- changes->left = sw_cursor->lastx;
- changes->right = sw_cursor->lastx + sw_cursor->lastw;
-
- changes->top = sw_cursor->lasty;
- changes->bottom = sw_cursor->lasty + sw_cursor->lasth;
- }
-
- sw_cursor->blitlock--;
- }
- else
- {
- if(changes)
- {
- changes->left = 0;
- changes->right = 0;
- changes->top = 0;
- changes->bottom = 0;
- }
- }
- cursor_cs_leave();
- }
-}
-
-void cursor_lock()
-{
- if(sw_cursor)
- {
- cursor_cs_enter();
- sw_cursor->blitlock++;
- cursor_cs_leave();
- }
-}
-
-void cursor_unlock()
-{
- if(sw_cursor)
- {
- cursor_cs_enter();
- sw_cursor->blitlock--;
- if(sw_cursor->blitlock < 0)
- {
- sw_cursor->blitlock = 0;
- }
- cursor_cs_leave();
- }
-}
-
-void cursor_blit(longRECT __far *changes)
-{
- //dbg_printf("cursor_blit\n");
-
- if(sw_cursor)
- {
- long x, y;
-
- if(sw_cursor->ps != (wBpp + 7)/8)
- {
- return;
- }
-
- cursor_cs_enter();
- if(sw_cursor->state == STATE_ERASED && sw_cursor->blitlock == 0)
- {
- //dbg_printf("blit: state - %ld\n", sw_cursor->state);
- sw_cursor->blitlock++;
-
- switch(sw_cursor->ps)
- {
- case 1:
- {
- for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
- if(y >= 0 && y < wScrY){
- const long ptx = (y - sw_cursor->offy)*sw_cursor->w;
- BYTE __far *dst = GetLinePtr(y);
- BYTE __far *bd = cursor_backdata + ptx;
- BYTE __far *am = cursor_andmask + ptx;
- BYTE __far *xm = cursor_xormask + ptx;
- for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
- if(x >= 0 && x < wScrX){
- *bd = dst[x];
- dst[x] &= *am;
- dst[x] ^= *xm;
- }
- bd++; am++; xm++;
- } } }
- break;
- }
- case 2:
- {
- for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
- if(y >= 0 && y < wScrY){
- const long ptx = (y - sw_cursor->offy)*sw_cursor->w;
- WORD __far *dst = GetLinePtr(y);
- WORD __far *bd = (WORD __far *)(cursor_backdata) + ptx;
- WORD __far *am = (WORD __far *)(cursor_andmask) + ptx;
- WORD __far *xm = (WORD __far *)(cursor_xormask) + ptx;
- for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
- if(x >= 0 && x < wScrX){
- *bd = dst[x];
- dst[x] &= *am;
- dst[x] ^= *xm;
- }
- bd++; am++; xm++;
- } } }
- break;
- }
- case 3:
- {
- for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
- if(y >= 0 && y < wScrY){
- const long ptx = (y - sw_cursor->offy)*sw_cursor->w*3;
- BYTE __far *dst = GetLinePtr(y);
- BYTE __far *bd = cursor_backdata + ptx;
- BYTE __far *am = cursor_andmask + ptx;
- BYTE __far *xm = cursor_xormask + ptx;
- for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
- if(x >= 0 && x < wScrX){
- *bd = dst[x*3 ]; dst[x*3 ] &= *am; dst[x*3 ] ^= *xm;
- *(bd+1) = dst[x*3+1]; dst[x*3+1] &= *(am+1); dst[x*3+1] ^= *(xm+1);
- *(bd+2) = dst[x*3+2]; dst[x*3+2] &= *(am+2); dst[x*3+2] ^= *(xm+2);
- }
- bd += 3;
- am += 3;
- xm += 3;
- } } }
- break;
- }
- case 4:
- {
- for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
- if(y >= 0 && y < wScrY){
- const long ptx = (y - sw_cursor->offy)*sw_cursor->w;
- DWORD __far *dst = GetLinePtr(y);
- DWORD __far *bd = (DWORD __far *)(cursor_backdata) + ptx;
- DWORD __far *am = (DWORD __far *)(cursor_andmask) + ptx;
- DWORD __far *xm = (DWORD __far *)(cursor_xormask) + ptx;
- for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
- if(x >= 0 && x < wScrX){
- *bd = dst[x];
- dst[x] &= *am;
- dst[x] ^= *xm;
- }
- bd++; am++; xm++;
- } } }
- break;
- }
- } // switch bpp
-
- sw_cursor->state = STATE_BLITED;
- sw_cursor->lastx = sw_cursor->offx;
- sw_cursor->lasty = sw_cursor->offy;
- sw_cursor->lastw = sw_cursor->w;
- sw_cursor->lasth = sw_cursor->h;
-
- if(changes)
- {
- changes->left = sw_cursor->offx;
- changes->right = sw_cursor->offx + sw_cursor->w;
-
- changes->top = sw_cursor->offy;
- changes->bottom = sw_cursor->offy + sw_cursor->h;
- }
- sw_cursor->blitlock--;
- } /* !empty */
- else
- {
- //dbg_printf("cursor_blit: state %ld, lock: %ld\n", sw_cursor->state, sw_cursor->blitlock);
-
- if(changes)
- {
- changes->left = 0;
- changes->right = 0;
- changes->top = 0;
- changes->bottom = 0;
- }
- }
- cursor_cs_leave();
- }
-}
-
diff --git a/swcursor.h b/swcursor.h
deleted file mode 100644
index d8d5af8..0000000
--- a/swcursor.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __SWCURSOR_H__INCLUDED__
-#define __SWCURSOR_H__INCLUDED__
-
-/* from dibcall.c */
-extern LONG cursorX;
-extern LONG cursorY;
-
-/* from DDK98 */
-#pragma pack(push)
-#pragma pack(1)
-typedef struct
-{
- int xHotSpot, yHotSpot;
- int cx, cy;
- int cbWidth;
- BYTE Planes;
- BYTE BitsPixel;
-} CURSORSHAPE;
-#pragma pack(pop)
-
-typedef struct _SWCURSOR SWCURSOR;
-
-BOOL cursor_init();
-BOOL cursor_load(CURSORSHAPE __far *lpCursor, longRECT __far *changes);
-void cursor_unload(longRECT __far *changes);
-void cursor_coordinates(long curx, long cury);
-void cursor_erase(longRECT __far *changes);
-void cursor_blit(longRECT __far *changes);
-void cursor_move(longRECT __far *changes);
-void cursor_merge_rect(longRECT __far *r1, longRECT __far *r2);
-
-void cursor_lock();
-void cursor_unlock();
-
-extern BOOL sw_cursor_enabled;
-extern SWCURSOR __far *sw_cursor;
-
-#endif /* __SWCURSOR_H__INCLUDED__ */
diff --git a/vmware/pci32.c b/vmware/pci32.c
deleted file mode 100644
index cd00f19..0000000
--- a/vmware/pci32.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define VXD32
-#include "pci.c"
diff --git a/vmware/svga.c b/vmware/svga.c
index 573a568..8f320ae 100644
--- a/vmware/svga.c
+++ b/vmware/svga.c
@@ -37,6 +37,10 @@
#include "svga_all.h"
#ifdef VXD32
+#include "code32.h"
+#endif
+
+#ifdef VXD32
#define IO_IN32
#define IO_OUT32
#include "io32.h"
@@ -64,11 +68,6 @@ void dbg_printf( const char *s, ... );
#define MAX(a, b) (((b) > (a)) ? (b) : (a))
#endif
-#ifdef VXD32
-#include "code32.h"
-#endif
-
-
SVGADevice gSVGA = {0};
static void SVGAFIFOFull(void);
@@ -190,7 +189,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
gSVGA.fifoPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 2);
} else {
- if(SVGA_IsSVGA3()) /* VMware SVGA2 */
+ if(SVGA_IsSVGA3()) /* VMware SVGA3 */
{
gSVGA.rmmio_start = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
gSVGA.rmmio_size = PCI_GetBARSize(&gSVGA.pciAddr, 0);
@@ -201,7 +200,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
gSVGA.fifoPhy = 0;
gSVGA.ioBase = 0;
}
- else /* VMware SVGA3 */
+ else /* VMware SVGA2 */
{
gSVGA.ioBase = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
@@ -280,6 +279,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
#ifdef VXD32
if (gSVGA.fbSize < 0x100000) {
SVGA_Panic("FB size very small, probably incorrect.");
+ return 4;
}
#endif
@@ -287,6 +287,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
{
if (gSVGA.fifoSize < 0x20000) {
SVGA_Panic("FIFO size very small, probably incorrect.");
+ return 5;
}
}
@@ -489,7 +490,7 @@ SVGA_Disable(void)
*/
void
-SVGA_SetMode(uint32 width, // IN
+SVGA_SetModeLegacy(uint32 width, // IN
uint32 height, // IN
uint32 bpp) // IN
{
@@ -681,6 +682,110 @@ SVGA_HasFIFOCap(unsigned long cap)
return (gSVGA.fifoMem[SVGA_FIFO_CAPABILITIES] & cap) != 0;
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_RingDoorbell --
+ *
+ * FIFO fences are fundamentally a host-to-guest notification
+ * mechanism. This is the opposite: we can explicitly wake up
+ * the host when we know there is work for it to do.
+ *
+ * Background: The host processes the SVGA command FIFO in a
+ * separate thread which runs asynchronously with the virtual
+ * machine's CPU and other I/O devices. When the SVGA device is
+ * idle, this thread is sleeping. It periodically wakes up to
+ * poll for new commands. This polling must occur for various
+ * reasons, but it's mostly related to the historical way in
+ * which the SVGA device processes 2D updates.
+ *
+ * This polling introduces significant latency between when the
+ * first new command is placed in an empty FIFO, and when the
+ * host begins processing it. Normally this isn't a huge problem
+ * since the host and guest run fairly asynchronously, but in
+ * a synchronization-heavy workload this can be a bottleneck.
+ *
+ * For example, imagine an application with a worst-case
+ * synchronization bottleneck: The guest enqueues a single FIFO
+ * command, then waits for that command to finish using
+ * SyncToFence, then the guest spends a little time doing
+ * CPU-intensive processing before the cycle repeats. The
+ * workload may be latency-bound if the host-to-guest or
+ * guest-to-host notifications ever block.
+ *
+ * One solution would be for the guest to explicitly wake up the
+ * SVGA3D device any time a command is enqueued. This would solve
+ * the latency bottleneck above, but it would be inefficient on
+ * single-CPU host machines. One could easily imagine a situation
+ * in which we wake up the host after enqueueing one FIFO
+ * command, the physical CPU context switches to the SVGA
+ * device's thread, the single command is processed, then we
+ * context switch back to running guest code.
+ *
+ * Our recommended solution is to wake up the host only either:
+ *
+ * - After a "significant" amount of work has been enqueued into
+ * the FIFO. For example, at least one 3D drawing command.
+ *
+ * - After a complete frame has been rendered.
+ *
+ * - Just before the guest sleeps for any reason.
+ *
+ * This function implements the above guest wakeups. It uses the
+ * SVGA_FIFO_BUSY register to quickly assess whether the SVGA
+ * device may be idle. If so, it asynchronously wakes up the host
+ * by writing to SVGA_REG_SYNC.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May wake up the SVGA3D device.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_RingDoorbell(void)
+{
+ if (SVGA_IsFIFORegValid(SVGA_FIFO_BUSY) &&
+ gSVGA.fifoMem[SVGA_FIFO_BUSY] == FALSE) {
+
+ /* Remember that we already rang the doorbell. */
+ gSVGA.fifoMem[SVGA_FIFO_BUSY] = TRUE;
+
+ /*
+ * Asynchronously wake up the SVGA3D device. The second
+ * parameter is an arbitrary nonzero 'sync reason' which can be
+ * used for debugging, but which isn't part of the SVGA3D
+ * protocol proper and which isn't used by release builds of
+ * VMware products.
+ */
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Flush --
+ *
+ * Force to apply all register changes. Useful if registry changes
+ * needs be applyed immediately
+ *
+ *-----------------------------------------------------------------------------
+ */
+void SVGA_Flush(void)
+{
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ while (SVGA_ReadReg(SVGA_REG_BUSY) != FALSE);
+#ifndef VXD32
+ dbg_printf("SVGA_Flush\n");
+#endif
+}
+
+#if 0 /* JH: all commands using bounce buffer and fifo, better write them myself */
/*
*-----------------------------------------------------------------------------
@@ -1455,110 +1560,6 @@ SVGA_HasFencePassed(uint32 fence) // IN
/*
*-----------------------------------------------------------------------------
*
- * SVGA_RingDoorbell --
- *
- * FIFO fences are fundamentally a host-to-guest notification
- * mechanism. This is the opposite: we can explicitly wake up
- * the host when we know there is work for it to do.
- *
- * Background: The host processes the SVGA command FIFO in a
- * separate thread which runs asynchronously with the virtual
- * machine's CPU and other I/O devices. When the SVGA device is
- * idle, this thread is sleeping. It periodically wakes up to
- * poll for new commands. This polling must occur for various
- * reasons, but it's mostly related to the historical way in
- * which the SVGA device processes 2D updates.
- *
- * This polling introduces significant latency between when the
- * first new command is placed in an empty FIFO, and when the
- * host begins processing it. Normally this isn't a huge problem
- * since the host and guest run fairly asynchronously, but in
- * a synchronization-heavy workload this can be a bottleneck.
- *
- * For example, imagine an application with a worst-case
- * synchronization bottleneck: The guest enqueues a single FIFO
- * command, then waits for that command to finish using
- * SyncToFence, then the guest spends a little time doing
- * CPU-intensive processing before the cycle repeats. The
- * workload may be latency-bound if the host-to-guest or
- * guest-to-host notifications ever block.
- *
- * One solution would be for the guest to explicitly wake up the
- * SVGA3D device any time a command is enqueued. This would solve
- * the latency bottleneck above, but it would be inefficient on
- * single-CPU host machines. One could easily imagine a situation
- * in which we wake up the host after enqueueing one FIFO
- * command, the physical CPU context switches to the SVGA
- * device's thread, the single command is processed, then we
- * context switch back to running guest code.
- *
- * Our recommended solution is to wake up the host only either:
- *
- * - After a "significant" amount of work has been enqueued into
- * the FIFO. For example, at least one 3D drawing command.
- *
- * - After a complete frame has been rendered.
- *
- * - Just before the guest sleeps for any reason.
- *
- * This function implements the above guest wakeups. It uses the
- * SVGA_FIFO_BUSY register to quickly assess whether the SVGA
- * device may be idle. If so, it asynchronously wakes up the host
- * by writing to SVGA_REG_SYNC.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May wake up the SVGA3D device.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-SVGA_RingDoorbell(void)
-{
- if (SVGA_IsFIFORegValid(SVGA_FIFO_BUSY) &&
- gSVGA.fifoMem[SVGA_FIFO_BUSY] == FALSE) {
-
- /* Remember that we already rang the doorbell. */
- gSVGA.fifoMem[SVGA_FIFO_BUSY] = TRUE;
-
- /*
- * Asynchronously wake up the SVGA3D device. The second
- * parameter is an arbitrary nonzero 'sync reason' which can be
- * used for debugging, but which isn't part of the SVGA3D
- * protocol proper and which isn't used by release builds of
- * VMware products.
- */
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SVGA_Flush --
- *
- * Force to apply all register changes. Useful if registry changes
- * needs be applyed immediately
- *
- *-----------------------------------------------------------------------------
- */
-void SVGA_Flush(void)
-{
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- while (SVGA_ReadReg(SVGA_REG_BUSY) != FALSE);
-#ifndef VXD32
- dbg_printf("SVGA_Flush\n");
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
* SVGA_ClearIRQ --
*
* Clear all pending IRQs. Any IRQs which occurred prior to this
@@ -2091,3 +2092,5 @@ SVGA_VideoFlush(uint32 streamId) // IN
cmd->streamId = streamId;
SVGA_FIFOCommitAll();
}
+
+#endif /* 0 */
diff --git a/vmware/svga.h b/vmware/svga.h
index 733f3af..6fc4b72 100644
--- a/vmware/svga.h
+++ b/vmware/svga.h
@@ -137,7 +137,7 @@ int __loadds 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);
+void SVGA_SetModeLegacy(uint32 width, uint32 height, uint32 bpp);
void SVGA_Disable(void);
void SVGA_Panic(const char *err);
void SVGA_DefaultFaultHandler(int vector);
diff --git a/vmware/svga32.c b/vmware/svga32.c
deleted file mode 100644
index 1091735..0000000
--- a/vmware/svga32.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define VXD32
-#include "svga.c"
diff --git a/vmware/svga_reg.h b/vmware/svga_reg.h
index ab904a7..2d8b2a6 100644
--- a/vmware/svga_reg.h
+++ b/vmware/svga_reg.h
@@ -460,6 +460,8 @@ typedef enum {
typedef enum {
SVGA_CB_FLAG_NONE = 0,
SVGA_CB_FLAG_NO_IRQ = 1 << 0,
+ SVGA_CB_FLAG_DX_CONTEXT = 1 << 1,
+ SVGA_CB_FLAG_MOB = 1 << 2,
SVGA_CB_FLAG_FORCE_UINT = MAX_UINT32,
} SVGACBFlags;
@@ -473,7 +475,9 @@ struct {
union {
uint64 pa; // PA
} ptr;
- uint32 mustBeZero[8];
+ uint32 offset; /* Valid if CMD_BUFFERS_2 cap set, must be zero otherwise, modified by device. */
+ uint32 dxContext; /* Valid if DX_CONTEXT flag set, must be zero otherwise */
+ uint32 mustBeZero[6];
} SVGACBHeader;
typedef enum {
diff --git a/vmwsmini.lst b/vmwsmini.lst
new file mode 100644
index 0000000..589c7d2
--- /dev/null
+++ b/vmwsmini.lst
@@ -0,0 +1,5338 @@
+cseg01:C0000000 ;
+cseg01:C0000000 ; +-------------------------------------------------------------------------+
+cseg01:C0000000 ; | This file has been generated by The Interactive Disassembler (IDA) |
+cseg01:C0000000 ; | Copyright (c) 2015 Hex-Rays, <support@hex-rays.com> |
+cseg01:C0000000 ; | License info: 48-B611-7234-BB |
+cseg01:C0000000 ; | Doskey Lee, Kingsoft Internet Security Software |
+cseg01:C0000000 ; +-------------------------------------------------------------------------+
+cseg01:C0000000 ;
+cseg01:C0000000 ; Input MD5 : 7293BC05582EF6DC3A231E597D3A70BE
+cseg01:C0000000 ; Input CRC32 : 1D73AFE9
+cseg01:C0000000
+cseg01:C0000000 ; File Name : D:\Projekty\vssync\vmdisp9x\vmwsmini.vxd
+cseg01:C0000000 ; Format : Linear Executable (LE)
+cseg01:C0000000 ; Target operating system MS Windows 386
+cseg01:C0000000 ; Module Version 00000000h ( 0. )
+cseg01:C0000000 ; Program Entry Point (CS:EIP) 0:00000000h
+cseg01:C0000000 ; Initial Stack Pointer (SS:ESP) 0:00000000h
+cseg01:C0000000 ; DS Object 2
+cseg01:C0000000 ; Heap Size 00000000h ( 0. )
+cseg01:C0000000 ; Program Flags (00038000h): Prot. Virt. Dev. Driver
+cseg01:C0000000 ; ----------------------------------------------------------------------------
+cseg01:C0000000 ; Object Number : 1.
+cseg01:C0000000 ; Virtual Size : 00002BC1h
+cseg01:C0000000 ; Number of Pages : 3 (present in the file)
+cseg01:C0000000 ; Attributes (00002045): Readable Executable PreloadPages Big
+cseg01:C0000000
+cseg01:C0000000 .686p
+cseg01:C0000000 .mmx
+cseg01:C0000000 .model flat
+cseg01:C0000000
+cseg01:C0000000 ; ===========================================================================
+cseg01:C0000000
+cseg01:C0000000 ; Segment type: Pure code
+cseg01:C0000000 cseg01 segment para public 'CODE' use32
+cseg01:C0000000 assume cs:cseg01
+cseg01:C0000000 ;org 0C0000000h
+cseg01:C0000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
+cseg01:C0000000
+cseg01:C0000000 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000000
+cseg01:C0000000
+cseg01:C0000000 sub_C0000000 proc near ; CODE XREF: sub_C00028A2+5p
+cseg01:C0000000
+cseg01:C0000000 arg_0 = dword ptr 4
+cseg01:C0000000
+cseg01:C0000000 mov edx, [esp+arg_0]
+cseg01:C0000004 in al, dx
+cseg01:C0000005 retn
+cseg01:C0000005 sub_C0000000 endp
+cseg01:C0000005
+cseg01:C0000006
+cseg01:C0000006 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000006
+cseg01:C0000006
+cseg01:C0000006 sub_C0000006 proc near ; CODE XREF: sub_C0002841+7p
+cseg01:C0000006 ; sub_C0002841+19p ...
+cseg01:C0000006
+cseg01:C0000006 arg_0 = dword ptr 4
+cseg01:C0000006 arg_4 = byte ptr 8
+cseg01:C0000006
+cseg01:C0000006 mov al, [esp+arg_4]
+cseg01:C000000A mov edx, [esp+arg_0]
+cseg01:C000000E out dx, al
+cseg01:C000000F retn
+cseg01:C000000F sub_C0000006 endp
+cseg01:C000000F
+cseg01:C000000F ; ---------------------------------------------------------------------------
+cseg01:C0000010 dword_C0000010 dd 3 dup(0) ; DATA XREF: sub_C0000F51+Co
+cseg01:C000001C
+cseg01:C000001C ; =============== S U B R O U T I N E =======================================
+cseg01:C000001C
+cseg01:C000001C
+cseg01:C000001C sub_C000001C proc near ; CODE XREF: sub_C0000DC1+26p
+cseg01:C000001C
+cseg01:C000001C arg_0 = dword ptr 4
+cseg01:C000001C
+cseg01:C000001C mov edx, [esp+arg_0]
+cseg01:C0000020
+cseg01:C0000020 loc_C0000020: ; DATA XREF: sub_C00020E0+41o
+cseg01:C0000020 ; sub_C00025C1+3Bo
+cseg01:C0000020 in eax, dx
+cseg01:C0000021 retn
+cseg01:C0000021 sub_C000001C endp
+cseg01:C0000021
+cseg01:C0000022
+cseg01:C0000022 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000022
+cseg01:C0000022
+cseg01:C0000022 sub_C0000022 proc near ; CODE XREF: sub_C0000DC1+19p
+cseg01:C0000022 ; sub_C0000DF0+19p ...
+cseg01:C0000022
+cseg01:C0000022 arg_0 = dword ptr 4
+cseg01:C0000022 arg_4 = dword ptr 8
+cseg01:C0000022
+cseg01:C0000022 mov eax, [esp+arg_4]
+cseg01:C0000026 mov edx, [esp+arg_0]
+cseg01:C000002A out dx, eax
+cseg01:C000002B retn
+cseg01:C000002B sub_C0000022 endp
+cseg01:C000002B
+cseg01:C000002C
+cseg01:C000002C ; =============== S U B R O U T I N E =======================================
+cseg01:C000002C
+cseg01:C000002C
+cseg01:C000002C sub_C000002C proc near ; CODE XREF: sub_C0000DF0+26p
+cseg01:C000002C
+cseg01:C000002C arg_0 = dword ptr 4
+cseg01:C000002C
+cseg01:C000002C mov edx, [esp+arg_0]
+cseg01:C0000030 in ax, dx
+cseg01:C0000032 retn
+cseg01:C0000032 sub_C000002C endp
+cseg01:C0000032
+cseg01:C0000033
+cseg01:C0000033 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000033
+cseg01:C0000033
+cseg01:C0000033 sub_C0000033 proc near ; CODE XREF: sub_C0000E82+2Cp
+cseg01:C0000033
+cseg01:C0000033 arg_0 = dword ptr 4
+cseg01:C0000033 arg_4 = dword ptr 8
+cseg01:C0000033
+cseg01:C0000033 mov eax, [esp+arg_4]
+cseg01:C0000037 mov edx, [esp+arg_0]
+cseg01:C000003B out dx, ax
+cseg01:C000003D retn
+cseg01:C000003D sub_C0000033 endp
+cseg01:C000003D
+cseg01:C000003E
+cseg01:C000003E ; =============== S U B R O U T I N E =======================================
+cseg01:C000003E
+cseg01:C000003E
+cseg01:C000003E sub_C000003E proc near ; CODE XREF: cseg01:C0000E45p
+cseg01:C000003E
+cseg01:C000003E arg_0 = dword ptr 4
+cseg01:C000003E
+cseg01:C000003E mov edx, [esp+arg_0]
+cseg01:C0000042 in al, dx
+cseg01:C0000043 retn
+cseg01:C0000043 sub_C000003E endp
+cseg01:C0000043
+cseg01:C0000043 ; ---------------------------------------------------------------------------
+cseg01:C0000044 dword_C0000044 dd 0 ; DATA XREF: sub_C00028B5r
+cseg01:C0000044 ; sub_C00028B5+Ew
+cseg01:C0000048 ;
+cseg01:C0000048 ; External Entry #1 into the Module vmwsmini
+cseg01:C0000048 ; Attributes: 32-bit entry Exported
+cseg01:C0000048 ;
+cseg01:C0000048 public VMWS_DDB
+cseg01:C0000048 VMWS_DDB dd 0 ; Next_0
+cseg01:C000004C SDK_Version_0 dw 30Ah
+cseg01:C000004E Req_Device_Number_0 dw 4331h
+cseg01:C0000050 Dev_Major_Version_0 db 4 ; Major device number
+cseg01:C0000051 Dev_Minor_Version_0 db 0 ; Minor device number
+cseg01:C0000052 Flags_0 dw 0 ; Flags for init calls complete
+cseg01:C0000054 Name_0 db 'VMWSVXD',0 ; Device name
+cseg01:C000005C Init_Order_0 dd 28000000h ; Initialization Order
+cseg01:C0000060 Control_Proc_0 dd offset Control_0 ; Offset of control procedure
+cseg01:C0000064 V86_API_Proc_0 dd offset V86_0 ; Offset of API procedure (or 0)
+cseg01:C0000068 PM_API_Proc_0 dd offset V86_0 ; Offset of API procedure (or 0)
+cseg01:C000006C V86_API_CSIP_0 dd 0 ; CS:IP of API entry point
+cseg01:C0000070 PM_API_CSIP_0 dd 0 ; CS:IP of API entry point
+cseg01:C0000074 Reference_Data_0 dd 0 ; Reference data from real mode
+cseg01:C0000078 Service_Table_Ptr_0 dd 0 ; Pointer to service table
+cseg01:C000007C Service_Size_0 dd 0 ; Number of services
+cseg01:C0000080 Win32_Service_Table_0 dd 0 ; Pointer to Win32 services
+cseg01:C0000084 Prev_0 dd 0 ; Pointer to previous DDB
+cseg01:C0000088 Size_0 dd 50h ; Size of VxD_Desc_Block
+cseg01:C000008C Reserved1_0 dd 0
+cseg01:C0000090 Reserved2_0 dd 0
+cseg01:C0000094 Reserved3_0 dd 0
+cseg01:C0000098 aHelloWorld db 'Hello world!',0Ah,0
+cseg01:C00000A6 aVmmVersion db 'VMM version: ',0
+cseg01:C00000B4 aRegionCreateEr db 'region create error',0Ah,0
+cseg01:C00000C9 aDevice_init_pr db 'Device_Init_proc',0Ah,0 ; DATA XREF: sub_C000050Ao
+cseg01:C00000DB aDevice_init__0 db 'Device_Init_proc success',0Ah,0
+cseg01:C00000DB ; DATA XREF: sub_C00019F5+17Bo
+cseg01:C00000F5 aDeviceiocont_1 db 'DeviceIOControl: Ring',0Ah,0
+cseg01:C000010C aDeviceiocont_2 db 'DeviceIOControl: Sync',0Ah,0
+cseg01:C0000123 aDeviceiocont_0 db 'DeviceIOControl: Unknown: %d',0Ah,0
+cseg01:C0000123 ; DATA XREF: sub_C000055F+21Fo
+cseg01:C0000141 aDeviceiocontro db 'DeviceIOControl: System code: %d',0Ah,0
+cseg01:C0000141 ; DATA XREF: sub_C000055F+FCo
+cseg01:C0000163 aLxLx db '%lx -> %lx',0Ah,0
+cseg01:C000016F aVirtualLx db 'Virtual: %lx',0Ah,0
+cseg01:C000017D aAllocatedOtabl db 'Allocated OTable row: %d',0Ah,0
+cseg01:C000017D ; DATA XREF: sub_C0001599+92o
+cseg01:C0000197 aS db '%s',0Ah,0
+cseg01:C000019B aCbSubmitFailed db 'CB submit FAILED',0Ah,0
+cseg01:C00001AD aCbSubmitD db 'CB submit %d',0Ah,0
+cseg01:C00001BB aReusedCbDWithS db 'Reused CB (%d) with status: %d',0Ah,0
+cseg01:C00001DB aErrorCommandLx db 'Error command: %lX',0Ah,0
+cseg01:C00001EF aCbSupportedAnd db 'CB supported and allocated',0Ah,0
+cseg01:C00001EF ; DATA XREF: sub_C00019F5+2C3o
+cseg01:C000020B aGbSupportedAnd db 'GB supported and allocated',0Ah,0
+cseg01:C000020B ; DATA XREF: sub_C00019F5+294o
+cseg01:C0000227 aCbContext0Enab db 'CB context 0 enabled',0Ah,0
+cseg01:C000023D aRegionIdD db 'Region id = %d',0Ah,0
+cseg01:C000024D aRegionAddressL db 'Region address = %lX, PPN = %lX, GMRBLK = %lX',0Ah,0
+cseg01:C000027C aMemoryMapping db 'Memory mapping:',0Ah,0
+cseg01:C000027C ; DATA XREF: sub_C00019F5:loc_C0001BF6o
+cseg01:C000028D aXX db ' %X -> %X',0Ah,0 ; DATA XREF: sub_C00019F5+195o
+cseg01:C000028D ; sub_C00019F5+21Co ...
+cseg01:C0000299 aDriverDestroye db 'Driver destroyed',0Ah,0 ; DATA XREF: sub_C0000795o
+cseg01:C00002AB aSizeOfGsvga2DD db 'Size of gSVGA(2) = %d %d',0Ah,0
+cseg01:C00002AB ; DATA XREF: sub_C00019F5+262o
+cseg01:C00002C5 aTestD db 'test %d',0Ah,0 ; DATA XREF: sub_C00019F5+8Co
+cseg01:C00002C5 ; sub_C00019F5+EBo ...
+cseg01:C00002CE aSvga_initD db 'SVGA_Init: %d',0Ah,0 ; DATA XREF: sub_C00019F5+ABo
+cseg01:C00002DD aUpdateScreenDD db 'Update screen: %d %d %d',0Ah,0
+cseg01:C00002F6 dword_C00002F6 dd 0 ; DATA XREF: sub_C0000302+9w
+cseg01:C00002F6 ; sub_C000050A+29r ...
+cseg01:C00002FA dword_C00002FA dd 0 ; DATA XREF: sub_C0000302+Fw
+cseg01:C00002FA ; sub_C000050A+20r
+cseg01:C00002FE dword_C00002FE dd 0 ; DATA XREF: sub_C000050A+11w
+cseg01:C0000302
+cseg01:C0000302 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000302
+cseg01:C0000302
+cseg01:C0000302 sub_C0000302 proc near ; CODE XREF: sub_C000050A+1Bp
+cseg01:C0000302 push ebx
+cseg01:C0000303 push esi
+cseg01:C0000304 push edi
+cseg01:C0000305 VxDCall VDD_Get_Mini_Dispatch_Table
+cseg01:C000030B mov ds:dword_C00002F6, edi
+cseg01:C0000311 mov ds:dword_C00002FA, ecx
+cseg01:C0000317 pop edi
+cseg01:C0000318 pop esi
+cseg01:C0000319 pop ebx
+cseg01:C0000319 sub_C0000302 endp ; sp-analysis failed
+cseg01:C0000319
+cseg01:C000031A ; [00000001 BYTES: COLLAPSED FUNCTION nullsub_1. PRESS CTRL-NUMPAD+ TO EXPAND]
+cseg01:C000031B ; ---------------------------------------------------------------------------
+cseg01:C000031B ; START OF FUNCTION CHUNK FOR Control_0
+cseg01:C000031B
+cseg01:C000031B loc_C000031B: ; CODE XREF: Control_0+3Fj
+cseg01:C000031B push esi
+cseg01:C000031C call sub_C000055F
+cseg01:C0000321 retn
+cseg01:C0000321 ; END OF FUNCTION CHUNK FOR Control_0
+cseg01:C0000322
+cseg01:C0000322 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000322
+cseg01:C0000322
+cseg01:C0000322 public Control_0
+cseg01:C0000322 Control_0 proc near ; DATA XREF: cseg01:Control_Proc_0o
+cseg01:C0000322
+cseg01:C0000322 ; FUNCTION CHUNK AT cseg01:C000031B SIZE 00000007 BYTES
+cseg01:C0000322
+cseg01:C0000322 cmp eax, 0
+cseg01:C0000325 jnz loc_C0000334
+cseg01:C000032B pusha
+cseg01:C000032C call nullsub_1
+cseg01:C0000331 popa
+cseg01:C0000332 clc
+cseg01:C0000333 retn
+cseg01:C0000334 ; ---------------------------------------------------------------------------
+cseg01:C0000334
+cseg01:C0000334 loc_C0000334: ; CODE XREF: Control_0+3j
+cseg01:C0000334 cmp eax, 1
+cseg01:C0000337 jnz loc_C0000345
+cseg01:C000033D call nullsub_1
+cseg01:C0000342 popa
+cseg01:C0000343 clc
+cseg01:C0000344 retn
+cseg01:C0000345 ; ---------------------------------------------------------------------------
+cseg01:C0000345
+cseg01:C0000345 loc_C0000345: ; CODE XREF: Control_0+15j
+cseg01:C0000345 cmp eax, 1Bh
+cseg01:C0000348 jnz loc_C0000358
+cseg01:C000034E pusha
+cseg01:C000034F push ebx
+cseg01:C0000350 call sub_C000050A
+cseg01:C0000355 popa
+cseg01:C0000356 clc
+cseg01:C0000357 retn
+cseg01:C0000358 ; ---------------------------------------------------------------------------
+cseg01:C0000358
+cseg01:C0000358 loc_C0000358: ; CODE XREF: Control_0+26j
+cseg01:C0000358 cmp eax, 23h
+cseg01:C000035B jnz loc_C0000366
+cseg01:C0000361 jmp loc_C000031B
+cseg01:C0000366 ; ---------------------------------------------------------------------------
+cseg01:C0000366
+cseg01:C0000366 loc_C0000366: ; CODE XREF: Control_0+39j
+cseg01:C0000366 cmp eax, 5
+cseg01:C0000369 jnz loc_C0000379
+cseg01:C000036F pusha
+cseg01:C0000370 push ebx
+cseg01:C0000371 call sub_C0000795
+cseg01:C0000376 popa
+cseg01:C0000377 clc
+cseg01:C0000378 retn
+cseg01:C0000379 ; ---------------------------------------------------------------------------
+cseg01:C0000379
+cseg01:C0000379 loc_C0000379: ; CODE XREF: Control_0+47j
+cseg01:C0000379 clc
+cseg01:C000037A retn
+cseg01:C000037A Control_0 endp ; sp-analysis failed
+cseg01:C000037A
+cseg01:C000037B
+cseg01:C000037B ; =============== S U B R O U T I N E =======================================
+cseg01:C000037B
+cseg01:C000037B
+cseg01:C000037B sub_C000037B proc near ; CODE XREF: V86_0+1p
+cseg01:C000037B
+cseg01:C000037B arg_0 = dword ptr 4
+cseg01:C000037B
+cseg01:C000037B push ebx
+cseg01:C000037C push esi
+cseg01:C000037D push edi
+cseg01:C000037E push ebp
+cseg01:C000037F mov ebx, [esp+10h+arg_0]
+cseg01:C0000383 mov esi, 0FFFFh
+cseg01:C0000388 mov ax, [ebx+14h]
+cseg01:C000038C cmp ax, 110Fh
+cseg01:C0000390 jb short loc_C00003EA
+cseg01:C0000392 jbe loc_C0000461
+cseg01:C0000398 cmp ax, 2001h
+cseg01:C000039C jb short loc_C00003C7
+cseg01:C000039E jbe loc_C0000496
+cseg01:C00003A4 cmp ax, 2004h
+cseg01:C00003A8 jz loc_C00004D7
+cseg01:C00003AE cmp ax, 2003h
+cseg01:C00003B2 jz loc_C00004D0
+cseg01:C00003B8 cmp ax, 2002h
+cseg01:C00003BC jz loc_C00004BE
+cseg01:C00003C2 jmp loc_C00004DE
+cseg01:C00003C7 ; ---------------------------------------------------------------------------
+cseg01:C00003C7
+cseg01:C00003C7 loc_C00003C7: ; CODE XREF: sub_C000037B+21j
+cseg01:C00003C7 cmp ax, 2000h
+cseg01:C00003CB jz loc_C000048F
+cseg01:C00003D1 cmp ax, 1111h
+cseg01:C00003D5 jz loc_C000047C
+cseg01:C00003DB cmp ax, 1110h
+cseg01:C00003DF jz loc_C0000468
+cseg01:C00003E5 jmp loc_C00004DE
+cseg01:C00003EA ; ---------------------------------------------------------------------------
+cseg01:C00003EA
+cseg01:C00003EA loc_C00003EA: ; CODE XREF: sub_C000037B+15j
+cseg01:C00003EA cmp ax, 110Bh
+cseg01:C00003EE jb short loc_C0000400
+cseg01:C00003F0 jbe short loc_C0000425
+cseg01:C00003F2 cmp ax, 110Eh
+cseg01:C00003F6 jz short loc_C0000453
+cseg01:C00003F8 cmp ax, 110Dh
+cseg01:C00003FC jz short loc_C0000448
+cseg01:C00003FE jmp short loc_C000043A
+cseg01:C0000400 ; ---------------------------------------------------------------------------
+cseg01:C0000400
+cseg01:C0000400 loc_C0000400: ; CODE XREF: sub_C000037B+73j
+cseg01:C0000400 cmp ax, 1
+cseg01:C0000404 jz short loc_C0000419
+cseg01:C0000406 test ax, ax
+cseg01:C0000409 jnz loc_C00004DE
+cseg01:C000040F mov esi, 400h
+cseg01:C0000414 jmp loc_C00004B1
+cseg01:C0000419 ; ---------------------------------------------------------------------------
+cseg01:C0000419
+cseg01:C0000419 loc_C0000419: ; CODE XREF: sub_C000037B+89j
+cseg01:C0000419 call sub_C0001270
+cseg01:C000041E mov esi, eax
+cseg01:C0000420 jmp loc_C00004DE
+cseg01:C0000425 ; ---------------------------------------------------------------------------
+cseg01:C0000425
+cseg01:C0000425 loc_C0000425: ; CODE XREF: sub_C000037B+75j
+cseg01:C0000425 call sub_C0001157
+cseg01:C000042A test eax, eax
+cseg01:C000042C jz loc_C00004DE
+cseg01:C0000432 mov [ebx+18h], eax
+cseg01:C0000435 jmp loc_C00004AC
+cseg01:C000043A ; ---------------------------------------------------------------------------
+cseg01:C000043A
+cseg01:C000043A loc_C000043A: ; CODE XREF: sub_C000037B+83j
+cseg01:C000043A mov edx, [ebx+18h]
+cseg01:C000043D push edx
+cseg01:C000043E call sub_C000115D
+cseg01:C0000443
+cseg01:C0000443 loc_C0000443: ; CODE XREF: sub_C000037B+D6j
+cseg01:C0000443 add esp, 4
+cseg01:C0000446 jmp short loc_C00004AC
+cseg01:C0000448 ; ---------------------------------------------------------------------------
+cseg01:C0000448
+cseg01:C0000448 loc_C0000448: ; CODE XREF: sub_C000037B+81j
+cseg01:C0000448 mov ecx, [ebx+18h]
+cseg01:C000044B push ecx
+cseg01:C000044C call sub_C0002630
+cseg01:C0000451 jmp short loc_C0000443
+cseg01:C0000453 ; ---------------------------------------------------------------------------
+cseg01:C0000453
+cseg01:C0000453 loc_C0000453: ; CODE XREF: sub_C000037B+7Bj
+cseg01:C0000453 mov esi, [ebx+18h]
+cseg01:C0000456 push esi
+cseg01:C0000457 call sub_C0002180
+cseg01:C000045C add esp, 4
+cseg01:C000045F jmp short loc_C00004A9
+cseg01:C0000461 ; ---------------------------------------------------------------------------
+cseg01:C0000461
+cseg01:C0000461 loc_C0000461: ; CODE XREF: sub_C000037B+17j
+cseg01:C0000461 call sub_C000116E
+cseg01:C0000466 jmp short loc_C00004AC
+cseg01:C0000468 ; ---------------------------------------------------------------------------
+cseg01:C0000468
+cseg01:C0000468 loc_C0000468: ; CODE XREF: sub_C000037B+64j
+cseg01:C0000468 mov eax, [ebx]
+cseg01:C000046A push eax
+cseg01:C000046B mov al, [ebx+18h]
+cseg01:C000046E movzx eax, al
+cseg01:C0000471 push eax
+cseg01:C0000472 call sub_C00026B8
+cseg01:C0000477 add esp, 8
+cseg01:C000047A jmp short loc_C00004AC
+cseg01:C000047C ; ---------------------------------------------------------------------------
+cseg01:C000047C
+cseg01:C000047C loc_C000047C: ; CODE XREF: sub_C000037B+5Aj
+cseg01:C000047C mov al, [ebx+18h]
+cseg01:C000047F movzx eax, al
+cseg01:C0000482 push eax
+cseg01:C0000483 call sub_C000270C
+cseg01:C0000488 add esp, 4
+cseg01:C000048B mov [ebx], eax
+cseg01:C000048D jmp short loc_C00004AC
+cseg01:C000048F ; ---------------------------------------------------------------------------
+cseg01:C000048F
+cseg01:C000048F loc_C000048F: ; CODE XREF: sub_C000037B+50j
+cseg01:C000048F call sub_C000262A
+cseg01:C0000494 jmp short loc_C00004A9
+cseg01:C0000496 ; ---------------------------------------------------------------------------
+cseg01:C0000496
+cseg01:C0000496 loc_C0000496: ; CODE XREF: sub_C000037B+23j
+cseg01:C0000496 mov esi, [ebx+18h]
+cseg01:C0000499 push esi
+cseg01:C000049A mov edi, [ebx]
+cseg01:C000049C push edi
+cseg01:C000049D mov ebp, [ebx+4]
+cseg01:C00004A0 push ebp
+cseg01:C00004A1 call sub_C0002353
+cseg01:C00004A6
+cseg01:C00004A6 loc_C00004A6: ; CODE XREF: sub_C000037B+153j
+cseg01:C00004A6 add esp, 0Ch
+cseg01:C00004A9
+cseg01:C00004A9 loc_C00004A9: ; CODE XREF: sub_C000037B+E4j
+cseg01:C00004A9 ; sub_C000037B+119j
+cseg01:C00004A9 mov [ebx+1Ch], eax
+cseg01:C00004AC
+cseg01:C00004AC loc_C00004AC: ; CODE XREF: sub_C000037B+BAj
+cseg01:C00004AC ; sub_C000037B+CBj ...
+cseg01:C00004AC mov esi, 1
+cseg01:C00004B1
+cseg01:C00004B1 loc_C00004B1: ; CODE XREF: sub_C000037B+99j
+cseg01:C00004B1 ; sub_C000037B+167j
+cseg01:C00004B1 and byte ptr [ebx+2Ch], 0FEh
+cseg01:C00004B5
+cseg01:C00004B5 loc_C00004B5: ; CODE XREF: sub_C000037B+16Dj
+cseg01:C00004B5 mov eax, esi
+cseg01:C00004B7
+cseg01:C00004B7 loc_C00004B7: ; CODE XREF: sub_C000055F+139j
+cseg01:C00004B7 ; sub_C000055F+231j
+cseg01:C00004B7 pop ebp
+cseg01:C00004B8 pop edi
+cseg01:C00004B9 pop esi
+cseg01:C00004BA pop ebx
+cseg01:C00004BB retn 4
+cseg01:C00004BE ; ---------------------------------------------------------------------------
+cseg01:C00004BE
+cseg01:C00004BE loc_C00004BE: ; CODE XREF: sub_C000037B+41j
+cseg01:C00004BE mov eax, [ebx+18h]
+cseg01:C00004C1 push eax
+cseg01:C00004C2 mov edx, [ebx]
+cseg01:C00004C4 push edx
+cseg01:C00004C5 mov ecx, [ebx+4]
+cseg01:C00004C8 push ecx
+cseg01:C00004C9 call sub_C00022E5
+cseg01:C00004CE jmp short loc_C00004A6
+cseg01:C00004D0 ; ---------------------------------------------------------------------------
+cseg01:C00004D0
+cseg01:C00004D0 loc_C00004D0: ; CODE XREF: sub_C000037B+37j
+cseg01:C00004D0 call sub_C00025A4
+cseg01:C00004D5 jmp short loc_C00004AC
+cseg01:C00004D7 ; ---------------------------------------------------------------------------
+cseg01:C00004D7
+cseg01:C00004D7 loc_C00004D7: ; CODE XREF: sub_C000037B+2Dj
+cseg01:C00004D7 call sub_C0002620
+cseg01:C00004DC jmp short loc_C00004AC
+cseg01:C00004DE ; ---------------------------------------------------------------------------
+cseg01:C00004DE
+cseg01:C00004DE loc_C00004DE: ; CODE XREF: sub_C000037B+47j
+cseg01:C00004DE ; sub_C000037B+6Aj ...
+cseg01:C00004DE cmp si, 0FFFFh
+cseg01:C00004E2 jnz short loc_C00004B1
+cseg01:C00004E4 or byte ptr [ebx+2Ch], 1
+cseg01:C00004E8 jmp short loc_C00004B5
+cseg01:C00004E8 sub_C000037B endp
+cseg01:C00004E8
+cseg01:C00004EA
+cseg01:C00004EA ; =============== S U B R O U T I N E =======================================
+cseg01:C00004EA
+cseg01:C00004EA
+cseg01:C00004EA V86_0 proc near ; DATA XREF: cseg01:V86_API_Proc_0o
+cseg01:C00004EA ; cseg01:PM_API_Proc_0o
+cseg01:C00004EA push ebp
+cseg01:C00004EB call sub_C000037B
+cseg01:C00004F0 mov [ebp+1Ch], ax
+cseg01:C00004F4 retn
+cseg01:C00004F4 V86_0 endp
+cseg01:C00004F4
+cseg01:C00004F5
+cseg01:C00004F5 ; =============== S U B R O U T I N E =======================================
+cseg01:C00004F5
+cseg01:C00004F5
+cseg01:C00004F5 sub_C00004F5 proc near ; DATA XREF: sub_C000050A+2Eo
+cseg01:C00004F5 push ebp
+cseg01:C00004F6 call sub_C0002764
+cseg01:C00004FB retn
+cseg01:C00004FB sub_C00004F5 endp
+cseg01:C00004FB
+cseg01:C00004FC
+cseg01:C00004FC ; =============== S U B R O U T I N E =======================================
+cseg01:C00004FC
+cseg01:C00004FC
+cseg01:C00004FC sub_C00004FC proc near ; DATA XREF: sub_C000050A+39o
+cseg01:C00004FC push ebp
+cseg01:C00004FD call sub_C00027A1
+cseg01:C0000502 retn
+cseg01:C0000502 sub_C00004FC endp
+cseg01:C0000502
+cseg01:C0000503
+cseg01:C0000503 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000503
+cseg01:C0000503
+cseg01:C0000503 sub_C0000503 proc near ; DATA XREF: sub_C000050A+48o
+cseg01:C0000503 push ebp
+cseg01:C0000504 call sub_C000276F
+cseg01:C0000509 retn
+cseg01:C0000509 sub_C0000503 endp
+cseg01:C0000509
+cseg01:C000050A
+cseg01:C000050A ; =============== S U B R O U T I N E =======================================
+cseg01:C000050A
+cseg01:C000050A
+cseg01:C000050A sub_C000050A proc near ; CODE XREF: Control_0+2Ep
+cseg01:C000050A
+cseg01:C000050A arg_0 = dword ptr 4
+cseg01:C000050A
+cseg01:C000050A push offset aDevice_init_pr ; "Device_Init_proc\n"
+cseg01:C000050F call sub_C0002A03
+cseg01:C0000514 add esp, 4
+cseg01:C0000517 mov eax, [esp+arg_0]
+cseg01:C000051B mov ds:dword_C00002FE, eax
+cseg01:C0000520 call sub_C00019F5
+cseg01:C0000525 call sub_C0000302
+cseg01:C000052A cmp ds:dword_C00002FA, 31h
+cseg01:C0000531 jb short locret_C000055C
+cseg01:C0000533 mov eax, ds:dword_C00002F6
+cseg01:C0000538 mov dword ptr [eax], offset sub_C00004F5
+cseg01:C000053E mov eax, ds:dword_C00002F6
+cseg01:C0000543 mov dword ptr [eax+90h], offset sub_C00004FC
+cseg01:C000054D mov eax, ds:dword_C00002F6
+cseg01:C0000552 mov dword ptr [eax+0A8h], offset sub_C0000503
+cseg01:C000055C
+cseg01:C000055C locret_C000055C: ; CODE XREF: sub_C000050A+27j
+cseg01:C000055C retn 4
+cseg01:C000055C sub_C000050A endp
+cseg01:C000055C
+cseg01:C000055F
+cseg01:C000055F ; =============== S U B R O U T I N E =======================================
+cseg01:C000055F
+cseg01:C000055F
+cseg01:C000055F sub_C000055F proc near ; CODE XREF: Control_0-6p
+cseg01:C000055F
+cseg01:C000055F arg_0 = dword ptr 4
+cseg01:C000055F
+cseg01:C000055F push ebx
+cseg01:C0000560 push esi
+cseg01:C0000561 push edi
+cseg01:C0000562 push ebp
+cseg01:C0000563 mov ecx, [esp+10h+arg_0]
+cseg01:C0000567 mov eax, [ecx+10h]
+cseg01:C000056A mov ebx, [ecx+18h]
+cseg01:C000056D mov edx, [ecx+0Ch]
+cseg01:C0000570 cmp edx, 2006h
+cseg01:C0000576 jl short loc_C00005EB
+cseg01:C0000578 jle loc_C00006CC
+cseg01:C000057E cmp edx, 200Bh
+cseg01:C0000584 jl short loc_C00005C8
+cseg01:C0000586 jle loc_C0000711
+cseg01:C000058C cmp edx, 200Eh
+cseg01:C0000592 jl short loc_C00005B7
+cseg01:C0000594 jle loc_C000074D
+cseg01:C000059A cmp edx, 2010h
+cseg01:C00005A0 jz loc_C0000770
+cseg01:C00005A6 cmp edx, 200Fh
+cseg01:C00005AC jz loc_C0000766
+cseg01:C00005B2 jmp loc_C000077A
+cseg01:C00005B7 ; ---------------------------------------------------------------------------
+cseg01:C00005B7
+cseg01:C00005B7 loc_C00005B7: ; CODE XREF: sub_C000055F+33j
+cseg01:C00005B7 cmp edx, 200Dh
+cseg01:C00005BD jz loc_C0000739
+cseg01:C00005C3 jmp loc_C000072E
+cseg01:C00005C8 ; ---------------------------------------------------------------------------
+cseg01:C00005C8
+cseg01:C00005C8 loc_C00005C8: ; CODE XREF: sub_C000055F+25j
+cseg01:C00005C8 cmp edx, 2008h
+cseg01:C00005CE jl loc_C00006D6
+cseg01:C00005D4 jle loc_C00006F3
+cseg01:C00005DA cmp edx, 200Ah
+cseg01:C00005E0 jz loc_C0000704
+cseg01:C00005E6 jmp loc_C00006FA
+cseg01:C00005EB ; ---------------------------------------------------------------------------
+cseg01:C00005EB
+cseg01:C00005EB loc_C00005EB: ; CODE XREF: sub_C000055F+17j
+cseg01:C00005EB cmp edx, 110Eh
+cseg01:C00005F1 jl short loc_C0000635
+cseg01:C00005F3 jle loc_C0000689
+cseg01:C00005F9 cmp edx, 1111h
+cseg01:C00005FF jl short loc_C0000624
+cseg01:C0000601 jle loc_C00006B3
+cseg01:C0000607 cmp edx, 2005h
+cseg01:C000060D jz loc_C00006C5
+cseg01:C0000613 cmp edx, 2000h
+cseg01:C0000619 jz loc_C00006BE
+cseg01:C000061F jmp loc_C000077A
+cseg01:C0000624 ; ---------------------------------------------------------------------------
+cseg01:C0000624
+cseg01:C0000624 loc_C0000624: ; CODE XREF: sub_C000055F+A0j
+cseg01:C0000624 cmp edx, 1110h
+cseg01:C000062A jz loc_C00006A4
+cseg01:C0000630 jmp loc_C000069D
+cseg01:C0000635 ; ---------------------------------------------------------------------------
+cseg01:C0000635
+cseg01:C0000635 loc_C0000635: ; CODE XREF: sub_C000055F+92j
+cseg01:C0000635 cmp edx, 110Bh
+cseg01:C000063B jl short loc_C0000649
+cseg01:C000063D jle short loc_C000066B
+cseg01:C000063F cmp edx, 110Dh
+cseg01:C0000645 jz short loc_C000067F
+cseg01:C0000647 jmp short loc_C0000672
+cseg01:C0000649 ; ---------------------------------------------------------------------------
+cseg01:C0000649
+cseg01:C0000649 loc_C0000649: ; CODE XREF: sub_C000055F+DCj
+cseg01:C0000649 cmp edx, 0FFFFFFFFh
+cseg01:C000064C jl loc_C000077A
+cseg01:C0000652 test edx, edx
+cseg01:C0000654 jg loc_C000077A
+cseg01:C000065A push edx
+cseg01:C000065B mov eax, offset aDeviceiocontro ; "DeviceIOControl: System code: %d\n"
+cseg01:C0000660 push eax
+cseg01:C0000661 call sub_C0002A03
+cseg01:C0000666
+cseg01:C0000666 loc_C0000666: ; CODE XREF: sub_C000055F+152j
+cseg01:C0000666 add esp, 8
+cseg01:C0000669 jmp short loc_C0000696
+cseg01:C000066B ; ---------------------------------------------------------------------------
+cseg01:C000066B
+cseg01:C000066B loc_C000066B: ; CODE XREF: sub_C000055F+DEj
+cseg01:C000066B call sub_C0001157
+cseg01:C0000670 jmp short loc_C0000694
+cseg01:C0000672 ; ---------------------------------------------------------------------------
+cseg01:C0000672
+cseg01:C0000672 loc_C0000672: ; CODE XREF: sub_C000055F+E8j
+cseg01:C0000672 mov edi, [eax]
+cseg01:C0000674 push edi
+cseg01:C0000675 call sub_C000115D
+cseg01:C000067A
+cseg01:C000067A loc_C000067A: ; CODE XREF: sub_C000055F+128j
+cseg01:C000067A ; sub_C000055F+175j ...
+cseg01:C000067A add esp, 4
+cseg01:C000067D jmp short loc_C0000696
+cseg01:C000067F ; ---------------------------------------------------------------------------
+cseg01:C000067F
+cseg01:C000067F loc_C000067F: ; CODE XREF: sub_C000055F+E6j
+cseg01:C000067F mov ebp, [eax]
+cseg01:C0000681 push ebp
+cseg01:C0000682 call sub_C0002630
+cseg01:C0000687 jmp short loc_C000067A
+cseg01:C0000689 ; ---------------------------------------------------------------------------
+cseg01:C0000689
+cseg01:C0000689 loc_C0000689: ; CODE XREF: sub_C000055F+94j
+cseg01:C0000689 mov esi, [eax]
+cseg01:C000068B push esi
+cseg01:C000068C call sub_C0002180
+cseg01:C0000691
+cseg01:C0000691 loc_C0000691: ; CODE XREF: sub_C000055F+15Dj
+cseg01:C0000691 ; sub_C000055F+1A3j
+cseg01:C0000691 add esp, 4
+cseg01:C0000694
+cseg01:C0000694 loc_C0000694: ; CODE XREF: sub_C000055F+111j
+cseg01:C0000694 ; sub_C000055F+164j ...
+cseg01:C0000694 mov [ebx], eax
+cseg01:C0000696
+cseg01:C0000696 loc_C0000696: ; CODE XREF: sub_C000055F+10Aj
+cseg01:C0000696 ; sub_C000055F+11Ej ...
+cseg01:C0000696 xor eax, eax
+cseg01:C0000698 jmp loc_C00004B7
+cseg01:C000069D ; ---------------------------------------------------------------------------
+cseg01:C000069D
+cseg01:C000069D loc_C000069D: ; CODE XREF: sub_C000055F+D1j
+cseg01:C000069D call sub_C000116E
+cseg01:C00006A2 jmp short loc_C0000696
+cseg01:C00006A4 ; ---------------------------------------------------------------------------
+cseg01:C00006A4
+cseg01:C00006A4 loc_C00006A4: ; CODE XREF: sub_C000055F+CBj
+cseg01:C00006A4 mov ecx, [eax+4]
+cseg01:C00006A7 push ecx
+cseg01:C00006A8 movzx eax, byte ptr [eax]
+cseg01:C00006AB push eax
+cseg01:C00006AC call sub_C00026B8
+cseg01:C00006B1 jmp short loc_C0000666
+cseg01:C00006B3 ; ---------------------------------------------------------------------------
+cseg01:C00006B3
+cseg01:C00006B3 loc_C00006B3: ; CODE XREF: sub_C000055F+A2j
+cseg01:C00006B3 movzx eax, byte ptr [eax]
+cseg01:C00006B6 push eax
+cseg01:C00006B7 call sub_C000270C
+cseg01:C00006BC jmp short loc_C0000691
+cseg01:C00006BE ; ---------------------------------------------------------------------------
+cseg01:C00006BE
+cseg01:C00006BE loc_C00006BE: ; CODE XREF: sub_C000055F+BAj
+cseg01:C00006BE call sub_C000262A
+cseg01:C00006C3 jmp short loc_C0000694
+cseg01:C00006C5 ; ---------------------------------------------------------------------------
+cseg01:C00006C5
+cseg01:C00006C5 loc_C00006C5: ; CODE XREF: sub_C000055F+AEj
+cseg01:C00006C5 call sub_C0001714
+cseg01:C00006CA jmp short loc_C0000694
+cseg01:C00006CC ; ---------------------------------------------------------------------------
+cseg01:C00006CC
+cseg01:C00006CC loc_C00006CC: ; CODE XREF: sub_C000055F+19j
+cseg01:C00006CC mov edx, [eax]
+cseg01:C00006CE push edx
+cseg01:C00006CF call sub_C000176A
+cseg01:C00006D4 jmp short loc_C000067A
+cseg01:C00006D6 ; ---------------------------------------------------------------------------
+cseg01:C00006D6
+cseg01:C00006D6 loc_C00006D6: ; CODE XREF: sub_C000055F+6Fj
+cseg01:C00006D6 mov ecx, [eax+0Ch]
+cseg01:C00006D9 push ecx
+cseg01:C00006DA mov esi, [eax+8]
+cseg01:C00006DD push esi
+cseg01:C00006DE add ebx, 10h
+cseg01:C00006E1 push ebx
+cseg01:C00006E2 mov edi, [eax+4]
+cseg01:C00006E5 push edi
+cseg01:C00006E6 mov ebp, [eax]
+cseg01:C00006E8 push ebp
+cseg01:C00006E9 call sub_C00017FE
+cseg01:C00006EE add esp, 14h
+cseg01:C00006F1 jmp short loc_C0000696
+cseg01:C00006F3 ; ---------------------------------------------------------------------------
+cseg01:C00006F3
+cseg01:C00006F3 loc_C00006F3: ; CODE XREF: sub_C000055F+75j
+cseg01:C00006F3 call sub_C000179A
+cseg01:C00006F8 jmp short loc_C0000694
+cseg01:C00006FA ; ---------------------------------------------------------------------------
+cseg01:C00006FA
+cseg01:C00006FA loc_C00006FA: ; CODE XREF: sub_C000055F+87j
+cseg01:C00006FA mov ebp, [eax]
+cseg01:C00006FC push ebp
+cseg01:C00006FD call sub_C00017C1
+cseg01:C0000702 jmp short loc_C0000691
+cseg01:C0000704 ; ---------------------------------------------------------------------------
+cseg01:C0000704
+cseg01:C0000704 loc_C0000704: ; CODE XREF: sub_C000055F+81j
+cseg01:C0000704 mov edx, [eax]
+cseg01:C0000706 push edx
+cseg01:C0000707 call sub_C00017D1
+cseg01:C000070C jmp loc_C000067A
+cseg01:C0000711 ; ---------------------------------------------------------------------------
+cseg01:C0000711
+cseg01:C0000711 loc_C0000711: ; CODE XREF: sub_C000055F+27j
+cseg01:C0000711 mov esi, ebx
+cseg01:C0000713 cmp ebx, eax
+cseg01:C0000715 jz short loc_C0000723
+cseg01:C0000717 push 1Ch
+cseg01:C0000719 push eax
+cseg01:C000071A push ebx
+cseg01:C000071B call sub_C0001222
+cseg01:C0000720 add esp, 0Ch
+cseg01:C0000723
+cseg01:C0000723 loc_C0000723: ; CODE XREF: sub_C000055F+1B6j
+cseg01:C0000723 push esi
+cseg01:C0000724 call sub_C0001D48
+cseg01:C0000729 jmp loc_C000067A
+cseg01:C000072E ; ---------------------------------------------------------------------------
+cseg01:C000072E
+cseg01:C000072E loc_C000072E: ; CODE XREF: sub_C000055F+64j
+cseg01:C000072E push eax
+cseg01:C000072F call sub_C0002055
+cseg01:C0000734 jmp loc_C000067A
+cseg01:C0000739 ; ---------------------------------------------------------------------------
+cseg01:C0000739
+cseg01:C0000739 loc_C0000739: ; CODE XREF: sub_C000055F+5Ej
+cseg01:C0000739 mov esi, [eax+4]
+cseg01:C000073C push esi
+cseg01:C000073D mov edi, [eax]
+cseg01:C000073F push edi
+cseg01:C0000740 call sub_C0002520
+cseg01:C0000745 add esp, 8
+cseg01:C0000748 jmp loc_C0000694
+cseg01:C000074D ; ---------------------------------------------------------------------------
+cseg01:C000074D
+cseg01:C000074D loc_C000074D: ; CODE XREF: sub_C000055F+35j
+cseg01:C000074D push ebx
+cseg01:C000074E mov edx, [eax+8]
+cseg01:C0000751 push edx
+cseg01:C0000752 mov ecx, [eax+4]
+cseg01:C0000755 push ecx
+cseg01:C0000756 mov ebx, [eax]
+cseg01:C0000758 push ebx
+cseg01:C0000759 call sub_C0002574
+cseg01:C000075E add esp, 10h
+cseg01:C0000761 jmp loc_C0000696
+cseg01:C0000766 ; ---------------------------------------------------------------------------
+cseg01:C0000766
+cseg01:C0000766 loc_C0000766: ; CODE XREF: sub_C000055F+4Dj
+cseg01:C0000766 call sub_C000170E
+cseg01:C000076B jmp loc_C0000694
+cseg01:C0000770 ; ---------------------------------------------------------------------------
+cseg01:C0000770
+cseg01:C0000770 loc_C0000770: ; CODE XREF: sub_C000055F+41j
+cseg01:C0000770 call sub_C000163E
+cseg01:C0000775 jmp loc_C0000694
+cseg01:C000077A ; ---------------------------------------------------------------------------
+cseg01:C000077A
+cseg01:C000077A loc_C000077A: ; CODE XREF: sub_C000055F+53j
+cseg01:C000077A ; sub_C000055F+C0j ...
+cseg01:C000077A mov edx, [ecx+0Ch]
+cseg01:C000077D push edx
+cseg01:C000077E push offset aDeviceiocont_0 ; "DeviceIOControl: Unknown: %d\n"
+cseg01:C0000783 call sub_C0002A03
+cseg01:C0000788 add esp, 8
+cseg01:C000078B mov eax, 1
+cseg01:C0000790 jmp loc_C00004B7
+cseg01:C0000790 sub_C000055F endp
+cseg01:C0000790
+cseg01:C0000795
+cseg01:C0000795 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000795
+cseg01:C0000795
+cseg01:C0000795 sub_C0000795 proc near ; CODE XREF: Control_0+4Fp
+cseg01:C0000795 push offset aDriverDestroye ; "Driver destroyed\n"
+cseg01:C000079A call sub_C0002A03
+cseg01:C000079F add esp, 4
+cseg01:C00007A2 call sub_C0002620
+cseg01:C00007A7 retn 4
+cseg01:C00007A7 sub_C0000795 endp
+cseg01:C00007A7
+cseg01:C00007A7 ; ---------------------------------------------------------------------------
+cseg01:C00007AA align 4
+cseg01:C00007AC dword_C00007AC dd 0 ; DATA XREF: sub_C0000861+Ao
+cseg01:C00007AC ; sub_C0000861:loc_C0000895o ...
+cseg01:C00007B0 dword_C00007B0 dd 0 ; DATA XREF: sub_C0000861+F8w
+cseg01:C00007B0 ; sub_C0000861+162w ...
+cseg01:C00007B4 dword_C00007B4 dd 0 ; DATA XREF: sub_C0000BA8r
+cseg01:C00007B4 ; sub_C0000BA8+Br ...
+cseg01:C00007B8 dword_C00007B8 dd 0 ; DATA XREF: sub_C00019F5+1E9w
+cseg01:C00007B8 ; sub_C00019F5+20Er
+cseg01:C00007BC dword_C00007BC dd 0 ; DATA XREF: sub_C0000861+25Cw
+cseg01:C00007BC ; sub_C0000861+28Ar ...
+cseg01:C00007C0 dword_C00007C0 dd 0 ; DATA XREF: sub_C00019F5+1DFw
+cseg01:C00007C0 ; sub_C00019F5+1F7r
+cseg01:C00007C4 align 8
+cseg01:C00007C8 dword_C00007C8 dd 0 ; DATA XREF: sub_C0000861+15Dw
+cseg01:C00007C8 ; sub_C0000861+1B3w ...
+cseg01:C00007CC dword_C00007CC dd 0 ; DATA XREF: sub_C0000861+26Bw
+cseg01:C00007D0 dword_C00007D0 dd 0 ; DATA XREF: sub_C00019F5+1BAw
+cseg01:C00007D0 ; sub_C00019F5:loc_C0001BD9r ...
+cseg01:C00007D4 dword_C00007D4 dd 0 ; DATA XREF: sub_C0000861+D0w
+cseg01:C00007D4 ; sub_C0000861+142w ...
+cseg01:C00007D8 dword_C00007D8 dd 0 ; DATA XREF: sub_C0000861+E4w
+cseg01:C00007D8 ; sub_C0000861+156w ...
+cseg01:C00007DC dword_C00007DC dd 0 ; DATA XREF: sub_C0000861+200w
+cseg01:C00007DC ; sub_C0000861:loc_C0000A67r ...
+cseg01:C00007E0 dword_C00007E0 dd 0 ; DATA XREF: sub_C0000861+2B6w
+cseg01:C00007E0 ; sub_C0002496+4r
+cseg01:C00007E4 dword_C00007E4 dd 0 ; DATA XREF: sub_C0000C25+4w
+cseg01:C00007E8 dword_C00007E8 dd 0 ; DATA XREF: sub_C0000C25+Dw
+cseg01:C00007EC dword_C00007EC dd 0 ; DATA XREF: sub_C0000C25+16w
+cseg01:C00007F0 dword_C00007F0 dd 0 ; DATA XREF: sub_C0000C25+68w
+cseg01:C00007F4 align 8
+cseg01:C00007F8 dword_C00007F8 dd 0 ; DATA XREF: sub_C00019F5+24Ar
+cseg01:C00007FC align 10h
+cseg01:C0000800 dword_C0000800 dd 0 ; DATA XREF: sub_C00019F5+243r
+cseg01:C0000804 align 8
+cseg01:C0000808 dword_C0000808 dd 0 ; DATA XREF: sub_C0000861+25w
+cseg01:C0000808 ; sub_C0000861+4Fw ...
+cseg01:C000080C dword_C000080C dd 0 ; DATA XREF: sub_C0000861+2BDw
+cseg01:C000080C ; sub_C0000861+2F4w ...
+cseg01:C0000810 dword_C0000810 dd 0 ; DATA XREF: sub_C0000861+11Aw
+cseg01:C0000814 dword_C0000814 dd 0 ; DATA XREF: sub_C0000861+12Ew
+cseg01:C0000818 dword_C0000818 dd 0 ; DATA XREF: sub_C000156E+20w
+cseg01:C000081C dword_C000081C dd 0 ; DATA XREF: sub_C0000C93+Dr
+cseg01:C000081C ; sub_C0000CD3+10r ...
+cseg01:C0000820 aPciBarsLxLxLx db 'PCI bars: %lx %lx %lx',0Ah,0
+cseg01:C0000820 ; DATA XREF: sub_C0000861+1CDo
+cseg01:C0000837 aSizeOfGsvga1DD db 'Size of gSVGA(1) = %d %d',0Ah,0
+cseg01:C0000837 ; DATA XREF: sub_C0000861+323o
+cseg01:C0000851
+cseg01:C0000851 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000851
+cseg01:C0000851
+cseg01:C0000851 sub_C0000851 proc near ; CODE XREF: sub_C0000C93+37p
+cseg01:C0000851
+cseg01:C0000851 arg_0 = dword ptr 4
+cseg01:C0000851
+cseg01:C0000851 mov edx, [esp+arg_0]
+cseg01:C0000855 in eax, dx
+cseg01:C0000856 retn
+cseg01:C0000856 sub_C0000851 endp
+cseg01:C0000856
+cseg01:C0000857
+cseg01:C0000857 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000857
+cseg01:C0000857
+cseg01:C0000857 sub_C0000857 proc near ; CODE XREF: sub_C0000C93+24p
+cseg01:C0000857 ; sub_C0000CD3+2Bp ...
+cseg01:C0000857
+cseg01:C0000857 arg_0 = dword ptr 4
+cseg01:C0000857 arg_4 = dword ptr 8
+cseg01:C0000857
+cseg01:C0000857 mov eax, [esp+arg_4]
+cseg01:C000085B mov edx, [esp+arg_0]
+cseg01:C000085F out dx, eax
+cseg01:C0000860 retn
+cseg01:C0000860 sub_C0000857 endp
+cseg01:C0000860
+cseg01:C0000861
+cseg01:C0000861 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000861
+cseg01:C0000861
+cseg01:C0000861 sub_C0000861 proc near ; CODE XREF: sub_C00019F5+A0p
+cseg01:C0000861
+cseg01:C0000861 arg_0 = dword ptr 4
+cseg01:C0000861 arg_4 = dword ptr 8
+cseg01:C0000861
+cseg01:C0000861 push ebx
+cseg01:C0000862 push esi
+cseg01:C0000863 push edi
+cseg01:C0000864 push ebp
+cseg01:C0000865 mov esi, [esp+10h+arg_4]
+cseg01:C0000869 xor ebx, ebx
+cseg01:C000086B push offset dword_C00007AC
+cseg01:C0000870 push 406h
+cseg01:C0000875 push 15ADh
+cseg01:C000087A call sub_C0000F51
+cseg01:C000087F add esp, 0Ch
+cseg01:C0000882 test eax, eax
+cseg01:C0000884 jz short loc_C0000895
+cseg01:C0000886 mov ds:dword_C0000808, 40615ADh
+cseg01:C0000890 mov ebx, 1
+cseg01:C0000895
+cseg01:C0000895 loc_C0000895: ; CODE XREF: sub_C0000861+23j
+cseg01:C0000895 push offset dword_C00007AC
+cseg01:C000089A push 405h
+cseg01:C000089F push 15ADh
+cseg01:C00008A4 call sub_C0000F51
+cseg01:C00008A9 add esp, 0Ch
+cseg01:C00008AC test eax, eax
+cseg01:C00008AE jz short loc_C00008BF
+cseg01:C00008B0 mov ds:dword_C0000808, 40515ADh
+cseg01:C00008BA mov ebx, 1
+cseg01:C00008BF
+cseg01:C00008BF loc_C00008BF: ; CODE XREF: sub_C0000861+4Dj
+cseg01:C00008BF push offset dword_C00007AC
+cseg01:C00008C4 push 0BEEFh
+cseg01:C00008C9 push 80EEh
+cseg01:C00008CE call sub_C0000F51
+cseg01:C00008D3 add esp, 0Ch
+cseg01:C00008D6 test eax, eax
+cseg01:C00008D8 jz short loc_C00008FA
+cseg01:C00008DA push offset dword_C00007AC
+cseg01:C00008DF call sub_C0001074
+cseg01:C00008E4 add esp, 4
+cseg01:C00008E7 cmp eax, 40515ADh
+cseg01:C00008EC jnz short loc_C00008FA
+cseg01:C00008EE mov ds:dword_C0000808, 0BEEF80EEh
+cseg01:C00008F8 jmp short loc_C0000908
+cseg01:C00008FA ; ---------------------------------------------------------------------------
+cseg01:C00008FA
+cseg01:C00008FA loc_C00008FA: ; CODE XREF: sub_C0000861+77j
+cseg01:C00008FA ; sub_C0000861+8Bj
+cseg01:C00008FA test ebx, ebx
+cseg01:C00008FC jnz short loc_C0000908
+cseg01:C00008FE mov eax, 1
+cseg01:C0000903 pop ebp
+cseg01:C0000904 pop edi
+cseg01:C0000905 pop esi
+cseg01:C0000906 pop ebx
+cseg01:C0000907 retn
+cseg01:C0000908 ; ---------------------------------------------------------------------------
+cseg01:C0000908
+cseg01:C0000908 loc_C0000908: ; CODE XREF: sub_C0000861+97j
+cseg01:C0000908 ; sub_C0000861+9Bj
+cseg01:C0000908 push 1
+cseg01:C000090A push offset dword_C00007AC
+cseg01:C000090F call sub_C0001084
+cseg01:C0000914 add esp, 8
+cseg01:C0000917 cmp word ptr ds:dword_C0000808+2, 0BEEFh
+cseg01:C0000920 jnz short loc_C0000963
+cseg01:C0000922 push 0
+cseg01:C0000924 push offset dword_C00007AC
+cseg01:C0000929 call sub_C0000FBE
+cseg01:C000092E add esp, 8
+cseg01:C0000931 mov ds:dword_C00007D4, eax
+cseg01:C0000936 push 0
+cseg01:C0000938 push offset dword_C00007AC
+cseg01:C000093D call sub_C0000FF5
+cseg01:C0000942 add esp, 8
+cseg01:C0000945 mov ds:dword_C00007D8, eax
+cseg01:C000094A push 1
+cseg01:C000094C push offset dword_C00007AC
+cseg01:C0000951 call sub_C0000FBE
+cseg01:C0000956 add esp, 8
+cseg01:C0000959 mov ds:dword_C00007B0, eax
+cseg01:C000095E jmp loc_C0000A05
+cseg01:C0000963 ; ---------------------------------------------------------------------------
+cseg01:C0000963
+cseg01:C0000963 loc_C0000963: ; CODE XREF: sub_C0000861+BFj
+cseg01:C0000963 call sub_C0000B98
+cseg01:C0000968 test eax, eax
+cseg01:C000096A jz short loc_C00009CA
+cseg01:C000096C push 0
+cseg01:C000096E push offset dword_C00007AC
+cseg01:C0000973 call sub_C0000FBE
+cseg01:C0000978 add esp, 8
+cseg01:C000097B mov ds:dword_C0000810, eax
+cseg01:C0000980 push 0
+cseg01:C0000982 push offset dword_C00007AC
+cseg01:C0000987 call sub_C0000FF5
+cseg01:C000098C add esp, 8
+cseg01:C000098F mov ds:dword_C0000814, eax
+cseg01:C0000994 push 2
+cseg01:C0000996 push offset dword_C00007AC
+cseg01:C000099B call sub_C0000FBE
+cseg01:C00009A0 add esp, 8
+cseg01:C00009A3 mov ds:dword_C00007D4, eax
+cseg01:C00009A8 push 2
+cseg01:C00009AA push offset dword_C00007AC
+cseg01:C00009AF call sub_C0000FF5
+cseg01:C00009B4 add esp, 8
+cseg01:C00009B7 mov ds:dword_C00007D8, eax
+cseg01:C00009BC xor eax, eax
+cseg01:C00009BE mov ds:dword_C00007C8, eax
+cseg01:C00009C3 mov ds:dword_C00007B0, eax
+cseg01:C00009C8 jmp short loc_C0000A19
+cseg01:C00009CA ; ---------------------------------------------------------------------------
+cseg01:C00009CA
+cseg01:C00009CA loc_C00009CA: ; CODE XREF: sub_C0000861+109j
+cseg01:C00009CA push eax
+cseg01:C00009CB push offset dword_C00007AC
+cseg01:C00009D0 call sub_C0000FBE
+cseg01:C00009D5 add esp, 8
+cseg01:C00009D8 mov ds:dword_C00007B0, eax
+cseg01:C00009DD push 1
+cseg01:C00009DF push offset dword_C00007AC
+cseg01:C00009E4 call sub_C0000FBE
+cseg01:C00009E9 add esp, 8
+cseg01:C00009EC mov ds:dword_C00007D4, eax
+cseg01:C00009F1 push 1
+cseg01:C00009F3 push offset dword_C00007AC
+cseg01:C00009F8 call sub_C0000FF5
+cseg01:C00009FD add esp, 8
+cseg01:C0000A00 mov ds:dword_C00007D8, eax
+cseg01:C0000A05
+cseg01:C0000A05 loc_C0000A05: ; CODE XREF: sub_C0000861+FDj
+cseg01:C0000A05 push 2
+cseg01:C0000A07 push offset dword_C00007AC
+cseg01:C0000A0C call sub_C0000FBE
+cseg01:C0000A11 add esp, 8
+cseg01:C0000A14 mov ds:dword_C00007C8, eax
+cseg01:C0000A19
+cseg01:C0000A19 loc_C0000A19: ; CODE XREF: sub_C0000861+167j
+cseg01:C0000A19 mov ecx, ds:dword_C00007C8
+cseg01:C0000A1F push ecx
+cseg01:C0000A20 mov ebx, ds:dword_C00007D4
+cseg01:C0000A26 push ebx
+cseg01:C0000A27 mov edi, ds:dword_C00007B0
+cseg01:C0000A2D push edi
+cseg01:C0000A2E push offset aPciBarsLxLxLx ; "PCI bars: %lx %lx %lx\n"
+cseg01:C0000A33 call sub_C0002A03
+cseg01:C0000A38 add esp, 10h
+cseg01:C0000A3B call sub_C000156E
+cseg01:C0000A40 test esi, esi
+cseg01:C0000A42 jnz short loc_C0000A5B
+cseg01:C0000A44 cmp word ptr ds:dword_C0000808+2, 406h
+cseg01:C0000A4D jnz short loc_C0000A56
+cseg01:C0000A4F mov esi, 3
+cseg01:C0000A54 jmp short loc_C0000A5B
+cseg01:C0000A56 ; ---------------------------------------------------------------------------
+cseg01:C0000A56
+cseg01:C0000A56 loc_C0000A56: ; CODE XREF: sub_C0000861+1ECj
+cseg01:C0000A56 mov esi, 2
+cseg01:C0000A5B
+cseg01:C0000A5B loc_C0000A5B: ; CODE XREF: sub_C0000861+1E1j
+cseg01:C0000A5B ; sub_C0000861+1F3j
+cseg01:C0000A5B or esi, 90000000h
+cseg01:C0000A61 mov ds:dword_C00007DC, esi
+cseg01:C0000A67
+cseg01:C0000A67 loc_C0000A67: ; CODE XREF: sub_C0000861+23Aj
+cseg01:C0000A67 mov ebp, ds:dword_C00007DC
+cseg01:C0000A6D push ebp
+cseg01:C0000A6E push 0
+cseg01:C0000A70 call sub_C0000CD3
+cseg01:C0000A75 add esp, 8
+cseg01:C0000A78 push 0
+cseg01:C0000A7A call sub_C0000C93
+cseg01:C0000A7F add esp, 4
+cseg01:C0000A82 mov edx, ds:dword_C00007DC
+cseg01:C0000A88 cmp eax, edx
+cseg01:C0000A8A jz short loc_C0000A9D
+cseg01:C0000A8C lea ecx, [edx-1]
+cseg01:C0000A8F mov ds:dword_C00007DC, ecx
+cseg01:C0000A95 cmp ecx, 90000000h
+cseg01:C0000A9B jnb short loc_C0000A67
+cseg01:C0000A9D
+cseg01:C0000A9D loc_C0000A9D: ; CODE XREF: sub_C0000861+229j
+cseg01:C0000A9D cmp ds:dword_C00007DC, 90000000h
+cseg01:C0000AA7 jnb short loc_C0000AB3
+cseg01:C0000AA9 mov eax, 2
+cseg01:C0000AAE pop ebp
+cseg01:C0000AAF pop edi
+cseg01:C0000AB0 pop esi
+cseg01:C0000AB1 pop ebx
+cseg01:C0000AB2 retn
+cseg01:C0000AB3 ; ---------------------------------------------------------------------------
+cseg01:C0000AB3
+cseg01:C0000AB3 loc_C0000AB3: ; CODE XREF: sub_C0000861+246j
+cseg01:C0000AB3 push 13h
+cseg01:C0000AB5 call sub_C0000C93
+cseg01:C0000ABA add esp, 4
+cseg01:C0000ABD mov ds:dword_C00007BC, eax
+cseg01:C0000AC2 push 10h
+cseg01:C0000AC4 call sub_C0000C93
+cseg01:C0000AC9 add esp, 4
+cseg01:C0000ACC mov ds:dword_C00007CC, eax
+cseg01:C0000AD1 cmp eax, 100000h
+cseg01:C0000AD6 jnb short loc_C0000AE2
+cseg01:C0000AD8 mov eax, 4
+cseg01:C0000ADD pop ebp
+cseg01:C0000ADE pop edi
+cseg01:C0000ADF pop esi
+cseg01:C0000AE0 pop ebx
+cseg01:C0000AE1 retn
+cseg01:C0000AE2 ; ---------------------------------------------------------------------------
+cseg01:C0000AE2
+cseg01:C0000AE2 loc_C0000AE2: ; CODE XREF: sub_C0000861+275j
+cseg01:C0000AE2 call sub_C0000B98
+cseg01:C0000AE7 test eax, eax
+cseg01:C0000AE9 jz short loc_C0000B01
+cseg01:C0000AEB cmp ds:dword_C00007BC, 20000h
+cseg01:C0000AF5 jnb short loc_C0000B01
+cseg01:C0000AF7 mov eax, 5
+cseg01:C0000AFC pop ebp
+cseg01:C0000AFD pop edi
+cseg01:C0000AFE pop esi
+cseg01:C0000AFF pop ebx
+cseg01:C0000B00 retn
+cseg01:C0000B01 ; ---------------------------------------------------------------------------
+cseg01:C0000B01
+cseg01:C0000B01 loc_C0000B01: ; CODE XREF: sub_C0000861+288j
+cseg01:C0000B01 ; sub_C0000861+294j
+cseg01:C0000B01 cmp ds:dword_C00007DC, 90000001h
+cseg01:C0000B0B jb short loc_C0000B1C
+cseg01:C0000B0D push 11h
+cseg01:C0000B0F call sub_C0000C93
+cseg01:C0000B14 add esp, 4
+cseg01:C0000B17 mov ds:dword_C00007E0, eax
+cseg01:C0000B1C
+cseg01:C0000B1C loc_C0000B1C: ; CODE XREF: sub_C0000861+2AAj
+cseg01:C0000B1C xor eax, eax
+cseg01:C0000B1E mov ds:dword_C000080C, eax
+cseg01:C0000B23 push 1
+cseg01:C0000B25 push 1
+cseg01:C0000B27 call sub_C0000CD3
+cseg01:C0000B2C add esp, 8
+cseg01:C0000B2F push 1
+cseg01:C0000B31 push 14h
+cseg01:C0000B33 call sub_C0000CD3
+cseg01:C0000B38 add esp, 8
+cseg01:C0000B3B push 8
+cseg01:C0000B3D push 7
+cseg01:C0000B3F call sub_C0000CD3
+cseg01:C0000B44 add esp, 8
+cseg01:C0000B47 push 14h
+cseg01:C0000B49 call sub_C0000C93
+cseg01:C0000B4E add esp, 4
+cseg01:C0000B51 test eax, eax
+cseg01:C0000B53 jnz short loc_C0000B5C
+cseg01:C0000B55 or byte ptr ds:dword_C000080C, 1
+cseg01:C0000B5C
+cseg01:C0000B5C loc_C0000B5C: ; CODE XREF: sub_C0000861+2F2j
+cseg01:C0000B5C push 0
+cseg01:C0000B5E push 1
+cseg01:C0000B60 call sub_C0000CD3
+cseg01:C0000B65 add esp, 8
+cseg01:C0000B68 push 0
+cseg01:C0000B6A push 14h
+cseg01:C0000B6C call sub_C0000CD3
+cseg01:C0000B71 add esp, 8
+cseg01:C0000B74 cmp [esp+10h+arg_0], 0
+cseg01:C0000B79 jz short loc_C0000B80
+cseg01:C0000B7B call sub_C0000BA8
+cseg01:C0000B80
+cseg01:C0000B80 loc_C0000B80: ; CODE XREF: sub_C0000861+318j
+cseg01:C0000B80 push 4
+cseg01:C0000B82 push 74h
+cseg01:C0000B84 push offset aSizeOfGsvga1DD ; "Size of gSVGA(1) = %d %d\n"
+cseg01:C0000B89 call sub_C0002A03
+cseg01:C0000B8E add esp, 0Ch
+cseg01:C0000B91 xor eax, eax
+cseg01:C0000B93 pop ebp
+cseg01:C0000B94 pop edi
+cseg01:C0000B95 pop esi
+cseg01:C0000B96 pop ebx
+cseg01:C0000B97 retn
+cseg01:C0000B97 sub_C0000861 endp
+cseg01:C0000B97
+cseg01:C0000B98
+cseg01:C0000B98 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000B98
+cseg01:C0000B98
+cseg01:C0000B98 sub_C0000B98 proc near ; CODE XREF: sub_C0000861:loc_C0000963p
+cseg01:C0000B98 ; sub_C0000861:loc_C0000AE2p ...
+cseg01:C0000B98 cmp word ptr ds:dword_C0000808+2, 406h
+cseg01:C0000BA1 setz al
+cseg01:C0000BA4 movzx eax, al
+cseg01:C0000BA7 retn
+cseg01:C0000BA7 sub_C0000B98 endp
+cseg01:C0000BA7
+cseg01:C0000BA8
+cseg01:C0000BA8 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000BA8
+cseg01:C0000BA8
+cseg01:C0000BA8 sub_C0000BA8 proc near ; CODE XREF: sub_C0000861+31Ap
+cseg01:C0000BA8 ; sub_C00019F5+26Fp
+cseg01:C0000BA8 mov eax, ds:dword_C00007B4
+cseg01:C0000BAD mov dword ptr [eax], 48Ch
+cseg01:C0000BB3 mov eax, ds:dword_C00007B4
+cseg01:C0000BB8 mov edx, ds:dword_C00007BC
+cseg01:C0000BBE mov [eax+4], edx
+cseg01:C0000BC1 mov eax, ds:dword_C00007B4
+cseg01:C0000BC6 mov edx, [eax]
+cseg01:C0000BC8 mov [eax+8], edx
+cseg01:C0000BCB mov eax, ds:dword_C00007B4
+cseg01:C0000BD0 mov edx, [eax]
+cseg01:C0000BD2 mov [eax+0Ch], edx
+cseg01:C0000BD5 push 8000h
+cseg01:C0000BDA call sub_C0000D34
+cseg01:C0000BDF add esp, 4
+cseg01:C0000BE2 test eax, eax
+cseg01:C0000BE4 jz short loc_C0000C06
+cseg01:C0000BE6 push 120h
+cseg01:C0000BEB call sub_C0000D1F
+cseg01:C0000BF0 add esp, 4
+cseg01:C0000BF3 test eax, eax
+cseg01:C0000BF5 jz short loc_C0000C06
+cseg01:C0000BF7 mov eax, ds:dword_C00007B4
+cseg01:C0000BFC mov dword ptr [eax+480h], 20001h
+cseg01:C0000C06
+cseg01:C0000C06 loc_C0000C06: ; CODE XREF: sub_C0000BA8+3Cj
+cseg01:C0000C06 ; sub_C0000BA8+4Dj
+cseg01:C0000C06 push 1
+cseg01:C0000C08 push 1
+cseg01:C0000C0A call sub_C0000CD3
+cseg01:C0000C0F add esp, 8
+cseg01:C0000C12 push 1
+cseg01:C0000C14 push 14h
+cseg01:C0000C16
+cseg01:C0000C16 loc_C0000C16: ; CODE XREF: sub_C0002620-19FDj
+cseg01:C0000C16 call sub_C0000CD3
+cseg01:C0000C1B add esp, 8
+cseg01:C0000C1E retn
+cseg01:C0000C1E sub_C0000BA8 endp
+cseg01:C0000C1E
+cseg01:C0000C1F ; ---------------------------------------------------------------------------
+cseg01:C0000C1F ; START OF FUNCTION CHUNK FOR sub_C0002620
+cseg01:C0000C1F
+cseg01:C0000C1F loc_C0000C1F: ; CODE XREF: sub_C0002620+5j
+cseg01:C0000C1F push 0
+cseg01:C0000C21 push 1
+cseg01:C0000C23 jmp short loc_C0000C16
+cseg01:C0000C23 ; END OF FUNCTION CHUNK FOR sub_C0002620
+cseg01:C0000C25
+cseg01:C0000C25 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000C25
+cseg01:C0000C25
+cseg01:C0000C25 sub_C0000C25 proc near ; CODE XREF: sub_C0002353+37p
+cseg01:C0000C25
+cseg01:C0000C25 arg_0 = dword ptr 4
+cseg01:C0000C25 arg_4 = dword ptr 8
+cseg01:C0000C25 arg_8 = dword ptr 0Ch
+cseg01:C0000C25
+cseg01:C0000C25 mov eax, [esp+arg_0]
+cseg01:C0000C29 mov ds:dword_C00007E4, eax
+cseg01:C0000C2E mov eax, [esp+arg_4]
+cseg01:C0000C32 mov ds:dword_C00007E8, eax
+cseg01:C0000C37 mov eax, [esp+arg_8]
+cseg01:C0000C3B mov ds:dword_C00007EC, eax
+cseg01:C0000C40 mov eax, [esp+arg_0]
+cseg01:C0000C44 push eax
+cseg01:C0000C45 push 2
+cseg01:C0000C47 call sub_C0000CD3
+cseg01:C0000C4C add esp, 8
+cseg01:C0000C4F mov edx, [esp+arg_4]
+cseg01:C0000C53 push edx
+cseg01:C0000C54 push 3
+cseg01:C0000C56 call sub_C0000CD3
+cseg01:C0000C5B add esp, 8
+cseg01:C0000C5E mov ecx, [esp+arg_8]
+cseg01:C0000C62 push ecx
+cseg01:C0000C63 push 7
+cseg01:C0000C65 call sub_C0000CD3
+cseg01:C0000C6A add esp, 8
+cseg01:C0000C6D push 0Eh
+cseg01:C0000C6F call sub_C0000C93
+cseg01:C0000C74 add esp, 4
+cseg01:C0000C77 push 1
+cseg01:C0000C79 push 1
+cseg01:C0000C7B call sub_C0000CD3
+cseg01:C0000C80 add esp, 8
+cseg01:C0000C83 push 0Ch
+cseg01:C0000C85 call sub_C0000C93
+cseg01:C0000C8A add esp, 4
+cseg01:C0000C8D mov ds:dword_C00007F0, eax
+cseg01:C0000C92 retn
+cseg01:C0000C92 sub_C0000C25 endp
+cseg01:C0000C92
+cseg01:C0000C93
+cseg01:C0000C93 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000C93
+cseg01:C0000C93
+cseg01:C0000C93 sub_C0000C93 proc near ; CODE XREF: sub_C0000861+219p
+cseg01:C0000C93 ; sub_C0000861+254p ...
+cseg01:C0000C93
+cseg01:C0000C93 arg_0 = dword ptr 4
+cseg01:C0000C93
+cseg01:C0000C93 call sub_C0000B98
+cseg01:C0000C98 test eax, eax
+cseg01:C0000C9A jz short loc_C0000CAA
+cseg01:C0000C9C mov eax, [esp+arg_0]
+cseg01:C0000CA0 mov edx, ds:dword_C000081C
+cseg01:C0000CA6 mov eax, [edx+eax*4]
+cseg01:C0000CA9 retn
+cseg01:C0000CAA ; ---------------------------------------------------------------------------
+cseg01:C0000CAA
+cseg01:C0000CAA loc_C0000CAA: ; CODE XREF: sub_C0000C93+7j
+cseg01:C0000CAA mov eax, [esp+arg_0]
+cseg01:C0000CAE push eax
+cseg01:C0000CAF movzx eax, word ptr ds:dword_C00007B0
+cseg01:C0000CB6 push eax
+cseg01:C0000CB7 call sub_C0000857
+cseg01:C0000CBC add esp, 8
+cseg01:C0000CBF mov ax, word ptr ds:dword_C00007B0
+cseg01:C0000CC5 inc eax
+cseg01:C0000CC6 movzx eax, ax
+cseg01:C0000CC9 push eax
+cseg01:C0000CCA call sub_C0000851
+cseg01:C0000CCF add esp, 4
+cseg01:C0000CD2 retn
+cseg01:C0000CD2 sub_C0000C93 endp
+cseg01:C0000CD2
+cseg01:C0000CD3
+cseg01:C0000CD3 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000CD3
+cseg01:C0000CD3
+cseg01:C0000CD3 sub_C0000CD3 proc near ; CODE XREF: sub_C0000861+20Fp
+cseg01:C0000CD3 ; sub_C0000861+2C6p ...
+cseg01:C0000CD3
+cseg01:C0000CD3 arg_0 = dword ptr 4
+cseg01:C0000CD3 arg_4 = dword ptr 8
+cseg01:C0000CD3
+cseg01:C0000CD3 call sub_C0000B98
+cseg01:C0000CD8 test eax, eax
+cseg01:C0000CDA jz short loc_C0000CF1
+cseg01:C0000CDC mov edx, [esp+arg_0]
+cseg01:C0000CE0 shl edx, 2
+cseg01:C0000CE3 mov eax, ds:dword_C000081C
+cseg01:C0000CE8 add eax, edx
+cseg01:C0000CEA mov edx, [esp+arg_4]
+cseg01:C0000CEE mov [eax], edx
+cseg01:C0000CF0 retn
+cseg01:C0000CF1 ; ---------------------------------------------------------------------------
+cseg01:C0000CF1
+cseg01:C0000CF1 loc_C0000CF1: ; CODE XREF: sub_C0000CD3+7j
+cseg01:C0000CF1 mov eax, [esp+arg_0]
+cseg01:C0000CF5 push eax
+cseg01:C0000CF6 movzx eax, word ptr ds:dword_C00007B0
+cseg01:C0000CFD push eax
+cseg01:C0000CFE call sub_C0000857
+cseg01:C0000D03 add esp, 8
+cseg01:C0000D06 mov edx, [esp+arg_4]
+cseg01:C0000D0A push edx
+cseg01:C0000D0B mov ax, word ptr ds:dword_C00007B0
+cseg01:C0000D11 inc eax
+cseg01:C0000D12 movzx eax, ax
+cseg01:C0000D15 push eax
+cseg01:C0000D16 call sub_C0000857
+cseg01:C0000D1B add esp, 8
+cseg01:C0000D1E retn
+cseg01:C0000D1E sub_C0000CD3 endp
+cseg01:C0000D1E
+cseg01:C0000D1F
+cseg01:C0000D1F ; =============== S U B R O U T I N E =======================================
+cseg01:C0000D1F
+cseg01:C0000D1F
+cseg01:C0000D1F sub_C0000D1F proc near ; CODE XREF: sub_C0000BA8+43p
+cseg01:C0000D1F ; cseg01:C0000D4Cp
+cseg01:C0000D1F
+cseg01:C0000D1F arg_0 = dword ptr 4
+cseg01:C0000D1F
+cseg01:C0000D1F mov eax, ds:dword_C00007B4
+cseg01:C0000D24 mov edx, [esp+arg_0]
+cseg01:C0000D28 shl edx, 2
+cseg01:C0000D2B cmp edx, [eax]
+cseg01:C0000D2D setb al
+cseg01:C0000D30 movzx eax, al
+cseg01:C0000D33 retn
+cseg01:C0000D33 sub_C0000D1F endp
+cseg01:C0000D33
+cseg01:C0000D34
+cseg01:C0000D34 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000D34
+cseg01:C0000D34
+cseg01:C0000D34 sub_C0000D34 proc near ; CODE XREF: sub_C0000BA8+32p
+cseg01:C0000D34 ; sub_C000213B+5p ...
+cseg01:C0000D34
+cseg01:C0000D34 arg_0 = dword ptr 4
+cseg01:C0000D34
+cseg01:C0000D34 mov eax, ds:dword_C00007B4
+cseg01:C0000D39 mov eax, [eax+10h]
+cseg01:C0000D3C test [esp+arg_0], eax
+cseg01:C0000D40 setnz al
+cseg01:C0000D43 movzx eax, al
+cseg01:C0000D46 retn
+cseg01:C0000D46 sub_C0000D34 endp
+cseg01:C0000D46
+cseg01:C0000D47 ; ---------------------------------------------------------------------------
+cseg01:C0000D47 push 122h
+cseg01:C0000D4C call sub_C0000D1F
+cseg01:C0000D51 add esp, 4
+cseg01:C0000D54 test eax, eax
+cseg01:C0000D56 jz short locret_C0000D7C
+cseg01:C0000D58 mov eax, ds:dword_C00007B4
+cseg01:C0000D5D cmp dword ptr [eax+488h], 0
+cseg01:C0000D64 jnz short locret_C0000D7C
+cseg01:C0000D66 mov dword ptr [eax+488h], 1
+cseg01:C0000D70 push 1
+cseg01:C0000D72 push 15h
+cseg01:C0000D74 call sub_C0000CD3
+cseg01:C0000D79 add esp, 8
+cseg01:C0000D7C
+cseg01:C0000D7C locret_C0000D7C: ; CODE XREF: cseg01:C0000D56j
+cseg01:C0000D7C ; cseg01:C0000D64j
+cseg01:C0000D7C retn
+cseg01:C0000D7D
+cseg01:C0000D7D ; =============== S U B R O U T I N E =======================================
+cseg01:C0000D7D
+cseg01:C0000D7D
+cseg01:C0000D7D sub_C0000D7D proc near ; CODE XREF: sub_C000179A+9p
+cseg01:C0000D7D ; sub_C0001D48:loc_C0002020p ...
+cseg01:C0000D7D push 1
+cseg01:C0000D7F push 15h
+cseg01:C0000D81 call sub_C0000CD3
+cseg01:C0000D86 add esp, 8
+cseg01:C0000D89
+cseg01:C0000D89 loc_C0000D89: ; CODE XREF: sub_C0000D7D+18j
+cseg01:C0000D89 push 16h
+cseg01:C0000D8B call sub_C0000C93
+cseg01:C0000D90 add esp, 4
+cseg01:C0000D93 test eax, eax
+cseg01:C0000D95 jnz short loc_C0000D89
+cseg01:C0000D97 retn
+cseg01:C0000D97 sub_C0000D7D endp
+cseg01:C0000D97
+cseg01:C0000D98
+cseg01:C0000D98 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000D98
+cseg01:C0000D98
+cseg01:C0000D98 sub_C0000D98 proc near ; CODE XREF: sub_C0000DC1+Bp
+cseg01:C0000D98 ; sub_C0000DF0+Bp ...
+cseg01:C0000D98
+cseg01:C0000D98 arg_0 = dword ptr 4
+cseg01:C0000D98 arg_4 = word ptr 8
+cseg01:C0000D98
+cseg01:C0000D98 mov eax, [esp+arg_0]
+cseg01:C0000D9C movzx edx, byte ptr [eax+1]
+cseg01:C0000DA0 shl edx, 0Bh
+cseg01:C0000DA3 movzx ecx, byte ptr [eax]
+cseg01:C0000DA6 shl ecx, 10h
+cseg01:C0000DA9 or edx, ecx
+cseg01:C0000DAB movzx eax, byte ptr [eax+2]
+cseg01:C0000DAF shl eax, 8
+cseg01:C0000DB2 or edx, eax
+cseg01:C0000DB4 movzx eax, [esp+arg_4]
+cseg01:C0000DB9 or eax, edx
+cseg01:C0000DBB or eax, 80000000h
+cseg01:C0000DC0 retn
+cseg01:C0000DC0 sub_C0000D98 endp
+cseg01:C0000DC0
+cseg01:C0000DC1
+cseg01:C0000DC1 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000DC1
+cseg01:C0000DC1
+cseg01:C0000DC1 sub_C0000DC1 proc near ; CODE XREF: sub_C0000EE0+Ep
+cseg01:C0000DC1 ; sub_C0000FBE+15p ...
+cseg01:C0000DC1
+cseg01:C0000DC1 arg_0 = dword ptr 4
+cseg01:C0000DC1 arg_4 = word ptr 8
+cseg01:C0000DC1
+cseg01:C0000DC1 movzx eax, [esp+arg_4]
+cseg01:C0000DC6 push eax
+cseg01:C0000DC7 mov eax, [esp+4+arg_0]
+cseg01:C0000DCB push eax
+cseg01:C0000DCC call sub_C0000D98
+cseg01:C0000DD1 add esp, 8
+cseg01:C0000DD4 push eax
+cseg01:C0000DD5 push 0CF8h
+cseg01:C0000DDA call sub_C0000022
+cseg01:C0000DDF add esp, 8
+cseg01:C0000DE2 push 0CFCh
+cseg01:C0000DE7 call sub_C000001C
+cseg01:C0000DEC add esp, 4
+cseg01:C0000DEF retn
+cseg01:C0000DEF sub_C0000DC1 endp
+cseg01:C0000DEF
+cseg01:C0000DF0
+cseg01:C0000DF0 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000DF0
+cseg01:C0000DF0
+cseg01:C0000DF0 sub_C0000DF0 proc near ; CODE XREF: sub_C0001084+7p
+cseg01:C0000DF0
+cseg01:C0000DF0 arg_0 = dword ptr 4
+cseg01:C0000DF0 arg_4 = word ptr 8
+cseg01:C0000DF0
+cseg01:C0000DF0 movzx eax, [esp+arg_4]
+cseg01:C0000DF5 push eax
+cseg01:C0000DF6 mov eax, [esp+4+arg_0]
+cseg01:C0000DFA push eax
+cseg01:C0000DFB call sub_C0000D98
+cseg01:C0000E00 add esp, 8
+cseg01:C0000E03 push eax
+cseg01:C0000E04 push 0CF8h
+cseg01:C0000E09 call sub_C0000022
+cseg01:C0000E0E add esp, 8
+cseg01:C0000E11 push 0CFCh
+cseg01:C0000E16 call sub_C000002C
+cseg01:C0000E1B add esp, 4
+cseg01:C0000E1E retn
+cseg01:C0000E1E sub_C0000DF0 endp
+cseg01:C0000E1E
+cseg01:C0000E1F ; ---------------------------------------------------------------------------
+cseg01:C0000E1F movzx eax, word ptr [esp+8]
+cseg01:C0000E24 push eax
+cseg01:C0000E25 mov eax, [esp+8]
+cseg01:C0000E29 push eax
+cseg01:C0000E2A call sub_C0000D98
+cseg01:C0000E2F add esp, 8
+cseg01:C0000E32 push eax
+cseg01:C0000E33 push 0CF8h
+cseg01:C0000E38 call sub_C0000022
+cseg01:C0000E3D add esp, 8
+cseg01:C0000E40 push 0CFCh
+cseg01:C0000E45 call sub_C000003E
+cseg01:C0000E4A add esp, 4
+cseg01:C0000E4D retn
+cseg01:C0000E4E
+cseg01:C0000E4E ; =============== S U B R O U T I N E =======================================
+cseg01:C0000E4E
+cseg01:C0000E4E
+cseg01:C0000E4E sub_C0000E4E proc near ; CODE XREF: cseg01:C0000FB5p
+cseg01:C0000E4E ; sub_C0000FF5+4Ap ...
+cseg01:C0000E4E
+cseg01:C0000E4E arg_0 = dword ptr 4
+cseg01:C0000E4E arg_4 = word ptr 8
+cseg01:C0000E4E arg_8 = dword ptr 0Ch
+cseg01:C0000E4E
+cseg01:C0000E4E movzx eax, [esp+arg_4]
+cseg01:C0000E53 push eax
+cseg01:C0000E54 mov eax, [esp+4+arg_0]
+cseg01:C0000E58 push eax
+cseg01:C0000E59 call sub_C0000D98
+cseg01:C0000E5E add esp, 8
+cseg01:C0000E61 push eax
+cseg01:C0000E62 push 0CF8h
+cseg01:C0000E67 call sub_C0000022
+cseg01:C0000E6C add esp, 8
+cseg01:C0000E6F mov edx, [esp+arg_8]
+cseg01:C0000E73 push edx
+cseg01:C0000E74
+cseg01:C0000E74 loc_C0000E74: ; CODE XREF: cseg01:C0000EDEj
+cseg01:C0000E74 push 0CFCh
+cseg01:C0000E79 call sub_C0000022
+cseg01:C0000E7E add esp, 8
+cseg01:C0000E81 retn
+cseg01:C0000E81 sub_C0000E4E endp
+cseg01:C0000E81
+cseg01:C0000E82
+cseg01:C0000E82 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000E82
+cseg01:C0000E82
+cseg01:C0000E82 sub_C0000E82 proc near ; CODE XREF: sub_C0001084+27p
+cseg01:C0000E82
+cseg01:C0000E82 arg_0 = dword ptr 4
+cseg01:C0000E82 arg_4 = word ptr 8
+cseg01:C0000E82 arg_8 = word ptr 0Ch
+cseg01:C0000E82
+cseg01:C0000E82 movzx eax, [esp+arg_4]
+cseg01:C0000E87 push eax
+cseg01:C0000E88 mov eax, [esp+4+arg_0]
+cseg01:C0000E8C push eax
+cseg01:C0000E8D call sub_C0000D98
+cseg01:C0000E92 add esp, 8
+cseg01:C0000E95 push eax
+cseg01:C0000E96 push 0CF8h
+cseg01:C0000E9B call sub_C0000022
+cseg01:C0000EA0 add esp, 8
+cseg01:C0000EA3 movzx eax, [esp+arg_8]
+cseg01:C0000EA8 push eax
+cseg01:C0000EA9 push 0CFCh
+cseg01:C0000EAE call sub_C0000033
+cseg01:C0000EB3 add esp, 8
+cseg01:C0000EB6 retn
+cseg01:C0000EB6 sub_C0000E82 endp
+cseg01:C0000EB6
+cseg01:C0000EB7 ; ---------------------------------------------------------------------------
+cseg01:C0000EB7 movzx eax, word ptr [esp+8]
+cseg01:C0000EBC push eax
+cseg01:C0000EBD mov eax, [esp+8]
+cseg01:C0000EC1 push eax
+cseg01:C0000EC2 call sub_C0000D98
+cseg01:C0000EC7 add esp, 8
+cseg01:C0000ECA push eax
+cseg01:C0000ECB push 0CF8h
+cseg01:C0000ED0 call sub_C0000022
+cseg01:C0000ED5 add esp, 8
+cseg01:C0000ED8 movzx eax, byte ptr [esp+0Ch]
+cseg01:C0000EDD push eax
+cseg01:C0000EDE jmp short loc_C0000E74
+cseg01:C0000EE0
+cseg01:C0000EE0 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000EE0
+cseg01:C0000EE0
+cseg01:C0000EE0 sub_C0000EE0 proc near ; CODE XREF: sub_C0000F51+17p
+cseg01:C0000EE0
+cseg01:C0000EE0 var_8 = dword ptr -8
+cseg01:C0000EE0 arg_0 = dword ptr 4
+cseg01:C0000EE0
+cseg01:C0000EE0 push ebx
+cseg01:C0000EE1 sub esp, 4
+cseg01:C0000EE4 mov ebx, [esp+8+arg_0]
+cseg01:C0000EE8
+cseg01:C0000EE8 loc_C0000EE8: ; CODE XREF: sub_C0000EE0+57j
+cseg01:C0000EE8 push 0
+cseg01:C0000EEA lea eax, [ebx+4]
+cseg01:C0000EED push eax
+cseg01:C0000EEE call sub_C0000DC1
+cseg01:C0000EF3 add esp, 8
+cseg01:C0000EF6 mov [esp+8+var_8], eax
+cseg01:C0000EF9 mov eax, [ebx+4]
+cseg01:C0000EFC mov [ebx+8], eax
+cseg01:C0000EFF mov al, [ebx+6]
+cseg01:C0000F02 inc al
+cseg01:C0000F04 mov [ebx+6], al
+cseg01:C0000F07 cmp al, 8
+cseg01:C0000F09 jnz short loc_C0000F33
+cseg01:C0000F0B mov byte ptr [ebx+6], 0
+cseg01:C0000F0F mov dl, [ebx+5]
+cseg01:C0000F12 inc dl
+cseg01:C0000F14 mov [ebx+5], dl
+cseg01:C0000F17 cmp dl, 20h
+cseg01:C0000F1A jnz short loc_C0000F33
+cseg01:C0000F1C mov byte ptr [ebx+5], 0
+cseg01:C0000F20 mov cl, [ebx+4]
+cseg01:C0000F23 inc cl
+cseg01:C0000F25 mov [ebx+4], cl
+cseg01:C0000F28 cmp cl, dl
+cseg01:C0000F2A jnz short loc_C0000F33
+cseg01:C0000F2C xor eax, eax
+cseg01:C0000F2E add esp, 4
+cseg01:C0000F31 pop ebx
+cseg01:C0000F32 retn
+cseg01:C0000F33 ; ---------------------------------------------------------------------------
+cseg01:C0000F33
+cseg01:C0000F33 loc_C0000F33: ; CODE XREF: sub_C0000EE0+29j
+cseg01:C0000F33 ; sub_C0000EE0+3Aj ...
+cseg01:C0000F33 cmp [esp+8+var_8], 0FFFFFFFFh
+cseg01:C0000F37 jz short loc_C0000EE8
+cseg01:C0000F39 mov eax, [esp+8+var_8]
+cseg01:C0000F3C mov [ebx], ax
+cseg01:C0000F3F mov eax, [esp+8+var_8+2]
+cseg01:C0000F43 mov [ebx+2], ax
+cseg01:C0000F47 mov eax, 1
+cseg01:C0000F4C add esp, 4
+cseg01:C0000F4F pop ebx
+cseg01:C0000F50 retn
+cseg01:C0000F50 sub_C0000EE0 endp
+cseg01:C0000F50
+cseg01:C0000F51
+cseg01:C0000F51 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000F51
+cseg01:C0000F51
+cseg01:C0000F51 sub_C0000F51 proc near ; CODE XREF: sub_C0000861+19p
+cseg01:C0000F51 ; sub_C0000861+43p ...
+cseg01:C0000F51
+cseg01:C0000F51 var_18 = word ptr -18h
+cseg01:C0000F51 var_16 = dword ptr -16h
+cseg01:C0000F51 var_10 = dword ptr -10h
+cseg01:C0000F51 arg_0 = dword ptr 4
+cseg01:C0000F51 arg_4 = word ptr 8
+cseg01:C0000F51 arg_8 = dword ptr 0Ch
+cseg01:C0000F51
+cseg01:C0000F51 push ebx
+cseg01:C0000F52 push esi
+cseg01:C0000F53 push edi
+cseg01:C0000F54 sub esp, 0Ch
+cseg01:C0000F57 mov ebx, [esp+18h+arg_0]
+cseg01:C0000F5B mov edi, esp
+cseg01:C0000F5D mov esi, offset dword_C0000010
+cseg01:C0000F62 movsd
+cseg01:C0000F63 movsd
+cseg01:C0000F64 movsd
+cseg01:C0000F65
+cseg01:C0000F65 loc_C0000F65: ; CODE XREF: sub_C0000F51+27j
+cseg01:C0000F65 ; sub_C0000F51+32j
+cseg01:C0000F65 mov eax, esp
+cseg01:C0000F67 push eax
+cseg01:C0000F68 call sub_C0000EE0
+cseg01:C0000F6D add esp, 4
+cseg01:C0000F70 test eax, eax
+cseg01:C0000F72 jz short loc_C0000F94
+cseg01:C0000F74 cmp bx, [esp+18h+var_18]
+cseg01:C0000F78 jnz short loc_C0000F65
+cseg01:C0000F7A mov eax, [esp+18h+var_16]
+cseg01:C0000F7E cmp ax, [esp+18h+arg_4]
+cseg01:C0000F83 jnz short loc_C0000F65
+cseg01:C0000F85 mov eax, [esp+18h+var_10]
+cseg01:C0000F89 mov edx, [esp+18h+arg_8]
+cseg01:C0000F8D mov [edx], eax
+cseg01:C0000F8F mov eax, 1
+cseg01:C0000F94
+cseg01:C0000F94 loc_C0000F94: ; CODE XREF: sub_C0000F51+21j
+cseg01:C0000F94 add esp, 0Ch
+cseg01:C0000F97 pop edi
+cseg01:C0000F98 pop esi
+cseg01:C0000F99 pop ebx
+cseg01:C0000F9A retn
+cseg01:C0000F9A sub_C0000F51 endp
+cseg01:C0000F9A
+cseg01:C0000F9B ; ---------------------------------------------------------------------------
+cseg01:C0000F9B mov eax, [esp+0Ch]
+cseg01:C0000F9F push eax
+cseg01:C0000FA0 mov eax, [esp+0Ch]
+cseg01:C0000FA4 shl eax, 2
+cseg01:C0000FA7 add eax, 10h
+cseg01:C0000FAC movzx eax, ax
+cseg01:C0000FAF push eax
+cseg01:C0000FB0 mov edx, [esp+0Ch]
+cseg01:C0000FB4 push edx
+cseg01:C0000FB5 call sub_C0000E4E
+cseg01:C0000FBA add esp, 0Ch
+cseg01:C0000FBD retn
+cseg01:C0000FBE
+cseg01:C0000FBE ; =============== S U B R O U T I N E =======================================
+cseg01:C0000FBE
+cseg01:C0000FBE
+cseg01:C0000FBE sub_C0000FBE proc near ; CODE XREF: sub_C0000861+C8p
+cseg01:C0000FBE ; sub_C0000861+F0p ...
+cseg01:C0000FBE
+cseg01:C0000FBE arg_0 = dword ptr 4
+cseg01:C0000FBE arg_4 = dword ptr 8
+cseg01:C0000FBE
+cseg01:C0000FBE mov eax, [esp+arg_4]
+cseg01:C0000FC2 shl eax, 2
+cseg01:C0000FC5 add eax, 10h
+cseg01:C0000FCA movzx eax, ax
+cseg01:C0000FCD push eax
+cseg01:C0000FCE mov eax, [esp+4+arg_0]
+cseg01:C0000FD2 push eax
+cseg01:C0000FD3 call sub_C0000DC1
+cseg01:C0000FD8 add esp, 8
+cseg01:C0000FDB mov edx, eax
+cseg01:C0000FDD test al, 1
+cseg01:C0000FDF jz short loc_C0000FEB
+cseg01:C0000FE1 mov eax, 3
+cseg01:C0000FE6 not eax
+cseg01:C0000FE8 and eax, edx
+cseg01:C0000FEA retn
+cseg01:C0000FEB ; ---------------------------------------------------------------------------
+cseg01:C0000FEB
+cseg01:C0000FEB loc_C0000FEB: ; CODE XREF: sub_C0000FBE+21j
+cseg01:C0000FEB mov eax, 0Fh
+cseg01:C0000FF0 not eax
+cseg01:C0000FF2 and eax, edx
+cseg01:C0000FF4 retn
+cseg01:C0000FF4 sub_C0000FBE endp
+cseg01:C0000FF4
+cseg01:C0000FF5
+cseg01:C0000FF5 ; =============== S U B R O U T I N E =======================================
+cseg01:C0000FF5
+cseg01:C0000FF5
+cseg01:C0000FF5 sub_C0000FF5 proc near ; CODE XREF: sub_C0000861+DCp
+cseg01:C0000FF5 ; sub_C0000861+126p ...
+cseg01:C0000FF5
+cseg01:C0000FF5 arg_0 = dword ptr 4
+cseg01:C0000FF5 arg_4 = dword ptr 8
+cseg01:C0000FF5
+cseg01:C0000FF5 push ebx
+cseg01:C0000FF6 push esi
+cseg01:C0000FF7 push edi
+cseg01:C0000FF8 push ebp
+cseg01:C0000FF9 mov eax, [esp+10h+arg_4]
+cseg01:C0000FFD shl eax, 2
+cseg01:C0001000 add eax, 10h
+cseg01:C0001005 movzx eax, ax
+cseg01:C0001008 push eax
+cseg01:C0001009 mov eax, [esp+14h+arg_0]
+cseg01:C000100D push eax
+cseg01:C000100E call sub_C0000DC1
+cseg01:C0001013 add esp, 8
+cseg01:C0001016 mov ebp, eax
+cseg01:C0001018 test al, 1
+cseg01:C000101A jz short loc_C0001023
+cseg01:C000101C mov edi, 3
+cseg01:C0001021 jmp short loc_C0001028
+cseg01:C0001023 ; ---------------------------------------------------------------------------
+cseg01:C0001023
+cseg01:C0001023 loc_C0001023: ; CODE XREF: sub_C0000FF5+25j
+cseg01:C0001023 mov edi, 0Fh
+cseg01:C0001028
+cseg01:C0001028 loc_C0001028: ; CODE XREF: sub_C0000FF5+2Cj
+cseg01:C0001028 push 0FFFFFFFFh
+cseg01:C000102A mov eax, [esp+14h+arg_4]
+cseg01:C000102E shl eax, 2
+cseg01:C0001031 add eax, 10h
+cseg01:C0001036 movzx ebx, ax
+cseg01:C0001039 push ebx
+cseg01:C000103A mov edx, [esp+18h+arg_0]
+cseg01:C000103E push edx
+cseg01:C000103F call sub_C0000E4E
+cseg01:C0001044 add esp, 0Ch
+cseg01:C0001047 push ebx
+cseg01:C0001048 mov ecx, [esp+14h+arg_0]
+cseg01:C000104C push ecx
+cseg01:C000104D call sub_C0000DC1
+cseg01:C0001052 mov esi, eax
+cseg01:C0001054 add esp, 8
+cseg01:C0001057 push ebp
+cseg01:C0001058 push ebx
+cseg01:C0001059 mov ebx, [esp+18h+arg_0]
+cseg01:C000105D push ebx
+cseg01:C000105E call sub_C0000E4E
+cseg01:C0001063 add esp, 0Ch
+cseg01:C0001066 not edi
+cseg01:C0001068 mov eax, esi
+cseg01:C000106A and eax, edi
+cseg01:C000106C not eax
+cseg01:C000106E inc eax
+cseg01:C000106F pop ebp
+cseg01:C0001070 pop edi
+cseg01:C0001071 pop esi
+cseg01:C0001072 pop ebx
+cseg01:C0001073 retn
+cseg01:C0001073 sub_C0000FF5 endp
+cseg01:C0001073
+cseg01:C0001074
+cseg01:C0001074 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001074
+cseg01:C0001074
+cseg01:C0001074 sub_C0001074 proc near ; CODE XREF: sub_C0000861+7Ep
+cseg01:C0001074
+cseg01:C0001074 arg_0 = dword ptr 4
+cseg01:C0001074
+cseg01:C0001074 push 2Ch
+cseg01:C0001076 mov eax, [esp+4+arg_0]
+cseg01:C000107A push eax
+cseg01:C000107B call sub_C0000DC1
+cseg01:C0001080 add esp, 8
+cseg01:C0001083 retn
+cseg01:C0001083 sub_C0001074 endp
+cseg01:C0001083
+cseg01:C0001084
+cseg01:C0001084 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001084
+cseg01:C0001084
+cseg01:C0001084 sub_C0001084 proc near ; CODE XREF: sub_C0000861+AEp
+cseg01:C0001084
+cseg01:C0001084 arg_0 = dword ptr 4
+cseg01:C0001084 arg_4 = dword ptr 8
+cseg01:C0001084
+cseg01:C0001084 push 4
+cseg01:C0001086 mov eax, [esp+4+arg_0]
+cseg01:C000108A push eax
+cseg01:C000108B call sub_C0000DF0
+cseg01:C0001090 add esp, 8
+cseg01:C0001093 cmp [esp+arg_4], 0
+cseg01:C0001098 jz short loc_C000109E
+cseg01:C000109A or al, 7
+cseg01:C000109C jmp short loc_C00010A0
+cseg01:C000109E ; ---------------------------------------------------------------------------
+cseg01:C000109E
+cseg01:C000109E loc_C000109E: ; CODE XREF: sub_C0001084+14j
+cseg01:C000109E and al, 0F8h
+cseg01:C00010A0
+cseg01:C00010A0 loc_C00010A0: ; CODE XREF: sub_C0001084+18j
+cseg01:C00010A0 movzx eax, ax
+cseg01:C00010A3 push eax
+cseg01:C00010A4 push 4
+cseg01:C00010A6 mov ecx, [esp+8+arg_0]
+cseg01:C00010AA push ecx
+cseg01:C00010AB call sub_C0000E82
+cseg01:C00010B0 add esp, 0Ch
+cseg01:C00010B3 retn
+cseg01:C00010B3 sub_C0001084 endp
+cseg01:C00010B3
+cseg01:C00010B3 ; ---------------------------------------------------------------------------
+cseg01:C00010B4 dword_C00010B4 dd 0 ; DATA XREF: sub_C00010BC+1Bw
+cseg01:C00010B4 ; sub_C00010BC+31r ...
+cseg01:C00010B8 dword_C00010B8 dd 0 ; DATA XREF: sub_C00010BC+52w
+cseg01:C00010B8 ; cseg01:loc_C0001143r ...
+cseg01:C00010BC
+cseg01:C00010BC ; =============== S U B R O U T I N E =======================================
+cseg01:C00010BC
+cseg01:C00010BC
+cseg01:C00010BC sub_C00010BC proc near ; CODE XREF: sub_C00019F5+7Dp
+cseg01:C00010BC push 8
+cseg01:C00010BE push 0
+cseg01:C00010C0 push 100000h
+cseg01:C00010C5 push 0
+cseg01:C00010C7 push 0
+cseg01:C00010C9 push 0
+cseg01:C00010CB push 1
+cseg01:C00010CD push 1
+cseg01:C00010CF call sub_C000135A
+cseg01:C00010D4 add esp, 20h
+cseg01:C00010D7 mov ds:dword_C00010B4, eax
+cseg01:C00010DC test eax, eax
+cseg01:C00010DE jz short locret_C000112E
+cseg01:C00010E0 push 3Ch
+cseg01:C00010E2 push 0
+cseg01:C00010E4 push eax
+cseg01:C00010E5 call sub_C00011BA
+cseg01:C00010EA add esp, 0Ch
+cseg01:C00010ED mov eax, ds:dword_C00010B4
+cseg01:C00010F2 mov dword ptr [eax], 3Ch
+cseg01:C00010F8 mov eax, ds:dword_C00010B4
+cseg01:C00010FD mov dword ptr [eax+4], 0
+cseg01:C0001104 push 1
+cseg01:C0001106 call sub_C00012BB
+cseg01:C000110B add esp, 4
+cseg01:C000110E mov ds:dword_C00010B8, eax
+cseg01:C0001113 test eax, eax
+cseg01:C0001115 jnz short loc_C0001129
+cseg01:C0001117 push eax
+cseg01:C0001118 mov eax, ds:dword_C00010B4
+cseg01:C000111D push eax
+cseg01:C000111E call sub_C0001360
+cseg01:C0001123 add esp, 8
+cseg01:C0001126 xor eax, eax
+cseg01:C0001128 retn
+cseg01:C0001129 ; ---------------------------------------------------------------------------
+cseg01:C0001129
+cseg01:C0001129 loc_C0001129: ; CODE XREF: sub_C00010BC+59j
+cseg01:C0001129 mov eax, 1
+cseg01:C000112E
+cseg01:C000112E locret_C000112E: ; CODE XREF: sub_C00010BC+22j
+cseg01:C000112E retn
+cseg01:C000112E sub_C00010BC endp
+cseg01:C000112E
+cseg01:C000112F ; ---------------------------------------------------------------------------
+cseg01:C000112F mov eax, ds:dword_C00010B4
+cseg01:C0001134 test eax, eax
+cseg01:C0001136 jz short loc_C0001143
+cseg01:C0001138 push 0
+cseg01:C000113A push eax
+cseg01:C000113B call sub_C0001360
+cseg01:C0001140 add esp, 8
+cseg01:C0001143
+cseg01:C0001143 loc_C0001143: ; CODE XREF: cseg01:C0001136j
+cseg01:C0001143 mov ecx, ds:dword_C00010B8
+cseg01:C0001149 test ecx, ecx
+cseg01:C000114B jz short locret_C0001156
+cseg01:C000114D push ecx
+cseg01:C000114E call sub_C00012F2
+cseg01:C0001153 add esp, 4
+cseg01:C0001156
+cseg01:C0001156 locret_C0001156: ; CODE XREF: cseg01:C000114Bj
+cseg01:C0001156 retn
+cseg01:C0001157
+cseg01:C0001157 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001157
+cseg01:C0001157
+cseg01:C0001157 sub_C0001157 proc near ; CODE XREF: sub_C000037B:loc_C0000425p
+cseg01:C0001157 ; sub_C000055F:loc_C000066Bp
+cseg01:C0001157 mov eax, ds:dword_C00010B4
+cseg01:C000115C retn
+cseg01:C000115C sub_C0001157 endp
+cseg01:C000115C
+cseg01:C000115D
+cseg01:C000115D ; =============== S U B R O U T I N E =======================================
+cseg01:C000115D
+cseg01:C000115D
+cseg01:C000115D sub_C000115D proc near ; CODE XREF: sub_C000037B+C3p
+cseg01:C000115D ; sub_C000055F+116p ...
+cseg01:C000115D push 0
+cseg01:C000115F mov eax, ds:dword_C00010B8
+cseg01:C0001164 push eax
+cseg01:C0001165 call sub_C000130F
+cseg01:C000116A add esp, 8
+cseg01:C000116D retn
+cseg01:C000116D sub_C000115D endp
+cseg01:C000116D
+cseg01:C000116E
+cseg01:C000116E ; =============== S U B R O U T I N E =======================================
+cseg01:C000116E
+cseg01:C000116E
+cseg01:C000116E sub_C000116E proc near ; CODE XREF: sub_C000037B:loc_C0000461p
+cseg01:C000116E ; sub_C000055F:loc_C000069Dp
+cseg01:C000116E push 0
+cseg01:C0001170 call sub_C000115D
+cseg01:C0001175 add esp, 4
+cseg01:C0001178 mov eax, ds:dword_C00010B4
+cseg01:C000117D mov edx, [eax+1Ch]
+cseg01:C0001180 push edx
+cseg01:C0001181 push 0
+cseg01:C0001183 mov edx, [eax+20h]
+cseg01:C0001186 push edx
+cseg01:C0001187 call sub_C00011BA
+cseg01:C000118C add esp, 0Ch
+cseg01:C000118F push 0
+cseg01:C0001191 call sub_C0002630
+cseg01:C0001196 add esp, 4
+cseg01:C0001199 retn
+cseg01:C0001199 sub_C000116E endp
+cseg01:C0001199
+cseg01:C0001199 ; ---------------------------------------------------------------------------
+cseg01:C000119A align 4
+cseg01:C000119C word_C000119C dw 0 ; DATA XREF: sub_C0001270+Dw
+cseg01:C000119C ; sub_C0001270+15r
+cseg01:C000119E dword_C000119E dd 0 ; DATA XREF: sub_C0001290+7w
+cseg01:C000119E ; sub_C0001290+Dr
+cseg01:C00011A2 dword_C00011A2 dd 0 ; DATA XREF: sub_C00012BB+7w
+cseg01:C00011A2 ; sub_C00012BB+15r
+cseg01:C00011A6 dword_C00011A6 dd 0 ; DATA XREF: sub_C00012BB+Ew
+cseg01:C00011A6 ; sub_C00012BB+27w ...
+cseg01:C00011AA dword_C00011AA dd 0 ; DATA XREF: sub_C00012F2+7w
+cseg01:C00011AA ; sub_C00012F2+Dr
+cseg01:C00011AE dword_C00011AE dd 0 ; DATA XREF: sub_C000130F+7w
+cseg01:C00011AE ; sub_C000130F+17r
+cseg01:C00011B2 dword_C00011B2 dd 0 ; DATA XREF: sub_C000130F+10w
+cseg01:C00011B2 ; sub_C000130F+1Cr
+cseg01:C00011B6 dword_C00011B6 dd 0 ; DATA XREF: sub_C000133D+7w
+cseg01:C00011B6 ; sub_C000133D+Dr
+cseg01:C00011BA
+cseg01:C00011BA ; =============== S U B R O U T I N E =======================================
+cseg01:C00011BA
+cseg01:C00011BA
+cseg01:C00011BA sub_C00011BA proc near ; CODE XREF: sub_C00010BC+29p
+cseg01:C00011BA ; sub_C000116E+19p ...
+cseg01:C00011BA
+cseg01:C00011BA var_10 = dword ptr -10h
+cseg01:C00011BA arg_0 = dword ptr 4
+cseg01:C00011BA arg_4 = dword ptr 8
+cseg01:C00011BA arg_8 = dword ptr 0Ch
+cseg01:C00011BA
+cseg01:C00011BA push ebx
+cseg01:C00011BB push esi
+cseg01:C00011BC push edi
+cseg01:C00011BD sub esp, 4
+cseg01:C00011C0 mov ecx, [esp+10h+arg_0]
+cseg01:C00011C4 mov edi, [esp+10h+arg_8]
+cseg01:C00011C8 mov eax, [esp+10h+arg_4]
+cseg01:C00011CC and eax, 0FFh
+cseg01:C00011D1 mov [esp+10h+arg_4], eax
+cseg01:C00011D5 mov edx, eax
+cseg01:C00011D7 shl edx, 18h
+cseg01:C00011DA shl eax, 10h
+cseg01:C00011DD or eax, edx
+cseg01:C00011DF mov edx, [esp+10h+arg_4]
+cseg01:C00011E3 shl edx, 8
+cseg01:C00011E6 or eax, edx
+cseg01:C00011E8 mov esi, [esp+10h+arg_4]
+cseg01:C00011EC or esi, eax
+cseg01:C00011EE mov ebx, edi
+cseg01:C00011F0 shr ebx, 2
+cseg01:C00011F3 mov eax, edi
+cseg01:C00011F5 and al, 0FCh
+cseg01:C00011F7 mov [esp+10h+var_10], eax
+cseg01:C00011FA xor eax, eax
+cseg01:C00011FC
+cseg01:C00011FC loc_C00011FC: ; CODE XREF: sub_C00011BA+4Cj
+cseg01:C00011FC cmp eax, ebx
+cseg01:C00011FE jnb short loc_C0001208
+cseg01:C0001200 mov edx, eax
+cseg01:C0001202 mov [ecx+edx*4], esi
+cseg01:C0001205 inc eax
+cseg01:C0001206 jmp short loc_C00011FC
+cseg01:C0001208 ; ---------------------------------------------------------------------------
+cseg01:C0001208
+cseg01:C0001208 loc_C0001208: ; CODE XREF: sub_C00011BA+44j
+cseg01:C0001208 mov eax, [esp+10h+var_10]
+cseg01:C000120B mov bl, byte ptr [esp+10h+arg_4]
+cseg01:C000120F
+cseg01:C000120F loc_C000120F: ; CODE XREF: sub_C00011BA+5Fj
+cseg01:C000120F cmp eax, edi
+cseg01:C0001211 jnb short loc_C000121B
+cseg01:C0001213 lea edx, [ecx+eax]
+cseg01:C0001216 mov [edx], bl
+cseg01:C0001218 inc eax
+cseg01:C0001219 jmp short loc_C000120F
+cseg01:C000121B ; ---------------------------------------------------------------------------
+cseg01:C000121B
+cseg01:C000121B loc_C000121B: ; CODE XREF: sub_C00011BA+57j
+cseg01:C000121B ; sub_C0001222+4Cj
+cseg01:C000121B add esp, 4
+cseg01:C000121E pop edi
+cseg01:C000121F pop esi
+cseg01:C0001220 pop ebx
+cseg01:C0001221 retn
+cseg01:C0001221 sub_C00011BA endp
+cseg01:C0001221
+cseg01:C0001222
+cseg01:C0001222 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001222
+cseg01:C0001222
+cseg01:C0001222 sub_C0001222 proc near ; CODE XREF: sub_C000055F+1BCp
+cseg01:C0001222 ; sub_C0001599+33p ...
+cseg01:C0001222
+cseg01:C0001222 var_10 = dword ptr -10h
+cseg01:C0001222 arg_0 = dword ptr 4
+cseg01:C0001222 arg_4 = dword ptr 8
+cseg01:C0001222 arg_8 = dword ptr 0Ch
+cseg01:C0001222
+cseg01:C0001222 push ebx
+cseg01:C0001223 push esi
+cseg01:C0001224 push edi
+cseg01:C0001225 sub esp, 4
+cseg01:C0001228 mov esi, [esp+10h+arg_0]
+cseg01:C000122C mov ebx, [esp+10h+arg_4]
+cseg01:C0001230 mov edi, [esp+10h+arg_8]
+cseg01:C0001234 shr edi, 2
+cseg01:C0001237 mov eax, [esp+10h+arg_8]
+cseg01:C000123B and al, 0FCh
+cseg01:C000123D mov [esp+10h+var_10], eax
+cseg01:C0001240 xor eax, eax
+cseg01:C0001242
+cseg01:C0001242 loc_C0001242: ; CODE XREF: sub_C0001222+32j
+cseg01:C0001242 cmp eax, edi
+cseg01:C0001244 jnb short loc_C0001256
+cseg01:C0001246 mov ecx, eax
+cseg01:C0001248 shl ecx, 2
+cseg01:C000124B lea edx, [ebx+ecx]
+cseg01:C000124E mov edx, [edx]
+cseg01:C0001250 mov [ecx+esi], edx
+cseg01:C0001253 inc eax
+cseg01:C0001254 jmp short loc_C0001242
+cseg01:C0001256 ; ---------------------------------------------------------------------------
+cseg01:C0001256
+cseg01:C0001256 loc_C0001256: ; CODE XREF: sub_C0001222+22j
+cseg01:C0001256 mov eax, [esp+10h+var_10]
+cseg01:C0001259
+cseg01:C0001259 loc_C0001259: ; CODE XREF: sub_C0001222+48j
+cseg01:C0001259 cmp eax, [esp+10h+arg_8]
+cseg01:C000125D jnb short loc_C000126C
+cseg01:C000125F lea edx, [ebx+eax]
+cseg01:C0001262 lea ecx, [esi+eax]
+cseg01:C0001265 mov dl, [edx]
+cseg01:C0001267 mov [ecx], dl
+cseg01:C0001269 inc eax
+cseg01:C000126A jmp short loc_C0001259
+cseg01:C000126C ; ---------------------------------------------------------------------------
+cseg01:C000126C
+cseg01:C000126C loc_C000126C: ; CODE XREF: sub_C0001222+3Bj
+cseg01:C000126C mov eax, esi
+cseg01:C000126E jmp short loc_C000121B
+cseg01:C000126E sub_C0001222 endp
+cseg01:C000126E
+cseg01:C0001270
+cseg01:C0001270 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001270
+cseg01:C0001270
+cseg01:C0001270 sub_C0001270 proc near ; CODE XREF: sub_C000037B:loc_C0000419p
+cseg01:C0001270 push ebx
+cseg01:C0001271 push esi
+cseg01:C0001272 push edi
+cseg01:C0001273 push ecx
+cseg01:C0001274 push eax
+cseg01:C0001275 xor eax, eax
+cseg01:C0001277 VMMCall Get_VMM_Version
+cseg01:C000127D mov ds:word_C000119C, ax
+cseg01:C0001283 pop ecx
+cseg01:C0001284 pop eax
+cseg01:C0001285 movzx eax, ds:word_C000119C
+cseg01:C000128C pop edi
+cseg01:C000128D pop esi
+cseg01:C000128E pop ebx
+cseg01:C000128F retn
+cseg01:C000128F sub_C0001270 endp
+cseg01:C000128F
+cseg01:C0001290
+cseg01:C0001290 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001290
+cseg01:C0001290
+cseg01:C0001290 sub_C0001290 proc near ; CODE XREF: sub_C00017FE+84p
+cseg01:C0001290 ; sub_C00017FE+12Bp
+cseg01:C0001290
+cseg01:C0001290 arg_0 = dword ptr 4
+cseg01:C0001290
+cseg01:C0001290 push ebx
+cseg01:C0001291 push esi
+cseg01:C0001292 push edi
+cseg01:C0001293 mov eax, [esp+0Ch+arg_0]
+cseg01:C0001297 mov ds:dword_C000119E, eax
+cseg01:C000129C push ecx
+cseg01:C000129D mov ecx, ds:dword_C000119E
+cseg01:C00012A3 VMMCall Begin_Critical_Section
+cseg01:C00012A9 pop ecx
+cseg01:C00012AA pop edi
+cseg01:C00012AB pop esi
+cseg01:C00012AC pop ebx
+cseg01:C00012AD retn
+cseg01:C00012AD sub_C0001290 endp
+cseg01:C00012AD
+cseg01:C00012AE
+cseg01:C00012AE ; =============== S U B R O U T I N E =======================================
+cseg01:C00012AE
+cseg01:C00012AE
+cseg01:C00012AE sub_C00012AE proc near ; CODE XREF: sub_C00017FE+CCp
+cseg01:C00012AE ; sub_C00017FE:loc_C0001996p
+cseg01:C00012AE push ebx
+cseg01:C00012AF push esi
+cseg01:C00012B0 push edi
+cseg01:C00012B1 VMMCall End_Critical_Section
+cseg01:C00012B7 pop edi
+cseg01:C00012B8 pop esi
+cseg01:C00012B9 pop ebx
+cseg01:C00012BA retn
+cseg01:C00012BA sub_C00012AE endp
+cseg01:C00012BA
+cseg01:C00012BB
+cseg01:C00012BB ; =============== S U B R O U T I N E =======================================
+cseg01:C00012BB
+cseg01:C00012BB
+cseg01:C00012BB sub_C00012BB proc near ; CODE XREF: sub_C00010BC+4Ap
+cseg01:C00012BB
+cseg01:C00012BB arg_0 = dword ptr 4
+cseg01:C00012BB
+cseg01:C00012BB push ebx
+cseg01:C00012BC push esi
+cseg01:C00012BD push edi
+cseg01:C00012BE mov eax, [esp+0Ch+arg_0]
+cseg01:C00012C2 mov ds:dword_C00011A2, eax
+cseg01:C00012C7 xor eax, eax
+cseg01:C00012C9 mov ds:dword_C00011A6, eax
+cseg01:C00012CE push eax
+cseg01:C00012CF push ecx
+cseg01:C00012D0 mov ecx, ds:dword_C00011A2
+cseg01:C00012D6 VMMCall Create_Semaphore
+cseg01:C00012DC jb loc_C00012E7
+cseg01:C00012E2 mov ds:dword_C00011A6, eax
+cseg01:C00012E7
+cseg01:C00012E7 loc_C00012E7: ; CODE XREF: sub_C00012BB+21j
+cseg01:C00012E7 pop ecx
+cseg01:C00012E8 pop eax
+cseg01:C00012E9 mov eax, ds:dword_C00011A6
+cseg01:C00012EE pop edi
+cseg01:C00012EF pop esi
+cseg01:C00012F0 pop ebx
+cseg01:C00012F1 retn
+cseg01:C00012F1 sub_C00012BB endp
+cseg01:C00012F1
+cseg01:C00012F2
+cseg01:C00012F2 ; =============== S U B R O U T I N E =======================================
+cseg01:C00012F2
+cseg01:C00012F2
+cseg01:C00012F2 sub_C00012F2 proc near ; CODE XREF: cseg01:C000114Ep
+cseg01:C00012F2
+cseg01:C00012F2 arg_0 = dword ptr 4
+cseg01:C00012F2
+cseg01:C00012F2 push ebx
+cseg01:C00012F3 push esi
+cseg01:C00012F4 push edi
+cseg01:C00012F5 mov eax, [esp+0Ch+arg_0]
+cseg01:C00012F9 mov ds:dword_C00011AA, eax
+cseg01:C00012FE push eax
+cseg01:C00012FF mov eax, ds:dword_C00011AA
+cseg01:C0001304 VMMCall Destroy_Semaphore
+cseg01:C000130A pop eax
+cseg01:C000130B pop edi
+cseg01:C000130C pop esi
+cseg01:C000130D pop ebx
+cseg01:C000130E retn
+cseg01:C000130E sub_C00012F2 endp
+cseg01:C000130E
+cseg01:C000130F
+cseg01:C000130F ; =============== S U B R O U T I N E =======================================
+cseg01:C000130F
+cseg01:C000130F
+cseg01:C000130F sub_C000130F proc near ; CODE XREF: sub_C000115D+8p
+cseg01:C000130F
+cseg01:C000130F arg_0 = dword ptr 4
+cseg01:C000130F arg_4 = dword ptr 8
+cseg01:C000130F
+cseg01:C000130F push ebx
+cseg01:C0001310 push esi
+cseg01:C0001311 push edi
+cseg01:C0001312 mov eax, [esp+0Ch+arg_0]
+cseg01:C0001316 mov ds:dword_C00011AE, eax
+cseg01:C000131B mov eax, [esp+0Ch+arg_4]
+cseg01:C000131F mov ds:dword_C00011B2, eax
+cseg01:C0001324 push eax
+cseg01:C0001325 push ecx
+cseg01:C0001326 mov eax, ds:dword_C00011AE
+cseg01:C000132B mov ecx, ds:dword_C00011B2
+cseg01:C0001331 VMMCall Wait_Semaphore
+cseg01:C0001337 pop ecx
+cseg01:C0001338 pop eax
+cseg01:C0001339 pop edi
+cseg01:C000133A pop esi
+cseg01:C000133B pop ebx
+cseg01:C000133C retn
+cseg01:C000133C sub_C000130F endp
+cseg01:C000133C
+cseg01:C000133D
+cseg01:C000133D ; =============== S U B R O U T I N E =======================================
+cseg01:C000133D
+cseg01:C000133D
+cseg01:C000133D sub_C000133D proc near ; CODE XREF: sub_C0002630+78p
+cseg01:C000133D
+cseg01:C000133D arg_0 = dword ptr 4
+cseg01:C000133D
+cseg01:C000133D push ebx
+cseg01:C000133E push esi
+cseg01:C000133F push edi
+cseg01:C0001340 mov eax, [esp+0Ch+arg_0]
+cseg01:C0001344 mov ds:dword_C00011B6, eax
+cseg01:C0001349 push eax
+cseg01:C000134A mov eax, ds:dword_C00011B6
+cseg01:C000134F VMMCall Signal_Semaphore
+cseg01:C0001355 pop eax
+cseg01:C0001356 pop edi
+cseg01:C0001357 pop esi
+cseg01:C0001358 pop ebx
+cseg01:C0001359 retn
+cseg01:C0001359 sub_C000133D endp
+cseg01:C0001359
+cseg01:C000135A
+cseg01:C000135A ; =============== S U B R O U T I N E =======================================
+cseg01:C000135A
+cseg01:C000135A
+cseg01:C000135A sub_C000135A proc near ; CODE XREF: sub_C00010BC+13p
+cseg01:C000135A ; sub_C0001599+1Ap ...
+cseg01:C000135A VMMJmp _PageAllocate
+cseg01:C000135A sub_C000135A endp
+cseg01:C000135A
+cseg01:C0001360
+cseg01:C0001360 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001360
+cseg01:C0001360
+cseg01:C0001360 sub_C0001360 proc near ; CODE XREF: sub_C00010BC+62p
+cseg01:C0001360 ; cseg01:C000113Bp ...
+cseg01:C0001360 VMMJmp _PageFree
+cseg01:C0001360 sub_C0001360 endp
+cseg01:C0001360
+cseg01:C0001366
+cseg01:C0001366 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001366
+cseg01:C0001366
+cseg01:C0001366 sub_C0001366 proc near ; CODE XREF: sub_C0001D1E+18p
+cseg01:C0001366 VMMJmp _CopyPageTable
+cseg01:C0001366 sub_C0001366 endp
+cseg01:C0001366
+cseg01:C000136C ; ---------------------------------------------------------------------------
+cseg01:C000136C VMMJmp _LinPageLock
+cseg01:C0001372 ; ---------------------------------------------------------------------------
+cseg01:C0001372 VMMJmp _LinPageUnlock
+cseg01:C0001378
+cseg01:C0001378 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001378
+cseg01:C0001378
+cseg01:C0001378 sub_C0001378 proc near ; CODE XREF: sub_C000156E+18p
+cseg01:C0001378 ; sub_C00019F5+1B2p ...
+cseg01:C0001378 VMMJmp _MapPhysToLinear
+cseg01:C0001378 sub_C0001378 endp
+cseg01:C0001378
+cseg01:C000137E ; ---------------------------------------------------------------------------
+cseg01:C000137E VMMJmp _MapPhysToLinear
+cseg01:C0001384 ; ---------------------------------------------------------------------------
+cseg01:C0001384 VMMJmp _PhysIntov86
+cseg01:C000138A
+cseg01:C000138A ; =============== S U B R O U T I N E =======================================
+cseg01:C000138A
+cseg01:C000138A
+cseg01:C000138A sub_C000138A proc near ; CODE XREF: sub_C00014C4+20p
+cseg01:C000138A VMMJmp _RegOpenKey
+cseg01:C000138A sub_C000138A endp
+cseg01:C000138A
+cseg01:C0001390
+cseg01:C0001390 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001390
+cseg01:C0001390
+cseg01:C0001390 sub_C0001390 proc near ; CODE XREF: sub_C00014C4+9Ap
+cseg01:C0001390 VMMJmp _RegCloseKey
+cseg01:C0001390 sub_C0001390 endp
+cseg01:C0001390
+cseg01:C0001396
+cseg01:C0001396 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001396
+cseg01:C0001396
+cseg01:C0001396 sub_C0001396 proc near ; CODE XREF: sub_C00014C4+4Ap
+cseg01:C0001396 VMMJmp _RegQueryValueEx
+cseg01:C0001396 sub_C0001396 endp
+cseg01:C0001396
+cseg01:C0001396 ; ---------------------------------------------------------------------------
+cseg01:C000139C dword_C000139C dd 0 ; DATA XREF: sub_C0001644+47w
+cseg01:C000139C ; sub_C0001644+5Cr ...
+cseg01:C00013A0 dword_C00013A0 dd 0 ; DATA XREF: sub_C00019F5+28Aw
+cseg01:C00013A0 ; sub_C0001D48+1ECr
+cseg01:C00013A4 dword_C00013A4 dd 0 ; DATA XREF: sub_C00017FE+Br
+cseg01:C00013A4 ; sub_C00019F5+2B9w ...
+cseg01:C00013A8 dword_C00013A8 dd 0 ; DATA XREF: sub_C00017FE+18r
+cseg01:C00013A8 ; sub_C00020E0+3w ...
+cseg01:C00013AC dword_C00013AC dd 0 ; DATA XREF: sub_C00019F5+318w
+cseg01:C00013AC ; sub_C000262Ar
+cseg01:C00013B0 dword_C00013B0 dd 0 ; DATA XREF: sub_C00017FE+8Cr
+cseg01:C00013B0 ; sub_C00017FE:loc_C0001893r ...
+cseg01:C00013B4 dword_C00013B4 dd 0 ; DATA XREF: sub_C00014C4+35o
+cseg01:C00013B4 ; sub_C00014C4+5Fo ...
+cseg01:C00013B8 dd 0Fh dup(0)
+cseg01:C00013F4 dword_C00013F4 dd 0 ; DATA XREF: sub_C00017EA+3w
+cseg01:C00013F4 ; sub_C00017FE:loc_C0001869r
+cseg01:C00013F8 dword_C00013F8 dd 0 ; DATA XREF: sub_C00017EA+9w
+cseg01:C00013F8 ; sub_C00017FE+73r
+cseg01:C00013FC dword_C00013FC dd 1 ; DATA XREF: sub_C000179Ar
+cseg01:C00013FC ; sub_C000179A+Ew ...
+cseg01:C0001400 dword_C0001400 dd 0 ; DATA XREF: sub_C00019F5+30Ew
+cseg01:C0001400 ; sub_C00020E0+11r ...
+cseg01:C0001404 dword_C0001404 dd 2 dup(0) ; DATA XREF: sub_C0001599+2Do
+cseg01:C000140C dd 82h, 3 dup(0)
+cseg01:C000141C dd 1D0h, 3 dup(0)
+cseg01:C000142C dd 1, 7 dup(0)
+cseg01:C000144C dd 1, 3 dup(0)
+cseg01:C000145C dd 1, 0
+cseg01:C0001464 dword_C0001464 dd 0 ; DATA XREF: sub_C0001599+2r
+cseg01:C0001464 ; sub_C0001599+22w ...
+cseg01:C0001468 aSoftwareSvga db 'Software\SVGA',0 ; DATA XREF: sub_C00014C4+16o
+cseg01:C0001476 aHwcursor db 'hwcursor',0 ; DATA XREF: sub_C00019F5+28o
+cseg01:C000147F aVram256 db 'vram256',0 ; DATA XREF: sub_C00019F5+3Ao
+cseg01:C000147F ; sub_C00019F5:loc_C0001ACEo
+cseg01:C0001487 aRgb565bug db 'rgb565bug',0 ; DATA XREF: sub_C00019F5+4Co
+cseg01:C0001491 aCommandbuffers db 'commandbuffers',0 ; DATA XREF: sub_C00019F5+5Eo
+cseg01:C00014A0 aHwversion db 'hwversion',0 ; DATA XREF: sub_C00019F5+70o
+cseg01:C00014AA aVmwsmini_vxd db 'vmwsmini.vxd',0 ; DATA XREF: sub_C00019F5+2F3o
+cseg01:C00014B7
+cseg01:C00014B7 ; =============== S U B R O U T I N E =======================================
+cseg01:C00014B7
+cseg01:C00014B7
+cseg01:C00014B7 sub_C00014B7 proc near ; CODE XREF: sub_C00017D1+12p
+cseg01:C00014B7 ; sub_C00017FE+A0p
+cseg01:C00014B7 push 1
+cseg01:C00014B9 push 15h
+cseg01:C00014BB call sub_C0000CD3
+cseg01:C00014C0 add esp, 8
+cseg01:C00014C3 retn
+cseg01:C00014C3 sub_C00014B7 endp
+cseg01:C00014C3
+cseg01:C00014C4
+cseg01:C00014C4 ; =============== S U B R O U T I N E =======================================
+cseg01:C00014C4
+cseg01:C00014C4
+cseg01:C00014C4 sub_C00014C4 proc near ; CODE XREF: sub_C00019F5+2Dp
+cseg01:C00014C4 ; sub_C00019F5+3Fp ...
+cseg01:C00014C4
+cseg01:C00014C4 var_14 = dword ptr -14h
+cseg01:C00014C4 var_10 = dword ptr -10h
+cseg01:C00014C4 var_C = dword ptr -0Ch
+cseg01:C00014C4 arg_0 = dword ptr 4
+cseg01:C00014C4 arg_4 = dword ptr 8
+cseg01:C00014C4
+cseg01:C00014C4 push ebx
+cseg01:C00014C5 push esi
+cseg01:C00014C6 sub esp, 0Ch
+cseg01:C00014C9 mov esi, [esp+14h+arg_4]
+cseg01:C00014CD mov [esp+14h+var_C], 40h
+cseg01:C00014D5 xor ebx, ebx
+cseg01:C00014D7 mov eax, esp
+cseg01:C00014D9 push eax
+cseg01:C00014DA push offset aSoftwareSvga ; "Software\\SVGA"
+cseg01:C00014DF push 80000002h
+cseg01:C00014E4 call sub_C000138A
+cseg01:C00014E9 add esp, 0Ch
+cseg01:C00014EC test eax, eax
+cseg01:C00014EE jnz loc_C0001566
+cseg01:C00014F4 lea eax, [esp+14h+var_C]
+cseg01:C00014F8 push eax
+cseg01:C00014F9 push offset dword_C00013B4
+cseg01:C00014FE lea eax, [esp+1Ch+var_10]
+cseg01:C0001502 push eax
+cseg01:C0001503 push ebx
+cseg01:C0001504 mov edx, [esp+24h+arg_0]
+cseg01:C0001508 push edx
+cseg01:C0001509 mov ecx, [esp+28h+var_14]
+cseg01:C000150D push ecx
+cseg01:C000150E call sub_C0001396
+cseg01:C0001513 add esp, 18h
+cseg01:C0001516 test eax, eax
+cseg01:C0001518 jnz short loc_C000155A
+cseg01:C000151A cmp [esp+14h+var_10], 1
+cseg01:C000151F jnz short loc_C000154E
+cseg01:C0001521 xor edx, edx
+cseg01:C0001523 mov eax, offset dword_C00013B4
+cseg01:C0001528
+cseg01:C0001528 loc_C0001528: ; CODE XREF: sub_C00014C4+6Aj
+cseg01:C0001528 cmp byte ptr [eax], 20h
+cseg01:C000152B jnz short loc_C0001530
+cseg01:C000152D inc eax
+cseg01:C000152E jmp short loc_C0001528
+cseg01:C0001530 ; ---------------------------------------------------------------------------
+cseg01:C0001530
+cseg01:C0001530 loc_C0001530: ; CODE XREF: sub_C00014C4+67j
+cseg01:C0001530 ; sub_C00014C4+84j
+cseg01:C0001530 mov bh, [eax]
+cseg01:C0001532 cmp bh, 30h
+cseg01:C0001535 jb short loc_C000154A
+cseg01:C0001537 cmp bh, 39h
+cseg01:C000153A ja short loc_C000154A
+cseg01:C000153C imul edx, 0Ah
+cseg01:C000153F movzx ecx, bh
+cseg01:C0001542 sub ecx, 30h
+cseg01:C0001545 add edx, ecx
+cseg01:C0001547 inc eax
+cseg01:C0001548 jmp short loc_C0001530
+cseg01:C000154A ; ---------------------------------------------------------------------------
+cseg01:C000154A
+cseg01:C000154A loc_C000154A: ; CODE XREF: sub_C00014C4+71j
+cseg01:C000154A ; sub_C00014C4+76j
+cseg01:C000154A mov [esi], edx
+cseg01:C000154C jmp short loc_C0001555
+cseg01:C000154E ; ---------------------------------------------------------------------------
+cseg01:C000154E
+cseg01:C000154E loc_C000154E: ; CODE XREF: sub_C00014C4+5Bj
+cseg01:C000154E mov eax, ds:dword_C00013B4
+cseg01:C0001553 mov [esi], eax
+cseg01:C0001555
+cseg01:C0001555 loc_C0001555: ; CODE XREF: sub_C00014C4+88j
+cseg01:C0001555 mov ebx, 1
+cseg01:C000155A
+cseg01:C000155A loc_C000155A: ; CODE XREF: sub_C00014C4+54j
+cseg01:C000155A mov esi, [esp+14h+var_14]
+cseg01:C000155D push esi
+cseg01:C000155E call sub_C0001390
+cseg01:C0001563 add esp, 4
+cseg01:C0001566
+cseg01:C0001566 loc_C0001566: ; CODE XREF: sub_C00014C4+2Aj
+cseg01:C0001566 mov eax, ebx
+cseg01:C0001568 add esp, 0Ch
+cseg01:C000156B
+cseg01:C000156B loc_C000156B: ; CODE XREF: sub_C0001599+42j
+cseg01:C000156B ; sub_C0001599+4Cj
+cseg01:C000156B pop esi
+cseg01:C000156C pop ebx
+cseg01:C000156D retn
+cseg01:C000156D sub_C00014C4 endp
+cseg01:C000156D
+cseg01:C000156E
+cseg01:C000156E ; =============== S U B R O U T I N E =======================================
+cseg01:C000156E
+cseg01:C000156E
+cseg01:C000156E sub_C000156E proc near ; CODE XREF: sub_C0000861+1DAp
+cseg01:C000156E call sub_C0000B98
+cseg01:C0001573 test eax, eax
+cseg01:C0001575 jz short locret_C0001598
+cseg01:C0001577 push 0
+cseg01:C0001579 mov eax, ds:dword_C00007BC
+cseg01:C000157E push eax
+cseg01:C000157F mov edx, ds:dword_C00007C8
+cseg01:C0001585 push edx
+cseg01:C0001586 call sub_C0001378
+cseg01:C000158B add esp, 0Ch
+cseg01:C000158E mov ds:dword_C0000818, eax
+cseg01:C0001593 mov ds:dword_C000081C, eax
+cseg01:C0001598
+cseg01:C0001598 locret_C0001598: ; CODE XREF: sub_C000156E+7j
+cseg01:C0001598 retn
+cseg01:C0001598 sub_C000156E endp
+cseg01:C0001598
+cseg01:C0001599
+cseg01:C0001599 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001599
+cseg01:C0001599
+cseg01:C0001599 sub_C0001599 proc near ; CODE XREF: sub_C00019F5+285p
+cseg01:C0001599 push ebx
+cseg01:C000159A push esi
+cseg01:C000159B mov eax, ds:dword_C0001464
+cseg01:C00015A0 test eax, eax
+cseg01:C00015A2 jnz short loc_C00015D4
+cseg01:C00015A4 push 8
+cseg01:C00015A6 push eax
+cseg01:C00015A7 push 100000h
+cseg01:C00015AC push eax
+cseg01:C00015AD push eax
+cseg01:C00015AE push eax
+cseg01:C00015AF push 1
+cseg01:C00015B1 push 1
+cseg01:C00015B3 call sub_C000135A
+cseg01:C00015B8 add esp, 20h
+cseg01:C00015BB mov ds:dword_C0001464, eax
+cseg01:C00015C0 test eax, eax
+cseg01:C00015C2 jz short loc_C00015D4
+cseg01:C00015C4 push 60h
+cseg01:C00015C6 push offset dword_C0001404
+cseg01:C00015CB push eax
+cseg01:C00015CC call sub_C0001222
+cseg01:C00015D1 add esp, 0Ch
+cseg01:C00015D4
+cseg01:C00015D4 loc_C00015D4: ; CODE XREF: sub_C0001599+9j
+cseg01:C00015D4 ; sub_C0001599+29j
+cseg01:C00015D4 cmp ds:dword_C0001464, 0
+cseg01:C00015DB jz short loc_C000156B
+cseg01:C00015DD xor esi, esi
+cseg01:C00015DF jmp short loc_C00015E7
+cseg01:C00015E1 ; ---------------------------------------------------------------------------
+cseg01:C00015E1
+cseg01:C00015E1 loc_C00015E1: ; CODE XREF: sub_C0001599+60j
+cseg01:C00015E1 ; sub_C0001599+66j ...
+cseg01:C00015E1 inc esi
+cseg01:C00015E2 cmp esi, 6
+cseg01:C00015E5 jge short loc_C000156B
+cseg01:C00015E7
+cseg01:C00015E7 loc_C00015E7: ; CODE XREF: sub_C0001599+46j
+cseg01:C00015E7 mov eax, esi
+cseg01:C00015E9 shl eax, 4
+cseg01:C00015EC mov ebx, ds:dword_C0001464
+cseg01:C00015F2 add ebx, eax
+cseg01:C00015F4 mov ecx, [ebx+8]
+cseg01:C00015F7 test ecx, ecx
+cseg01:C00015F9 jz short loc_C00015E1
+cseg01:C00015FB test byte ptr [ebx+0Ch], 1
+cseg01:C00015FF jnz short loc_C00015E1
+cseg01:C0001601 push 0Eh
+cseg01:C0001603 push ebx
+cseg01:C0001604 push 100000h
+cseg01:C0001609 push 0
+cseg01:C000160B push 0
+cseg01:C000160D push 0
+cseg01:C000160F push 1
+cseg01:C0001611 lea eax, [ecx+0FFFh]
+cseg01:C0001617 shr eax, 0Ch
+cseg01:C000161A push eax
+cseg01:C000161B call sub_C000135A
+cseg01:C0001620 add esp, 20h
+cseg01:C0001623 mov [ebx+4], eax
+cseg01:C0001626 test eax, eax
+cseg01:C0001628 jz short loc_C00015E1
+cseg01:C000162A push esi
+cseg01:C000162B push offset aAllocatedOtabl ; "Allocated OTable row: %d\n"
+cseg01:C0001630 call sub_C0002A03
+cseg01:C0001635 add esp, 8
+cseg01:C0001638 or byte ptr [ebx+0Ch], 1
+cseg01:C000163C jmp short loc_C00015E1
+cseg01:C000163C sub_C0001599 endp
+cseg01:C000163C
+cseg01:C000163E
+cseg01:C000163E ; =============== S U B R O U T I N E =======================================
+cseg01:C000163E
+cseg01:C000163E
+cseg01:C000163E sub_C000163E proc near ; CODE XREF: sub_C000055F:loc_C0000770p
+cseg01:C000163E mov eax, ds:dword_C0001464
+cseg01:C0001643 retn
+cseg01:C0001643 sub_C000163E endp
+cseg01:C0001643
+cseg01:C0001644
+cseg01:C0001644 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001644
+cseg01:C0001644
+cseg01:C0001644 sub_C0001644 proc near ; CODE XREF: sub_C00019F5:loc_C0001CC5p
+cseg01:C0001644 push ebx
+cseg01:C0001645 push 2Bh
+cseg01:C0001647 call sub_C0000C93
+cseg01:C000164C add esp, 4
+cseg01:C000164F mov ebx, eax
+cseg01:C0001651 shl ebx, 5
+cseg01:C0001654 push 4Dh
+cseg01:C0001656 call sub_C0002496
+cseg01:C000165B add esp, 4
+cseg01:C000165E shl eax, 3
+cseg01:C0001661 add eax, ebx
+cseg01:C0001663 lea ebx, [eax+784h]
+cseg01:C0001669 push 8
+cseg01:C000166B push 0
+cseg01:C000166D push 100000h
+cseg01:C0001672 push 0
+cseg01:C0001674 push 0
+cseg01:C0001676 push 0
+cseg01:C0001678 push 1
+cseg01:C000167A add eax, 1783h
+cseg01:C000167F shr eax, 0Ch
+cseg01:C0001682 push eax
+cseg01:C0001683 call sub_C000135A
+cseg01:C0001688 add esp, 20h
+cseg01:C000168B mov ds:dword_C000139C, eax
+cseg01:C0001690 test eax, eax
+cseg01:C0001692 jz short loc_C000170C
+cseg01:C0001694 push ebx
+cseg01:C0001695 push 0
+cseg01:C0001697 push eax
+cseg01:C0001698 call sub_C00011BA
+cseg01:C000169D add esp, 0Ch
+cseg01:C00016A0 mov eax, ds:dword_C000139C
+cseg01:C00016A5 lea ebx, [eax+1Ch]
+cseg01:C00016A8 mov [eax], ebx
+cseg01:C00016AA push 2Bh
+cseg01:C00016AC call sub_C0000C93
+cseg01:C00016B1 mov edx, eax
+cseg01:C00016B3 add esp, 4
+cseg01:C00016B6 mov eax, ds:dword_C000139C
+cseg01:C00016BB mov [eax+0Ch], edx
+cseg01:C00016BE mov eax, ds:dword_C000139C
+cseg01:C00016C3 mov edx, [eax+0Ch]
+cseg01:C00016C6 shl edx, 5
+cseg01:C00016C9 add ebx, edx
+cseg01:C00016CB mov [eax+4], ebx
+cseg01:C00016CE push 4Dh
+cseg01:C00016D0 call sub_C0002496
+cseg01:C00016D5 mov edx, eax
+cseg01:C00016D7 add esp, 4
+cseg01:C00016DA mov eax, ds:dword_C000139C
+cseg01:C00016DF mov [eax+10h], edx
+cseg01:C00016E2 mov eax, ds:dword_C000139C
+cseg01:C00016E7 mov edx, [eax+10h]
+cseg01:C00016EA shl edx, 3
+cseg01:C00016ED add ebx, edx
+cseg01:C00016EF mov [eax+8], ebx
+cseg01:C00016F2 mov eax, ds:dword_C000139C
+cseg01:C00016F7 mov dword ptr [eax+14h], 4Eh
+cseg01:C00016FE mov eax, ds:dword_C000139C
+cseg01:C0001703 imul edx, [eax+14h], 18h
+cseg01:C0001707 add ebx, edx
+cseg01:C0001709 mov [eax+18h], ebx
+cseg01:C000170C
+cseg01:C000170C loc_C000170C: ; CODE XREF: sub_C0001644+4Ej
+cseg01:C000170C pop ebx
+cseg01:C000170D retn
+cseg01:C000170D sub_C0001644 endp
+cseg01:C000170D
+cseg01:C000170E
+cseg01:C000170E ; =============== S U B R O U T I N E =======================================
+cseg01:C000170E
+cseg01:C000170E
+cseg01:C000170E sub_C000170E proc near ; CODE XREF: sub_C000055F:loc_C0000766p
+cseg01:C000170E mov eax, ds:dword_C000139C
+cseg01:C0001713 retn
+cseg01:C0001713 sub_C000170E endp
+cseg01:C0001713
+cseg01:C0001714
+cseg01:C0001714 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001714
+cseg01:C0001714
+cseg01:C0001714 sub_C0001714 proc near ; CODE XREF: sub_C000055F:loc_C00006C5p
+cseg01:C0001714 ; sub_C00019F5+309p
+cseg01:C0001714
+cseg01:C0001714 var_8 = dword ptr -8
+cseg01:C0001714
+cseg01:C0001714 push ebx
+cseg01:C0001715 sub esp, 4
+cseg01:C0001718 push 0Eh
+cseg01:C000171A lea eax, [esp+0Ch+var_8]
+cseg01:C000171E push eax
+cseg01:C000171F push 100000h
+cseg01:C0001724 push 0
+cseg01:C0001726 push 0
+cseg01:C0001728 push 0
+cseg01:C000172A push 1
+cseg01:C000172C push 80h
+cseg01:C0001731 call sub_C000135A
+cseg01:C0001736 mov ebx, eax
+cseg01:C0001738 add esp, 20h
+cseg01:C000173B test eax, eax
+cseg01:C000173D jz short loc_C0001765
+cseg01:C000173F push 4
+cseg01:C0001741 push 0
+cseg01:C0001743 push eax
+cseg01:C0001744 call sub_C00011BA
+cseg01:C0001749 add esp, 0Ch
+cseg01:C000174C mov dword ptr [ebx], 1
+cseg01:C0001752 mov dword ptr [ebx+1Ch], 0
+cseg01:C0001759 mov eax, [esp+8+var_8]
+cseg01:C000175C add eax, 40h
+cseg01:C000175F mov [ebx+18h], eax
+cseg01:C0001762 lea eax, [ebx+40h]
+cseg01:C0001765
+cseg01:C0001765 loc_C0001765: ; CODE XREF: sub_C0001714+29j
+cseg01:C0001765 add esp, 4
+cseg01:C0001768 pop ebx
+cseg01:C0001769 retn
+cseg01:C0001769 sub_C0001714 endp
+cseg01:C0001769
+cseg01:C000176A
+cseg01:C000176A ; =============== S U B R O U T I N E =======================================
+cseg01:C000176A
+cseg01:C000176A
+cseg01:C000176A sub_C000176A proc near ; CODE XREF: sub_C000055F+170p
+cseg01:C000176A
+cseg01:C000176A arg_0 = dword ptr 4
+cseg01:C000176A
+cseg01:C000176A push 0
+cseg01:C000176C mov eax, [esp+4+arg_0]
+cseg01:C0001770 sub eax, 40h
+cseg01:C0001773 push eax
+cseg01:C0001774 call sub_C0001360
+cseg01:C0001779 add esp, 8
+cseg01:C000177C retn
+cseg01:C000177C sub_C000176A endp
+cseg01:C000177C
+cseg01:C000177D
+cseg01:C000177D ; =============== S U B R O U T I N E =======================================
+cseg01:C000177D
+cseg01:C000177D
+cseg01:C000177D sub_C000177D proc near ; CODE XREF: sub_C00017C1+5p
+cseg01:C000177D ; sub_C00017FE+1E7p
+cseg01:C000177D call sub_C0000B98
+cseg01:C0001782 test eax, eax
+cseg01:C0001784 jz short loc_C0001791
+cseg01:C0001786 push 45h
+cseg01:C0001788 call sub_C0000C93
+cseg01:C000178D add esp, 4
+cseg01:C0001790 retn
+cseg01:C0001791 ; ---------------------------------------------------------------------------
+cseg01:C0001791
+cseg01:C0001791 loc_C0001791: ; CODE XREF: sub_C000177D+7j
+cseg01:C0001791 mov eax, ds:dword_C00007B4
+cseg01:C0001796 mov eax, [eax+18h]
+cseg01:C0001799 retn
+cseg01:C0001799 sub_C000177D endp
+cseg01:C0001799
+cseg01:C000179A
+cseg01:C000179A ; =============== S U B R O U T I N E =======================================
+cseg01:C000179A
+cseg01:C000179A
+cseg01:C000179A sub_C000179A proc near ; CODE XREF: sub_C000055F:loc_C00006F3p
+cseg01:C000179A ; sub_C00017FE+148p
+cseg01:C000179A cmp ds:dword_C00013FC, 0
+cseg01:C00017A1 jnz short loc_C00017B2
+cseg01:C00017A3 call sub_C0000D7D
+cseg01:C00017A8 mov ds:dword_C00013FC, 1
+cseg01:C00017B2
+cseg01:C00017B2 loc_C00017B2: ; CODE XREF: sub_C000179A+7j
+cseg01:C00017B2 mov eax, ds:dword_C00013FC
+cseg01:C00017B7 lea edx, [eax+1]
+cseg01:C00017BA mov ds:dword_C00013FC, edx
+cseg01:C00017C0 retn
+cseg01:C00017C0 sub_C000179A endp
+cseg01:C00017C0
+cseg01:C00017C1
+cseg01:C00017C1 ; =============== S U B R O U T I N E =======================================
+cseg01:C00017C1
+cseg01:C00017C1
+cseg01:C00017C1 sub_C00017C1 proc near ; CODE XREF: sub_C000055F+19Ep
+cseg01:C00017C1 ; sub_C00017D1+6p
+cseg01:C00017C1
+cseg01:C00017C1 arg_0 = dword ptr 4
+cseg01:C00017C1
+cseg01:C00017C1 push ebx
+cseg01:C00017C2 mov ebx, [esp+4+arg_0]
+cseg01:C00017C6 call sub_C000177D
+cseg01:C00017CB test ebx, ebx
+cseg01:C00017CD xor eax, eax
+cseg01:C00017CF
+cseg01:C00017CF loc_C00017CF: ; CODE XREF: sub_C00017D1+10j
+cseg01:C00017CF pop ebx
+cseg01:C00017D0 retn
+cseg01:C00017D0 sub_C00017C1 endp
+cseg01:C00017D0
+cseg01:C00017D1
+cseg01:C00017D1 ; =============== S U B R O U T I N E =======================================
+cseg01:C00017D1
+cseg01:C00017D1
+cseg01:C00017D1 sub_C00017D1 proc near ; CODE XREF: sub_C000055F+1A8p
+cseg01:C00017D1 ; sub_C00017FE+1A8p
+cseg01:C00017D1
+cseg01:C00017D1 arg_0 = dword ptr 4
+cseg01:C00017D1
+cseg01:C00017D1 push ebx
+cseg01:C00017D2 mov ebx, [esp+4+arg_0]
+cseg01:C00017D6
+cseg01:C00017D6 loc_C00017D6: ; CODE XREF: sub_C00017D1+17j
+cseg01:C00017D6 push ebx
+cseg01:C00017D7 call sub_C00017C1
+cseg01:C00017DC add esp, 4
+cseg01:C00017DF test eax, eax
+cseg01:C00017E1 jz short loc_C00017CF
+cseg01:C00017E3 call sub_C00014B7
+cseg01:C00017E8 jmp short loc_C00017D6
+cseg01:C00017E8 sub_C00017D1 endp
+cseg01:C00017E8
+cseg01:C00017EA
+cseg01:C00017EA ; =============== S U B R O U T I N E =======================================
+cseg01:C00017EA
+cseg01:C00017EA
+cseg01:C00017EA sub_C00017EA proc near ; CODE XREF: sub_C00017FE:loc_C0001912p
+cseg01:C00017EA push ebx
+cseg01:C00017EB push esi
+cseg01:C00017EC push edi
+cseg01:C00017ED inc ds:dword_C00013F4
+cseg01:C00017F3 adc ds:dword_C00013F8, 0
+cseg01:C00017FA pop edi
+cseg01:C00017FB pop esi
+cseg01:C00017FC pop ebx
+cseg01:C00017FD retn
+cseg01:C00017FD sub_C00017EA endp
+cseg01:C00017FD
+cseg01:C00017FE
+cseg01:C00017FE ; =============== S U B R O U T I N E =======================================
+cseg01:C00017FE
+cseg01:C00017FE
+cseg01:C00017FE sub_C00017FE proc near ; CODE XREF: sub_C000055F+18Ap
+cseg01:C00017FE ; sub_C00020E0+51p ...
+cseg01:C00017FE
+cseg01:C00017FE var_1C = dword ptr -1Ch
+cseg01:C00017FE var_18 = dword ptr -18h
+cseg01:C00017FE var_14 = dword ptr -14h
+cseg01:C00017FE arg_0 = dword ptr 4
+cseg01:C00017FE arg_4 = dword ptr 8
+cseg01:C00017FE arg_8 = dword ptr 0Ch
+cseg01:C00017FE arg_C = byte ptr 10h
+cseg01:C00017FE arg_F = byte ptr 13h
+cseg01:C00017FE arg_10 = dword ptr 14h
+cseg01:C00017FE
+cseg01:C00017FE push ebx
+cseg01:C00017FF push esi
+cseg01:C0001800 push edi
+cseg01:C0001801 push ebp
+cseg01:C0001802 sub esp, 0Ch
+cseg01:C0001805 mov ebp, [esp+1Ch+arg_8]
+cseg01:C0001809 cmp ds:dword_C00013A4, 0
+cseg01:C0001810 jz loc_C000191C
+cseg01:C0001816 cmp ds:dword_C00013A8, 0
+cseg01:C000181D jnz short loc_C000182A
+cseg01:C000181F test [esp+1Ch+arg_F], 80h
+cseg01:C0001824 jz loc_C000191C
+cseg01:C000182A
+cseg01:C000182A loc_C000182A: ; CODE XREF: sub_C00017FE+1Fj
+cseg01:C000182A mov ah, [esp+1Ch+arg_F]
+cseg01:C000182E test ah, 20h
+cseg01:C0001831 jnz loc_C000191C
+cseg01:C0001837 mov ebx, [esp+1Ch+arg_0]
+cseg01:C000183B sub ebx, 40h
+cseg01:C000183E xor edi, edi
+cseg01:C0001840 test ah, 80h
+cseg01:C0001843 jz short loc_C000184A
+cseg01:C0001845 mov edi, 3Fh
+cseg01:C000184A
+cseg01:C000184A loc_C000184A: ; CODE XREF: sub_C00017FE+45j
+cseg01:C000184A mov dword ptr [ebx], 0
+cseg01:C0001850 mov dword ptr [ebx+10h], 1
+cseg01:C0001857 test [esp+1Ch+arg_C], 2
+cseg01:C000185C jz short loc_C0001869
+cseg01:C000185E or byte ptr [ebx+10h], 2
+cseg01:C0001862 mov eax, [esp+1Ch+arg_10]
+cseg01:C0001866 mov [ebx+24h], eax
+cseg01:C0001869
+cseg01:C0001869 loc_C0001869: ; CODE XREF: sub_C00017FE+5Ej
+cseg01:C0001869 mov eax, ds:dword_C00013F4
+cseg01:C000186E mov [ebx+8], eax
+cseg01:C0001871 mov eax, ds:dword_C00013F8
+cseg01:C0001876 mov [ebx+0Ch], eax
+cseg01:C0001879 mov eax, [esp+1Ch+arg_4]
+cseg01:C000187D mov [ebx+14h], eax
+cseg01:C0001880 push 0
+cseg01:C0001882 call sub_C0001290
+cseg01:C0001887 add esp, 4
+cseg01:C000188A cmp ds:dword_C00013B0, 0
+cseg01:C0001891 jz short loc_C00018A5
+cseg01:C0001893
+cseg01:C0001893 loc_C0001893: ; CODE XREF: sub_C00017FE+A5j
+cseg01:C0001893 mov esi, ds:dword_C00013B0
+cseg01:C0001899 cmp dword ptr [esi], 0
+cseg01:C000189C jnz short loc_C00018A5
+cseg01:C000189E call sub_C00014B7
+cseg01:C00018A3 jmp short loc_C0001893
+cseg01:C00018A5 ; ---------------------------------------------------------------------------
+cseg01:C00018A5
+cseg01:C00018A5 loc_C00018A5: ; CODE XREF: sub_C00017FE+93j
+cseg01:C00018A5 ; sub_C00017FE+9Ej
+cseg01:C00018A5 push 0
+cseg01:C00018A7 push 31h
+cseg01:C00018A9 call sub_C0000CD3
+cseg01:C00018AE add esp, 8
+cseg01:C00018B1 mov eax, [ebx+18h]
+cseg01:C00018B4 sub eax, 40h
+cseg01:C00018B7 or edi, eax
+cseg01:C00018B9 push edi
+cseg01:C00018BA push 30h
+cseg01:C00018BC call sub_C0000CD3
+cseg01:C00018C1 add esp, 8
+cseg01:C00018C4 mov ds:dword_C00013B0, ebx
+cseg01:C00018CA call sub_C00012AE
+cseg01:C00018CF test [esp+1Ch+arg_F], 40h
+cseg01:C00018D4 jz short loc_C00018FD
+cseg01:C00018D6
+cseg01:C00018D6 loc_C00018D6: ; CODE XREF: sub_C00017FE+E9j
+cseg01:C00018D6 cmp dword ptr [ebx], 0
+cseg01:C00018D9 jnz short loc_C00018E9
+cseg01:C00018DB push 1
+cseg01:C00018DD push 15h
+cseg01:C00018DF call sub_C0000CD3
+cseg01:C00018E4 add esp, 8
+cseg01:C00018E7 jmp short loc_C00018D6
+cseg01:C00018E9 ; ---------------------------------------------------------------------------
+cseg01:C00018E9
+cseg01:C00018E9 loc_C00018E9: ; CODE XREF: sub_C00017FE+DBj
+cseg01:C00018E9 test ebp, ebp
+cseg01:C00018EB jz short loc_C0001912
+cseg01:C00018ED mov dword ptr [ebp+4], 1
+cseg01:C00018F4 mov dword ptr [ebp+0], 0
+cseg01:C00018FB jmp short loc_C000190B
+cseg01:C00018FD ; ---------------------------------------------------------------------------
+cseg01:C00018FD
+cseg01:C00018FD loc_C00018FD: ; CODE XREF: sub_C00017FE+D6j
+cseg01:C00018FD test ebp, ebp
+cseg01:C00018FF jz short loc_C0001912
+cseg01:C0001901 mov dword ptr [ebp+4], 0
+cseg01:C0001908 mov [ebp+0], ebx
+cseg01:C000190B
+cseg01:C000190B loc_C000190B: ; CODE XREF: sub_C00017FE+FDj
+cseg01:C000190B mov dword ptr [ebp+8], 0
+cseg01:C0001912
+cseg01:C0001912 loc_C0001912: ; CODE XREF: sub_C00017FE+EDj
+cseg01:C0001912 ; sub_C00017FE+101j
+cseg01:C0001912 call sub_C00017EA
+cseg01:C0001917 jmp loc_C00019E1
+cseg01:C000191C ; ---------------------------------------------------------------------------
+cseg01:C000191C
+cseg01:C000191C loc_C000191C: ; CODE XREF: sub_C00017FE+12j
+cseg01:C000191C ; sub_C00017FE+26j ...
+cseg01:C000191C mov esi, [esp+1Ch+arg_0]
+cseg01:C0001920 mov edi, [esp+1Ch+arg_4]
+cseg01:C0001924 shr edi, 2
+cseg01:C0001927 push 0
+cseg01:C0001929 call sub_C0001290
+cseg01:C000192E add esp, 4
+cseg01:C0001931 mov eax, ds:dword_C00007B4
+cseg01:C0001936 mov ebx, [eax+8]
+cseg01:C0001939 mov edx, [eax+4]
+cseg01:C000193C mov [esp+1Ch+var_14], edx
+cseg01:C0001940 mov eax, [eax]
+cseg01:C0001942 mov [esp+1Ch+var_18], eax
+cseg01:C0001946 call sub_C000179A
+cseg01:C000194B mov edx, eax
+cseg01:C000194D mov [esp+1Ch+var_1C], eax
+cseg01:C0001950 mov eax, edi
+cseg01:C0001952 shl eax, 2
+cseg01:C0001955 add eax, esi
+cseg01:C0001957 mov dword ptr [eax], 1Eh
+cseg01:C000195D mov [eax+4], edx
+cseg01:C0001960 add edi, 2
+cseg01:C0001963
+cseg01:C0001963 loc_C0001963: ; CODE XREF: sub_C00017FE+196j
+cseg01:C0001963 test edi, edi
+cseg01:C0001965 jbe short loc_C0001996
+cseg01:C0001967 mov eax, ebx
+cseg01:C0001969 shr eax, 2
+cseg01:C000196C shl eax, 2
+cseg01:C000196F mov edx, ds:dword_C00007B4
+cseg01:C0001975 add eax, edx
+cseg01:C0001977 mov edx, [esi]
+cseg01:C0001979 mov [eax], edx
+cseg01:C000197B add esi, 4
+cseg01:C000197E add ebx, 4
+cseg01:C0001981 cmp ebx, [esp+1Ch+var_14]
+cseg01:C0001985 jb short loc_C000198B
+cseg01:C0001987 mov ebx, [esp+1Ch+var_18]
+cseg01:C000198B
+cseg01:C000198B loc_C000198B: ; CODE XREF: sub_C00017FE+187j
+cseg01:C000198B mov eax, ds:dword_C00007B4
+cseg01:C0001990 mov [eax+8], ebx
+cseg01:C0001993 dec edi
+cseg01:C0001994 jmp short loc_C0001963
+cseg01:C0001996 ; ---------------------------------------------------------------------------
+cseg01:C0001996
+cseg01:C0001996 loc_C0001996: ; CODE XREF: sub_C00017FE+167j
+cseg01:C0001996 call sub_C00012AE
+cseg01:C000199B test [esp+1Ch+arg_F], 40h
+cseg01:C00019A0 jz short loc_C00019C9
+cseg01:C00019A2 mov edi, [esp+1Ch+var_1C]
+cseg01:C00019A5 push edi
+cseg01:C00019A6 call sub_C00017D1
+cseg01:C00019AB add esp, 4
+cseg01:C00019AE test ebp, ebp
+cseg01:C00019B0 jz short loc_C00019E1
+cseg01:C00019B2 mov dword ptr [ebp+4], 1
+cseg01:C00019B9 mov dword ptr [ebp+0], 0
+cseg01:C00019C0 mov dword ptr [ebp+8], 0
+cseg01:C00019C7 jmp short loc_C00019E1
+cseg01:C00019C9 ; ---------------------------------------------------------------------------
+cseg01:C00019C9
+cseg01:C00019C9 loc_C00019C9: ; CODE XREF: sub_C00017FE+1A2j
+cseg01:C00019C9 test ebp, ebp
+cseg01:C00019CB jz short loc_C00019E1
+cseg01:C00019CD mov dword ptr [ebp+4], 0FFh
+cseg01:C00019D4 mov eax, [esp+1Ch+var_1C]
+cseg01:C00019D7 mov [ebp+8], eax
+cseg01:C00019DA mov dword ptr [ebp+0], 0
+cseg01:C00019E1
+cseg01:C00019E1 loc_C00019E1: ; CODE XREF: sub_C00017FE+119j
+cseg01:C00019E1 ; sub_C00017FE+1B2j ...
+cseg01:C00019E1 test ebp, ebp
+cseg01:C00019E3 jz short loc_C00019ED
+cseg01:C00019E5 call sub_C000177D
+cseg01:C00019EA mov [ebp+0Ch], eax
+cseg01:C00019ED
+cseg01:C00019ED loc_C00019ED: ; CODE XREF: sub_C00017FE+1E5j
+cseg01:C00019ED add esp, 0Ch
+cseg01:C00019F0 pop ebp
+cseg01:C00019F1 pop edi
+cseg01:C00019F2 pop esi
+cseg01:C00019F3 pop ebx
+cseg01:C00019F4 retn
+cseg01:C00019F4 sub_C00017FE endp
+cseg01:C00019F4
+cseg01:C00019F5
+cseg01:C00019F5 ; =============== S U B R O U T I N E =======================================
+cseg01:C00019F5
+cseg01:C00019F5
+cseg01:C00019F5 sub_C00019F5 proc near ; CODE XREF: sub_C000050A+16p
+cseg01:C00019F5
+cseg01:C00019F5 var_24 = dword ptr -24h
+cseg01:C00019F5 var_20 = dword ptr -20h
+cseg01:C00019F5 var_1C = dword ptr -1Ch
+cseg01:C00019F5 var_18 = dword ptr -18h
+cseg01:C00019F5 var_14 = dword ptr -14h
+cseg01:C00019F5
+cseg01:C00019F5 push ebx
+cseg01:C00019F6 push esi
+cseg01:C00019F7 push edi
+cseg01:C00019F8 push ebp
+cseg01:C00019F9 sub esp, 14h
+cseg01:C00019FC xor eax, eax
+cseg01:C00019FE mov [esp+24h+var_24], eax
+cseg01:C0001A01 mov [esp+24h+var_20], eax
+cseg01:C0001A05 mov ecx, 1
+cseg01:C0001A0A mov [esp+24h+var_1C], ecx
+cseg01:C0001A0E mov [esp+24h+var_18], ecx
+cseg01:C0001A12 mov [esp+24h+var_14], 2
+cseg01:C0001A1A mov eax, esp
+cseg01:C0001A1C push eax
+cseg01:C0001A1D push offset aHwcursor ; "hwcursor"
+cseg01:C0001A22 call sub_C00014C4
+cseg01:C0001A27 add esp, 8
+cseg01:C0001A2A lea eax, [esp+24h+var_20]
+cseg01:C0001A2E push eax
+cseg01:C0001A2F push offset aVram256 ; "vram256"
+cseg01:C0001A34 call sub_C00014C4
+cseg01:C0001A39 add esp, 8
+cseg01:C0001A3C lea eax, [esp+24h+var_1C]
+cseg01:C0001A40 push eax
+cseg01:C0001A41 push offset aRgb565bug ; "rgb565bug"
+cseg01:C0001A46 call sub_C00014C4
+cseg01:C0001A4B add esp, 8
+cseg01:C0001A4E lea eax, [esp+24h+var_18]
+cseg01:C0001A52 push eax
+cseg01:C0001A53 push offset aCommandbuffers ; "commandbuffers"
+cseg01:C0001A58 call sub_C00014C4
+cseg01:C0001A5D add esp, 8
+cseg01:C0001A60 lea eax, [esp+24h+var_14]
+cseg01:C0001A64 push eax
+cseg01:C0001A65 push offset aHwversion ; "hwversion"
+cseg01:C0001A6A call sub_C00014C4
+cseg01:C0001A6F add esp, 8
+cseg01:C0001A72 call sub_C00010BC
+cseg01:C0001A77 test eax, eax
+cseg01:C0001A79 jz loc_C0001D16
+cseg01:C0001A7F push 0
+cseg01:C0001A81 push offset aTestD ; "test %d\n"
+cseg01:C0001A86 call sub_C0002A03
+cseg01:C0001A8B add esp, 8
+cseg01:C0001A8E mov edi, [esp+24h+var_14]
+cseg01:C0001A92 push edi
+cseg01:C0001A93 push 0
+cseg01:C0001A95 call sub_C0000861
+cseg01:C0001A9A mov ebx, eax
+cseg01:C0001A9C add esp, 8
+cseg01:C0001A9F push eax
+cseg01:C0001AA0 push offset aSvga_initD ; "SVGA_Init: %d\n"
+cseg01:C0001AA5 call sub_C0002A03
+cseg01:C0001AAA add esp, 8
+cseg01:C0001AAD test ebx, ebx
+cseg01:C0001AAF jnz loc_C0001D14
+cseg01:C0001AB5 xor ebp, ebp
+cseg01:C0001AB7 mov ds:dword_C000080C, ebp
+cseg01:C0001ABD cmp [esp+24h+var_1C], 0
+cseg01:C0001AC2 jz short loc_C0001ACE
+cseg01:C0001AC4 mov ds:dword_C000080C, 8
+cseg01:C0001ACE
+cseg01:C0001ACE loc_C0001ACE: ; CODE XREF: sub_C00019F5+CDj
+cseg01:C0001ACE mov eax, offset aVram256 ; "vram256"
+cseg01:C0001AD3 test eax, eax
+cseg01:C0001AD5 jz short loc_C0001ADE
+cseg01:C0001AD7 or byte ptr ds:dword_C000080C, 10h
+cseg01:C0001ADE
+cseg01:C0001ADE loc_C0001ADE: ; CODE XREF: sub_C00019F5+E0j
+cseg01:C0001ADE push 1
+cseg01:C0001AE0 push offset aTestD ; "test %d\n"
+cseg01:C0001AE5 call sub_C0002A03
+cseg01:C0001AEA add esp, 8
+cseg01:C0001AED push 11h
+cseg01:C0001AEF call sub_C0000C93
+cseg01:C0001AF4 add esp, 4
+cseg01:C0001AF7 test al, 20h
+cseg01:C0001AF9 jz short loc_C0001B08
+cseg01:C0001AFB cmp [esp+24h+var_24], 0
+cseg01:C0001AFF jz short loc_C0001B08
+cseg01:C0001B01 or byte ptr ds:dword_C000080C, 2
+cseg01:C0001B08
+cseg01:C0001B08 loc_C0001B08: ; CODE XREF: sub_C00019F5+104j
+cseg01:C0001B08 ; sub_C00019F5+10Aj
+cseg01:C0001B08 push 2
+cseg01:C0001B0A push offset aTestD ; "test %d\n"
+cseg01:C0001B0F call sub_C0002A03
+cseg01:C0001B14 add esp, 8
+cseg01:C0001B17 push 11h
+cseg01:C0001B19 call sub_C0000C93
+cseg01:C0001B1E add esp, 4
+cseg01:C0001B21 test ah, 2
+cseg01:C0001B24 jz short loc_C0001B33
+cseg01:C0001B26 cmp [esp+24h+var_24], 0
+cseg01:C0001B2A jz short loc_C0001B33
+cseg01:C0001B2C or byte ptr ds:dword_C000080C, 4
+cseg01:C0001B33
+cseg01:C0001B33 loc_C0001B33: ; CODE XREF: sub_C00019F5+12Fj
+cseg01:C0001B33 ; sub_C00019F5+135j
+cseg01:C0001B33 push 3
+cseg01:C0001B35 push offset aTestD ; "test %d\n"
+cseg01:C0001B3A call sub_C0002A03
+cseg01:C0001B3F add esp, 8
+cseg01:C0001B42 test byte ptr ds:dword_C000080C, 10h
+cseg01:C0001B49 jz short loc_C0001B61
+cseg01:C0001B4B cmp ds:dword_C00007D8, 8000000h
+cseg01:C0001B55 jbe short loc_C0001B61
+cseg01:C0001B57 mov ds:dword_C00007D8, 8000000h
+cseg01:C0001B61
+cseg01:C0001B61 loc_C0001B61: ; CODE XREF: sub_C00019F5+154j
+cseg01:C0001B61 ; sub_C00019F5+160j
+cseg01:C0001B61 push 4
+cseg01:C0001B63 push offset aTestD ; "test %d\n"
+cseg01:C0001B68 call sub_C0002A03
+cseg01:C0001B6D add esp, 8
+cseg01:C0001B70 push offset aDevice_init__0 ; "Device_Init_proc success\n"
+cseg01:C0001B75 call sub_C0002A03
+cseg01:C0001B7A add esp, 4
+cseg01:C0001B7D mov ebp, ds:dword_C00007C8
+cseg01:C0001B83 push ebp
+cseg01:C0001B84 mov eax, ds:dword_C00007D4
+cseg01:C0001B89 push eax
+cseg01:C0001B8A push offset aXX ; " %X -> %X\n"
+cseg01:C0001B8F call sub_C0002A03
+cseg01:C0001B94 add esp, 0Ch
+cseg01:C0001B97 push 0
+cseg01:C0001B99 mov edx, ds:dword_C00007D8
+cseg01:C0001B9F push edx
+cseg01:C0001BA0 mov ecx, ds:dword_C00007D4
+cseg01:C0001BA6 push ecx
+cseg01:C0001BA7 call sub_C0001378
+cseg01:C0001BAC add esp, 0Ch
+cseg01:C0001BAF mov ds:dword_C00007D0, eax
+cseg01:C0001BB4 call sub_C0000B98
+cseg01:C0001BB9 test eax, eax
+cseg01:C0001BBB jnz short loc_C0001BD9
+cseg01:C0001BBD push eax
+cseg01:C0001BBE mov ebx, ds:dword_C00007BC
+cseg01:C0001BC4 push ebx
+cseg01:C0001BC5 mov esi, ds:dword_C00007C8
+cseg01:C0001BCB push esi
+cseg01:C0001BCC call sub_C0001378
+cseg01:C0001BD1 add esp, 0Ch
+cseg01:C0001BD4 mov ds:dword_C00007C0, eax
+cseg01:C0001BD9
+cseg01:C0001BD9 loc_C0001BD9: ; CODE XREF: sub_C00019F5+1C6j
+cseg01:C0001BD9 mov eax, ds:dword_C00007D0
+cseg01:C0001BDE mov ds:dword_C00007B8, eax
+cseg01:C0001BE3 call sub_C0000B98
+cseg01:C0001BE8 test eax, eax
+cseg01:C0001BEA jnz short loc_C0001BF6
+cseg01:C0001BEC mov eax, ds:dword_C00007C0
+cseg01:C0001BF1 mov ds:dword_C00007B4, eax
+cseg01:C0001BF6
+cseg01:C0001BF6 loc_C0001BF6: ; CODE XREF: sub_C00019F5+1F5j
+cseg01:C0001BF6 push offset aMemoryMapping ; "Memory mapping:\n"
+cseg01:C0001BFB call sub_C0002A03
+cseg01:C0001C00 add esp, 4
+cseg01:C0001C03 mov edi, ds:dword_C00007B8
+cseg01:C0001C09 push edi
+cseg01:C0001C0A mov ebp, ds:dword_C00007D4
+cseg01:C0001C10 push ebp
+cseg01:C0001C11 push offset aXX ; " %X -> %X\n"
+cseg01:C0001C16 call sub_C0002A03
+cseg01:C0001C1B add esp, 0Ch
+cseg01:C0001C1E mov eax, ds:dword_C00007B4
+cseg01:C0001C23 push eax
+cseg01:C0001C24 mov edx, ds:dword_C00007C8
+cseg01:C0001C2A push edx
+cseg01:C0001C2B push offset aXX ; " %X -> %X\n"
+cseg01:C0001C30 call sub_C0002A03
+cseg01:C0001C35 add esp, 0Ch
+cseg01:C0001C38 mov ecx, ds:dword_C0000800
+cseg01:C0001C3E push ecx
+cseg01:C0001C3F mov ebx, ds:dword_C00007F8
+cseg01:C0001C45 push ebx
+cseg01:C0001C46 push offset aXX ; " %X -> %X\n"
+cseg01:C0001C4B call sub_C0002A03
+cseg01:C0001C50 add esp, 0Ch
+cseg01:C0001C53 push 4
+cseg01:C0001C55 push 74h
+cseg01:C0001C57 push offset aSizeOfGsvga2DD ; "Size of gSVGA(2) = %d %d\n"
+cseg01:C0001C5C call sub_C0002A03
+cseg01:C0001C61 add esp, 0Ch
+cseg01:C0001C64 call sub_C0000BA8
+cseg01:C0001C69 push 11h
+cseg01:C0001C6B call sub_C0000C93
+cseg01:C0001C70 add esp, 4
+cseg01:C0001C73 test eax, 8000000h
+cseg01:C0001C78 jz short loc_C0001C96
+cseg01:C0001C7A call sub_C0001599
+cseg01:C0001C7F mov ds:dword_C00013A0, 1
+cseg01:C0001C89 push offset aGbSupportedAnd ; "GB supported and allocated\n"
+cseg01:C0001C8E call sub_C0002A03
+cseg01:C0001C93 add esp, 4
+cseg01:C0001C96
+cseg01:C0001C96 loc_C0001C96: ; CODE XREF: sub_C00019F5+283j
+cseg01:C0001C96 push 11h
+cseg01:C0001C98 call sub_C0000C93
+cseg01:C0001C9D add esp, 4
+cseg01:C0001CA0 test eax, 5000000h
+cseg01:C0001CA5 jz short loc_C0001CC5
+cseg01:C0001CA7 cmp [esp+24h+var_18], 0
+cseg01:C0001CAC jz short loc_C0001CC5
+cseg01:C0001CAE mov ds:dword_C00013A4, 1
+cseg01:C0001CB8 push offset aCbSupportedAnd ; "CB supported and allocated\n"
+cseg01:C0001CBD call sub_C0002A03
+cseg01:C0001CC2 add esp, 4
+cseg01:C0001CC5
+cseg01:C0001CC5 loc_C0001CC5: ; CODE XREF: sub_C00019F5+2B0j
+cseg01:C0001CC5 ; sub_C00019F5+2B7j
+cseg01:C0001CC5 call sub_C0001644
+cseg01:C0001CCA mov eax, ds:dword_C00010B4
+cseg01:C0001CCF mov ebx, ds:dword_C00007D0
+cseg01:C0001CD5 mov [eax+20h], ebx
+cseg01:C0001CD8 mov eax, ds:dword_C00010B4
+cseg01:C0001CDD mov ebx, ds:dword_C00007D8
+cseg01:C0001CE3 mov [eax+28h], ebx
+cseg01:C0001CE6 push 0Dh
+cseg01:C0001CE8 push offset aVmwsmini_vxd ; "vmwsmini.vxd"
+cseg01:C0001CED mov eax, ds:dword_C00010B4
+cseg01:C0001CF2 add eax, 2Ch
+cseg01:C0001CF5 push eax
+cseg01:C0001CF6 call sub_C0001222
+cseg01:C0001CFB add esp, 0Ch
+cseg01:C0001CFE call sub_C0001714
+cseg01:C0001D03 mov ds:dword_C0001400, eax
+cseg01:C0001D08 mov eax, 1
+cseg01:C0001D0D mov ds:dword_C00013AC, eax
+cseg01:C0001D12 jmp short loc_C0001D16
+cseg01:C0001D14 ; ---------------------------------------------------------------------------
+cseg01:C0001D14
+cseg01:C0001D14 loc_C0001D14: ; CODE XREF: sub_C00019F5+BAj
+cseg01:C0001D14 xor eax, eax
+cseg01:C0001D16
+cseg01:C0001D16 loc_C0001D16: ; CODE XREF: sub_C00019F5+84j
+cseg01:C0001D16 ; sub_C00019F5+31Dj
+cseg01:C0001D16 add esp, 14h
+cseg01:C0001D19 pop ebp
+cseg01:C0001D1A pop edi
+cseg01:C0001D1B pop esi
+cseg01:C0001D1C pop ebx
+cseg01:C0001D1D retn
+cseg01:C0001D1D sub_C00019F5 endp
+cseg01:C0001D1D
+cseg01:C0001D1E
+cseg01:C0001D1E ; =============== S U B R O U T I N E =======================================
+cseg01:C0001D1E
+cseg01:C0001D1E
+cseg01:C0001D1E sub_C0001D1E proc near ; CODE XREF: sub_C0001D48+C2p
+cseg01:C0001D1E ; sub_C0001D48+E7p ...
+cseg01:C0001D1E
+cseg01:C0001D1E var_4 = dword ptr -4
+cseg01:C0001D1E arg_0 = dword ptr 4
+cseg01:C0001D1E
+cseg01:C0001D1E sub esp, 4
+cseg01:C0001D21 xor eax, eax
+cseg01:C0001D23 mov [esp+4+var_4], eax
+cseg01:C0001D26 push eax
+cseg01:C0001D27 lea eax, [esp+8+var_4]
+cseg01:C0001D2B push eax
+cseg01:C0001D2C push 1
+cseg01:C0001D2E mov eax, [esp+10h+arg_0]
+cseg01:C0001D32 shr eax, 0Ch
+cseg01:C0001D35 push eax
+cseg01:C0001D36 call sub_C0001366
+cseg01:C0001D3B add esp, 10h
+cseg01:C0001D3E mov eax, [esp+4+var_4]
+cseg01:C0001D41 shr eax, 0Ch
+cseg01:C0001D44 add esp, 4
+cseg01:C0001D47 retn
+cseg01:C0001D47 sub_C0001D1E endp
+cseg01:C0001D47
+cseg01:C0001D48
+cseg01:C0001D48 ; =============== S U B R O U T I N E =======================================
+cseg01:C0001D48
+cseg01:C0001D48
+cseg01:C0001D48 sub_C0001D48 proc near ; CODE XREF: sub_C000055F+1C5p
+cseg01:C0001D48
+cseg01:C0001D48 var_34 = dword ptr -34h
+cseg01:C0001D48 var_30 = dword ptr -30h
+cseg01:C0001D48 var_2C = dword ptr -2Ch
+cseg01:C0001D48 var_28 = dword ptr -28h
+cseg01:C0001D48 var_24 = dword ptr -24h
+cseg01:C0001D48 var_20 = dword ptr -20h
+cseg01:C0001D48 var_1C = dword ptr -1Ch
+cseg01:C0001D48 var_18 = dword ptr -18h
+cseg01:C0001D48 var_14 = dword ptr -14h
+cseg01:C0001D48 arg_0 = dword ptr 4
+cseg01:C0001D48
+cseg01:C0001D48 push ebx
+cseg01:C0001D49 push esi
+cseg01:C0001D4A push edi
+cseg01:C0001D4B push ebp
+cseg01:C0001D4C sub esp, 24h
+cseg01:C0001D4F mov eax, [esp+34h+arg_0]
+cseg01:C0001D53 mov eax, [eax+4]
+cseg01:C0001D56 add eax, 0FFFh
+cseg01:C0001D5B shr eax, 0Ch
+cseg01:C0001D5E mov [esp+34h+var_14], eax
+cseg01:C0001D62 push 0Eh
+cseg01:C0001D64 lea eax, [esp+38h+var_34]
+cseg01:C0001D68 push eax
+cseg01:C0001D69 push 100000h
+cseg01:C0001D6E push 0
+cseg01:C0001D70 push 0
+cseg01:C0001D72 push 0
+cseg01:C0001D74 push 1
+cseg01:C0001D76 mov eax, [esp+50h+var_14]
+cseg01:C0001D7A inc eax
+cseg01:C0001D7B push eax
+cseg01:C0001D7C call sub_C000135A
+cseg01:C0001D81 add esp, 20h
+cseg01:C0001D84 test eax, eax
+cseg01:C0001D86 jz short loc_C0001DD7
+cseg01:C0001D88 mov edx, [esp+34h+var_34]
+cseg01:C0001D8B shr edx, 0Ch
+cseg01:C0001D8E inc edx
+cseg01:C0001D8F mov [eax], edx
+cseg01:C0001D91 mov edx, [esp+34h+var_14]
+cseg01:C0001D95 mov [eax+4], edx
+cseg01:C0001D98 lea ebx, [eax+8]
+cseg01:C0001D9B mov dword ptr [ebx], 0
+cseg01:C0001DA1 mov dword ptr [ebx+4], 0
+cseg01:C0001DA8 add eax, 1000h
+cseg01:C0001DAD mov edx, [esp+34h+arg_0]
+cseg01:C0001DB1 mov [edx+8], eax
+cseg01:C0001DB4 mov dword ptr [edx+0Ch], 0
+cseg01:C0001DBB mov eax, [esp+34h+var_34]
+cseg01:C0001DBE shr eax, 0Ch
+cseg01:C0001DC1 mov [edx+10h], eax
+cseg01:C0001DC4 mov dword ptr [edx+14h], 0
+cseg01:C0001DCB mov eax, [esp+34h+var_34]
+cseg01:C0001DCE shr eax, 0Ch
+cseg01:C0001DD1 inc eax
+cseg01:C0001DD2 jmp loc_C000201D
+cseg01:C0001DD7 ; ---------------------------------------------------------------------------
+cseg01:C0001DD7
+cseg01:C0001DD7 loc_C0001DD7: ; CODE XREF: sub_C0001D48+3Ej
+cseg01:C0001DD7 mov ebp, 1
+cseg01:C0001DDC mov [esp+34h+var_20], eax
+cseg01:C0001DE0 mov [esp+34h+var_30], eax
+cseg01:C0001DE4 push 8
+cseg01:C0001DE6 push eax
+cseg01:C0001DE7 push 100000h
+cseg01:C0001DEC push eax
+cseg01:C0001DED push eax
+cseg01:C0001DEE push eax
+cseg01:C0001DEF push ebp
+cseg01:C0001DF0 mov ecx, [esp+50h+var_14]
+cseg01:C0001DF4 push ecx
+cseg01:C0001DF5 call sub_C000135A
+cseg01:C0001DFA add esp, 20h
+cseg01:C0001DFD mov [esp+34h+var_18], eax
+cseg01:C0001E01 test eax, eax
+cseg01:C0001E03 jz loc_C000204D
+cseg01:C0001E09 push eax
+cseg01:C0001E0A call sub_C0001D1E
+cseg01:C0001E0F add esp, 4
+cseg01:C0001E12 mov edi, eax
+cseg01:C0001E14 mov ebx, ebp
+cseg01:C0001E16 mov esi, ebp
+cseg01:C0001E18
+cseg01:C0001E18 loc_C0001E18: ; CODE XREF: sub_C0001D48+105j
+cseg01:C0001E18 lea eax, [ebp+1]
+cseg01:C0001E1B mov [esp+34h+var_24], eax
+cseg01:C0001E1F cmp esi, [esp+34h+var_14]
+cseg01:C0001E23 jnb short loc_C0001E4F
+cseg01:C0001E25 mov eax, esi
+cseg01:C0001E27 shl eax, 0Ch
+cseg01:C0001E2A add eax, [esp+34h+var_18]
+cseg01:C0001E2E push eax
+cseg01:C0001E2F call sub_C0001D1E
+cseg01:C0001E34 add esp, 4
+cseg01:C0001E37 lea edx, [edi+ebx]
+cseg01:C0001E3A cmp eax, edx
+cseg01:C0001E3C jz short loc_C0001E4B
+cseg01:C0001E3E mov edi, eax
+cseg01:C0001E40 mov ebx, 1
+cseg01:C0001E45 mov ebp, [esp+34h+var_24]
+cseg01:C0001E49 jmp short loc_C0001E4C
+cseg01:C0001E4B ; ---------------------------------------------------------------------------
+cseg01:C0001E4B
+cseg01:C0001E4B loc_C0001E4B: ; CODE XREF: sub_C0001D48+F4j
+cseg01:C0001E4B inc ebx
+cseg01:C0001E4C
+cseg01:C0001E4C loc_C0001E4C: ; CODE XREF: sub_C0001D48+101j
+cseg01:C0001E4C inc esi
+cseg01:C0001E4D jmp short loc_C0001E18
+cseg01:C0001E4F ; ---------------------------------------------------------------------------
+cseg01:C0001E4F
+cseg01:C0001E4F loc_C0001E4F: ; CODE XREF: sub_C0001D48+DBj
+cseg01:C0001E4F shr eax, 9
+cseg01:C0001E52 inc eax
+cseg01:C0001E53 add eax, ebp
+cseg01:C0001E55 inc eax
+cseg01:C0001E56 shr eax, 9
+cseg01:C0001E59 inc eax
+cseg01:C0001E5A push 8
+cseg01:C0001E5C push 0
+cseg01:C0001E5E push 100000h
+cseg01:C0001E63 push 0
+cseg01:C0001E65 push 0
+cseg01:C0001E67 push 0
+cseg01:C0001E69 push 1
+cseg01:C0001E6B push eax
+cseg01:C0001E6C call sub_C000135A
+cseg01:C0001E71 mov esi, eax
+cseg01:C0001E73 add esp, 20h
+cseg01:C0001E76 mov [esp+34h+var_2C], eax
+cseg01:C0001E7A test eax, eax
+cseg01:C0001E7C jnz short loc_C0001E93
+cseg01:C0001E7E push eax
+cseg01:C0001E7F mov ecx, [esp+38h+var_18]
+cseg01:C0001E83 push ecx
+cseg01:C0001E84
+cseg01:C0001E84 loc_C0001E84: ; CODE XREF: sub_C0001D48+23Dj
+cseg01:C0001E84 call sub_C0001360
+cseg01:C0001E89 add esp, 8
+cseg01:C0001E8C xor eax, eax
+cseg01:C0001E8E jmp loc_C000204D
+cseg01:C0001E93 ; ---------------------------------------------------------------------------
+cseg01:C0001E93
+cseg01:C0001E93 loc_C0001E93: ; CODE XREF: sub_C0001D48+134j
+cseg01:C0001E93 mov ebx, eax
+cseg01:C0001E95 mov edx, [esp+34h+var_18]
+cseg01:C0001E99 push edx
+cseg01:C0001E9A call sub_C0001D1E
+cseg01:C0001E9F add esp, 4
+cseg01:C0001EA2 mov [esi], eax
+cseg01:C0001EA4 mov dword ptr [esi+4], 1
+cseg01:C0001EAB mov ebp, 1
+cseg01:C0001EB0 mov esi, ebp
+cseg01:C0001EB2
+cseg01:C0001EB2 loc_C0001EB2: ; CODE XREF: sub_C0001D48+1DDj
+cseg01:C0001EB2 lea edi, [ebx+8]
+cseg01:C0001EB5 mov ecx, [esp+34h+var_14]
+cseg01:C0001EB9 cmp esi, ecx
+cseg01:C0001EBB jnb short loc_C0001F27
+cseg01:C0001EBD mov eax, esi
+cseg01:C0001EBF shl eax, 0Ch
+cseg01:C0001EC2 add eax, [esp+34h+var_18]
+cseg01:C0001EC6 push eax
+cseg01:C0001EC7 call sub_C0001D1E
+cseg01:C0001ECC mov edx, eax
+cseg01:C0001ECE add esp, 4
+cseg01:C0001ED1 mov [esp+34h+var_28], eax
+cseg01:C0001ED5 mov eax, [ebx]
+cseg01:C0001ED7 mov ecx, [ebx+4]
+cseg01:C0001EDA add eax, ecx
+cseg01:C0001EDC cmp edx, eax
+cseg01:C0001EDE jnz short loc_C0001EE8
+cseg01:C0001EE0 lea edi, [ecx+1]
+cseg01:C0001EE3 mov [ebx+4], edi
+cseg01:C0001EE6 jmp short loc_C0001F24
+cseg01:C0001EE8 ; ---------------------------------------------------------------------------
+cseg01:C0001EE8
+cseg01:C0001EE8 loc_C0001EE8: ; CODE XREF: sub_C0001D48+196j
+cseg01:C0001EE8 lea eax, [ebp+1]
+cseg01:C0001EEB mov [esp+34h+var_1C], eax
+cseg01:C0001EEF test word ptr [esp+34h+var_1C], 1FFh
+cseg01:C0001EF6 jnz short loc_C0001F13
+cseg01:C0001EF8 mov ebx, edi
+cseg01:C0001EFA mov dword ptr [edi+4], 0
+cseg01:C0001F01 lea eax, [edi+8]
+cseg01:C0001F04 push eax
+cseg01:C0001F05 call sub_C0001D1E
+cseg01:C0001F0A add esp, 4
+cseg01:C0001F0D mov [edi], eax
+cseg01:C0001F0F mov ebp, [esp+34h+var_1C]
+cseg01:C0001F13
+cseg01:C0001F13 loc_C0001F13: ; CODE XREF: sub_C0001D48+1AEj
+cseg01:C0001F13 add ebx, 8
+cseg01:C0001F16 mov eax, [esp+34h+var_28]
+cseg01:C0001F1A mov [ebx], eax
+cseg01:C0001F1C mov dword ptr [ebx+4], 1
+cseg01:C0001F23 inc ebp
+cseg01:C0001F24
+cseg01:C0001F24 loc_C0001F24: ; CODE XREF: sub_C0001D48+19Ej
+cseg01:C0001F24 inc esi
+cseg01:C0001F25 jmp short loc_C0001EB2
+cseg01:C0001F27 ; ---------------------------------------------------------------------------
+cseg01:C0001F27
+cseg01:C0001F27 loc_C0001F27: ; CODE XREF: sub_C0001D48+173j
+cseg01:C0001F27 mov dword ptr [edi], 0
+cseg01:C0001F2D mov dword ptr [edi+4], 0
+cseg01:C0001F34 cmp ds:dword_C00013A0, 0
+cseg01:C0001F3B jz loc_C0001FE2
+cseg01:C0001F41 push 0Eh
+cseg01:C0001F43 lea eax, [esp+38h+var_30]
+cseg01:C0001F47 push eax
+cseg01:C0001F48 push 100000h
+cseg01:C0001F4D push 0
+cseg01:C0001F4F push 0
+cseg01:C0001F51 push 0
+cseg01:C0001F53 push 1
+cseg01:C0001F55 lea eax, [ecx+3FFh]
+cseg01:C0001F5B shr eax, 0Ah
+cseg01:C0001F5E inc eax
+cseg01:C0001F5F push eax
+cseg01:C0001F60 call sub_C000135A
+cseg01:C0001F65 add esp, 20h
+cseg01:C0001F68 mov [esp+34h+var_20], eax
+cseg01:C0001F6C test eax, eax
+cseg01:C0001F6E jnz short loc_C0001F8A
+cseg01:C0001F70 push eax
+cseg01:C0001F71 mov esi, [esp+38h+var_18]
+cseg01:C0001F75 push esi
+cseg01:C0001F76 call sub_C0001360
+cseg01:C0001F7B add esp, 8
+cseg01:C0001F7E push 0
+cseg01:C0001F80 mov edi, [esp+38h+var_2C]
+cseg01:C0001F84 push edi
+cseg01:C0001F85 jmp loc_C0001E84
+cseg01:C0001F8A ; ---------------------------------------------------------------------------
+cseg01:C0001F8A
+cseg01:C0001F8A loc_C0001F8A: ; CODE XREF: sub_C0001D48+226j
+cseg01:C0001F8A xor ebx, ebx
+cseg01:C0001F8C
+cseg01:C0001F8C loc_C0001F8C: ; CODE XREF: sub_C0001D48+26Aj
+cseg01:C0001F8C mov eax, [esp+34h+var_14]
+cseg01:C0001F90 add eax, 3FFh
+cseg01:C0001F95 shr eax, 0Ah
+cseg01:C0001F98 cmp ebx, eax
+cseg01:C0001F9A jnb short loc_C0001FB4
+cseg01:C0001F9C mov edx, [esp+34h+var_30]
+cseg01:C0001FA0 shr edx, 0Ch
+cseg01:C0001FA3 add edx, ebx
+cseg01:C0001FA5 mov eax, ebx
+cseg01:C0001FA7 shl eax, 2
+cseg01:C0001FAA add eax, [esp+34h+var_20]
+cseg01:C0001FAE inc edx
+cseg01:C0001FAF mov [eax], edx
+cseg01:C0001FB1 inc ebx
+cseg01:C0001FB2 jmp short loc_C0001F8C
+cseg01:C0001FB4 ; ---------------------------------------------------------------------------
+cseg01:C0001FB4
+cseg01:C0001FB4 loc_C0001FB4: ; CODE XREF: sub_C0001D48+252j
+cseg01:C0001FB4 xor ebx, ebx
+cseg01:C0001FB6
+cseg01:C0001FB6 loc_C0001FB6: ; CODE XREF: sub_C0001D48+298j
+cseg01:C0001FB6 cmp ebx, [esp+34h+var_14]
+cseg01:C0001FBA jnb short loc_C0001FE2
+cseg01:C0001FBC mov eax, ebx
+cseg01:C0001FBE shl eax, 0Ch
+cseg01:C0001FC1 add eax, [esp+34h+var_18]
+cseg01:C0001FC5 push eax
+cseg01:C0001FC6 call sub_C0001D1E
+cseg01:C0001FCB mov edx, eax
+cseg01:C0001FCD add esp, 4
+cseg01:C0001FD0 mov eax, ebx
+cseg01:C0001FD2 shl eax, 2
+cseg01:C0001FD5 add eax, [esp+34h+var_20]
+cseg01:C0001FD9 mov [eax+1000h], edx
+cseg01:C0001FDF inc ebx
+cseg01:C0001FE0 jmp short loc_C0001FB6
+cseg01:C0001FE2 ; ---------------------------------------------------------------------------
+cseg01:C0001FE2
+cseg01:C0001FE2 loc_C0001FE2: ; CODE XREF: sub_C0001D48+1F3j
+cseg01:C0001FE2 ; sub_C0001D48+272j
+cseg01:C0001FE2 mov eax, [esp+34h+var_18]
+cseg01:C0001FE6 mov edx, [esp+34h+arg_0]
+cseg01:C0001FEA mov [edx+8], eax
+cseg01:C0001FED mov eax, [esp+34h+var_2C]
+cseg01:C0001FF1 mov [edx+0Ch], eax
+cseg01:C0001FF4 push eax
+cseg01:C0001FF5 call sub_C0001D1E
+cseg01:C0001FFA add esp, 4
+cseg01:C0001FFD mov edx, [esp+34h+arg_0]
+cseg01:C0002001 mov [edx+10h], eax
+cseg01:C0002004 mov eax, [esp+34h+var_20]
+cseg01:C0002008 mov [edx+14h], eax
+cseg01:C000200B mov dword ptr [edx+18h], 0
+cseg01:C0002012 test eax, eax
+cseg01:C0002014 jz short loc_C0002020
+cseg01:C0002016 mov eax, [esp+34h+var_30]
+cseg01:C000201A shr eax, 0Ch
+cseg01:C000201D
+cseg01:C000201D loc_C000201D: ; CODE XREF: sub_C0001D48+8Aj
+cseg01:C000201D mov [edx+18h], eax
+cseg01:C0002020
+cseg01:C0002020 loc_C0002020: ; CODE XREF: sub_C0001D48+2CCj
+cseg01:C0002020 call sub_C0000D7D
+cseg01:C0002025 mov eax, [esp+34h+arg_0]
+cseg01:C0002029 mov edi, [eax]
+cseg01:C000202B push edi
+cseg01:C000202C push 29h
+cseg01:C000202E call sub_C0000CD3
+cseg01:C0002033 add esp, 8
+cseg01:C0002036 mov eax, [esp+34h+arg_0]
+cseg01:C000203A mov ebp, [eax+10h]
+cseg01:C000203D push ebp
+cseg01:C000203E push 2Ah
+cseg01:C0002040 call sub_C0000CD3
+cseg01:C0002045 add esp, 8
+cseg01:C0002048 mov eax, 1
+cseg01:C000204D
+cseg01:C000204D loc_C000204D: ; CODE XREF: sub_C0001D48+BBj
+cseg01:C000204D ; sub_C0001D48+146j
+cseg01:C000204D add esp, 24h
+cseg01:C0002050 pop ebp
+cseg01:C0002051 pop edi
+cseg01:C0002052 pop esi
+cseg01:C0002053 pop ebx
+cseg01:C0002054 retn
+cseg01:C0002054 sub_C0001D48 endp
+cseg01:C0002054
+cseg01:C0002055
+cseg01:C0002055 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002055
+cseg01:C0002055
+cseg01:C0002055 sub_C0002055 proc near ; CODE XREF: sub_C000055F+1D0p
+cseg01:C0002055
+cseg01:C0002055 arg_0 = dword ptr 4
+cseg01:C0002055
+cseg01:C0002055 push ebx
+cseg01:C0002056 push esi
+cseg01:C0002057 push edi
+cseg01:C0002058 mov ebx, [esp+0Ch+arg_0]
+cseg01:C000205C mov esi, [ebx+8]
+cseg01:C000205F call sub_C0000D7D
+cseg01:C0002064 mov eax, [ebx]
+cseg01:C0002066 push eax
+cseg01:C0002067 push 29h
+cseg01:C0002069 call sub_C0000CD3
+cseg01:C000206E add esp, 8
+cseg01:C0002071 push 0
+cseg01:C0002073 push 2Ah
+cseg01:C0002075 call sub_C0000CD3
+cseg01:C000207A add esp, 8
+cseg01:C000207D call sub_C0000D7D
+cseg01:C0002082 mov edx, [ebx+0Ch]
+cseg01:C0002085 test edx, edx
+cseg01:C0002087 jz short loc_C0002096
+cseg01:C0002089 push 0
+cseg01:C000208B push edx
+cseg01:C000208C call sub_C0001360
+cseg01:C0002091 add esp, 8
+cseg01:C0002094 jmp short loc_C000209C
+cseg01:C0002096 ; ---------------------------------------------------------------------------
+cseg01:C0002096
+cseg01:C0002096 loc_C0002096: ; CODE XREF: sub_C0002055+32j
+cseg01:C0002096 sub esi, 1000h
+cseg01:C000209C
+cseg01:C000209C loc_C000209C: ; CODE XREF: sub_C0002055+3Fj
+cseg01:C000209C mov edi, [ebx+10h]
+cseg01:C000209F test edi, edi
+cseg01:C00020A1 jz short loc_C00020AE
+cseg01:C00020A3 push 0
+cseg01:C00020A5 push edi
+cseg01:C00020A6 call sub_C0001360
+cseg01:C00020AB add esp, 8
+cseg01:C00020AE
+cseg01:C00020AE loc_C00020AE: ; CODE XREF: sub_C0002055+4Cj
+cseg01:C00020AE push 0
+cseg01:C00020B0 push esi
+cseg01:C00020B1 call sub_C0001360
+cseg01:C00020B6 add esp, 8
+cseg01:C00020B9 mov dword ptr [ebx+8], 0
+cseg01:C00020C0 mov dword ptr [ebx+0Ch], 0
+cseg01:C00020C7 mov dword ptr [ebx+14h], 0
+cseg01:C00020CE mov dword ptr [ebx+10h], 0
+cseg01:C00020D5 mov dword ptr [ebx+18h], 0
+cseg01:C00020DC pop edi
+cseg01:C00020DD pop esi
+cseg01:C00020DE pop ebx
+cseg01:C00020DF retn
+cseg01:C00020DF sub_C0002055 endp
+cseg01:C00020DF
+cseg01:C00020E0
+cseg01:C00020E0 ; =============== S U B R O U T I N E =======================================
+cseg01:C00020E0
+cseg01:C00020E0
+cseg01:C00020E0 sub_C00020E0 proc near ; CODE XREF: sub_C0002353+27p
+cseg01:C00020E0 ; sub_C0002620p
+cseg01:C00020E0 push ebx
+cseg01:C00020E1 xor eax, eax
+cseg01:C00020E3 mov ds:dword_C00013A8, eax
+cseg01:C00020E8 cmp ds:dword_C00013A4, 0
+cseg01:C00020EF jz short loc_C0002139
+cseg01:C00020F1 mov ebx, ds:dword_C0001400
+cseg01:C00020F7 push 4Ch
+cseg01:C00020F9 push eax
+cseg01:C00020FA push ebx
+cseg01:C00020FB call sub_C00011BA
+cseg01:C0002100 add esp, 0Ch
+cseg01:C0002103 mov dword ptr [ebx+14h], 0Ch
+cseg01:C000210A mov dword ptr [ebx+40h], 1
+cseg01:C0002111 mov dword ptr [ebx+44h], 0
+cseg01:C0002118 mov dword ptr [ebx+48h], 0
+cseg01:C000211F push 0
+cseg01:C0002121 push 0C0000000h
+cseg01:C0002126 push 0
+cseg01:C0002128 push 4Ch
+cseg01:C000212A mov ecx, ds:dword_C0001400
+cseg01:C0002130 push ecx
+cseg01:C0002131 call sub_C00017FE
+cseg01:C0002136 add esp, 14h
+cseg01:C0002139
+cseg01:C0002139 loc_C0002139: ; CODE XREF: sub_C00020E0+Fj
+cseg01:C0002139 pop ebx
+cseg01:C000213A retn
+cseg01:C000213A sub_C00020E0 endp
+cseg01:C000213A
+cseg01:C000213B
+cseg01:C000213B ; =============== S U B R O U T I N E =======================================
+cseg01:C000213B
+cseg01:C000213B
+cseg01:C000213B sub_C000213B proc near ; CODE XREF: sub_C0002353+49p
+cseg01:C000213B push 280h
+cseg01:C0002140 call sub_C0000D34
+cseg01:C0002145 add esp, 4
+cseg01:C0002148 test eax, eax
+cseg01:C000214A setnz al
+cseg01:C000214D movzx eax, al
+cseg01:C0002150 retn
+cseg01:C0002150 sub_C000213B endp
+cseg01:C0002150
+cseg01:C0002151
+cseg01:C0002151 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002151
+cseg01:C0002151
+cseg01:C0002151 sub_C0002151 proc near ; CODE XREF: sub_C0002353+44p
+cseg01:C0002151
+cseg01:C0002151 ; FUNCTION CHUNK AT cseg01:C0002183 SIZE 00000006 BYTES
+cseg01:C0002151
+cseg01:C0002151 push 100h
+cseg01:C0002156 call sub_C0000D34
+cseg01:C000215B add esp, 4
+cseg01:C000215E test eax, eax
+cseg01:C0002160 jz short loc_C000216C
+cseg01:C0002162 mov eax, ds:dword_C00007B4
+cseg01:C0002167 mov eax, [eax+44h]
+cseg01:C000216A jmp short loc_C0002174
+cseg01:C000216C ; ---------------------------------------------------------------------------
+cseg01:C000216C
+cseg01:C000216C loc_C000216C: ; CODE XREF: sub_C0002151+Fj
+cseg01:C000216C mov eax, ds:dword_C00007B4
+cseg01:C0002171 mov eax, [eax+1Ch]
+cseg01:C0002174
+cseg01:C0002174 loc_C0002174: ; CODE XREF: sub_C0002151+19j
+cseg01:C0002174 test eax, eax
+cseg01:C0002176 jnz short loc_C0002179
+cseg01:C0002178 retn
+cseg01:C0002179 ; ---------------------------------------------------------------------------
+cseg01:C0002179
+cseg01:C0002179 loc_C0002179: ; CODE XREF: sub_C0002151+25j
+cseg01:C0002179 cmp eax, 20000h
+cseg01:C000217E jge short loc_C0002183
+cseg01:C000217E sub_C0002151 endp
+cseg01:C000217E
+cseg01:C0002180
+cseg01:C0002180 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002180
+cseg01:C0002180
+cseg01:C0002180 sub_C0002180 proc near ; CODE XREF: sub_C000037B+DCp
+cseg01:C0002180 ; sub_C000055F+12Dp
+cseg01:C0002180 xor eax, eax
+cseg01:C0002182 retn
+cseg01:C0002182 sub_C0002180 endp
+cseg01:C0002182
+cseg01:C0002183 ; ---------------------------------------------------------------------------
+cseg01:C0002183 ; START OF FUNCTION CHUNK FOR sub_C0002151
+cseg01:C0002183
+cseg01:C0002183 loc_C0002183: ; CODE XREF: sub_C0002151+2Dj
+cseg01:C0002183 mov eax, 1
+cseg01:C0002188 retn
+cseg01:C0002188 ; END OF FUNCTION CHUNK FOR sub_C0002151
+cseg01:C0002189
+cseg01:C0002189 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002189
+cseg01:C0002189
+cseg01:C0002189 sub_C0002189 proc near ; CODE XREF: sub_C00021C7+7Ap
+cseg01:C0002189 ; sub_C00021C7+C9p ...
+cseg01:C0002189
+cseg01:C0002189 arg_0 = dword ptr 4
+cseg01:C0002189 arg_4 = dword ptr 8
+cseg01:C0002189
+cseg01:C0002189 mov eax, [esp+arg_4]
+cseg01:C000218D add eax, 7
+cseg01:C0002190 shr eax, 3
+cseg01:C0002193 imul eax, [esp+arg_0]
+cseg01:C0002198 add eax, 3
+cseg01:C000219B and al, 0FCh
+cseg01:C000219D retn
+cseg01:C000219D sub_C0002189 endp
+cseg01:C000219D
+cseg01:C000219E
+cseg01:C000219E ; =============== S U B R O U T I N E =======================================
+cseg01:C000219E
+cseg01:C000219E
+cseg01:C000219E sub_C000219E proc near ; CODE XREF: sub_C00021C7+1Fp
+cseg01:C000219E ; sub_C00021C7+A8p ...
+cseg01:C000219E
+cseg01:C000219E arg_0 = dword ptr 4
+cseg01:C000219E arg_4 = dword ptr 8
+cseg01:C000219E arg_8 = dword ptr 0Ch
+cseg01:C000219E arg_C = dword ptr 10h
+cseg01:C000219E
+cseg01:C000219E push ebx
+cseg01:C000219F mov edx, [esp+4+arg_4]
+cseg01:C00021A3 mov eax, [edx]
+cseg01:C00021A5 shr eax, 2
+cseg01:C00021A8 shl eax, 2
+cseg01:C00021AB add eax, [esp+4+arg_0]
+cseg01:C00021AF mov ecx, [esp+4+arg_8]
+cseg01:C00021B3 mov [eax], ecx
+cseg01:C00021B5 mov ecx, [edx]
+cseg01:C00021B7 add ecx, 4
+cseg01:C00021BA mov ebx, [esp+4+arg_C]
+cseg01:C00021BE add ebx, ecx
+cseg01:C00021C0 mov [edx], ebx
+cseg01:C00021C2 add eax, 4
+cseg01:C00021C5 pop ebx
+cseg01:C00021C6 retn
+cseg01:C00021C6 sub_C000219E endp
+cseg01:C00021C6
+cseg01:C00021C7
+cseg01:C00021C7 ; =============== S U B R O U T I N E =======================================
+cseg01:C00021C7
+cseg01:C00021C7
+cseg01:C00021C7 sub_C00021C7 proc near ; CODE XREF: sub_C0002353+59p
+cseg01:C00021C7
+cseg01:C00021C7 var_10 = dword ptr -10h
+cseg01:C00021C7 arg_0 = dword ptr 4
+cseg01:C00021C7 arg_4 = dword ptr 8
+cseg01:C00021C7 arg_8 = dword ptr 0Ch
+cseg01:C00021C7
+cseg01:C00021C7 push ebx
+cseg01:C00021C8 push esi
+cseg01:C00021C9 push edi
+cseg01:C00021CA sub esp, 4
+cseg01:C00021CD mov edi, [esp+10h+arg_8]
+cseg01:C00021D1 xor eax, eax
+cseg01:C00021D3 mov [esp+10h+var_10], eax
+cseg01:C00021D6 push 2Ch
+cseg01:C00021D8 push 22h
+cseg01:C00021DA lea eax, [esp+18h+var_10]
+cseg01:C00021DE push eax
+cseg01:C00021DF mov edx, ds:dword_C0001400
+cseg01:C00021E5 push edx
+cseg01:C00021E6 call sub_C000219E
+cseg01:C00021EB mov ebx, eax
+cseg01:C00021ED add esp, 10h
+cseg01:C00021F0 mov esi, eax
+cseg01:C00021F2 push 2Ch
+cseg01:C00021F4 push 0
+cseg01:C00021F6 push eax
+cseg01:C00021F7 call sub_C00011BA
+cseg01:C00021FC add esp, 0Ch
+cseg01:C00021FF mov dword ptr [ebx], 2Ch
+cseg01:C0002205 mov dword ptr [ebx+4], 0
+cseg01:C000220C mov dword ptr [ebx+8], 3
+cseg01:C0002213 mov eax, [esp+10h+arg_0]
+cseg01:C0002217 mov [ebx+0Ch], eax
+cseg01:C000221A mov eax, [esp+10h+arg_4]
+cseg01:C000221E mov [ebx+10h], eax
+cseg01:C0002221 mov dword ptr [ebx+14h], 0
+cseg01:C0002228 mov dword ptr [ebx+18h], 0
+cseg01:C000222F mov dword ptr [ebx+28h], 0
+cseg01:C0002236 cmp edi, 20h
+cseg01:C0002239 jnb short loc_C000224C
+cseg01:C000223B push edi
+cseg01:C000223C mov ecx, [esp+14h+arg_0]
+cseg01:C0002240 push ecx
+cseg01:C0002241 call sub_C0002189
+cseg01:C0002246 add esp, 8
+cseg01:C0002249 mov [ebx+24h], eax
+cseg01:C000224C
+cseg01:C000224C loc_C000224C: ; CODE XREF: sub_C00021C7+72j
+cseg01:C000224C mov dword ptr [esi+20h], 0
+cseg01:C0002253 mov dword ptr [esi+1Ch], 0FFFFFFFEh
+cseg01:C000225A cmp edi, 0Fh
+cseg01:C000225D jb short loc_C00022C1
+cseg01:C000225F push 10h
+cseg01:C0002261 push 24h
+cseg01:C0002263 lea eax, [esp+18h+var_10]
+cseg01:C0002267 push eax
+cseg01:C0002268 mov ebx, ds:dword_C0001400
+cseg01:C000226E push ebx
+cseg01:C000226F call sub_C000219E
+cseg01:C0002274 mov ebx, eax
+cseg01:C0002276 add esp, 10h
+cseg01:C0002279 test eax, eax
+cseg01:C000227B jz short loc_C00022C1
+cseg01:C000227D mov dword ptr [eax], 0FFFFFFFEh
+cseg01:C0002283 mov dword ptr [eax+4], 0
+cseg01:C000228A push edi
+cseg01:C000228B mov esi, [esp+14h+arg_0]
+cseg01:C000228F push esi
+cseg01:C0002290 call sub_C0002189
+cseg01:C0002295 add esp, 8
+cseg01:C0002298 mov [ebx+8], eax
+cseg01:C000229B mov eax, edi
+cseg01:C000229D and eax, 0FFh
+cseg01:C00022A2 mov byte ptr [ebx+0Dh], 0
+cseg01:C00022A6 shl eax, 8
+cseg01:C00022A9 or [ebx+0Ch], eax
+cseg01:C00022AC cmp edi, 18h
+cseg01:C00022AF jb short loc_C00022BA
+cseg01:C00022B1 mov dword ptr [ebx+0Ch], 1820h
+cseg01:C00022B8 jmp short loc_C00022C1
+cseg01:C00022BA ; ---------------------------------------------------------------------------
+cseg01:C00022BA
+cseg01:C00022BA loc_C00022BA: ; CODE XREF: sub_C00021C7+E8j
+cseg01:C00022BA mov dword ptr [ebx+0Ch], 1010h
+cseg01:C00022C1
+cseg01:C00022C1 loc_C00022C1: ; CODE XREF: sub_C00021C7+96j
+cseg01:C00022C1 ; sub_C00021C7+B4j ...
+cseg01:C00022C1 push 0
+cseg01:C00022C3 push 60000000h
+cseg01:C00022C8 push 0
+cseg01:C00022CA mov eax, [esp+1Ch+var_10]
+cseg01:C00022CE push eax
+cseg01:C00022CF mov edx, ds:dword_C0001400
+cseg01:C00022D5 push edx
+cseg01:C00022D6 call sub_C00017FE
+cseg01:C00022DB add esp, 14h
+cseg01:C00022DE add esp, 4
+cseg01:C00022E1 pop edi
+cseg01:C00022E2 pop esi
+cseg01:C00022E3 pop ebx
+cseg01:C00022E4 retn
+cseg01:C00022E4 sub_C00021C7 endp
+cseg01:C00022E4
+cseg01:C00022E5
+cseg01:C00022E5 ; =============== S U B R O U T I N E =======================================
+cseg01:C00022E5
+cseg01:C00022E5
+cseg01:C00022E5 sub_C00022E5 proc near ; CODE XREF: sub_C000037B+14Ep
+cseg01:C00022E5 ; sub_C0002353+12p
+cseg01:C00022E5
+cseg01:C00022E5 arg_0 = dword ptr 4
+cseg01:C00022E5 arg_4 = dword ptr 8
+cseg01:C00022E5 arg_8 = dword ptr 0Ch
+cseg01:C00022E5
+cseg01:C00022E5 push ebx
+cseg01:C00022E6 push esi
+cseg01:C00022E7 mov ebx, [esp+8+arg_8]
+cseg01:C00022EB cmp ebx, 20h
+cseg01:C00022EE jz short loc_C00022FA
+cseg01:C00022F0 cmp ebx, 10h
+cseg01:C00022F3 jz short loc_C00022FA
+cseg01:C00022F5 cmp ebx, 8
+cseg01:C00022F8 jnz short loc_C000234E
+cseg01:C00022FA
+cseg01:C00022FA loc_C00022FA: ; CODE XREF: sub_C00022E5+9j
+cseg01:C00022FA ; sub_C00022E5+Ej
+cseg01:C00022FA push 4
+cseg01:C00022FC call sub_C0000C93
+cseg01:C0002301 add esp, 4
+cseg01:C0002304 cmp eax, [esp+8+arg_0]
+cseg01:C0002308 jb short loc_C000234E
+cseg01:C000230A push 5
+cseg01:C000230C call sub_C0000C93
+cseg01:C0002311 add esp, 4
+cseg01:C0002314 cmp eax, [esp+8+arg_4]
+cseg01:C0002318 jb short loc_C000234E
+cseg01:C000231A push ebx
+cseg01:C000231B mov esi, [esp+0Ch+arg_0]
+cseg01:C000231F push esi
+cseg01:C0002320 call sub_C0002189
+cseg01:C0002325 add esp, 8
+cseg01:C0002328 mov edx, [esp+8+arg_4]
+cseg01:C000232C imul edx, eax
+cseg01:C000232F mov eax, ds:dword_C00010B4
+cseg01:C0002334 cmp edx, [eax+28h]
+cseg01:C0002337 jnb short loc_C000234E
+cseg01:C0002339 cmp ebx, 20h
+cseg01:C000233C jz short loc_C0002346
+cseg01:C000233E cmp edx, 1000000h
+cseg01:C0002344 ja short loc_C000234E
+cseg01:C0002346
+cseg01:C0002346 loc_C0002346: ; CODE XREF: sub_C00022E5+57j
+cseg01:C0002346 mov eax, 1
+cseg01:C000234B pop esi
+cseg01:C000234C pop ebx
+cseg01:C000234D retn
+cseg01:C000234E ; ---------------------------------------------------------------------------
+cseg01:C000234E
+cseg01:C000234E loc_C000234E: ; CODE XREF: sub_C00022E5+13j
+cseg01:C000234E ; sub_C00022E5+23j ...
+cseg01:C000234E xor eax, eax
+cseg01:C0002350 pop esi
+cseg01:C0002351 pop ebx
+cseg01:C0002352 retn
+cseg01:C0002352 sub_C00022E5 endp
+cseg01:C0002352
+cseg01:C0002353
+cseg01:C0002353 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002353
+cseg01:C0002353
+cseg01:C0002353 sub_C0002353 proc near ; CODE XREF: sub_C000037B+126p
+cseg01:C0002353
+cseg01:C0002353 arg_0 = dword ptr 4
+cseg01:C0002353 arg_4 = dword ptr 8
+cseg01:C0002353 arg_8 = dword ptr 0Ch
+cseg01:C0002353
+cseg01:C0002353 push ebx
+cseg01:C0002354 push esi
+cseg01:C0002355 push edi
+cseg01:C0002356 mov ebx, [esp+0Ch+arg_8]
+cseg01:C000235A push ebx
+cseg01:C000235B mov eax, [esp+10h+arg_4]
+cseg01:C000235F push eax
+cseg01:C0002360 mov edx, [esp+14h+arg_0]
+cseg01:C0002364 push edx
+cseg01:C0002365 call sub_C00022E5
+cseg01:C000236A add esp, 0Ch
+cseg01:C000236D test eax, eax
+cseg01:C000236F jz loc_C000244A
+cseg01:C0002375 call sub_C0000D7D
+cseg01:C000237A call sub_C00020E0
+cseg01:C000237F push ebx
+cseg01:C0002380 mov ecx, [esp+10h+arg_4]
+cseg01:C0002384 push ecx
+cseg01:C0002385 mov esi, [esp+14h+arg_0]
+cseg01:C0002389 push esi
+cseg01:C000238A call sub_C0000C25
+cseg01:C000238F add esp, 0Ch
+cseg01:C0002392 call sub_C0000D7D
+cseg01:C0002397 call sub_C0002151
+cseg01:C000239C call sub_C000213B
+cseg01:C00023A1 test eax, eax
+cseg01:C00023A3 jz short loc_C00023B9
+cseg01:C00023A5 push ebx
+cseg01:C00023A6 mov edi, [esp+10h+arg_4]
+cseg01:C00023AA push edi
+cseg01:C00023AB push esi
+cseg01:C00023AC call sub_C00021C7
+cseg01:C00023B1 add esp, 0Ch
+cseg01:C00023B4 call sub_C0000D7D
+cseg01:C00023B9
+cseg01:C00023B9 loc_C00023B9: ; CODE XREF: sub_C0002353+50j
+cseg01:C00023B9 call sub_C00025C1
+cseg01:C00023BE cmp ebx, 20h
+cseg01:C00023C1 jnz short loc_C00023C7
+cseg01:C00023C3 push 0
+cseg01:C00023C5 jmp short loc_C00023C9
+cseg01:C00023C7 ; ---------------------------------------------------------------------------
+cseg01:C00023C7
+cseg01:C00023C7 loc_C00023C7: ; CODE XREF: sub_C0002353+6Ej
+cseg01:C00023C7 push 1
+cseg01:C00023C9
+cseg01:C00023C9 loc_C00023C9: ; CODE XREF: sub_C0002353+72j
+cseg01:C00023C9 push 2Dh
+cseg01:C00023CB call sub_C0000CD3
+cseg01:C00023D0 add esp, 8
+cseg01:C00023D3 push 1
+cseg01:C00023D5 push 1
+cseg01:C00023D7 call sub_C0000CD3
+cseg01:C00023DC add esp, 8
+cseg01:C00023DF call sub_C0000D7D
+cseg01:C00023E4 push 2
+cseg01:C00023E6 call sub_C0000C93
+cseg01:C00023EB mov edx, eax
+cseg01:C00023ED add esp, 4
+cseg01:C00023F0 mov eax, ds:dword_C00010B4
+cseg01:C00023F5 mov [eax+8], edx
+cseg01:C00023F8 push 3
+cseg01:C00023FA call sub_C0000C93
+cseg01:C00023FF mov edx, eax
+cseg01:C0002401 add esp, 4
+cseg01:C0002404 mov eax, ds:dword_C00010B4
+cseg01:C0002409 mov [eax+0Ch], edx
+cseg01:C000240C push 7
+cseg01:C000240E call sub_C0000C93
+cseg01:C0002413 add esp, 4
+cseg01:C0002416 mov edx, ds:dword_C00010B4
+cseg01:C000241C mov [edx+10h], eax
+cseg01:C000241F push 0Ch
+cseg01:C0002421 call sub_C0000C93
+cseg01:C0002426 add esp, 4
+cseg01:C0002429 mov edx, ds:dword_C00010B4
+cseg01:C000242F mov [edx+14h], eax
+cseg01:C0002432 mov eax, edx
+cseg01:C0002434 mov edx, [edx+0Ch]
+cseg01:C0002437 imul edx, [eax+14h]
+cseg01:C000243B mov [eax+1Ch], edx
+cseg01:C000243E mov dword ptr [eax+18h], 0
+cseg01:C0002445 mov eax, 1
+cseg01:C000244A
+cseg01:C000244A loc_C000244A: ; CODE XREF: sub_C0002353+1Cj
+cseg01:C000244A pop edi
+cseg01:C000244B pop esi
+cseg01:C000244C pop ebx
+cseg01:C000244D retn
+cseg01:C000244D sub_C0002353 endp
+cseg01:C000244D
+cseg01:C000244E
+cseg01:C000244E ; =============== S U B R O U T I N E =======================================
+cseg01:C000244E
+cseg01:C000244E
+cseg01:C000244E sub_C000244E proc near ; CODE XREF: sub_C0002496:loc_C00024C2p
+cseg01:C000244E
+cseg01:C000244E arg_0 = dword ptr 4
+cseg01:C000244E arg_5 = byte ptr 9
+cseg01:C000244E
+cseg01:C000244E cmp [esp+arg_0], 26h
+cseg01:C0002453 jnz short loc_C0002491
+cseg01:C0002455 test byte ptr ds:dword_C000080C, 8
+cseg01:C000245C jz short loc_C000246E
+cseg01:C000245E
+cseg01:C000245E loc_C000245E: ; CODE XREF: sub_C000244E+27j
+cseg01:C000245E push 20h
+cseg01:C0002460 call sub_C0002496
+cseg01:C0002465 add esp, 4
+cseg01:C0002468 and eax, 0FFEFFFFFh
+cseg01:C000246D retn
+cseg01:C000246E ; ---------------------------------------------------------------------------
+cseg01:C000246E
+cseg01:C000246E loc_C000246E: ; CODE XREF: sub_C000244E+Ej
+cseg01:C000246E mov ah, [esp+arg_5]
+cseg01:C0002472 test ah, 1
+cseg01:C0002475 jnz short loc_C000245E
+cseg01:C0002477 test ah, 8
+cseg01:C000247A jnz short loc_C0002491
+cseg01:C000247C push 20h
+cseg01:C000247E call sub_C0002496
+cseg01:C0002483 add esp, 4
+cseg01:C0002486 and eax, 0FFEFFFFFh
+cseg01:C000248B test ah, 8
+cseg01:C000248E jz short loc_C0002491
+cseg01:C0002490 retn
+cseg01:C0002491 ; ---------------------------------------------------------------------------
+cseg01:C0002491
+cseg01:C0002491 loc_C0002491: ; CODE XREF: sub_C000244E+5j
+cseg01:C0002491 ; sub_C000244E+2Cj ...
+cseg01:C0002491 mov eax, [esp+8]
+cseg01:C0002495 retn
+cseg01:C0002495 sub_C000244E endp
+cseg01:C0002495
+cseg01:C0002496
+cseg01:C0002496 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002496
+cseg01:C0002496
+cseg01:C0002496 sub_C0002496 proc near ; CODE XREF: sub_C0001644+12p
+cseg01:C0002496 ; sub_C0001644+8Cp ...
+cseg01:C0002496
+cseg01:C0002496 arg_0 = dword ptr 4
+cseg01:C0002496
+cseg01:C0002496 push ebx
+cseg01:C0002497 push esi
+cseg01:C0002498 push edi
+cseg01:C0002499 push ebp
+cseg01:C000249A test byte ptr ds:dword_C00007E0+3, 8
+cseg01:C00024A1 jz short loc_C00024CF
+cseg01:C00024A3 mov eax, [esp+10h+arg_0]
+cseg01:C00024A7 push eax
+cseg01:C00024A8 push 34h
+cseg01:C00024AA call sub_C0000CD3
+cseg01:C00024AF add esp, 8
+cseg01:C00024B2 push 34h
+cseg01:C00024B4 call sub_C0000C93
+cseg01:C00024B9 add esp, 4
+cseg01:C00024BC push eax
+cseg01:C00024BD mov edx, [esp+14h+arg_0]
+cseg01:C00024C1 push edx
+cseg01:C00024C2
+cseg01:C00024C2 loc_C00024C2: ; CODE XREF: sub_C0002496+75j
+cseg01:C00024C2 call sub_C000244E
+cseg01:C00024C7 add esp, 8
+cseg01:C00024CA pop ebp
+cseg01:C00024CB pop edi
+cseg01:C00024CC pop esi
+cseg01:C00024CD pop ebx
+cseg01:C00024CE retn
+cseg01:C00024CF ; ---------------------------------------------------------------------------
+cseg01:C00024CF
+cseg01:C00024CF loc_C00024CF: ; CODE XREF: sub_C0002496+Bj
+cseg01:C00024CF mov ebx, ds:dword_C00007B4
+cseg01:C00024D5 add ebx, 80h
+cseg01:C00024DB mov ebp, [esp+10h+arg_0]
+cseg01:C00024DF
+cseg01:C00024DF loc_C00024DF: ; CODE XREF: sub_C0002496+81j
+cseg01:C00024DF mov ecx, [ebx]
+cseg01:C00024E1 test ecx, ecx
+cseg01:C00024E3 jz short loc_C0002519
+cseg01:C00024E5 cmp dword ptr [ebx+4], 100h
+cseg01:C00024EC jnz short loc_C0002510
+cseg01:C00024EE lea esi, [ecx-2]
+cseg01:C00024F1 shr esi, 1
+cseg01:C00024F3 lea edi, [ebx+8]
+cseg01:C00024F6 xor edx, edx
+cseg01:C00024F8
+cseg01:C00024F8 loc_C00024F8: ; CODE XREF: sub_C0002496+78j
+cseg01:C00024F8 cmp edx, esi
+cseg01:C00024FA jnb short loc_C0002510
+cseg01:C00024FC mov eax, edx
+cseg01:C00024FE mov ecx, [edi+eax*8]
+cseg01:C0002501 mov eax, [edi+eax*8+4]
+cseg01:C0002505 cmp ecx, ebp
+cseg01:C0002507 jnz short loc_C000250D
+cseg01:C0002509 push eax
+cseg01:C000250A push ebp
+cseg01:C000250B jmp short loc_C00024C2
+cseg01:C000250D ; ---------------------------------------------------------------------------
+cseg01:C000250D
+cseg01:C000250D loc_C000250D: ; CODE XREF: sub_C0002496+71j
+cseg01:C000250D inc edx
+cseg01:C000250E jmp short loc_C00024F8
+cseg01:C0002510 ; ---------------------------------------------------------------------------
+cseg01:C0002510
+cseg01:C0002510 loc_C0002510: ; CODE XREF: sub_C0002496+56j
+cseg01:C0002510 ; sub_C0002496+64j
+cseg01:C0002510 mov eax, [ebx]
+cseg01:C0002512 shl eax, 2
+cseg01:C0002515 add ebx, eax
+cseg01:C0002517 jmp short loc_C00024DF
+cseg01:C0002519 ; ---------------------------------------------------------------------------
+cseg01:C0002519
+cseg01:C0002519 loc_C0002519: ; CODE XREF: sub_C0002496+4Dj
+cseg01:C0002519 xor eax, eax
+cseg01:C000251B
+cseg01:C000251B loc_C000251B: ; CODE XREF: sub_C0002574+14j
+cseg01:C000251B pop ebp
+cseg01:C000251C pop edi
+cseg01:C000251D pop esi
+cseg01:C000251E pop ebx
+cseg01:C000251F retn
+cseg01:C000251F sub_C0002496 endp
+cseg01:C000251F
+cseg01:C0002520
+cseg01:C0002520 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002520
+cseg01:C0002520
+cseg01:C0002520 sub_C0002520 proc near ; CODE XREF: sub_C000055F+1E1p
+cseg01:C0002520 ; sub_C0002574+1Fp
+cseg01:C0002520
+cseg01:C0002520 arg_0 = dword ptr 4
+cseg01:C0002520 arg_4 = dword ptr 8
+cseg01:C0002520
+cseg01:C0002520 mov edx, [esp+arg_0]
+cseg01:C0002524 mov eax, [esp+arg_4]
+cseg01:C0002528 cmp edx, 3
+cseg01:C000252B jz short loc_C000255D
+cseg01:C000252D cmp edx, 2
+cseg01:C0002530 jz short loc_C0002548
+cseg01:C0002532 cmp edx, 1
+cseg01:C0002535 jnz short loc_C000256E
+cseg01:C0002537 cmp eax, 100h
+cseg01:C000253C jnb short loc_C000256E
+cseg01:C000253E push eax
+cseg01:C000253F call sub_C0000C93
+cseg01:C0002544 add esp, 4
+cseg01:C0002547
+cseg01:C0002547 locret_C0002547: ; CODE XREF: sub_C00025A4+9j
+cseg01:C0002547 ; sub_C00025A4+Fj
+cseg01:C0002547 retn
+cseg01:C0002548 ; ---------------------------------------------------------------------------
+cseg01:C0002548
+cseg01:C0002548 loc_C0002548: ; CODE XREF: sub_C0002520+10j
+cseg01:C0002548 cmp eax, 400h
+cseg01:C000254D jnb short loc_C000256E
+cseg01:C000254F mov edx, eax
+cseg01:C0002551 shl edx, 2
+cseg01:C0002554 mov eax, ds:dword_C00007B4
+cseg01:C0002559 mov eax, [edx+eax]
+cseg01:C000255C retn
+cseg01:C000255D ; ---------------------------------------------------------------------------
+cseg01:C000255D
+cseg01:C000255D loc_C000255D: ; CODE XREF: sub_C0002520+Bj
+cseg01:C000255D cmp eax, 200h
+cseg01:C0002562 jnb short loc_C000256E
+cseg01:C0002564 push eax
+cseg01:C0002565 call sub_C0002496
+cseg01:C000256A add esp, 4
+cseg01:C000256D retn
+cseg01:C000256E ; ---------------------------------------------------------------------------
+cseg01:C000256E
+cseg01:C000256E loc_C000256E: ; CODE XREF: sub_C0002520+15j
+cseg01:C000256E ; sub_C0002520+1Cj ...
+cseg01:C000256E mov eax, 0FFFFFFFFh
+cseg01:C0002573 retn
+cseg01:C0002573 sub_C0002520 endp
+cseg01:C0002573
+cseg01:C0002574
+cseg01:C0002574 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002574
+cseg01:C0002574
+cseg01:C0002574 sub_C0002574 proc near ; CODE XREF: sub_C000055F+1FAp
+cseg01:C0002574
+cseg01:C0002574 arg_0 = dword ptr 4
+cseg01:C0002574 arg_4 = dword ptr 8
+cseg01:C0002574 arg_8 = dword ptr 0Ch
+cseg01:C0002574 arg_C = dword ptr 10h
+cseg01:C0002574
+cseg01:C0002574 push ebx
+cseg01:C0002575 push esi
+cseg01:C0002576 push edi
+cseg01:C0002577 push ebp
+cseg01:C0002578 mov esi, [esp+10h+arg_4]
+cseg01:C000257C mov edi, [esp+10h+arg_8]
+cseg01:C0002580 mov ebp, [esp+10h+arg_C]
+cseg01:C0002584 xor ebx, ebx
+cseg01:C0002586
+cseg01:C0002586 loc_C0002586: ; CODE XREF: sub_C0002574+2Ej
+cseg01:C0002586 cmp ebx, edi
+cseg01:C0002588 jnb short loc_C000251B
+cseg01:C000258A lea eax, [esi+ebx]
+cseg01:C000258D push eax
+cseg01:C000258E mov eax, [esp+14h+arg_0]
+cseg01:C0002592 push eax
+cseg01:C0002593 call sub_C0002520
+cseg01:C0002598 add esp, 8
+cseg01:C000259B mov edx, ebx
+cseg01:C000259D mov [ebp+edx*4+0], eax
+cseg01:C00025A1 inc ebx
+cseg01:C00025A2 jmp short loc_C0002586
+cseg01:C00025A2 sub_C0002574 endp
+cseg01:C00025A2
+cseg01:C00025A4
+cseg01:C00025A4 ; =============== S U B R O U T I N E =======================================
+cseg01:C00025A4
+cseg01:C00025A4
+cseg01:C00025A4 sub_C00025A4 proc near ; CODE XREF: sub_C000037B:loc_C00004D0p
+cseg01:C00025A4 mov eax, ds:dword_C00010B4
+cseg01:C00025A9 cmp dword ptr [eax+8], 0
+cseg01:C00025AD jbe short locret_C0002547
+cseg01:C00025AF cmp dword ptr [eax+0Ch], 0
+cseg01:C00025B3 jbe short locret_C0002547
+cseg01:C00025B5 push 1
+cseg01:C00025B7 push 1
+cseg01:C00025B9 call sub_C0000CD3
+cseg01:C00025BE add esp, 8
+cseg01:C00025BE sub_C00025A4 endp ; sp-analysis failed
+cseg01:C00025BE
+cseg01:C00025C1
+cseg01:C00025C1 ; =============== S U B R O U T I N E =======================================
+cseg01:C00025C1
+cseg01:C00025C1
+cseg01:C00025C1 sub_C00025C1 proc near ; CODE XREF: sub_C0002353:loc_C00023B9p
+cseg01:C00025C1 push ebx
+cseg01:C00025C2 cmp ds:dword_C00013A4, 0
+cseg01:C00025C9 jz short loc_C000261E
+cseg01:C00025CB mov ebx, ds:dword_C0001400
+cseg01:C00025D1 push 4Ch
+cseg01:C00025D3 push 0
+cseg01:C00025D5 push ebx
+cseg01:C00025D6 call sub_C00011BA
+cseg01:C00025DB add esp, 0Ch
+cseg01:C00025DE mov dword ptr [ebx+14h], 0Ch
+cseg01:C00025E5 mov dword ptr [ebx+40h], 1
+cseg01:C00025EC mov dword ptr [ebx+44h], 1
+cseg01:C00025F3 mov dword ptr [ebx+48h], 0
+cseg01:C00025FA push 0
+cseg01:C00025FC push 0C0000000h
+cseg01:C0002601 push 0
+cseg01:C0002603 push 4Ch
+cseg01:C0002605 mov edx, ds:dword_C0001400
+cseg01:C000260B push edx
+cseg01:C000260C call sub_C00017FE
+cseg01:C0002611 add esp, 14h
+cseg01:C0002614 mov ds:dword_C00013A8, 1
+cseg01:C000261E
+cseg01:C000261E loc_C000261E: ; CODE XREF: sub_C00025C1+8j
+cseg01:C000261E pop ebx
+cseg01:C000261F retn
+cseg01:C000261F sub_C00025C1 endp
+cseg01:C000261F
+cseg01:C0002620
+cseg01:C0002620 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002620
+cseg01:C0002620
+cseg01:C0002620 sub_C0002620 proc near ; CODE XREF: sub_C000037B:loc_C00004D7p
+cseg01:C0002620 ; sub_C0000795+Dp
+cseg01:C0002620
+cseg01:C0002620 ; FUNCTION CHUNK AT cseg01:C0000C1F SIZE 00000006 BYTES
+cseg01:C0002620
+cseg01:C0002620 call sub_C00020E0
+cseg01:C0002625 jmp loc_C0000C1F
+cseg01:C0002625 sub_C0002620 endp
+cseg01:C0002625
+cseg01:C000262A
+cseg01:C000262A ; =============== S U B R O U T I N E =======================================
+cseg01:C000262A
+cseg01:C000262A
+cseg01:C000262A sub_C000262A proc near ; CODE XREF: sub_C000037B:loc_C000048Fp
+cseg01:C000262A ; sub_C000055F:loc_C00006BEp ...
+cseg01:C000262A mov eax, ds:dword_C00013AC
+cseg01:C000262F retn
+cseg01:C000262F sub_C000262A endp
+cseg01:C000262F
+cseg01:C0002630
+cseg01:C0002630 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002630
+cseg01:C0002630
+cseg01:C0002630 sub_C0002630 proc near ; CODE XREF: sub_C000037B+D1p
+cseg01:C0002630 ; sub_C000055F+123p ...
+cseg01:C0002630
+cseg01:C0002630 var_14 = dword ptr -14h
+cseg01:C0002630
+cseg01:C0002630 push ebx
+cseg01:C0002631 push esi
+cseg01:C0002632 push edi
+cseg01:C0002633 push ebp
+cseg01:C0002634 sub esp, 4
+cseg01:C0002637 mov eax, ds:dword_C00010B4
+cseg01:C000263C cmp dword ptr [eax+10h], 20h
+cseg01:C0002640 jnz short loc_C00026A1
+cseg01:C0002642 xor ecx, ecx
+cseg01:C0002644 mov [esp+14h+var_14], ecx
+cseg01:C0002647 push 10h
+cseg01:C0002649 push 1
+cseg01:C000264B lea eax, [esp+1Ch+var_14]
+cseg01:C000264F push eax
+cseg01:C0002650 mov ebx, ds:dword_C0001400
+cseg01:C0002656 push ebx
+cseg01:C0002657 call sub_C000219E
+cseg01:C000265C add esp, 10h
+cseg01:C000265F mov dword ptr [eax], 0
+cseg01:C0002665 mov dword ptr [eax+4], 0
+cseg01:C000266C mov edx, ds:dword_C00010B4
+cseg01:C0002672 mov edx, [edx+8]
+cseg01:C0002675 mov [eax+8], edx
+cseg01:C0002678 mov edx, ds:dword_C00010B4
+cseg01:C000267E mov edx, [edx+0Ch]
+cseg01:C0002681 mov [eax+0Ch], edx
+cseg01:C0002684 push 0
+cseg01:C0002686 push 60000000h
+cseg01:C000268B push 0
+cseg01:C000268D mov esi, [esp+20h+var_14]
+cseg01:C0002691 push esi
+cseg01:C0002692 mov edi, ds:dword_C0001400
+cseg01:C0002698 push edi
+cseg01:C0002699 call sub_C00017FE
+cseg01:C000269E add esp, 14h
+cseg01:C00026A1
+cseg01:C00026A1 loc_C00026A1: ; CODE XREF: sub_C0002630+10j
+cseg01:C00026A1 mov ebp, ds:dword_C00010B8
+cseg01:C00026A7 push ebp
+cseg01:C00026A8 call sub_C000133D
+cseg01:C00026AD add esp, 4
+cseg01:C00026B0 add esp, 4
+cseg01:C00026B3 pop ebp
+cseg01:C00026B4 pop edi
+cseg01:C00026B5 pop esi
+cseg01:C00026B6 pop ebx
+cseg01:C00026B7 retn
+cseg01:C00026B7 sub_C0002630 endp
+cseg01:C00026B7
+cseg01:C00026B8
+cseg01:C00026B8 ; =============== S U B R O U T I N E =======================================
+cseg01:C00026B8
+cseg01:C00026B8
+cseg01:C00026B8 sub_C00026B8 proc near ; CODE XREF: sub_C000037B+F7p
+cseg01:C00026B8 ; sub_C000055F+14Dp
+cseg01:C00026B8
+cseg01:C00026B8 arg_0 = byte ptr 4
+cseg01:C00026B8 arg_4 = dword ptr 8
+cseg01:C00026B8
+cseg01:C00026B8 push ebx
+cseg01:C00026B9 movzx ebx, [esp+4+arg_0]
+cseg01:C00026BE lea ebx, [ebx+ebx*2+400h]
+cseg01:C00026C5 mov eax, [esp+4+arg_4]
+cseg01:C00026C9 shr eax, 10h
+cseg01:C00026CC and eax, 0FFh
+cseg01:C00026D1 push eax
+cseg01:C00026D2 push ebx
+cseg01:C00026D3 call sub_C0000CD3
+cseg01:C00026D8 add esp, 8
+cseg01:C00026DB mov eax, [esp+4+arg_4]
+cseg01:C00026DF shr eax, 8
+cseg01:C00026E2 and eax, 0FFh
+cseg01:C00026E7 push eax
+cseg01:C00026E8 lea eax, [ebx+1]
+cseg01:C00026EB push eax
+cseg01:C00026EC call sub_C0000CD3
+cseg01:C00026F1 add esp, 8
+cseg01:C00026F4 mov eax, [esp+4+arg_4]
+cseg01:C00026F8 and eax, 0FFh
+cseg01:C00026FD push eax
+cseg01:C00026FE add ebx, 2
+cseg01:C0002701 push ebx
+cseg01:C0002702 call sub_C0000CD3
+cseg01:C0002707 add esp, 8
+cseg01:C000270A pop ebx
+cseg01:C000270B retn
+cseg01:C000270B sub_C00026B8 endp
+cseg01:C000270B
+cseg01:C000270C
+cseg01:C000270C ; =============== S U B R O U T I N E =======================================
+cseg01:C000270C
+cseg01:C000270C
+cseg01:C000270C sub_C000270C proc near ; CODE XREF: sub_C000037B+108p
+cseg01:C000270C ; sub_C000055F+158p
+cseg01:C000270C
+cseg01:C000270C arg_0 = byte ptr 4
+cseg01:C000270C
+cseg01:C000270C push ebx
+cseg01:C000270D push esi
+cseg01:C000270E movzx eax, [esp+8+arg_0]
+cseg01:C0002713 lea eax, [eax+eax*2]
+cseg01:C0002716 lea ebx, [eax+400h]
+cseg01:C000271C push ebx
+cseg01:C000271D call sub_C0000C93
+cseg01:C0002722 add esp, 4
+cseg01:C0002725 mov esi, eax
+cseg01:C0002727 and esi, 0FFh
+cseg01:C000272D shl esi, 10h
+cseg01:C0002730 lea eax, [ebx+1]
+cseg01:C0002733 push eax
+cseg01:C0002734 call sub_C0000C93
+cseg01:C0002739 add esp, 4
+cseg01:C000273C and eax, 0FFh
+cseg01:C0002741 shl eax, 8
+cseg01:C0002744 or esi, eax
+cseg01:C0002746 add ebx, 2
+cseg01:C0002749 push ebx
+cseg01:C000274A call sub_C0000C93
+cseg01:C000274F add esp, 4
+cseg01:C0002752 and eax, 0FFh
+cseg01:C0002757 or eax, esi
+cseg01:C0002759 pop esi
+cseg01:C000275A pop ebx
+cseg01:C000275B retn
+cseg01:C000275B sub_C000270C endp
+cseg01:C000275B
+cseg01:C000275B ; ---------------------------------------------------------------------------
+cseg01:C000275C dword_C000275C dd 2 dup(0) ; DATA XREF: sub_C00027CF+7w
+cseg01:C000275C ; sub_C00027CF+Dr ...
+cseg01:C0002764
+cseg01:C0002764 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002764
+cseg01:C0002764
+cseg01:C0002764 sub_C0002764 proc near ; CODE XREF: sub_C00004F5+1p
+cseg01:C0002764
+cseg01:C0002764 arg_0 = dword ptr 4
+cseg01:C0002764
+cseg01:C0002764 mov eax, [esp+arg_0]
+cseg01:C0002768 and byte ptr [eax+2Ch], 0FEh
+cseg01:C000276C retn 4
+cseg01:C000276C sub_C0002764 endp
+cseg01:C000276C
+cseg01:C000276F
+cseg01:C000276F ; =============== S U B R O U T I N E =======================================
+cseg01:C000276F
+cseg01:C000276F
+cseg01:C000276F sub_C000276F proc near ; CODE XREF: sub_C0000503+1p
+cseg01:C000276F
+cseg01:C000276F arg_0 = dword ptr 4
+cseg01:C000276F
+cseg01:C000276F push ebx
+cseg01:C0002770 mov ebx, [esp+4+arg_0]
+cseg01:C0002774 call sub_C000262A
+cseg01:C0002779 test eax, eax
+cseg01:C000277B jz short loc_C000279A
+cseg01:C000277D movzx eax, word ptr ds:dword_C0000808
+cseg01:C0002784 shl eax, 10h
+cseg01:C0002787 test eax, eax
+cseg01:C0002789 jnz short loc_C0002795
+cseg01:C000278B cmp word ptr ds:dword_C0000808+2, 0
+cseg01:C0002793 jz short loc_C000279A
+cseg01:C0002795
+cseg01:C0002795 loc_C0002795: ; CODE XREF: sub_C000276F+1Aj
+cseg01:C0002795 mov eax, 1
+cseg01:C000279A
+cseg01:C000279A loc_C000279A: ; CODE XREF: sub_C000276F+Cj
+cseg01:C000279A ; sub_C000276F+24j
+cseg01:C000279A mov [ebx+1Ch], eax
+cseg01:C000279D pop ebx
+cseg01:C000279E retn 4
+cseg01:C000279E sub_C000276F endp
+cseg01:C000279E
+cseg01:C00027A1
+cseg01:C00027A1 ; =============== S U B R O U T I N E =======================================
+cseg01:C00027A1
+cseg01:C00027A1
+cseg01:C00027A1 sub_C00027A1 proc near ; CODE XREF: sub_C00004FC+1p
+cseg01:C00027A1
+cseg01:C00027A1 arg_0 = dword ptr 4
+cseg01:C00027A1
+cseg01:C00027A1 push ebx
+cseg01:C00027A2 mov ebx, [esp+4+arg_0]
+cseg01:C00027A6 call sub_C000262A
+cseg01:C00027AB test eax, eax
+cseg01:C00027AD jz short loc_C00027C4
+cseg01:C00027AF push 0Fh
+cseg01:C00027B1 call sub_C0000C93
+cseg01:C00027B6 add esp, 4
+cseg01:C00027B9 mov [ebx+18h], eax
+cseg01:C00027BC or byte ptr [ebx+2Ch], 1
+cseg01:C00027C0 pop ebx
+cseg01:C00027C1 retn 4
+cseg01:C00027C4 ; ---------------------------------------------------------------------------
+cseg01:C00027C4
+cseg01:C00027C4 loc_C00027C4: ; CODE XREF: sub_C00027A1+Cj
+cseg01:C00027C4 mov [ebx+18h], eax
+cseg01:C00027C7 and byte ptr [ebx+2Ch], 0FEh
+cseg01:C00027CB pop ebx
+cseg01:C00027CC retn 4
+cseg01:C00027CC sub_C00027A1 endp
+cseg01:C00027CC
+cseg01:C00027CF
+cseg01:C00027CF ; =============== S U B R O U T I N E =======================================
+cseg01:C00027CF
+cseg01:C00027CF
+cseg01:C00027CF sub_C00027CF proc near ; CODE XREF: cseg01:C000282Dp
+cseg01:C00027CF ; cseg01:C000283Ap
+cseg01:C00027CF
+cseg01:C00027CF arg_0 = dword ptr 4
+cseg01:C00027CF
+cseg01:C00027CF push ebx
+cseg01:C00027D0 push esi
+cseg01:C00027D1 push edi
+cseg01:C00027D2 mov eax, [esp+0Ch+arg_0]
+cseg01:C00027D6 mov ds:dword_C000275C, eax
+cseg01:C00027DB push edx
+cseg01:C00027DC mov edx, ds:dword_C000275C
+cseg01:C00027E2 VMMCall Enable_Global_Trapping
+cseg01:C00027E8 pop edx
+cseg01:C00027E9 pop edi
+cseg01:C00027EA pop esi
+cseg01:C00027EB pop ebx
+cseg01:C00027EC retn
+cseg01:C00027EC sub_C00027CF endp
+cseg01:C00027EC
+cseg01:C00027ED
+cseg01:C00027ED ; =============== S U B R O U T I N E =======================================
+cseg01:C00027ED
+cseg01:C00027ED
+cseg01:C00027ED sub_C00027ED proc near ; CODE XREF: cseg01:C0002810p
+cseg01:C00027ED ; cseg01:C000281Dp
+cseg01:C00027ED
+cseg01:C00027ED arg_0 = dword ptr 4
+cseg01:C00027ED
+cseg01:C00027ED push ebx
+cseg01:C00027EE push esi
+cseg01:C00027EF push edi
+cseg01:C00027F0 mov eax, [esp+0Ch+arg_0]
+cseg01:C00027F4 mov ds:dword_C000275C+4, eax
+cseg01:C00027F9 push edx
+cseg01:C00027FA mov edx, ds:dword_C000275C+4
+cseg01:C0002800 VMMCall Disable_Global_Trapping
+cseg01:C0002806 pop edx
+cseg01:C0002807 pop edi
+cseg01:C0002808 pop esi
+cseg01:C0002809 pop ebx
+cseg01:C000280A retn
+cseg01:C000280A sub_C00027ED endp
+cseg01:C000280A
+cseg01:C000280B ; ---------------------------------------------------------------------------
+cseg01:C000280B push 1CEh
+cseg01:C0002810 call sub_C00027ED
+cseg01:C0002815 add esp, 4
+cseg01:C0002818 push 1CFh
+cseg01:C000281D call sub_C00027ED
+cseg01:C0002822
+cseg01:C0002822 loc_C0002822: ; CODE XREF: cseg01:C000283Fj
+cseg01:C0002822 add esp, 4
+cseg01:C0002825 retn 4
+cseg01:C0002828 ; ---------------------------------------------------------------------------
+cseg01:C0002828 push 1CEh
+cseg01:C000282D call sub_C00027CF
+cseg01:C0002832 add esp, 4
+cseg01:C0002835 push 1CFh
+cseg01:C000283A call sub_C00027CF
+cseg01:C000283F jmp short loc_C0002822
+cseg01:C0002841
+cseg01:C0002841 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002841
+cseg01:C0002841
+cseg01:C0002841 sub_C0002841 proc near ; CODE XREF: sub_C00028B5+9p
+cseg01:C0002841 push 0
+cseg01:C0002843 push 2F9h
+cseg01:C0002848 call sub_C0000006
+cseg01:C000284D add esp, 8
+cseg01:C0002850 push 80h
+cseg01:C0002855 push 2FBh
+cseg01:C000285A call sub_C0000006
+cseg01:C000285F add esp, 8
+cseg01:C0002862 push 12h
+cseg01:C0002864 push 2F8h
+cseg01:C0002869 call sub_C0000006
+cseg01:C000286E add esp, 8
+cseg01:C0002871 push 0
+cseg01:C0002873 push 2F9h
+cseg01:C0002878 call sub_C0000006
+cseg01:C000287D add esp, 8
+cseg01:C0002880 push 3
+cseg01:C0002882 push 2FBh
+cseg01:C0002887 call sub_C0000006
+cseg01:C000288C add esp, 8
+cseg01:C000288F push 0C7h
+cseg01:C0002894 push 2FAh
+cseg01:C0002899
+cseg01:C0002899 loc_C0002899: ; CODE XREF: sub_C00028B5+2Cj
+cseg01:C0002899 call sub_C0000006
+cseg01:C000289E add esp, 8
+cseg01:C00028A1 retn
+cseg01:C00028A1 sub_C0002841 endp
+cseg01:C00028A1
+cseg01:C00028A2
+cseg01:C00028A2 ; =============== S U B R O U T I N E =======================================
+cseg01:C00028A2
+cseg01:C00028A2
+cseg01:C00028A2 sub_C00028A2 proc near ; CODE XREF: sub_C00028B5:loc_C00028CDp
+cseg01:C00028A2 push 2FDh
+cseg01:C00028A7 call sub_C0000000
+cseg01:C00028AC add esp, 4
+cseg01:C00028AF and al, 20h
+cseg01:C00028B1 movzx eax, al
+cseg01:C00028B4 retn
+cseg01:C00028B4 sub_C00028A2 endp
+cseg01:C00028B4
+cseg01:C00028B5
+cseg01:C00028B5 ; =============== S U B R O U T I N E =======================================
+cseg01:C00028B5
+cseg01:C00028B5
+cseg01:C00028B5 sub_C00028B5 proc near ; CODE XREF: sub_C00028FA+37p
+cseg01:C00028B5 ; sub_C00028FA+48p ...
+cseg01:C00028B5
+cseg01:C00028B5 arg_0 = byte ptr 4
+cseg01:C00028B5
+cseg01:C00028B5 cmp ds:dword_C0000044, 0
+cseg01:C00028BC jnz short loc_C00028CD
+cseg01:C00028BE call sub_C0002841
+cseg01:C00028C3 mov ds:dword_C0000044, 1
+cseg01:C00028CD
+cseg01:C00028CD loc_C00028CD: ; CODE XREF: sub_C00028B5+7j
+cseg01:C00028CD ; sub_C00028B5+1Fj
+cseg01:C00028CD call sub_C00028A2
+cseg01:C00028D2 test eax, eax
+cseg01:C00028D4 jz short loc_C00028CD
+cseg01:C00028D6 movzx eax, [esp+arg_0]
+cseg01:C00028DB push eax
+cseg01:C00028DC push 2F8h
+cseg01:C00028E1 jmp short loc_C0002899
+cseg01:C00028E1 sub_C00028B5 endp
+cseg01:C00028E1
+cseg01:C00028E3
+cseg01:C00028E3 ; =============== S U B R O U T I N E =======================================
+cseg01:C00028E3
+cseg01:C00028E3
+cseg01:C00028E3 sub_C00028E3 proc near ; CODE XREF: sub_C0002A03+189p
+cseg01:C00028E3
+cseg01:C00028E3 arg_0 = dword ptr 4
+cseg01:C00028E3
+cseg01:C00028E3 mov eax, [esp+arg_0]
+cseg01:C00028E7 cmp eax, 30h
+cseg01:C00028EA jl short loc_C00028F7
+cseg01:C00028EC cmp eax, 39h
+cseg01:C00028EF jg short loc_C00028F7
+cseg01:C00028F1 mov eax, 1
+cseg01:C00028F6 retn
+cseg01:C00028F7 ; ---------------------------------------------------------------------------
+cseg01:C00028F7
+cseg01:C00028F7 loc_C00028F7: ; CODE XREF: sub_C00028E3+7j
+cseg01:C00028F7 ; sub_C00028E3+Cj
+cseg01:C00028F7 xor eax, eax
+cseg01:C00028F9 retn
+cseg01:C00028F9 sub_C00028E3 endp
+cseg01:C00028F9
+cseg01:C00028FA
+cseg01:C00028FA ; =============== S U B R O U T I N E =======================================
+cseg01:C00028FA
+cseg01:C00028FA
+cseg01:C00028FA sub_C00028FA proc near ; CODE XREF: sub_C0002955+24p
+cseg01:C00028FA ; sub_C0002A03+B8p
+cseg01:C00028FA
+cseg01:C00028FA var_1C = byte ptr -1Ch
+cseg01:C00028FA arg_0 = dword ptr 4
+cseg01:C00028FA arg_4 = dword ptr 8
+cseg01:C00028FA
+cseg01:C00028FA push ebx
+cseg01:C00028FB push esi
+cseg01:C00028FC push edi
+cseg01:C00028FD sub esp, 10h
+cseg01:C0002900 mov esi, [esp+1Ch+arg_4]
+cseg01:C0002904 xor ebx, ebx
+cseg01:C0002906 mov ecx, [esp+1Ch+arg_0]
+cseg01:C000290A mov edi, 0Ah
+cseg01:C000290F
+cseg01:C000290F loc_C000290F: ; CODE XREF: sub_C00028FA+2Fj
+cseg01:C000290F xor edx, edx
+cseg01:C0002911 mov eax, ecx
+cseg01:C0002913 div edi
+cseg01:C0002915 mov edx, eax
+cseg01:C0002917 mov ch, 0Ah
+cseg01:C0002919 mul ch
+cseg01:C000291B sub cl, al
+cseg01:C000291D mov al, cl
+cseg01:C000291F add al, 30h
+cseg01:C0002921 mov [esp+ebx+1Ch+var_1C], al
+cseg01:C0002924 mov ecx, edx
+cseg01:C0002926 inc ebx
+cseg01:C0002927 test edx, edx
+cseg01:C0002929 jnz short loc_C000290F
+cseg01:C000292B
+cseg01:C000292B loc_C000292B: ; CODE XREF: sub_C00028FA+40j
+cseg01:C000292B cmp esi, ebx
+cseg01:C000292D jle short loc_C000293C
+cseg01:C000292F push 20h
+cseg01:C0002931 call sub_C00028B5
+cseg01:C0002936 add esp, 4
+cseg01:C0002939 dec esi
+cseg01:C000293A jmp short loc_C000292B
+cseg01:C000293C ; ---------------------------------------------------------------------------
+cseg01:C000293C
+cseg01:C000293C loc_C000293C: ; CODE XREF: sub_C00028FA+33j
+cseg01:C000293C ; sub_C00028FA+52j
+cseg01:C000293C dec ebx
+cseg01:C000293D movzx edx, [esp+ebx+1Ch+var_1C]
+cseg01:C0002941 push edx
+cseg01:C0002942 call sub_C00028B5
+cseg01:C0002947 add esp, 4
+cseg01:C000294A test ebx, ebx
+cseg01:C000294C jnz short loc_C000293C
+cseg01:C000294E add esp, 10h
+cseg01:C0002951 pop edi
+cseg01:C0002952 pop esi
+cseg01:C0002953 pop ebx
+cseg01:C0002954 retn
+cseg01:C0002954 sub_C00028FA endp
+cseg01:C0002954
+cseg01:C0002955
+cseg01:C0002955 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002955
+cseg01:C0002955
+cseg01:C0002955 sub_C0002955 proc near ; CODE XREF: sub_C0002A03+9Fp
+cseg01:C0002955
+cseg01:C0002955 arg_0 = dword ptr 4
+cseg01:C0002955 arg_4 = dword ptr 8
+cseg01:C0002955
+cseg01:C0002955 push ebx
+cseg01:C0002956 mov ebx, [esp+4+arg_4]
+cseg01:C000295A mov eax, [esp+4+arg_0]
+cseg01:C000295E test eax, eax
+cseg01:C0002960 jge short loc_C0002977
+cseg01:C0002962 push 2Dh
+cseg01:C0002964 call sub_C00028B5
+cseg01:C0002969 add esp, 4
+cseg01:C000296C mov eax, [esp+4+arg_0]
+cseg01:C0002970 neg eax
+cseg01:C0002972 test ebx, ebx
+cseg01:C0002974 jle short loc_C0002977
+cseg01:C0002976 dec ebx
+cseg01:C0002977
+cseg01:C0002977 loc_C0002977: ; CODE XREF: sub_C0002955+Bj
+cseg01:C0002977 ; sub_C0002955+1Fj
+cseg01:C0002977 push ebx
+cseg01:C0002978 push eax
+cseg01:C0002979 call sub_C00028FA
+cseg01:C000297E add esp, 8
+cseg01:C0002981 pop ebx
+cseg01:C0002982 retn
+cseg01:C0002982 sub_C0002955 endp
+cseg01:C0002982
+cseg01:C0002983
+cseg01:C0002983 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002983
+cseg01:C0002983
+cseg01:C0002983 sub_C0002983 proc near ; CODE XREF: sub_C0002A03+EDp
+cseg01:C0002983 ; sub_C0002A03+108p
+cseg01:C0002983
+cseg01:C0002983 var_10 = byte ptr -10h
+cseg01:C0002983 arg_0 = dword ptr 4
+cseg01:C0002983 arg_4 = dword ptr 8
+cseg01:C0002983 arg_8 = byte ptr 0Ch
+cseg01:C0002983
+cseg01:C0002983 push ebx
+cseg01:C0002984 push esi
+cseg01:C0002985 sub esp, 8
+cseg01:C0002988 mov eax, [esp+10h+arg_0]
+cseg01:C000298C mov esi, [esp+10h+arg_4]
+cseg01:C0002990 xor ebx, ebx
+cseg01:C0002992
+cseg01:C0002992 loc_C0002992: ; CODE XREF: sub_C0002983+33j
+cseg01:C0002992 mov edx, eax
+cseg01:C0002994 and edx, 0Fh
+cseg01:C0002997 shr eax, 4
+cseg01:C000299A cmp edx, 9
+cseg01:C000299D jle short loc_C00029A9
+cseg01:C000299F movzx ecx, [esp+10h+arg_8]
+cseg01:C00029A4 sub ecx, 0Ah
+cseg01:C00029A7 jmp short loc_C00029AE
+cseg01:C00029A9 ; ---------------------------------------------------------------------------
+cseg01:C00029A9
+cseg01:C00029A9 loc_C00029A9: ; CODE XREF: sub_C0002983+1Aj
+cseg01:C00029A9 mov ecx, 30h
+cseg01:C00029AE
+cseg01:C00029AE loc_C00029AE: ; CODE XREF: sub_C0002983+24j
+cseg01:C00029AE add edx, ecx
+cseg01:C00029B0 mov [esp+ebx+10h+var_10], dl
+cseg01:C00029B3 inc ebx
+cseg01:C00029B4 test eax, eax
+cseg01:C00029B6 jnz short loc_C0002992
+cseg01:C00029B8
+cseg01:C00029B8 loc_C00029B8: ; CODE XREF: sub_C0002983+44j
+cseg01:C00029B8 cmp esi, ebx
+cseg01:C00029BA jle short loc_C00029C9
+cseg01:C00029BC push 30h
+cseg01:C00029BE call sub_C00028B5
+cseg01:C00029C3 add esp, 4
+cseg01:C00029C6 dec esi
+cseg01:C00029C7 jmp short loc_C00029B8
+cseg01:C00029C9 ; ---------------------------------------------------------------------------
+cseg01:C00029C9
+cseg01:C00029C9 loc_C00029C9: ; CODE XREF: sub_C0002983+37j
+cseg01:C00029C9 ; sub_C0002983+56j
+cseg01:C00029C9 dec ebx
+cseg01:C00029CA movzx eax, [esp+ebx+10h+var_10]
+cseg01:C00029CE push eax
+cseg01:C00029CF call sub_C00028B5
+cseg01:C00029D4 add esp, 4
+cseg01:C00029D7 test ebx, ebx
+cseg01:C00029D9 jnz short loc_C00029C9
+cseg01:C00029DB add esp, 8
+cseg01:C00029DE
+cseg01:C00029DE loc_C00029DE: ; CODE XREF: sub_C00029E1+11j
+cseg01:C00029DE pop esi
+cseg01:C00029DF pop ebx
+cseg01:C00029E0 retn
+cseg01:C00029E0 sub_C0002983 endp
+cseg01:C00029E0
+cseg01:C00029E1
+cseg01:C00029E1 ; =============== S U B R O U T I N E =======================================
+cseg01:C00029E1
+cseg01:C00029E1
+cseg01:C00029E1 sub_C00029E1 proc near ; CODE XREF: sub_C0002A03+121p
+cseg01:C00029E1
+cseg01:C00029E1 arg_0 = dword ptr 4
+cseg01:C00029E1 arg_4 = dword ptr 8
+cseg01:C00029E1
+cseg01:C00029E1 push ebx
+cseg01:C00029E2 push esi
+cseg01:C00029E3 mov esi, [esp+8+arg_4]
+cseg01:C00029E7 mov ebx, [esp+8+arg_0]
+cseg01:C00029EB
+cseg01:C00029EB loc_C00029EB: ; CODE XREF: sub_C00029E1+20j
+cseg01:C00029EB mov gs, esi
+cseg01:C00029ED mov al, gs:[ebx]
+cseg01:C00029F0 test al, al
+cseg01:C00029F2 jz short loc_C00029DE
+cseg01:C00029F4 movzx eax, al
+cseg01:C00029F7 push eax
+cseg01:C00029F8 inc ebx
+cseg01:C00029F9 call sub_C00028B5
+cseg01:C00029FE add esp, 4
+cseg01:C0002A01 jmp short loc_C00029EB
+cseg01:C0002A01 sub_C00029E1 endp
+cseg01:C0002A01
+cseg01:C0002A03
+cseg01:C0002A03 ; =============== S U B R O U T I N E =======================================
+cseg01:C0002A03
+cseg01:C0002A03
+cseg01:C0002A03 sub_C0002A03 proc near ; CODE XREF: sub_C000050A+5p
+cseg01:C0002A03 ; sub_C000055F+102p ...
+cseg01:C0002A03
+cseg01:C0002A03 var_18 = word ptr -18h
+cseg01:C0002A03 var_14 = byte ptr -14h
+cseg01:C0002A03 var_10 = byte ptr -10h
+cseg01:C0002A03 arg_0 = dword ptr 4
+cseg01:C0002A03 arg_4 = byte ptr 8
+cseg01:C0002A03
+cseg01:C0002A03 push ebx
+cseg01:C0002A04 push esi
+cseg01:C0002A05 push edi
+cseg01:C0002A06 sub esp, 0Ch
+cseg01:C0002A09 lea esi, [esp+18h+arg_4]
+cseg01:C0002A0D jmp loc_C0002B63
+cseg01:C0002A12 ; ---------------------------------------------------------------------------
+cseg01:C0002A12
+cseg01:C0002A12 loc_C0002A12: ; CODE XREF: sub_C0002A03+193j
+cseg01:C0002A12 mov eax, [esp+18h+arg_0]
+cseg01:C0002A16 mov al, [eax]
+cseg01:C0002A18 cmp al, 6Ch
+cseg01:C0002A1A jz short loc_C0002A20
+cseg01:C0002A1C cmp al, 57h
+cseg01:C0002A1E jnz short loc_C0002A31
+cseg01:C0002A20
+cseg01:C0002A20 loc_C0002A20: ; CODE XREF: sub_C0002A03+17j
+cseg01:C0002A20 mov eax, [esp+18h+arg_0]
+cseg01:C0002A24 lea edx, [eax+1]
+cseg01:C0002A27 mov [esp+18h+arg_0], edx
+cseg01:C0002A2B mov al, [eax]
+cseg01:C0002A2D mov [esp+18h+var_14], al
+cseg01:C0002A31
+cseg01:C0002A31 loc_C0002A31: ; CODE XREF: sub_C0002A03+1Bj
+cseg01:C0002A31 mov eax, [esp+18h+arg_0]
+cseg01:C0002A35 mov al, [eax]
+cseg01:C0002A37 cmp al, 70h
+cseg01:C0002A39 jb short loc_C0002A4B
+cseg01:C0002A3B jbe short loc_C0002A5F
+cseg01:C0002A3D cmp al, 78h
+cseg01:C0002A3F jz short loc_C0002A5F
+cseg01:C0002A41 cmp al, 75h
+cseg01:C0002A43 jz short loc_C0002A5F
+cseg01:C0002A45 cmp al, 73h
+cseg01:C0002A47 jz short loc_C0002A5F
+cseg01:C0002A49 jmp short loc_C0002A70
+cseg01:C0002A4B ; ---------------------------------------------------------------------------
+cseg01:C0002A4B
+cseg01:C0002A4B loc_C0002A4B: ; CODE XREF: sub_C0002A03+36j
+cseg01:C0002A4B cmp al, 58h
+cseg01:C0002A4D jb short loc_C0002A5B
+cseg01:C0002A4F jbe short loc_C0002A5F
+cseg01:C0002A51 cmp al, 63h
+cseg01:C0002A53 jb short loc_C0002A70
+cseg01:C0002A55 cmp al, 64h
+cseg01:C0002A57 jbe short loc_C0002A5F
+cseg01:C0002A59 jmp short loc_C0002A70
+cseg01:C0002A5B ; ---------------------------------------------------------------------------
+cseg01:C0002A5B
+cseg01:C0002A5B loc_C0002A5B: ; CODE XREF: sub_C0002A03+4Aj
+cseg01:C0002A5B cmp al, 50h
+cseg01:C0002A5D jnz short loc_C0002A70
+cseg01:C0002A5F
+cseg01:C0002A5F loc_C0002A5F: ; CODE XREF: sub_C0002A03+38j
+cseg01:C0002A5F ; sub_C0002A03+3Cj ...
+cseg01:C0002A5F mov eax, [esp+18h+arg_0]
+cseg01:C0002A63 lea ecx, [eax+1]
+cseg01:C0002A66 mov [esp+18h+arg_0], ecx
+cseg01:C0002A6A mov al, [eax]
+cseg01:C0002A6C mov [esp+18h+var_10], al
+cseg01:C0002A70
+cseg01:C0002A70 loc_C0002A70: ; CODE XREF: sub_C0002A03+46j
+cseg01:C0002A70 ; sub_C0002A03+50j ...
+cseg01:C0002A70 mov ch, [esp+18h+var_10]
+cseg01:C0002A74 test ch, ch
+cseg01:C0002A76 jz loc_C0002B4C
+cseg01:C0002A7C add esi, 4
+cseg01:C0002A7F mov eax, [esi-4]
+cseg01:C0002A82 mov [esp+18h+var_18], ax
+cseg01:C0002A86 cmp ch, 63h
+cseg01:C0002A89 jnz short loc_C0002A94
+cseg01:C0002A8B movzx eax, byte ptr [esp+18h+var_18]
+cseg01:C0002A8F jmp loc_C0002B5A
+cseg01:C0002A94 ; ---------------------------------------------------------------------------
+cseg01:C0002A94
+cseg01:C0002A94 loc_C0002A94: ; CODE XREF: sub_C0002A03+86j
+cseg01:C0002A94 cmp ch, 64h
+cseg01:C0002A97 jnz short loc_C0002AAD
+cseg01:C0002A99 cmp [esp+18h+var_14], 6Ch
+cseg01:C0002A9E jnz short loc_C0002AA9
+cseg01:C0002AA0 push ebx
+cseg01:C0002AA1
+cseg01:C0002AA1 loc_C0002AA1: ; CODE XREF: sub_C0002A03+A8j
+cseg01:C0002AA1 push eax
+cseg01:C0002AA2 call sub_C0002955
+cseg01:C0002AA7 jmp short loc_C0002AC0
+cseg01:C0002AA9 ; ---------------------------------------------------------------------------
+cseg01:C0002AA9
+cseg01:C0002AA9 loc_C0002AA9: ; CODE XREF: sub_C0002A03+9Bj
+cseg01:C0002AA9 push ebx
+cseg01:C0002AAA cwde
+cseg01:C0002AAB jmp short loc_C0002AA1
+cseg01:C0002AAD ; ---------------------------------------------------------------------------
+cseg01:C0002AAD
+cseg01:C0002AAD loc_C0002AAD: ; CODE XREF: sub_C0002A03+94j
+cseg01:C0002AAD cmp ch, 75h
+cseg01:C0002AB0 jnz short loc_C0002ACE
+cseg01:C0002AB2 cmp [esp+18h+var_14], 6Ch
+cseg01:C0002AB7 jnz short loc_C0002AC8
+cseg01:C0002AB9 push ebx
+cseg01:C0002ABA
+cseg01:C0002ABA loc_C0002ABA: ; CODE XREF: sub_C0002A03+C9j
+cseg01:C0002ABA push eax
+cseg01:C0002ABB call sub_C00028FA
+cseg01:C0002AC0
+cseg01:C0002AC0 loc_C0002AC0: ; CODE XREF: sub_C0002A03+A4j
+cseg01:C0002AC0 ; sub_C0002A03+126j
+cseg01:C0002AC0 add esp, 8
+cseg01:C0002AC3 jmp loc_C0002B63
+cseg01:C0002AC8 ; ---------------------------------------------------------------------------
+cseg01:C0002AC8
+cseg01:C0002AC8 loc_C0002AC8: ; CODE XREF: sub_C0002A03+B4j
+cseg01:C0002AC8 push ebx
+cseg01:C0002AC9 movzx eax, ax
+cseg01:C0002ACC jmp short loc_C0002ABA
+cseg01:C0002ACE ; ---------------------------------------------------------------------------
+cseg01:C0002ACE
+cseg01:C0002ACE loc_C0002ACE: ; CODE XREF: sub_C0002A03+ADj
+cseg01:C0002ACE cmp ch, 70h
+cseg01:C0002AD1 jz short loc_C0002AD8
+cseg01:C0002AD3 cmp ch, 50h
+cseg01:C0002AD6 jnz short loc_C0002B1B
+cseg01:C0002AD8
+cseg01:C0002AD8 loc_C0002AD8: ; CODE XREF: sub_C0002A03+CEj
+cseg01:C0002AD8 mov dl, [esp+18h+var_10]
+cseg01:C0002ADC sub dl, 0Fh
+cseg01:C0002ADF cmp [esp+18h+var_14], 57h
+cseg01:C0002AE4 jnz short loc_C0002B15
+cseg01:C0002AE6 movzx ebx, dl
+cseg01:C0002AE9 push ebx
+cseg01:C0002AEA push 4
+cseg01:C0002AEC shr eax, 10h
+cseg01:C0002AEF push eax
+cseg01:C0002AF0 call sub_C0002983
+cseg01:C0002AF5 add esp, 0Ch
+cseg01:C0002AF8 push 3Ah
+cseg01:C0002AFA call sub_C00028B5
+cseg01:C0002AFF add esp, 4
+cseg01:C0002B02 push ebx
+cseg01:C0002B03
+cseg01:C0002B03 loc_C0002B03: ; CODE XREF: sub_C0002A03+116j
+cseg01:C0002B03 push 4
+cseg01:C0002B05 movzx eax, [esp+20h+var_18]
+cseg01:C0002B0A
+cseg01:C0002B0A loc_C0002B0A: ; CODE XREF: sub_C0002A03+147j
+cseg01:C0002B0A push eax
+cseg01:C0002B0B call sub_C0002983
+cseg01:C0002B10 add esp, 0Ch
+cseg01:C0002B13 jmp short loc_C0002B63
+cseg01:C0002B15 ; ---------------------------------------------------------------------------
+cseg01:C0002B15
+cseg01:C0002B15 loc_C0002B15: ; CODE XREF: sub_C0002A03+E1j
+cseg01:C0002B15 movzx eax, dl
+cseg01:C0002B18 push eax
+cseg01:C0002B19 jmp short loc_C0002B03
+cseg01:C0002B1B ; ---------------------------------------------------------------------------
+cseg01:C0002B1B
+cseg01:C0002B1B loc_C0002B1B: ; CODE XREF: sub_C0002A03+D3j
+cseg01:C0002B1B cmp ch, 73h
+cseg01:C0002B1E jnz short loc_C0002B2B
+cseg01:C0002B20 mov edx, ds
+cseg01:C0002B22 push edx
+cseg01:C0002B23 push eax
+cseg01:C0002B24 call sub_C00029E1
+cseg01:C0002B29 jmp short loc_C0002AC0
+cseg01:C0002B2B ; ---------------------------------------------------------------------------
+cseg01:C0002B2B
+cseg01:C0002B2B loc_C0002B2B: ; CODE XREF: sub_C0002A03+11Bj
+cseg01:C0002B2B cmp ch, 78h
+cseg01:C0002B2E jz short loc_C0002B35
+cseg01:C0002B30 cmp ch, 58h
+cseg01:C0002B33 jnz short loc_C0002B63
+cseg01:C0002B35
+cseg01:C0002B35 loc_C0002B35: ; CODE XREF: sub_C0002A03+12Bj
+cseg01:C0002B35 mov dl, [esp+18h+var_10]
+cseg01:C0002B39 sub dl, 17h
+cseg01:C0002B3C test ebx, ebx
+cseg01:C0002B3E jnz short loc_C0002B45
+cseg01:C0002B40 mov ebx, 8
+cseg01:C0002B45
+cseg01:C0002B45 loc_C0002B45: ; CODE XREF: sub_C0002A03+13Bj
+cseg01:C0002B45 movzx edx, dl
+cseg01:C0002B48 push edx
+cseg01:C0002B49 push ebx
+cseg01:C0002B4A jmp short loc_C0002B0A
+cseg01:C0002B4C ; ---------------------------------------------------------------------------
+cseg01:C0002B4C
+cseg01:C0002B4C loc_C0002B4C: ; CODE XREF: sub_C0002A03+73j
+cseg01:C0002B4C mov eax, [esp+18h+arg_0]
+cseg01:C0002B50 lea ebx, [eax+1]
+cseg01:C0002B53 mov [esp+18h+arg_0], ebx
+cseg01:C0002B57
+cseg01:C0002B57 loc_C0002B57: ; CODE XREF: sub_C0002A03+1B5j
+cseg01:C0002B57 movzx eax, byte ptr [eax]
+cseg01:C0002B5A
+cseg01:C0002B5A loc_C0002B5A: ; CODE XREF: sub_C0002A03+8Cj
+cseg01:C0002B5A push eax
+cseg01:C0002B5B call sub_C00028B5
+cseg01:C0002B60 add esp, 4
+cseg01:C0002B63
+cseg01:C0002B63 loc_C0002B63: ; CODE XREF: sub_C0002A03+Aj
+cseg01:C0002B63 ; sub_C0002A03+C0j ...
+cseg01:C0002B63 mov eax, [esp+18h+arg_0]
+cseg01:C0002B67 cmp byte ptr [eax], 0
+cseg01:C0002B6A jz short loc_C0002BBA
+cseg01:C0002B6C lea edx, [eax+1]
+cseg01:C0002B6F cmp byte ptr [eax], 25h
+cseg01:C0002B72 jnz short loc_C0002BB4
+cseg01:C0002B74 mov [esp+18h+var_10], 0
+cseg01:C0002B79 xor ebx, ebx
+cseg01:C0002B7B mov [esp+18h+var_14], 0
+cseg01:C0002B80 mov [esp+18h+arg_0], edx
+cseg01:C0002B84
+cseg01:C0002B84 loc_C0002B84: ; CODE XREF: sub_C0002A03+1AFj
+cseg01:C0002B84 mov eax, [esp+18h+arg_0]
+cseg01:C0002B88 movzx eax, byte ptr [eax]
+cseg01:C0002B8B push eax
+cseg01:C0002B8C call sub_C00028E3
+cseg01:C0002B91 add esp, 4
+cseg01:C0002B94 test eax, eax
+cseg01:C0002B96 jz loc_C0002A12
+cseg01:C0002B9C imul ebx, 0Ah
+cseg01:C0002B9F mov eax, [esp+18h+arg_0]
+cseg01:C0002BA3 lea edi, [eax+1]
+cseg01:C0002BA6 mov [esp+18h+arg_0], edi
+cseg01:C0002BAA movzx eax, byte ptr [eax]
+cseg01:C0002BAD sub eax, 30h
+cseg01:C0002BB0 add ebx, eax
+cseg01:C0002BB2 jmp short loc_C0002B84
+cseg01:C0002BB4 ; ---------------------------------------------------------------------------
+cseg01:C0002BB4
+cseg01:C0002BB4 loc_C0002BB4: ; CODE XREF: sub_C0002A03+16Fj
+cseg01:C0002BB4 mov [esp+18h+arg_0], edx
+cseg01:C0002BB8 jmp short loc_C0002B57
+cseg01:C0002BBA ; ---------------------------------------------------------------------------
+cseg01:C0002BBA
+cseg01:C0002BBA loc_C0002BBA: ; CODE XREF: sub_C0002A03+167j
+cseg01:C0002BBA add esp, 0Ch
+cseg01:C0002BBD pop edi
+cseg01:C0002BBE pop esi
+cseg01:C0002BBF pop ebx
+cseg01:C0002BC0 retn
+cseg01:C0002BC0 sub_C0002A03 endp
+cseg01:C0002BC0
+cseg01:C0002BC0 ; ---------------------------------------------------------------------------
+cseg01:C0002BC1 align 800h
+cseg01:C0002BC1 cseg01 ends
+cseg01:C0002BC1
+cseg01:C0002BC1
+cseg01:C0002BC1 end Control_0
diff --git a/vmwsvxd.c b/vmwsvxd.c
deleted file mode 100644
index f36941d..0000000
--- a/vmwsvxd.c
+++ /dev/null
@@ -1,1613 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2023 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 VXD32
-#define SVGA
-
-#include "winhack.h"
-#include "vmm.h"
-#include "vxdcodes.h"
-
-#include "svga_all.h"
-
-#include "minivdd32.h"
-
-#include "version.h"
-
-#ifndef ERROR_SUCCESS
-#define ERROR_SUCCESS 0
-#endif
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
-
-#define PTONPAGE (PAGE_SIZE/sizeof(DWORD))
-
-#if 0
-/* dynamic VXDs don't using this init function in discardable segment */
-
-#pragma data_seg("_ITEXT", "ICODE")
-#pragma code_seg("_ITEXT", "ICODE")
-
-BOOL __cdecl VMWS_Sys_Critical_Init(DWORD hVM, DWORD dwRefData,
- PSTR pCmdTail, PCRS_32 pCRS)
-{
- return TRUE;
-}
-
-BOOL __cdecl VMWS_Device_Init(DWORD hVM, PSTR pCmdTail, PCRS_32 pCRS)
-{
- return TRUE;
-}
-
-#endif
-
-#include "code32.h"
-
-void VMWS_Control();
-void VMWS_API_Entry();
-
-/*
- VXD structure
- this variable must be in first address in code segment.
- In other cases VXD isn't loadable (WLINK bug?)
-*/
-DDB VMWS_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",
- VDD_Init_Order, //Undefined_Init_Order,
- (DWORD)VMWS_Control,
- (DWORD)VMWS_API_Entry,
- (DWORD)VMWS_API_Entry,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, // DDB_Win32_Service_Table
- NULL, // prev
- sizeof(DDB)
-};
-
-/* string tables */
-#ifdef DBGPRINT
-char dbg_hello[] = "Hello world!\n";
-char dbg_version[] = "VMM version: ";
-char dbg_region_err[] = "region create error\n";
-
-char dbg_Device_Init_proc[] = "Device_Init_proc\n";
-char dbg_Device_Init_proc_succ[] = "Device_Init_proc success\n";
-char dbg_dic_ring[] = "DeviceIOControl: Ring\n";
-char dbg_dic_sync[] = "DeviceIOControl: Sync\n";
-char dbg_dic_unknown[] = "DeviceIOControl: Unknown: %d\n";
-char dbg_dic_system[] = "DeviceIOControl: System code: %d\n";
-char dbg_get_ppa[] = "%lx -> %lx\n";
-char dbg_get_ppa_beg[] = "Virtual: %lx\n";
-char dbg_mob_allocate[] = "Allocated OTable row: %d\n";
-
-char dbg_str[] = "%s\n";
-
-char dbg_submitcb_fail[] = "CB submit FAILED\n";
-char dbg_submitcb[] = "CB submit %d\n";
-char dbg_lockcb[] = "Reused CB (%d) with status: %d\n";
-
-char dbg_lockcb_lasterr[] = "Error command: %lX\n";
-
-char dbg_cb_on[] = "CB supported and allocated\n";
-char dbg_gb_on[] = "GB supported and allocated\n";
-char dbg_cb_ena[] = "CB context 0 enabled\n";
-
-char dbg_region_info_1[] = "Region id = %d\n";
-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";
-
-#endif
-
-typedef struct _otinfo_entry_t
-{
- DWORD phy;
- void *lin;
- DWORD size;
- DWORD flags;
-} otinfo_entry_t;
-
-typedef struct _cmd_buf_t
-{
- DWORD phy;
- void *lin;
- DWORD status;
-} cmd_buf_t;
-
-#define CB_STATUS_EMPTY 0 /* buffer was not used yet */
-#define CB_STATUS_LOCKED 1 /* buffer is using by Ring-3 proccess */
-#define CB_STATUS_PROCESS 2 /* buffer is register by VGPU */
-
-#define CB_COUNT 4
-
-uint64 cmd_buf_next_id = {0, 0};
-
-cmd_buf_t cmd_bufs[CB_COUNT] = {{0}};
-
-int queued_cmd_buf = -1;
-
-BOOL cb_support = FALSE;
-BOOL gb_support = FALSE;
-BOOL cb_context0 = FALSE;
-
-#define ROUND_TO_PAGES(_cb)((((_cb) + PAGE_SIZE - 1)/PAGE_SIZE)*PAGE_SIZE)
-
-#define SVGA3D_MAX_MOBS (SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS)
-#define VBOX_VIDEO_MAX_SCREENS 64
-
-#define FLAG_ALLOCATED 1
-#define FLAG_ACTIVE 2
-
-otinfo_entry_t otable[SVGA_OTABLE_DX_MAX] = {
- {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_MOBS*sizeof(SVGAOTableMobEntry)), 0}, /* SVGA_OTABLE_MOB */
- {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_SURFACE_IDS*sizeof(SVGAOTableSurfaceEntry)), 0}, /* SVGA_OTABLE_SURFACE */
- {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableContextEntry)), 0}, /* SVGA_OTABLE_CONTEXT */
- {0, NULL, 0, 0}, /* SVGA_OTABLE_SHADER - not used */
- {0, NULL, ROUND_TO_PAGES(VBOX_VIDEO_MAX_SCREENS*sizeof(SVGAOTableScreenTargetEntry)), 0}, /* SVGA_OTABLE_SCREENTARGET (VBOX_VIDEO_MAX_SCREENS) */
- {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableDXContextEntry)), 0}, /* SVGA_OTABLE_DXCONTEXT */
-};
-
-DWORD *DispatchTable = 0;
-DWORD DispatchTableLength = 0;
-DWORD ThisVM = 0;
-
-Bool svga_init_success = FALSE;
-
-/**
- * VMM calls wrapers
- **/
-DWORD Get_VMM_Version()
-{
- static WORD ver = 0;
-
- _asm push ecx
- _asm push eax
- _asm xor eax, eax
- VMMCall(Get_VMM_Version);
- _asm mov [ver],ax
- _asm pop ecx
- _asm pop eax
-
- return ver;
-}
-
-ULONG __declspec(naked) __cdecl _PageAllocate(ULONG nPages, ULONG pType, ULONG VM, ULONG AlignMask, ULONG minPhys, ULONG maxPhys, ULONG *PhysAddr, ULONG flags)
-{
- VMMJmp(_PageAllocate);
-}
-
-ULONG __declspec(naked) __cdecl _PageFree(PVOID hMem, DWORD flags)
-{
- VMMJmp(_PageFree);
-}
-
-ULONG __declspec(naked) __cdecl _CopyPageTable(ULONG LinPgNum, ULONG nPages, DWORD *PageBuf, ULONG flags)
-{
- VMMJmp(_CopyPageTable);
-}
-
-ULONG __declspec(naked) __cdecl _LinPageLock(ULONG page, ULONG npages, ULONG flags)
-{
- VMMJmp(_LinPageLock);
-}
-
-ULONG __declspec(naked) __cdecl _LinPageUnLock(ULONG page, ULONG npages, ULONG flags)
-{
- VMMJmp(_LinPageUnLock);
-}
-
-ULONG __declspec(naked) __cdecl _MapPhysToLinear(ULONG PhysAddr, ULONG nBytes, ULONG flags)
-{
- 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
- **/
-void VDD_Get_Mini_Dispatch_Table()
-{
- VxDCall(VDD, Get_Mini_Dispatch_Table);
- _asm mov [DispatchTable],edi
- _asm mov [DispatchTableLength],ecx
-}
-
-/**
- * Control Handles
- **/
-void Sys_Critical_Init_proc()
-{
- // nop
-}
-
-/*
- * 32-bit DeviceIoControl ends here
- *
- */
-#define SVGA_DBG 0x110B
-#define SVGA_REGION_CREATE 0x1114
-#define SVGA_REGION_FREE 0x1115
-#define SVGA_SYNC 0x1116
-#define SVGA_RING 0x1117
-#define SVGA_ALLOCPHY 0x1200
-#define SVGA_FREEPHY 0x1201
-#define SVGA_OTABLE_QUERY 0x1202
-#define SVGA_OTABLE_FLAGS 0x1203
-
-#define SVGA_CB_LOCK 0x1204
-#define SVGA_CB_SUBMIT 0x1205
-#define SVGA_CB_SYNC 0x1206
-#define SVGA_CB_SUBMIT_SYNC 0x1207
-
-DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params);
-
-void __declspec(naked) Device_IO_Control_proc()
-{
- _asm {
- push esi /* struct DIOCParams */
- call Device_IO_Control_entry
- retn
- }
-}
-
-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, ...)
- * clear carry if succes (this is always success)
- */
-void __declspec(naked) VMWS_Control()
-{
- // eax = 0x00 - Sys Critical Init
- // eax = 0x01 - sys dynamic init
- // eax = 0x1B - dynamic init
- // eax = 0x1C - dynamic exit
- // eax = 0x23 - device IO control
-
- _asm {
- cmp eax,Sys_Critical_Init
- jnz control_1
- pushad
- call Sys_Critical_Init_proc
- popad
- clc
- ret
- control_1:
- cmp eax,Device_Init
- jnz control_2
- call Device_Init_proc
- popad
- clc
- ret
- control_2:
- cmp eax,0x1B
- jnz control_3
- pushad
- push ebx ; VM handle
- call Device_Dynamic_Init_proc
- popad
- clc
- ret
- control_3:
- cmp eax,W32_DEVICEIOCONTROL
- 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
- };
-}
-
-/**
- * Return PPN (physical page number) from virtual address
- *
- **/
-static DWORD getPPN(DWORD virtualaddr)
-{
- DWORD phy = 0;
- _CopyPageTable(virtualaddr/P_SIZE, 1, &phy, 0);
- return phy/P_SIZE;
-}
-
-/**
- * Allocate guest memory region (GMR) - HW needs know memory physical
- * addressed of pages in (virtual) memory block.
- * Technically this allocate 2 memory block, 1st for data and 2nd as its
- * physical description.
- *
- * @param nPages: number of pages to allocate
- * @param outDataAddr: linear address (system space) of data block
- * @param outGMRAddr: linear address of GMR block
- * @param outPPN: physical page number of outGMRAddr (first page)
- * @param outMobAddr: linear address of MOB PT block - if is NOT null,
- * extra memory of MOB maybe allocated. If result
- * is NULL, MOB is full flat (no PT needed).
- * @param outMobPPN: physical page number of MOB
- *
- * @return: TRUE on success
- *
- **/
-static BOOL GMRAlloc(ULONG nPages, ULONG *outDataAddr, ULONG *outGMRAddr, ULONG *outPPN,
- ULONG *outMobAddr, ULONG *outMobPPN)
-{
- ULONG phy;
- ULONG pgblk_phy;
- ULONG laddr;
- ULONG pgblk;
- SVGAGuestMemDescriptor *desc;
- laddr = _PageAllocate(nPages, PG_SYS, 0, 0, 0x0, 0x100000, &phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
-
- if(laddr)
- {
- pgblk = _PageAllocate(1, PG_SYS, 0, 0, 0x0, 0x100000, &pgblk_phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
- if(pgblk)
- {
- desc = (SVGAGuestMemDescriptor*)pgblk;
- desc->ppn = (phy/P_SIZE);
- desc->numPages = nPages;
- desc++;
- desc->ppn = 0;
- desc->numPages = 0;
-
- *outDataAddr = laddr;
- *outGMRAddr = pgblk;
- *outPPN = (pgblk_phy/P_SIZE);
-
- if(outMobAddr)
- *outMobAddr = 0;
-
- if(outMobPPN)
- *outMobPPN = (phy/P_SIZE);
-
- return TRUE;
- }
- else
- {
- _PageFree((PVOID)laddr, 0);
- return FALSE;
- }
- }
- else
- {
- ULONG taddr;
- ULONG tppn;
- ULONG pgi;
- ULONG base_ppn;
- ULONG base_cnt;
- ULONG blocks = 1;
- ULONG blk_pages = 0;
-
- laddr = _PageAllocate(nPages, PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
-
- if(laddr)
- {
- /* determine how many physical continuous blocks we have */
- base_ppn = getPPN(laddr);
- base_cnt = 1;
- for(pgi = 1; pgi < nPages; pgi++)
- {
- taddr = laddr + pgi*P_SIZE;
- tppn = getPPN(taddr);
-
- if(tppn != base_ppn + base_cnt)
- {
- base_ppn = tppn;
- base_cnt = 1;
- blocks++;
- }
- else
- {
- base_cnt++;
- }
- }
-
- // number of pages to store regions information
- blk_pages = ((blocks+1)/(P_SIZE/sizeof(SVGAGuestMemDescriptor))) + 1;
-
- // 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, NULL, PAGEFIXED);
- if(pgblk)
- {
- desc = (SVGAGuestMemDescriptor*)pgblk;
- desc->ppn = getPPN(laddr);
- desc->numPages = 1;
- blocks = 1;
-
- for(pgi = 1; pgi < nPages; pgi++)
- {
- taddr = laddr + pgi*P_SIZE;
- tppn = getPPN(taddr);
-
- if(tppn == desc->ppn + desc->numPages)
- {
- desc->numPages++;
- }
- else
- {
- /* next descriptor is on page edge */
- if((blocks+1) % (P_SIZE/sizeof(SVGAGuestMemDescriptor)) == 0)
- {
- desc++;
- desc->numPages = 0;
- desc->ppn = getPPN((DWORD)(desc+1));
- //dbg_printf(old_new_ppn, blocks, getPPN((DWORD)(desc)), getPPN((DWORD)(desc+1)), getPPN((DWORD)(desc+2)));
- blocks++;
- }
-
- desc++;
- desc->ppn = tppn;
- desc->numPages = 1;
- blocks++;
- }
- }
-
- desc++;
- desc->ppn = 0;
- desc->numPages = 0;
-
- *outDataAddr = laddr;
- *outGMRAddr = pgblk;
- *outPPN = getPPN(pgblk); //(pgblk_phy/P_SIZE);
-
- if(outMobAddr)
- {
- if(gb_support) /* don't create MOBs for Gen9 */
- {
- 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)
- {
- 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;
- }
- else
- {
- *outMobAddr = NULL;
- if(outMobPPN) *outMobPPN = getPPN(laddr);
- }
- }
- else
- {
- *outMobAddr = NULL;
- if(outMobPPN) *outMobPPN = NULL;
- }
- }
-
- return TRUE;
- }
- else
- {
- _PageFree((PVOID)laddr, 0);
- return FALSE;
- }
- }
- }
-
- return FALSE;
-}
-
-/**
- * Free data allocated by GMRAlloc
- *
- **/
-static BOOL GMRFree(ULONG DataAddr, ULONG GMRAddr, ULONG MobAddr)
-{
- BOOL ret = FALSE;
-
- if(_PageFree((PVOID)DataAddr, 0) != 0)
- {
- ret = TRUE;
- }
-
- if(_PageFree((PVOID)GMRAddr, 0) != 0)
- {
- ret = TRUE;
- }
-
- if(MobAddr != 0)
- {
- _PageFree((PVOID)MobAddr, 0);
- }
-
- return ret;
-}
-
-/**
- * Allocate OTable for GB objects
- **/
-static void AllocateOTable()
-{
- int i;
- for(i = 0; i < SVGA_OTABLE_DX_MAX; i++)
- {
- otinfo_entry_t *entry = &otable[i];
- if(entry->size != 0 && (entry->flags & FLAG_ALLOCATED) == 0)
- {
- entry->lin = (void*)_PageAllocate(entry->size/PAGE_SIZE, PG_SYS, 0, 0, 0x0, 0x100000, &entry->phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
- if(entry->lin)
- {
- dbg_printf(dbg_mob_allocate, i);
- entry->flags |= FLAG_ALLOCATED;
- }
- }
- }
-}
-
-/**
- * Allocate Command Buffers
- **/
-static void AllocateCB()
-{
- int i;
- for(i = 0; i < CB_COUNT; i++)
- {
- if(cmd_bufs[i].phy == 0)
- {
- cmd_bufs[i].lin = (void *)_PageAllocate((SVGA_CB_MAX_SIZE+PAGE_SIZE-1)/PAGE_SIZE, PG_SYS, 0, 0, 0x0, 0x100000, &(cmd_bufs[i].phy), PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
- cmd_bufs[i].status = CB_STATUS_EMPTY;
- }
- }
-}
-
-/**
- * Test if selected CB is not used
- **/
-static BOOL isCBfree(int index)
-{
- switch(cmd_bufs[index].status)
- {
- case CB_STATUS_EMPTY:
- return TRUE;
- case CB_STATUS_PROCESS:
- {
- SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
- if(cb->status > SVGA_CB_STATUS_NONE)
- {
- return TRUE;
- }
- break;
- }
- }
-
- return FALSE;
-}
-
-/**
- * Increment 64-bit ID of CB segment
- **/
-static void nextID_CB()
-{
- _asm
- {
- inc dword ptr [cmd_buf_next_id]
- adc dword ptr [cmd_buf_next_id+4], 0
- }
-}
-
-/**
- * Lock one of buffers and return ptr for RING-3
- **/
-static void *LockCB()
-{
- int index;
- for(index = 0; index < CB_COUNT; index++)
- {
- if(isCBfree(index))
- {
-#ifdef DBGPRINT
- {
- SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
- if(cb->status > 1)
- {
- dbg_printf(dbg_lockcb, index, cb->status);
-
- if(cb->status == SVGA_CB_STATUS_COMMAND_ERROR)
- {
- DWORD *ptr = (DWORD*)(((unsigned char*)cmd_bufs[index].lin) + sizeof(SVGACBHeader) + cb->errorOffset);
- dbg_printf(dbg_lockcb_lasterr, *ptr);
- }
-
- }
- }
-#endif
- cmd_bufs[index].status = CB_STATUS_LOCKED;
-
- if(queued_cmd_buf == index)
- {
- queued_cmd_buf = -1;
- }
-
- return cmd_bufs[index].lin;
- }
- }
-
- return NULL;
-}
-
-/**
- * Submit CB to GPU.
- * If length is 0, buffer not executed
- * cbctx_id = SVGA_CB_CONTEXT_0,...
- **/
-
-static BOOL submitCB(void *ptr, DWORD cbctx_id, BOOL sync)
-{
- int index;
-
- /* context 0 is turned on and of by driver and if it is off don't use it! */
- if(cb_context0 == FALSE && cbctx_id == SVGA_CB_CONTEXT_0)
- {
- return FALSE;
- }
-
- for(index = 0; index < CB_COUNT; index++)
- {
- if(cmd_bufs[index].lin == ptr)
- {
- SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
- if(cb->length > 0)
- {
- cb->status = SVGA_CB_STATUS_NONE;
- cb->ptr.pa.hi = 0;
- cb->ptr.pa.low = cmd_bufs[index].phy + sizeof(SVGACBHeader);
- cb->flags |= SVGA_CB_FLAG_NO_IRQ;
- cb->id.low = cmd_buf_next_id.low;
- cb->id.hi = cmd_buf_next_id.hi;
-
-#if 0
- if(queued_cmd_buf >= 0)
- {
- /* wait to complete the last command */
- SVGACBHeader *cb_queued = (SVGACBHeader *)cmd_bufs[queued_cmd_buf].lin;
-
- while(cb_queued->status == SVGA_CB_STATUS_NONE)
- {
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- }
- }
-#endif
-
- SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0); // high part of 64-bit memory address...
- SVGA_WriteReg(SVGA_REG_COMMAND_LOW, cmd_bufs[index].phy | cbctx_id);
- cmd_bufs[index].status = CB_STATUS_PROCESS;
-
- if(sync)
- {
- while(cb->status == SVGA_CB_STATUS_NONE)
- {
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- }
- queued_cmd_buf = -1;
- }
- else
- {
- queued_cmd_buf = index;
- }
-
- //dbg_printf(dbg_submitcb, cbctx_id);
-
- nextID_CB();
- }
- else
- {
- cmd_bufs[index].status = CB_STATUS_EMPTY;
- }
-
- return TRUE;
- }
- }
-
- dbg_printf(dbg_submitcb_fail);
-
- return FALSE;
-}
-
-/**
- * Wait until all CB are completed
- **/
-static void syncCB()
-{
- int index;
- BOOL synced;
- do
- {
- synced = TRUE;
- for(index = 0; index < CB_COUNT; index++)
- {
- switch(cmd_bufs[index].status)
- {
- case CB_STATUS_EMPTY:
- case CB_STATUS_LOCKED:
- break;
- case CB_STATUS_PROCESS:
- {
- SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
- if(cb->status == SVGA_CB_STATUS_NONE)
- {
- synced = FALSE;
- }
- break;
- }
- }
- }
-
- if(!synced)
- {
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- }
- } while(!synced);
-}
-
-/**
- * PM16 driver RING0 calls
- **/
-BOOL CreateRegion(unsigned int nPages, ULONG *lpLAddr, ULONG *lpPPN, ULONG *lpPGBLK)
-{
- return GMRAlloc(nPages, lpLAddr, lpPGBLK, lpPPN, NULL, NULL);
-}
-
-BOOL FreeRegion(ULONG LAddr, ULONG PGBLK, ULONG MobAddr)
-{
- return GMRFree(LAddr, PGBLK, MobAddr);
-}
-
-/* some CRT */
-void memset(void *dst, int c, unsigned int size)
-{
- unsigned int par;
- unsigned int i;
- unsigned int dw_count;
- unsigned int dw_size;
-
- c &= 0xFF;
- par = (c << 24) | (c << 16) | (c << 8) | c;
- dw_count = size >> 2;
- dw_size = size & 0xFFFFFFFCUL;
-
- for(i = 0; i < dw_count; i++)
- {
- ((unsigned int*)dst)[i] = par;
- }
-
- for(i = dw_size; i < size; i++)
- {
- ((unsigned char*)dst)[i] = c;
- }
-}
-
-void *memcpy(void *dst, const void *src, unsigned int size)
-{
- unsigned int dw_count;
- unsigned int dw_size;
- unsigned int i;
-
- dw_count = size >> 2;
- dw_size = size & 0xFFFFFFFCUL;
-
- for(i = 0; i < dw_count; i++)
- {
- ((unsigned int*)dst)[i] = ((unsigned int*)src)[i];
- }
-
- for(i = dw_size; i < size; i++)
- {
- ((unsigned char*)dst)[i] = ((unsigned char*)src)[i];
- }
-
- return dst;
-}
-
-
-#if 0
-/* I'm using this sometimes for developing, not for end user! */
-BOOL AllocPhysical(DWORD nPages, DWORD *outLinear, DWORD *outPhysical)
-{
- *outLinear = _PageAllocate(nPages, PG_SYS, 0, 0, 0x0, 0x100000, outPhysical, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
-
- if(*outLinear != NULL)
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
-void FreePhysical(DWORD linear)
-{
- _PageFree((void*)linear, 0);
-}
-#endif
-
-#pragma pack(push)
-#pragma pack(1)
-typedef struct _cb_enable_t
-{
- SVGACBHeader cbheader;
- uint32 cmd;
- SVGADCCmdStartStop cbstart;
-} cb_enable_t;
-#pragma pack(pop)
-
-/* process V86/PM16 calls */
-WORD __stdcall VMWS_API_Proc(PCRS_32 state)
-{
- WORD rc = 0xFFFF;
- WORD service = state->Client_EDX & 0xFFFF;
- switch(service)
- {
- case VXD_PM16_VERSION:
- rc = (VXD_MAJOR_VER << 8) | VXD_MINOR_VER;
- break;
- case VXD_PM16_VMM_VERSION:
- rc = Get_VMM_Version();
- break;
- /* create region = input: ECX - num_pages; output: EDX - lin. address of descriptor, ECX - PPN of descriptor */
- case VMWSVXD_PM16_CREATE_REGION:
- {
- ULONG lAddr;
- ULONG PPN;
- ULONG PGBLK;
-
- if(CreateRegion(state->Client_ECX, &lAddr, &PPN, &PGBLK))
- {
- state->Client_ECX = PPN;
- state->Client_EDX = lAddr;
- state->Client_EBX = PGBLK;
- rc = 1;
- }
- else
- {
- state->Client_ECX = 0;
- state->Client_EDX = 0;
- state->Client_EBX = 0;
-
- dbg_printf(dbg_region_err);
-
- rc = 0;
- }
- break;
- }
- /* free region = input: ECX: lin. address */
- case VMWSVXD_PM16_DESTROY_REGION:
- {
- if(FreeRegion(state->Client_ECX, state->Client_EBX, 0))
- {
- rc = 1;
- }
- else
- {
- rc = 0;
- }
- break;
- }
- /* clear memory on linear address (ESI) by defined size (ECX) */
- case VXD_PM16_ZEROMEM:
- memset((void*)state->Client_ESI, 0, state->Client_ECX);
- rc = 1;
- break;
- /* set ECX to actual api version */
- case VMWSVXD_PM16_APIVER:
- state->Client_ECX = DRV_API_LEVEL;
- rc = 1;
- break;
- case VMWSVXD_PM16_CB_START:
- if(cb_support)
- {
- cb_enable_t *cbe;
- 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 = 1;
- cbe->cbstart.context = SVGA_CB_CONTEXT_0;
- submitCB(cbe, SVGA_CB_CONTEXT_DEVICE, FALSE);
-
- dbg_printf(dbg_cb_ena);
- cb_context0 = TRUE;
- }
- rc = 1;
- break;
- case VMWSVXD_PM16_CB_STOP:
- if(cb_support)
- {
- 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);
- }
- rc = 1;
- break;
- case VMWSVXD_PM16_GET_ADDR:
- state->Client_ECX = gSVGA.fbLinear;
- if(SVGA_IsSVGA3())
- {
- state->Client_EDI = gSVGA.rmmio_linear;
- }
- else
- {
- state->Client_EDI = gSVGA.fifoLinear;
- }
- state->Client_ESI = gSVGA.fifo.bounceLinear + PAGE_SIZE; /* first page is for CB header (if CB supported) */
-
- rc = 1;
- break;
- case VMWSVXD_PM16_FIFO_COMMIT:
- {
- DWORD cmd_size = state->Client_ECX;
- if(cb_support && cb_context0) /* command buffer is supported - use CB instead of FIFO */
- {
-#if 0
- SVGACBHeader *cb = (SVGACBHeader *)gSVGA.fifo.bounceLinear;
- memset(cb, 0, sizeof(SVGACBHeader));
-
- cb->length = cmd_size;
- cb->status = SVGA_CB_STATUS_NONE;
- cb->ptr.pa.hi = 0;
- cb->ptr.pa.low = gSVGA.fifo.bouncePhy + PAGE_SIZE;
- cb->flags = SVGA_CB_FLAG_NO_IRQ;
-
- cb->id.low = cmd_buf_next_id.low;
- cb->id.hi = cmd_buf_next_id.hi;
-
- SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0);
- SVGA_WriteReg(SVGA_REG_COMMAND_LOW, gSVGA.fifo.bouncePhy | SVGA_CB_CONTEXT_0);
-
- nextID_CB();
-
- /* wait to complete */
- while(cb->status == SVGA_CB_STATUS_NONE)
- {
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- }
-#endif
- SVGACBHeader *cb;
-
- do
- {
- cb = LockCB();
- } while(cb == NULL);
- memset(cb, 0, sizeof(SVGACBHeader));
- cb->length = cmd_size;
- memcpy(cb+1, gSVGA.fifo.bounceMem, cmd_size);
-
- submitCB(cb, SVGA_CB_CONTEXT_0, TRUE);
- }
- else /* use FIFO */
- {
- gSVGA.fifo.reservedSize = cmd_size;
- SVGA_FIFOCommit(cmd_size);
- }
-
- rc = 1;
- break;
- }
- case VMWSVXD_PM16_FIFO_COMMIT_SYNC:
- {
- DWORD cmd_size = state->Client_ECX;
- if(cb_support && cb_context0) /* command buffer is supported - use CB instead of FIFO */
- {
- SVGACBHeader *cb = (SVGACBHeader *)gSVGA.fifo.bounceLinear;
- memset(cb, 0, sizeof(SVGACBHeader));
-
- cb->length = cmd_size;
- cb->status = SVGA_CB_STATUS_NONE;
- cb->ptr.pa.hi = 0;
- cb->ptr.pa.low = gSVGA.fifo.bouncePhy + PAGE_SIZE;
- cb->flags = SVGA_CB_FLAG_NO_IRQ;
-
- cb->id.low = cmd_buf_next_id.low;
- cb->id.hi = cmd_buf_next_id.hi;
-
- SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0);
- SVGA_WriteReg(SVGA_REG_COMMAND_LOW, gSVGA.fifo.bouncePhy | SVGA_CB_CONTEXT_0);
-
- nextID_CB();
-
- /* wait to complete */
- while(cb->status == SVGA_CB_STATUS_NONE)
- {
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- }
- }
- else /* use FIFO */
- {
- gSVGA.fifo.reservedSize = cmd_size;
- SVGA_FIFOCommit(cmd_size);
- }
-
- rc = 1;
- break;
- }
- case VMWSVXD_PM16_GET_FLAGS:
- state->Client_ECX = gSVGA.userFlags;
- break;
- }
-
- if(rc == 0xFFFF)
- {
- state->Client_EFlags |= 0x1; // set carry
- }
- else
- {
- state->Client_EFlags &= 0xFFFFFFFEUL; // clear carry
- }
-
- return rc;
-}
-
-/*
- * 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
- * function is placed to saved AX register.
- *
- */
-void __declspec(naked) VMWS_API_Entry()
-{
- _asm {
- push ebp
- call VMWS_API_Proc
- mov [ebp+1Ch], ax
- retn
- }
-}
-
-/* generate all entry pro VDD function */
-#define VDDFUNC(_fnname, _procname) void __declspec(naked) _procname ## _entry() { \
- _asm { push ebp }; \
- _asm { call _procname ## _proc }; \
- _asm { retn }; \
- }
-#include "minivdd_func.h"
-#undef VDDFUNC
-
-#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;
-}
-
-void SVGA_MapIO()
-{
- if(SVGA_IsSVGA3)
- {
- gSVGA.rmmio_linear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.vramSize, 0);
- gSVGA.rmmio = (uint32 FARP*)gSVGA.rmmio_linear;
- }
-}
-
-/* init device and fill dispatch table */
-void Device_Dynamic_Init_proc(DWORD VM)
-{
- 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
- 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 = 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)
- {
- if(conf_hw_cursor)
- {
- gSVGA.userFlags |= SVGA_USER_FLAGS_HWCURSOR;
- }
- }
-
- if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_ALPHA_CURSOR)
- {
- if(conf_hw_cursor)
- {
- gSVGA.userFlags |= SVGA_USER_FLAGS_ALPHA_CUR;
- }
- }
-
- if(gSVGA.userFlags & SVGA_USER_FLAGS_128MB_MAX)
- {
- if(gSVGA.vramSize > 128*1024*1024)
- {
- gSVGA.vramSize = 128*1024*1024;
- }
- }
-
- dbg_printf(dbg_Device_Init_proc_succ);
- svga_init_success = TRUE;
-
- dbg_printf(dbg_mapping_map, gSVGA.fbPhy, gSVGA.fifoPhy);
-
- /* map phys FB to linear */
- gSVGA.fbLinear = _MapPhysToLinear(gSVGA.fbPhy, gSVGA.vramSize, 0);
-
- /* map phys FIFO to linear */
- if(!SVGA_IsSVGA3())
- gSVGA.fifoLinear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.fifoSize, 0);
-
- /* allocate fifo bounce buffer */
- gSVGA.fifo.bounceLinear =
- _PageAllocate(
- (SVGA_BOUNCE_SIZE + PAGE_SIZE)/PAGE_SIZE,
- PG_SYS, 0, 0, 0x0, 0x100000, &(gSVGA.fifo.bouncePhy), PAGECONTIG | PAGEUSEALIGN | PAGEFIXED
- );
-
- /* system linear addres == PM32 address */
- gSVGA.fbMem = (uint8 *)gSVGA.fbLinear;
- if(!SVGA_IsSVGA3())
- gSVGA.fifoMem = (uint32 *)gSVGA.fifoLinear;
-
- gSVGA.fifo.bounceMem = (uint8 *)(gSVGA.fifo.bounceLinear + PAGE_SIZE); /* first page is for CB header (if CB supported) */
-
-
- dbg_printf(dbg_mapping);
- dbg_printf(dbg_mapping_map, gSVGA.fbPhy, gSVGA.fbMem);
- dbg_printf(dbg_mapping_map, gSVGA.fifoPhy, gSVGA.fifoMem);
- dbg_printf(dbg_mapping_map, gSVGA.fifo.bouncePhy, gSVGA.fifo.bounceMem);
- dbg_printf(dbg_siz, sizeof(gSVGA), sizeof(uint8 FARP *));
-
- /* enable FIFO */
- SVGA_Enable();
-
- /* allocate GB tables, if supported */
- if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_GBOBJECTS)
- {
- AllocateOTable();
- gb_support = TRUE;
- dbg_printf(dbg_gb_on);
- }
-
- /* allocate command buffers if supported */
- if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & (SVGA_CAP_COMMAND_BUFFERS | SVGA_CAP_CMD_BUFFERS_2))
- {
- if(conf_cb)
- {
- AllocateCB();
- cb_support = TRUE;
- dbg_printf(dbg_cb_on);
- }
- }
-
- /* register miniVDD functions */
- VDD_Get_Mini_Dispatch_Table();
- if(DispatchTableLength >= 0x31)
- {
- #include "minivdd_func.h"
- }
- }
-}
-#undef VDDFUNC
-
-/* process user space (PM32, RING-3) call */
-DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params)
-{
- switch(params->dwIoControlCode)
- {
- case DIOC_OPEN:
- case DIOC_CLOSEHANDLE:
- dbg_printf(dbg_dic_system, params->dwIoControlCode);
- return 0;
- case SVGA_SYNC:
- SVGA_Flush();
- return 0;
- case SVGA_RING:
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- return 0;
-#if 0
- case SVGA_ALLOCPHY:
- {
- DWORD nPages = ((DWORD*)params->lpInBuffer)[0];
- DWORD *linear = &((DWORD*)params->lpOutBuffer)[0];
- DWORD *phy = &((DWORD*)params->lpOutBuffer)[1];
- if(AllocPhysical(nPages, linear, phy))
- {
- return 0;
- }
- return 1;
- }
- case SVGA_FREEPHY:
- {
- DWORD linear = ((DWORD*)params->lpInBuffer)[0];
- FreePhysical(linear);
- return 0;
- }
-#endif
- /* input:
- - id
- output:
- - linear
- - physical
- - size
- - flags
- */
- case SVGA_OTABLE_QUERY:
- {
- DWORD id = ((DWORD*)params->lpInBuffer)[0];
- DWORD *out = (DWORD*)params->lpOutBuffer;
-
- if(!gb_support)
- return 1;
-
- if(id < SVGA_OTABLE_DX_MAX)
- {
- out[0] = (DWORD)otable[id].lin;
- out[1] = otable[id].phy;
- out[2] = otable[id].size;
- out[3] = otable[id].flags;
- return 0;
- }
- return 1;
- }
- /* input:
- - id
- - new flags
- */
- case SVGA_OTABLE_FLAGS:
- {
- DWORD id = ((DWORD*)params->lpInBuffer)[0];
- DWORD flags = ((DWORD*)params->lpInBuffer)[1];
-
- if(!gb_support)
- return 1;
-
- if(id < SVGA_OTABLE_DX_MAX)
- {
- otable[id].flags = flags;
- return 0;
- }
- return 1;
- }
- /*
- input:
- output:
- - linear address of buffer
- */
- case SVGA_CB_LOCK:
- {
- if(cb_support)
- {
- DWORD *out = (DWORD*)params->lpOutBuffer;
- out[0] = (DWORD)LockCB();
- return 0;
- }
- return 1;
- }
- /*
- input:
- - linear address of buffer
- - CB context ID
- output:
- */
- case SVGA_CB_SUBMIT:
- {
- if(cb_support)
- {
- DWORD *in = (DWORD*)params->lpInBuffer;
-
- if(submitCB((void*)in[0], in[1], FALSE))
- {
- return 0;
- }
- }
- return 1;
- }
- case SVGA_CB_SUBMIT_SYNC:
- {
- if(cb_support)
- {
- DWORD *in = (DWORD*)params->lpInBuffer;
-
- if(submitCB((void*)in[0], in[1], TRUE))
- {
- return 0;
- }
- }
- return 1;
- }
- /*
- none arguments
- */
- case SVGA_CB_SYNC:
- if(cb_support)
- {
- syncCB();
- return 0;
- }
- return 1;
- /*
- input:
- - region id
- - pages
- output:
- - region id
- - user page address
- - page block
- - mob page address
- - mob ppn
- */
- case SVGA_REGION_CREATE:
- {
- DWORD *lpIn = (DWORD*)params->lpInBuffer;
- DWORD *lpOut = (DWORD*)params->lpOutBuffer;
- DWORD gmrPPN = 0;
-
- //dbg_printf(dbg_region_info_1, lpIn[0]);
-
- if(GMRAlloc(lpIn[1], &lpOut[1], &lpOut[2], &gmrPPN, &lpOut[3], &lpOut[4]))
- {
- if(lpIn[0] != 0)
- {
- DWORD gmr_max = SVGA_ReadReg(SVGA_REG_GMR_MAX_IDS);
-
- /* if region id extends GRM max, don't register region and only use it as MOB */
- if(lpIn[0] < gmr_max)
- {
- SVGA_WriteReg(SVGA_REG_GMR_ID, lpIn[0]);
- SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, gmrPPN);
- }
-
- //dbg_printf(dbg_region_info_2, lpOut[1], gmrPPN, lpOut[2]);
-
- /* refresh all register, so make sure that new commands will accepts this region */
- SVGA_Flush();
-
- lpOut[0] = lpIn[0]; // copy GMR ID
- }
- return 0;
- }
- else
- {
- dbg_printf(dbg_region_err);
- }
-
- return 1;
- }
- /*
- input
- - region id
- - user page address
- - page block address
- - mob PT address
- */
- case SVGA_REGION_FREE:
- {
- DWORD *lpIn = (DWORD*)params->lpInBuffer;
-
- /* flush all register inc. fifo so make sure, that all commands are processed */
- SVGA_Flush();
-
- SVGA_WriteReg(SVGA_REG_GMR_ID, lpIn[0]);
- SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, 0);
-
- /* sync again */
- SVGA_Flush();
-
- if(FreeRegion(lpIn[1], lpIn[2], lpIn[3]))
- {
- return 0;
- }
- return 1;
- }
- case SVGA_DBG:
-#ifdef DBGPRINT
- dbg_printf(dbg_str, params->lpInBuffer);
-#endif
- return 0;
- }
-
- dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
-
- return 1;
-}
-
-void Device_Init_proc()
-{
- /* nop */
-}
-
-/* shutdown procedure */
-void Device_Exit_proc(DWORD VM)
-{
- 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
-}
diff --git a/vxd.h b/vxd.h
new file mode 100644
index 0000000..5a55fa6
--- /dev/null
+++ b/vxd.h
@@ -0,0 +1,26 @@
+#ifndef __VXD_H__INCLUDED__
+#define __VXD_H__INCLUDED__
+
+/* Table of "known" drivers
+ * https://fd.lod.bz/rbil/interrup/windows/2f1684.html#sect-4579
+ * This looks like free
+ */
+#define VXD_DEVICE_SVGA_ID 0x4331
+#define VXD_DEVICE_QEMU_ID 0x4332
+#define VXD_DEVICE_VBE_ID 0x4333
+
+#if defined(SVGA)
+#define VXD_DEVICE_ID VXD_DEVICE_SVGA_ID
+#elif defined(QEMU)
+#define VXD_DEVICE_ID VXD_DEVICE_QEMU_ID
+#else
+#define VXD_DEVICE_ID VXD_DEVICE_VBE_ID
+#endif
+
+#define VXD_MAJOR_VER 4 /* should be 4 for windows 95 and newer */
+#define VXD_MINOR_VER 0
+
+#define VXD_PM16_VERSION 0
+#define VXD_PM16_VMM_VERSION 1
+
+#endif /* __VXD_H__INCLUDED__ */
diff --git a/vxd_fbhda.c b/vxd_fbhda.c
new file mode 100644
index 0000000..2a258bc
--- /dev/null
+++ b/vxd_fbhda.c
@@ -0,0 +1,89 @@
+/*****************************************************************************
+
+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.
+
+*****************************************************************************/
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+
+#include "vxd_lib.h"
+#include "3d_accel.h"
+
+#include "code32.h"
+
+FBHDA_t *hda = NULL;
+ULONG hda_sem = 0;
+LONG fb_lock_cnt = 0;
+
+BOOL FBHDA_init_hw()
+{
+ hda = (FBHDA_t *)_PageAllocate(RoundToPages(sizeof(FBHDA_t)), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+ if(hda)
+ {
+ memset(hda, 0, sizeof(FBHDA_t));
+
+ hda->cb = sizeof(FBHDA_t);
+ hda->flags = 0;
+
+ hda_sem = Create_Semaphore(1);
+ if(hda_sem == 0)
+ {
+ _PageFree(hda, 0);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void FBHDA_release_hw()
+{
+ if(hda)
+ {
+ _PageFree(hda, 0);
+ }
+
+ if(hda_sem)
+ {
+ Destroy_Semaphore(hda_sem);
+ }
+}
+
+FBHDA_t *FBHDA_setup()
+{
+ return hda;
+}
+
+void FBHDA_access_begin(DWORD flags)
+{
+ //Wait_Semaphore(hda_sem, 0);
+ fb_lock_cnt++;
+}
+
+void FBHDA_clean()
+{
+ FBHDA_access_begin(0);
+ memset(hda->vram_pm32, 0, hda->stride);
+ FBHDA_access_end(0);
+}
diff --git a/vxd_lib.c b/vxd_lib.c
new file mode 100644
index 0000000..bab7ff5
--- /dev/null
+++ b/vxd_lib.c
@@ -0,0 +1,234 @@
+/*****************************************************************************
+
+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.
+
+*****************************************************************************/
+
+/* 32 bit RING-0 system calls and CRT function */
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+
+#include "svga_all.h"
+
+#include "vxd_vdd.h"
+
+#include "vxd_lib.h"
+
+#include "code32.h"
+
+/* some CRT */
+void memset(void *dst, int c, unsigned int size)
+{
+ unsigned int par;
+ unsigned int i;
+ unsigned int dw_count;
+ unsigned int dw_size;
+
+ c &= 0xFF;
+ par = (c << 24) | (c << 16) | (c << 8) | c;
+ dw_count = size >> 2;
+ dw_size = size & 0xFFFFFFFCUL;
+
+ for(i = 0; i < dw_count; i++)
+ {
+ ((unsigned int*)dst)[i] = par;
+ }
+
+ for(i = dw_size; i < size; i++)
+ {
+ ((unsigned char*)dst)[i] = c;
+ }
+}
+
+void *memcpy(void *dst, const void *src, unsigned int size)
+{
+ unsigned int dw_count;
+ unsigned int dw_size;
+ unsigned int i;
+
+ dw_count = size >> 2;
+ dw_size = size & 0xFFFFFFFCUL;
+
+ for(i = 0; i < dw_count; i++)
+ {
+ ((unsigned int*)dst)[i] = ((unsigned int*)src)[i];
+ }
+
+ for(i = dw_size; i < size; i++)
+ {
+ ((unsigned char*)dst)[i] = ((unsigned char*)src)[i];
+ }
+
+ return dst;
+}
+
+
+/**
+ * VMM calls wrapers
+ **/
+DWORD Get_VMM_Version()
+{
+ static WORD ver = 0;
+
+ _asm push ecx
+ _asm push eax
+ _asm xor eax, eax
+ VMMCall(Get_VMM_Version);
+ _asm mov [ver],ax
+ _asm pop ecx
+ _asm pop eax
+
+ return ver;
+}
+
+void __cdecl Begin_Critical_Section(ULONG Flags)
+{
+ static ULONG sFlags;
+ sFlags = Flags;
+
+ _asm push ecx
+ _asm mov ecx, [sFlags]
+ VMMCall(Begin_Critical_Section);
+ _asm pop ecx
+}
+
+void __cdecl End_Critical_Section()
+{
+ VMMCall(End_Critical_Section);
+}
+
+ULONG __cdecl Create_Semaphore(ULONG TokenCount)
+{
+ static ULONG sTokenCount;
+ static ULONG sSemHandle;
+ sTokenCount = TokenCount;
+ sSemHandle = 0;
+
+ _asm push eax
+ _asm push ecx
+ _asm mov ecx, [sTokenCount]
+ VMMCall(Create_Semaphore);
+ _asm {
+ jc create_sem_error
+ mov [sSemHandle], eax
+ create_sem_error:
+ pop ecx
+ pop eax
+ }
+
+ return sSemHandle;
+}
+
+void __cdecl Destroy_Semaphore(ULONG SemHandle)
+{
+ static ULONG sSemHandle;
+ sSemHandle = SemHandle;
+
+ _asm push eax
+ _asm mov eax, [sSemHandle]
+ VMMCall(Destroy_Semaphore);
+ _asm pop eax
+}
+
+void __cdecl Wait_Semaphore(ULONG semHandle, ULONG flags)
+{
+ static ULONG sSemHandle;
+ static ULONG sFlags;
+ sSemHandle = semHandle;
+ sFlags = flags;
+
+ _asm push eax
+ _asm push ecx
+ _asm mov eax, [sSemHandle]
+ _asm mov ecx, [sFlags]
+ VMMCall(Wait_Semaphore);
+ _asm pop ecx
+ _asm pop eax
+}
+
+void __cdecl Signal_Semaphore(ULONG SemHandle)
+{
+ static ULONG sSemHandle;
+ sSemHandle = SemHandle;
+
+ _asm push eax
+ _asm mov eax, [sSemHandle]
+ VMMCall(Signal_Semaphore);
+ _asm pop eax
+}
+
+ULONG __declspec(naked) __cdecl _PageAllocate(ULONG nPages, ULONG pType, ULONG VM, ULONG AlignMask, ULONG minPhys, ULONG maxPhys, ULONG *PhysAddr, ULONG flags)
+{
+ VMMJmp(_PageAllocate);
+}
+
+ULONG __declspec(naked) __cdecl _PageFree(PVOID hMem, DWORD flags)
+{
+ VMMJmp(_PageFree);
+}
+
+ULONG __declspec(naked) __cdecl _CopyPageTable(ULONG LinPgNum, ULONG nPages, DWORD *PageBuf, ULONG flags)
+{
+ VMMJmp(_CopyPageTable);
+}
+
+ULONG __declspec(naked) __cdecl _LinPageLock(ULONG page, ULONG npages, ULONG flags)
+{
+ VMMJmp(_LinPageLock);
+}
+
+ULONG __declspec(naked) __cdecl _LinPageUnLock(ULONG page, ULONG npages, ULONG flags)
+{
+ VMMJmp(_LinPageUnLock);
+}
+
+ULONG __declspec(naked) __cdecl _MapPhysToLinear(ULONG PhysAddr, ULONG nBytes, ULONG flags)
+{
+ 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);
+}
+
diff --git a/vxd_lib.h b/vxd_lib.h
new file mode 100644
index 0000000..dd36f32
--- /dev/null
+++ b/vxd_lib.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+
+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.
+
+*****************************************************************************/
+
+/* 32 bit RING-0 system calls and CRT function */
+
+void memset(void *dst, int c, unsigned int size);
+void *memcpy(void *dst, const void *src, unsigned int size);
+
+DWORD Get_VMM_Version();
+ULONG __cdecl _PageAllocate(ULONG nPages, ULONG pType, ULONG VM, ULONG AlignMask, ULONG minPhys, ULONG maxPhys, ULONG *PhysAddr, ULONG flags);
+ULONG __cdecl _PageFree(PVOID hMem, DWORD flags);
+ULONG __cdecl _CopyPageTable(ULONG LinPgNum, ULONG nPages, DWORD *PageBuf, ULONG flags);
+ULONG __cdecl _LinPageLock(ULONG page, ULONG npages, ULONG flags);
+ULONG __cdecl _LinPageUnLock(ULONG page, ULONG npages, ULONG flags);
+ULONG __cdecl _MapPhysToLinear(ULONG PhysAddr, ULONG nBytes, ULONG flags);
+ULONG __cdecl GetNulPageHandle();
+ULONG __cdecl _PhysIntoV86(ULONG PhysPage, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG flags);
+DWORD __cdecl _RegOpenKey(DWORD hKey, char *lpszSubKey, DWORD *lphKey);
+DWORD __cdecl _RegCloseKey(DWORD hKey);
+DWORD __cdecl _RegQueryValueEx(DWORD hKey, char *lpszValueName, DWORD *lpdwReserved, DWORD *lpdwType, BYTE *lpbData, DWORD *lpcbData);
+void __cdecl Begin_Critical_Section(ULONG Flags);
+void __cdecl End_Critical_Section();
+ULONG __cdecl Create_Semaphore(ULONG TokenCount);
+void __cdecl Destroy_Semaphore(ULONG SemHandle);
+void __cdecl Wait_Semaphore(ULONG semHandle, ULONG flags);
+void __cdecl Signal_Semaphore(ULONG SemHandle);
+
+/**
+ * round size in bytes to number of pages
+ **/
+#define RoundToPages(_size) (((_size) + P_SIZE - 1)/P_SIZE)
+
+/* sometimes missing */
+#ifndef ERROR_SUCCESS
+#define ERROR_SUCCESS 0
+#endif
+
+/* debug */
+#ifdef DBGPRINT
+void dbg_printf( const char *s, ... );
+#else
+#define dbg_printf(s, ...)
+#endif
+
diff --git a/vxd_main.c b/vxd_main.c
new file mode 100644
index 0000000..c95a881
--- /dev/null
+++ b/vxd_main.c
@@ -0,0 +1,442 @@
+/*****************************************************************************
+
+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.
+
+*****************************************************************************/
+
+#ifndef VXD32
+#error VXD32 not defined!
+#endif
+
+#define VXD_MAIN
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+#include "vxd_lib.h"
+
+#include "3d_accel.h"
+#include "vxd_vdd.h"
+
+#ifdef SVGA
+# include "svga_all.h"
+#endif
+
+#include "version.h"
+
+#include "code32.h"
+
+void VMWS_control();
+void VMWS_API_entry();
+void Device_Init_proc();
+void __stdcall Device_Dynamic_Init_proc(DWORD VM);
+void __stdcall Device_Exit_proc(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 = {
+ 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",
+ VDD_Init_Order, //Undefined_Init_Order,
+ (DWORD)VMWS_control,
+ (DWORD)VMWS_API_entry,
+ (DWORD)VMWS_API_entry,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, // DDB_Win32_Service_Table
+ NULL, // prev
+ sizeof(DDB)
+};
+
+#include "vxd_strings.h"
+
+DWORD *DispatchTable = 0;
+DWORD DispatchTableLength = 0;
+DWORD ThisVM = 0;
+
+/**
+ * VDD calls wrapers
+ **/
+void VDD_Get_Mini_Dispatch_Table()
+{
+ VxDCall(VDD, Get_Mini_Dispatch_Table);
+ _asm mov [DispatchTable],edi
+ _asm mov [DispatchTableLength],ecx
+}
+
+/**
+ * Control Handles
+ **/
+void Sys_Critical_Init_proc()
+{
+ // nop
+}
+
+DWORD __stdcall Device_IO_Control_proc(struct DIOCParams *params);
+
+/*
+ * 32-bit DeviceIoControl ends here
+ *
+ */
+void __declspec(naked) Device_IO_Control_entry()
+{
+ _asm {
+ push esi /* struct DIOCParams */
+ call Device_IO_Control_proc
+ retn
+ }
+}
+
+/*
+ * service module calls (init, exit, deviceIoControl, ...)
+ * clear carry if succes (this is always success)
+ */
+void __declspec(naked) VMWS_control()
+{
+ // eax = 0x00 - Sys Critical Init
+ // eax = 0x01 - sys dynamic init
+ // eax = 0x1B - dynamic init
+ // eax = 0x1C - dynamic exit
+ // eax = 0x23 - device IO control
+
+ _asm {
+ cmp eax,Sys_Critical_Init
+ jnz control_1
+ pushad
+ call Sys_Critical_Init_proc
+ popad
+ clc
+ ret
+ control_1:
+ cmp eax,Device_Init
+ jnz control_2
+ call Device_Init_proc
+ popad
+ clc
+ ret
+ control_2:
+ cmp eax,0x1B
+ jnz control_3
+ pushad
+ push ebx ; VM handle
+ call Device_Dynamic_Init_proc
+ popad
+ clc
+ ret
+ control_3:
+ cmp eax,W32_DEVICEIOCONTROL
+ jnz control_4
+ jmp Device_IO_Control_entry
+ 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
+ };
+}
+
+/* process V86/PM16 calls */
+WORD __stdcall VMWS_API_Proc(PCRS_32 state)
+{
+ WORD rc = 0xFFFF;
+ WORD service = state->Client_EDX & 0xFFFF;
+ switch(service)
+ {
+ case VXD_PM16_VERSION:
+ rc = (VXD_MAJOR_VER << 8) | VXD_MINOR_VER;
+ break;
+ case VXD_PM16_VMM_VERSION:
+ rc = Get_VMM_Version();
+ break;
+ case OP_FBHDA_SETUP:
+ {
+ DWORD dptr = (DWORD)FBHDA_setup();
+ if(dptr)
+ {
+ state->Client_ECX = dptr;
+ rc = 1;
+ }
+ break;
+ }
+ break;
+ case OP_FBHDA_ACCESS_BEGIN:
+ FBHDA_access_begin(state->Client_ECX);
+ rc = 1;
+ break;
+ case OP_FBHDA_ACCESS_END:
+ FBHDA_access_end(state->Client_ECX);
+ rc = 1;
+ break;
+ case OP_FBHDA_SWAP:
+ {
+ BOOL rs;
+ rs = FBHDA_swap(state->Client_ECX);
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_FBHDA_CLEAN:
+ FBHDA_clean();
+ rc = 1;
+ break;
+ case OP_FBHDA_PALETTE_SET:
+ FBHDA_palette_set(state->Client_ECX & 0xFF, state->Client_EDI);
+ rc = 1;
+ break;
+ case OP_FBHDA_PALETTE_GET:
+ {
+ DWORD color;
+ color = FBHDA_palette_get(state->Client_ECX & 0xFF);
+ state->Client_EDI = color;
+ rc = 1;
+ break;
+ }
+#ifdef SVGA
+ case OP_SVGA_VALID:
+ {
+ BOOL rs;
+ rs = SVGA_valid();
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_SVGA_SETMODE:
+ {
+ BOOL rs;
+ rs = SVGA_setmode(state->Client_ESI, state->Client_EDI, state->Client_ECX);
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_SVGA_VALIDMODE:
+ {
+ BOOL rs;
+ rs = SVGA_validmode(state->Client_ESI, state->Client_EDI, state->Client_ECX);
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_SVGA_HW_ENABLE:
+ SVGA_HW_enable();
+ rc = 1;
+ break;
+ case OP_SVGA_HW_DISABLE:
+ SVGA_HW_disable();
+ rc = 1;
+ break;
+#endif
+ }
+
+ if(rc == 0xFFFF)
+ {
+ state->Client_EFlags |= 0x1; // set carry
+ }
+ else
+ {
+ state->Client_EFlags &= 0xFFFFFFFEUL; // clear carry
+ }
+
+ return rc;
+}
+
+/*
+ * 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
+ * function is placed to saved AX register.
+ *
+ */
+void __declspec(naked) VMWS_API_entry()
+{
+ _asm {
+ push ebp
+ call VMWS_API_Proc
+ mov [ebp+1Ch], ax
+ retn
+ }
+}
+
+/* generate all entry pro VDD function */
+#define VDDFUNC(_fnname, _procname) void __declspec(naked) _procname ## _entry() { \
+ _asm { push ebp }; \
+ _asm { call _procname ## _proc }; \
+ _asm { retn }; \
+ }
+#include "vxd_vdd_list.h"
+#undef VDDFUNC
+
+#define VDDFUNC(id, procname) DispatchTable[id] = (DWORD)(procname ## _entry);
+
+/* init device and fill dispatch table */
+void Device_Dynamic_Init_proc(DWORD VM)
+{
+ dbg_printf(dbg_Device_Init_proc);
+
+ // VMMCall _Allocate_Device_CB_Area
+ ThisVM = VM;
+
+#ifdef SVGA
+ SVGA_init_hw();
+#endif
+
+ /* register miniVDD functions */
+ VDD_Get_Mini_Dispatch_Table();
+ if(DispatchTableLength >= 0x31)
+ {
+ #include "vxd_vdd_list.h"
+ }
+}
+#undef VDDFUNC
+
+/* process user space (PM32, RING-3) call */
+DWORD __stdcall Device_IO_Control_proc(struct DIOCParams *params)
+{
+ DWORD *inBuf = (DWORD*)params->lpInBuffer;
+ DWORD *outBuf = (DWORD*)params->lpOutBuffer;
+
+ //dbg_printf(dbg_deviceiocontrol, params->dwIoControlCode);
+
+ switch(params->dwIoControlCode)
+ {
+ /* DX */
+ case DIOC_OPEN:
+ case DIOC_CLOSEHANDLE:
+ dbg_printf(dbg_dic_system, params->dwIoControlCode);
+ return 0;
+ case OP_FBHDA_SETUP:
+ outBuf[0] = (DWORD)FBHDA_setup();
+ return 0;
+ case OP_FBHDA_ACCESS_BEGIN:
+ FBHDA_access_begin(inBuf[0]);
+ return 0;
+ case OP_FBHDA_ACCESS_END:
+ FBHDA_access_end(inBuf[0]);
+ return 0;
+ case OP_FBHDA_SWAP:
+ outBuf[0] = FBHDA_swap(inBuf[0]);
+ return 0;
+ case OP_FBHDA_CLEAN:
+ FBHDA_clean();
+ return 0;
+ case OP_FBHDA_PALETTE_SET:
+ FBHDA_palette_set(inBuf[0], inBuf[1]);
+ return 0;
+ case OP_FBHDA_PALETTE_GET:
+ outBuf[0] = FBHDA_palette_get(inBuf[0]);
+ return 0;
+#ifdef SVGA
+ case OP_SVGA_VALID:
+ outBuf[0] = SVGA_valid();
+ return 0;
+ case OP_SVGA_CMB_ALLOC:
+ outBuf[0] = (DWORD)SVGA_CMB_alloc();
+ return 0;
+ case OP_SVGA_CMB_FREE:
+ SVGA_CMB_free((DWORD*)inBuf[0]);
+ return 0;
+ case OP_SVGA_CMB_SUBMIT:
+ {
+ SVGA_CMB_submit_io_t *inio = (SVGA_CMB_submit_io_t*)inBuf;
+ SVGA_CMB_status_t *status = (SVGA_CMB_status_t*)outBuf;
+
+ SVGA_CMB_submit(inio->cmb, inio->cmb_size, status, inio->flags, inio->DXCtxId);
+ return 0;
+ }
+ case OP_SVGA_FENCE_GET:
+ outBuf[0] = SVGA_fence_get();
+ return 0;
+ case OP_SVGA_FENCE_QUERY:
+ SVGA_fence_query(&outBuf[0], &outBuf[1]);
+ return 0;
+ case OP_SVGA_FENCE_WAIT:
+ SVGA_fence_wait(inBuf[0]);
+ return 0;
+ case OP_SVGA_REGION_CREATE:
+ {
+ SVGA_region_info_t *inio = (SVGA_region_info_t*)inBuf;
+ SVGA_region_info_t *outio = (SVGA_region_info_t*)outBuf;
+ if(outio != inio)
+ {
+ memcpy(outio, inio, sizeof(SVGA_region_info_t));
+ }
+ SVGA_region_create(outio);
+ return 0;
+ }
+ case OP_SVGA_REGION_FREE:
+ {
+ SVGA_region_info_t *inio = (SVGA_region_info_t*)inBuf;
+ SVGA_region_free(inio);
+ return 0;
+ }
+ case OP_SVGA_QUERY:
+ outBuf[0] = SVGA_query(inBuf[0], inBuf[1]);
+ return 0;
+ case OP_SVGA_QUERY_VECTOR:
+ SVGA_query_vector(inBuf[0], inBuf[1], inBuf[2], outBuf);
+ return 0;
+ case OP_SVGA_DB_SETUP:
+ outBuf[0] = (DWORD)SVGA_DB_setup();
+ return 0;
+ case OP_SVGA_OT_SETUP:
+ outBuf[0] = (DWORD)SVGA_OT_setup();
+ return 0;
+#endif /* SVGA */
+ }
+
+ dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
+
+ return 1;
+}
+
+void Device_Init_proc()
+{
+ /* nop */
+}
+
+/* shutdown procedure */
+void Device_Exit_proc(DWORD VM)
+{
+ dbg_printf(dbg_destroy);
+
+#ifdef SVGA
+ SVGA_HW_disable();
+#endif
+
+ // TODO: free memory
+}
diff --git a/vxd_main_qemu.c b/vxd_main_qemu.c
new file mode 100644
index 0000000..de46c9c
--- /dev/null
+++ b/vxd_main_qemu.c
@@ -0,0 +1,2 @@
+#define QEMU
+#include "vxd_main.c"
diff --git a/vxd_main_svga.c b/vxd_main_svga.c
new file mode 100644
index 0000000..100dd48
--- /dev/null
+++ b/vxd_main_svga.c
@@ -0,0 +1,2 @@
+#define SVGA
+#include "vxd_main.c"
diff --git a/vxd_strings.h b/vxd_strings.h
new file mode 100644
index 0000000..7dca2e4
--- /dev/null
+++ b/vxd_strings.h
@@ -0,0 +1,86 @@
+/*
+ * Open Watcom generate invalid code when using inline const strings,
+ * so this code doesn't work:
+ * void somefunc(){
+ * printf("Hello %s!", "World");
+ * }
+ * Workaround is following:
+ * static char str_hello[] = "Hello %s!";
+ * static char str_world[] = "World";
+ * void somefunc(){
+ * printf(str_hello, str_world);
+ * }
+ *
+ * And for these string is this file...
+ *
+ */
+#ifdef DBGPRINT
+
+#ifdef VXD_MAIN
+#define DSTR(_n, _s) char _n[] = _s
+#else
+#define DSTR(_n, _s) extern char _n[]
+#endif
+
+DSTR(dbg_hello, "Hello world!\n");
+DSTR(dbg_version, "VMM version: ");
+DSTR(dbg_region_err, "region create error\n");
+
+DSTR(dbg_Device_Init_proc, "Device_Init_proc\n");
+DSTR(dbg_Device_Init_proc_succ, "Device_Init_proc success\n");
+DSTR(dbg_dic_ring, "DeviceIOControl: Ring\n");
+DSTR(dbg_dic_sync, "DeviceIOControl: Sync\n");
+DSTR(dbg_dic_unknown, "DeviceIOControl: Unknown: %d\n");
+DSTR(dbg_dic_system, "DeviceIOControl: System code: %d\n");
+DSTR(dbg_get_ppa, "%lx -> %lx\n");
+DSTR(dbg_get_ppa_beg, "Virtual: %lx\n");
+DSTR(dbg_mob_allocate, "Allocated OTable row: %d\n");
+
+DSTR(dbg_str, "%s\n");
+
+DSTR(dbg_submitcb_fail, "CB submit FAILED\n");
+DSTR(dbg_submitcb, "CB submit %d\n");
+DSTR(dbg_lockcb, "Reused CB (%d) with status: %d\n");
+
+DSTR(dbg_lockcb_lasterr, "Error command: %lX\n");
+
+DSTR(dbg_cb_on, "CB supported and allocated\n");
+DSTR(dbg_gb_on, "GB supported and allocated\n");
+DSTR(dbg_cb_ena, "CB context 0 enabled\n");
+
+DSTR(dbg_region_info_1, "Region id = %d\n");
+DSTR(dbg_region_info_2,"Region address = %lX, PPN = %lX, GMRBLK = %lX\n");
+
+DSTR(dbg_mapping, "Memory mapping:\n");
+DSTR(dbg_mapping_map, " %X -> %X\n");
+DSTR(dbg_destroy, "Driver destroyed\n");
+
+DSTR(dbg_siz, "Size of gSVGA(2) = %d %d\n");
+
+DSTR(dbg_test, "test %d\n");
+
+DSTR(dbg_SVGA_Init, "SVGA_Init: %d\n");
+
+DSTR(dbg_update, "Update screen: %d %d %d\n");
+
+DSTR(dbg_cmd_on, "SVGA_CMB_submit: first cmd: %X, flags: %X, size: %d\n");
+DSTR(dbg_cmd_off, "SVGA_CMB_submit: end - cmd: %X\n");
+DSTR(dbg_cmd_error, "CB error: %d, first cmd %X (error at %d)\n");
+
+DSTR(dbg_deviceiocontrol, "DeviceIoControl(%x);\n");
+
+DSTR(dbg_gmr, "GMR: %ld at %X\n");
+DSTR(dbg_gmr_succ, "GMR success, size: %ld\n");
+
+DSTR(dbg_region_simple, "GMR is continous, memory maped: %X, user memory: %X\n");
+DSTR(dbg_region_fragmented, "GMR is fragmented\n");
+
+DSTR(dbg_pages, "GMR: size: %ld pages: %ld P_SIZE: %ld\n");
+
+DSTR(dbg_fence_overflow, "fence overflow\n");
+
+DSTR(dbg_pagefree, "_PageFree: %X\n");
+
+#undef DSTR
+
+#endif
diff --git a/vxd_svga.c b/vxd_svga.c
new file mode 100644
index 0000000..89d0cb7
--- /dev/null
+++ b/vxd_svga.c
@@ -0,0 +1,1431 @@
+/*****************************************************************************
+
+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.
+
+*****************************************************************************/
+
+/* 32 bit RING-0 code for SVGA-II 3D acceleration */
+#define SVGA
+
+#include <limits.h>
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+#include "vxd_lib.h"
+
+#include "svga_all.h"
+
+#include "3d_accel.h"
+
+#include "code32.h"
+
+#include "vxd_strings.h"
+
+/*
+ * consts
+ */
+//#define SVGA3D_MAX_MOBS 33280UL /* SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS */
+#define SVGA3D_MAX_MOBS (SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS)
+#define VBOX_VIDEO_MAX_SCREENS 64
+
+#define PTONPAGE (P_SIZE/sizeof(DWORD))
+
+/*
+ * types
+ */
+
+#pragma pack(push)
+#pragma pack(1)
+typedef struct _cb_enable_t
+{
+// SVGACBHeader cbheader;
+ uint32 cmd;
+ SVGADCCmdStartStop cbstart;
+} cb_enable_t;
+#pragma pack(pop)
+
+/*
+ * globals
+ */
+extern FBHDA_t *hda;
+extern ULONG hda_sem;
+static SVGA_DB_t *svga_db = NULL;
+
+extern LONG fb_lock_cnt;
+
+static BOOL gb_support = FALSE;
+static BOOL cb_support = FALSE;
+static BOOL cb_context0 = FALSE;
+
+static BOOL SVGA_is_valid = FALSE;
+
+static SVGACBHeader *last_cb = NULL;
+
+/* temp for reading registry */
+static union
+{
+ DWORD dw;
+ char str[64];
+} RegReadConfBuf = {0};
+
+static uint64 cb_next_id = {0, 0};
+static DWORD fence_next_id = 1;
+static void *cmdbuf = NULL;
+
+/* object table for GPU10 */
+static SVGA_OT_info_entry_t otable_setup[SVGA_OTABLE_DX_MAX] = {
+ {0, NULL, RoundToPages(SVGA3D_MAX_MOBS*sizeof(SVGAOTableMobEntry))*P_SIZE, 0}, /* SVGA_OTABLE_MOB */
+ {0, NULL, RoundToPages(SVGA3D_MAX_SURFACE_IDS*sizeof(SVGAOTableSurfaceEntry))*P_SIZE, 0}, /* SVGA_OTABLE_SURFACE */
+ {0, NULL, RoundToPages(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableContextEntry))*P_SIZE, 0}, /* SVGA_OTABLE_CONTEXT */
+ {0, NULL, 0, 0}, /* SVGA_OTABLE_SHADER - not used */
+ {0, NULL, RoundToPages(VBOX_VIDEO_MAX_SCREENS*sizeof(SVGAOTableScreenTargetEntry))*P_SIZE, 0}, /* SVGA_OTABLE_SCREENTARGET (VBOX_VIDEO_MAX_SCREENS) */
+ {0, NULL, RoundToPages(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableDXContextEntry))*P_SIZE, 0}, /* SVGA_OTABLE_DXCONTEXT */
+};
+
+static SVGA_OT_info_entry_t *otable = NULL;
+
+/*
+ * strings
+ */
+static char SVGA_conf_path[] = "Software\\SVGA";
+static char SVGA_conf_hw_cursor[] = "hwcursor";
+static char SVGA_conf_vram256[] = "vram256";
+static char SVGA_conf_rgb565bug[] = "rgb565bug";
+static char SVGA_conf_cb[] = "commandbuffers";
+static char SVGA_conf_hw_version[] = "hwversion";
+static char SVGA_vxd_name[] = "vmwsmini.vxd";
+
+/* prototypes */
+DWORD SVGA_GetDevCap(DWORD search_id);
+
+/**
+ * Notify virtual HW that is some work to do
+ **/
+static void SVGA_Sync()
+{
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+}
+
+static void SVGA_Flush_CB()
+{
+ Begin_Critical_Section(0);
+
+ /* wait for actual CB */
+ if(last_cb != NULL)
+ {
+ while(last_cb->status == SVGA_CB_STATUS_NONE)
+ {
+ SVGA_Sync();
+ }
+ }
+
+ /* drain FIFO */
+ SVGA_Flush();
+
+ End_Critical_Section();
+}
+
+/**
+ * Read integer value from registry
+ *
+ **/
+static 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;
+}
+
+/* map physical addresses to system linear space */
+void SVGA_MapIO()
+{
+ if(SVGA_IsSVGA3())
+ {
+ gSVGA.rmmio_linear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.fifoSize, 0);
+ gSVGA.rmmio = (uint32 FARP*)gSVGA.rmmio_linear;
+ }
+}
+
+/**
+ * Allocate OTable for GB objects
+ **/
+static void SVGA_OTable_alloc()
+{
+ int i;
+
+ if(otable == NULL)
+ {
+ otable = (SVGA_OT_info_entry_t *)_PageAllocate(RoundToPages(sizeof(otable_setup)), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+ if(otable)
+ {
+ memcpy(otable, &(otable_setup[0]), sizeof(otable_setup));
+ }
+ }
+
+ if(otable)
+ {
+ for(i = 0; i < SVGA_OTABLE_DX_MAX; i++)
+ {
+ SVGA_OT_info_entry_t *entry = &otable[i];
+ if(entry->size != 0 && (entry->flags & SVGA_OT_FLAG_ALLOCATED) == 0)
+ {
+ entry->lin = (void*)_PageAllocate(RoundToPages(entry->size), PG_SYS, 0, 0, 0x0, 0x100000, &entry->phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+ if(entry->lin)
+ {
+ dbg_printf(dbg_mob_allocate, i);
+ entry->flags |= SVGA_OT_FLAG_ALLOCATED;
+ }
+ }
+ }
+ }
+}
+
+SVGA_OT_info_entry_t *SVGA_OT_setup()
+{
+ return otable;
+}
+
+static char db_mutexname[] = "svga_db_mux";
+
+static void SVGA_DB_alloc()
+{
+ DWORD size;
+ BYTE *mem = NULL;
+
+ DWORD max_regions = SVGA3D_MAX_MOBS; ///SVGA_ReadReg(SVGA_REG_GMR_MAX_IDS);
+
+ size = max_regions * sizeof(SVGA_DB_region_t) +
+ SVGA3D_MAX_CONTEXT_IDS * sizeof(SVGA_DB_context_t) +
+ SVGA3D_MAX_SURFACE_IDS * sizeof(SVGA_DB_surface_t) +
+ sizeof(SVGA_DB_t);
+
+ svga_db = (SVGA_DB_t*)_PageAllocate(RoundToPages(size), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+ if(svga_db)
+ {
+ memset(svga_db, 0, size);
+
+ mem = (BYTE*)(svga_db+1);
+
+ svga_db->regions = (SVGA_DB_region_t*)mem;
+ svga_db->regions_cnt = max_regions;
+ mem += svga_db->regions_cnt * sizeof(SVGA_DB_region_t);
+
+ svga_db->contexts = (SVGA_DB_context_t*)mem;
+ svga_db->contexts_cnt = SVGA3D_MAX_CONTEXT_IDS;
+ mem += svga_db->contexts_cnt * sizeof(SVGA_DB_context_t);
+
+ svga_db->surfaces = (SVGA_DB_surface_t*)mem;
+ svga_db->surfaces_cnt = SVGA3D_MAX_SURFACE_IDS;
+ mem += svga_db->surfaces_cnt * sizeof(SVGA_DB_surface_t);
+
+ memcpy(svga_db->mutexname, &(db_mutexname[0]), sizeof(db_mutexname));
+ }
+}
+
+SVGA_DB_t *SVGA_DB_setup()
+{
+ return svga_db;
+}
+
+static DWORD SVGA_fence_passed()
+{
+ if(SVGA_IsSVGA3())
+ {
+ return SVGA_ReadReg(SVGA_REG_FENCE);
+ }
+
+ return gSVGA.fifoMem[SVGA_FIFO_FENCE];
+}
+
+DWORD SVGA_fence_get()
+{
+ if(fence_next_id == 0)
+ {
+ /* fence overflow, we'll wait to all other fences to complete and start from 1 */
+ SVGA_Flush_CB();
+ fence_next_id = 1;
+ dbg_printf(dbg_fence_overflow);
+ }
+
+ return fence_next_id++;
+}
+
+void SVGA_fence_query(DWORD FBPTR ptr_fence_passed, DWORD FBPTR ptr_fence_last)
+{
+ if(ptr_fence_passed)
+ {
+ *ptr_fence_passed = SVGA_fence_passed();
+ }
+
+ if(ptr_fence_last)
+ {
+ *ptr_fence_last = fence_next_id-1;
+
+ if(*ptr_fence_last == 0)
+ {
+ *ptr_fence_last = ULONG_MAX;
+ }
+ }
+}
+
+void SVGA_fence_wait(DWORD fence_id)
+{
+ DWORD last_pased;
+ DWORD last_fence;
+
+ for(;;)
+ {
+ SVGA_fence_query(&last_pased, &last_fence);
+ if(fence_id > last_fence)
+ {
+ break;
+ }
+
+ if(fence_id <= last_pased)
+ {
+ break;
+ }
+
+ SVGA_Sync();
+ }
+}
+
+/**
+ * Allocate memory for command buffer
+ **/
+DWORD *SVGA_CMB_alloc()
+{
+ DWORD phy;
+ SVGACBHeader *cb;
+ cb = (SVGACBHeader*)_PageAllocate(RoundToPages(SVGA_CB_MAX_SIZE), PG_SYS, 0, 0, 0x0, 0x100000, &phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+
+ if(cb)
+ {
+ memset(cb, 0, sizeof(SVGACBHeader));
+ cb->status = SVGA_CB_STATUS_COMPLETED; /* important to sync between commands */
+ cb->ptr.pa.hi = 0;
+ cb->ptr.pa.low = phy + sizeof(SVGACBHeader);
+
+ return (DWORD*)(cb+1);
+ }
+
+ return NULL;
+}
+
+void SVGA_CMB_free(DWORD *cmb)
+{
+ SVGACBHeader *cb = (SVGACBHeader *)cmb;
+ --cb;
+
+ Begin_Critical_Section(0);
+
+ if(cb == last_cb)
+ {
+ while(last_cb->status == SVGA_CB_STATUS_NONE)
+ {
+ SVGA_Sync();
+ }
+ last_cb = NULL;
+ }
+
+ End_Critical_Section();
+
+ _PageFree(cb, 0);
+}
+
+// FIXME: inline?
+static void SVGA_cb_id_inc()
+{
+ _asm
+ {
+ inc dword ptr [cb_next_id]
+ adc dword ptr [cb_next_id+4], 0
+ }
+}
+
+void SVGA_CMB_submit(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_status_t FBPTR status, DWORD flags, DWORD DXCtxId)
+{
+ //dbg_printf(dbg_cmd_on, cmb[0], flags, cmb_size);
+
+ //Begin_Critical_Section(0);
+
+ if( /* CB are supported and enabled */
+ cb_support &&
+ (cb_context0 || (flags & SVGA_CB_USE_CONTEXT_DEVICE)) &&
+ (flags & SVGA_CB_FORCE_FIFO) == 0
+ )
+ {
+ SVGACBHeader *cb = ((SVGACBHeader *)cmb)-1;
+ DWORD cbhwctxid = SVGA_CB_CONTEXT_0;
+ DWORD fence = 0;
+
+ if(flags & SVGA_CB_USE_CONTEXT_DEVICE)
+ {
+ cbhwctxid = SVGA_CB_CONTEXT_DEVICE;
+ }
+
+ if(flags & SVGA_CB_FORCE_FENCE)
+ {
+ DWORD dwords = cmb_size/sizeof(DWORD);
+ fence = SVGA_fence_get();
+ cmb[dwords] = SVGA_CMD_FENCE;
+ cmb[dwords+1] = fence;
+ cmb_size += sizeof(DWORD)*2;
+ }
+
+ if(cmb_size == 0)
+ {
+ if(status)
+ {
+ status->sStatus = SVGA_PROC_COMPLETED;
+ status->qStatus = NULL;
+ status->fifo_fence_used = 0;
+ }
+ }
+ else
+ {
+ cb->status = SVGA_CB_STATUS_NONE;
+ cb->errorOffset = 0;
+ cb->flags = SVGA_CB_FLAG_NO_IRQ;
+
+ if(flags & SVGA_CB_FLAG_DX_CONTEXT)
+ {
+ cb->flags |= SVGA_CB_FLAG_DX_CONTEXT;
+ cb->dxContext = DXCtxId;
+ }
+ else
+ {
+ cb->dxContext = 0;
+ }
+
+ cb->id.low = cb_next_id.low;
+ cb->id.hi = cb_next_id.hi;
+ cb->length = cmb_size;
+
+ /* wait for last CB to complete */
+ if(last_cb && cb != last_cb)
+ {
+ while(last_cb->status == SVGA_CB_STATUS_NONE)
+ {
+ SVGA_Sync();
+ }
+ }
+
+ Begin_Critical_Section(0);
+ SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0); // high part of 64-bit memory address...
+ SVGA_WriteReg(SVGA_REG_COMMAND_LOW, cb->ptr.pa.low - sizeof(SVGACBHeader) | cbhwctxid);
+ End_Critical_Section();
+
+ last_cb = cb;
+
+ if(flags & SVGA_CB_SYNC)
+ {
+ while(cb->status == SVGA_CB_STATUS_NONE)
+ {
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ }
+
+ if(cb->status != SVGA_CB_STATUS_COMPLETED)
+ {
+ dbg_printf(dbg_cmd_error, cb->status, cmb[0], cb->errorOffset);
+ }
+
+ if(status)
+ {
+ status->sStatus = SVGA_PROC_COMPLETED;
+ status->qStatus = NULL;
+ status->fifo_fence_used = fence;
+ }
+ }
+ else
+ {
+ if(status)
+ {
+ status->sStatus = SVGA_PROC_NONE;
+ status->qStatus = (volatile DWORD*)&cb->status;
+ status->fifo_fence_used = fence;
+ }
+ }
+ }
+
+ SVGA_cb_id_inc();
+ }
+ else /* copy to FIFO */
+ {
+ DWORD *ptr = cmb;
+ DWORD dwords = cmb_size/sizeof(DWORD);
+ DWORD nextCmd, max, min;
+ DWORD fence;
+
+ /* insert fence CMD */
+ fence = SVGA_fence_get();
+ ptr[dwords] = SVGA_CMD_FENCE;
+ ptr[dwords+1] = fence;
+
+ dwords += 2;
+
+ Begin_Critical_Section(0);
+
+ nextCmd = gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD];
+ max = gSVGA.fifoMem[SVGA_FIFO_MAX];
+ min = gSVGA.fifoMem[SVGA_FIFO_MIN];
+
+ /* copy to fifo */
+ while(dwords > 0)
+ {
+ gSVGA.fifoMem[nextCmd/sizeof(DWORD)] = *ptr;
+ ptr++;
+
+ nextCmd += sizeof(uint32);
+ if (nextCmd >= max)
+ {
+ nextCmd = min;
+ }
+ gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD] = nextCmd;
+ dwords--;
+ }
+
+ End_Critical_Section();
+
+ if(flags & SVGA_CB_SYNC)
+ {
+ SVGA_fence_wait(fence);
+ if(status)
+ {
+ status->sStatus = SVGA_PROC_COMPLETED;
+ status->qStatus = NULL;
+ status->fifo_fence_used = 0;
+ }
+ }
+ else
+ {
+ if(status)
+ {
+ status->sStatus = SVGA_PROC_FENCE;
+ status->fifo_fence_used = fence;
+ status->qStatus = NULL;
+ }
+ }
+ }
+
+ if(status)
+ {
+ status->fifo_fence_last = SVGA_fence_passed();
+ }
+
+ End_Critical_Section();
+
+ //dbg_printf(dbg_cmd_off, cmb[0]);
+}
+
+/**
+ * Init SVGA-II hardware
+ * return TRUE on success
+ * return FALSE on failure (unsupported HW version or invalid HW)
+ **/
+BOOL SVGA_init_hw()
+{
+ /* defaults */
+ DWORD conf_hw_cursor = 0;
+ DWORD conf_vram256 = 0;
+ DWORD conf_rgb565bug = 1;
+ DWORD conf_cb = 1;
+ DWORD conf_hw_version = SVGA_VERSION_2;
+ int rc;
+
+ /* configs in registry */
+ 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(!FBHDA_init_hw())
+ {
+ return FALSE;
+ }
+
+ dbg_printf(dbg_test, 0);
+
+ rc = SVGA_Init(FALSE, conf_hw_version);
+ dbg_printf(dbg_SVGA_Init, rc);
+
+ if(rc == 0)
+ {
+ /* default flags */
+ gSVGA.userFlags = 0;
+
+ if(conf_rgb565bug)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_RGB565_BROKEN;
+ }
+
+ if(SVGA_conf_vram256)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_128MB_MAX;
+ }
+
+ dbg_printf(dbg_test, 1);
+
+ if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_CURSOR)
+ {
+ if(conf_hw_cursor)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_HWCURSOR;
+ }
+ }
+
+ dbg_printf(dbg_test, 2);
+
+ if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_ALPHA_CURSOR)
+ {
+ if(conf_hw_cursor)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_ALPHA_CUR;
+ }
+ }
+
+ dbg_printf(dbg_test, 3);
+
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_128MB_MAX)
+ {
+ if(gSVGA.vramSize > 128*1024*1024)
+ {
+ gSVGA.vramSize = 128*1024*1024;
+ }
+ }
+
+ dbg_printf(dbg_test, 4);
+
+ dbg_printf(dbg_Device_Init_proc_succ);
+
+ dbg_printf(dbg_mapping_map, gSVGA.fbPhy, gSVGA.fifoPhy);
+
+ /* map phys FB to linear */
+ gSVGA.fbLinear = _MapPhysToLinear(gSVGA.fbPhy, gSVGA.vramSize, 0);
+
+ /* map phys FIFO to linear */
+ if(!SVGA_IsSVGA3())
+ gSVGA.fifoLinear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.fifoSize, 0);
+
+#if 0
+ /* allocate fifo bounce buffer */
+ gSVGA.fifo.bounceLinear =
+ _PageAllocate(
+ (SVGA_BOUNCE_SIZE + PAGE_SIZE)/PAGE_SIZE,
+ PG_SYS, 0, 0, 0x0, 0x100000, &(gSVGA.fifo.bouncePhy), PAGECONTIG | PAGEUSEALIGN | PAGEFIXED
+ );
+#endif
+
+ /* system linear addres == PM32 address */
+ gSVGA.fbMem = (uint8 *)gSVGA.fbLinear;
+ if(!SVGA_IsSVGA3())
+ gSVGA.fifoMem = (uint32 *)gSVGA.fifoLinear;
+
+#if 0
+ gSVGA.fifo.bounceMem = (uint8 *)(gSVGA.fifo.bounceLinear + PAGE_SIZE); /* first page is for CB header (if CB supported) */
+#endif
+
+ dbg_printf(dbg_mapping);
+ dbg_printf(dbg_mapping_map, gSVGA.fbPhy, gSVGA.fbMem);
+ dbg_printf(dbg_mapping_map, gSVGA.fifoPhy, gSVGA.fifoMem);
+ //dbg_printf(dbg_mapping_map, gSVGA.fifo.bouncePhy, gSVGA.fifo.bounceMem);
+ dbg_printf(dbg_siz, sizeof(gSVGA), sizeof(uint8 FARP *));
+
+ /* enable FIFO */
+ SVGA_Enable();
+
+ /* allocate GB tables, if supported */
+ if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_GBOBJECTS)
+ {
+ SVGA_OTable_alloc();
+ gb_support = TRUE;
+ dbg_printf(dbg_gb_on);
+ }
+
+ /* enable command buffers if supported and enabled */
+ if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & (SVGA_CAP_COMMAND_BUFFERS | SVGA_CAP_CMD_BUFFERS_2))
+ {
+ if(conf_cb)
+ {
+ cb_support = TRUE;
+ dbg_printf(dbg_cb_on);
+ }
+ }
+
+ SVGA_DB_alloc();
+
+ /* fill address in FBHDA */
+ hda->vram_pm32 = (void*)gSVGA.fbLinear;
+ hda->vram_size = gSVGA.vramSize;
+ memcpy(hda->vxdname, SVGA_vxd_name, sizeof(SVGA_vxd_name));
+
+ /* allocate CB for this driver */
+ cmdbuf = SVGA_CMB_alloc();
+
+ hda->flags |= FB_ACCEL_VMSVGA;
+
+ if(cb_support && gb_support)
+ {
+ hda->flags |= FB_ACCEL_VMSVGA10;
+ }
+
+ SVGA_is_valid = TRUE;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Return PPN (physical page number) from virtual address
+ *
+ **/
+static DWORD getPPN(DWORD virtualaddr)
+{
+ DWORD phy = 0;
+ _CopyPageTable(virtualaddr/P_SIZE, 1, &phy, 0);
+ return phy/P_SIZE;
+}
+
+/**
+ * Allocate guest memory region (GMR) - HW needs know memory physical
+ * addressed of pages in (virtual) memory block.
+ * Technically this allocate 2 memory block, 1st for data and 2nd as its
+ * physical description.
+ *
+ * @return: TRUE on success
+ *
+ **/
+BOOL SVGA_region_create(SVGA_region_info_t *rinfo)
+{
+ ULONG phy = 0;
+ ULONG laddr;
+ ULONG pgblk;
+ ULONG nPages = RoundToPages(rinfo->size);
+
+ SVGAGuestMemDescriptor *desc;
+
+ dbg_printf(dbg_pages, rinfo->size, nPages, P_SIZE);
+
+ /* first try to allocate continuous physical memory space, 1st page is used for GMR descriptor */
+ laddr = _PageAllocate(nPages+1, PG_SYS, 0, 0, 0x0, 0x100000, &phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+
+ if(laddr)
+ {
+ desc = (SVGAGuestMemDescriptor*)laddr;
+ desc->ppn = (phy/P_SIZE)+1;
+ desc->numPages = nPages;
+ desc++;
+ desc->ppn = 0;
+ desc->numPages = 0;
+
+ rinfo->address = (void*)(laddr+P_SIZE);
+ rinfo->region_address = 0;
+ rinfo->region_ppn = (phy/P_SIZE);
+ rinfo->mob_address = 0;
+ rinfo->mob_ppn = (phy/P_SIZE)+1;
+
+ dbg_printf(dbg_region_simple, laddr, rinfo->address);
+ }
+ else
+ {
+ /* memory is too fragmented to create this large continous region */
+ ULONG taddr;
+ ULONG tppn;
+ ULONG pgi;
+ ULONG base_ppn;
+ ULONG base_cnt;
+ ULONG blocks = 1;
+ ULONG blk_pages = 0;
+
+ DWORD *mob = NULL;
+ DWORD mobphy = 0;
+
+ /* allocate user block */
+ laddr = _PageAllocate(nPages, PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+
+ if(!laddr) return FALSE;
+
+ /* determine how many physical continuous blocks we have */
+ base_ppn = getPPN(laddr);
+ base_cnt = 1;
+ for(pgi = 1; pgi < nPages; pgi++)
+ {
+ taddr = laddr + pgi*P_SIZE;
+ tppn = getPPN(taddr);
+
+ if(tppn != base_ppn + base_cnt)
+ {
+ base_ppn = tppn;
+ base_cnt = 1;
+ blocks++;
+ }
+ else
+ {
+ base_cnt++;
+ }
+ }
+
+ // number of pages to store regions information
+ blk_pages = ((blocks+1)/(P_SIZE/sizeof(SVGAGuestMemDescriptor))) + 1;
+
+ // add extra descriptors for pages edge
+ blk_pages = ((blocks+blk_pages+1)/(P_SIZE/sizeof(SVGAGuestMemDescriptor))) + 1;
+
+ /* allocate memory for GMR descriptor */
+ pgblk = _PageAllocate(blk_pages, PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+ if(!pgblk)
+ {
+ _PageFree((PVOID)laddr, 0);
+ return FALSE;
+ }
+
+ desc = (SVGAGuestMemDescriptor*)pgblk;
+ desc->ppn = getPPN(laddr);
+ desc->numPages = 1;
+ blocks = 1;
+
+ /* fill GMR physical structure */
+ for(pgi = 1; pgi < nPages; pgi++)
+ {
+ taddr = laddr + pgi*P_SIZE;
+ tppn = getPPN(taddr);
+
+ if(tppn == desc->ppn + desc->numPages)
+ {
+ desc->numPages++;
+ }
+ else
+ {
+ /* next descriptor is on page edge */
+ if((blocks+1) % (P_SIZE/sizeof(SVGAGuestMemDescriptor)) == 0)
+ {
+ desc++;
+ desc->numPages = 0;
+ desc->ppn = getPPN((DWORD)(desc+1));
+ blocks++;
+ }
+
+ desc++;
+ desc->ppn = tppn;
+ desc->numPages = 1;
+ blocks++;
+ }
+ }
+
+ desc++;
+ desc->ppn = 0;
+ desc->numPages = 0;
+
+
+ if(gb_support) /* don't create MOBs for Gen9 */
+ {
+ int i;
+ /* for simplicity we're always creating table of depth 2, first page is page of PPN pages */
+ mob = (DWORD *)_PageAllocate(1 + (nPages + PTONPAGE - 1)/PTONPAGE, PG_SYS, 0, 0, 0x0, 0x100000, &mobphy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+
+ if(!mob)
+ {
+ _PageFree((PVOID)laddr, 0);
+ _PageFree((PVOID)pgblk, 0);
+ return FALSE;
+ }
+
+ /* dim 1 */
+ for(i = 0; i < (nPages + PTONPAGE - 1)/PTONPAGE; i++)
+ {
+ mob[i] = (mobphy/P_SIZE) + i + 1;
+ }
+ /* dim 2 */
+ for(i = 0; i < nPages; i++)
+ {
+ mob[PTONPAGE + i] = getPPN(laddr + i*P_SIZE);
+ }
+ }
+
+ rinfo->address = (void*)laddr;
+ rinfo->region_address = (void*)pgblk;
+ rinfo->region_ppn = getPPN(pgblk);
+ rinfo->mob_address = (void*)mob;
+ rinfo->mob_ppn = 0;
+ if(mob)
+ {
+ rinfo->mob_ppn = mobphy/P_SIZE;
+ }
+
+ dbg_printf(dbg_region_fragmented);
+ }
+
+ dbg_printf(dbg_gmr, rinfo->region_id, rinfo->region_ppn);
+
+
+ SVGA_Flush_CB();
+
+ if(rinfo->region_id <= SVGA_ReadReg(SVGA_REG_GMR_MAX_IDS))
+ {
+ /* register GMR */
+ SVGA_WriteReg(SVGA_REG_GMR_ID, rinfo->region_id);
+ SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, rinfo->region_ppn);
+ SVGA_Flush_CB();
+ }
+ else
+ {
+ /* GMR is too high, use it as only as MOB (DX) */
+ rinfo->region_ppn = 0;
+ }
+
+ dbg_printf(dbg_gmr_succ, rinfo->size);
+
+ return TRUE;
+}
+
+/**
+ * Free data allocated by SVGA_region_create
+ *
+ **/
+void SVGA_region_free(SVGA_region_info_t *rinfo)
+{
+ BYTE *free_ptr = (BYTE*)rinfo->address;
+
+ SVGA_Flush_CB();
+ SVGA_WriteReg(SVGA_REG_GMR_ID, rinfo->region_id);
+ SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, 0);
+ SVGA_Flush_CB();
+
+ if(rinfo->region_address != NULL)
+ {
+ dbg_printf(dbg_pagefree, rinfo->region_address);
+ _PageFree((PVOID)rinfo->region_address, 0);
+ }
+ else
+ {
+ free_ptr -= P_SIZE;
+ }
+
+ if(rinfo->mob_address != NULL)
+ {
+ dbg_printf(dbg_pagefree, rinfo->mob_address);
+ _PageFree((PVOID)rinfo->mob_address, 0);
+ }
+
+ dbg_printf(dbg_pagefree, free_ptr);
+ _PageFree((PVOID)free_ptr, 0);
+
+ rinfo->address = NULL;
+ rinfo->region_address = NULL;
+ rinfo->mob_address = NULL;
+ rinfo->region_ppn = 0;
+ rinfo->mob_ppn = 0;
+}
+
+/**
+ * GPU10: start context0
+ *
+ **/
+static void SVGA_CB_start()
+{
+ if(cb_support)
+ {
+ cb_enable_t *cbe = cmdbuf;
+
+ memset(cbe, 0, sizeof(cb_enable_t));
+ cbe->cmd = SVGA_DC_CMD_START_STOP_CONTEXT;
+ cbe->cbstart.enable = 1;
+ cbe->cbstart.context = SVGA_CB_CONTEXT_0;
+
+ SVGA_CMB_submit(cmdbuf, sizeof(cb_enable_t), NULL, SVGA_CB_USE_CONTEXT_DEVICE|SVGA_CB_SYNC, 0);
+
+ cb_context0 = TRUE;
+ }
+}
+
+/**
+ * GPU10: stop context0
+ *
+ **/
+static void SVGA_CB_stop()
+{
+ cb_context0 = FALSE;
+
+ if(cb_support)
+ {
+ cb_enable_t *cbe = cmdbuf;
+
+ memset(cbe, 0, sizeof(cb_enable_t));
+ cbe->cmd = SVGA_DC_CMD_START_STOP_CONTEXT;
+ cbe->cbstart.enable = 0;
+ cbe->cbstart.context = SVGA_CB_CONTEXT_0;
+
+ SVGA_CMB_submit(cmdbuf, sizeof(cb_enable_t), NULL, SVGA_CB_USE_CONTEXT_DEVICE|SVGA_CB_SYNC, 0);
+ }
+}
+
+/* Check if screen acceleration is available */
+static BOOL SVGA_hasAccelScreen()
+{
+ if(SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT | SVGA_FIFO_CAP_SCREEN_OBJECT_2))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* from svga3d.c, we need only this function from whole file */
+BOOL SVGA3D_Init(void)
+{
+ SVGA3dHardwareVersion hwVersion;
+
+ if(!(gSVGA.capabilities & SVGA_CAP_EXTENDED_FIFO))
+ {
+// dbg_printf("3D requires the Extended FIFO capability.\n");
+ }
+
+ if(SVGA_HasFIFOCap(SVGA_FIFO_CAP_3D_HWVERSION_REVISED))
+ {
+ hwVersion = gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION_REVISED];
+ }
+ else
+ {
+ if(gSVGA.fifoMem[SVGA_FIFO_MIN] <= sizeof(uint32) * SVGA_FIFO_GUEST_3D_HWVERSION)
+ {
+ //dbg_printf("GUEST_3D_HWVERSION register not present.\n");
+ }
+ hwVersion = gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION];
+ }
+
+ /*
+ * Check the host's version, make sure we're binary compatible.
+ */
+ if(hwVersion == 0)
+ {
+ //dbg_printf("3D disabled by host.");
+ return FALSE;
+ }
+ if (hwVersion < SVGA3D_HWVERSION_WS65_B1)
+ {
+ //dbg_printf("Host SVGA3D protocol is too old, not binary compatible.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static DWORD SVGA_pitch(DWORD width, DWORD bpp)
+{
+ DWORD bp = (bpp + 7) / 8;
+ return (bp * width + 3) & 0xFFFFFFFC;
+}
+
+static void *SVGA_cmd_ptr(DWORD *buf, DWORD *pOffset, DWORD cmd, DWORD cmdsize)
+{
+ DWORD pp = (*pOffset)/sizeof(DWORD);
+ buf[pp] = cmd;
+ *pOffset = (*pOffset) + sizeof(DWORD) + cmdsize;
+
+ return (void*)(buf + pp + 1);
+}
+
+static void SVGA_defineScreen(DWORD w, DWORD h, DWORD bpp)
+{
+ SVGAFifoCmdDefineScreen *screen;
+ SVGAFifoCmdDefineGMRFB *fbgmr;
+ DWORD cmdoff = 0;
+
+ screen = SVGA_cmd_ptr(cmdbuf, &cmdoff, SVGA_CMD_DEFINE_SCREEN, sizeof(SVGAFifoCmdDefineScreen));
+
+ memset(screen, 0, sizeof(SVGAFifoCmdDefineScreen));
+ screen->screen.structSize = sizeof(SVGAScreenObject);
+ screen->screen.id = 0;
+ screen->screen.flags = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
+ screen->screen.size.width = w;
+ screen->screen.size.height = h;
+ screen->screen.root.x = 0;
+ screen->screen.root.y = 0;
+ screen->screen.cloneCount = 0;
+
+ if(bpp < 32)
+ {
+ screen->screen.backingStore.pitch = SVGA_pitch(w, bpp);
+ }
+
+ screen->screen.backingStore.ptr.offset = 0;
+ screen->screen.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
+
+ /* set GMR to same location as screen */
+ if(bpp >= 15/* || bpp < 32*/)
+ {
+ fbgmr = SVGA_cmd_ptr(cmdbuf, &cmdoff, SVGA_CMD_DEFINE_GMRFB, sizeof(SVGAFifoCmdDefineGMRFB));
+
+ if(fbgmr)
+ {
+ fbgmr->ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
+ fbgmr->ptr.offset = 0;
+ fbgmr->bytesPerLine = SVGA_pitch(w, bpp);
+ fbgmr->format.colorDepth = bpp;
+ if(bpp >= 24)
+ {
+ fbgmr->format.bitsPerPixel = 32;
+ fbgmr->format.colorDepth = 24;
+ fbgmr->format.reserved = 0;
+ }
+ else
+ {
+ fbgmr->format.bitsPerPixel = 16;
+ fbgmr->format.colorDepth = 16;
+ fbgmr->format.reserved = 0;
+ }
+ }
+ }
+
+ SVGA_CMB_submit(cmdbuf, cmdoff, NULL, SVGA_CB_SYNC/*|SVGA_CB_FORCE_FIFO*/, 0);
+}
+
+/**
+ * Test if display mode is supported
+ **/
+BOOL SVGA_validmode(DWORD w, DWORD h, DWORD bpp)
+{
+ switch(bpp)
+ {
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
+ return FALSE;
+ }
+
+ if(w <= SVGA_ReadReg(SVGA_REG_MAX_WIDTH))
+ {
+ if(h <= SVGA_ReadReg(SVGA_REG_MAX_HEIGHT))
+ {
+ DWORD size = SVGA_pitch(w, bpp) * h;
+ if(size < hda->vram_size)
+ {
+ if(bpp != 32 && size > SVGA_FB_MAX_TRACEABLE_SIZE)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * Set display mode
+ *
+ **/
+BOOL SVGA_setmode(DWORD w, DWORD h, DWORD bpp)
+{
+ BOOL has3D;
+ if(!SVGA_validmode(w, h, bpp))
+ {
+ return FALSE;
+ }
+
+ /* Make sure, that we drain full FIFO */
+ SVGA_Flush_CB();
+
+ /* stop command buffer context 0 */
+ SVGA_CB_stop();
+
+ SVGA_SetModeLegacy(w, h, bpp); /* setup by legacy registry */
+ SVGA_Flush_CB(); /* make sure, that is really set */
+
+ has3D = SVGA3D_Init();
+
+ /* setting screen by fifo, this method is required in VB 6.1 */
+ if(SVGA_hasAccelScreen())
+ {
+ SVGA_defineScreen(w, h, bpp);
+ SVGA_Flush_CB();
+ }
+
+ /* start command buffer context 0 */
+ SVGA_CB_start();
+
+ /*
+ * JH: this is a bit stupid = all SVGA command cannot work with non 32 bpp.
+ * SVGA_CMD_UPDATE included. So if we're working in 32 bpp, we'll disable
+ * traces and updating framebuffer changes with SVGA_CMD_UPDATE.
+ * On non 32 bpp we just enable SVGA_REG_TRACES.
+ *
+ * QEMU hasn't SVGA_REG_TRACES register and framebuffer cannot be se to
+ * 16 or 8 bpp = we supporting only 32 bpp moders if we're running under it.
+ */
+ if(bpp == 32)
+ {
+ SVGA_WriteReg(SVGA_REG_TRACES, FALSE);
+ }
+ else
+ {
+ SVGA_WriteReg(SVGA_REG_TRACES, TRUE);
+ }
+
+ SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
+ SVGA_Flush_CB();
+
+ hda->width = SVGA_ReadReg(SVGA_REG_WIDTH);
+ hda->height = SVGA_ReadReg(SVGA_REG_HEIGHT);
+ hda->bpp = SVGA_ReadReg(SVGA_REG_BITS_PER_PIXEL);
+ hda->pitch = SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE);
+ hda->stride = hda->height * hda->pitch;
+ hda->surface = 0;
+
+ if(has3D && SVGA_GetDevCap(SVGA3D_DEVCAP_3D) > 0)
+ {
+ hda->flags |= FB_ACCEL_VMSVGA3D;
+ }
+ else
+ {
+ hda->flags &= ~((DWORD)FB_ACCEL_VMSVGA3D);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Fix SVGA caps which are known as bad:
+ * - VirtualBox returning A4R4G4B4 instead of R5G6B5,
+ * try to guess it's value from X8R8G8B8.
+ *
+ */
+DWORD SVGA_FixDevCap(DWORD cap_id, DWORD cap_val)
+{
+ switch(cap_id)
+ {
+ case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
+ {
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_RGB565_BROKEN)
+ {
+ DWORD xrgb8888 = SVGA_GetDevCap(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
+ xrgb8888 &= ~SVGA3DFORMAT_OP_SRGBWRITE; /* nvidia */
+ return xrgb8888;
+ }
+ else
+ {
+ if(cap_val & SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET) /* VirtualBox BUG */
+ {
+ DWORD xrgb8888 = SVGA_GetDevCap(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
+ xrgb8888 &= ~SVGA3DFORMAT_OP_SRGBWRITE; /* nvidia */
+ return xrgb8888;
+ }
+
+ if((cap_val & SVGA3DFORMAT_OP_3DACCELERATION) == 0) /* VirtualBox BUG, older drivers */
+ {
+ DWORD xrgb8888 = SVGA_GetDevCap(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
+ xrgb8888 &= ~SVGA3DFORMAT_OP_SRGBWRITE; /* nvidia */
+ if(xrgb8888 & SVGA3DFORMAT_OP_3DACCELERATION)
+ {
+ return xrgb8888;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ return cap_val;
+}
+
+/**
+ * Read HW cap, supported old way (GPU gen9):
+ * struct SVGA_FIFO_3D_CAPS in FIFO,
+ * and new way (GPU gen10):
+ * SVGA_REG_DEV_CAP HW register
+ *
+ **/
+DWORD SVGA_GetDevCap(DWORD search_id)
+{
+ if (gSVGA.capabilities & SVGA_CAP_GBOBJECTS)
+ {
+ /* new way to read device CAPS */
+ SVGA_WriteReg(SVGA_REG_DEV_CAP, search_id);
+ return SVGA_FixDevCap(search_id, SVGA_ReadReg(SVGA_REG_DEV_CAP));
+ }
+ else
+ {
+ SVGA3dCapsRecord *pCaps = (SVGA3dCapsRecord *)&(gSVGA.fifoMem[SVGA_FIFO_3D_CAPS]);
+ while(pCaps->header.length != 0)
+ {
+ if(pCaps->header.type == SVGA3DCAPS_RECORD_DEVCAPS)
+ {
+ DWORD datalen = (pCaps->header.length - 2)/2;
+ SVGA3dCapPair *pData = (SVGA3dCapPair *)(&pCaps->data);
+ DWORD i;
+
+ for(i = 0; i < datalen; i++)
+ {
+ DWORD id = pData[i][0];
+ DWORD val = pData[i][1];
+
+ if(id == search_id)
+ {
+ return SVGA_FixDevCap(search_id, val);
+ }
+ }
+ }
+ pCaps = (SVGA3dCapsRecord *)((DWORD *)pCaps + pCaps->header.length);
+ }
+ }
+
+ return 0;
+}
+
+DWORD SVGA_query(DWORD type, DWORD index)
+{
+ switch(type)
+ {
+ case SVGA_QUERY_REGS:
+ if(index >= 256) break;
+ return SVGA_ReadReg(index);
+ case SVGA_QUERY_FIFO:
+ if(index >= 1024) break;
+ return gSVGA.fifoMem[index];
+ case SVGA_QUERY_CAPS:
+ if(index >= 512) break;
+ return SVGA_GetDevCap(index);
+ }
+
+ return ~0x0;
+}
+
+void SVGA_query_vector(DWORD type, DWORD index_start, DWORD count, DWORD *out)
+{
+ DWORD i;
+ for(i = 0; i < count; i++)
+ {
+ out[i] = SVGA_query(type, index_start+i);
+ }
+}
+
+void SVGA_HW_enable()
+{
+ if(hda->width > 0 && hda->height > 0)
+ {
+ SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
+
+ SVGA_CB_start();
+ }
+}
+
+void SVGA_HW_disable()
+{
+ SVGA_CB_stop();
+
+ SVGA_Disable();
+}
+
+BOOL SVGA_valid()
+{
+ return SVGA_is_valid;
+}
+
+BOOL FBHDA_swap(DWORD offset)
+{
+ return FALSE;
+}
+
+void FBHDA_access_end(DWORD flags)
+{
+ //dbg_printf(dbg_update, hda->width, hda->height, hda->bpp);
+ fb_lock_cnt--;
+ if(fb_lock_cnt < 0) fb_lock_cnt = 0;
+
+ if(fb_lock_cnt == 0)
+ {
+ if(hda->bpp == 32)
+ {
+ SVGAFifoCmdUpdate *cmd_update;
+ DWORD cmd_offset = 0;
+
+ cmd_update = SVGA_cmd_ptr(cmdbuf, &cmd_offset, SVGA_CMD_UPDATE, sizeof(SVGAFifoCmdUpdate));
+ cmd_update->x = 0;
+ cmd_update->y = 0;
+ cmd_update->width = hda->width;
+ cmd_update->height = hda->height;
+
+ SVGA_CMB_submit(cmdbuf, cmd_offset, NULL, SVGA_CB_SYNC/*|SVGA_CB_FORCE_FIFO*/, 0);
+ }
+ }
+
+ //Signal_Semaphore(hda_sem);
+}
+
+void FBHDA_palette_set(unsigned char index, DWORD rgb)
+{
+ UINT sIndex = SVGA_PALETTE_BASE + index*3;
+
+ SVGA_WriteReg(sIndex+0, (rgb >> 16) & 0xFF);
+ SVGA_WriteReg(sIndex+1, (rgb >> 8) & 0xFF);
+ SVGA_WriteReg(sIndex+2, rgb & 0xFF);
+}
+
+DWORD FBHDA_palette_get(unsigned char index)
+{
+ UINT sIndex = SVGA_PALETTE_BASE + index*3;
+
+ return ((SVGA_ReadReg(sIndex+0) & 0xFF) << 16) |
+ ((SVGA_ReadReg(sIndex+1) & 0xFF) << 8) |
+ (SVGA_ReadReg(sIndex+2) & 0xFF);
+}
diff --git a/minivdd.c b/vxd_vdd.c
index b98ec80..aca9793 100644
--- a/minivdd.c
+++ b/vxd_vdd.c
@@ -24,7 +24,8 @@ THE SOFTWARE.
#include "winhack.h"
#include "vmm.h"
-#include "minivdd32.h"
+#include "vxd_vdd.h"
+#include "3d_accel.h"
#ifdef SVGA
#include "svga_all.h"
@@ -33,10 +34,6 @@ THE SOFTWARE.
/* code and data is same segment */
#include "code32.h"
-#ifdef SVGA
-extern Bool svga_init_success;
-#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
@@ -111,7 +108,7 @@ hardware detection to re-detect the video card.
VDDPROC(GET_CHIP_ID, get_chip_id)
{
#ifdef SVGA
- if(svga_init_success)
+ if(SVGA_valid())
{
uint32 chip_id = (((uint32)gSVGA.vendorId) << 16) || ((uint32)gSVGA.deviceId);
state->Client_EAX = chip_id;
@@ -214,7 +211,7 @@ For performance reasons, you should implement this function.
VDDPROC(GET_TOTAL_VRAM_SIZE, get_total_vram_size)
{
#ifdef SVGA
- if(svga_init_success)
+ if(SVGA_valid())
{
uint32 vram_size = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
state->Client_ECX = vram_size;
diff --git a/minivdd32.h b/vxd_vdd.h
index 38c3a4c..54dcd43 100644
--- a/minivdd32.h
+++ b/vxd_vdd.h
@@ -1,5 +1,5 @@
-#ifndef __MINIVDD32_H__INCLUDED__
-#define __MINIVDD32_H__INCLUDED__
+#ifndef __VXD_VDD_H__INCLUDED__
+#define __VXD_VDD_H__INCLUDED__
#ifdef DBGPRINT
void dbg_printf( const char *s, ... );
@@ -101,7 +101,7 @@ void dbg_printf( const char *s, ... );
/* generate prototypes */
#define VDDFUNC(_fnname, _procname) void __stdcall _procname ## _proc(PCRS_32 state);
-#include "minivdd_func.h"
+#include "vxd_vdd_list.h"
#undef VDDFUNC
#define VDDPROC(_fnname, _procname) void __stdcall _procname ## _proc(PCRS_32 state)
@@ -109,4 +109,4 @@ void dbg_printf( const char *s, ... );
#define VDD_CY state->Client_EFlags |= 0x1
#define VDD_NC state->Client_EFlags &= 0xFFFFFFFEUL
-#endif /* __MINIVDD32_H__INCLUDED__ */
+#endif /* __VXD_VDD_H__INCLUDED__ */
diff --git a/minivdd_func.h b/vxd_vdd_list.h
index cf67e02..cf67e02 100644
--- a/minivdd_func.h
+++ b/vxd_vdd_list.h
diff --git a/vxd_vdd_qemu.c b/vxd_vdd_qemu.c
new file mode 100644
index 0000000..bec4170
--- /dev/null
+++ b/vxd_vdd_qemu.c
@@ -0,0 +1,2 @@
+#define QEMU
+#include "vxd_vdd.c"
diff --git a/vxd_vdd_svga.c b/vxd_vdd_svga.c
new file mode 100644
index 0000000..6f5a503
--- /dev/null
+++ b/vxd_vdd_svga.c
@@ -0,0 +1,2 @@
+#define SVGA
+#include "vxd_vdd.c"
diff --git a/vxdcall.c b/vxdcall.c
deleted file mode 100644
index f43a9c8..0000000
--- a/vxdcall.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2023 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.
-
-*****************************************************************************/
-/* Communication from ring3 PM16 -> ring0 PM32 */
-
-#include <wchar.h> /* wchar_t */
-#include <string.h> /* _fmemset */
-#include <stdint.h>
-#include "winhack.h" /* BOOL */
-
-#include "vxdcodes.h"
-#include "vxdcall.h"
-
-#ifdef DBGPRINT
-extern void dbg_printf( const char *s, ... );
-#else
-#define dbg_printf(...)
-#endif
-
-static DWORD VXD_srv = 0;
-
-#pragma code_seg( _INIT )
-
-BOOL VXD_load()
-{
- if(VXD_srv != 0)
- {
- return TRUE;
- }
-
- _asm{
- push es
- push ax
- push dx
- push bx
- push di
-
- xor di,di
- mov es,di
- mov ax, 1684H
- mov bx, VXD_DEVICE_ID
- int 2FH
- mov word ptr [VXD_srv],di
- mov word ptr [VXD_srv+2],es
-
- pop di
- pop bx
- pop dx
- pop ax
- pop es
- };
-
- return VXD_srv != 0;
-}
-
-void VXD_zeromem(DWORD LAddr, DWORD size)
-{
- static DWORD sLAddr;
- static DWORD ssize;
-
- sLAddr = LAddr;
- ssize = size;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- push ecx
- push esi
-
- mov edx, VXD_PM16_ZEROMEM
- mov esi, [sLAddr]
- mov ecx, [ssize]
- call dword ptr [VXD_srv]
-
- pop esi
- pop ecx
- pop edx
- pop eax
- }
- }
-}
-
-/*** SVGA ***/
-#ifdef SVGA
-BOOL VXD_CreateRegion(DWORD nPages, DWORD __far *lpLAddr, DWORD __far *lpPPN, DWORD __far *lpPGBLKAddr)
-{
- static DWORD snPages;
- static DWORD sLAddr;
- static DWORD sPPN;
- static DWORD sPGBLKAddr;
- static uint16_t state = 0;
-
- snPages = nPages;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- push ecx
- push ebx
-
- mov edx, VMWSVXD_PM16_CREATE_REGION
- mov ecx, [snPages]
- call dword ptr [VXD_srv]
- mov [state], ax
- mov [sLAddr], edx
- mov [sPPN], ecx
- mov [sPGBLKAddr], ebx
-
- pop ebx
- pop ecx
- pop edx
- pop eax
- };
-
- if(state == 1)
- {
- *lpLAddr = sLAddr;
- *lpPPN = sPPN;
- *lpPGBLKAddr = sPGBLKAddr;
-
- return TRUE;
- }
- else
- {
- dbg_printf("state: %X, LAddr: %lX, PPN: %lX\n", state, sLAddr, sPPN);
- }
- }
-
- return FALSE;
-}
-
-BOOL VXD_FreeRegion(DWORD LAddr, DWORD PGBLKAddr)
-{
- static DWORD sLAddr;
- static uint16_t state;
- static DWORD sPGBLKAddr;
-
- sLAddr = LAddr;
- sPGBLKAddr = PGBLKAddr;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- push ecx
- push ebx
-
- mov edx, VMWSVXD_PM16_DESTROY_REGION
- mov ecx, [sLAddr]
- mov ebx, [sPGBLKAddr]
- call dword ptr [VXD_srv]
- mov [state], ax
-
- pop ebx
- pop ecx
- pop edx
- pop eax
- };
-
- if(state == 1)
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-DWORD VXD_apiver()
-{
- static DWORD sver = 0;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- push ecx
-
- mov edx, VMWSVXD_PM16_APIVER
- call dword ptr [VXD_srv]
- mov [sver], ecx
-
- pop ecx
- pop edx
- pop eax
- }
- }
-
- return sver;
-}
-
-
-void CB_start()
-{
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- mov edx, VMWSVXD_PM16_CB_START
- call dword ptr [VXD_srv]
- pop edx
- pop eax
- }
- }
-}
-
-void CB_stop()
-{
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- mov edx, VMWSVXD_PM16_CB_STOP
- call dword ptr [VXD_srv]
- pop edx
- pop eax
- }
- }
-}
-
-void VXD_get_addr(DWORD __far *lpLinFB, DWORD __far *lpLinFifo, DWORD __far *lpLinFifoBounce)
-{
- static DWORD linFB = 0;
- static DWORD linFifo = 0;
- static DWORD linFifoBounce = 0;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
-
- push ecx
- push esi
- push edi
-
- mov edx, VMWSVXD_PM16_GET_ADDR
- call dword ptr [VXD_srv]
-
- mov [linFB], ecx
- mov [linFifo], edi
- mov [linFifoBounce], esi
-
- pop edi
- pop esi
- pop ecx
-
- pop edx
- pop eax
- }
- }
-
- *lpLinFB = linFB;
- *lpLinFifo = linFifo;
- *lpLinFifoBounce = linFifoBounce;
-}
-
-void VXD_get_flags(DWORD __far *lpFlags)
-{
- static DWORD flags = 0;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
-
- push ecx
-
- mov edx, VMWSVXD_PM16_GET_FLAGS
- call dword ptr [VXD_srv]
-
- mov [flags], ecx
-
- pop ecx
-
- pop edx
- pop eax
- }
- }
-
- *lpFlags = flags;
-}
-
-BOOL VXD_FIFOCommit(DWORD bytes, BOOL sync)
-{
- static DWORD sbytes;
- static DWORD cmd;
-
- cmd = VMWSVXD_PM16_FIFO_COMMIT;
- if(sync)
- {
- cmd = VMWSVXD_PM16_FIFO_COMMIT_SYNC;
- }
-
- sbytes = bytes;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- push ecx
-
- mov ecx, [sbytes]
- mov edx, [cmd]
- call dword ptr [VXD_srv]
-
- pop ecx
- pop edx
- pop eax
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-#endif /* SVGA */
-
-/*** QEMU ***/
-BOOL VXD_QEMUFX_supported()
-{
- static DWORD result = 0;
-
- if(VXD_srv != 0)
- {
- _asm
- {
- .386
- push eax
- push edx
- push ecx
-
- mov edx, QEMUVXD_QEMUFX
- call dword ptr [VXD_srv]
- mov [result], ecx
-
- pop ecx
- pop edx
- pop eax
- }
-
- return result == 0 ? FALSE : TRUE;
- }
-
- return FALSE;
-}
diff --git a/vxdcall.h b/vxdcall.h
deleted file mode 100644
index f2ba75d..0000000
--- a/vxdcall.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __VXDCALL_H__INCLUDED__
-#define __VXDCALL_H__INCLUDED__
-
-BOOL VXD_load();
-void VXD_zeromem(DWORD LAddr, DWORD size);
-
-#ifdef SVGA
-BOOL VXD_CreateRegion(DWORD nPages, DWORD __far *lpLAddr, DWORD __far *lpPPN, DWORD __far *lpPGBLKAddr);
-BOOL VXD_FreeRegion(DWORD LAddr, DWORD PGBLKAddr);
-DWORD VXD_apiver();
-void CB_start();
-void CB_stop();
-void VXD_get_addr(DWORD __far *lpLinFB, DWORD __far *lpLinFifo, DWORD __far *lpLinFifoBounce);
-void VXD_get_flags(DWORD __far *lpFlags);
-BOOL VXD_FIFOCommit(DWORD bytes, BOOL sync);
-
-#define VXD_FIFOCommitAll() \
- if(VXD_FIFOCommit(gSVGA.fifo.reservedSize, FALSE)){gSVGA.fifo.reservedSize = 0;}
-
-// if(VXD_FIFOCommit(gSVGA.fifo.reservedSize, FALSE)){gSVGA.fifo.reservedSize = 0;}else{SVGA_FIFOCommitAll();}
-
-#define VXD_FIFOCommitSync() \
- VXD_FIFOCommit(gSVGA.fifo.reservedSize, TRUE);gSVGA.fifo.reservedSize = 0
-#endif /* SVGA */
-
-#ifdef QEMU
-BOOL VXD_QEMUFX_supported();
-#endif
-
-#endif /* __VXDCALL_H__INCLUDED__ */
diff --git a/vxdcall_qemu.c b/vxdcall_qemu.c
deleted file mode 100644
index bc02b59..0000000
--- a/vxdcall_qemu.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define QEMU
-#include "vxdcall.c"
diff --git a/vxdcall_svga.c b/vxdcall_svga.c
deleted file mode 100644
index cc29dd8..0000000
--- a/vxdcall_svga.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SVGA
-#include "vxdcall.c"
diff --git a/vxdcodes.h b/vxdcodes.h
deleted file mode 100644
index 0df14f4..0000000
--- a/vxdcodes.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __VMWSVXD_H__INCLUDED__
-#define __VMWSVXD_H__INCLUDED__
-
-/* Table of "known" drivers
- * https://fd.lod.bz/rbil/interrup/windows/2f1684.html#sect-4579
- * This looks like free
- */
-#define VXD_DEVICE_SVGA_ID 0x4331
-#define VXD_DEVICE_QEMU_ID 0x4332
-
-#ifdef SVGA
-#define VXD_DEVICE_ID VXD_DEVICE_SVGA_ID
-#endif
-
-#ifdef QEMU
-#define VXD_DEVICE_ID VXD_DEVICE_QEMU_ID
-#endif
-
-#define VXD_MAJOR_VER 4 /* should be 4 for windows 95 and newer */
-#define VXD_MINOR_VER 0
-
-#define VXD_PM16_VERSION 0
-#define VXD_PM16_VMM_VERSION 1
-#define VXD_PM16_ZEROMEM 6
-
-/* SVGA specific functions */
-#define VMWSVXD_PM16_CREATE_REGION 2
-#define VMWSVXD_PM16_DESTROY_REGION 3
-#define VMWSVXD_PM16_APIVER 7
-#define VMWSVXD_PM16_CB_START 8
-#define VMWSVXD_PM16_CB_STOP 9
-#define VMWSVXD_PM16_GET_ADDR 10
-#define VMWSVXD_PM16_FIFO_COMMIT 11
-#define VMWSVXD_PM16_FIFO_COMMIT_SYNC 12
-#define VMWSVXD_PM16_GET_FLAGS 13
-
-/* QEMU specific function */
-#define QEMUVXD_QEMUFX 14
-
-#endif /* __VMWSVXD_H__INCLUDED__ */