⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vesa.h

📁 这个版本修正了已知的Bug,同时添加了部分函数
💻 H
📖 第 1 页 / 共 2 页
字号:
#include<io.h>
#include<time.h>
#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
#include<bios.h>
#include<stdarg.h>
#include<stddef.h>

#include"timer.h"
#include"draw.h"
#include"hzk.h"

RMInfo          RMI;
VBEHardWare     HardWareInfo;
VBEModeInfo     VesaModeInfo;
long            VideoPhysBasePtr,
                screen_videomem;
PCXHEAD         pcx;
unsigned char   ColorTable[256][3];
BITMAP          *_Screen=NULL,*_Display;


struct LineWriteMode
{unsigned char StyLine;
}LineWriteMode;

char DpmiRealMalloc(unsigned short Size, unsigned short *Segment,  unsigned short *Selector)
{   union REGS regs;
    memset(&regs, 0, sizeof(regs));
    regs.x.eax = 0x0100;               // DPMI 分配DOS内存
    regs.x.ebx = Size;                 // Size * 16
    int386 (0x31, &regs, &regs);       // 分配DOS内存块
    if (regs.x.cflag)                  // 失败
    {
        printf("\nError: Allocate DOS memory: %dunsigned char", Size*16);
        return FALSE;
    }
    *Selector = regs.w.dx;
    *Segment = regs.w.ax;
    return TRUE;
}

char DpmiRealFree(unsigned short Selector)
{  union REGS regs;
    memset(&regs, 0, sizeof(regs));
    regs.x.eax = 0x0101;
    regs.x.edx = Selector;             // 块的选择符
    int386 (0x31, &regs, &regs);       // 释放DOS内存块
    if (regs.x.cflag)                  // 失败
    {
        printf("\nError: Free DOS memory: Selector = %d", Selector);
        return FALSE;
    }
    return TRUE;
}

char DpmiRealInt386x(unsigned char IntNO, RMInfo *RealRegs)
{ union REGS regs;
  struct SREGS sregs;
    memset(&regs, 0, sizeof(regs));
    memset(&sregs, 0, sizeof(sregs));
    regs.w.ax = 0x0300;
    regs.h.bl = IntNO;
    regs.h.bh = 0;
    regs.w.cx = 0;
    sregs.es = FP_SEG(RealRegs);
    regs.x.edi = FP_OFF(RealRegs);
    int386x(0x31, &regs, &regs, &sregs);
    if (regs.x.cflag)                  // 失败
    {
        printf("\nError: Issue the DOS interrupt: %dh", IntNO);
        return FALSE;
    }
    return TRUE;
}

unsigned long DPMIPhysicalToLinear(unsigned long physAddr, unsigned long limit)
{   union REGS regs;
    regs.w.ax = 0x800;    // 物理地址 -> 线形地址
    regs.w.bx = physAddr >> 16;
    regs.w.cx = physAddr & 0xFFFF;
    regs.w.si = limit >> 16;
    regs.w.di = limit & 0xFFFF;
    int386(0x31, &regs, &regs);
    if (regs.w.cflag) return FALSE;
    return ((unsigned long)regs.w.bx << 16) + regs.w.cx;
}

unsigned long DPMIGetSelectorBase(unsigned short Selector)
{   union REGS regs;
    regs.w.ax = 6;        // 取描述符的基地址
    regs.w.bx = Selector;
    int386(0x31, &regs, &regs);
    return ((unsigned long)regs.w.cx << 16) + regs.w.dx;
}

char DPMISetSelectorLimit(unsigned short Selector, unsigned long limit)
{   union REGS regs;
    regs.w.ax = 8;        // 设置描述符的访问范围
    regs.w.bx = Selector;
    regs.w.cx = limit >> 16;
    regs.w.dx = limit & 0xFFFF;
    int386(0x31, &regs, &regs);
    if (regs.w.cflag) return FALSE;
    return TRUE;
}

void *DPMIPhysicalAddr(unsigned long base, unsigned long limit)
{
    struct SREGS sregs;
    unsigned long  linAddr;
    unsigned long  DSBaseAddr;
    segread(&sregs);
    DSBaseAddr = DPMIGetSelectorBase(sregs.ds);
    if((linAddr = DPMIPhysicalToLinear(base, limit))==FALSE)
      return NULL;
     if(DPMISetSelectorLimit(sregs.ds, 0xFFFFFFFFUL)==FALSE)
      return NULL;
return (void*)(linAddr - DSBaseAddr);
}

char GetVesaInfo(void)         // 取VESA显示卡信息
{
    unsigned short segment, selector;
    unsigned char *vesalist;

    DpmiRealMalloc(0x0010, &segment, &selector);
    if(segment == NULL)
    {
        printf("Error: Malloc DOS memory error !\n");
        return FALSE;
    }
    memset(&RMI, 0, sizeof(RMI));
    RMI.EAX = VESA_FUNC + VESA_VGA_INFO;
    RMI.ES  = segment;
    RMI.EDI = 0;
    DpmiRealInt386x(0x10,  &RMI);
    if(RMI.EAX == VESA_SUCCESS)
    {
        vesalist = (unsigned char *)(segment<<4);
        memcpy(&HardWareInfo, vesalist, 256);
        if(strncmp((char*)HardWareInfo.VESASignature, "VESA", 4) == 0)
        {
            unsigned char *OEMStr, *VideoPtr;
            OEMStr = (unsigned char *)((unsigned long)(HardWareInfo.OEMStringSeg<<4)
                                      +HardWareInfo.OEMStringOff);
            VideoPtr = (unsigned char *)((unsigned long)(HardWareInfo.VideoModePtrSeg<<4)
                                      +HardWareInfo.VideoModePtrOff);
            DpmiRealFree(selector);
            if( VESA_VERSION_MAJOR(HardWareInfo.VESAVersion) < 2)
            {
                printf("Error: Requirement VESA V2.0 !!!\n");
                return FALSE;
            }
            return TRUE;
        }
        printf("Error: VESA ID not found !\n");
        return FALSE;
}
    DpmiRealFree(selector);
    printf("Error: INT 10h 4F00 Call failed !\n");
    return FALSE;
}

char GetVesaModeInfo(unsigned short mode)           // 取VESA显示卡指定模式信息
{
    unsigned short segment, selector;
    unsigned char *vesalist;
    DpmiRealMalloc(0x0010, &segment, &selector);
    if(segment == NULL)
    {
        printf("Error: Malloc DOS memory error !\n");
        return FALSE;
    }
    memset(&RMI, 0, sizeof(RMI));
    RMI.EAX = VESA_FUNC + VESA_MODE_INFO;
    RMI.ES  = segment;
    RMI.ECX = mode;
    RMI.EDI = 0;
    DpmiRealInt386x(0x10,  &RMI);
    if(RMI.EAX == VESA_SUCCESS)
    {
        vesalist = (unsigned char *)(segment<<4);
        memcpy(&VesaModeInfo, vesalist, 256);
        if((VesaModeInfo.ModeAttributes & MODE_SUPPORTED) == 1)
        {
            VideoPhysBasePtr = VesaModeInfo.PhysBasePtr;
            DpmiRealFree(selector);
            return TRUE;
        }
        printf("Error: VESA %xh Mode no supported !\n", mode);
        return FALSE;
}
    DpmiRealFree(selector);
    printf("Error: INT 10h 4F01 Call failed !\n");
    return FALSE;
}

char vesa_2l_init(short mode)                       // 初始化显示卡
{
    if(GetVesaInfo()==TRUE)
    {
      if(GetVesaModeInfo(mode)==TRUE)
      {
        if(SetVesaMode(mode)==FALSE)
        {   grp_exit();
            printf("Error: VESA %xh Mode set Error !\n", mode);
            return FALSE;
        }
      }
      else
      {grp_exit();
        printf("Error: Get VESA %xh mode Information Error !\n", mode);
        return FALSE;
      }
      screen->w=VesaModeInfo.XResolution;
      screen->h=VesaModeInfo.YResolution;
      _Display=create_bitmap(screen->w,screen->h);
      delete []_Display->dat;
      _Display->dat=(unsigned char *)DPMIPhysicalAddr(VideoPhysBasePtr,
                       VesaModeInfo.XResolution*VesaModeInfo.YResolution);
      _Display->line[0]=_Display->dat;
      for(int i=1;i<screen->h;i++)
      _Display->line[i]=_Display->line[i-1]+screen->w;
      return TRUE;
    }
    return FALSE;
}

char SetVesaMode(short mode)      // 设置显示模式
{
    union REGS regs;

    memset(&regs, 0, sizeof(regs));
    regs.x.eax = VESA_FUNC+VESA_SET_MODE;               
    regs.x.ebx = mode;
    regs.x.ebx |= 0xc000;      // VESA 2.0 新定义了bit14
    int386 (0x10, &regs, &regs);
    if(regs.w.ax == VESA_SUCCESS){
    return TRUE;
     }
    else
    {
        printf("Error: Set VESA Mode: %x\n",  mode);
        return FALSE;
    }
}

unsigned short GetVesaMode(void)       // 取当前的显示模式
{
    union REGS regs;

    memset(&regs, 0, sizeof(regs));
    regs.x.eax = VESA_FUNC+VESA_GET_MODE;               
    int386 (0x10, &regs, &regs);       
    return (regs.w.bx&0xfff);
}

void setwritemode(char mode)
{if(mode){screen=_Display;screen_write=0;}
 else
 if(_Screen!=NULL)
 {screen=_Screen;screen_write=1;}
}

/* 真正的显卡初始化
 mode  显示模式,在vesa.h中有定义
*/
char grp_init(int mode)
{
 LineWriteMode.StyLine=0xff;//画线模式
  if(mode>=0x100)
   { if(vesa_2l_init(mode)==FALSE){
      grp_exit();
      printf("Error: Can't Set VESA Liner Mode: %x\n",  mode);
      exit(0);
      }
      }
     else
     {union REGS r;
      r.w.ax=mode;
      int386(0x10,&r,&r);
      screen->w=320;
      screen->h=200;
      _Display=create_bitmap(320,200);
      delete [] _Display->dat;
      _Display->dat=(unsigned char *)0xa0000;
      _Display->line[0]=_Display->dat;
      for(unsigned char i=1;i<200;i++)
      _Display->line[i]=_Display->line[i-1]+320;
      screen_videomem=64000;
      }
      screen_videomem=screen->w*screen->h;
//      _Screen=create_bitmap(screen->w,screen->h);
      timer_init();
      setwritemode(TRUE);
      clear(screen);
      grp_mem_lock(screen->dat,screen_videomem);
      atexit(grp_exit);
return TRUE;
}

//退出图形模式
void grp_exit()
{  grp_mem_unlock(screen->dat,screen_videomem);
    union REGS r;
     r.w.ax=3;
     int386(0x10,&r,&r);
if(_Screen->dat!=NULL)destroy_bitmap(_Screen);
}

void Disappear(int time)
{    register int i,j,k;
     unsigned char Source[256][3];
     for(j=0;j<3;j++)
     for(i=0;i<256;i++)
        Source[i][j]=ColorTable[i][j];
        for(j=0;j<64;j++)
        {delay(time);
        for(i=0;i<256;i++)
        {
        outp(0x3c8,i);
        for(k=0;k<3;k++)
        {if(Source[i][k]>0)Source[i][k]--;
        outp(0x3c9,Source[i][k]);
        }
}
}
}
//渐显
void Appear(int time)
{    register int i,j,k;
     unsigned char Source[256][3];
     for(i=0;i<3;i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -