]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/framebuf.c
remove rcs tags
[btb/d2x.git] / unused / vga / framebuf.c
1 /*
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.
12 */
13
14 #include <dos.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <i86.h>
19 #include <dos.h>
20 #include "mono.h"
21
22
23 #include "fxdpmi.h"
24 #include "fxvesa.h"
25
26 #define DPMI_INTERRUPT 0x31
27 const VIDEO_INTERRUPT = 0x10;
28
29 typedef struct
30 {
31   short   ModeAttributes;         /* Mode attributes                  */
32   char    WinAAttributes;         /* Window A attributes              */
33   char    WinBAttributes;         /* Window B attributes              */
34   short   WinGranularity;         /* Window granularity in k          */
35   short   WinSize;                /* Window size in k                 */
36   short   WinASegment;            /* Window A segment                 */
37   short   WinBSegment;            /* Window B segment                 */
38   void   *WinFuncPtr;             /* Pointer to window function       */
39   short   BytesPerScanLine;       /* Bytes per scanline               */
40   short   XResolution;            /* Horizontal resolution            */
41   short   YResolution;            /* Vertical resolution              */
42   char    XCharSize;              /* Character cell width             */
43   char    YCharSize;              /* Character cell height            */
44   char    NumberOfPlanes;         /* Number of memory planes          */
45   char    BitsPerPixel;           /* Bits per pixel                   */
46   char    NumberOfBanks;          /* Number of CGA style banks        */
47   char    MemoryModel;            /* Memory model type                */
48   char    BankSize;               /* Size of CGA style banks          */
49   char    NumberOfImagePages;     /* Number of images pages           */
50   char    res1;                   /* Reserved                         */
51   char    RedMaskSize;            /* Size of direct color red mask    */
52   char    RedFieldPosition;       /* Bit posn of lsb of red mask      */
53   char    GreenMaskSize;          /* Size of direct color green mask  */
54   char    GreenFieldPosition;     /* Bit posn of lsb of green mask    */
55   char    BlueMaskSize;           /* Size of direct color blue mask   */
56   char    BlueFieldPosition;      /* Bit posn of lsb of blue mask     */
57   char    RsvdMaskSize;           /* Size of direct color res mask    */
58   char    RsvdFieldPosition;      /* Bit posn of lsb of res mask      */
59   char    DirectColorModeInfo;    /* Direct color mode attributes     */
60   FxU32   PhysBasePtr;            /* Physical address of lfb          */
61   FxU32   OffScreenMemOffset;
62   FxU32   OffScreenMemSize;
63   char    res2[206];              /* Pad to 256 byte block size       */
64 } ModeInfoBlock;
65
66
67 void VesaMain()
68 {
69    FxU16     mode = 0x111;
70    VesaErr_t error;
71
72    if ( ( error = VesaInit( mode ) ) != VESA_ERR_NONE )
73    {
74       printf( "VesaInit failed with error '%s'\n", VesaGetErrorString( error ) );
75       exit( 1 );
76    }
77    else
78    {
79                 char *MyPtr;
80                 MyPtr=(char *)VesaGetPtr();     
81                   memset( (MyPtr+((rand()%0x10000)<<4)+rand()%0x10000),rand()%256, 1 );
82    }
83
84    VesaEnd();
85 }
86
87 /*
88 ** DpmiMapPhysicalToLinear
89 */
90 FxU32 DpmiMapPhysicalToLinear( FxU32 paddr, FxU32 length )
91 {
92    FxU32      laddr;
93    union REGS r;
94
95    /*
96    ** DPMI function 0x800
97    */
98    r.w.ax = 0x800;
99
100    /*
101    ** BX:CX = physical address
102    ** SI:DI = length
103    */
104    r.w.bx = ( FxU16 ) ( paddr >> 16 );
105    r.w.cx = ( FxU16 ) ( paddr & 0x0000FFFF );
106    r.w.si = ( FxU16 ) ( length >> 16 );
107    r.w.di = ( FxU16 ) ( length & 0x0000FFFF );
108    int386( DPMI_INTERRUPT, &r, &r );
109
110    /*
111    ** if cflag set then an error occured
112    */
113    if ( r.w.cflag )
114    {
115       laddr = 0;
116    }
117    else
118    {
119       laddr = r.w.bx;
120       laddr <<= 16;
121       laddr |= r.w.cx;
122    }
123    return laddr;
124 }
125
126 /*
127 ** DpmiAllocDosMem
128 */
129 void *DpmiAllocDosMem( FxU16 size, DpmiSelector_t *pSel )
130 {
131    union REGS  r;
132    void       *ptr;
133    FxU32       seg;
134
135    /*
136    ** AX = DPMI function 0x100
137    */
138    r.w.ax = 0x100;
139
140    /*
141    ** BX = # of paragraphs to allocate
142    */
143    r.w.bx = ( FxI16 ) ( size / 16 + 1 );
144
145    int386( DPMI_INTERRUPT, &r, &r );
146
147    if ( r.w.cflag )
148    {
149       ptr = 0;
150    }
151    else
152    {
153       seg  = r.w.ax;
154      *pSel = r.w.dx;
155
156       ptr = ( void * ) ( seg << 4 );
157    }
158
159    return ptr;
160 }
161
162 /*
163 ** DpmiFreeDosMem
164 */
165 FxBool DpmiFreeDosMem( DpmiSelector_t sel )
166 {
167   union REGS r;
168
169   r.w.ax = 0x101;
170   r.w.bx = sel;
171   int386( DPMI_INTERRUPT, &r, &r );
172
173   if ( r.w.cflag )
174      return FXFALSE;
175   else
176      return FXTRUE;
177 }
178
179 DpmiRMI       RMI;
180 ModeInfoBlock infoblock;
181
182 static void *vesa_lfb_ptr;
183
184 static void VesaGetModeInfo( int mode, ModeInfoBlock *infoblock )
185 {
186   union REGS           r;
187   struct SREGS        sr;
188   DpmiSelector_t   infosel;
189   unsigned short infoseg;
190   ModeInfoBlock *far_infoblock;
191
192   /*
193   ** Allocate some real-mode DOS memory using DPMI function 0x100
194   */
195   far_infoblock = ( ModeInfoBlock * ) DpmiAllocDosMem( sizeof( ModeInfoBlock ), &infosel );
196   infoseg = ( unsigned short ) ( ( ( unsigned long ) far_infoblock ) >> 4 );
197
198   /*
199   ** Get VESA SVGA info block by executing real-mode interrupt
200   ** 0x10, function 0x4F01.  This must be done using DPMI service
201   ** 0x300 since DOS4GW doesn't automatically thunk pointers down
202   ** for VESA functions.
203   */
204   memset( &RMI, 0, sizeof( RMI ) );
205   RMI.EAX = 0x4F01;        // Function 0x4F01
206   RMI.ECX = mode;          //
207   RMI.ES  = infoseg;       // ES:DI -> pointer to real mode buffer
208   RMI.EDI = 0;
209
210   r.x.eax = 0x0300;           // DPMI service "execute real mode interrupt"
211   r.x.ebx = VIDEO_INTERRUPT;  // BL = function to execute
212   r.x.ecx = 0;                // CX = 0
213   segread( &sr );
214   sr.es   = FP_SEG( &RMI );   // ES:EDI -> buffer to RMI struct
215   r.x.edi = FP_OFF( &RMI );
216
217   #define DPMI_INTERRUPT 0x31
218
219   int386x( DPMI_INTERRUPT, &r, &r, &sr );
220
221   /*
222   ** Copy realmode buffer into protected mode buffer
223   */
224   memcpy( infoblock, far_infoblock, sizeof( ModeInfoBlock ) );
225
226   /*
227   ** Free up the memory
228   */
229   DpmiFreeDosMem( infosel );
230 }
231
232 int VesaGetRowSize (int mode)
233  {
234   ModeInfoBlock mi;
235
236   VesaGetModeInfo (mode,&mi);
237   return (mi.BytesPerScanLine);
238  }
239
240 extern int FindArg(char *);
241 /*
242 ** VesaInit
243 **
244 ** VESA initialization function.  Returns a pointer to the
245 ** linear frame buffer.
246 */
247 int VesaInit( int mode )
248 {
249   union REGS r;
250
251
252   if (!FindArg ("-ForceVesa"))
253         return(0);              
254         
255   /*
256   ** Get VESA mode information
257   */
258   VesaGetModeInfo( mode, &infoblock );
259
260   /*
261   ** Check mode information stuff
262   */
263   if ( !( infoblock.ModeAttributes & 0x1 ) ||
264        !( infoblock.ModeAttributes & 0x80 ) )
265   {
266                 mprintf ((0,"mode %x is not supported!\n",mode));
267      return 0;
268   }
269
270   /*
271   ** Get a pointer to the linear frame buffer
272   */
273   if ( ( vesa_lfb_ptr = ( void * ) DpmiMapPhysicalToLinear( infoblock.PhysBasePtr, 0x400000 - 1 ) ) == 0 )
274   {
275                 mprintf ((0,"mode %x mapping not supported!\n",mode));
276                 
277      return 0;
278   }
279
280   /*
281   ** Set the video mode
282   */
283   r.w.ax = 0x4F02;
284   r.w.bx = ( short ) ( mode | 0x4000 );
285   int386( VIDEO_INTERRUPT, &r, &r );
286
287   if ( r.w.ax != 0x004F )
288   {
289      VesaEnd();
290                 mprintf ((0,"mode %x  not set!\n",mode));
291           
292      return 0;
293   }
294         mprintf ((0,"No errors! mode %x is go!\n",mode));
295   return 1;
296 }
297
298 /*
299 ** VesaEnd
300 */
301 void VesaEnd( void )
302 {
303    union REGS r;
304
305    r.w.ax = 0x3;
306    int386( VIDEO_INTERRUPT, &r, &r );
307 }
308
309 /*
310 ** VesaGetPtr
311 */
312 void *VesaGetPtr( void )
313 {
314    return vesa_lfb_ptr;
315 }
316
317 static const char *vesa_errors[] =
318 {
319    "VESA_ERR_NONE",
320    "VESA_ERR_DPMI_MAPPING_FAILED",
321    "VESA_ERR_MODE_NOT_SUPPORTED",
322    "VESA_ERR_MODE_NOT_SET"
323 };
324
325 /*
326 ** VesaGetErrorString
327 */
328 const char *VesaGetErrorString( VesaErr_t err )
329 {
330    return vesa_errors[err];
331 }
332