1 /*
2 */
3 
4 
5 #include <stdlib.h>
6 #include <stdio.h>		/* for printf */
7 #include <string.h>		/* for memset */
8 #include <unistd.h>
9 #include <sys/mman.h>		/* for mmap */
10 #include "vga.h"
11 #include "libvga.h"
12 #include "driver.h"
13 
14 
15 /* New style driver interface. */
16 #include "timing.h"
17 #include "vgaregs.h"
18 #include "interface.h"
19 #include "accel.h"
20 #include "lrmi.h"
21 #include "vbe.h"
22 #define VESAREG_SAVE(i) (VGA_TOTAL_REGS+i)
23 #define VESA_TOTAL_REGS (VGA_TOTAL_REGS + 4024)
24 
25 /* #define VESA_savebitmap 0x0e */
26 int __svgalib_VESA_savebitmap=0x0e;
27 int __svgalib_VESA_textmode=3;
28 
29 static int vesa_init(int, int, int);
30 static void vesa_unlock(void);
31 
32 static int vesa_memory,vesa_chiptype;
33 static int vesa_is_linear, vesa_logical_width, vesa_bpp, vesa_granularity;
34 static int vesa_regs_size, vesa_linear_base, vesa_last_mode_set;
35 static struct LRMI_regs vesa_r;
36 static int vesa_read_write, vesa_read_window, vesa_write_window;
37 static void * LRMI_mem1;
38 
39 static CardSpecs *cardspecs;
40 static struct
41 	{
42 	struct vbe_info_block *info;
43 	struct vbe_mode_info_block *mode;
44 	} vesa_data;
45 
46 static int SVGALIB_VESA[__GLASTMODE+1];
47 
48 static int lrmi_inited=0;
49 
vesa_setpage(int page)50 static void vesa_setpage(int page)
51 {
52 vesa_r.eax=0x4f05;
53 vesa_r.ebx=0;
54 vesa_r.edx=page*64/vesa_granularity;
55 __svgalib_LRMI_int(0x10,&vesa_r);
56 
57 if(vesa_read_write){
58    vesa_r.eax=0x4f05;
59    vesa_r.ebx=1;
60    vesa_r.edx=page*64/vesa_granularity;
61    __svgalib_LRMI_int(0x10,&vesa_r);
62 };
63 }
64 
65 
__svgalib_vesa_inlinearmode(void)66 static int __svgalib_vesa_inlinearmode(void)
67 {
68 return vesa_is_linear;
69 }
70 
71 
72 /* Fill in chipset specific mode information */
73 
vesa_getmodeinfo(int mode,vga_modeinfo * modeinfo)74 static void vesa_getmodeinfo(int mode, vga_modeinfo *modeinfo)
75 {
76     if ((mode < G640x480x256 )
77 	|| mode == G720x348x2)
78 	return __svgalib_vga_driverspecs.getmodeinfo(mode, modeinfo);
79 
80     if(modeinfo->colors==16)return;
81 
82     modeinfo->maxpixels = vesa_memory*1024/modeinfo->bytesperpixel;
83     modeinfo->maxlogicalwidth = 4088; /* just a guess, */
84     modeinfo->startaddressrange = vesa_memory * 1024 - 1;
85     modeinfo->haveblit = 0;
86     modeinfo->flags &= ~HAVE_RWPAGE;
87     modeinfo->flags |= vesa_read_write;  /* sets HAVE_RWPAGE bit */
88 
89     /* for linear need VBE2 */
90     if(vesa_chiptype>=1)
91       if (modeinfo->bytesperpixel >= 1) {
92 	modeinfo->flags |= CAPABLE_LINEAR;
93         if (__svgalib_vesa_inlinearmode())
94 	    modeinfo->flags |= IS_LINEAR;
95       }
96 
97     /* to get the logical scanline width */
98     memset(&vesa_r, 0, sizeof(vesa_r));
99 
100     vesa_r.eax = 0x4f01;
101     vesa_r.ecx = SVGALIB_VESA[mode];
102     vesa_r.es = (unsigned int)vesa_data.mode >> 4;
103     vesa_r.edi = (unsigned int)vesa_data.mode & 0xf;
104 
105     if (!__svgalib_LRMI_int(0x10, &vesa_r)) {
106        fprintf(stderr, "Can't get mode info (vm86 failure)\n");
107        return;
108     }
109     modeinfo->linewidth = vesa_data.mode->bytes_per_scanline;
110 }
111 
112 /* Read and save chipset-specific registers */
vesa_saveregs(unsigned char regs[])113 static int vesa_saveregs(unsigned char regs[])
114 {
115   void * buf;
116   buf=LRMI_mem1;
117   vesa_r.eax=0x4f04;
118   vesa_r.ebx=0;
119   vesa_r.es=((long)buf)>>4;
120   vesa_r.edx=1;
121   vesa_r.ecx=__svgalib_VESA_savebitmap;
122   __svgalib_LRMI_int(0x10,&vesa_r);
123   memcpy(&regs[VGA_TOTAL_REGS],buf,vesa_regs_size);
124     return vesa_regs_size;
125 }
126 
127 /* Set chipset-specific registers */
128 
vesa_setregs(const unsigned char regs[],int mode)129 static void vesa_setregs(const unsigned char regs[], int mode)
130 {
131 
132   void * buf;
133   buf=LRMI_mem1;
134   memcpy(buf,&regs[VGA_TOTAL_REGS],vesa_regs_size);
135   vesa_r.eax=0x4f04;
136   vesa_r.ebx=0;
137   vesa_r.es=((long)buf)>>4;
138   vesa_r.edx=2;
139   vesa_r.ecx=__svgalib_VESA_savebitmap;
140   __svgalib_LRMI_int(0x10,&vesa_r);
141 }
142 
143 
144 /* Return nonzero if mode is available */
145 
vesa_modeavailable(int mode)146 static int vesa_modeavailable(int mode)
147 {
148     struct info *info;
149     ModeTiming *modetiming;
150     ModeInfo *modeinfo;
151 
152 
153     if ((mode < G640x480x256 )
154 	|| mode == G720x348x2)
155 	return __svgalib_vga_driverspecs.modeavailable(mode);
156 
157     info = &__svgalib_infotable[mode];
158 
159     modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
160 
161     modetiming = malloc(sizeof(ModeTiming));
162     if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
163 	free(modetiming);
164 	free(modeinfo);
165 	return 0;
166     }
167     free(modetiming);
168     free(modeinfo);
169 
170 return SVGALIB_VESA[mode];
171 }
172 
vesa_setmode(int mode,int prv_mode)173 static int vesa_setmode(int mode, int prv_mode)
174 {
175     vesa_bpp=1;
176     vesa_granularity=1;
177     if ((mode < G640x480x256)|| (mode == G720x348x2)) {
178 
179         if(__svgalib_vesatext){
180             vesa_r.eax=0x4f02; /* make sure we are in a regular VGA mode before we start */
181             vesa_r.ebx=__svgalib_VESA_textmode;    /* without this, if we start in SVGA mode the result might */
182             __svgalib_LRMI_int(0x10,&vesa_r); /* be something weird */
183         };
184 	return __svgalib_vga_driverspecs.setmode(mode, prv_mode);
185     }
186     if (!vesa_modeavailable(mode)) return 1;
187     vesa_r.eax=0x4f02;
188     vesa_r.ebx=SVGALIB_VESA[mode]|0x8000|(vesa_is_linear*0x4000);
189     vesa_last_mode_set=vesa_r.ebx;
190     __svgalib_LRMI_int(0x10,&vesa_r);
191 
192     vesa_r.eax = 0x4f01;
193     vesa_r.ecx=SVGALIB_VESA[mode];
194     vesa_r.es = (unsigned int)vesa_data.mode >> 4;
195     vesa_r.edi = (unsigned int)vesa_data.mode&0xf;
196     __svgalib_LRMI_int(0x10, &vesa_r);
197     vesa_logical_width=vesa_data.mode->bytes_per_scanline;
198     vesa_bpp=(vesa_data.mode->bits_per_pixel+7)/8;
199     if(vesa_logical_width==0) vesa_logical_width=vesa_bpp*vesa_data.mode->x_resolution;
200                                         	/* if not reported then guess */
201     vesa_granularity=vesa_data.mode->win_granularity;
202     if(vesa_granularity==0)vesa_granularity=64; /* if not reported then guess */
203     if(vesa_chiptype>=1)vesa_linear_base=vesa_data.mode->phys_base_ptr;
204     vesa_read_write=0;
205     vesa_read_window=0;
206     vesa_write_window=0;
207     if((vesa_data.mode->win_a_attributes&6)!=6){
208         vesa_read_write=1;
209         if ((vesa_data.mode->win_b_attributes&2) == 2) vesa_read_window=1;
210         if ((vesa_data.mode->win_b_attributes&4) == 4) vesa_write_window=1;
211     }
212     return 0;
213 }
214 
215 
216 /* Unlock chipset-specific registers */
217 
vesa_unlock(void)218 static void vesa_unlock(void)
219 {
220 }
221 
222 
223 /* Relock chipset-specific registers */
224 /* (currently not used) */
225 
vesa_lock(void)226 static void vesa_lock(void)
227 {
228 }
229 
230 
231 /* Indentify chipset, initialize and return non-zero if detected */
232 
vesa_test(void)233 static int vesa_test(void)
234 {
235 
236     if ((getenv("IOPERM") == NULL) && ((iopl(3) < 0)||(ioperm(0,0x400,1)<0))) {
237 	printf("svgalib(vesa): Cannot get I/O permissions.\n");
238 	exit(-1);
239     }
240 
241     lrmi_inited=1;
242     __svgalib_LRMI_init();
243     vesa_data.info = __svgalib_LRMI_alloc_real(sizeof(struct vbe_info_block)
244 	 + sizeof(struct vbe_mode_info_block));
245     vesa_data.mode = (struct vbe_mode_info_block *)(vesa_data.info + 1);
246     vesa_r.eax = 0x4f00;
247     vesa_r.es = (unsigned int)vesa_data.info >> 4;
248     vesa_r.edi = 0;
249 
250     __svgalib_LRMI_int(0x10, &vesa_r);
251     if (vesa_r.eax!=0x4f) return 0;
252     return !vesa_init(0,0,0);
253 }
254 
255 
256 /* No r/w paging */
vesa_setrdpage(int page)257 static void vesa_setrdpage(int page)
258 {
259 vesa_r.eax=0x4f05;
260 vesa_r.ebx=vesa_read_window;
261 vesa_r.edx=page*64/vesa_granularity;
262 __svgalib_LRMI_int(0x10,&vesa_r);
263 }
vesa_setwrpage(int page)264 static void vesa_setwrpage(int page)
265 {
266 vesa_r.eax=0x4f05;
267 vesa_r.ebx=vesa_write_window;
268 vesa_r.edx=page*64/vesa_granularity;
269 __svgalib_LRMI_int(0x10,&vesa_r);
270 }
271 
272 
273 /* Set display start address (not for 16 color modes) */
274 
vesa_setdisplaystart(int address)275 static void vesa_setdisplaystart(int address)
276 {
277   vesa_r.eax=0x4f07;
278   vesa_r.ebx=0;
279   vesa_r.ecx=address % vesa_logical_width;
280   vesa_r.edx=address / vesa_logical_width;
281 
282   __svgalib_LRMI_int(0x10,&vesa_r);
283 
284 }
285 
286 /* Set logical scanline length (usually multiple of 8) */
287 
vesa_setlogicalwidth(int width)288 static void vesa_setlogicalwidth(int width)
289 {
290   vesa_r.eax=0x4f06;
291   vesa_r.ebx=0;
292   vesa_r.ecx=width / vesa_bpp ;
293   __svgalib_LRMI_int(0x10,&vesa_r);
294   vesa_logical_width=vesa_r.ebx;
295 
296 }
297 
vesa_linear(int op,int param)298 static int vesa_linear(int op, int param)
299 {
300 if (op==LINEAR_ENABLE) {
301   vesa_r.eax=0x4f02;
302   vesa_r.ebx=vesa_last_mode_set|0x4000;
303   __svgalib_LRMI_int(0x10,&vesa_r);
304   vesa_is_linear=1;
305 };
306 
307 if (op==LINEAR_DISABLE){
308   vesa_r.eax=0x4f02;
309   vesa_r.ebx=vesa_last_mode_set;
310   __svgalib_LRMI_int(0x10,&vesa_r);
311   vesa_is_linear=0;
312 };
313 if (op==LINEAR_QUERY_BASE) {return vesa_linear_base ;}
314 if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0;		/* No granularity or range. */
315     else return -1;		/* Unknown function. */
316 }
317 
vesa_match_programmable_clock(int clock)318 static int vesa_match_programmable_clock(int clock)
319 {
320 return clock ;
321 }
vesa_map_clock(int bpp,int clock)322 static int vesa_map_clock(int bpp, int clock)
323 {
324 return clock ;
325 }
vesa_map_horizontal_crtc(int bpp,int pixelclock,int htiming)326 static int vesa_map_horizontal_crtc(int bpp, int pixelclock, int htiming)
327 {
328 return htiming;
329 }
330 /* Function table (exported) */
331 
332 DriverSpecs __svgalib_vesa_driverspecs =
333 {
334     vesa_saveregs,
335     vesa_setregs,
336     vesa_unlock,
337     vesa_lock,
338     vesa_test,
339     vesa_init,
340     vesa_setpage,
341     vesa_setrdpage,
342     vesa_setwrpage,
343     vesa_setmode,
344     vesa_modeavailable,
345     vesa_setdisplaystart,
346     vesa_setlogicalwidth,
347     vesa_getmodeinfo,
348     0,				/* old blit funcs */
349     0,
350     0,
351     0,
352     0,
353     0,				/* ext_set */
354     0,				/* accel */
355     vesa_linear,
356     0,				/* accelspecs, filled in during init. */
357     NULL,                       /* Emulation */
358 };
359 
360 /* Initialize chipset (called after detection) */
361 
vesa_init(int force,int par1,int par2)362 static int vesa_init(int force, int par1, int par2)
363 {
364     short int *mode_list;
365     int i;
366     unsigned char *m;
367     int address;
368 
369     m=mmap(0,1024,PROT_READ,MAP_SHARED,__svgalib_mem_fd,0);
370 
371     address=((long)*(unsigned short *)(m+64))+(((long)*(unsigned short *)(m+66))<<4);
372     if((address<0xa0000)||(address>0xfffff)) {
373        	fprintf(stderr, "Real mode int 0x10 handler not in ROM.\n");
374         fprintf(stderr, "Try running vga_reset.\n");
375        	return 1;
376     };
377 
378 
379     __svgalib_textprog|=1;
380 
381     /* Get I/O priviledge */
382     if ((getenv("IOPERM") == NULL) && ((iopl(3) < 0)||(ioperm(0,0x400,1)<0))) {
383 	printf("svgalib(vesa): Cannot get I/O permissions.\n");
384 	exit(-1);
385     }
386 
387     if (force) {
388 	vesa_memory = par1;
389 	vesa_chiptype = par2;
390     } else {
391         vesa_memory=4096;
392     };
393 
394     if(!lrmi_inited) {
395         __svgalib_LRMI_init();
396         vesa_data.info = __svgalib_LRMI_alloc_real(sizeof(struct vbe_info_block)
397 	                 + sizeof(struct vbe_mode_info_block));
398         vesa_data.mode = (struct vbe_mode_info_block *)(vesa_data.info + 1);
399         lrmi_inited=1;
400     }
401     for(i=0;i<__GLASTMODE;i++)SVGALIB_VESA[i]=((i<G640x480x256)||(i==G720x348x2));
402 
403     vesa_r.eax = 0x4f00;
404     vesa_r.es = (unsigned int)vesa_data.info >> 4;
405     vesa_r.edi = 0;
406 
407     memcpy(vesa_data.info->vbe_signature, "VBE2", 4);
408 
409     __svgalib_LRMI_int(0x10, &vesa_r);
410 
411     if ((vesa_r.eax & 0xffff) != 0x4f || strncmp(vesa_data.info->vbe_signature, "VESA", 4) != 0) {
412        	fprintf(stderr,"No VESA bios detected!\n");
413         fprintf(stderr,"%04x %i %i %i %i\n",vesa_r.eax,
414         vesa_data.info->vbe_signature[0],
415         vesa_data.info->vbe_signature[1],
416         vesa_data.info->vbe_signature[2],
417         vesa_data.info->vbe_signature[3]);
418         fprintf(stderr,"Try running vga_reset.\n");
419        	return 1;
420     }
421 
422     if(vesa_data.info->vbe_version>=0x0200)vesa_chiptype=1 ; else vesa_chiptype=0;
423     if(vesa_data.info->vbe_version>=0x0300)vesa_chiptype=2 ;
424 
425     vesa_memory = vesa_data.info->total_memory*64;
426 
427     mode_list = (short int *)(vesa_data.info->video_mode_list_seg * 16 + vesa_data.info->video_mode_list_off);
428 
429     while (*mode_list != -1) {
430        memset(&vesa_r, 0, sizeof(vesa_r));
431 
432        vesa_r.eax = 0x4f01;
433        vesa_r.ecx = *mode_list;
434        vesa_r.es = (unsigned int)vesa_data.mode >> 4;
435        vesa_r.edi = (unsigned int)vesa_data.mode & 0xf;
436 
437        if((vesa_chiptype>=1)&&(vesa_data.mode->mode_attributes&0x80))
438           vesa_linear_base=vesa_data.mode->phys_base_ptr;
439        if (!__svgalib_LRMI_int(0x10, &vesa_r)) {
440           fprintf(stderr, "Can't get mode info (vm86 failure)\n");
441           return 1;
442        }
443 #if 1
444        for(i=0;i<=__GLASTMODE;i++)
445           if((infotable[i].xdim==vesa_data.mode->x_resolution)&&
446              (infotable[i].ydim==vesa_data.mode->y_resolution)&&
447              (((vesa_data.mode->rsvd_mask_size==8)&&(infotable[i].bytesperpixel==4))||
448               ((vesa_data.mode->bits_per_pixel==32)&&(infotable[i].bytesperpixel==4))||
449               ((vesa_data.mode->bits_per_pixel==24)&&(infotable[i].bytesperpixel==3))||
450               ((vesa_data.mode->green_mask_size==5)&&(infotable[i].colors==32768))||
451               ((vesa_data.mode->green_mask_size==6)&&(infotable[i].colors==65536))||
452               ((vesa_data.mode->memory_model==VBE_MODEL_PLANAR)&&(infotable[i].colors==16))||
453               ((vesa_data.mode->memory_model==VBE_MODEL_256)&&(infotable[i].colors==256))||
454               ((vesa_data.mode->memory_model==VBE_MODEL_PACKED)&&
455                (infotable[i].colors==256)&&(vesa_data.mode->bits_per_pixel==8)))){
456                   	SVGALIB_VESA[i]=*mode_list;
457                         i=__GLASTMODE+1;
458           };
459 
460 #else
461        if (vesa_data.mode->memory_model == VBE_MODEL_RGB) {
462           if((vesa_data.mode->rsvd_mask_size==8)||(vesa_data.mode->bits_per_pixel==32)) {
463              switch(vesa_data.mode->y_resolution){
464                 case 200: if(vesa_data.mode->x_resolution==320)
465                    SVGALIB_VESA[G320x200x16M32]=*mode_list; break;
466                 case 240: if(vesa_data.mode->x_resolution==320)
467                    SVGALIB_VESA[G320x240x16M32]=*mode_list; break;
468                 case 300: if(vesa_data.mode->x_resolution==400)
469                    SVGALIB_VESA[G400x300x16M32]=*mode_list; break;
470                 case 384: if(vesa_data.mode->x_resolution==512)
471                    SVGALIB_VESA[G512x384x16M32]=*mode_list; break;
472                 case 480: if(vesa_data.mode->x_resolution==640)
473                    SVGALIB_VESA[G640x480x16M32]=*mode_list; break;
474                 case 600: if(vesa_data.mode->x_resolution==800)
475                    SVGALIB_VESA[G800x600x16M32]=*mode_list; break;
476                 case 720: if(vesa_data.mode->x_resolution==960)
477                    SVGALIB_VESA[G960x720x16M32]=*mode_list; break;
478                 case 768: if(vesa_data.mode->x_resolution==1024)
479                    SVGALIB_VESA[G1024x768x16M32]=*mode_list; break;
480                 case 864: if(vesa_data.mode->x_resolution==1152)
481                     SVGALIB_VESA[G1152x864x16M32]=*mode_list; break;
482                 case 1024: if(vesa_data.mode->x_resolution==1280)
483                     SVGALIB_VESA[G1280x1024x16M32]=*mode_list; break;
484                 case 1200: if(vesa_data.mode->x_resolution==1600)
485                    SVGALIB_VESA[G1600x1200x16M32]=*mode_list; break;
486                 case 1440: if(vesa_data.mode->x_resolution==1920)
487                    SVGALIB_VESA[G1920x1440x16M32]=*mode_list; break;
488              }
489           } else {
490               i=0;
491               switch(vesa_data.mode->y_resolution){
492                  case 200: if(vesa_data.mode->x_resolution==320)
493                     i=G320x200x32K; break;
494                  case 240: if(vesa_data.mode->x_resolution==320)
495                     i=G320x240x32K; break;
496                  case 300: if(vesa_data.mode->x_resolution==400)
497                     i=G400x300x32K; break;
498                  case 384: if(vesa_data.mode->x_resolution==512)
499                     i=G512x384x32K; break;
500                  case 480: if(vesa_data.mode->x_resolution==640)
501                     i=G640x480x32K; break;
502                  case 600: if(vesa_data.mode->x_resolution==800)
503                     i=G800x600x32K; break;
504                  case 720: if(vesa_data.mode->x_resolution==960)
505                     i=G960x720x32K; break;
506                  case 768: if(vesa_data.mode->x_resolution==1024)
507                     i=G1024x768x32K; break;
508                  case 864: if(vesa_data.mode->x_resolution==1152)
509                     i=G1152x864x32K; break;
510                  case 1024: if(vesa_data.mode->x_resolution==1280)
511                     i=G1280x1024x32K; break;
512                  case 1200: if(vesa_data.mode->x_resolution==1600)
513                     i=G1600x1200x32K; break;
514                  case 1440: if(vesa_data.mode->x_resolution==1920)
515                     i=G1920x1440x32K; break;
516               };
517               if(i>0)switch(vesa_data.mode->green_mask_size){
518                  case 5:SVGALIB_VESA[i]=*mode_list; break;
519                  case 6:SVGALIB_VESA[i+1]=*mode_list; break;
520                  case 8:if(vesa_data.mode->rsvd_mask_size==0)SVGALIB_VESA[i+2]=*mode_list; break;
521               };
522           };
523        } else if ((vesa_data.mode->memory_model == VBE_MODEL_256) ||
524           	  (vesa_data.mode->memory_model == VBE_MODEL_PACKED)){
525             switch(vesa_data.mode->y_resolution){
526                case 200: if(vesa_data.mode->x_resolution==320)
527                   SVGALIB_VESA[G320x200x256]=*mode_list; break;
528                case 240: if(vesa_data.mode->x_resolution==320) {
529                  if(vesa_data.mode->number_of_planes==8)
530                     SVGALIB_VESA[G320x240x256]=*mode_list;
531                     else SVGALIB_VESA[G320x240x256V]=*mode_list;
532                  };
533                  break;
534                case 300: if(vesa_data.mode->x_resolution==400)
535                   SVGALIB_VESA[G400x300x256]=*mode_list; break;
536                case 384: if(vesa_data.mode->x_resolution==512)
537                   SVGALIB_VESA[G512x384x256]=*mode_list; break;
538                case 480: if(vesa_data.mode->x_resolution==640)
539                   SVGALIB_VESA[G640x480x256]=*mode_list; break;
540                case 600: if(vesa_data.mode->x_resolution==800)
541                   SVGALIB_VESA[G800x600x256]=*mode_list; break;
542                case 720: if(vesa_data.mode->x_resolution==960)
543                   SVGALIB_VESA[G960x720x256]=*mode_list; break;
544                case 768: if(vesa_data.mode->x_resolution==1024)
545                   SVGALIB_VESA[G1024x768x256]=*mode_list; break;
546                case 864: if(vesa_data.mode->x_resolution==1152)
547                   SVGALIB_VESA[G1152x864x256]=*mode_list; break;
548                case 1024: if(vesa_data.mode->x_resolution==1280)
549                   SVGALIB_VESA[G1280x1024x256]=*mode_list; break;
550                case 1200: if(vesa_data.mode->x_resolution==1600)
551                   SVGALIB_VESA[G1600x1200x256]=*mode_list; break;
552                case 1440: if(vesa_data.mode->x_resolution==1920)
553                   SVGALIB_VESA[G1920x1440x256]=*mode_list; break;
554             }
555        }
556 #endif
557        mode_list++;
558     };
559     vesa_r.eax=0x4f04;
560     vesa_r.edx=0;
561     vesa_r.ecx=__svgalib_VESA_savebitmap;
562     vesa_r.ebx=0;
563     __svgalib_LRMI_int(0x10,&vesa_r);
564     vesa_regs_size=vesa_r.ebx*64;
565 
566     SVGALIB_VESA[TEXT]=3;
567 
568     cardspecs = malloc(sizeof(CardSpecs));
569     cardspecs->videoMemory = vesa_memory;
570     cardspecs->maxPixelClock4bpp = 300000;
571     cardspecs->maxPixelClock8bpp = 300000;
572     cardspecs->maxPixelClock16bpp = 300000;
573     cardspecs->maxPixelClock24bpp = 300000;
574     cardspecs->maxPixelClock32bpp = 300000;
575     cardspecs->flags = CLOCK_PROGRAMMABLE;
576     cardspecs->maxHorizontalCrtc = 4088;
577     cardspecs->nClocks =1;
578     cardspecs->clocks = NULL;
579     cardspecs->mapClock = vesa_map_clock;
580     cardspecs->mapHorizontalCrtc = vesa_map_horizontal_crtc;
581     cardspecs->matchProgrammableClock=vesa_match_programmable_clock;
582     __svgalib_driverspecs = &__svgalib_vesa_driverspecs;
583 
584     LRMI_mem1 = __svgalib_LRMI_alloc_real(vesa_regs_size);
585 
586     __svgalib_banked_mem_base=0xa0000;
587     __svgalib_banked_mem_size=0x10000;
588     if(vesa_chiptype>=1) {
589       __svgalib_linear_mem_base=vesa_linear_base;
590       __svgalib_linear_mem_size=vesa_memory*0x400;
591     };
592 
593     if (__svgalib_driver_report) {
594 	printf("Using VESA driver, %iKB. %s\n",vesa_memory,
595                 (vesa_chiptype==2)?"VBE3":(vesa_chiptype?"VBE2.0":"VBE1.2"));
596     }
597     return 0;
598 }
599 
600