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