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

📄 svgac.c

📁 VESA 图形编程的汇编子程序库
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                          SuperVGA Test Library
*
*                   Copyright (C) 1993 SciTech Software
*                           All rights reserved.
*
* Filename:     $RCSfile: svgac.c $
* Version:      $Revision: 1.3 $
*
* Language:     ANSI C
* Environment:  IBM PC (MSDOS)
*
* Description:  Simple library to collect together the functions in the
*               SuperVGA test library for use in other C programs. The
*               support is reasonably low level, so you can do what you
*               want. The set of routines in this source file are general
*               SuperVGA routines and are independant of the video mode
*               selected.
*
*               MUST be compiled in the large model.
*
* $Id: svgac.c 1.3 1993/10/22 08:58:40 kjb release $
*
****************************************************************************/

#include <string.h>
#include <dos.h>
#include <stdlib.h>
#include "svga.h"
#include "vesavbe.h"

/*---------------------------- Global Variables ---------------------------*/

#define MAXMODES    50              /* Maximum modes available in list  */

int     maxx,maxy,memory;
long	maxcolor,defcolor;
int     maxpage,bytesperline;
uchar	redMask,greenMask,blueMask;
int		redPos,redAdjust;
int		greenPos,greenAdjust;
int		bluePos,blueAdjust;
bool    twobanks = false,extendedflipping = false,widedac = false;
short   modeList[MAXMODES];
char    OEMString[80];

int     oldMode;                    /* Old video mode number            */
bool    old50Lines;                 /* Was old mode 80x50?              */
int     curBank;                    /* Current read/write bank          */
int     bankAdjust;                 /* Bank granularity adjust factor   */
long    pagesize;                   /* Page size for current mode       */
void    *bankSwitch;                /* Pointer to bank switch routine   */
void    *writeBank;                 /* Relocated write bank routine     */
void    *readBank;                  /* Relocated read bank routine      */
void    *pageFlip;                  /* Relocated page flip routine      */
void 	(*putPixel)(int x,int y,long color);
void 	(*clear)(void);

/*----------------------------- Implementation ----------------------------*/

/* Declare all video mode dependent routines */

void _putPixel16(int x,int y,long color);
void _putPixel256(int x,int y,long color);
void _putPixel32k(int x,int y,long color);
void _putPixel64k(int x,int y,long color);
void _putPixel16m(int x,int y,long color);
void _clear16(void);
void _clear256(void);
void _clear32k(void);
void _clear64k(void);
void _clear16m(void);

PRIVATE bool checkVESAPageFlip(void)
/****************************************************************************
*
* Function:     checkVESAPageFlip
* Returns:      True if VBE supports page flipping.
*
* Description:  Determines if the VESA VBE supports extended page
*               flipping or not. Assume a suitable video mode has already
*               been initialised.
*
****************************************************************************/
{
    union REGS  regs;

    regs.x.ax = 0x4F07;         /* Set display start service            */
    regs.x.bx = 0;              /* BH := 0, BL := 0 (set display start) */
    regs.x.cx = 0;              /* Leftmost pixel in line               */
    regs.x.dx = 0;              /* First displayed scanline             */
    int86(0x10,&regs,&regs);
    if (regs.x.ax != 0x004F)
        return false;           /* Function failed, not page flip       */

    regs.x.ax = 0x4F07;         /* Get display start service            */
    regs.x.bx = 1;              /* BH := 0, BL := 1 (get display start) */
    int86(0x10,&regs,&regs);
    if (regs.x.ax != 0x004F)
        return false;           /* Function failed, not page flip       */
    if (regs.h.bh != 0)
        return false;
    if (regs.x.cx != 0)
        return false;
    if (regs.x.dx != 0)
        return false;
    return true;
}

bool checkWideDAC(void)
/****************************************************************************
*
* Function:     checkWideDAC
* Returns:      True if 8 bit wide DAC is supported.
*
* Description:  Tests to see if the VBE BIOS supports an 8 bit wide
*               DAC. This assumes the video card is in an appropriate
*               video mode before being called.
*
****************************************************************************/
{
    union REGS  regs;
    short       bits;

    regs.x.ax = 0x4F08;         /* Set DAC service                      */
    regs.x.bx = 0x0800;         /* BH := 8, BL := 0 (set DAC width)     */
    int86(0x10,&regs,&regs);
    if (regs.x.ax != 0x004F)
        return false;           /* Function failed, no wide dac         */
    if (regs.h.bh == 6)
        return false;
    regs.x.ax = 0x4F08;
    regs.x.bx = 0x0001;         /* Get DAC width (should now be 8)      */
    int86(0x10,&regs,&regs);
    if (regs.x.ax != 0x004F)
        return false;
    bits = regs.h.bh;
    regs.x.ax = 0x4F08;
    regs.x.bx = 0x0600;
    int86(0x10,&regs,&regs);    /* Restore to 6 bit DAC                 */
    if (regs.x.ax != 0x004F)
        return false;

    return (bits == 8);
}

PUBLIC int initSuperVGA(void)
/****************************************************************************
*
* Function:     initSuperVGA
* Returns:      VBE version number for the SuperVGA (0 if no SuperVGA).
*
* Description:  Detects if a VESA VBE compliant SuperVGA is out there, and
*               initialises the library if one is. The VBE version number
*               is specified with the major version number in the high
*               byte and the minor version number in the low byte. So
*               version 1.2 is the number 0x102.
*
****************************************************************************/
{
    VgaInfoBlock    vgaInfo;
    ModeInfoBlock   modeInfo;
    union REGS      regs;
    struct SREGS    sregs;
    short           *p,i;

    sregs.es = SEG(&vgaInfo);
    regs.x.di = OFF(&vgaInfo);
    regs.x.ax = 0x4F00;
    int86x(0x10,&regs,&regs,&sregs);    /* Get SuperVGA information     */
    if (regs.x.ax != 0x004F)
        return false;
    if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0)
        return false;

    /* Copy relavent information from the mode block into our globals.
     * Note that the video mode list _may_ be built in the information
     * block that we have passed, so we _must_ copy this from here
     * into our our storage if we want to continue to use it. Note
     * that we filter out the mode 0x6A, which some BIOSes include as
     * well as the 0x102 mode for 800x600x16.
     */

    for (i = 0,p = vgaInfo.VideoModePtr; *p != -1; p++,i++) {
        if (*p != 0x6A)
            modeList[i] = *p;
        }
    modeList[i] = -1;
    memory = vgaInfo.TotalMemory * 64;
    strcpy(OEMString,vgaInfo.OEMStringPtr);

    /* Determine if the board supports separate read/write banks and
     * extended page flipping. Some VESA VBE's require the card to be
     * in a graphics mode for these tests to work, so we find a suitable
     * mode and use that.
     */

    for (p = modeList; *p != -1; p++) {
        sregs.es = SEG(&modeInfo);
        regs.x.di = OFF(&modeInfo);
        regs.x.ax = 0x4F01;
        regs.x.cx = *p;
        int86x(0x10,&regs,&regs,&sregs);    /* Get SuperVGA mode info   */
		if (regs.x.ax == 0x004F &&
				(modeInfo.MemoryModel == 3 || modeInfo.MemoryModel == 4)) {
            modeInfo.WinBAttributes &= 0x7;
            twobanks = (modeInfo.WinBAttributes == 0x3);
            setSuperVGAMode(*p);
            extendedflipping = checkVESAPageFlip();
            widedac = checkWideDAC();
            restoreMode();
            break;
            }
        }

    return vgaInfo.VESAVersion;
}

PRIVATE void computePageInfo(ModeInfoBlock *modeInfo,int *maxpage,
    long *pagesize)
/****************************************************************************
*
* Function:     computePageInfo
* Parameters:   modeInfo    - Pointer to valid mode information block
*               maxpage     - Number of display pages - 1
*               pagesize    - Size of each logical display page in bytes
*
* Description:  Computes the number of image pages and size of each image
*               page for a specified video mode.
*
****************************************************************************/
{
    long    memsize,size;

    if (extendedflipping)
        memsize = memory * 1024L;
    else
        memsize = 256 * 1024L;      /* Use only 256k to compute pages   */

    size = (long)modeInfo->BytesPerScanLine * (long)modeInfo->YResolution;
    if (modeInfo->BitsPerPixel == 4) {
        /* We have a 16 color video mode, so round up the page size to
         * 8k, 16k, 32k or 64k boundaries depending on how large it is.
         */

        size = (size + 0x1FFFL) & 0xFFFFE000L;
        if (size != 0x2000) {
            size = (size + 0x3FFFL) & 0xFFFFC000L;
            if (size != 0x4000) {
                size = (size + 0x7FFFL) & 0xFFFF8000L;
                if (size != 0x8000)
                    size = (size + 0xFFFFL) & 0xFFFF0000L;
                }
            }
        }
    else
        size = (size + 0xFFFFL) & 0xFFFF0000L;

    if (modeInfo->MemoryModel == memPL)
        memsize /= 4;
    if (size <= memsize)
        *maxpage = (memsize / size) - 1;
    else
        *maxpage = 0;
    *pagesize = size;
}

PUBLIC bool getSuperVGAModeInfo(int mode,int *xres,int *yres,
    int *bytesperline,int *bitsperpixel,int *memmodel,int *maxpage,
    long *pagesize)
/****************************************************************************
*
* Function:     getSuperVGAModeInfo
* Parameters:   mode            - Mode to get information about
*               xres            - Place to store x resolution
*               yres            - Place to store y resolution
*               bytesperline    - Bytes per scanline
*               bitsperpixel    - Place to store bits per pixel (2^n colors)
*               memmodel        - Memory model for mode (planar, packed etc)
*               maxpage         - Number of display pages - 1
*               pagesize        - Size of each logical display page in bytes
* Returns:      True if mode number was valid, false if not.
*
* Description:  Obtains information about a specific video mode from the
*               VBE. You should use this function to find the video mode
*               you wish to set, as the new VBE 2.0 mode numbers may be
*               completely arbitrary.
*
****************************************************************************/
{
    ModeInfoBlock   modeInfo;
    union REGS      regs;
    struct SREGS    sregs;

    if (mode <= 0x13) {
        /* This is a standard VGA mode, so fill in the required information
         * ourselves.
         */

        switch (mode) {
            case 0x0D:
                modeInfo.XResolution = 320;
                modeInfo.YResolution = 200;
                modeInfo.BytesPerScanLine = 40;
                modeInfo.BitsPerPixel = 4;
                modeInfo.MemoryModel = memPL;
                break;
            case 0x0E:
                modeInfo.XResolution = 640;
                modeInfo.YResolution = 200;
                modeInfo.BytesPerScanLine = 80;
                modeInfo.BitsPerPixel = 4;
                modeInfo.MemoryModel = memPL;
                break;
            case 0x10:
                modeInfo.XResolution = 640;
                modeInfo.YResolution = 350;
                modeInfo.BytesPerScanLine = 80;
                modeInfo.BitsPerPixel = 4;
                modeInfo.MemoryModel = memPL;
                break;
            case 0x12:
                modeInfo.XResolution = 640;
                modeInfo.YResolution = 480;
                modeInfo.BytesPerScanLine = 80;
                modeInfo.BitsPerPixel = 4;
                modeInfo.MemoryModel = memPL;
                break;
            case 0x13:
                modeInfo.XResolution = 320;
                modeInfo.YResolution = 200;
                modeInfo.BytesPerScanLine = 320;
                modeInfo.BitsPerPixel = 8;
                modeInfo.MemoryModel = memPK;
                break;
            default:
                return false;
            }
        }
    else {
        /* This is a VESA mode, so call the BIOS to get information about
         * it.
         */

        sregs.es = SEG(&modeInfo);
        regs.x.di = OFF(&modeInfo);
        regs.x.ax = 0x4F01;
        regs.x.cx = mode;
        int86x(0x10,&regs,&regs,&sregs);    /* Get mode information         */
		if (regs.x.ax != 0x004F)
			return false;
		if ((modeInfo.ModeAttributes & 0x1) == 0)
			return false;
		}
	*xres = modeInfo.XResolution;
	*yres = modeInfo.YResolution;
	*bytesperline = modeInfo.BytesPerScanLine;
	*memmodel = modeInfo.MemoryModel;
	*bitsperpixel = modeInfo.BitsPerPixel;
	if (*memmodel == memPK && *bitsperpixel > 8) {
		/* Support old style definitions, which some BIOS'es still use :-( */
		*memmodel = memRGB;
		switch (*bitsperpixel) {
			case 15:
				redMask = 0x1F;		redPos = 10;	redAdjust = 3;
				greenMask = 0x1F;	greenPos = 5;	greenAdjust = 3;

⌨️ 快捷键说明

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