MetaWINDOW FAQ

Using Linear Frame Buffer Bitmaps with MetaWINDOW and Phar Lap ETS

Document ID: MWFAQ029.HTM

The information in this document applies to:

  • MetaWINDOW-386/S

  • Phar Lap ETS

  • VESA Video BIOS Support

QUESTION

We're using MetaWINDOW with Phar Lap ETS. The graphics hardware we're using includes VESA driver support built into its ROM BIOS.  Since ETS does not support INT 10 video BIOS calls during runtime, is there a way to call VESA BIOS during initialization to set up the card and then have MetaWINDOW use "linear frame buffer mode" to perform drawing operations?

ANSWER

Yes.  This can work also even without VESA BIOS support if you manually initialize your graphics hardware to set it into "linear frame buffer mode". By editing the EkCustomBiosInit() within the Phar Lap ETS "pcati2.c" source file, you can call INT 10 video BIOS to set a VESA display mode during ETS initialization before it switches into protected mode.  You need to initialize the graphics card for "linear frame buffer mode" either by using the appropriate INT 10 VESA BIOS call, or by programming the graphics hardware directly.  Please also refer to the ETSNOTES.TXT file provided with your MetaWINDOW Source Code distribution, and the Phar Lap documentation for further information on customizing "pcati2.c" initializations.

Before going too far, you need to make sure that your graphics hardware can be programmed into linear frame buffer buffer, or that your VESA BIOS in fact supports "linear frame buffer" modes and not just "bank switched" modes.  (Certain older graphics chipsets only support "bank switched" modes which require BIOS to be called during runtime - INT 10 VESA BIOS services that MetaWINDOW would normally use for bank switching cannot be accessed from the ETS runtime).  The programs "vesatest.exe", "vbetest.exe" and "vesainfo.exe" can be used to test and display VESA modes supported by your hardware. These programs can be downloaded from the Metagraphics web site:

      vesatest.exe (10Kb) - Displays available VESA modes.

      vbetest.exe (193Kb) - Tests available VESA modes.

      vesainfo.exe (15Kb) - Queries VESA BIOS and returns ModeInfoBlock information.

Documentation for setting VESA linear frame buffer modes is available in the "VESA BIOS Extensions Core Functions Standard Version 3" ("vbe3.pdf", Adobe Acrobat document) which you can download also from the Metagraphics web site at:

      vbe3.pdf (272Kb) - VESA BIOS Extensions Core Functions Standard Version 3 specification

The following addition to the EkCustomBiosInit() function in Phar Lap ETS "pcati2.c" source file illustrates how to initialize the graphics hardware for standard VGA 640x480 16-color mode:

void EkCustomBiosInit(int StartupType)        // (ETS pcati2.c)
{
    VSB_VARS CS_BASED *pvsbvars;
    USHORT Heads0;
    USHORT Secs0;
    USHORT Heads1;
    USHORT Secs1;

    // *** modification for graphics display initialization *** 
    if ( StartupType != EK_ST_RESTART )
    {
        // initialize for VGA 640x480 16-color mode (mode 12h)
        _asm mov    ax,012h
        _asm int    10h
    }
    // ********************************************************

Sections 6.3 and 14.2 in the Phar Lap ETS Basics of Operation manual provide the details for rebulding ETS bootable kernels.  One of the easiest ways to test is by creating a simple ETS removable boot diskette (this requires only a single standard PC, and allows you to test the MetaWINDOW ETS example programs from an ETS bootable diskette without requiring a second computer or serial link).  The following steps outline the procedure for rebuilding the ETS PC removable boot diskette kernel:

   1. From Windows Explorer, make a duplicate backup copy of the ETS \monitor
      directory (and subdirectories) called "\monitor-original".
 
   2. Open an MS-DOS box window and from the DOS command prompt execute the
      batch file to set paths for \bin, \include and \lib directories for
      Phar Lap ETS and Microsoft Visual C v1.5 (16-bit), and then switch
      to the MetaWINDOW \mw386ets directory (a sample et9vc1.bat file is
      provided in the MetaWINDOW \mw386ets directory):

          > et9vc1
 
   3. Copy the modified pcati2.c source file contained in the MetaWINDOW
      directory to the ETS \monitor\build directory:
 
          > copy pcati2.c ..\monitor\build

   4. Switch to the ETS \monitor\build directory and execute the ETS
      msckern.bat batch file to recompile the ETS kernal source code:
 
          > cd  ..\monitor\build
          > msckern
 
   5. Execute the ETS bld_disk.bat batch file to build a new diskkern.bin:
 
         > bld_disk
 
   6. Copy the new diskkern.bin to the ETS \monitor directory:
 
         > copy  diskkern.bin  ..\
         
   7. Switch to the ETS \monitor directory and execute the bootdisk.bat batch
      file to format and create a removable ETS boot diskette:
 
         > cd  ..\
         > bootdisk  a          (no colon)

   8. Execute the et9vc6.bat batch file to set paths for \bin, \include and \lib
      directories for Phar Lap ETS and Microsoft Visual C v6 (32-bit), and then
      switch to the MetaWINDOW \mw386ets directory (a sample et9vc6.bat file is
      provided in your MetaWINDOW directory).
      
         > et9vc1
 
   9. Compile and link the MetaWINDOW ETS mwst4ets.c example program using the
      MetaWINDOW gcl_ets.bat batch file provided:
 
         > gcl_ets  mwst4ets
 
  10. Copy the resultant mwst4ets.exe program to the ETS boot disk, and then
      run the ETS cfigkern.exe utility to configure mwst4ets.exe to execute
      automatically after the ETS kernal boots:
 
         > copy  mwst4ets.exe  a:
         > cfigkern  a:diskkern.bin  -appname mwst4ets.exe  -nowaithost
         > exit
 
  11. Exit the DOS-box Window.  From the Windows "Start" menu select
      "Shut Down | Restart" to shut down Windows and reboot your computer.
      With your ETS boot disk in drive a:, ETS should boot and then execute
      the mwst4ets.exe example program.

Once you have verified that your code runs properly in standard VGA 640x480 16-color mode, you can change the initialization to a higher 256-color linear frame buffer mode.  The following modification to the EkCustomBiosInit() function in the Phar Lap ETS "pcati2.c" source file shows how to initialize the graphics hardware for VESA linear frame buffer mode 640x480 256-color:

void EkCustomBiosInit(int StartupType)     // (ETS pcati2.c)
{
    VSB_VARS CS_BASED *pvsbvars;
    USHORT Heads0;
    USHORT Secs0;
    USHORT Heads1;
    USHORT Secs1;

/* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ */
/* ///////////////////////////////////////////////////////////////////////// */
    /* Metagraphics modification to initialize graphics mode for MetaWINDOW
     *
     * DOCUMENTATION REFERENCE:
     *    VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0
     *    http://www.metagraphics.com/metawindow/vesa/vbe3.pdf
     *
     *    VBE MODE NUMBERS
     *      vbe3.pdf, page 19
     *
     *    VBE FUNCTION 4F02h - SET VBE MODE
     *      vbe3.pdf, page 40
     */
    if ( StartupType != EK_ST_RESTART )
    {
        /* call VESA BIOS to initialize for linear frame buffer mode */
        _asm mov    ax,0x4F02   // Set VBE Mode (VESA BIOS function 4F02h)
        _asm mov    bx,0x4101   //  640x 480 256-color (linear + mode 101h)
//***   _asm mov    bx,0x4103   //  800x 600 256-color (linear + mode 103h)
//***   _asm mov    bx,0x4105   // 1024x 768 256-color (linear + mode 105h)
//***   _asm mov    bx,0x4107   // 1280x1024 256-color (linear + mode 107h)
        _asm int    10h         // call video BIOS to initialize graphics
    }
/* ///////////////////////////////////////////////////////////////////////// */
/* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ */

 
Once you have the graphics hardware initialized for linear frame buffer mode and your application starts in protected mode, you then just need to set up a custom MetaWINDOW grafMap data structure with the address of the linear frame buffer that MetaWINDOW can access directly.  Sample code for initializing the grafMap data structure and setting up MetaWINDOW is provided in the MetaWINDOW ETS "mwst5ets.c" example program as illustrated below.

// ///////////////////////////////////////////////////////////////////////
// The following code illustrates how to initialize
// MetaWINDOW for operating with linear frame buffer video
// modes.  Once the graphics hardware is initialized for the
// appropriate linear frame buffer mode we can initialize a
// custom MetaWINDOW grafMap data structure that contains
// a pointer to where the video linear frame buffer starts.

#define NUM_PAGES  1                 // number of video pages
// (more then one video page can be supported if you supply your
//  own function for setting the visible display page, see below.)
#define PIX_HEIGHT (1280*NUM_PAGES)   // maximum pixel height

void InitMeta( int videoMode )
{
    static grafMap  myBitmap;       // new custom MW grafMap struct
    static Byte    *myRowTable[PIX_HEIGHT+1]; // array of pointers
                                              //   to each raster line.
    grafPort       *mwGrafPort;     // pointer to default grafPort
    rect            scrnRect;       // rect containing screen limits
    int             i, j, result;   // local work variables
    int             myPixWidth;     // pixel width for this video mode
    int             myPixHeight;    // pixel height for this video mode
    Byte           *rowPtr;         // used for debug (see below)

    /* Initialize MetaWINDOW Software
     *
     * Initialize for a standard linear VGA 256-color mode
     * (use VGA320x200X for all 256-color linear
     *  address modes regardless of resolution)
     */
    result = InitGraphics( VGA320x200X );
    if ( result != 0 )
    {
        printf("MetaWINDOW InitGraphics error - %d\n", result);
        exit(1);
    }
    
    /* set myPixWidth & myPixHeight based on the input display mode */
    switch ( videoMode )
    {
        case VESA640x480X:
            myPixWidth  =  640;
            myPixHeight =  480;
            break;
            
        case VESA800x600X:
            myPixWidth  =  800;
            myPixHeight =  600;
            break;
            
        case VESA1024x768X:
            myPixWidth  = 1024;
            myPixHeight =  768;
            break;
            
        case VESA1280x1024X:
            myPixWidth  = 1280;
            myPixHeight = 1024;
            break;
    }

    // If not done in ETS pcati2.c, initialize video for linear frame buffer access
//  vInitVideo();         // custom user function

    // Get pointer to the current (default) port
    GetPort(&mwGrafPort);

    // See InitRowTable() description for fields to initialize
    // (pg 206-207 in the MetaWINDOW Reference Manual)
    memset( &myBitmap, 0, sizeof(myBitmap) );     // zero the grafMap struct
    myBitmap.devClass    = mwGrafPort->portMap->devClass;    // copy
    myBitmap.devTech     = mwGrafPort->portMap->devTech;     //  these
    myBitmap.mapWinScans = mwGrafPort->portMap->mapWinScans; //   three (=-2)
    myBitmap.pixBytes    = myPixWidth;            // offset between raster lines
    myBitmap.pixWidth    = myPixWidth;            // pixel width
    myBitmap.pixHeight   = myPixHeight*NUM_PAGES; // pixel height
    myBitmap.pixResX     = myBitmap.pixResY = 96; // pixels per inch
    myBitmap.pixBits     = 8;                     // bits per pixel
    myBitmap.pixPlanes   = 1;                     // planes per pixel
    myBitmap.mapTable[0] = myRowTable;      // pointer to rowTable array

    /* Set pointer to the start of the video linear frame buffer memory.
     * If working with a standard PC and graphics card you can use the
     * Metagraphics "vesainfo.exe" utility to query VESA BIOS and return
     * the physical address for video memory when in linear address mode.
     * "vesainfo.exe" is included in the mw_ets.zip distribution file,
     * or can be downloaded from the Metagraphics web site at
     * http://www.metagraphics.com/metawindow/files.htm#VESAINFO.
     * (Note - "vesainfo.exe" should be executed under DOS directly.
     *  The "PhysBasePtr" linear frame buffer address may be reported
     *  incorrectly if running under a Windows DOS-box.)
     */
    myRowTable[0] = (Byte *)0xE8000000UL; // example value!!!

    InitRowTable(&myBitmap, 1, 0, 0);     // initialize the rowTable

    InitBitmap(cUSER, &myBitmap);         // initialize the bitmap

#ifdef    _DEBUG1  // verify rowTable pointers
    // double check that the rowTable was initialized properly
    rowPtr = myRowTable[0];
    for ( i=0; i < (myPixHeight*NUM_PAGES); i++ )
    {
        _ASSERT( rowPtr == myRowTable[i] );
//      if ( rowPtr != myRowTable[i] )
//         DebugBreak();   /* rowTable error */
        rowPtr += myBitmap.pixBytes;
    }
#endif // _DEBUG1

//#define _DEBUG2
#ifdef    _DEBUG2  // verify video-RAM access
    // loop through each raster line
    for ( i=0; i < (myPixHeight*NUM_PAGES); i++ )
    {   // loop through each pixel within each raster line
        rowPtr = myRowTable[i];
        for ( j=0; j < myPixWidth; )
        {   // store some pixel values
            *rowPtr++ = 0x00;
            *rowPtr++ = 0x55;
            *rowPtr++ = 0xAA;
            *rowPtr++ = 0xFF;
            j += 4;
        }
    }
    getch(); /* press a key to continue */
#endif // _DEBUG2

    // attach this bitmap to the current port for drawing
    PortBitmap( &myBitmap );

    // use this bitmap for cursor tracking
    CursorBitmap( &myBitmap );

    // set the port size to the size of one page
    PortSize( myPixWidth, myPixHeight );

    // update the clip rectangle size
    ClipRect( &mwGrafPort->portRect );

    // get the screen rectangle limits
    ScreenRect( &scrnRect );

#if      numPages > 1   /* ------------------------------------------------- */
    // The following code shows page flipping using two video pages
    
    // display page 1 while page 0 is being drawn
//  videoSetDisplayPage( 1 );   // custom user function

    // move the grapPort to the start of page 0
    MovePortTo(0, 0);
    
    // Set the background color to black and pen color to white for page 0
    BackColor( 0 );
    PenColor( 15 );

    // erase the screen to the background color
    EraseRect( &scrnRect );

    // display page 0 while page 1 is being drawn
//  videoSetDisplayPage( 0 );   // custom user function

    // move the grapPort to the start of page 1
    MovePortTo( 0, scrnRect.Ymax );
#endif /*numPages > 1*/ /* ------------------------------------------------- */
    
    // Set the background color to white and pen color to black
    BackColor( 15 );
    PenColor( 0 );

    // erase the screen to the background color
    EraseRect( &scrnRect );
    
#ifdef    _DEBUG2
    getch();   /* press a key to continue */
#endif // _DEBUG2

}  /* InitMeta()*/


What To Do If You Have Difficulty

  1. First make sure the MetaWINDOW ETS example program "mwst4ets.c" compiles, links and runs cleanly in standard VGA 640x480 16-color mode.

  2. Second, use the MetaWINDOW ETS example program "mwst5ets.c" as a base for testing linear frame buffer modes. "mwst5ets.c" is set up to test 256-color linear frame buffer modes for either 640x480, 800x600, 1024x768 or 1280x1024.

  3. After you make changes to initialize for linear address mode, if nothing appears on the screen first check that the values stored in the "rowTable" array are initialized properly (the rowTable array contains a list of pointers to the beginning of each raster line in video RAM).  See the code between the "#ifdef _DEBUG1" and "#endif" statements in the above example to see how this can be checked.

  4. If the rowTable is initialized properly, attempt to manually store some pixel values into video-RAM.  See the code between the "#ifdef _DEBUG2" and "#endif" in the above example to see how this is performed.  If the graphics screen does not change after manually storing pixel values into video-RAM, the video-RAM address you are using may be incorrect.  Alternatively if you're using a custom graphics controller, check to make sure that the video-RAM address range does not conflict or overlap with the address space for system-memory.



Link To MetaWINDOW FAQ Index
Link To MetaWINDOW Home Page
Link To Metagraphics Home Page

© Copyright - Metagraphics Software Corporation. All rights reserved.