]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/framebuf.jas
This commit was generated by cvs2svn to compensate for changes in r2,
[btb/d2x.git] / unused / vga / framebuf.jas
1 #include <dos.h>\r
2 #include <string.h>\r
3 #include <stdlib.h>\r
4 #include <stdio.h>\r
5 #include <i86.h>\r
6 #include <dos.h>\r
7 #include "mono.h"\r
8 \r
9 \r
10 #include "fxdpmi.h"\r
11 #include "fxvesa.h"\r
12 \r
13 #define DPMI_INTERRUPT 0x31\r
14 const VIDEO_INTERRUPT = 0x10;\r
15 \r
16 typedef struct\r
17 {\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
51 } ModeInfoBlock;\r
52 \r
53 \r
54 void VesaMain()\r
55 {\r
56    FxU16     mode = 0x111;\r
57    VesaErr_t error;\r
58 \r
59    if ( ( error = VesaInit( mode ) ) != VESA_ERR_NONE )\r
60    {\r
61       printf( "VesaInit failed with error '%s'\n", VesaGetErrorString( error ) );\r
62       exit( 1 );\r
63    }\r
64    else\r
65    {\r
66                 char *MyPtr;\r
67                 MyPtr=(char *)VesaGetPtr();     \r
68                   memset( (MyPtr+((rand()%0x10000)<<4)+rand()%0x10000),rand()%256, 1 );\r
69    }\r
70 \r
71    VesaEnd();\r
72 }\r
73 \r
74 /*\r
75 ** DpmiMapPhysicalToLinear\r
76 */\r
77 FxU32 DpmiMapPhysicalToLinear( FxU32 paddr, FxU32 length )\r
78 {\r
79    FxU32      laddr;\r
80    union REGS r;\r
81 \r
82    /*\r
83    ** DPMI function 0x800\r
84    */\r
85    r.w.ax = 0x800;\r
86 \r
87    /*\r
88    ** BX:CX = physical address\r
89    ** SI:DI = length\r
90    */\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
96 \r
97    /*\r
98    ** if cflag set then an error occured\r
99    */\r
100    if ( r.w.cflag )\r
101    {\r
102       laddr = 0;\r
103    }\r
104    else\r
105    {\r
106       laddr = r.w.bx;\r
107       laddr <<= 16;\r
108       laddr |= r.w.cx;\r
109    }\r
110    return laddr;\r
111 }\r
112 \r
113 /*\r
114 ** DpmiAllocDosMem\r
115 */\r
116 void *DpmiAllocDosMem( FxU16 size, DpmiSelector_t *pSel )\r
117 {\r
118    union REGS  r;\r
119    void       *ptr;\r
120    FxU32       seg;\r
121 \r
122    /*\r
123    ** AX = DPMI function 0x100\r
124    */\r
125    r.w.ax = 0x100;\r
126 \r
127    /*\r
128    ** BX = # of paragraphs to allocate\r
129    */\r
130    r.w.bx = ( FxI16 ) ( size / 16 + 1 );\r
131 \r
132    int386( DPMI_INTERRUPT, &r, &r );\r
133 \r
134    if ( r.w.cflag )\r
135    {\r
136       ptr = 0;\r
137    }\r
138    else\r
139    {\r
140       seg  = r.w.ax;\r
141      *pSel = r.w.dx;\r
142 \r
143       ptr = ( void * ) ( seg << 4 );\r
144    }\r
145 \r
146    return ptr;\r
147 }\r
148 \r
149 /*\r
150 ** DpmiFreeDosMem\r
151 */\r
152 FxBool DpmiFreeDosMem( DpmiSelector_t sel )\r
153 {\r
154   union REGS r;\r
155 \r
156   r.w.ax = 0x101;\r
157   r.w.bx = sel;\r
158   int386( DPMI_INTERRUPT, &r, &r );\r
159 \r
160   if ( r.w.cflag )\r
161      return FXFALSE;\r
162   else\r
163      return FXTRUE;\r
164 }\r
165 \r
166 DpmiRMI       RMI;\r
167 ModeInfoBlock infoblock;\r
168 \r
169 static void *vesa_lfb_ptr;\r
170 \r
171 static void VesaGetModeInfo( int mode, ModeInfoBlock *infoblock )\r
172 {\r
173   union REGS           r;\r
174   struct SREGS        sr;\r
175   DpmiSelector_t   infosel;\r
176   unsigned short infoseg;\r
177   ModeInfoBlock *far_infoblock;\r
178 \r
179   /*\r
180   ** Allocate some real-mode DOS memory using DPMI function 0x100\r
181   */\r
182   far_infoblock = ( ModeInfoBlock * ) DpmiAllocDosMem( sizeof( ModeInfoBlock ), &infosel );\r
183   infoseg = ( unsigned short ) ( ( ( unsigned long ) far_infoblock ) >> 4 );\r
184 \r
185   /*\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
190   */\r
191   memset( &RMI, 0, sizeof( RMI ) );\r
192   RMI.EAX = 0x4F01;        // Function 0x4F01\r
193   RMI.ECX = mode;          //\r
194   RMI.ES  = infoseg;       // ES:DI -> pointer to real mode buffer\r
195   RMI.EDI = 0;\r
196 \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
200   segread( &sr );\r
201   sr.es   = FP_SEG( &RMI );   // ES:EDI -> buffer to RMI struct\r
202   r.x.edi = FP_OFF( &RMI );\r
203 \r
204   #define DPMI_INTERRUPT 0x31\r
205 \r
206   int386x( DPMI_INTERRUPT, &r, &r, &sr );\r
207 \r
208   /*\r
209   ** Copy realmode buffer into protected mode buffer\r
210   */\r
211   memcpy( infoblock, far_infoblock, sizeof( ModeInfoBlock ) );\r
212 \r
213   /*\r
214   ** Free up the memory\r
215   */\r
216   DpmiFreeDosMem( infosel );\r
217 }\r
218 \r
219 \r
220 extern int FindArg(char *);\r
221 /*\r
222 ** VesaInit\r
223 **\r
224 ** VESA initialization function.  Returns a pointer to the\r
225 ** linear frame buffer.\r
226 */\r
227 \r
228 \r
229 int VesaInit( int mode )\r
230 {\r
231   union REGS r;\r
232 \r
233         if ( FindArg( "-virge" ) && (mode==0x101) )     {\r
234                 vesa_lfb_ptr = virge_init();\r
235                 return 1;\r
236         }\r
237 \r
238   if (FindArg ("-novesa"))\r
239         return(0);              \r
240         \r
241   /*\r
242   ** Get VESA mode information\r
243   */\r
244   VesaGetModeInfo( mode, &infoblock );\r
245 \r
246   /*\r
247   ** Check mode information stuff\r
248   */\r
249   if ( !( infoblock.ModeAttributes & 0x1 ) ||\r
250        !( infoblock.ModeAttributes & 0x80 ) )\r
251   {\r
252                 mprintf ((0,"mode %x is not supported!\n",mode));\r
253      return 0;\r
254   }\r
255 \r
256   /*\r
257   ** Get a pointer to the linear frame buffer\r
258   */\r
259   if ( ( vesa_lfb_ptr = ( void * ) DpmiMapPhysicalToLinear( infoblock.PhysBasePtr, 0x400000 - 1 ) ) == 0 )\r
260   {\r
261                 mprintf ((0,"mode %x mapping not supported!\n",mode));\r
262                 \r
263      return 0;\r
264   }\r
265 \r
266   /*\r
267   ** Set the video mode\r
268   */\r
269   r.w.ax = 0x4F02;\r
270   r.w.bx = ( short ) ( mode | 0x4000 );\r
271   int386( VIDEO_INTERRUPT, &r, &r );\r
272 \r
273   if ( r.w.ax != 0x004F )\r
274   {\r
275      VesaEnd();\r
276                 mprintf ((0,"mode %x  not set!\n",mode));\r
277           \r
278      return 0;\r
279   }\r
280         mprintf ((0,"No errors! mode %x is go!\n",mode));\r
281   return 1;\r
282 }\r
283 \r
284 /*\r
285 ** VesaEnd\r
286 */\r
287 void VesaEnd( void )\r
288 {\r
289    union REGS r;\r
290 \r
291    r.w.ax = 0x3;\r
292    int386( VIDEO_INTERRUPT, &r, &r );\r
293 }\r
294 \r
295 /*\r
296 ** VesaGetPtr\r
297 */\r
298 void *VesaGetPtr( void )\r
299 {\r
300    return vesa_lfb_ptr;\r
301 }\r
302 \r
303 static const char *vesa_errors[] =\r
304 {\r
305    "VESA_ERR_NONE",\r
306    "VESA_ERR_DPMI_MAPPING_FAILED",\r
307    "VESA_ERR_MODE_NOT_SUPPORTED",\r
308    "VESA_ERR_MODE_NOT_SET"\r
309 };\r
310 \r
311 /*\r
312 ** VesaGetErrorString\r
313 */\r
314 const char *VesaGetErrorString( VesaErr_t err )\r
315 {\r
316    return vesa_errors[err];\r
317 }\r
318 \r
319 \1a\r
320 \1a