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
First make sure the MetaWINDOW ETS example program "mwst4ets.c" compiles,
links and runs cleanly in standard VGA 640x480 16-color mode.
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.
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.
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.
To MetaWINDOW FAQ Index
To MetaWINDOW Home Page
To Metagraphics Home Page
© Copyright - Metagraphics Software Corporation. All rights reserved.
|