From e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb Mon Sep 17 00:00:00 2001 From: Yang Zhang Date: Fri, 28 Aug 2015 09:58:54 +0800 Subject: Add qemu 2.4.0 Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang --- qemu/roms/vgabios/tests/lfbprof/Makefile | 5 + qemu/roms/vgabios/tests/lfbprof/lfbprof.c | 594 ++++++++++++++++++++++++++++++ qemu/roms/vgabios/tests/lfbprof/lfbprof.h | 149 ++++++++ qemu/roms/vgabios/tests/testbios.c | 353 ++++++++++++++++++ 4 files changed, 1101 insertions(+) create mode 100644 qemu/roms/vgabios/tests/lfbprof/Makefile create mode 100644 qemu/roms/vgabios/tests/lfbprof/lfbprof.c create mode 100644 qemu/roms/vgabios/tests/lfbprof/lfbprof.h create mode 100644 qemu/roms/vgabios/tests/testbios.c (limited to 'qemu/roms/vgabios/tests') diff --git a/qemu/roms/vgabios/tests/lfbprof/Makefile b/qemu/roms/vgabios/tests/lfbprof/Makefile new file mode 100644 index 000000000..7c42e38b0 --- /dev/null +++ b/qemu/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/qemu/roms/vgabios/tests/lfbprof/lfbprof.c b/qemu/roms/vgabios/tests/lfbprof/lfbprof.c new file mode 100644 index 000000000..df37452e8 --- /dev/null +++ b/qemu/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 +* - fixed unsigned short for mode list (-1 != 0xffff otherwise) +* - fixed LfbMapRealPointer macro mask problem (some modes were skipped) +* +****************************************************************************/ + +#include +#include +#include +#include +#include +#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 \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/qemu/roms/vgabios/tests/lfbprof/lfbprof.h b/qemu/roms/vgabios/tests/lfbprof/lfbprof.h new file mode 100644 index 000000000..bae0e09b1 --- /dev/null +++ b/qemu/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/qemu/roms/vgabios/tests/testbios.c b/qemu/roms/vgabios/tests/testbios.c new file mode 100644 index 000000000..99da5a65f --- /dev/null +++ b/qemu/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 +#include +#include + + +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; + } +} -- cgit 1.2.3-korg