diff options
-rw-r--r-- | init.c | 2 | ||||
-rw-r--r-- | makefile | 117 | ||||
-rw-r--r-- | modes.c | 27 | ||||
-rw-r--r-- | modes_vesa.c | 2 | ||||
-rw-r--r-- | pm16_calls.c | 100 | ||||
-rw-r--r-- | pm16_calls_vesa.c | 2 | ||||
-rw-r--r-- | res/display.rcv | 2 | ||||
-rw-r--r-- | res/vesamini.rc | 19 | ||||
-rw-r--r-- | vesa.h | 139 | ||||
-rw-r--r-- | vmdisp9x.inf | 23 | ||||
-rw-r--r-- | vxd.h | 3 | ||||
-rw-r--r-- | vxd_lib.c | 47 | ||||
-rw-r--r-- | vxd_lib.h | 7 | ||||
-rw-r--r-- | vxd_main.c | 46 | ||||
-rw-r--r-- | vxd_main_vesa.c | 2 | ||||
-rw-r--r-- | vxd_vbe.c | 3 | ||||
-rw-r--r-- | vxd_vdd.c | 14 | ||||
-rw-r--r-- | vxd_vdd_vesa.c | 2 | ||||
-rw-r--r-- | vxd_vesa.c | 391 |
19 files changed, 942 insertions, 6 deletions
@@ -168,6 +168,8 @@ extern char __based( __segname( "_TEXT" ) ) *pText; UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
{
+ dbg_printf( "DriverInit: ENTER\n" );
+
/* Lock the code segment. */
GlobalSmartPageLock( (__segment)pText );
@@ -3,17 +3,18 @@ OBJS = & dibthunk.obj dddrv.obj drvlib.obj enable.obj init.obj &
control.obj pm16_calls.obj pm16_calls_svga.obj pm16_calls_qemu.obj &
palette.obj sswhook.obj modes.obj modes_svga.obj scrsw.obj scrsw_svga.obj &
+ pm16_calls_vesa.obj modes_vesa.obj
OBJS += &
dbgprint32.obj svga.obj pci.obj vxd_fbhda.obj vxd_lib.obj vxd_main.obj &
vxd_main_qemu.obj vxd_main_svga.obj vxd_svga.obj vxd_vdd.obj vxd_vdd_qemu.obj &
vxd_vdd_svga.obj vxd_vbe.obj vxd_vbe_qemu.obj vxd_mouse.obj &
vxd_mouse_svga.obj vxd_svga_mouse.obj vxd_svga_mem.obj vxd_svga_cb.obj &
- vxd_halloc.obj
+ vxd_halloc.obj vxd_main_vesa.obj vxd_vesa.obj vxd_vdd_vesa.obj
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 109
+VER_BUILD = 110
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
@@ -69,13 +70,15 @@ RC16_FLAGS = -40 -i $(DDK98_PATH)\inc\win98\inc16 -i res -d DRV_VER_BUILD=$(VER_ BOXVMINI_DRV_RC = $(RC16) $(RC16_FLAGS) res\boxvmini.rc $@
VMWSMINI_DRV_RC = $(RC16) $(RC16_FLAGS) res\vmwsmini.rc $@
QEMUMINI_DRV_RC = $(RC16) $(RC16_FLAGS) res\qemumini.rc $@
+VESAMINI_DRV_RC = $(RC16) $(RC16_FLAGS) res\vesamini.rc $@
!else
BOXVMINI_DRV_RC = wrc -q boxvmini.res $@ && $(FIXLINK_EXE) -40 $@
VMWSMINI_DRV_RC = wrc -q vmwsmini.res $@ && $(FIXLINK_EXE) -40 $@
QEMUMINI_DRV_RC = wrc -q qemumini.res $@ && $(FIXLINK_EXE) -40 $@
+VESAMINI_DRV_RC = wrc -q vesamini.res $@ && $(FIXLINK_EXE) -40 $@
!endif
-all : vmwsmini.drv vmwsmini.vxd qemumini.drv qemumini.vxd boxvmini.drv boxvmini.vxd
+all : vmwsmini.drv vmwsmini.vxd qemumini.drv qemumini.vxd boxvmini.drv boxvmini.vxd vesamini.drv vesamini.vxd
# Object files: PM16 RING-3
dbgprint.obj : dbgprint.c .autodepend
@@ -111,6 +114,9 @@ pm16_calls_svga.obj : pm16_calls_svga.c .autodepend pm16_calls_qemu.obj : pm16_calls_qemu.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+pm16_calls_vesa.obj : pm16_calls_vesa.c .autodepend
+ $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+
palette.obj : palette.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
@@ -123,6 +129,9 @@ modes.obj : modes.c .autodepend modes_svga.obj : modes_svga.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+modes_vesa.obj : modes_vesa.c .autodepend
+ $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+
scrsw.obj : scrsw.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
@@ -155,6 +164,9 @@ vxd_main_qemu.obj : vxd_main_qemu.c .autodepend vxd_main_svga.obj : vxd_main_svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_main_vesa.obj : vxd_main_vesa.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
vxd_mouse.obj : vxd_mouse.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
@@ -179,6 +191,9 @@ vxd_halloc.obj : vxd_halloc.c .autodepend vxd_vbe.obj : vxd_vbe.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_vesa.obj : vxd_vesa.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
vxd_vbe_qemu.obj : vxd_vbe_qemu.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
@@ -191,6 +206,9 @@ vxd_vdd_qemu.obj : vxd_vdd_qemu.c .autodepend vxd_vdd_svga.obj : vxd_vdd_svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_vdd_vesa.obj : vxd_vdd_vesa.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
wrc -q -r -ad -bt=windows -fo=$@ -Ires -I$(%WATCOM)/h/win $(FLAGS) res/boxvmini.rc
@@ -201,6 +219,9 @@ vmwsmini.res : res/vmwsmini.rc res/colortab.bin res/config.bin res/fonts.bin res qemumini.res : res/qemumini.rc res/colortab.bin res/config.bin res/fonts.bin res/fonts120.bin .autodepend
wrc -q -r -ad -bt=windows -fo=$@ -Ires -I$(%WATCOM)/h/win $(FLAGS) res/qemumini.rc
+vesamini.res : res/vesamini.rc res/colortab.bin res/config.bin res/fonts.bin res/fonts120.bin .autodepend
+ wrc -q -r -ad -bt=windows -fo=$@ -Ires -I$(%WATCOM)/h/win $(FLAGS) res/vesamini.rc
+
res/colortab.bin : res/colortab.c
wcc -q $(INCS) $<
wlink op quiet disable 1014, 1023 name $@ sys dos output raw file colortab.obj
@@ -429,6 +450,74 @@ import GlobalSmartPageLock KERNEL.230 <<
$(QEMUMINI_DRV_RC)
+vesamini.drv : $(OBJS) vesamini.res dibeng.lib $(FIXLINK_EXE)
+ wlink op quiet, start=DriverInit_ disable 2055 $(DBGFILE) @<<vesamini.lnk
+system windows dll initglobal
+file dibcall.obj
+file dibthunk.obj
+file dddrv.obj
+file drvlib.obj
+file enable.obj
+file init.obj
+file control.obj
+file palette.obj
+file sswhook.obj
+file scrsw.obj
+file pm16_calls_vesa.obj
+file modes_vesa.obj
+name vesamini.drv
+option map=vesamini.map
+library dibeng.lib
+library clibs.lib
+option modname=DISPLAY
+option description 'DISPLAY : 100, 96, 96 : DIB Engine based Mini display driver.'
+option oneautodata
+segment type data preload fixed
+segment '_TEXT' preload shared
+segment '_INIT' preload moveable
+export BitBlt.1
+export ColorInfo.2
+export Control.3
+export Disable.4
+export Enable.5
+export EnumDFonts.6
+export EnumObj.7
+export Output.8
+export Pixel.9
+export RealizeObject.10
+export StrBlt.11
+export ScanLR.12
+export DeviceMode.13
+export ExtTextOut.14
+export GetCharWidth.15
+export DeviceBitmap.16
+export FastBorder.17
+export SetAttribute.18
+export DibBlt.19
+export CreateDIBitmap.20
+export DibToDevice.21
+export SetPalette.22
+export GetPalette.23
+export SetPaletteTranslate.24
+export GetPaletteTranslate.25
+export UpdateColors.26
+export StretchBlt.27
+export StretchDIBits.28
+export SelectBitmap.29
+export BitmapBits.30
+export ReEnable.31
+export DDIGammaRamp.32
+export Inquire.101
+export SetCursor.102
+export MoveCursor.103
+export CheckCursor.104
+export GetDriverResourceID.450
+export UserRepaintDisable.500
+export ValidateMode.700
+import GlobalSmartPageLock KERNEL.230
+<<
+ $(VESAMINI_DRV_RC)
+
vmwsmini.vxd : $(OBJS) $(FIXLINK_EXE)
wlink op quiet $(DBGFILE32) @<<vmwsmini.lnk
system win_vxd dynamic
@@ -503,6 +592,28 @@ export VXD_DDB.1 <<
$(FIXLINK_EXE) -vxd32 $@
+vesamini.vxd : $(OBJS) $(FIXLINK_EXE)
+ wlink op quiet $(DBGFILE32) @<<vesamini.lnk
+system win_vxd dynamic
+option map=vesamini.map
+option nodefaultlibs
+name vesamini.vxd
+file vxd_main_vesa.obj
+file pci.obj
+file vxd_fbhda.obj
+file vxd_lib.obj
+file vxd_vesa.obj
+file vxd_vdd_vesa.obj
+file vxd_mouse.obj
+segment '_TEXT' PRELOAD NONDISCARDABLE
+segment '_DATA' PRELOAD NONDISCARDABLE
+segment 'CONST' PRELOAD NONDISCARDABLE
+segment 'CONST2' PRELOAD NONDISCARDABLE
+segment '_BSS' PRELOAD NONDISCARDABLE
+export VXD_DDB.1
+<<
+ $(FIXLINK_EXE) -vxd32 $@
+
# Cleanup
clean : .symbolic
rm *.obj
@@ -166,6 +166,13 @@ static int IsModeOK( WORD wXRes, WORD wYRes, WORD wBpp ) }
#endif
+#ifdef VESA
+ if(!VESA_validmode(wXRes, wYRes, wBpp))
+ {
+ return 0;
+ }
+#endif
+
return( 1 );
}
@@ -205,6 +212,13 @@ static int SetDisplayMode( WORD wXRes, WORD wYRes, int bFullSet ) }
#endif
+#ifdef VESA
+ if(!VESA_setmode(wXRes, wYRes, wBpp))
+ {
+ return 0;
+ }
+#endif
+
if( bFullSet ) {
wScreenX = hda->width;
wScreenY = hda->height;
@@ -263,6 +277,10 @@ int PhysicalEnable( void ) VBE_setmode(wScrX, wScrY, wBpp);
#endif
+#ifdef VESA
+ VESA_setmode(wScrX, wScrY, wBpp);
+#endif
+
/* Let the VDD know that the mode changed. */
CallVDD( VDD_POST_MODE_CHANGE );
CallVDD( VDD_SAVE_DRIVER_STATE );
@@ -303,6 +321,15 @@ UINT WINAPI __loadds ValidateMode( DISPVALMODE FAR *lpValMode ) }
#endif
+#ifdef VESA
+ /* Check if we have PCI VESA card */
+ if(!VESA_valid())
+ {
+ rc = VALMODE_NO_WRONGDRV;
+ break;
+ }
+#endif
+
if( !IsModeOK( lpValMode->dvmXRes, lpValMode->dvmYRes, lpValMode->dvmBpp ) ) {
rc = VALMODE_NO_NOMEM;
}
diff --git a/modes_vesa.c b/modes_vesa.c new file mode 100644 index 0000000..9d5f10f --- /dev/null +++ b/modes_vesa.c @@ -0,0 +1,2 @@ +#define VESA
+#include "modes.c"
diff --git a/pm16_calls.c b/pm16_calls.c index f9334b2..e801b13 100644 --- a/pm16_calls.c +++ b/pm16_calls.c @@ -693,3 +693,103 @@ BOOL VBE_validmode(DWORD w, DWORD h, DWORD bpp) }
#endif /* VBE */
+
+
+#ifdef VESA
+BOOL VESA_valid()
+{
+ static BOOL status;
+ status = FALSE;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_VESA_VALID
+ call dword ptr [VXD_VM]
+ mov [status], cx
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+BOOL VESA_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_VESA_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 VESA_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_VESA_VALIDMODE
+ mov ecx, [bpp]
+ mov esi, [w]
+ mov edi, [h]
+ call dword ptr [VXD_VM]
+ mov [status], cx
+
+ pop edi
+ pop esi
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+#endif /* VESA */
diff --git a/pm16_calls_vesa.c b/pm16_calls_vesa.c new file mode 100644 index 0000000..6616ccb --- /dev/null +++ b/pm16_calls_vesa.c @@ -0,0 +1,2 @@ +#define VESA
+#include "pm16_calls.c"
diff --git a/res/display.rcv b/res/display.rcv index 9dbdd80..fc36896 100644 --- a/res/display.rcv +++ b/res/display.rcv @@ -7,7 +7,7 @@ #define VER_FILESUBTYPE VFT2_DRV_DISPLAY
#define VER_FILEDESCRIPTION_STR "Windows 9x Display Minidriver"
#define VER_INTERNALNAME_STR "DISPLAY"
-#define VER_LEGALCOPYRIGHT_YEARS "2012-2024"
+#define VER_LEGALCOPYRIGHT_YEARS "2012-2025"
#define VER_LEGALCOPYRIGHT_STR "Copyright \251 The OS/2 Museum " VER_LEGALCOPYRIGHT_YEARS
#define VER_COMPANYNAME_STR "OS/2 Museum\0"
diff --git a/res/vesamini.rc b/res/vesamini.rc new file mode 100644 index 0000000..9b5ee63 --- /dev/null +++ b/res/vesamini.rc @@ -0,0 +1,19 @@ +/*
+ * Windows 9x minidriver resource file.
+ * Most of the contents is defined by backward compatibility
+ * requirements. Much of the detail is explained in the Windows 3.x
+ * and 2.x DDKs.
+ */
+
+#include "windows.h"
+
+#define VER_ORIGINALFILENAME_STR "vesamini.drv"
+
+#include "display.rcv"
+
+1 oembin PRELOAD config.bin
+2 oembin colortab.bin
+3 oembin PRELOAD fonts.bin
+fonts oembin fonts.bin
+
+2003 oembin PRELOAD fonts120.bin
@@ -0,0 +1,139 @@ +/*****************************************************************************
+
+Copyright (c) 2025 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 __VESA_H__INCLUDED__
+#define __VESA_H__INCLUDED__
+
+#include "types16.h"
+
+/* https://wiki.osdev.org/VESA_Video_Modes */
+
+#pragma pack(push)
+#pragma pack(1)
+
+/* VBE 3.0 specification, p.25 */
+
+typedef struct vesa_info_block
+{
+ uint8 VESASignature[4]; /* "VESA" 4 byte signature */
+ uint16 VESAVersion; /* VBE version number */
+ uint32 OEMStringPtr; /* Pointer to OEM string */
+ uint8 Capabilities[4]; /* Capabilities of video card */
+ uint32 VideoModePtr; /* Pointer to supported modes */
+ uint16 TotalMemory; /* Number of 64kb memory blocks */
+ uint16 OemSoftwareRev; /* VBE implementation Software revision */
+ uint32 OemVendorNamePtr; /* VbeFarPtr to Vendor Name String */
+ uint32 OemProductNamePtr; /* VbeFarPtr to Product Name String */
+ uint32 OemProductRevPtr; /* VbeFarPtr to Product Revision String */
+ uint8 Reserved[222]; /* Pad to 256 byte block size */
+ uint8 OemData[256]; /* Data Area for OEM Strings */
+} vesa_info_block_t;
+
+/* p.30 */
+
+typedef struct vesa_mode_info
+{
+ uint16 ModeAttributes; /* mode attributes */
+ uint8 WinAAttributes; /* window A attributes */
+ uint8 WinBAttributes; /* window B attributes */
+ uint16 WinGranularity; /* window granularity */
+ uint16 WinSize; /* window size */
+ uint16 WinASegment; /* window A start segment */
+ uint16 WinBSegment; /* window B start segment */
+ uint32 WinFuncPtr; /* real mode pointer to window function */
+ uint16 BytesPerScanLine; /* bytes per scan line (pitch) */
+ /* VBE 1.2 */
+ uint16 XResolution; /* horizontal resolution in pixels or characters (width) */
+ uint16 YResolution; /* vertical resolution in pixels or characters (height) */
+ uint8 XCharSize; /* character cell width in pixels */
+ uint8 YCharSize; /* character cell height in pixels */
+ uint8 NumberOfPlanes; /* number of memory planes */
+ uint8 BitsPerPixel; /* bits per pixel (bpp) */
+ uint8 NumberOfBanks; /* number of banks */
+ uint8 MemoryModel; /* memory model type */
+ uint8 BankSize; /* bank size in KB */
+ uint8 NumberOfImagePages; /* number of images */
+ uint8 Reserved0; /* reserved for page function */
+ /* Direct Color fields (required for direct/6 and YUV/7 memory models) */
+ uint8 RedMaskSize; /* size of direct color red mask in bits */
+ uint8 RedFieldPosition; /* bit position of lsb of red mask */
+ uint8 GreenMaskSize; /* size of direct color green mask in bits */
+ uint8 GreenFieldPosition; /* bit position of lsb of green mask */
+ uint8 BlueMaskSize; /* size of direct color blue mask in bits */
+ uint8 BlueFieldPosition; /* bit position of lsb of blue mask */
+ uint8 RsvdMaskSize; /* size of direct color reserved mask in bits */
+ uint8 RsvdFieldPosition; /* bit position of lsb of reserved mask */
+ uint8 DirectColorModeInfo; /* direct color mode attributes */
+ /* VBE 2.0 */
+ uint32 PhysBasePtr; /* physical address for flat memory frame buffer */
+ uint32 Reserved1; /* Reserved - always set to 0 */
+ uint16 Reserved2; /* Reserved - always set to 0 */
+ /* VBE 3.0 */
+ uint16 LinBytesPerScanLine; /* bytes per scan line for linear modes */
+ uint8 BnkNumberOfImagePages; /* number of images for banked modes */
+ uint8 LinNumberOfImagePages; /* number of images for linear modes */
+ uint8 LinRedMaskSize; /* size of direct color red mask (linear modes) */
+ uint8 LinRedFieldPosition; /* bit position of lsb of red mask (linear modes) */
+ uint8 LinGreenMaskSize; /* size of direct color green mask (linear modes) */
+ uint8 LinGreenFieldPosition; /* bit position of lsb of green mask (linear modes) */
+ uint8 LinBlueMaskSize; /* size of direct color blue mask (linear modes) */
+ uint8 LinBlueFieldPosition; /* bit position of lsb of blue mask (linear modes) */
+ uint8 LinRsvdMaskSize; /* size of direct color reserved mask (linear modes) */
+ uint8 LinRsvdFieldPosition; /* bit position of lsb of reserved mask (linear modes) */
+ uint32 MaxPixelClock; /* maximum pixel clock (in Hz) for graphics mode */
+ uint8 Reserved3[189]; /* remainder of ModeInfoBlock */
+} vesa_mode_info_t;
+
+#define VESA_MODE_HW_SUPPORTED 0x0001
+#define VESA_MODE_TTY_OUTPUT 0x0004
+#define VESA_MODE_COLOR 0x0008
+#define VESA_MODE_GRAPHICS 0x0010
+#define VESA_MODE_VGA_COMPACT 0x0020
+#define VESA_MODE_WINDOWED 0x0040
+#define VESA_MODE_LINEAR_FRAMEBUFFER 0x0080
+#define VESA_MODE_DOUBLE_SCAN 0x0100
+#define VESA_MODE_INTERLACED 0x0200
+#define VESA_MODE_TRIPLE_BUFFERING 0x0400
+#define VESA_MODE_STEREOSCOPIC 0x0800
+#define VESA_MODE_DUAL_DISPLAY 0x1000
+
+/* p.41 */
+
+typedef struct vesa_crtc_info
+{
+ uint16 HorizontalTotal; /* Horizontal total in pixels */
+ uint16 HorizontalSyncStart; /* Horizontal sync start in pixels */
+ uint16 HorizontalSyncEnd; /* Horizontal sync end in pixels */
+ uint16 VerticalTotal; /* Vertical total in lines */
+ uint16 VerticalSyncStart; /* Vertical sync start in lines */
+ uint16 VerticalSyncEnd; /* Vertical sync end in lines */
+ uint8 Flags; /* Flags (Interlaced, Double Scan etc) */
+ uint32 PixelClock; /* Pixel clock in units of Hz */
+ uint16 RefreshRate; /* Refresh rate in units of 0.01 Hz */
+ uint8 Reserved[40]; /* remainder of ModeInfoBlock */
+} vesa_crtc_info_t;
+
+#pragma pack(pop)
+
+#endif /* __VESA_H__INCLUDED__ */
diff --git a/vmdisp9x.inf b/vmdisp9x.inf index a93be20..3b71412 100644 --- a/vmdisp9x.inf +++ b/vmdisp9x.inf @@ -19,6 +19,8 @@ VBox.Copy=11 VMSvga.Copy=11
DX.Copy=11
Voodoo.Copy=11
+VESA.Copy=11
+Qemu.Copy=11
[SourceDisksNames]
; BOXV9X is the driver disk volume label
@@ -33,6 +35,8 @@ qemumini.drv=1 qemumini.vxd=1
qxlmini.drv=1
qxlmini.vxd=1
+vesamini.drv=1
+vesamini.vxd=1
;mesa:mesa3d.dll=1
;mesa:vmwsgl32.dll=1
;openglide:glide2x.dll=1
@@ -60,6 +64,7 @@ qxlmini.vxd=1 ;svga3:%VBoxVideoVM3.DeviceDesc%=VMSvga, PCI\VEN_15AD&DEV_0406&SUBSYS_040615AD
%QemuStd.DeviceDesc%=Qemu, PCI\VEN_1234&DEV_1111
;qxl;%QemuQXL.DeviceDesc%=QXL, PCI\VEN_1B36&DEV_0100
+%VESAVideo.DeviceDesc%=VESA, *PNP0900
[VBox]
CopyFiles=VBox.Copy,Dx.Copy,Voodoo.Copy
@@ -86,6 +91,11 @@ CopyFiles=VMSvga.Copy,Dx.Copy,Voodoo.Copy DelReg=VM.DelReg
AddReg=VMSvga.AddReg,VM.AddReg,DX.addReg,VM.regextra
+[VESA]
+CopyFiles=VESA.Copy,Dx.Copy,Voodoo.Copy
+DelReg=VM.DelReg
+AddReg=VESA.AddReg,VM.AddReg,DX.addReg,VM.regextra
+
[VBox.Copy]
boxvmini.drv,,,0x00000004
boxvmini.vxd,,,0x00000004
@@ -115,6 +125,13 @@ vmwsmini.vxd,,,0x00000004 ;vmhal:vmhal9x.dll,,,0x00000004
;vmhal:vmdisp9x.dll,,,0x00000004
+[VESA.Copy]
+vesamini.drv,,,0x00000004
+vesamini.vxd,,,0x00000004
+;mesa:mesa3d.dll,,,0x00000004
+;vmhal:vmhal9x.dll,,,0x00000004
+;vmhal:vmdisp9x.dll,,,0x00000004
+
[Voodoo.Copy]
;3dfx:3dfxspl2.dll,,,0x00000010
;3dfx:3dfxspl3.dll,,,0x00000010
@@ -151,6 +168,11 @@ HKR,DEFAULT,drv,,vmwsmini.drv HKR,DEFAULT,minivdd,,vmwsmini.vxd
HKR,DEFAULT,Mode,,"32,640,480"
+[VESA.AddReg]
+HKR,DEFAULT,drv,,vesamini.drv
+HKR,DEFAULT,minivdd,,vesamini.vxd
+HKR,DEFAULT,Mode,,"16,640,480"
+
[VM.DelReg]
HKR,,Ver
HKR,,DevLoader
@@ -384,6 +406,7 @@ VBoxVideoVM2.DeviceDesc="VMWare SVGA-II PCI Adapter" VBoxVideoVM3.DeviceDesc="VMWare SVGA-III PCI Adapter"
QemuStd.DeviceDesc="QEMU STD VGA PCI Adapter"
QemuQXL.DeviceDesc="QEMU QXL VGA PCI Adapter"
+VESAVideo.DeviceDesc="VESA PCI Adapter"
[VM.regextra]
;swvoodoo:HKLM,Software\vmdisp9x\driver,OVERLAY_1_SIZE,,8
@@ -17,6 +17,9 @@ #elif defined(QEMU)
#define VXD_DEVICE_ID VXD_DEVICE_VMDISP9X_ID
#define VXD_DEVICE_NAME "QEMUVXD"
+#elif defined(VESA)
+#define VXD_DEVICE_ID VXD_DEVICE_VMDISP9X_ID
+#define VXD_DEVICE_NAME "VESAVXD"
#else
#define VXD_DEVICE_ID VXD_DEVICE_VMDISP9X_ID
#define VXD_DEVICE_NAME "BOXVVXD"
@@ -85,6 +85,23 @@ void *memcpy(void *dst, const void *src, unsigned int size) return dst;
}
+int memcmp(const void *ptr1, const void *ptr2, unsigned int num)
+{
+ const unsigned char *p1 = (const unsigned char *)ptr1;
+ const unsigned char *p2 = (const unsigned char *)ptr2;
+
+ if(num == 0) return 0;
+
+ while(num > 1 && *p1 == *p2)
+ {
+ p1++;
+ p2++;
+ num--;
+ }
+
+ return *p1 - *p2;
+}
+
unsigned int strlen(const char *s)
{
const char *ptr = s;
@@ -519,6 +536,36 @@ DWORD __declspec(naked) __cdecl _PageCommitContig(ULONG page, ULONG npages, ULON VMMJmp(_PageCommitContig);
}
+DWORD __declspec(naked) __cdecl _LinMapIntoV86(ULONG HLinPgNum, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG flags)
+{
+ VMMJmp(_LinMapIntoV86);
+}
+
+DWORD __declspec(naked) __cdecl _MapIntoV86(ULONG hMem, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG PageOff, ULONG flags)
+{
+ VMMJmp(_MapIntoV86);
+}
+
+DWORD __declspec(naked) __cdecl _GetFirstV86Page()
+{
+ VMMJmp(_GetFirstV86Page);
+}
+
+DWORD __declspec(naked) __cdecl _GetLastV86Page()
+{
+ VMMJmp(_GetLastV86Page);
+}
+
+DWORD __declspec(naked) __cdecl _SetLastV86Page(ULONG PgNum, ULONG flags)
+{
+ VMMJmp(_SetLastV86Page);
+}
+
+DWORD __declspec(naked) __cdecl _Allocate_Global_V86_Data_Area(ULONG nBytes, ULONG flags)
+{
+ VMMJmp(_Allocate_Global_V86_Data_Area);
+}
+
void Enable_Global_Trapping(DWORD port)
{
_asm push edx
@@ -26,6 +26,7 @@ THE SOFTWARE. void memset(void *dst, int c, unsigned int size);
void *memcpy(void *dst, const void *src, unsigned int size);
+int memcmp(const void *ptr1, const void *ptr2, unsigned int num);
unsigned int strlen(const char *s);
char *strcpy(char *dst, const char *src);
char *strcat(char *dst, const char *src);
@@ -60,6 +61,12 @@ 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 _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);
+DWORD __cdecl _GetFirstV86Page();
+DWORD __cdecl _GetLastV86Page();
+DWORD __cdecl _SetLastV86Page(ULONG PgNum, ULONG flags);
void __cdecl Resume_VM(ULONG VM);
void Release_Time_Slice();
@@ -165,7 +165,7 @@ void __declspec(naked) Device_IO_Control_entry() void __stdcall print_ctrl(DWORD type)
{
- dbg_printf("VXD_control: %d\n", type);
+ dbg_printf("VXD_control: %lX\n", type);
}
/*
@@ -179,6 +179,16 @@ void __declspec(naked) VXD_control() // eax = 0x1B - dynamic init
// eax = 0x1C - dynamic exit
// eax = 0x23 - device IO control
+
+#if 0
+ _asm
+ {
+ pushad
+ push eax
+ call print_ctrl
+ popad
+ }
+#endif
_asm {
cmp eax,Sys_Critical_Init
@@ -416,6 +426,35 @@ WORD __stdcall VXD_API_Proc(PCRS_32 state) }
#endif
+#ifdef VESA
+ case OP_VESA_VALID:
+ {
+ BOOL rs;
+ rs = VESA_valid();
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_VESA_SETMODE:
+ {
+ BOOL rs;
+ Begin_Critical_Section(0);
+ rs = VESA_setmode(state->Client_ESI, state->Client_EDI, state->Client_ECX);
+ End_Critical_Section();
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+ case OP_VESA_VALIDMODE:
+ {
+ BOOL rs;
+ rs = VESA_validmode(state->Client_ESI, state->Client_EDI, state->Client_ECX);
+ state->Client_ECX = (DWORD)rs;
+ rc = 1;
+ break;
+ }
+#endif
+
}
if(rc == 0xFFFF)
@@ -563,6 +602,10 @@ void Device_Init_proc(DWORD VM) VBE_init_hw();
#endif
+#ifdef VESA
+ VESA_init_hw();
+#endif
+
#if defined(QEMU)
Install_IO_Handler(0x1ce, (DWORD)virtual_0x1ce);
Disable_Global_Trapping(0x1ce);
@@ -594,6 +637,7 @@ void Device_Init_proc(DWORD VM) vxd_hstats_update();
#endif
End_Critical_Section();
+ dbg_printf("Device_Init_proc DONE\n");
}
#undef VDDFUNC
#undef VDDNAKED
diff --git a/vxd_main_vesa.c b/vxd_main_vesa.c new file mode 100644 index 0000000..669fa33 --- /dev/null +++ b/vxd_main_vesa.c @@ -0,0 +1,2 @@ +#define VESA
+#include "vxd_main.c"
@@ -150,10 +150,11 @@ BOOL VBE_init_hw() hda->vram_size = vram_size;
hda->vram_bar_size = vram_size;
- FBHDA_memtest();
hda->vram_pm32 = (void*)_MapPhysToLinear(vram_phy, vram_size, 0);
hda->flags |= FB_SUPPORT_FLIPING;
+
+ FBHDA_memtest();
memcpy(hda->vxdname, vbe_vxd_name, sizeof(vbe_vxd_name));
@@ -231,6 +231,20 @@ VDDPROC(GET_CHIP_ID, get_chip_id) }
#endif
+#ifdef VESA
+ if(VESA_valid())
+ {
+ state->Client_EAX = 0x1234;
+ VDD_CY;
+ }
+ else
+ {
+ state->Client_EAX = 0;
+ VDD_NC;
+ }
+#endif
+
+
}
/**
diff --git a/vxd_vdd_vesa.c b/vxd_vdd_vesa.c new file mode 100644 index 0000000..f14a5bd --- /dev/null +++ b/vxd_vdd_vesa.c @@ -0,0 +1,2 @@ +#define VESA
+#include "vxd_vdd.c"
diff --git a/vxd_vesa.c b/vxd_vesa.c new file mode 100644 index 0000000..001406c --- /dev/null +++ b/vxd_vesa.c @@ -0,0 +1,391 @@ +/**************************************************************************
+
+Copyright (c) 2025 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 VESA
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+
+#include "vxd_lib.h"
+#include "3d_accel.h"
+
+#include "boxvint.h"
+
+#include "pci.h" /* re-use PCI functions from SVGA */
+#include "vesa.h"
+
+#include "code32.h"
+
+#define ISA_LFB 0xE0000000UL
+
+extern FBHDA_t *hda;
+extern LONG fb_lock_cnt;
+extern DWORD ThisVM;
+
+static char vesa_vxd_name[] = "vesamini.vxd";
+
+typedef struct vesa_mode
+{
+ DWORD width;
+ DWORD height;
+ DWORD bpp;
+ DWORD pitch;
+ DWORD phy;
+ WORD mode_id;
+} vesa_mode_t;
+
+vesa_mode_t *vesa_modes = NULL;
+DWORD vesa_modes_cnt = 0;
+
+#include "vxd_strings.h"
+
+void vesa_bios(CRS_32 *V86regs)
+{
+ // sizeof(CRS_32) = 108
+ _asm mov ebx, [ThisVM]
+ _asm mov ecx, [V86regs]
+ /* save state */
+ _asm sub esp, 108
+ _asm mov edi, esp
+ VMMCall(Save_Client_State);
+ /* switch to V86regs */
+ _asm mov esi, ecx
+ VMMCall(Restore_Client_State)
+ /* V86 INT */
+ VMMCall(Begin_Nest_V86_Exec);
+ _asm mov eax, 10h
+ VMMCall(Exec_Int);
+ VMMCall(End_Nest_Exec);
+ /* copy result state to V86regs */
+ _asm mov edi, ecx
+ VMMCall(Save_Client_State);
+ /* restore state regs */
+ _asm mov esi, esp
+ VMMCall(Restore_Client_State)
+ _asm add esp, 108
+}
+
+void load_client_state(CRS_32 *V86regs)
+{
+ _asm mov edi, [V86regs]
+ VMMCall(Save_Client_State);
+}
+
+DWORD vesa_buf_flat = 0;
+DWORD vesa_buf_v86;
+void *vesa_buf;
+
+#define MODE_OFFSET 1024
+#define CRTC_OFFSET 2048
+
+#define V86_SEG(_lin) ((_lin) >> 4)
+#define V86_OFF(_lin) ((_lin) & 0xF)
+
+#define LIN_FROM_V86(_flatptr) ((((_flatptr) >> 12) & 0xFFFF0UL) + ((_flatptr) & 0xFFFFUL))
+
+static BOOL vesa_valid = FALSE;
+
+static void alloc_modes_info(DWORD cnt)
+{
+ DWORD vesa_modes_pages = ((sizeof(vesa_mode_t) * cnt) + P_SIZE - 1) / P_SIZE;
+ vesa_modes = (vesa_mode_t*)_PageAllocate(vesa_modes_pages, PG_SYS, 0, 0x0, 0, 0x100000, NULL, PAGEZEROINIT);
+ dbg_printf("vesa_modes = %lX\n", vesa_modes);
+ vesa_modes_cnt = 0;
+}
+
+BOOL VESA_init_hw()
+{
+ DWORD phy;
+ DWORD flat;
+ dbg_printf("VESA init begin...\n");
+
+ flat = _PageAllocate(1, PG_SYS, 0, 0x0, 0, 0x100000, &phy, PAGEUSEALIGN | PAGECONTIG | PAGEFIXED);
+ vesa_buf = (void*)flat;
+
+ if(vesa_buf)
+ {
+ DWORD modes_count = 0;
+#if 0
+ /* JH: bad idea, memory must upper 640k! */
+ DWORD lp = _GetLastV86Page();
+ DWORD v86_page = lp+1;
+
+ _SetLastV86Page(v86_page, 0);
+ if(_PhysIntoV86(phy >> 12, ThisVM, v86_page, 1, 0))
+ {
+ vesa_buf_v86 = v86_page*4096;
+ }
+
+ dbg_printf("last page was=%lX\n", lp);
+ dbg_printf("VESA V86 addr=0x%lX, phy=0x%lX\n", vesa_buf_v86, phy);
+#else
+ /* FIXME: check if pages is free! */
+ DWORD v86_page = 0xB0;
+ if(_PhysIntoV86(phy >> 12, ThisVM, v86_page, 1, 0))
+ {
+ vesa_buf_v86 = v86_page*4096;
+ }
+ dbg_printf("VESA V86 addr=0x%lX, phy=0x%lX\n", vesa_buf_v86, phy);
+#endif
+
+ if(vesa_buf_v86)
+ {
+ DWORD i;
+ DWORD fb_phy = 0xFFFFFFFFF;
+ CRS_32 regs;
+ vesa_info_block_t *info = vesa_buf;
+ vesa_mode_info_t *modeinfo = (vesa_mode_info_t*)((char*)vesa_buf + MODE_OFFSET);
+
+ memset(info, 0, sizeof(vesa_info_block_t));
+ memset(modeinfo, 0, sizeof(vesa_mode_info_t));
+ memcpy(&info->VESASignature[0], "VBE2", 4);
+
+ load_client_state(®s);
+ regs.Client_EAX = 0x4f00;
+ regs.Client_ES = V86_SEG(vesa_buf_v86);
+ regs.Client_EDI = V86_OFF(vesa_buf_v86);
+
+ vesa_bios(®s);
+
+ if((regs.Client_EAX & 0xFFFF) == 0x004F &&
+ memcmp(info->VESASignature, "VESA", 4) == 0)
+ {
+ WORD *modes = NULL;
+
+ dbg_printf("VESA bios result=%X, vesa_version=%X, modes_ptr=%lX\n",
+ regs.Client_EAX & 0xFFFF, info->VESAVersion, info->VideoModePtr);
+
+ modes = (WORD*)LIN_FROM_V86(info->VideoModePtr);
+ if(modes != NULL)
+ {
+ while(*modes != 0xFFFF)
+ {
+ //dbg_printf("modes: 0x%04X\n", *modes);
+ modes++;
+ modes_count++;
+ }
+ }
+
+ alloc_modes_info(modes_count);
+ modes = (WORD*)LIN_FROM_V86(info->VideoModePtr);
+
+ for(i = 0; i < modes_count; i++)
+ {
+ regs.Client_EAX = 0x4F01;
+ regs.Client_ECX = modes[i];
+ regs.Client_ES = V86_SEG(vesa_buf_v86+MODE_OFFSET);
+ regs.Client_EDI = V86_OFF(vesa_buf_v86+MODE_OFFSET);
+
+ vesa_bios(®s);
+
+ //dbg_printf("mode=%X atrs=0x%lX eax=0x%lX\n", modes[i], modeinfo->ModeAttributes, regs.Client_EAX);
+ if((regs.Client_EAX & 0xFFFF) == 0x004F)
+ {
+ if(modeinfo->ModeAttributes &
+ (VESA_MODE_HW_SUPPORTED | VESA_MODE_COLOR | VESA_MODE_GRAPHICS | VESA_MODE_LINEAR_FRAMEBUFFER))
+ {
+ vesa_mode_t *m = &vesa_modes[vesa_modes_cnt];
+ m->width = modeinfo->XResolution;
+ m->height = modeinfo->YResolution;
+ m->bpp = modeinfo->BitsPerPixel;
+ m->pitch = modeinfo->BytesPerScanLine;
+ m->phy = modeinfo->PhysBasePtr;
+ m->mode_id = modes[i];
+ vesa_modes_cnt++;
+
+ if(m->phy)
+ {
+ if(m->phy < fb_phy)
+ {
+ fb_phy = m->phy;
+ }
+ }
+
+ dbg_printf("Mode 0x%X = (%ld x %ld x %ld) = phy:%lX\n",
+ m->mode_id, m->width, m->height, m->bpp, m->phy);
+ }
+ }
+ } // for
+
+ if(vesa_modes_cnt == 0)
+ {
+ return FALSE;
+ }
+
+ if(!FBHDA_init_hw())
+ {
+ return FALSE;
+ }
+
+ memcpy(hda->vxdname, vesa_vxd_name, sizeof(vesa_vxd_name));
+ hda->vram_size = info->TotalMemory * 0x10000UL;
+ //hda->vram_size = 16*1024*1024;
+ hda->vram_bar_size = hda->vram_size;
+
+ hda->vram_pm32 = (void*)_MapPhysToLinear(fb_phy, hda->vram_size, 0);
+ //hda->vram_pm32 = (void*)_MapPhysToLinear(ISA_LFB, hda->vram_size, 0);
+
+ hda->flags |= FB_SUPPORT_FLIPING;
+
+ vesa_valid = TRUE;
+
+ dbg_printf("VESA_init_hw(vram_size=%ld) = TRUE\n", hda->vram_size);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+BOOL VESA_valid()
+{
+ dbg_printf("VESA_valid()\n");
+ return vesa_valid;
+}
+
+BOOL VESA_validmode(DWORD w, DWORD h, DWORD bpp)
+{
+ DWORD i;
+ dbg_printf("VESA_validmode()\n");
+
+ for(i = 0; i < vesa_modes_cnt; i++)
+ {
+ if(vesa_modes[i].width == w && vesa_modes[i].height == h && vesa_modes[i].bpp == bpp)
+ {
+ return TRUE;
+ }
+ }
+
+ dbg_printf("fail to valid mode: %ld %ld %ld\n", w, h, bpp);
+ return FALSE;
+}
+
+void VESA_clear()
+{
+ memset(hda->vram_pm32, 0, hda->pitch*hda->height);
+}
+
+BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp)
+{
+ DWORD i;
+ dbg_printf("VESA_validmode()\n");
+ //if(!VESA_validmode(w, h, bpp)) return FALSE;
+
+ for(i = 0; i < vesa_modes_cnt; i++)
+ {
+ if(vesa_modes[i].width == w && vesa_modes[i].height == h && vesa_modes[i].bpp == bpp)
+ {
+ CRS_32 regs;
+ load_client_state(®s);
+ // set mode
+ regs.Client_EAX = 0x4f02;
+ regs.Client_EBX = vesa_modes[i].mode_id | (1 << 14);
+ regs.Client_ES = 0;
+ regs.Client_EDI = 0;
+ vesa_bios(®s);
+
+ if((regs.Client_EAX & 0xFFFF) == 0x004F)
+ {
+ dbg_printf("SET success: %d %d %d\n", w, h, bpp);
+ hda->width = w;
+ hda->height = h;
+ hda->bpp = bpp;
+ hda->pitch = vesa_modes[i].pitch;
+ hda->stride = h * hda->pitch;
+ hda->surface = 0;
+
+ VESA_clear();
+ mouse_invalidate();
+ FBHDA_update_heap_size(FALSE);
+
+ return TRUE;
+ }
+ else
+ {
+ dbg_printf("vbios fail: eax=0x%lX\n", regs.Client_EAX);
+ }
+ }
+ } // for
+
+ dbg_printf("fail to set %ld %ld %ld\n", w, h, bpp);
+ return FALSE;
+}
+
+void FBHDA_palette_set(unsigned char index, DWORD rgb)
+{
+
+}
+
+DWORD FBHDA_palette_get(unsigned char index)
+{
+ return 0;
+}
+
+BOOL FBHDA_swap(DWORD offset)
+{
+ return TRUE;
+}
+
+void FBHDA_access_begin(DWORD flags)
+{
+ //Wait_Semaphore(hda_sem, 0);
+ if(fb_lock_cnt++ == 0)
+ {
+ mouse_erase();
+ }
+}
+
+void FBHDA_access_rect(DWORD left, DWORD top, DWORD right, DWORD bottom)
+{
+ FBHDA_access_begin(0);
+}
+
+void FBHDA_access_end(DWORD flags)
+{
+ fb_lock_cnt--;
+ if(fb_lock_cnt < 0) fb_lock_cnt = 0;
+
+ if(fb_lock_cnt == 0)
+ {
+ mouse_blit();
+ // cursor
+ }
+
+ //Signal_Semaphore(hda_sem);
+}
+
+DWORD FBHDA_overlay_setup(DWORD overlay, DWORD width, DWORD height, DWORD bpp)
+{
+ return 0;
+}
+
+void FBHDA_overlay_lock(DWORD left, DWORD top, DWORD right, DWORD bottom)
+{
+
+}
+
+void FBHDA_overlay_unlock(DWORD flags)
+{
+
+}
|