📄 vesavbe.c
字号:
* pixelClock - Desired pixel clock* Returns: Closest pixel clock to desired clock (-1 if not supported)** Description: Calls the VBE/Core 3.0 interface to determine the closest* pixel clock to the requested value. The BIOS will always* search for a pixel clock that is no more than 1% below the* requested clock or somewhere higher than the clock. If the* clock is higher note that it may well be many Mhz higher* that requested and the application will have to check that* the returned value is suitable for it's needs. This function* returns the actual pixel clock that will be programmed by* the hardware.** Note that if the pixel clock will be used with a linear* framebuffer mode, make sure you pass in the linear* framebuffer flag to this function.** NOTE: Requires VBE/Core 3.0*****************************************************************************/{ RMREGS regs; if (state->VBEVersion >= 0x300) { regs.x.ax = 0x4F0B; regs.h.bl = 0x00; regs.e.ecx = pixelClock; regs.x.dx = mode; PM_int86(0x10,®s,®s); if (regs.x.ax == VBE_SUCCESS) return regs.e.ecx; } return -1;}ibool VBEAPI VBE_setDACWidth(int width)/****************************************************************************** Function: VBE_setDACWidth* Parameters: width - Width to set the DAC to* Returns: True on success, false on failure*****************************************************************************/{ RMREGS regs; regs.x.ax = 0x4F08; regs.h.bl = 0x00; regs.h.bh = width; PM_int86(0x10,®s,®s); return regs.x.ax == VBE_SUCCESS;}int VBEAPI VBE_getDACWidth(void)/****************************************************************************** Function: VBE_getDACWidth* Returns: Current width of the palette DAC*****************************************************************************/{ RMREGS regs; regs.x.ax = 0x4F08; regs.h.bl = 0x01; PM_int86(0x10,®s,®s); if (regs.x.ax != VBE_SUCCESS) return -1; return regs.h.bh;}ibool VBEAPI VBE_setPalette(int start,int num,VBE_palette *pal,ibool waitVRT)/****************************************************************************** Function: VBE_setPalette* Parameters: start - Starting palette index to program* num - Number of palette indexes to program* pal - Palette buffer containing values* waitVRT - Wait for vertical retrace flag* Returns: True on success, false on failure** Description: Sets a block of palette registers by calling the VBE 2.0* BIOS. This function will fail on VBE 1.2 implementations.*****************************************************************************/{ RMREGS regs; regs.x.ax = 0x4F09; regs.h.bl = waitVRT ? 0x80 : 0x00; regs.x.cx = num; regs.x.dx = start; VBE_callESDI(®s, pal, sizeof(VBE_palette) * num); return regs.x.ax == VBE_SUCCESS;}void * VBEAPI VBE_getBankedPointer(VBE_modeInfo *modeInfo)/****************************************************************************** Function: VBE_getBankedPointer* Parameters: modeInfo - Mode info block for video mode* Returns: Selector to the linear framebuffer (0 on failure)** Description: Returns a near pointer to the VGA framebuffer area.*****************************************************************************/{ /* We just map the pointer every time, since the pointer will always * be in real mode memory, so we wont actually be mapping any real * memory. * * NOTE: We cannot currently map a near pointer to the banked frame * buffer for Watcom Win386, so we create a 16:16 far pointer to * the video memory. All the assembler code will render to the * video memory by loading the selector rather than using a * near pointer. */ ulong seg = (ushort)modeInfo->WinASegment; if (seg != 0) { if (seg == 0xA000) return (void*)PM_getA0000Pointer(); else return (void*)PM_mapPhysicalAddr(seg << 4,0xFFFF,true); } return NULL;}#ifndef REALMODEvoid * VBEAPI VBE_getLinearPointer(VBE_modeInfo *modeInfo)/****************************************************************************** Function: VBE_getLinearPointer* Parameters: modeInfo - Mode info block for video mode* Returns: Selector to the linear framebuffer (0 on failure)** Description: Returns a near pointer to the linear framebuffer for the video* mode.*****************************************************************************/{ static ulong physPtr[MAX_LIN_PTRS] = {0}; static void *linPtr[MAX_LIN_PTRS] = {0}; static int numPtrs = 0; int i; /* Search for an already mapped pointer */ for (i = 0; i < numPtrs; i++) { if (physPtr[i] == modeInfo->PhysBasePtr) return linPtr[i]; } if (numPtrs < MAX_LIN_PTRS) { physPtr[numPtrs] = modeInfo->PhysBasePtr; linPtr[numPtrs] = PM_mapPhysicalAddr(modeInfo->PhysBasePtr,(state->VBEMemory * 1024L)-1,true); return linPtr[numPtrs++]; } return NULL;}static void InitPMCode(void)/****************************************************************************** Function: InitPMCode - 32 bit protected mode version** Description: Finds the address of and relocates the protected mode* code block from the VBE 2.0 into a local memory block. The* memory block is allocated with malloc() and must be freed* with VBE_freePMCode() after graphics processing is complete.** Note that this buffer _must_ be recopied after each mode set,* as the routines will change depending on the underlying* video mode.*****************************************************************************/{ RMREGS regs; RMSREGS sregs; uchar *code; int pmLen; if (!state->pmInfo && state->VBEVersion >= 0x200) { regs.x.ax = 0x4F0A; regs.x.bx = 0; PM_int86x(0x10,®s,®s,&sregs); if (regs.x.ax != VBE_SUCCESS) return; if (VBE_shared) state->pmInfo = PM_mallocShared(regs.x.cx); else state->pmInfo = PM_malloc(regs.x.cx); if (state->pmInfo == NULL) return; state->pmInfo32 = state->pmInfo; pmLen = regs.x.cx; /* Relocate the block into our local data segment */ code = PM_mapRealPointer(sregs.es,regs.x.di); memcpy(state->pmInfo,code,pmLen); /* Now do a sanity check on the information we recieve to ensure * that is is correct. Some BIOS return totally bogus information * in here (Matrox is one)! Under DOS this works OK, but under OS/2 * we are screwed. */ if (state->pmInfo->setWindow >= pmLen || state->pmInfo->setDisplayStart >= pmLen || state->pmInfo->setPalette >= pmLen || state->pmInfo->IOPrivInfo >= pmLen) { if (VBE_shared) PM_freeShared(state->pmInfo); else PM_free(state->pmInfo); state->pmInfo32 = state->pmInfo = NULL; return; } /* Read the IO priveledge info and determine if we need to * pass a selector to MMIO registers to the bank switch code. * Since we no longer support selector allocation, we no longer * support this mechanism so we disable the protected mode * interface in this case. */ if (state->pmInfo->IOPrivInfo && !state->MMIOSel) { ushort *p = (ushort*)((uchar*)state->pmInfo + state->pmInfo->IOPrivInfo); while (*p != 0xFFFF) p++; p++; if (*p != 0xFFFF) VBE_freePMCode(); } }}void * VBEAPI VBE_getSetBank(void)/****************************************************************************** Function: VBE_getSetBank* Returns: Pointer to the 32 VBE 2.0 bit bank switching routine.*****************************************************************************/{ if (state->VBEVersion >= 0x200) { InitPMCode(); if (state->pmInfo) return (uchar*)state->pmInfo + state->pmInfo->setWindow; } return NULL;}void * VBEAPI VBE_getSetDisplayStart(void)/****************************************************************************** Function: VBE_getSetDisplayStart* Returns: Pointer to the 32 VBE 2.0 bit CRT start address routine.*****************************************************************************/{ if (state->VBEVersion >= 0x200) { InitPMCode(); if (state->pmInfo) return (uchar*)state->pmInfo + state->pmInfo->setDisplayStart; } return NULL;}void * VBEAPI VBE_getSetPalette(void)/****************************************************************************** Function: VBE_getSetPalette* Returns: Pointer to the 32 VBE 2.0 bit palette programming routine.*****************************************************************************/{ if (state->VBEVersion >= 0x200) { InitPMCode(); if (state->pmInfo) return (uchar*)state->pmInfo + state->pmInfo->setPalette; } return NULL;}void VBEAPI VBE_freePMCode(void)/****************************************************************************** Function: VBE_freePMCode** Description: This routine frees the protected mode code blocks that* we copied from the VBE 2.0 interface. This routine must* be after you have finished graphics processing to free up* the memory occupied by the routines. This is necessary* because the PM info memory block must be re-copied after* every video mode set from the VBE 2.0 implementation.*****************************************************************************/{ if (state->pmInfo) { if (VBE_shared) PM_freeShared(state->pmInfo); else PM_free(state->pmInfo); state->pmInfo = NULL; state->pmInfo32 = NULL; }}void VBEAPI VBE_sharePMCode(void)/****************************************************************************** Function: VBE_sharePMCode** Description: Enables internal sharing of the PM code buffer for OS/2.*****************************************************************************/{ VBE_shared = true;}/* Set of code stubs used to build the final bank switch code */#define VBE20_adjustOffset 7static uchar VBE20A_bankFunc32_Start[] = { 0x53,0x51, /* push ebx,ecx */ 0x8B,0xD0, /* mov edx,eax */ 0x33,0xDB, /* xor ebx,ebx */ 0xB1,0x00, /* mov cl,0 */ 0xD2,0xE2, /* shl dl,cl */ };static uchar VBE20_bankFunc32_End[] = { 0x59,0x5B, /* pop ecx,ebx */ };static uchar bankFunc32[100];#define copy(p,b,a) memcpy(b,a,sizeof(a)); (p) = (b) + sizeof(a)ibool VBEAPI VBE_getBankFunc32(int *codeLen,void **bankFunc,int dualBanks, int bankAdjust)/****************************************************************************** Function: VBE_getBankFunc32* Parameters: codeLen - Place to store length of code* bankFunc - Place to store pointer to bank switch code* dualBanks - True if dual banks are in effect* bankAdjust - Bank shift adjustment factor* Returns: True on success, false if not compatible.** Description: Creates a local 32 bit bank switch function from the* VBE 2.0 bank switch code that is compatible with the* virtual flat framebuffer devices (does not have a return* instruction at the end and takes the bank number in EAX* not EDX). Note that this 32 bit code cannot include int 10h* instructions, so we can only do this if we have VBE 2.0* or later.** Note that we need to know the length of the 32 bit* bank switch function, which the standard VBE 2.0 spec* does not provide. In order to support this we have* extended the VBE 2.0 state->pmInfo structure in UniVBE 5.2 in a* way to support this, and we hope that this will become* a VBE 2.0 ammendment.** Note also that we cannot run the linear framebuffer* emulation code with bank switching routines that require* a selector to the memory mapped registers passed in ES.*****************************************************************************/{ int len; uchar *code; uchar *p; InitPMCode(); if (state->VBEVersion >= 0x200 && state->pmInfo32 && !state->MMIOSel) { code = (uchar*)state->pmInfo32 + state->pmInfo32->setWindow; if (state->pmInfo32->extensionSig == VBE20_EXT_SIG) len = state->pmInfo32->setWindowLen-1; else { /* We are running on a system without the UniVBE 5.2 extension. * We do as best we can by scanning through the code for the * ret function to determine the length. This is not foolproof, * but is the best we can do. */ p = code; while (*p != 0xC3) p++; len = p - code; } if ((len + sizeof(VBE20A_bankFunc32_Start) + sizeof(VBE20_bankFunc32_End)) > sizeof(bankFunc32)) PM_fatalError("32-bit bank switch function too long!"); copy(p,bankFunc32,VBE20A_bankFunc32_Start); memcpy(p,code,len); p += len; copy(p,p,VBE20_bankFunc32_End); *codeLen = p - bankFunc32; bankFunc32[VBE20_adjustOffset] = (uchar)bankAdjust; *bankFunc = bankFunc32; return true; } return false;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -