diff options
author | Jaroslav Hensl <jara@hensl.cz> | 2025-07-13 00:20:18 +0200 |
---|---|---|
committer | Jaroslav Hensl <jara@hensl.cz> | 2025-07-13 00:20:18 +0200 |
commit | 3d70cb97ac6195d7af643addc50ba2d2c06da549 (patch) | |
tree | a34fb91d3bf19c99d8d7b5968a03600c6fc60c08 | |
parent | e059722c721125a5d10e0fafb6f9b0e378e86302 (diff) | |
download | vmdisp9x-main.tar.gz |
-rw-r--r-- | 3d_accel.h | 23 | ||||
-rw-r--r-- | makefile | 2 | ||||
-rw-r--r-- | modes.c | 4 | ||||
-rw-r--r-- | pm16_calls.c | 12 | ||||
-rw-r--r-- | vesa.h | 68 | ||||
-rw-r--r-- | vmdisp9x.inf | 8 | ||||
-rw-r--r-- | vxd_main.c | 14 | ||||
-rw-r--r-- | vxd_vdd.c | 6 | ||||
-rw-r--r-- | vxd_vdd_list.h | 4 | ||||
-rw-r--r-- | vxd_vesa.c | 349 |
10 files changed, 422 insertions, 68 deletions
@@ -167,6 +167,15 @@ typedef struct FBHDA DWORD res3;
} FBHDA_t;
+typedef struct FBHDA_mode
+{
+ DWORD cb;
+ DWORD width;
+ DWORD height;
+ DWORD bpp;
+ DWORD refresh;
+} FBHDA_mode_t;
+
#define FB_VRAM_HEAP_GRANULARITY (4*32)
/* minimum of vram allocation (32px at 32bpp, or 64px at 16bpp) */
@@ -182,6 +191,10 @@ typedef struct FBHDA #define FB_ACCEL_VMSVGA10_ST 512 /* not used */
#define FB_BUG_VMWARE_UPDATE 1024
#define FB_ACCEL_GPUMEM 2048
+#define FB_VESA_MODES 8192
+#define FB_SUPPORT_VSYNC 16384
+#define FB_SUPPORT_CLOCK 32768
+#define FB_SUPPORT_TRIPLE 65536
/* for internal use in RING-0 by VXD only */
BOOL FBHDA_init_hw();
@@ -201,10 +214,15 @@ void FBHDA_free(); #define FBHDA_ACCESS_MOUSE_MOVE 2
#define FBHDA_ACCESS_SURFACE_DIRTY 4
+#define FBHDA_SWAP_NOWAIT 1
+#define FBHDA_SWAP_WAIT 2
+#define FBHDA_SWAP_SCHEDULE 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);
void FBHDA_clean();
void FBHDA_palette_set(unsigned char index, DWORD rgb);
DWORD FBHDA_palette_get(unsigned char index);
@@ -239,6 +257,9 @@ void mouse_erase(); /* helper for some hacks */
BOOL FBHDA_page_modify(DWORD flat_address, DWORD size, const BYTE *new_data);
+/* query resulitions + refresh rate */
+BOOL FBHDA_mode_query(DWORD index, FBHDA_mode_t *mode);
+
/*
* VMWare SVGA-II API
*/
@@ -424,7 +445,7 @@ void VESA_HW_enable(); void VESA_HW_disable();
BOOL VESA_valid();
BOOL VESA_validmode(DWORD w, DWORD h, DWORD bpp);
-BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp);
+BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp, DWORD rr_min, DWORD rr_max);
#endif
@@ -14,7 +14,7 @@ OBJS += & INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 110
+VER_BUILD = 111
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
@@ -213,7 +213,7 @@ static int SetDisplayMode( WORD wXRes, WORD wYRes, int bFullSet ) #endif
#ifdef VESA
- if(!VESA_setmode(wXRes, wYRes, wBpp))
+ if(!VESA_setmode(wXRes, wYRes, wBpp, 0, 0))
{
return 0;
}
@@ -278,7 +278,7 @@ int PhysicalEnable( void ) #endif
#ifdef VESA
- VESA_setmode(wScrX, wScrY, wBpp);
+ VESA_setmode(wScrX, wScrY, wBpp, 0, 0);
#endif
/* Let the VDD know that the mode changed. */
diff --git a/pm16_calls.c b/pm16_calls.c index e801b13..83987d1 100644 --- a/pm16_calls.c +++ b/pm16_calls.c @@ -720,15 +720,15 @@ BOOL VESA_valid() return status == 0 ? FALSE : TRUE;
}
-BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp)
+BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp, DWORD rr_min, DWORD rr_max)
{
static BOOL status;
- static DWORD sw, sh, sbpp;
+ static DWORD s_wh, s_rr, sbpp;
status = FALSE;
- sw = w;
- sh = h;
+ s_wh = (w << 16) | h;
sbpp = bpp;
+ s_rr = (rr_min << 16) | rr_max;
_asm
{
@@ -741,8 +741,8 @@ BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp) mov edx, OP_VESA_SETMODE
mov ecx, [bpp]
- mov esi, [w]
- mov edi, [h]
+ mov esi, [s_wh]
+ mov edi, [s_rr]
call dword ptr [VXD_VM]
mov [status], cx
@@ -32,6 +32,17 @@ THE SOFTWARE. #pragma pack(push)
#pragma pack(1)
+#define VESA_CMD_ADAPTER_INFO 0x4F00
+#define VESA_CMD_MODE_INFO 0x4F01
+#define VESA_CMD_MODE_SET 0x4F02
+#define VESA_CMD_MODE_GET 0x4F03
+#define VESA_CMD_STATE 0x4F04
+#define VESA_CMD_WINDOWS_CTRL 0x4F05
+#define VESA_CMD_SCANLINE 0x4F06
+#define VESA_CMD_DISPLAY_START 0x4F07
+#define VESA_CMD_PALETTE_FORMAT 0x4F08
+#define VESA_CMD_PALETTE_DATA 0x4F09
+
/* VBE 3.0 specification, p.25 */
typedef struct vesa_info_block
@@ -39,7 +50,7 @@ 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 Capabilities; /* Capabilities of video card */
uint32 VideoModePtr; /* Pointer to supported modes */
uint16 TotalMemory; /* Number of 64kb memory blocks */
uint16 OemSoftwareRev; /* VBE implementation Software revision */
@@ -50,6 +61,16 @@ typedef struct vesa_info_block uint8 OemData[256]; /* Data Area for OEM Strings */
} vesa_info_block_t;
+#define VESA_VBE_1_2 0x0102
+#define VESA_VBE_2_0 0x0200
+#define VESA_VBE_3_0 0x0300
+
+#define VESA_CAP_DAC8BIT 0x01
+#define VESA_CAP_NONVGA 0x02
+#define VESA_CAP_RAMDAC_SLOW 0x04
+#define VESA_CAP_STEREO 0x08
+#define VESA_CAP_STEREO_EVC 0x10
+
/* p.30 */
typedef struct vesa_mode_info
@@ -111,7 +132,7 @@ typedef struct vesa_mode_info #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_LFB 0x0080
#define VESA_MODE_DOUBLE_SCAN 0x0100
#define VESA_MODE_INTERLACED 0x0200
#define VESA_MODE_TRIPLE_BUFFERING 0x0400
@@ -134,6 +155,49 @@ typedef struct vesa_crtc_info uint8 Reserved[40]; /* remainder of ModeInfoBlock */
} vesa_crtc_info_t;
+#define VESA_SETMODE_CRTC 0x0800
+#define VESA_SETMODE_LFB 0x4000
+#define VESA_SETMODE_CLEAR 0x8000
+
+#define VESA_DISPLAYSTART_SET 0x00
+#define VESA_DISPLAYSTART_GET 0x01
+#define VESA_DISPLAYSTART_SCHEDULE_ALT 0x02
+#define VESA_DISPLAYSTART_SCHEDULE STEREO 0x03
+#define VESA_DISPLAYSTART_SCHEDULED_STATUS 0x04
+#define VESA_DISPLAYSTART_STEREO_ON 0x05
+#define VESA_DISPLAYSTART_STEREO_OFF 0x06
+#define VESA_DISPLAYSTART_VTRACE 0x80
+#define VESA_DISPLAYSTART_VTRACE_ALT 0x82
+#define VESA_DISPLAYSTART_VTRACE_STEREO 0x82
+
+#define VESA_DAC_SETFORMAT 0x00
+#define VESA_DAC_GETFORMAT 0x01
+
+#define VESA_DAC_SET_8BIT (8 << 8)
+#define VESA_DAC_SET_6BIT (6 << 8)
+
+#define VESA_RAMDAC_DATA_SET 0x00
+#define VESA_RAMDAC_DATA_GET 0x01
+#define VESA_RAMDAC_DATA_SET_SECONDARY 0x02
+#define VESA_RAMDAC_DATA_GET_SECONDARY 0x03
+#define VESA_RAMDAC_DATA_SET_VSYNC 0x80
+
+/* p.55 */
+
+typedef struct vesa_palette_entry
+{
+ BYTE Blue;
+ BYTE Green;
+ BYTE Red;
+ BYTE Alignment;
+} vesa_palette_entry_t;
+
+/* in WORDs */
+#define VESA_PMTABLE_OFF_WINDOWS_CTRL 0
+#define VESA_PMTABLE_OFF_DISPLAY_START 1
+#define VESA_PMTABLE_OFF_PALETTE_DATA 2
+#define VESA_PMTABLE_OFF_PORTS 3
+
#pragma pack(pop)
#endif /* __VESA_H__INCLUDED__ */
diff --git a/vmdisp9x.inf b/vmdisp9x.inf index 3b71412..5387807 100644 --- a/vmdisp9x.inf +++ b/vmdisp9x.inf @@ -64,7 +64,8 @@ vesamini.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
+%VESAPCI.DeviceDesc%=VESA, PCI\CC_0300
+%VESAISA.DeviceDesc%=VESA, *PNP0900
[VBox]
CopyFiles=VBox.Copy,Dx.Copy,Voodoo.Copy
@@ -189,7 +190,7 @@ HKLM,Software\vmdisp9x\svga HKR,,Ver,,4.0
HKR,,DevLoader,,*vdd
HKR,DEFAULT,vdd,,"*vdd"
-HKR,DEFAULT,carddvdd,,cardsamp.vxd
+;HKR,DEFAULT,carddvdd,,cardsamp.vxd
HKR,DEFAULT,RefreshRate,,-1
HKR,DEFAULT,DDC,,1
HKR,DEFAULT,ExtModeSwitch,,0
@@ -406,7 +407,8 @@ 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"
+VESAPCI.DeviceDesc="VESA PCI Adapter"
+VESAISA.DeviceDesc="VESA ISA Adapter"
[VM.regextra]
;swvoodoo:HKLM,Software\vmdisp9x\driver,OVERLAY_1_SIZE,,8
@@ -103,7 +103,7 @@ DWORD DispatchTableLength = 0; DWORD ThisVM = 0;
DWORD is_qemu = FALSE;
-#if defined(QEMU) || defined(SVGA)
+#if defined(QEMU) || defined(SVGA) || defined(VESA)
/**
* This is fix of broken screen when open DOS window
*
@@ -127,7 +127,7 @@ void __declspec(naked) virtual_0x1ce() }
VxDJmp(VDD, Do_Physical_IO);
}
-#endif /* QEMU/SVGA */
+#endif /* QEMU/SVGA/VESA */
/**
* VDD calls wrapers
@@ -438,8 +438,14 @@ WORD __stdcall VXD_API_Proc(PCRS_32 state) case OP_VESA_SETMODE:
{
BOOL rs;
+ DWORD w, h, rr_min, rr_max;
+ w = state->Client_ESI >> 16;
+ h = state->Client_ESI & 0xFFFF;
+ rr_min = state->Client_EDI >> 16;
+ rr_max = state->Client_EDI & 0xFFFF;
+
Begin_Critical_Section(0);
- rs = VESA_setmode(state->Client_ESI, state->Client_EDI, state->Client_ECX);
+ rs = VESA_setmode(w, h, state->Client_ECX, rr_min, rr_max);
End_Critical_Section();
state->Client_ECX = (DWORD)rs;
rc = 1;
@@ -606,7 +612,7 @@ void Device_Init_proc(DWORD VM) VESA_init_hw();
#endif
-#if defined(QEMU)
+#if defined(QEMU) || defined(VESA)
Install_IO_Handler(0x1ce, (DWORD)virtual_0x1ce);
Disable_Global_Trapping(0x1ce);
Install_IO_Handler(0x1cf, (DWORD)virtual_0x1ce);
@@ -60,6 +60,10 @@ static DWORD mouse_pm16 = 0; extern WORD vbe_chip_id;
#endif
+#ifdef VESA
+extern WORD vesa_version;
+#endif
+
static BOOL mode_changing = FALSE;
static void VDD_Register_Extra_Screen_Selector(DWORD selector)
@@ -234,7 +238,7 @@ VDDPROC(GET_CHIP_ID, get_chip_id) #ifdef VESA
if(VESA_valid())
{
- state->Client_EAX = 0x1234;
+ state->Client_EAX = vesa_version;
VDD_CY;
}
else
diff --git a/vxd_vdd_list.h b/vxd_vdd_list.h index 4600757..74fb0ca 100644 --- a/vxd_vdd_list.h +++ b/vxd_vdd_list.h @@ -17,7 +17,7 @@ VDDFUNC(RESTORE_REGISTERS, restore_registers) //VDDFUNC(MODIFY_REGISTER_STATE, modify_register_state)
//VDDFUNC(ACCESS_VGA_MEMORY_MODE, access_vga_memory_mode)
//VDDFUNC(ACCESS_LINEAR_MEMORY_MODE, access_linear_memory_mode)
-#ifdef QEMU
+#if defined(QEMU) || defined(VESA)
VDDFUNC(ENABLE_TRAPS, enable_traps)
#endif
//VDDFUNC(DISABLE_TRAPS, disable_traps)
@@ -32,7 +32,7 @@ VDDFUNC(VIRTUALIZE_CRTC_OUT, virtualize_crtc_out) //VDDFUNC(RESET_LATCH_BANK, reset_latch_bank)
//VDDFUNC(SAVE_LATCHES, save_latches)
//VDDFUNC(RESTORE_LATCHES, restore_latches)
-#ifdef QEMU
+#if defined(QEMU) || defined(VESA)
VDDFUNC(DISPLAY_DRIVER_DISABLING, display_driver_disabling)
#endif
//VDDFUNC(SELECT_PLANE, select_plane)
@@ -30,11 +30,16 @@ THE SOFTWARE. #include "vxd_lib.h"
#include "3d_accel.h"
-#include "boxvint.h"
+#include "boxvint.h" /* VGA regitry */
#include "pci.h" /* re-use PCI functions from SVGA */
+
#include "vesa.h"
+#define IO_IN8
+#define IO_OUT8
+#include "io32.h"
+
#include "code32.h"
#define ISA_LFB 0xE0000000UL
@@ -53,10 +58,14 @@ typedef struct vesa_mode DWORD pitch;
DWORD phy;
WORD mode_id;
+ WORD flags;
} vesa_mode_t;
-vesa_mode_t *vesa_modes = NULL;
-DWORD vesa_modes_cnt = 0;
+static vesa_mode_t *vesa_modes = NULL;
+static DWORD vesa_modes_cnt = 0;
+WORD vesa_version = 0;
+static DWORD vesa_caps = 0;
+static int act_mode = -1;
#include "vxd_strings.h"
@@ -92,19 +101,38 @@ void load_client_state(CRS_32 *V86regs) VMMCall(Save_Client_State);
}
-DWORD vesa_buf_flat = 0;
-DWORD vesa_buf_v86;
-void *vesa_buf;
+static DWORD vesa_buf_v86;
+static void *vesa_buf;
+static DWORD vesa_buf_phy;
+static vesa_palette_entry_t *vesa_pal;
+static int vesa_pal_bits = 6;
+
+static BOOL vesa_valid = FALSE;
+
+#define SCREEN_EMULATED_CENTER 0
+#define SCREEN_EMULATED_COPY 1
+#define SCREEN_FLIP 2
+#define SCREEN_FLIP_VSYNC 3
+
+static DWORD screen_mode = SCREEN_EMULATED_COPY;
#define MODE_OFFSET 1024
#define CRTC_OFFSET 2048
+#define PAL_OFFSET 3072 // pal size = 4*256
#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;
+#define VESA_SUCC(_r) (((_r).Client_EAX & 0xFFFF)==0x004F)
+
+static void offset_calc(DWORD offset, DWORD *ox, DWORD *oy)
+{
+ DWORD ps = ((hda->bpp+7)/8);
+ *oy = offset/hda->pitch;
+ *ox = (offset % hda->pitch)/ps;
+}
static void alloc_modes_info(DWORD cnt)
{
@@ -116,37 +144,36 @@ static void alloc_modes_info(DWORD cnt) 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);
+ flat = _PageAllocate(1, PG_SYS, 0, 0x0, 0, 0x100000, &vesa_buf_phy, PAGEUSEALIGN | PAGECONTIG | PAGEFIXED);
vesa_buf = (void*)flat;
if(vesa_buf)
{
DWORD modes_count = 0;
#if 0
- /* JH: bad idea, memory must upper 640k! */
+ /* JH: bad idea, memory must be above 640k! */
DWORD lp = _GetLastV86Page();
DWORD v86_page = lp+1;
_SetLastV86Page(v86_page, 0);
- if(_PhysIntoV86(phy >> 12, ThisVM, v86_page, 1, 0))
+ if(_PhysIntoV86(vesa_buf_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);
+ dbg_printf("VESA V86 addr=0x%lX, phy=0x%lX\n", vesa_buf_v86, vesa_buf_phy);
#else
- /* FIXME: check if pages is free! */
+ /* FIXME: check if page is free! */
DWORD v86_page = 0xB0;
- if(_PhysIntoV86(phy >> 12, ThisVM, v86_page, 1, 0))
+ if(_PhysIntoV86(vesa_buf_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);
+ dbg_printf("VESA V86 addr=0x%lX, phy=0x%lX\n", vesa_buf_v86, vesa_buf_phy);
#endif
if(vesa_buf_v86)
@@ -162,7 +189,7 @@ BOOL VESA_init_hw() memcpy(&info->VESASignature[0], "VBE2", 4);
load_client_state(®s);
- regs.Client_EAX = 0x4f00;
+ regs.Client_EAX = VESA_CMD_ADAPTER_INFO;
regs.Client_ES = V86_SEG(vesa_buf_v86);
regs.Client_EDI = V86_OFF(vesa_buf_v86);
@@ -173,8 +200,14 @@ BOOL VESA_init_hw() {
WORD *modes = NULL;
- dbg_printf("VESA bios result=%X, vesa_version=%X, modes_ptr=%lX\n",
- regs.Client_EAX & 0xFFFF, info->VESAVersion, info->VideoModePtr);
+ dbg_printf("VESA bios result=%X, vesa_version=%X, modes_ptr=%lX vesa_caps=%lX\n",
+ regs.Client_EAX & 0xFFFF, info->VESAVersion, info->VideoModePtr, info->Capabilities);
+
+ if(info->VESAVersion < VESA_VBE_2_0)
+ {
+ dbg_printf("We need VBE 2.0 as minimum, abort\n");
+ return FALSE;
+ }
modes = (WORD*)LIN_FROM_V86(info->VideoModePtr);
if(modes != NULL)
@@ -189,10 +222,10 @@ BOOL VESA_init_hw() 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_EAX = VESA_CMD_MODE_INFO;
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);
@@ -200,10 +233,10 @@ BOOL VESA_init_hw() 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(VESA_SUCC(regs))
{
if(modeinfo->ModeAttributes &
- (VESA_MODE_HW_SUPPORTED | VESA_MODE_COLOR | VESA_MODE_GRAPHICS | VESA_MODE_LINEAR_FRAMEBUFFER))
+ (VESA_MODE_HW_SUPPORTED | VESA_MODE_COLOR | VESA_MODE_GRAPHICS | VESA_MODE_LFB))
{
vesa_mode_t *m = &vesa_modes[vesa_modes_cnt];
m->width = modeinfo->XResolution;
@@ -212,8 +245,9 @@ BOOL VESA_init_hw() m->pitch = modeinfo->BytesPerScanLine;
m->phy = modeinfo->PhysBasePtr;
m->mode_id = modes[i];
+ m->flags = modeinfo->ModeAttributes;
vesa_modes_cnt++;
-
+
if(m->phy)
{
if(m->phy < fb_phy)
@@ -238,18 +272,31 @@ BOOL VESA_init_hw() return FALSE;
}
+ vesa_version = info->VESAVersion;
+ vesa_caps = info->Capabilities;
+
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;
+ if(fb_phy == 0xFFFFFFFF)
+ {
+ fb_phy = ISA_LFB;
+ }
+
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;
-
+ hda->flags |= FB_SUPPORT_FLIPING | FB_VESA_MODES;
+
+ vesa_pal = (vesa_palette_entry_t*)(((BYTE*)vesa_buf)+PAL_OFFSET);
+
+ vesa_valid = TRUE;
+
+ //VESA_load_vbios_pm();
+
+ FBHDA_memtest();
+
dbg_printf("VESA_init_hw(vram_size=%ld) = TRUE\n", hda->vram_size);
return TRUE;
}
@@ -260,15 +307,13 @@ BOOL VESA_init_hw() 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)
@@ -276,17 +321,16 @@ BOOL VESA_validmode(DWORD w, DWORD h, DWORD bpp) return TRUE;
}
}
-
- dbg_printf("fail to valid mode: %ld %ld %ld\n", w, h, bpp);
+ //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);
+ memset((BYTE*)hda->vram_pm32+hda->system_surface, 0, hda->pitch*hda->height);
}
-BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp)
+BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp, DWORD rr_min, DWORD rr_max)
{
DWORD i;
dbg_printf("VESA_validmode()\n");
@@ -298,15 +342,19 @@ BOOL VESA_setmode(DWORD w, DWORD h, DWORD 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_EAX = VESA_CMD_MODE_SET;
+ regs.Client_EBX = vesa_modes[i].mode_id | VESA_SETMODE_LFB;
regs.Client_ES = 0;
regs.Client_EDI = 0;
+
vesa_bios(®s);
-
- if((regs.Client_EAX & 0xFFFF) == 0x004F)
+ if(VESA_SUCC(regs))
{
+ DWORD test_x;
+ DWORD test_y;
+
dbg_printf("SET success: %d %d %d\n", w, h, bpp);
hda->width = w;
hda->height = h;
@@ -315,10 +363,92 @@ BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp) hda->stride = h * hda->pitch;
hda->surface = 0;
+ /* set DAC to 8BIT if supported */
+ if(bpp <= 8)
+ {
+ if((vesa_caps & VESA_CAP_DAC8BIT) != 0)
+ {
+ /* set DAC to 8 bpp */
+ regs.Client_EAX = VESA_CMD_PALETTE_FORMAT;
+ regs.Client_EBX = VESA_DAC_SETFORMAT | VESA_DAC_SET_8BIT;
+ vesa_bios(®s);
+ if(VESA_SUCC(regs))
+ {
+ vesa_pal_bits = (regs.Client_EBX >> 8) & 0xFF;
+ }
+ else
+ {
+ vesa_pal_bits = 6;
+ }
+ }
+ else
+ {
+ vesa_pal_bits = 6;
+ }
+ }
+
+ /* test if HW flip supported */
+ offset_calc(hda->stride, &test_x, &test_y);
+ regs.Client_EAX = VESA_CMD_DISPLAY_START;
+ regs.Client_EBX = VESA_DISPLAYSTART_VTRACE;
+ regs.Client_ECX = test_x;
+ regs.Client_EDX = test_y;
+ vesa_bios(®s);
+ if(VESA_SUCC(regs))
+ {
+ screen_mode = SCREEN_FLIP_VSYNC;
+
+ regs.Client_EAX = VESA_CMD_DISPLAY_START;
+ regs.Client_EBX = VESA_DISPLAYSTART_SET;
+ regs.Client_ECX = 0;
+ regs.Client_EDX = 0;
+ vesa_bios(®s);
+ }
+ else
+ {
+ offset_calc(hda->stride, &test_x, &test_y);
+ regs.Client_EAX = VESA_CMD_DISPLAY_START;
+ regs.Client_EBX = VESA_DISPLAYSTART_SET;
+ regs.Client_ECX = test_x;
+ regs.Client_EDX = test_y;
+ vesa_bios(®s);
+
+ if(VESA_SUCC(regs))
+ {
+ screen_mode = SCREEN_FLIP;
+
+ regs.Client_EAX = VESA_CMD_DISPLAY_START;
+ regs.Client_EBX = VESA_DISPLAYSTART_SET;
+ regs.Client_ECX = test_x;
+ regs.Client_EDX = test_y;
+ vesa_bios(®s);
+ }
+ else
+ {
+ screen_mode = SCREEN_EMULATED_COPY;
+ }
+ }
+
+ if(screen_mode <= SCREEN_EMULATED_COPY)
+ {
+ hda->system_surface = hda->stride;
+ hda->surface = hda->stride;
+ //hda->system_surface = 0;
+ //hda->flags &= ~FB_SUPPORT_VSYNC;
+ }
+ else
+ {
+ hda->system_surface = 0;
+ hda->flags |= FB_SUPPORT_VSYNC;
+ }
+
VESA_clear();
mouse_invalidate();
FBHDA_update_heap_size(FALSE);
-
+
+ act_mode = i;
+
+ dbg_printf("mode set, mode_id=%d, screen_mode=%d\n", i, screen_mode);
return TRUE;
}
else
@@ -334,17 +464,137 @@ BOOL VESA_setmode(DWORD w, DWORD h, DWORD bpp) void FBHDA_palette_set(unsigned char index, DWORD rgb)
{
+ dbg_printf("PAL: %d:0x%lX,bpp:%d\n", index, rgb, vesa_pal_bits);
+ if((vesa_caps & VESA_CAP_NONVGA) == 0)
+ {
+ /* if mode is VGA compatible, we can use VGA regitry */
+ outp(VGA_DAC_W_INDEX, index); /* Set starting index. */
+ if(vesa_pal_bits == 8)
+ {
+ outp(VGA_DAC_DATA, (rgb >> 16) & 0xFF);
+ outp(VGA_DAC_DATA, (rgb >> 8) & 0xFF);
+ outp(VGA_DAC_DATA, rgb & 0xFF);
+ }
+ else
+ {
+ outp(VGA_DAC_DATA, (rgb >> 18) & 0x3F);
+ outp(VGA_DAC_DATA, (rgb >> 10) & 0x3F);
+ outp(VGA_DAC_DATA, (rgb >> 2) & 0x3F);
+ }
+ }
+ else
+ {
+ CRS_32 regs;
+ DWORD v86_ptr = vesa_buf_v86+PAL_OFFSET+4*index;
+
+ if(vesa_pal_bits == 8)
+ {
+ vesa_pal[index].Red = (rgb >> 16) & 0xFF;
+ vesa_pal[index].Green = (rgb >> 8) & 0xFF;
+ vesa_pal[index].Blue = rgb & 0xFF;
+ }
+ else
+ {
+ vesa_pal[index].Red = (rgb >> 18) & 0x3F;
+ vesa_pal[index].Green = (rgb >> 10) & 0x3F;
+ vesa_pal[index].Blue = (rgb >> 2) & 0x3F;
+ }
+
+ load_client_state(®s);
+ regs.Client_EAX = VESA_CMD_PALETTE_DATA;
+ regs.Client_EBX = VESA_RAMDAC_DATA_SET;
+ regs.Client_ECX = 1;
+ regs.Client_EDX = index;
+ regs.Client_ES = V86_SEG(v86_ptr);
+ regs.Client_EDI = V86_OFF(v86_ptr);
+ vesa_bios(®s);
+ }
}
DWORD FBHDA_palette_get(unsigned char index)
{
+ if((vesa_caps & VESA_CAP_NONVGA) == 0)
+ {
+ DWORD r, g, b;
+ outp(VGA_DAC_W_INDEX, index);
+ r = inp(VGA_DAC_DATA);
+ g = inp(VGA_DAC_DATA);
+ b = inp(VGA_DAC_DATA);
+
+ if(vesa_pal_bits == 8)
+ {
+ return (r << 16) | (g << 8) | b;
+ }
+ else
+ {
+ return (r << 18) | (g << 10) | (b << 2);
+ }
+ }
+ else
+ {
+ if(vesa_pal_bits == 8)
+ {
+ return
+ ((DWORD)(vesa_pal[index].Red) << 16) |
+ ((DWORD)(vesa_pal[index].Green) << 8) |
+ (DWORD)(vesa_pal[index].Blue);
+ }
+ else
+ {
+ return
+ ((DWORD)(vesa_pal[index].Red) << 18) |
+ ((DWORD)(vesa_pal[index].Green) << 10) |
+ ((DWORD)(vesa_pal[index].Blue) << 2);
+ }
+ }
+
return 0;
}
BOOL FBHDA_swap(DWORD offset)
{
- return TRUE;
+ if((offset + hda->stride) < hda->vram_size && offset >= hda->system_surface)
+ {
+ switch(screen_mode)
+ {
+ case SCREEN_EMULATED_CENTER:
+ case SCREEN_EMULATED_COPY:
+ FBHDA_access_begin(0);
+ hda->surface = offset;
+ FBHDA_access_end(0);
+ break;
+ case SCREEN_FLIP:
+ case SCREEN_FLIP_VSYNC:
+ {
+ CRS_32 regs;
+ DWORD off_x;
+ DWORD off_y;
+ if(fb_lock_cnt == 0)
+ {
+ mouse_erase();
+ }
+ offset_calc(offset, &off_x, &off_y);
+ load_client_state(®s);
+
+ regs.Client_EAX = VESA_CMD_DISPLAY_START;
+ regs.Client_EBX =
+ (screen_mode == SCREEN_FLIP_VSYNC) ? VESA_DISPLAYSTART_VTRACE : VESA_DISPLAYSTART_SET;
+ regs.Client_ECX = off_x;
+ regs.Client_EDX = off_y;
+ hda->surface = offset;
+ vesa_bios(®s);
+
+ if(fb_lock_cnt == 0)
+ {
+ mouse_blit();
+ }
+ break;
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
}
void FBHDA_access_begin(DWORD flags)
@@ -365,13 +615,20 @@ 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();
+ switch(screen_mode)
+ {
+ case SCREEN_EMULATED_CENTER:
+ case SCREEN_EMULATED_COPY:
+ memcpy(hda->vram_pm32, ((BYTE*)hda->vram_pm32)+hda->surface, hda->stride);
+ break;
+ }
// cursor
}
-
+
//Signal_Semaphore(hda_sem);
}
@@ -382,10 +639,10 @@ DWORD FBHDA_overlay_setup(DWORD overlay, DWORD width, DWORD height, DWORD bpp) void FBHDA_overlay_lock(DWORD left, DWORD top, DWORD right, DWORD bottom)
{
-
+
}
void FBHDA_overlay_unlock(DWORD flags)
{
-
+
}
|