📄 vesa.cpp
字号:
//#include "os.h"
//#ifdef OS_DOS
/****************************************************************************
* VBE 2.0 Linear Framebuffer Utilities
* Base Code by By Kendall Bennett and Brian Hook
* Modified for use by Matt Howard
*
* Filename: VESA.CPP
* Language: ANSI C + C++
* Environment: Watcom C/C++ 10.0a with DOS4GW
* Description: Utilities to use SuperVGA VESA modes
* Also allows burst copies to the screen
* For simplicity, this program only supports 256 color
* SuperVGA video modes that support a linear framebuffer.
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include "dpmiserv.h"
#include "vesa.h"
/*---------------------- Macros and type definitions ----------------------*/
#pragma pack(1)
/* SuperVGA information block */
typedef struct {
char VESASignature[4]; /* 'VESA' 4 byte signature */
short VESAVersion; /* VBE version number */
long OemStringPtr; /* Pointer to OEM string */
long Capabilities; /* Capabilities of video card */
long VideoModePtr; /* Pointer to supported modes */
short TotalMemory; /* Number of 64kb memory blocks */
/* VBE 2.0 extensions */
short OemSoftwareRev; /* OEM Software revision number */
long OemVendorNamePtr; /* Pointer to Vendor Name string */
long OemProductNamePtr; /* Pointer to Product Name string */
long OemProductRevPtr; /* Pointer to Product Revision str */
char reserved[222]; /* Pad to 256 byte block size */
char OemDATA[256]; /* Scratch pad for OEM data */
} VBE_vgaInfo;
/* SuperVGA mode information block */
typedef struct {
short ModeAttributes; /* Mode attributes */
char WinAAttributes; /* Window A attributes */
char WinBAttributes; /* Window B attributes */
short WinGranularity; /* Window granularity in k */
short WinSize; /* Window size in k */
short WinASegment; /* Window A segment */
short WinBSegment; /* Window B segment */
long WinFuncPtr; /* Pointer to window function */
short BytesPerScanLine; /* Bytes per scanline */
short XResolution; /* Horizontal resolution */
short YResolution; /* Vertical resolution */
char XCharSize; /* Character cell width */
char YCharSize; /* Character cell height */
char NumberOfPlanes; /* Number of memory planes */
char BitsPerPixel; /* Bits per pixel */
char NumberOfBanks; /* Number of CGA style banks */
char MemoryModel; /* Memory model type */
char BankSize; /* Size of CGA style banks */
char NumberOfImagePages; /* Number of images pages */
char res1; /* Reserved */
char RedMaskSize; /* Size of direct color red mask */
char RedFieldPosition; /* Bit posn of lsb of red mask */
char GreenMaskSize; /* Size of direct color green mask */
char GreenFieldPosition; /* Bit posn of lsb of green mask */
char BlueMaskSize; /* Size of direct color blue mask */
char BlueFieldPosition; /* Bit posn of lsb of blue mask */
char RsvdMaskSize; /* Size of direct color res mask */
char RsvdFieldPosition; /* Bit posn of lsb of res mask */
char DirectColorModeInfo; /* Direct color mode attributes */
/* VBE 2.0 extensions */
long PhysBasePtr; /* Physical address for linear buf */
long OffScreenMemOffset; /* Pointer to start of offscreen mem*/
short OffScreenMemSize; /* Amount of offscreen mem in 1K's */
char res2[206]; /* Pad to 256 byte block size */
} VBE_modeInfo;
#define vbeMemPK 4 /* Packed Pixel memory model */
#define vbeUseLFB 0x4000 /* Enable linear framebuffer mode */
/* Flags for the mode attributes returned by VBE_getModeInfo. If
* vbeMdNonBanked is set to 1 and vbeMdLinear is also set to 1, then only
* the linear framebuffer mode is available. */
#define vbeMdAvailable 0x0001 /* Video mode is available */
#define vbeMdColorMode 0x0008 /* Mode is a color video mode */
#define vbeMdGraphMode 0x0010 /* Mode is a graphics mode */
#define vbeMdNonBanked 0x0040 /* Banked mode is not supported */
#define vbeMdLinear 0x0080 /* Linear mode supported */
/* Inline assembler block fill/move routines */
void LfbMemset(int sel,int off,int c,int n);
#pragma aux LfbMemset = \
"push es" \
"mov es,ax" \
"shr ecx,2" \
"xor eax,eax" \
"mov al,bl" \
"shl ebx,8" \
"or ax,bx" \
"mov ebx,eax" \
"shl ebx,16" \
"or eax,ebx" \
"rep stosd" \
"pop es" \
parm [eax] [edi] [ebx] [ecx];
void LfbMemcpy(int sel,int off,void *src,int n);
#pragma aux LfbMemcpy = \
"push es" \
"mov es,ax" \
"shr ecx,2" \
"rep movsd" \
"pop es" \
parm [eax] [edi] [esi] [ecx];
/* Map a real mode pointer into address space */
#define LfbMapRealPointer(p) (void*)(((unsigned)(p) >> 12) + ((p) & 0xFFFF))
/* Get the current timer tick count */
#define LfbGetTicks() *((long*)0x46C)
#pragma pack()
/*---------------------------- Global Variables ---------------------------*/
int VESABuf_len = 1024; /* Length of VESABuf */
int VESABuf_sel = 0; /* Selector for VESABuf */
int VESABuf_rseg; /* Real mode segment of VESABuf */
short VESA_modeList[50]; /* List of available VBE modes */
int VESA_xres,VESA_yres; /* Video mode resolution */
int VESA_bytesperline; /* Bytes per scanline for mode */
long VESA_imageSize; /* Length of the video image */
char far * VESA_LFBPtr; /* Pointer to linear framebuffer */
/*-------------------------- VBE Interface routines -----------------------*/
static void ExitVBEBuf(void)
{
DPMI_freeRealSeg(VESABuf_sel);
}
void VBE_initRMBuf(void)
/****************************************************************************
* Function: VBE_initRMBuf
* Description: Initialises the VBE transfer buffer in real mode memory.
* This routine is called by the VESAVBE module every time
* it needs to use the transfer buffer, so we simply allocate
* it once and then return.
****************************************************************************/
{
if (!VESABuf_sel) {
DPMI_allocRealSeg(VESABuf_len, &VESABuf_sel, &VESABuf_rseg);
atexit(ExitVBEBuf);
}
}
void VBE_callESDI(RMREGS *regs, void *buffer, int size)
/****************************************************************************
* Function: VBE_callESDI
* Parameters: regs - Registers to load when calling VBE
* buffer - Buffer to copy VBE info block to
* size - Size of buffer to fill
* Description: Calls the VESA VBE and passes in a buffer for the VBE to
* store information in, which is then copied into the users
* buffer space. This works in protected mode as the buffer
* passed to the VESA VBE is allocated in conventional
* memory, and is then copied into the users memory block.
****************************************************************************/
{
RMSREGS sregs;
VBE_initRMBuf();
sregs.es = VESABuf_rseg;
regs->x.di = 0;
_fmemcpy(MK_FP(VESABuf_sel,0),buffer,size);
DPMI_int86x(0x10, regs, regs, &sregs);
_fmemcpy(buffer,MK_FP(VESABuf_sel,0),size);
}
int VBE_detect(void)
/****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -