13 #define DPMI_INTERRUPT 0x31
\r
14 const VIDEO_INTERRUPT = 0x10;
\r
18 short ModeAttributes; /* Mode attributes */
\r
19 char WinAAttributes; /* Window A attributes */
\r
20 char WinBAttributes; /* Window B attributes */
\r
21 short WinGranularity; /* Window granularity in k */
\r
22 short WinSize; /* Window size in k */
\r
23 short WinASegment; /* Window A segment */
\r
24 short WinBSegment; /* Window B segment */
\r
25 void *WinFuncPtr; /* Pointer to window function */
\r
26 short BytesPerScanLine; /* Bytes per scanline */
\r
27 short XResolution; /* Horizontal resolution */
\r
28 short YResolution; /* Vertical resolution */
\r
29 char XCharSize; /* Character cell width */
\r
30 char YCharSize; /* Character cell height */
\r
31 char NumberOfPlanes; /* Number of memory planes */
\r
32 char BitsPerPixel; /* Bits per pixel */
\r
33 char NumberOfBanks; /* Number of CGA style banks */
\r
34 char MemoryModel; /* Memory model type */
\r
35 char BankSize; /* Size of CGA style banks */
\r
36 char NumberOfImagePages; /* Number of images pages */
\r
37 char res1; /* Reserved */
\r
38 char RedMaskSize; /* Size of direct color red mask */
\r
39 char RedFieldPosition; /* Bit posn of lsb of red mask */
\r
40 char GreenMaskSize; /* Size of direct color green mask */
\r
41 char GreenFieldPosition; /* Bit posn of lsb of green mask */
\r
42 char BlueMaskSize; /* Size of direct color blue mask */
\r
43 char BlueFieldPosition; /* Bit posn of lsb of blue mask */
\r
44 char RsvdMaskSize; /* Size of direct color res mask */
\r
45 char RsvdFieldPosition; /* Bit posn of lsb of res mask */
\r
46 char DirectColorModeInfo; /* Direct color mode attributes */
\r
47 FxU32 PhysBasePtr; /* Physical address of lfb */
\r
48 FxU32 OffScreenMemOffset;
\r
49 FxU32 OffScreenMemSize;
\r
50 char res2[206]; /* Pad to 256 byte block size */
\r
59 if ( ( error = VesaInit( mode ) ) != VESA_ERR_NONE )
\r
61 printf( "VesaInit failed with error '%s'\n", VesaGetErrorString( error ) );
\r
67 MyPtr=(char *)VesaGetPtr();
\r
68 memset( (MyPtr+((rand()%0x10000)<<4)+rand()%0x10000),rand()%256, 1 );
\r
75 ** DpmiMapPhysicalToLinear
\r
77 FxU32 DpmiMapPhysicalToLinear( FxU32 paddr, FxU32 length )
\r
83 ** DPMI function 0x800
\r
88 ** BX:CX = physical address
\r
91 r.w.bx = ( FxU16 ) ( paddr >> 16 );
\r
92 r.w.cx = ( FxU16 ) ( paddr & 0x0000FFFF );
\r
93 r.w.si = ( FxU16 ) ( length >> 16 );
\r
94 r.w.di = ( FxU16 ) ( length & 0x0000FFFF );
\r
95 int386( DPMI_INTERRUPT, &r, &r );
\r
98 ** if cflag set then an error occured
\r
116 void *DpmiAllocDosMem( FxU16 size, DpmiSelector_t *pSel )
\r
123 ** AX = DPMI function 0x100
\r
128 ** BX = # of paragraphs to allocate
\r
130 r.w.bx = ( FxI16 ) ( size / 16 + 1 );
\r
132 int386( DPMI_INTERRUPT, &r, &r );
\r
143 ptr = ( void * ) ( seg << 4 );
\r
152 FxBool DpmiFreeDosMem( DpmiSelector_t sel )
\r
158 int386( DPMI_INTERRUPT, &r, &r );
\r
167 ModeInfoBlock infoblock;
\r
169 static void *vesa_lfb_ptr;
\r
171 static void VesaGetModeInfo( int mode, ModeInfoBlock *infoblock )
\r
175 DpmiSelector_t infosel;
\r
176 unsigned short infoseg;
\r
177 ModeInfoBlock *far_infoblock;
\r
180 ** Allocate some real-mode DOS memory using DPMI function 0x100
\r
182 far_infoblock = ( ModeInfoBlock * ) DpmiAllocDosMem( sizeof( ModeInfoBlock ), &infosel );
\r
183 infoseg = ( unsigned short ) ( ( ( unsigned long ) far_infoblock ) >> 4 );
\r
186 ** Get VESA SVGA info block by executing real-mode interrupt
\r
187 ** 0x10, function 0x4F01. This must be done using DPMI service
\r
188 ** 0x300 since DOS4GW doesn't automatically thunk pointers down
\r
189 ** for VESA functions.
\r
191 memset( &RMI, 0, sizeof( RMI ) );
\r
192 RMI.EAX = 0x4F01; // Function 0x4F01
\r
194 RMI.ES = infoseg; // ES:DI -> pointer to real mode buffer
\r
197 r.x.eax = 0x0300; // DPMI service "execute real mode interrupt"
\r
198 r.x.ebx = VIDEO_INTERRUPT; // BL = function to execute
\r
199 r.x.ecx = 0; // CX = 0
\r
201 sr.es = FP_SEG( &RMI ); // ES:EDI -> buffer to RMI struct
\r
202 r.x.edi = FP_OFF( &RMI );
\r
204 #define DPMI_INTERRUPT 0x31
\r
206 int386x( DPMI_INTERRUPT, &r, &r, &sr );
\r
209 ** Copy realmode buffer into protected mode buffer
\r
211 memcpy( infoblock, far_infoblock, sizeof( ModeInfoBlock ) );
\r
214 ** Free up the memory
\r
216 DpmiFreeDosMem( infosel );
\r
220 extern int FindArg(char *);
\r
224 ** VESA initialization function. Returns a pointer to the
\r
225 ** linear frame buffer.
\r
229 int VesaInit( int mode )
\r
233 if ( FindArg( "-virge" ) && (mode==0x101) ) {
\r
234 vesa_lfb_ptr = virge_init();
\r
238 if (FindArg ("-novesa"))
\r
242 ** Get VESA mode information
\r
244 VesaGetModeInfo( mode, &infoblock );
\r
247 ** Check mode information stuff
\r
249 if ( !( infoblock.ModeAttributes & 0x1 ) ||
\r
250 !( infoblock.ModeAttributes & 0x80 ) )
\r
252 mprintf ((0,"mode %x is not supported!\n",mode));
\r
257 ** Get a pointer to the linear frame buffer
\r
259 if ( ( vesa_lfb_ptr = ( void * ) DpmiMapPhysicalToLinear( infoblock.PhysBasePtr, 0x400000 - 1 ) ) == 0 )
\r
261 mprintf ((0,"mode %x mapping not supported!\n",mode));
\r
267 ** Set the video mode
\r
270 r.w.bx = ( short ) ( mode | 0x4000 );
\r
271 int386( VIDEO_INTERRUPT, &r, &r );
\r
273 if ( r.w.ax != 0x004F )
\r
276 mprintf ((0,"mode %x not set!\n",mode));
\r
280 mprintf ((0,"No errors! mode %x is go!\n",mode));
\r
287 void VesaEnd( void )
\r
292 int386( VIDEO_INTERRUPT, &r, &r );
\r
298 void *VesaGetPtr( void )
\r
300 return vesa_lfb_ptr;
\r
303 static const char *vesa_errors[] =
\r
306 "VESA_ERR_DPMI_MAPPING_FAILED",
\r
307 "VESA_ERR_MODE_NOT_SUPPORTED",
\r
308 "VESA_ERR_MODE_NOT_SET"
\r
312 ** VesaGetErrorString
\r
314 const char *VesaGetErrorString( VesaErr_t err )
\r
316 return vesa_errors[err];
\r