diff options
Diffstat (limited to 'roms/vgabios/tests')
| -rw-r--r-- | roms/vgabios/tests/lfbprof/Makefile | 5 | ||||
| -rw-r--r-- | roms/vgabios/tests/lfbprof/lfbprof.c | 594 | ||||
| -rw-r--r-- | roms/vgabios/tests/lfbprof/lfbprof.h | 149 | ||||
| -rw-r--r-- | roms/vgabios/tests/testbios.c | 353 | 
4 files changed, 1101 insertions, 0 deletions
diff --git a/roms/vgabios/tests/lfbprof/Makefile b/roms/vgabios/tests/lfbprof/Makefile new file mode 100644 index 00000000..7c42e38b --- /dev/null +++ b/roms/vgabios/tests/lfbprof/Makefile @@ -0,0 +1,5 @@ +# Very simple makefile for LFBPROF.C using Watcom C++ 10.0a with DOS4GW + +lfbprof.exe: lfbprof.c lfbprof.h +    wcl386 -zq -s -d2 lfbprof.c + diff --git a/roms/vgabios/tests/lfbprof/lfbprof.c b/roms/vgabios/tests/lfbprof/lfbprof.c new file mode 100644 index 00000000..df37452e --- /dev/null +++ b/roms/vgabios/tests/lfbprof/lfbprof.c @@ -0,0 +1,594 @@ +/**************************************************************************** +* +*                   VBE 2.0 Linear Framebuffer Profiler +*                    By Kendall Bennett and Brian Hook +* +* Filename:     LFBPROF.C +* Language:     ANSI C +* Environment:  Watcom C/C++ 10.0a with DOS4GW +* +* Description:  Simple program to profile the speed of screen clearing +*               and full screen BitBlt operations using a VESA VBE 2.0 +*               linear framebuffer from 32 bit protected mode. +* +*               For simplicity, this program only supports 256 color +*               SuperVGA video modes that support a linear framebuffer. +* +* +* 2002/02/18: Jeroen Janssen <japj at xs4all dot nl> +*               - fixed unsigned short for mode list (-1 != 0xffff otherwise) +*               - fixed LfbMapRealPointer macro mask problem (some modes were skipped) +* +****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <conio.h> +#include <dos.h> +#include "lfbprof.h" + +/*---------------------------- Global Variables ---------------------------*/ + +int     VESABuf_len = 1024;         /* Length of VESABuf                */ +int     VESABuf_sel = 0;            /* Selector for VESABuf             */ +int     VESABuf_rseg;               /* Real mode segment of VESABuf     */ +unsigned short   modeList[50];      /* List of available VBE modes      */ +float   clearsPerSec;               /* Number of clears per second      */ +float   clearsMbPerSec;             /* Memory transfer for clears       */ +float   bitBltsPerSec;              /* Number of BitBlt's per second    */ +float   bitBltsMbPerSec;            /* Memory transfer for bitblt's     */ +int     xres,yres;                  /* Video mode resolution            */ +int     bytesperline;               /* Bytes per scanline for mode      */ +long    imageSize;                  /* Length of the video image        */ +char    *LFBPtr;                	/* Pointer to linear framebuffer    */ + +/*------------------------- DPMI interface routines -----------------------*/ + +void DPMI_allocRealSeg(int size,int *sel,int *r_seg) +/**************************************************************************** +* +* Function:     DPMI_allocRealSeg +* Parameters:   size    - Size of memory block to allocate +*               sel     - Place to return protected mode selector +*               r_seg   - Place to return real mode segment +* +* Description:  Allocates a block of real mode memory using DPMI services. +*               This routine returns both a protected mode selector and +*               real mode segment for accessing the memory block. +* +****************************************************************************/ +{ +    union REGS      r; + +    r.w.ax = 0x100;                 /* DPMI allocate DOS memory         */ +    r.w.bx = (size + 0xF) >> 4;     /* number of paragraphs             */ +    int386(0x31, &r, &r); +    if (r.w.cflag) +        FatalError("DPMI_allocRealSeg failed!"); +    *sel = r.w.dx;                  /* Protected mode selector          */ +    *r_seg = r.w.ax;                /* Real mode segment                */ +} + +void DPMI_freeRealSeg(unsigned sel) +/**************************************************************************** +* +* Function:     DPMI_allocRealSeg +* Parameters:   sel - Protected mode selector of block to free +* +* Description:  Frees a block of real mode memory. +* +****************************************************************************/ +{ +    union REGS  r; + +    r.w.ax = 0x101;                 /* DPMI free DOS memory             */ +    r.w.dx = sel;                   /* DX := selector from 0x100        */ +    int386(0x31, &r, &r); +} + +typedef struct { +    long    edi; +    long    esi; +    long    ebp; +    long    reserved; +    long    ebx; +    long    edx; +    long    ecx; +    long    eax; +    short   flags; +    short   es,ds,fs,gs,ip,cs,sp,ss; +    } _RMREGS; + +#define IN(reg)     rmregs.e##reg = in->x.reg +#define OUT(reg)    out->x.reg = rmregs.e##reg + +int DPMI_int86(int intno, RMREGS *in, RMREGS *out) +/**************************************************************************** +* +* Function:     DPMI_int86 +* Parameters:   intno   - Interrupt number to issue +*               in      - Pointer to structure for input registers +*               out     - Pointer to structure for output registers +* Returns:      Value returned by interrupt in AX +* +* Description:  Issues a real mode interrupt using DPMI services. +* +****************************************************************************/ +{ +    _RMREGS         rmregs; +    union REGS      r; +    struct SREGS    sr; + +    memset(&rmregs, 0, sizeof(rmregs)); +    IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); + +    segread(&sr); +    r.w.ax = 0x300;                 /* DPMI issue real interrupt        */ +    r.h.bl = intno; +    r.h.bh = 0; +    r.w.cx = 0; +    sr.es = sr.ds; +    r.x.edi = (unsigned)&rmregs; +    int386x(0x31, &r, &r, &sr);     /* Issue the interrupt              */ + +    OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); +    out->x.cflag = rmregs.flags & 0x1; +    return out->x.ax; +} + +int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs) +/**************************************************************************** +* +* Function:     DPMI_int86 +* Parameters:   intno   - Interrupt number to issue +*               in      - Pointer to structure for input registers +*               out     - Pointer to structure for output registers +*               sregs   - Values to load into segment registers +* Returns:      Value returned by interrupt in AX +* +* Description:  Issues a real mode interrupt using DPMI services. +* +****************************************************************************/ +{ +    _RMREGS         rmregs; +    union REGS      r; +    struct SREGS    sr; + +    memset(&rmregs, 0, sizeof(rmregs)); +    IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); +    rmregs.es = sregs->es; +    rmregs.ds = sregs->ds; + +    segread(&sr); +    r.w.ax = 0x300;                 /* DPMI issue real interrupt        */ +    r.h.bl = intno; +    r.h.bh = 0; +    r.w.cx = 0; +    sr.es = sr.ds; +    r.x.edi = (unsigned)&rmregs; +    int386x(0x31, &r, &r, &sr);     /* Issue the interrupt */ + +    OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); +    sregs->es = rmregs.es; +    sregs->cs = rmregs.cs; +    sregs->ss = rmregs.ss; +    sregs->ds = rmregs.ds; +    out->x.cflag = rmregs.flags & 0x1; +    return out->x.ax; +} + +int DPMI_allocSelector(void) +/**************************************************************************** +* +* Function:     DPMI_allocSelector +* Returns:      Newly allocated protected mode selector +* +* Description:  Allocates a new protected mode selector using DPMI +*               services. This selector has a base address and limit of 0. +* +****************************************************************************/ +{ +    int         sel; +    union REGS  r; + +    r.w.ax = 0;                     /* DPMI allocate selector           */ +    r.w.cx = 1;                     /* Allocate a single selector       */ +    int386(0x31, &r, &r); +    if (r.x.cflag) +        FatalError("DPMI_allocSelector() failed!"); +    sel = r.w.ax; + +    r.w.ax = 9;                     /* DPMI set access rights           */ +    r.w.bx = sel; +    r.w.cx = 0x8092;                /* 32 bit page granular             */ +    int386(0x31, &r, &r); +    return sel; +} + +long DPMI_mapPhysicalToLinear(long physAddr,long limit) +/**************************************************************************** +* +* Function:     DPMI_mapPhysicalToLinear +* Parameters:   physAddr    - Physical memory address to map +*               limit       - Length-1 of physical memory region to map +* Returns:      Starting linear address for mapped memory +* +* Description:  Maps a section of physical memory into the linear address +*               space of a process using DPMI calls. Note that this linear +*               address cannot be used directly, but must be used as the +*               base address for a selector. +* +****************************************************************************/ +{ +    union REGS  r; + +    r.w.ax = 0x800;                 /* DPMI map physical to linear      */ +    r.w.bx = physAddr >> 16; +    r.w.cx = physAddr & 0xFFFF; +    r.w.si = limit >> 16; +    r.w.di = limit & 0xFFFF; +    int386(0x31, &r, &r); +    if (r.x.cflag) +        FatalError("DPMI_mapPhysicalToLinear() failed!"); +    return ((long)r.w.bx << 16) + r.w.cx; +} + +void DPMI_setSelectorBase(int sel,long linAddr) +/**************************************************************************** +* +* Function:     DPMI_setSelectorBase +* Parameters:   sel     - Selector to change base address for +*               linAddr - Linear address used for new base address +* +* Description:  Sets the base address for the specified selector. +* +****************************************************************************/ +{ +    union REGS  r; + +    r.w.ax = 7;                     /* DPMI set selector base address   */ +    r.w.bx = sel; +    r.w.cx = linAddr >> 16; +    r.w.dx = linAddr & 0xFFFF; +    int386(0x31, &r, &r); +    if (r.x.cflag) +        FatalError("DPMI_setSelectorBase() failed!"); +} + +void DPMI_setSelectorLimit(int sel,long limit) +/**************************************************************************** +* +* Function:     DPMI_setSelectorLimit +* Parameters:   sel     - Selector to change limit for +*               limit   - Limit-1 for the selector +* +* Description:  Sets the memory limit for the specified selector. +* +****************************************************************************/ +{ +    union REGS  r; + +    r.w.ax = 8;                     /* DPMI set selector limit          */ +    r.w.bx = sel; +    r.w.cx = limit >> 16; +    r.w.dx = limit & 0xFFFF; +    int386(0x31, &r, &r); +    if (r.x.cflag) +        FatalError("DPMI_setSelectorLimit() failed!"); +} + +/*-------------------------- VBE Interface routines -----------------------*/ + +void FatalError(char *msg) +{ +    fprintf(stderr,"%s\n", msg); +    exit(1); +} + +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) +/**************************************************************************** +* +* Function:     VBE_detect +* Parameters:   vgaInfo - Place to store the VGA information block +* Returns:      VBE version number, or 0 if not detected. +* +* Description:  Detects if a VESA VBE is out there and functioning +*               correctly. If we detect a VBE interface we return the +*               VGAInfoBlock returned by the VBE and the VBE version number. +* +****************************************************************************/ +{ +    RMREGS      regs; +    unsigned    short    *p1,*p2; +    VBE_vgaInfo vgaInfo; + +    /* Put 'VBE2' into the signature area so that the VBE 2.0 BIOS knows +     * that we have passed a 512 byte extended block to it, and wish +     * the extended information to be filled in. +     */ +    strncpy(vgaInfo.VESASignature,"VBE2",4); + +    /* Get the SuperVGA Information block */ +    regs.x.ax = 0x4F00; +    VBE_callESDI(®s, &vgaInfo, sizeof(VBE_vgaInfo)); +    if (regs.x.ax != 0x004F) +        return 0; +    if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0) +        return 0; + +    /* Now that we have detected a VBE interface, copy the list of available +     * video modes into our local buffer. We *must* copy this mode list, +     * since the VBE will build the mode list in the VBE_vgaInfo buffer +     * that we have passed, so the next call to the VBE will trash the +     * list of modes. +     */ +    printf("videomodeptr %x\n",vgaInfo.VideoModePtr); +    p1 = LfbMapRealPointer(vgaInfo.VideoModePtr); +    p2 = modeList; +    while (*p1 != -1) +    { +        printf("found mode %x\n",*p1); +        *p2++ = *p1++; +    } +    *p2 = -1; +    return vgaInfo.VESAVersion; +} + +int VBE_getModeInfo(int mode,VBE_modeInfo *modeInfo) +/**************************************************************************** +* +* Function:     VBE_getModeInfo +* Parameters:   mode        - VBE mode to get information for +*               modeInfo    - Place to store VBE mode information +* Returns:      1 on success, 0 if function failed. +* +* 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. +* +****************************************************************************/ +{ +    RMREGS  regs; + +    regs.x.ax = 0x4F01;             /* Get mode information         */ +    regs.x.cx = mode; +    VBE_callESDI(®s, modeInfo, sizeof(VBE_modeInfo)); +    if (regs.x.ax != 0x004F) +        return 0; +    if ((modeInfo->ModeAttributes & vbeMdAvailable) == 0) +        return 0; +    return 1; +} + +void VBE_setVideoMode(int mode) +/**************************************************************************** +* +* Function:     VBE_setVideoMode +* Parameters:   mode    - VBE mode number to initialise +* +****************************************************************************/ +{ +    RMREGS  regs; +    regs.x.ax = 0x4F02; +    regs.x.bx = mode; +    DPMI_int86(0x10,®s,®s); +} + +/*-------------------- Application specific routines ----------------------*/ + +void *GetPtrToLFB(long physAddr) +/**************************************************************************** +* +* Function:     GetPtrToLFB +* Parameters:   physAddr    - Physical memory address of linear framebuffer +* Returns:      Far pointer to the linear framebuffer memory +* +****************************************************************************/ +{ +    int     sel; +    long    linAddr,limit = (4096 * 1024) - 1; + +//	sel = DPMI_allocSelector(); +	linAddr = DPMI_mapPhysicalToLinear(physAddr,limit); +//	DPMI_setSelectorBase(sel,linAddr); +//	DPMI_setSelectorLimit(sel,limit); +//	return MK_FP(sel,0); +	return (void*)linAddr; +} + +void AvailableModes(void) +/**************************************************************************** +* +* Function:     AvailableModes +* +* Description:  Display a list of available LFB mode resolutions. +* +****************************************************************************/ +{ +    unsigned short           *p; +    VBE_modeInfo    modeInfo; + +    printf("Usage: LFBPROF <xres> <yres>\n\n"); +    printf("Available 256 color video modes:\n"); +    for (p = modeList; *p != -1; p++) { +        if (VBE_getModeInfo(*p, &modeInfo)) { +            /* Filter out only 8 bit linear framebuffer modes */ +            if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) +                continue; +            if (modeInfo.MemoryModel != vbeMemPK +                || modeInfo.BitsPerPixel != 8 +                || modeInfo.NumberOfPlanes != 1) +                continue; +            printf("    %4d x %4d %d bits per pixel\n", +                modeInfo.XResolution, modeInfo.YResolution, +                modeInfo.BitsPerPixel); +            } +        } +    exit(1); +} + +void InitGraphics(int x,int y) +/**************************************************************************** +* +* Function:     InitGraphics +* Parameters:   x,y - Requested video mode resolution +* +* Description:  Initialise the specified video mode. We search through +*               the list of available video modes for one that matches +*               the resolution and color depth are are looking for. +* +****************************************************************************/ +{ +    unsigned short           *p; +    VBE_modeInfo    modeInfo; +    printf("InitGraphics\n"); + +    for (p = modeList; *p != -1; p++) { +        if (VBE_getModeInfo(*p, &modeInfo)) { +            /* Filter out only 8 bit linear framebuffer modes */ +            if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) +                continue; +            if (modeInfo.MemoryModel != vbeMemPK +                || modeInfo.BitsPerPixel != 8 +                || modeInfo.NumberOfPlanes != 1) +                continue; +            if (modeInfo.XResolution != x || modeInfo.YResolution != y) +                continue; +            xres = x; +            yres = y; +            bytesperline = modeInfo.BytesPerScanLine; +            imageSize = bytesperline * yres; +            VBE_setVideoMode(*p | vbeUseLFB); +            LFBPtr = GetPtrToLFB(modeInfo.PhysBasePtr); +            return; +            } +        } +    printf("Valid video mode not found\n"); +    exit(1); +} + +void EndGraphics(void) +/**************************************************************************** +* +* Function:     EndGraphics +* +* Description:  Restores text mode. +* +****************************************************************************/ +{ +    RMREGS  regs; +    printf("EndGraphics\n"); +    regs.x.ax = 0x3; +    DPMI_int86(0x10, ®s, ®s); +} + +void ProfileMode(void) +/**************************************************************************** +* +* Function:     ProfileMode +* +* Description:  Profiles framebuffer performance for simple screen clearing +*               and for copying from system memory to video memory (BitBlt). +*               This routine thrashes the CPU cache by cycling through +*               enough system memory buffers to invalidate the entire +*               CPU external cache before re-using the first memory buffer +*               again. +* +****************************************************************************/ +{ +    int     i,numClears,numBlts,maxImages; +    long    startTicks,endTicks; +    void    *image[10],*dst; +    printf("ProfileMode\n"); + +    /* Profile screen clearing operation */ +    startTicks = LfbGetTicks(); +    numClears = 0; +    while ((LfbGetTicks() - startTicks) < 182) +		LfbMemset(LFBPtr,numClears++,imageSize); +	endTicks = LfbGetTicks(); +	clearsPerSec = numClears / ((endTicks - startTicks) * 0.054925); +	clearsMbPerSec = (clearsPerSec * imageSize) / 1048576.0; + +	/* Profile system memory to video memory copies */ +	maxImages = ((512 * 1024U) / imageSize) + 2; +	for (i = 0; i < maxImages; i++) { +		image[i] = malloc(imageSize); +		if (image[i] == NULL) +			FatalError("Not enough memory to profile BitBlt!"); +		memset(image[i],i+1,imageSize); +		} +	startTicks = LfbGetTicks(); +	numBlts = 0; +	while ((LfbGetTicks() - startTicks) < 182) +		LfbMemcpy(LFBPtr,image[numBlts++ % maxImages],imageSize); +    endTicks = LfbGetTicks(); +    bitBltsPerSec = numBlts / ((endTicks - startTicks) * 0.054925); +    bitBltsMbPerSec = (bitBltsPerSec * imageSize) / 1048576.0; +} + +void main(int argc, char *argv[]) +{ +    if (VBE_detect() < 0x200) +        FatalError("This program requires VBE 2.0; Please install UniVBE 5.1."); +    if (argc != 3) +        AvailableModes();       /* Display available modes              */ + +    InitGraphics(atoi(argv[1]),atoi(argv[2]));  /* Start graphics       */ +    ProfileMode();              /* Profile the video mode               */ +    EndGraphics();              /* Restore text mode                    */ + +    printf("Profiling results for %dx%d 8 bits per pixel.\n",xres,yres); +    printf("%3.2f clears/s, %2.2f Mb/s\n", clearsPerSec, clearsMbPerSec); +    printf("%3.2f bitBlt/s, %2.2f Mb/s\n", bitBltsPerSec, bitBltsMbPerSec); +} diff --git a/roms/vgabios/tests/lfbprof/lfbprof.h b/roms/vgabios/tests/lfbprof/lfbprof.h new file mode 100644 index 00000000..bae0e09b --- /dev/null +++ b/roms/vgabios/tests/lfbprof/lfbprof.h @@ -0,0 +1,149 @@ +/**************************************************************************** +* +*                   VBE 2.0 Linear Framebuffer Profiler +*                    By Kendall Bennett and Brian Hook +* +* Filename:     LFBPROF.H +* Language:     ANSI C +* Environment:  Watcom C/C++ 10.0a with DOS4GW +* +* Description:  Header file for the LFBPROF.C progam. +* +****************************************************************************/ + +#ifndef __LFBPROF_H +#define __LFBPROF_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            */ + +/* Structures for issuing real mode interrupts with DPMI */ + +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; +    unsigned short  cs; +    unsigned short  ss; +    unsigned short  ds; +    } RMSREGS; + +/* Inline assembler block fill/move routines */ + +void LfbMemset(void *p,int c,int n); +#pragma aux LfbMemset =             \ +	"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"                  \ +	parm [edi] [ebx] [ecx]; + +void LfbMemcpy(void *dst,void *src,int n); +#pragma aux LfbMemcpy =             \ +	"shr    ecx,2"                  \ +	"rep    movsd"                  \ +	parm [edi] [esi] [ecx]; + +/* Map a real mode pointer into address space */ + +#define LfbMapRealPointer(p)    (void*)(((unsigned)((p)  & 0xFFFF0000) >> 12) + ((p) & 0xFFFF)) + +/* Get the current timer tick count */ + +#define LfbGetTicks()       *((long*)0x46C) + +#pragma pack() + +#endif  /* __LFBPROF_H */ diff --git a/roms/vgabios/tests/testbios.c b/roms/vgabios/tests/testbios.c new file mode 100644 index 00000000..99da5a65 --- /dev/null +++ b/roms/vgabios/tests/testbios.c @@ -0,0 +1,353 @@ +/* 
 +   This is a little turbo C program that executes
 +   several int10, and let you inspect the content
 +   of the vgabios area
 +
 +   It is used to test the behavior of the vgabios
 +*/
 +
 +#include <stdio.h>
 +#include <dos.h>
 +#include <conio.h>
 +
 +
 +typedef unsigned char  Bit8u;
 +typedef unsigned short Bit16u;
 +
 +typedef struct
 +{Bit8u initial;
 + Bit8u current;
 + Bit16u nbcols;
 + Bit16u regen;
 + Bit16u start;
 + Bit16u curpos[8];
 + Bit8u curtyp;
 + Bit8u curpage;
 + Bit16u crtc;
 + Bit16u msr;
 + Bit16u cgapal;
 + Bit8u nbrows;
 + Bit16u cheight;
 + Bit8u ctl;
 + Bit8u switches;
 + Bit8u modeset;
 + Bit8u dcc;
 + Bit16u vsseg;
 + Bit16u vsoffset;
 +} BIOSAREA;
 +
 +void int10ax0003(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0003;
 + intr(0x10,regs);
 +}
 +
 +void int10ax02(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0200;
 + regs->r_bx=0x0000;
 + regs->r_dx=0x1710;
 + intr(0x10,regs);
 + printf("We are now at 24/17");
 +}
 +
 +void int10ax03(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0300;
 + regs->r_bx=0x0000;
 + intr(0x10,regs);
 + printf("\nCursor is ax%04x cx%04x dx%04x\n",regs->r_ax,regs->r_cx,regs->r_dx);
 +}
 +
 +void int10ax0501(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0501;
 + intr(0x10,regs);
 + regs->r_ax=0x0e61;
 + regs->r_bx=0x0000;
 + intr(0x10,regs);
 + printf("We are now on page 2");
 +}
 +
 +void int10ax0602(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0602;
 + regs->r_bx=0x0700;
 + regs->r_cx=0x0101;
 + regs->r_dx=0x0a0a;
 + intr(0x10,regs);
 + printf("Scrolled 2 up");
 +}
 +
 +void int10ax0702(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0702;
 + regs->r_bx=0x0700;
 + regs->r_cx=0x0101;
 + regs->r_dx=0x0a0a;
 + intr(0x10,regs);
 + printf("Scrolled 2 down");
 +}
 +
 +void int10ax08(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0800;
 + regs->r_bx=0x0000;
 + intr(0x10,regs);
 +}
 +
 +void int10ax09(struct REGPACK *regs)
 +{
 + char attr;
 + regs->r_ax=0x0501;
 + intr(0x10,regs);
 + for(attr=0;attr<16;attr++)
 +  {printf("%02x ",attr);
 +   regs->r_ax=0x0961+attr;
 +   regs->r_bx=0x0100+attr;
 +   regs->r_cx=0x0016;
 +   intr(0x10,regs);
 +   printf("\n");
 +  }
 +}
 +
 +void int10ax0a(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0501;
 + intr(0x10,regs);
 + regs->r_ax=0x0a62;
 + regs->r_bx=0x0101;
 + regs->r_cx=0x0016;
 + intr(0x10,regs);
 +}
 +
 +void int10ax0f(struct REGPACK *regs)
 +{
 + regs->r_ax=0x0501;
 + intr(0x10,regs);
 + regs->r_ax=0x0f00;
 + intr(0x10,regs);
 +}
 +
 +void int10ax1b(struct REGPACK *regs)
 +{unsigned char table[64];
 + unsigned char far *ptable;
 + int  i;
 +
 + regs->r_ax=0x0501;
 + intr(0x10,regs);
 + regs->r_ax=0x1b00;
 + regs->r_bx=0x0000;
 + ptable=&table;
 + regs->r_es=FP_SEG(ptable);
 + regs->r_di=FP_OFF(ptable);
 + printf("Read state info in %04x:%04x\n",regs->r_es,regs->r_di);
 + intr(0x10,regs);
 +
 + for(i=0;i<64;i++)
 +  {if(i%16==0)printf("\n%02x ",i);
 +   printf("%02x ",table[i]);
 +  }
 + printf("\n");
 +}
 +
 +static unsigned char var[64];
 +
 +void int10ax13(struct REGPACK *regs)
 +{unsigned char far *pvar;
 +
 + pvar=&var;
 +
 + regs->r_ax=0x1300;
 + regs->r_bx=0x000b;
 + regs->r_dx=0x1010;
 + regs->r_cx=0x0002;
 + regs->r_es=FP_SEG(pvar);
 + regs->r_bp=FP_OFF(pvar);
 + pokeb(regs->r_es,regs->r_bp,'t');
 + pokeb(regs->r_es,regs->r_bp+1,'b');
 + printf("Writing from %04x:%04x\n",regs->r_es,regs->r_bp);
 + intr(0x10,regs);
 + 
 +}
 +
 +void switch_50(struct REGPACK *regs)
 +{
 + regs->r_ax=0x1202;
 + regs->r_bx=0x3000;
 + intr(0x10,regs);
 + regs->r_ax=0x0003;
 + intr(0x10,regs);
 + regs->r_ax=0x1112;
 + regs->r_bx=0x0000;
 + intr(0x10,regs);
 +}
 +
 +char exec_function(struct REGPACK *regs)
 +{char c;
 +
 + printf("--- Functions --------------------\n");
 + printf("a. int10 ax0003\t");
 + printf("b. int10 ax02\t");
 + printf("c. int10 ax03\t");
 + printf("d. int10 ax0501\n");
 + printf("e. int10 ax0602\t");
 + printf("f. int10 ax0702\t");
 + printf("g. int10 ax08\t");
 + printf("h. int10 ax09\t");
 + printf("i. int10 ax0a\n");
 + printf("j. int10 ax0f\t");
 + printf("k. int10 ax1b\t");
 + printf("l. int10 ax13\n");
 + printf("q. Quit\t");
 + printf("r. switch to 50 lines\n");
 + c=getche();
 + 
 + switch(c)
 +  {case 'a':
 +    int10ax0003(regs);
 +    break;
 +   case 'b':
 +    int10ax02(regs);
 +    break;
 +   case 'c':
 +    int10ax03(regs);
 +    break;
 +   case 'd':
 +    int10ax0501(regs);
 +    break;
 +   case 'e':
 +    int10ax0602(regs);
 +    break;
 +   case 'f':
 +    int10ax0702(regs);
 +    break;
 +   case 'g':
 +    int10ax08(regs);
 +    break;
 +   case 'h':
 +    int10ax09(regs);
 +    break;
 +   case 'i':
 +    int10ax0a(regs);
 +    break;
 +   case 'j':
 +    int10ax0f(regs);
 +    break;
 +   case 'k':
 +    int10ax1b(regs);
 +    break;
 +   case 'l':
 +    int10ax13(regs);
 +    break;
 +   case 'q':
 +    break;
 +   case 'r':
 +    switch_50(regs);
 +    break;
 +   default:
 +    printf("No such function!\n");
 +  }
 +
 + if(c=='q')return 1;
 + while(kbhit()==0);
 + c=getch();
 + 
 + return 0;
 +}
 +
 +void read_bios_area(BIOSAREA *biosarea)
 +{
 + biosarea->initial=peekb(0x40,0x10);
 + biosarea->current=peekb(0x40,0x49);
 + biosarea->nbcols=peek(0x40,0x4a);
 + biosarea->regen=peek(0x40,0x4c);
 + biosarea->start=peek(0x40,0x4e);
 + biosarea->curpos[0]=peek(0x40,0x50);
 + biosarea->curpos[1]=peek(0x40,0x52);
 + biosarea->curpos[2]=peek(0x40,0x54);
 + biosarea->curpos[3]=peek(0x40,0x56);
 + biosarea->curpos[4]=peek(0x40,0x58);
 + biosarea->curpos[5]=peek(0x40,0x5a);
 + biosarea->curpos[6]=peek(0x40,0x5c);
 + biosarea->curpos[7]=peek(0x40,0x5e);
 + biosarea->curtyp=peek(0x40,0x60);
 + biosarea->curpage=peekb(0x40,0x62);
 + biosarea->crtc=peek(0x40,0x63);
 + biosarea->msr=peekb(0x40,0x65);
 + biosarea->cgapal=peekb(0x40,0x66);
 + biosarea->nbrows=peekb(0x40,0x84);
 + biosarea->cheight=peek(0x40,0x85);
 + biosarea->ctl=peekb(0x40,0x87);
 + biosarea->switches=peekb(0x40,0x88);
 + biosarea->modeset=peekb(0x40,0x89);
 + biosarea->dcc=peekb(0x40,0x8a);
 + biosarea->vsseg=peek(0x40,0xa8);
 + biosarea->vsoffset=peek(0x40,0xaa);
 +}
 +
 +void show_bios_area(BIOSAREA *biosarea)
 +{
 + printf("--- BIOS area --------------------\n");
 + printf("initial : %02x\t",biosarea->initial);
 + printf("current : %02x\t",biosarea->current);
 + printf("nbcols  : %04x\t",biosarea->nbcols);
 + printf("regen   : %04x\t",biosarea->regen);
 + printf("start   : %04x\n",biosarea->start);
 + printf("curpos  : %04x %04x %04x %04x %04x %04x %04x %04x\n",
 +   biosarea->curpos[0], biosarea->curpos[1], biosarea->curpos[2], biosarea->curpos[3],
 +   biosarea->curpos[4], biosarea->curpos[5], biosarea->curpos[6], biosarea->curpos[7]);
 + printf("curtyp  : %04x\t",biosarea->curtyp);
 + printf("curpage : %02x\t",biosarea->curpage);
 + printf("crtc    : %04x\t",biosarea->crtc);
 + printf("msr     : %04x\n",biosarea->msr);
 + printf("cgapal  : %04x\t",biosarea->cgapal);
 + printf("nbrows-1: %02x\t",biosarea->nbrows);
 + printf("cheight : %04x\t",biosarea->cheight);
 + printf("ctl     : %02x\n",biosarea->ctl);
 + printf("switches: %02x\t",biosarea->switches);
 + printf("modeset : %02x\t",biosarea->modeset);
 + printf("dcc     : %02x\t",biosarea->dcc);
 + printf("vs      : %04x:%04x\n",biosarea->vsseg,biosarea->vsoffset);
 +}
 +
 +void show_regs(struct REGPACK *regs)
 +{
 + printf("--- Registers --------------------\n");
 + printf("ax %04x\t",regs->r_ax);
 + printf("bx %04x\t",regs->r_bx);
 + printf("cx %04x\t",regs->r_cx);
 + printf("dx %04x\t",regs->r_dx);
 + printf("ds %04x\t",regs->r_ds);
 + printf("si %04x\t",regs->r_si);
 + printf("es %04x\t",regs->r_es);
 + printf("di %04x\n",regs->r_di);
 +}
 +
 +void reset_videomode()
 +{
 + struct REGPACK regs;
 +
 + regs.r_ax=0x0003;
 + intr(0x10,®s);
 +}
 +
 +void main()
 +{
 +
 + BIOSAREA biosarea;
 + struct REGPACK regs;
 +
 + directvideo=0;
 + 
 + while(1)
 +  {
 +   read_bios_area(&biosarea);
 +
 +   reset_videomode();
 +   show_bios_area(&biosarea);
 +   show_regs(®s);
 +
 +   if(exec_function(®s)!=0)break;
 +  }
 +}
  | 
