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