📄 ves2.h
字号:
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman// Ken Silverman's official web site: "http://www.advsys.net/ken"// See the included license file "BUILDLIC.TXT" for license info.// This file has been modified from Ken Silverman's original release#ifndef _INCLUDE_VES2_H_#define _INCLUDE_VES2_H_#if (!defined PLATFORM_DOS)#error Do not include this file. It is for the DOS target only.#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <conio.h>#include <dos.h>#include "build.h"#include "pragmas.h"#pragma pack(push,1);typedef struct{ char VESASignature[4]; short VESAVersion; long OemStringPtr, Capabilities, VideoModePtr; short TotalMemory, OemSoftwareRev; long OemVendorNamePtr, OemProductNamePtr, OemProductRevPtr; char reserved[222], OemDATA[256];} VBE_vgaInfo;typedef struct{ short ModeAttributes; char WinAAtributes, WinBAttributes; short WinGranularity, WinSize, WinASegment, WinBSegment; long WinFuncPtr; short BytesPerScanLine, XResolution, YResolution; char XCharSize, YCharSize, NumberOfPlanes, BitsPerPixel; char NumberOfBanks, MemoryModel, BankSize, NumberOfImagePages; char res1; char RedMaskSize, RedFieldPosition; char GreenMaskSize, GreenFieldPosition; char BlueMaskSize, BlueFieldPosition; char RsvdMaskSize, RsvdFieldPosition, DirectColorModeInfo; long PhysBasePtr, OffScreenMemOffset; short OffScreenMemSize; char res2[206];} VBE_modeInfo;struct _RMWORDREGS { unsigned short ax, bx, cx, dx, si, di, cflag; };struct _RMBYTEREGS { unsigned char al, ah, bl, bh, cl, ch, dl, dh; };typedef union { struct _RMWORDREGS x; struct _RMBYTEREGS h; } RMREGS;typedef struct { unsigned short es, cs, ss, ds; } RMSREGS;typedef struct{ long edi, esi, ebp, reserved, ebx, edx, ecx, eax; short flags, es, ds, fs, gs, ip, cs, sp, ss;} _RMREGS;#pragma pack(pop);long VESABuf_sel = 0, VESABuf_rseg;short modelist[256];char *screen = NULL, vesachecked = 0;long xres, yres, bytesperline, frameplace, imageSize, maxpages;long buffermode, origbuffermode, linearmode;long setactiveentry = 0, setvisualentry = 0, setpaletteentry = 0;char permanentupdate = 0, vgacompatible;short visualpagelookup[64][2];long activepagelookup[64];static long ves2lastx[MAXYDIM];static long davesapageshift;static VBE_vgaInfo vgaInfo;long globlinplace;static long backlinaddress = 0; //Save address for free operation (0x801)void faketimerhandler(void);void qlimitrate(void);#pragma aux qlimitrate =\ "mov dx, 0x3da",\ "wait1: in al, dx",\ "test al, 1",\ "jnz wait1",\ modify exact [eax edx]\void backupsegs(void);short ods, oes, oss;#pragma aux backupsegs =\ "mov ods, ds",\ "mov oes, es",\ "mov oss, ss",\ modify [eax]\void restoresegs(void);#pragma aux restoresegs =\ "mov ds, ods",\ "mov es, oes",\ "mov ss, oss",\ modify [eax]\/* //64-bit copybufbyte#pragma aux copybufbyte =\ "cmp ecx, 8",\ "jae longcopy",\ "test cl, 1",\ "jz shortskip1",\ "movsb",\ "shortskip1: shr ecx, 2",\ "jnc shortskip2",\ "movsw",\ "shortskip2: rep movsd",\ "jmp endit",\ "longcopy: test edi, 1",\ "jz skip1",\ "movsb",\ "dec ecx",\ "skip1: test edi, 2",\ "jz skip2",\ "movsw",\ "sub ecx, 2",\ "skip2: test edi, 4",\ "jz skip3",\ "movsd",\ "sub ecx, 4",\ "skip3: mov ebx, ecx",\ "shr ecx, 3",\ "jz skip4",\ "begloop: fld qword ptr [esi]",\ "fstp qword ptr [edi]",\ "add esi, 8",\ "add edi, 8",\ "dec ecx",\ "jnz begloop",\ "skip4: test bl, 4",\ "jz skip5",\ "movsd",\ "skip5: test bl, 2",\ "jz skip6",\ "movsw",\ "skip6: test bl, 1",\ "jz endit",\ "movsb",\ "endit:",\ parm [esi][edi][ecx]\ modify [ebx]\*/void vesasetactive(long i1, long i2, long i3, long i4);#pragma aux vesasetactive =\ "call dword ptr [setactiveentry]",\ parm [eax][ebx][ecx][edx]\void vesasetvisual(long i1, long i2, long i3, long i4);#pragma aux vesasetvisual =\ "call dword ptr [setvisualentry]",\ parm [eax][ebx][ecx][edx]\long vesasetpalette(long i1, long i2, long i3, long i4, long i5, char *i6);#pragma aux vesasetpalette =\ "call dword ptr [setpaletteentry]",\ parm [eax][ebx][ecx][edx][esi][edi]\long DPMI_int86(long intno, RMREGS *in, RMREGS *out){ _RMREGS rmregs; union REGS r; struct SREGS sr; memset(&rmregs,0,sizeof(rmregs)); rmregs.eax = in->x.ax; rmregs.ebx = in->x.bx; rmregs.ecx = in->x.cx; rmregs.edx = in->x.dx; rmregs.esi = in->x.si; rmregs.edi = in->x.di; segread(&sr); r.w.ax = 0x300; r.h.bl = intno; r.h.bh = 0; r.w.cx = 0; sr.es = sr.ds; r.x.edi = (unsigned)&rmregs; backupsegs(); int386x(0x31,&r,&r,&sr); restoresegs(); out->x.ax = rmregs.eax; out->x.bx = rmregs.ebx; out->x.cx = rmregs.ecx; out->x.dx = rmregs.edx; out->x.si = rmregs.esi; out->x.di = rmregs.edi; out->x.cflag = rmregs.flags&1; return(out->x.ax);}long DPMI_int86x(long intno, RMREGS *in, RMREGS *out, RMSREGS *sregs){ _RMREGS rmregs; union REGS r; struct SREGS sr; memset(&rmregs, 0, sizeof(rmregs)); rmregs.eax = in->x.ax; rmregs.ebx = in->x.bx; rmregs.ecx = in->x.cx; rmregs.edx = in->x.dx; rmregs.esi = in->x.si; rmregs.edi = in->x.di; rmregs.es = sregs->es; rmregs.ds = sregs->ds; segread(&sr); r.w.ax = 0x300; r.h.bl = intno; r.h.bh = 0; r.w.cx = 0; sr.es = sr.ds; r.x.edi = (unsigned)&rmregs; backupsegs(); int386x(0x31,&r,&r,&sr); restoresegs(); out->x.ax = rmregs.eax; out->x.bx = rmregs.ebx; out->x.cx = rmregs.ecx; out->x.dx = rmregs.edx; out->x.si = rmregs.esi; out->x.di = rmregs.edi; sregs->es = rmregs.es; sregs->cs = rmregs.cs; sregs->ss = rmregs.ss; sregs->ds = rmregs.ds; out->x.cflag = rmregs.flags&1; return(out->x.ax);}static void ExitVBEBuf(void){ union REGS r; r.w.ax = 0x101; r.w.dx = VESABuf_sel; //DPMI free real seg backupsegs(); int386(0x31,&r,&r); restoresegs();}void VBE_callESDI(RMREGS *regs, void *buffer, long size){ RMSREGS sregs; union REGS r; if (!VESABuf_sel) //Init Real mode buffer { r.w.ax = 0x100; r.w.bx = 1024>>4; backupsegs(); int386(0x31,&r,&r); restoresegs(); if (r.w.cflag) { printf("DPMI_allocRealSeg failed!\n"); exit(0); } VESABuf_sel = r.w.dx; VESABuf_rseg = r.w.ax; atexit(ExitVBEBuf); } 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);}long VBE_getModeInfo(long mode, VBE_modeInfo *modeInfo){ RMREGS regs; regs.x.ax = 0x4f01; regs.x.cx = mode; VBE_callESDI(®s, modeInfo, sizeof(VBE_modeInfo)); if (regs.x.ax != 0x004f) return(0); if ((modeInfo->ModeAttributes&1) == 0) return(0); //1 is vbeMdAvailable return(1);}GetPtrToLFB(long physAddr){ #define LIMIT (4096*1024)-1 long sel; union REGS r; r.w.ax = 0; r.w.cx = 1; backupsegs(); int386(0x31,&r,&r); restoresegs(); if (r.x.cflag) { printf("DPMI_allocSelector() failed!\n"); exit(0); } sel = r.w.ax; r.w.ax = 9; r.w.bx = sel; r.w.cx = 0x8092; backupsegs(); int386(0x31,&r,&r); restoresegs(); r.w.ax = 0x800; r.w.bx = physAddr >> 16; r.w.cx = physAddr & 0xffff; r.w.si = LIMIT>>16; r.w.di = LIMIT&0xffff; backupsegs(); int386(0x31,&r,&r); restoresegs(); if (r.x.cflag) { printf("DPMI_mapPhysicalToLinear() failed!\n"); exit(0); } backlinaddress = globlinplace = ((long)r.w.bx<<16)+r.w.cx; r.w.ax = 7; r.w.bx = sel; r.w.cx = globlinplace>>16; r.w.dx = globlinplace&0xffff; backupsegs(); int386(0x31,&r,&r); restoresegs(); if (r.x.cflag) { printf("DPMI_setSelectorBase() failed!\n"); exit(0); } r.w.ax = 8; r.w.bx = sel; r.w.cx = LIMIT>>16; r.w.dx = LIMIT&0xffff; backupsegs(); int386(0x31,&r,&r); restoresegs(); if (r.x.cflag) { printf("DPMI_setSelectorLimit() failed!\n"); exit(0); }}void getvalidvesamodes(void){ long i, j, k; short *p, *p2; VBE_modeInfo modeInfo; RMREGS regs; if (vesachecked) return; vesachecked = 1; validmodecnt = 0; modelist[0] = -1; strncpy(vgaInfo.VESASignature,"VBE2",4); regs.x.ax = 0x4f00; VBE_callESDI(®s,&vgaInfo,sizeof(VBE_vgaInfo)); if ((regs.x.ax != 0x004f) || (strncmp(vgaInfo.VESASignature,"VESA",4))) return; //if (vgaInfo.VESAVersion < 0x200) return; //LfbMapRealPointer p = (short *)(((vgaInfo.VideoModePtr&0xffff0000)>>12)+((vgaInfo.VideoModePtr)&0xffff)); p2 = modelist; while (*p != -1) *p2++ = *p++; *p2 = -1; for(p=modelist;*p!=-1;p++) { regs.x.ax = 0x4f01; regs.x.cx = *p; VBE_callESDI(®s,&modeInfo,sizeof(VBE_modeInfo)); if (regs.x.ax != 0x004f) continue; if (!(modeInfo.ModeAttributes&1)) continue; //1 is vbeMdAvailable if (modeInfo.MemoryModel != 4) continue; //4 is vbeMemPK if (modeInfo.BitsPerPixel != 8) continue; if (modeInfo.NumberOfPlanes != 1) continue; validmode[validmodecnt] = *p; validmodexdim[validmodecnt] = modeInfo.XResolution; validmodeydim[validmodecnt] = modeInfo.YResolution; validmodecnt++; } for(i=1;i<validmodecnt;i++) for(j=0;j<i;j++) if (validmodeydim[i] < validmodeydim[j]) { k = validmode[i]; validmode[i] = validmode[j]; validmode[j] = k; k = validmodexdim[i]; validmodexdim[i] = validmodexdim[j]; validmodexdim[j] = k; k = validmodeydim[i]; validmodeydim[i] = validmodeydim[j]; validmodeydim[j] = k; } for(i=1;i<validmodecnt;i++) for(j=0;j<i;j++) if (validmodexdim[i] < validmodexdim[j]) { k = validmode[i]; validmode[i] = validmode[j]; validmode[j] = k; k = validmodexdim[i]; validmodexdim[i] = validmodexdim[j]; validmodexdim[j] = k; k = validmodeydim[i]; validmodeydim[i] = validmodeydim[j]; validmodeydim[j] = k; }}int setvesa(long x, long y){ div_t dived; long i, j, k; //short *p, *p1, *p2; short *p1; VBE_modeInfo modeInfo; RMREGS regs; RMSREGS sregs; getvalidvesamodes(); xres = x; yres = y; for(k=0;k<validmodecnt;k++) { regs.x.ax = 0x4f01; regs.x.cx = validmode[k]; VBE_callESDI(®s,&modeInfo,sizeof(VBE_modeInfo)); if (regs.x.ax != 0x004f) continue; if (!(modeInfo.ModeAttributes&1)) continue; //1 is vbeMdAvailable if (modeInfo.MemoryModel != 4) continue; //4 is vbeMemPK if (modeInfo.BitsPerPixel != 8) continue; if (modeInfo.NumberOfPlanes != 1) continue; if (modeInfo.XResolution != x) continue; if (modeInfo.YResolution != y) continue; bytesperline = modeInfo.BytesPerScanLine; maxpages = min(modeInfo.NumberOfImagePages+1,64); regs.x.ax = 0x4f02; regs.x.bx = validmode[k] | ((modeInfo.ModeAttributes&128)<<7); DPMI_int86(0x10,®s,®s); if (modeInfo.ModeAttributes&32) vgacompatible = 0; else vgacompatible = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -