2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
14 char framebuf_rcsid[] = "$Id: framebuf.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $";
28 #define DPMI_INTERRUPT 0x31
29 const VIDEO_INTERRUPT = 0x10;
33 short ModeAttributes; /* Mode attributes */
34 char WinAAttributes; /* Window A attributes */
35 char WinBAttributes; /* Window B attributes */
36 short WinGranularity; /* Window granularity in k */
37 short WinSize; /* Window size in k */
38 short WinASegment; /* Window A segment */
39 short WinBSegment; /* Window B segment */
40 void *WinFuncPtr; /* Pointer to window function */
41 short BytesPerScanLine; /* Bytes per scanline */
42 short XResolution; /* Horizontal resolution */
43 short YResolution; /* Vertical resolution */
44 char XCharSize; /* Character cell width */
45 char YCharSize; /* Character cell height */
46 char NumberOfPlanes; /* Number of memory planes */
47 char BitsPerPixel; /* Bits per pixel */
48 char NumberOfBanks; /* Number of CGA style banks */
49 char MemoryModel; /* Memory model type */
50 char BankSize; /* Size of CGA style banks */
51 char NumberOfImagePages; /* Number of images pages */
52 char res1; /* Reserved */
53 char RedMaskSize; /* Size of direct color red mask */
54 char RedFieldPosition; /* Bit posn of lsb of red mask */
55 char GreenMaskSize; /* Size of direct color green mask */
56 char GreenFieldPosition; /* Bit posn of lsb of green mask */
57 char BlueMaskSize; /* Size of direct color blue mask */
58 char BlueFieldPosition; /* Bit posn of lsb of blue mask */
59 char RsvdMaskSize; /* Size of direct color res mask */
60 char RsvdFieldPosition; /* Bit posn of lsb of res mask */
61 char DirectColorModeInfo; /* Direct color mode attributes */
62 FxU32 PhysBasePtr; /* Physical address of lfb */
63 FxU32 OffScreenMemOffset;
64 FxU32 OffScreenMemSize;
65 char res2[206]; /* Pad to 256 byte block size */
74 if ( ( error = VesaInit( mode ) ) != VESA_ERR_NONE )
76 printf( "VesaInit failed with error '%s'\n", VesaGetErrorString( error ) );
82 MyPtr=(char *)VesaGetPtr();
83 memset( (MyPtr+((rand()%0x10000)<<4)+rand()%0x10000),rand()%256, 1 );
90 ** DpmiMapPhysicalToLinear
92 FxU32 DpmiMapPhysicalToLinear( FxU32 paddr, FxU32 length )
98 ** DPMI function 0x800
103 ** BX:CX = physical address
106 r.w.bx = ( FxU16 ) ( paddr >> 16 );
107 r.w.cx = ( FxU16 ) ( paddr & 0x0000FFFF );
108 r.w.si = ( FxU16 ) ( length >> 16 );
109 r.w.di = ( FxU16 ) ( length & 0x0000FFFF );
110 int386( DPMI_INTERRUPT, &r, &r );
113 ** if cflag set then an error occured
131 void *DpmiAllocDosMem( FxU16 size, DpmiSelector_t *pSel )
138 ** AX = DPMI function 0x100
143 ** BX = # of paragraphs to allocate
145 r.w.bx = ( FxI16 ) ( size / 16 + 1 );
147 int386( DPMI_INTERRUPT, &r, &r );
158 ptr = ( void * ) ( seg << 4 );
167 FxBool DpmiFreeDosMem( DpmiSelector_t sel )
173 int386( DPMI_INTERRUPT, &r, &r );
182 ModeInfoBlock infoblock;
184 static void *vesa_lfb_ptr;
186 static void VesaGetModeInfo( int mode, ModeInfoBlock *infoblock )
190 DpmiSelector_t infosel;
191 unsigned short infoseg;
192 ModeInfoBlock *far_infoblock;
195 ** Allocate some real-mode DOS memory using DPMI function 0x100
197 far_infoblock = ( ModeInfoBlock * ) DpmiAllocDosMem( sizeof( ModeInfoBlock ), &infosel );
198 infoseg = ( unsigned short ) ( ( ( unsigned long ) far_infoblock ) >> 4 );
201 ** Get VESA SVGA info block by executing real-mode interrupt
202 ** 0x10, function 0x4F01. This must be done using DPMI service
203 ** 0x300 since DOS4GW doesn't automatically thunk pointers down
204 ** for VESA functions.
206 memset( &RMI, 0, sizeof( RMI ) );
207 RMI.EAX = 0x4F01; // Function 0x4F01
209 RMI.ES = infoseg; // ES:DI -> pointer to real mode buffer
212 r.x.eax = 0x0300; // DPMI service "execute real mode interrupt"
213 r.x.ebx = VIDEO_INTERRUPT; // BL = function to execute
214 r.x.ecx = 0; // CX = 0
216 sr.es = FP_SEG( &RMI ); // ES:EDI -> buffer to RMI struct
217 r.x.edi = FP_OFF( &RMI );
219 #define DPMI_INTERRUPT 0x31
221 int386x( DPMI_INTERRUPT, &r, &r, &sr );
224 ** Copy realmode buffer into protected mode buffer
226 memcpy( infoblock, far_infoblock, sizeof( ModeInfoBlock ) );
229 ** Free up the memory
231 DpmiFreeDosMem( infosel );
234 int VesaGetRowSize (int mode)
238 VesaGetModeInfo (mode,&mi);
239 return (mi.BytesPerScanLine);
242 extern int FindArg(char *);
246 ** VESA initialization function. Returns a pointer to the
247 ** linear frame buffer.
249 int VesaInit( int mode )
254 if (!FindArg ("-ForceVesa"))
258 ** Get VESA mode information
260 VesaGetModeInfo( mode, &infoblock );
263 ** Check mode information stuff
265 if ( !( infoblock.ModeAttributes & 0x1 ) ||
266 !( infoblock.ModeAttributes & 0x80 ) )
268 mprintf ((0,"mode %x is not supported!\n",mode));
273 ** Get a pointer to the linear frame buffer
275 if ( ( vesa_lfb_ptr = ( void * ) DpmiMapPhysicalToLinear( infoblock.PhysBasePtr, 0x400000 - 1 ) ) == 0 )
277 mprintf ((0,"mode %x mapping not supported!\n",mode));
283 ** Set the video mode
286 r.w.bx = ( short ) ( mode | 0x4000 );
287 int386( VIDEO_INTERRUPT, &r, &r );
289 if ( r.w.ax != 0x004F )
292 mprintf ((0,"mode %x not set!\n",mode));
296 mprintf ((0,"No errors! mode %x is go!\n",mode));
308 int386( VIDEO_INTERRUPT, &r, &r );
314 void *VesaGetPtr( void )
319 static const char *vesa_errors[] =
322 "VESA_ERR_DPMI_MAPPING_FAILED",
323 "VESA_ERR_MODE_NOT_SUPPORTED",
324 "VESA_ERR_MODE_NOT_SET"
328 ** VesaGetErrorString
330 const char *VesaGetErrorString( VesaErr_t err )
332 return vesa_errors[err];