diff options
author | Jaroslav Hensl <emulator@emulace.cz> | 2025-08-17 01:57:04 +0200 |
---|---|---|
committer | Jaroslav Hensl <emulator@emulace.cz> | 2025-08-17 01:57:04 +0200 |
commit | ecf8b217a6797e791304b9d26dd3d05cbeb50c31 (patch) | |
tree | 59037cf423b0228bc42ed5e6687cc8e0d3c49da9 | |
parent | 739eb72235cba62334f8b42448c9e9c87e7d2dd6 (diff) | |
download | vmdisp9x-main.tar.gz |
-rw-r--r-- | 3d_accel.h | 27 | ||||
-rw-r--r-- | control.c | 12 | ||||
-rw-r--r-- | dddrv.c | 19 | ||||
-rw-r--r-- | makefile | 2 | ||||
-rw-r--r-- | mtrr.h | 4 | ||||
-rw-r--r-- | pm16_calls.c | 13 | ||||
-rw-r--r-- | vxd_lib.c | 5 | ||||
-rw-r--r-- | vxd_lib.h | 1 | ||||
-rw-r--r-- | vxd_main.c | 4 | ||||
-rw-r--r-- | vxd_mtrr.c | 14 | ||||
-rw-r--r-- | vxd_svga.c | 13 | ||||
-rw-r--r-- | vxd_vbe.c | 21 | ||||
-rw-r--r-- | vxd_vdd.c | 2 | ||||
-rw-r--r-- | vxd_vesa.c | 312 |
14 files changed, 355 insertions, 94 deletions
@@ -33,7 +33,7 @@ THE SOFTWARE. #endif
#endif
-#define API_3DACCEL_VER 20250702
+#define API_3DACCEL_VER 20250801
#define ESCAPE_DRV_NT 0x1103 /* (4355) */
@@ -134,14 +134,19 @@ typedef struct FBHDA volatile DWORD pitch;
volatile DWORD surface;
volatile DWORD stride;
+ volatile DWORD onflip;
#ifndef FBHDA_SIXTEEN
- void *vram_pm32;
- DWORD vram_pm16;
+ void *vram_pm32; /* frame buffer address */
+ DWORD vram_pm16;
+ void *vram_phylin; /* frame buffer mapped phy address */
#else
DWORD vram_pm32;
void __far *vram_pm16;
+ DWORD vram_phylin;
#endif
DWORD vram_size; /* real r/w memory size */
+ DWORD vram_size_bar; /* PCI region size, may be larger then vram_size */
+ DWORD vram_size_virt; /* virtual memory size (inc. textures) to reported to apps */
char vxdname[16]; /* file name or "NT" */
DWORD overlay;
FBHDA_overlay_t overlays[FBHDA_OVERLAYS_MAX];
@@ -164,7 +169,8 @@ typedef struct FBHDA #endif
DWORD heap_count; /* number of blocks = heap_size_in_bytes / FB_VRAM_HEAP_GRANULARITY */
DWORD heap_length; /* maximum usable block with current framebuffer */
- DWORD vram_bar_size; /* PCI region size, may be larger then vram_size */
+ DWORD res0;
+ DWORD res1;
DWORD res2;
DWORD res3;
} FBHDA_t;
@@ -197,6 +203,7 @@ typedef struct FBHDA_mode #define FB_SUPPORT_VSYNC 16384
#define FB_SUPPORT_CLOCK 32768
#define FB_SUPPORT_TRIPLE 65536
+#define FB_ACCEL_VIRGL 131072
/* for internal use in RING-0 by VXD only */
BOOL FBHDA_init_hw();
@@ -216,15 +223,17 @@ void FBHDA_free(); #define FBHDA_ACCESS_MOUSE_MOVE 2
#define FBHDA_ACCESS_SURFACE_DIRTY 4
+#define FBHDA_ACCESS_EXCLUSIVE_BEGIN 8
+#define FBHDA_ACCESS_EXCLUSIVE_END 16
+
#define FBHDA_SWAP_NOWAIT 1
-#define FBHDA_SWAP_WAIT 2
-#define FBHDA_SWAP_SCHEDULE 4
+#define FBHDA_SWAP_VTRACE 2
+#define FBHDA_SWAP_QUERY 4
void FBHDA_access_begin(DWORD flags);
void FBHDA_access_end(DWORD flags);
void FBHDA_access_rect(DWORD left, DWORD top, DWORD right, DWORD bottom);
-BOOL FBHDA_swap(DWORD offset);
-BOOL FBHDA_swap_ex(DWORD offset, DWORD flags);
+BOOL FBHDA_swap(DWORD offset, DWORD flags);
void FBHDA_clean();
void FBHDA_palette_set(unsigned char index, DWORD rgb);
DWORD FBHDA_palette_get(unsigned char index);
@@ -460,7 +469,7 @@ typedef FBHDA_t *(__cdecl *FBHDA_setup_t)(); typedef void (__cdecl *FBHDA_access_begin_t)(DWORD flags);
typedef void (__cdecl *FBHDA_access_end_t)(DWORD flags);
typedef void (__cdecl *FBHDA_access_rect_t)(DWORD left, DWORD top, DWORD right, DWORD bottom);
-typedef BOOL (__cdecl *FBHDA_swap_t)(DWORD offset);
+typedef BOOL (__cdecl *FBHDA_swap_t)(DWORD offset, DWORD flags);
typedef BOOL (__cdecl *FBHDA_page_modify_t)(DWORD flat_address, DWORD size, const BYTE *new_data);
typedef void (__cdecl *FBHDA_clean_t)(void);
typedef BOOL (__cdecl *FBHDA_mode_query_t)(DWORD index, FBHDA_mode_t *mode);
@@ -111,6 +111,13 @@ const static opengl_icd_t vmwsvga_icd = { "VMWSVGA"
};
+/* Mesa3D VirGL OpengGL */
+const static opengl_icd_t virgl_icd = {
+ 0x2,
+ 0x1,
+ "VIRGL"
+};
+
/* VIDEOPARAMETERS */
static VIDEOPARAMETERS_t tvsetup = {
{0x02C62061UL, 0x1097, 0x11d1, 0x92, 0x0F, 0x00, 0xA0, 0x24, 0xDF, 0x15, 0x6E},
@@ -216,6 +223,11 @@ LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function, _fmemcpy(lpOutput, &vmwsvga_icd, OPENGL_ICD_SIZE);
rc = 1;
}
+ else if((hda->flags & FB_ACCEL_VIRGL) && ((hda->flags & FB_FORCE_SOFTWARE) == 0))
+ {
+ _fmemcpy(lpOutput, &virgl_icd, OPENGL_ICD_SIZE);
+ rc = 1;
+ }
else if((hda->flags & FB_ACCEL_QEMU3DFX) && ((hda->flags & FB_FORCE_SOFTWARE) == 0))
{
_fmemcpy(lpOutput, &qemu3dfx_icd, OPENGL_ICD_SIZE);
@@ -196,6 +196,7 @@ static void buildDDHALInfo(VMDAHAL_t __far *hal, int modeidx) BOOL can_flip;
WORD heap;
WORD bytes_per_pixel;
+ DWORD stride;
// static DWORD dwpFOURCCs[3];
// DWORD bufpos;
@@ -256,13 +257,28 @@ static void buildDDHALInfo(VMDAHAL_t __far *hal, int modeidx) hal->ddHALInfo.vmiData.dwNumHeaps = 0;
heap = 0;
can_flip = hda->flags & FB_SUPPORT_FLIPING;
+
+ stride = hda->stride;
+
+ /* VESA driver need round system surface on pages */
+ if(hda->flags & FB_VESA_MODES)
+ {
+ DWORD m;
+ stride = (hda->stride + 0x00000FFFUL) & 0xFFFF000UL;
+ m = stride % hda->pitch;
+ if(m)
+ {
+ stride += hda->pitch - m;
+ }
+ }
hal->vidMem[0].dwFlags = VIDMEM_ISLINEAR;
hal->vidMem[0].ddsCaps.dwCaps = 0;//DDSCAPS_OFFSCREENPLAIN; - what this memory CANNOT be used for
- hal->vidMem[0].fpStart = hda->vram_pm32 + hda->system_surface + hda->stride;
+ hal->vidMem[0].fpStart = hda->vram_pm32 + hda->system_surface + stride;
hal->vidMem[0].fpEnd = hda->vram_pm32 + hda->vram_size - hda->overlays_size - 1;
hal->ddHALInfo.vmiData.dwNumHeaps = 1;
+#if 0
if(hda->vram_size < hda->vram_bar_size)
{
/* on vmware is only first 16 MB regular memory, we map the "blackhole" to another heap, but driver will alocate surface in system memory */
@@ -272,6 +288,7 @@ static void buildDDHALInfo(VMDAHAL_t __far *hal, int modeidx) hal->vidMem[1].ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN;
hal->ddHALInfo.vmiData.dwNumHeaps = 2;
}
+#endif
/*
* capabilities supported
@@ -14,7 +14,7 @@ OBJS += & INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 119
+VER_BUILD = 120
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
@@ -32,8 +32,8 @@ THE SOFTWARE. #define MTRR__MTRRIsPatSupported 2
#define MTRR__MTRR_PowerState_Change 3
-DWORD __cdecl MTRR_GetVersion();
-DWORD __cdecl MTRR_SetPhysicalCacheTypeRange(DWORD PhysicalAddress, DWORD reserved, DWORD NumberOfBytes, DWORD CacheType);
+DWORD __stdcall MTRR_GetVersion();
+DWORD __stdcall MTRR_SetPhysicalCacheTypeRange(DWORD PhysicalAddress, DWORD reserved, DWORD NumberOfBytes, DWORD CacheType);
#define MTRR_STATUS_SUCCESS 0x00000000UL
#define MTRR_STATUS_NO_SUCH_DEVICE 0xC000000EUL
diff --git a/pm16_calls.c b/pm16_calls.c index 8406be2..626d804 100644 --- a/pm16_calls.c +++ b/pm16_calls.c @@ -207,25 +207,30 @@ void FBHDA_access_rect(DWORD left, DWORD top, DWORD right, DWORD bottom) }
}
-BOOL FBHDA_swap(DWORD offset)
+BOOL FBHDA_swap(DWORD offset, DWORD flags)
{
static DWORD sOffset;
+ static DWORD sFlags;
static BOOL status;
sOffset = offset;
+ sFlags = flags;
status = FALSE;
-
+
_asm
{
.386
push eax
push edx
push ecx
+ push esi
mov edx, OP_FBHDA_SWAP
- mov ecx, [sOffset]
+ mov ecx, [sFlags]
+ mov esi, [sOffset]
call dword ptr [VXD_VM]
mov [status], cx
-
+
+ pop esi
pop ecx
pop edx
pop eax
@@ -547,6 +547,11 @@ DWORD __declspec(naked) __cdecl _PageCommitContig(ULONG page, ULONG npages, ULON VMMJmp(_PageCommitContig);
}
+DWORD __declspec(naked) __cdecl _PageDecommit(ULONG page, ULONG npages, ULONG flags)
+{
+ VMMJmp(_PageDecommit);
+}
+
DWORD __declspec(naked) __cdecl _LinMapIntoV86(ULONG HLinPgNum, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG flags)
{
VMMJmp(_LinMapIntoV86);
@@ -62,6 +62,7 @@ DWORD __cdecl _PageCommit(ULONG page, ULONG npages, ULONG hpd, ULONG pagerdata, DWORD __cdecl _PageCommitPhys(ULONG page, ULONG npages, ULONG physpg, ULONG flags);
DWORD __cdecl _PageReAllocate(ULONG hMem, ULONG nPages, ULONG flags);
DWORD __cdecl _PageCommitContig(ULONG page, ULONG npages, ULONG flags, ULONG alignmask, ULONG minphys, ULONG maxphys);
+DWORD __cdecl _PageDecommit(ULONG page, ULONG npages, ULONG flags);
DWORD __cdecl _LinMapIntoV86(ULONG HLinPgNum, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG flags);
DWORD __cdecl _MapIntoV86(ULONG hMem, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG PageOff, ULONG flags);
DWORD __cdecl _Allocate_Global_V86_Data_Area(ULONG nBytes, ULONG flags);
@@ -394,7 +394,7 @@ WORD __stdcall VXD_API_Proc(PCRS_32 state) case OP_FBHDA_SWAP:
{
BOOL rs;
- rs = FBHDA_swap(state->Client_ECX);
+ rs = FBHDA_swap(state->Client_ESI, state->Client_ECX);
state->Client_ECX = (DWORD)rs;
rc = 1;
break;
@@ -841,7 +841,7 @@ DWORD __stdcall Device_IO_Control_proc(DWORD vmhandle, struct DIOCParams *params rc = 0;
break;
case OP_FBHDA_SWAP:
- outBuf[0] = FBHDA_swap(inBuf[0]);
+ outBuf[0] = FBHDA_swap(inBuf[0], inBuf[1]);
rc = 0;
break;
case OP_FBHDA_CLEAN:
@@ -30,17 +30,21 @@ THE SOFTWARE. #include "vxd_lib.h"
#include "mtrr.h"
-DWORD __cdecl MTRR_GetVersion()
+DWORD __stdcall MTRR_GetVersion()
{
DWORD rc = 0;
VxDCall(MTRR, Get_Version);
- _asm and eax, 0xFFFF
- _asm mov eax, [rc]
-
+ _asm
+ {
+ jc mttr_fail
+ mov [rc],1
+ mttr_fail:
+ }
+
return rc;
}
-DWORD __declspec(naked) __cdecl MTRR_SetPhysicalCacheTypeRange(DWORD PhysicalAddress, DWORD reserved, DWORD NumberOfBytes, DWORD CacheType)
+DWORD __declspec(naked) __stdcall MTRR_SetPhysicalCacheTypeRange(DWORD PhysicalAddress, DWORD reserved, DWORD NumberOfBytes, DWORD CacheType)
{
VxDJmp(MTRR, MTRRSetPhysicalCacheTypeRange);
}
@@ -586,9 +586,11 @@ BOOL SVGA_init_hw() /* fill address in FBHDA */
hda->vram_pm32 = (void*)gSVGA.fbLinear;
hda->vram_size = gSVGA.vramSize;
- hda->vram_bar_size = gSVGA.vramSize;
+ hda->vram_size_bar = gSVGA.vramSize;
+ hda->vram_size_virt = conf_vram_limit*1024*1024;
hda->vram_pm16 = fb_pm16;
-
+ hda->vram_phylin = hda->vram_pm32; /* no fb buffer emulation */
+
memcpy(hda->vxdname, SVGA_vxd_name, sizeof(SVGA_vxd_name));
hda->flags |= FB_ACCEL_VMSVGA;
@@ -1134,10 +1136,15 @@ BOOL SVGA_valid() return SVGA_is_valid;
}
-BOOL FBHDA_swap(DWORD offset)
+BOOL FBHDA_swap(DWORD offset, DWORD flags)
{
BOOL rc = FALSE;
+ if((flags & FBHDA_SWAP_QUERY) != 0)
+ {
+ return TRUE;
+ }
+
if(hda->overlay > 0)
{
/* on overlay emulate behaviour */
@@ -150,10 +150,12 @@ BOOL VBE_init_hw() dbg_printf(dbg_vbe_init, vram_phy, vram_size);
hda->vram_size = vram_size;
- hda->vram_bar_size = vram_size;
+ hda->vram_size_bar = vram_size;
+ hda->vram_size_virt = vram_size;
hda->vram_pm32 = (void*)_MapPhysToLinear(vram_phy, vram_size, 0);
hda->flags |= FB_SUPPORT_FLIPING;
+ hda->vram_phylin = hda->vram_pm32;
#ifndef QEMU
FBHDA_memtest();
@@ -303,23 +305,28 @@ DWORD FBHDA_palette_get(unsigned char index) return (r << 16) | (g << 8) | b;
}
-BOOL FBHDA_swap(DWORD offset)
+BOOL FBHDA_swap(DWORD offset, DWORD flags)
{
DWORD ps = ((hda->bpp+7)/8);
DWORD offset_y = offset/hda->pitch;
DWORD offset_x = (offset % hda->pitch)/ps;
-
+
+ if((flags & FBHDA_SWAP_QUERY) != 0)
+ {
+ return TRUE;
+ }
+
if(offset + hda->stride > hda->vram_size) return FALSE; /* if exceed VRAM */
-
+
FBHDA_access_begin(0);
-
+
outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_Y_OFFSET);
outpw(VBE_DISPI_IOPORT_DATA, (WORD)offset_y);
outpw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_X_OFFSET);
outpw(VBE_DISPI_IOPORT_DATA, (WORD)offset_x);
-
+
hda->surface = offset;
-
+
FBHDA_access_end(0);
return TRUE;
@@ -372,7 +372,7 @@ For performance reasons, you should implement this function. **/
VDDPROC(GET_TOTAL_VRAM_SIZE, get_total_vram_size)
{
- state->Client_ECX = hda->vram_size;
+ state->Client_ECX = hda->vram_size_virt;
VDD_CY;
}
@@ -67,6 +67,9 @@ static DWORD vesa_modes_cnt = 0; WORD vesa_version = 0;
static DWORD vesa_caps = 0;
static int act_mode = -1;
+static BOOL exclusive_mode = FALSE;
+static BOOL vga_mode = TRUE;
+static BOOL mttr_was_set = FALSE;
/* access rect */
static DWORD rect_left;
@@ -126,6 +129,7 @@ static BOOL vesa_valid = FALSE; static DWORD conf_dos_window = 0;
static DWORD conf_hw_double_buf = 2;
+static DWORD conf_mtrr = 1;
#define SCREEN_EMULATED_CENTER 0
#define SCREEN_EMULATED_COPY 1
@@ -160,14 +164,86 @@ static void alloc_modes_info(DWORD cnt) vesa_modes_cnt = 0;
}
+DWORD ram_phy = 0;
+DWORD vram_phy = 0;
+DWORD vram_lin = 0;
+DWORD shadow_pages = 0;
+
+#define VMEM_FLAGS (PC_INCR|PC_USER|PC_WRITEABLE)
+
+static BOOL shadow_alloc(DWORD size)
+{
+ DWORD pages = size/P_SIZE;
+ DWORD free_pages = _GetFreePageCount(0);
+
+ if((free_pages*2) >= pages) /* we need twice memory than shadow buffer */
+ {
+ ram_phy = _PageCommitContig(0, pages, PCC_NOLIN, 0x03, 0, -1);
+ if(ram_phy != 0xFFFFFFFF)
+ {
+ vram_lin = _PageReserve(PR_SYSTEM, pages, PR_FIXED);
+ if(vram_lin != 0xFFFFFFFF)
+ {
+ _PageCommitPhys(vram_lin/P_SIZE, pages, ram_phy/P_SIZE, VMEM_FLAGS);
+ dbg_printf("_PageCommitPhys(..., %ld, %lX, ...)\n", pages, ram_phy);
+
+ shadow_pages = pages;
+ return TRUE;
+ }
+ }
+ }
+
+ vram_lin = 0;
+ return FALSE;
+}
+
+static void shadow_remap()
+{
+ if(vram_lin)
+ {
+ DWORD stride_pages = (hda->stride + P_SIZE - 1) / P_SIZE;
+ dbg_printf("_PageDecommit(%lX, %d, 0)\n", vram_lin/P_SIZE, shadow_pages);
+ //_PageDecommit(vram_lin/P_SIZE, shadow_pages, 0);
+ if(screen_mode >= SCREEN_FLIP)
+ {
+ /* when multiple buffering (flip) is supported, shadowing system area, other surfaces keep in vram */
+ if(!exclusive_mode)
+ {
+ DWORD pages_ram = stride_pages;
+ DWORD pages_vram = shadow_pages - pages_ram;
+ _PageCommitPhys(vram_lin/P_SIZE, pages_ram, ram_phy/P_SIZE, VMEM_FLAGS);
+ _PageCommitPhys((vram_lin/P_SIZE)+stride_pages, pages_vram, (vram_phy/P_SIZE)+stride_pages, VMEM_FLAGS);
+ dbg_printf("_PageCommitPhys >= SCREEN_FLIP (normal)\n");
+ }
+ else
+ {
+ _PageCommitPhys((vram_lin/P_SIZE), shadow_pages, (vram_phy/P_SIZE), VMEM_FLAGS);
+ }
+ }
+ else
+ {
+ /* when using flip emulation, shadow all vram but keep visible area in VRAM */
+ DWORD pages_ram = shadow_pages - stride_pages;
+ DWORD pages_vram = stride_pages;
+
+ dbg_printf("_PageCommitPhys < SCREEN_FLIP\n");
+
+ _PageCommitPhys(vram_lin/P_SIZE, pages_vram, vram_phy/P_SIZE, VMEM_FLAGS);
+ _PageCommitPhys((vram_lin/P_SIZE)+stride_pages, pages_ram, (ram_phy/P_SIZE)+stride_pages, VMEM_FLAGS);
+ }
+
+ dbg_printf("shadow_remap SUCC\n");
+ }
+}
+
static char VESA_conf_path[] = "Software\\vmdisp9x\\vesa";
BOOL VESA_init_hw()
{
DWORD flat;
DWORD conf_vram_limit = 128;
- DWORD conf_mtrr = 1;
- DWORD conf_no_memtest = 0;
+ DWORD conf_no_memtest = 1;
+ DWORD conf_shadow_mb = 32;
dbg_printf("VESA init begin...\n");
@@ -179,6 +255,11 @@ BOOL VESA_init_hw() flat = _PageAllocate(1, PG_SYS, 0, 0x0, 0, 0x100000, &vesa_buf_phy, PAGEUSEALIGN | PAGECONTIG | PAGEFIXED);
vesa_buf = (void*)flat;
+
+ if(!shadow_alloc(conf_shadow_mb*1024*1024))
+ {
+ dbg_printf("cannot allocated %d MB RAM!\n", conf_shadow_mb);
+ }
if(vesa_buf)
{
@@ -262,6 +343,14 @@ BOOL VESA_init_hw() m->phy = modeinfo->PhysBasePtr;
m->mode_id = modes[i];
m->flags = modeinfo->ModeAttributes;
+ if(m->bpp == 16)
+ {
+ if(modeinfo->GreenMaskSize == 5)
+ {
+ m->bpp = 15;
+ }
+ }
+
vesa_modes_cnt++;
if(m->phy)
@@ -293,34 +382,28 @@ BOOL VESA_init_hw() memcpy(hda->vxdname, vesa_vxd_name, sizeof(vesa_vxd_name));
hda->vram_size = info->TotalMemory * 0x10000UL;
- if(hda->vram_size > conf_vram_limit*1024*1024)
+ if(hda->vram_size > (conf_vram_limit*1024*1024))
{
hda->vram_size = conf_vram_limit*1024*1024;
}
- hda->vram_bar_size = hda->vram_size;
+ hda->vram_size_bar = hda->vram_size;
+ hda->vram_size_virt = conf_vram_limit*1024*1024;
if(fb_phy == 0xFFFFFFFF)
{
fb_phy = ISA_LFB;
}
-
- hda->vram_pm32 = (void*)_MapPhysToLinear(fb_phy, hda->vram_size, 0);
-
- if(conf_mtrr)
+
+ vram_phy = fb_phy;
+ hda->vram_phylin = (void*)_MapPhysToLinear(vram_phy, hda->vram_size, 0);
+ if(vram_lin)
{
- if(fb_phy > 1*1024*1024)
- {
- if(MTRR_GetVersion())
- {
- dbg_printf("MTRR supported\n");
- MTRR_SetPhysicalCacheTypeRange(fb_phy, 0, hda->vram_size, MTRR_FRAMEBUFFERCACHED);
- }
- else
- {
- dbg_printf("MTRR unsupported\n");
- }
- }
+ hda->vram_pm32 = (void*)vram_lin;
+ }
+ else
+ {
+ hda->vram_pm32 = hda->vram_phylin;
}
hda->flags |= FB_SUPPORT_FLIPING | FB_VESA_MODES;
@@ -367,7 +450,8 @@ BOOL VESA_validmode(DWORD w, DWORD h, DWORD bpp) void VESA_clear()
{
- memset((BYTE*)hda->vram_pm32+hda->system_surface, 0, hda->pitch*hda->height);
+ memset((BYTE*)hda->vram_pm32+hda->system_surface, 0, hda->stride);
+ dbg_printf("Clear success\n");
}
BOOL VESA_setmode_phy(DWORD w, DWORD h, DWORD bpp, DWORD rr_min, DWORD rr_max)
@@ -508,10 +592,33 @@ BOOL VESA_setmode_phy(DWORD w, DWORD h, DWORD bpp, DWORD rr_min, DWORD rr_max) return FALSE;
}
+static void mtrr_setup()
+{
+ if(conf_mtrr && !mttr_was_set)
+ {
+ if(vram_phy > 1*1024*1024)
+ {
+ if(MTRR_GetVersion())
+ {
+ dbg_printf("MTRR supported\n");
+ dbg_printf("MTRR_SetPhysicalCacheTypeRange(%lX, 0, %ld, %ld)\n", vram_phy, hda->vram_size, MTRR_FRAMEBUFFERCACHED);
+ MTRR_SetPhysicalCacheTypeRange(vram_phy, 0, hda->vram_size, MTRR_FRAMEBUFFERCACHED);
+ mttr_was_set = TRUE;
+ }
+ else
+ {
+ dbg_printf("MTRR unsupported\n");
+ }
+ }
+ }
+}
+
BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp, DWORD rr_min, DWORD rr_max)
{
if(VESA_setmode_phy(w, h, bpp, rr_min, rr_max))
{
+ shadow_remap();
+ mtrr_setup();
VESA_clear();
mouse_invalidate();
return TRUE;
@@ -611,8 +718,36 @@ DWORD FBHDA_palette_get(unsigned char index) #define SWAP_TESTS 1024
-BOOL FBHDA_swap(DWORD offset)
+static DWORD wait_off_x = 0;
+static DWORD wait_off_y = 0;
+
+BOOL FBHDA_swap(DWORD offset, DWORD flags)
{
+ if((flags & FBHDA_SWAP_QUERY) != 0)
+ {
+ if(hda->onflip)
+ {
+ CRS_32 regs;
+ load_client_state(®s);
+ regs.Client_EAX = VESA_CMD_DISPLAY_START;
+ regs.Client_EBX = VESA_DISPLAYSTART_GET;
+ regs.Client_ECX = 0;
+ regs.Client_EDX = 0;
+ if(!VESA_SUCC(regs))
+ {
+ hda->onflip = 0;
+ return FALSE;
+ }
+
+ if((wait_off_x == (regs.Client_ECX & 0xFFFF)) &&
+ (wait_off_y == (regs.Client_EDX & 0xFFFF)))
+ {
+ hda->onflip = 0;
+ }
+ }
+ return TRUE;
+ }
+
if((offset + hda->stride) < hda->vram_size && offset >= hda->system_surface)
{
switch(screen_mode)
@@ -625,11 +760,15 @@ BOOL FBHDA_swap(DWORD offset) break;
case SCREEN_FLIP:
case SCREEN_FLIP_VSYNC:
- {
+ {
CRS_32 regs;
DWORD off_x;
DWORD off_y;
- if(fb_lock_cnt == 0)
+ if(offset == 0)
+ {
+ FBHDA_access_begin(0);
+ }
+ else if(fb_lock_cnt == 0)
{
mouse_erase();
}
@@ -645,30 +784,44 @@ BOOL FBHDA_swap(DWORD offset) vesa_bios(®s);
if(VESA_SUCC(regs))
{
- /* wait until is set */
- DWORD test_off_x, test_off_y;
- DWORD nums_test = 0;
- do
+ if((flags & FBHDA_SWAP_NOWAIT) == 0)
{
- regs.Client_EAX = VESA_CMD_DISPLAY_START;
- regs.Client_EBX = VESA_DISPLAYSTART_GET;
- regs.Client_ECX = 0;
- regs.Client_EDX = 0;
- if(!VESA_SUCC(regs))
- {
- break;
- }
- if(++nums_test > SWAP_TESTS)
+ /* wait until is set */
+ DWORD test_off_x, test_off_y;
+ DWORD nums_test = 0;
+ do
{
- break;
- }
- test_off_x = regs.Client_ECX & 0xFFFF;
- test_off_y = regs.Client_EDX & 0xFFFF;
- } while((test_off_x != off_x) || (test_off_y != off_y));
+ regs.Client_EAX = VESA_CMD_DISPLAY_START;
+ regs.Client_EBX = VESA_DISPLAYSTART_GET;
+ regs.Client_ECX = 0;
+ regs.Client_EDX = 0;
+ if(!VESA_SUCC(regs))
+ {
+ break;
+ }
+ if(++nums_test > SWAP_TESTS)
+ {
+ break;
+ }
+ test_off_x = regs.Client_ECX & 0xFFFF;
+ test_off_y = regs.Client_EDX & 0xFFFF;
+ } while((test_off_x != off_x) || (test_off_y != off_y));
+ hda->onflip = 0;
+ }
+ else
+ {
+ hda->onflip = 1;
+ }
+ wait_off_x = off_x;
+ wait_off_y = off_y;
}
hda->surface = offset;
- if(fb_lock_cnt == 0)
+ if(offset == 0)
+ {
+ FBHDA_access_end(0);
+ }
+ else if(fb_lock_cnt == 0)
{
mouse_blit();
}
@@ -695,9 +848,41 @@ static inline void update_rect(DWORD left, DWORD top, DWORD right, DWORD bottom) rect_bottom = bottom;
}
+static inline void fix_rect()
+{
+ if(rect_left > hda->width)
+ rect_left = 0;
+
+ if(rect_top > hda->height)
+ rect_top = 0;
+
+ if(rect_right > hda->width)
+ rect_right = hda->width;
+
+ if(rect_bottom > hda->height)
+ rect_bottom = hda->height;
+}
+
void FBHDA_access_begin(DWORD flags)
{
- //Wait_Semaphore(hda_sem, 0);
+ if((flags & FBHDA_ACCESS_EXCLUSIVE_BEGIN) != 0)
+ {
+ if(!exclusive_mode)
+ {
+ exclusive_mode = TRUE;
+ shadow_remap();
+ }
+ }
+ else if((flags & FBHDA_ACCESS_EXCLUSIVE_END) != 0)
+ {
+ if(exclusive_mode)
+ {
+ exclusive_mode = FALSE;
+ shadow_remap();
+ }
+ }
+
+
if(fb_lock_cnt++ == 0)
{
if(flags & FBHDA_ACCESS_MOUSE_MOVE)
@@ -754,7 +939,7 @@ static void VESA_copy_rect() DWORD bs = (hda->bpp + 7) >> 3;
DWORD line_size = (rect_right - rect_left) * bs;
DWORD line_start = rect_left * bs;
- BYTE *dst = (BYTE*)hda->vram_pm32;
+ BYTE *dst = (BYTE*)hda->vram_phylin;
BYTE *src = ((BYTE*)hda->vram_pm32) + hda->surface;
dst += (rect_top * hda->pitch) + line_start;
@@ -792,22 +977,12 @@ void FBHDA_access_end(DWORD flags) case SCREEN_EMULATED_CENTER:
case SCREEN_EMULATED_COPY:
{
- if(rect_left > hda->width)
- rect_left = 0;
-
- if(rect_top > hda->height)
- rect_top = 0;
-
- if(rect_right > hda->width)
- rect_right = hda->width;
-
- if(rect_bottom > hda->height)
- rect_bottom = hda->height;
-
+ fix_rect();
if(rect_left == 0 && rect_top == 0 &&
rect_right == hda->width && rect_bottom == hda->height)
{
- memcpy(hda->vram_pm32, ((BYTE*)hda->vram_pm32)+hda->surface, hda->stride);
+ // TODO: DMA?
+ memcpy(hda->vram_phylin, ((BYTE*)hda->vram_pm32)+hda->surface, hda->stride);
}
else
{
@@ -816,6 +991,26 @@ void FBHDA_access_end(DWORD flags) break;
}
+ case SCREEN_FLIP:
+ case SCREEN_FLIP_VSYNC:
+ {
+ if(hda->surface == 0)
+ {
+ fix_rect();
+ if(rect_left == 0 && rect_top == 0 &&
+ rect_right == hda->width && rect_bottom == hda->height)
+ {
+ // TODO: DMA?
+ memcpy(hda->vram_phylin, hda->vram_pm32, hda->stride);
+ }
+ else
+ {
+ VESA_copy_rect();
+ }
+ }
+
+ break;
+ }
}
// cursor
}
@@ -838,7 +1033,6 @@ void FBHDA_overlay_unlock(DWORD flags) }
-static BOOL vga_mode = TRUE;
void VESA_HIRES_enable()
{
|