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

📄 tl_vesa.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
字号:
/*** thinlib (c) 2000 Matthew Conte (matt@conte.com)****** This program is free software; you can redistribute it and/or** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation.**** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU ** Library General Public License for more details.  To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.**** Any permitted reproduction of these routines, in whole or in part,** must bear this legend.****** tl_vesa.c**** VESA code.** $Id: tl_vesa.c,v 1.8 2001/03/12 06:06:55 matt Exp $*/#include <stdio.h>#include <string.h>#include <assert.h>#include <go32.h>#include <dos.h>#include <dpmi.h>#include "tl_types.h"#include "tl_log.h"#include "tl_bmp.h"#include "tl_djgpp.h"#include "tl_vga.h"#include "tl_vesa.h"#define  __PACKED__  __attribute__ ((packed))/* VESA information block structure */typedef struct vesainfo_s{   char   VESASignature[4]    __PACKED__;   uint16 VESAVersion         __PACKED__;   uint32 OEMStringPtr        __PACKED__;   char   Capabilities[4]     __PACKED__;   uint32 VideoModePtr        __PACKED__;    uint16 TotalMemory         __PACKED__;    uint16 OemSoftwareRev      __PACKED__;    uint32 OemVendorNamePtr    __PACKED__;    uint32 OemProductNamePtr   __PACKED__;    uint32 OemProductRevPtr    __PACKED__;    uint8  Reserved[222]       __PACKED__;    char   OemData[256]        __PACKED__; } vesainfo_t;/* SuperVGA mode information block */typedef struct modeinfo_s{   uint16 ModeAttributes      __PACKED__;    uint8  WinAAttributes      __PACKED__;    uint8  WinBAttributes      __PACKED__;    uint16 WinGranularity      __PACKED__;    uint16 WinSize             __PACKED__;    uint16 WinASegment         __PACKED__;    uint16 WinBSegment         __PACKED__;    uint32 WinFuncPtr          __PACKED__;    uint16 BytesPerScanLine    __PACKED__;    uint16 XResolution         __PACKED__;    uint16 YResolution         __PACKED__;    uint8  XCharSize           __PACKED__;    uint8  YCharSize           __PACKED__;    uint8  NumberOfPlanes      __PACKED__;    uint8  BitsPerPixel        __PACKED__;    uint8  NumberOfBanks       __PACKED__;    uint8  MemoryModel         __PACKED__;    uint8  BankSize            __PACKED__;    uint8  NumberOfImagePages  __PACKED__;   uint8  Reserved_page       __PACKED__;    uint8  RedMaskSize         __PACKED__;    uint8  RedMaskPos          __PACKED__;    uint8  GreenMaskSize       __PACKED__;    uint8  GreenMaskPos        __PACKED__;   uint8  BlueMaskSize        __PACKED__;    uint8  BlueMaskPos         __PACKED__;    uint8  ReservedMaskSize    __PACKED__;    uint8  ReservedMaskPos     __PACKED__;    uint8  DirectColorModeInfo __PACKED__;   /* VBE 2.0 extensions */   uint32 PhysBasePtr         __PACKED__;    uint32 OffScreenMemOffset  __PACKED__;    uint16 OffScreenMemSize    __PACKED__;    /* VBE 3.0 extensions */   uint16 LinBytesPerScanLine __PACKED__;   uint8  BnkNumberOfPages    __PACKED__;   uint8  LinNumberOfPages    __PACKED__;   uint8  LinRedMaskSize      __PACKED__;   uint8  LinRedFieldPos      __PACKED__;   uint8  LinGreenMaskSize    __PACKED__;   uint8  LinGreenFieldPos    __PACKED__;   uint8  LinBlueMaskSize     __PACKED__;   uint8  LinBlueFieldPos     __PACKED__;   uint8  LinRsvdMaskSize     __PACKED__;   uint8  LinRsvdFieldPos     __PACKED__;   uint32 MaxPixelClock       __PACKED__;   uint8  Reserved[190]       __PACKED__; } modeinfo_t;#define  MASK_LINEAR(addr)    (addr & 0x000FFFFF)#define  RM_TO_LINEAR(addr)   (((addr & 0xFFFF0000) >> 12) + (addr & 0xFFFF))#define  RM_OFFSET(addr)      (addr & 0xF)#define  RM_SEGMENT(addr)     ((addr >> 4) & 0xFFFF)#define  VBE_LINEAR_ADDR      0x4000#define  VBE_LINEAR_AVAIL     0x0080#define  VBE_INT              0x10#define  VBE_SUCCESS          0x004F#define  VBE_FUNC_DETECT      0x4F00#define  VBE_FUNC_GETMODEINFO 0x4F01#define  VBE_FUNC_SETMODE     0x4F02#define  VBE_FUNC_GETMODE     0x4F03#define  VBE_FUNC_FLIPPAGE    0x4F07#define  VBE_MAX_NUM_MODES    1024  /* liberal */static struct{   uint32 address;   int width, height;   int bpp;} cur_mode;static vesainfo_t vesa_info;static bitmap_t *screen = NULL;static bitmap_t *hardware = NULL;/* look for vesa */static int vesa_detect(vesainfo_t *vesainfo){   __dpmi_regs regs;   /* Use DOS transfer buffer to hold VBE info */   THIN_ASSERT(sizeof(*vesainfo) < _go32_info_block.size_of_transfer_buffer);   memset(&regs, 0, sizeof(regs));   strncpy(vesainfo->VESASignature, "VBE2", 4);   dosmemput(vesainfo, sizeof(*vesainfo), MASK_LINEAR(__tb));   regs.x.ax = VBE_FUNC_DETECT;   regs.x.di = RM_OFFSET(__tb);   regs.x.es = RM_SEGMENT(__tb);   __dpmi_int(VBE_INT, &regs);   if (VBE_SUCCESS != regs.x.ax)      return -1;   dosmemget(MASK_LINEAR(__tb), sizeof(*vesainfo), vesainfo);   if (strncmp(vesainfo->VESASignature, "VESA", 4) != 0)      return -1;   return 0;}static int vesa_getmodeinfo(uint16 mode, modeinfo_t *modeinfo){   __dpmi_regs regs;   THIN_ASSERT(sizeof(*modeinfo) < _go32_info_block.size_of_transfer_buffer);   memset(&regs, 0, sizeof(regs));   regs.x.ax = VBE_FUNC_GETMODEINFO;    regs.x.cx = mode;   regs.x.di = RM_OFFSET(__tb);   regs.x.es = RM_SEGMENT(__tb);     __dpmi_int(VBE_INT, &regs);   if (VBE_SUCCESS != regs.x.ax)      return -1;   dosmemget(MASK_LINEAR(__tb), sizeof(*modeinfo), modeinfo);   return 0;}static uint16 vesa_findmode(vesainfo_t *vesainfo, int width, int height, int bpp){   modeinfo_t mode_info;   uint16 modes[VBE_MAX_NUM_MODES], mode;   int i, mode_total = 0;   long list_ptr;      list_ptr = RM_TO_LINEAR(vesainfo->VideoModePtr);   while (mode_total < VBE_MAX_NUM_MODES)   {      dosmemget(list_ptr, 2, &mode);      if (0xFFFF == mode)         break;      modes[mode_total++] = mode;      list_ptr += 2;   }   /* VESA card on steroids? */   THIN_ASSERT(mode_total < VBE_MAX_NUM_MODES);   for (i = 0; i < mode_total; i++)   {      mode = modes[i];      if (vesa_getmodeinfo(mode, &mode_info))         return -1; /* we are definitely screwed */            if (mode_info.XResolution == width           && mode_info.YResolution == height           && mode_info.BitsPerPixel == bpp)         return mode;   }   return 0;}short int vid_selector = -1;static int vesa_setmodenum(uint16 mode){   __dpmi_regs regs;   __dpmi_meminfo mi;   modeinfo_t mode_info;   if (vesa_getmodeinfo(mode, &mode_info))      return -1;   mi.size = mode_info.BytesPerScanLine * mode_info.YResolution;   mi.address = mode_info.PhysBasePtr;   if (-1 == __dpmi_physical_address_mapping(&mi))      return -1;   if (0 == thinlib_nearptr)   {      vid_selector = __dpmi_allocate_ldt_descriptors(1);      if (-1 == vid_selector)         return -1;      /* paranoid */      if (-1 == __dpmi_set_descriptor_access_rights(vid_selector, 0x40f3))         return -1;      if (-1 == __dpmi_set_segment_base_address(vid_selector, mi.address))         return -1;      if (-1 == __dpmi_set_segment_limit(vid_selector, vesa_info.TotalMemory << 16 | 0xfff))         return -1;   }   memset(&regs, 0, sizeof(regs));   regs.x.ax = VBE_FUNC_SETMODE;   regs.x.bx = mode | VBE_LINEAR_ADDR;    __dpmi_int(VBE_INT, &regs);   if (VBE_SUCCESS != regs.x.ax)      return -1;   if (0 == thinlib_nearptr)      cur_mode.address = 0;   else      cur_mode.address = mi.address;   cur_mode.width = mode_info.XResolution;   cur_mode.height = mode_info.YResolution;   cur_mode.bpp = mode_info.BitsPerPixel;   if (NULL != screen)      thin_bmp_destroy(&screen);   if (thinlib_nearptr)   {      screen = thin_bmp_createhw((uint8 *) THIN_PHYS_ADDR(cur_mode.address),                                 cur_mode.width, cur_mode.height, cur_mode.bpp,                                 cur_mode.width);      if (NULL == screen)         return -1;   }   else   {      if (NULL != hardware)         thin_bmp_destroy(&hardware);      hardware = thin_bmp_createhw((uint8 *) cur_mode.address,                                    cur_mode.width, cur_mode.height, cur_mode.bpp,                                   cur_mode.width);      if (NULL == hardware)         return -1;      screen = thin_bmp_create(cur_mode.width, cur_mode.height, cur_mode.bpp, 0);      if (NULL == screen)         return -1;   }   return 0;}void thin_vesa_shutdown(void){   __dpmi_regs regs;   memset(&regs, 0, sizeof(regs));   regs.x.ax = 0x0003;   __dpmi_int(VBE_INT, &regs);   thin_bmp_destroy(&screen);   if (0 == thinlib_nearptr)      thin_bmp_destroy(&hardware);}int thin_vesa_setmode(int width, int height, int bpp){   uint16 mode;   mode = vesa_findmode(&vesa_info, width, height, bpp);   if (0 == mode)      return -1;   return vesa_setmodenum(mode);}int thin_vesa_init(int width, int height, int bpp){   memset(&vesa_info, 0, sizeof(vesa_info));   screen = NULL;   hardware = NULL;      if (vesa_detect(&vesa_info))      return -1;   /* check to see if linear framebuffer is available */   if ((vesa_info.VESAVersion >> 8) < 2)   {      thin_printf("thin@vesa: no linear framebuffer available\n");      return -1;   }   return thin_vesa_setmode(width, height, bpp);}bitmap_t *thin_vesa_lockwrite(void){   return screen;}void thin_vesa_freewrite(int num_dirties, rect_t *dirty_rects){   UNUSED(num_dirties);   UNUSED(dirty_rects);   if (0 == thinlib_nearptr)   {      movedata(_my_ds(), (unsigned) screen->line[0],               vid_selector, (unsigned) hardware->line[0],               hardware->pitch * hardware->height);   }}/*** $Log: tl_vesa.c,v $** Revision 1.8  2001/03/12 06:06:55  matt** better keyboard driver, support for bit depths other than 8bpp**** Revision 1.7  2001/02/01 06:28:26  matt** thinlib now works under NT/2000**** Revision 1.6  2001/01/15 05:25:52  matt** i hate near pointers**** Revision 1.5  2000/12/14 14:10:32  matt** cleaner initialization**** Revision 1.4  2000/11/25 20:28:34  matt** moved verboseness into correct places**** Revision 1.3  2000/11/06 02:22:33  matt** generalized video driver (tl_video.c)**** Revision 1.2  2000/11/05 16:32:36  matt** thinlib round 2**** Revision 1.1  2000/11/05 06:29:03  matt** initial revision***/

⌨️ 快捷键说明

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