1 /**
2 ** svgalib.c ---- Linux driver, i.e. an interface to SVGALIB
3 **
4 ** Copyright (c) 1995 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
5 ** [e-mail: csaba@vuse.vanderbilt.edu]
6 **
7 ** This file is part of the GRX graphics library.
8 **
9 ** The GRX graphics library is free software; you can redistribute it
10 ** and/or modify it under some conditions; see the "copying.grx" file
11 ** for details.
12 **
13 ** This library is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 **
17 **/
18
19 #include <string.h>
20 #include <vga.h>
21
22 #include "libgrx.h"
23 #include "grdriver.h"
24 #include "arith.h"
25 #include "memcopy.h"
26 #include "memfill.h"
27
28 #define NUM_MODES 80 /* max # of supported modes */
29 #define NUM_EXTS 15 /* max # of mode extensions */
30
31 static int initted = (-1);
32 static int initmode = 0;
33 static int isEGA;
34
detect(void)35 static int detect(void)
36 {
37 if(initted < 0) {
38 #if 0
39 /* make sure VGA will map to 64K boundary ... */
40 long endmem = (long)(sbrk(0));
41 if((endmem & 0xffffL) != 0) {
42 brk((void *)((endmem + 0xffffL) & ~0xffffL));
43 }
44 #endif
45 if(vga_init() >= 0) {
46 initted = 1;
47 isEGA = (vga_getcurrentchipset() == EGA);
48 initmode = vga_getcurrentmode();
49 }
50 else initted = 0;
51 }
52 return((initted > 0) ? TRUE : FALSE);
53 }
54
reset(void)55 static void reset(void)
56 {
57 if(initted > 0 && vga_getcurrentmode() != initmode)
58 vga_setmode(initmode);
59 }
60
setrwbanks(int rb,int wb)61 static void setrwbanks(int rb,int wb)
62 {
63 vga_setreadpage(rb);
64 vga_setwritepage(wb);
65 }
66
loadcolor(int c,int r,int g,int b)67 static void loadcolor(int c,int r,int g,int b)
68 {
69 vga_setpalette(c,(r >> 2),(g >> 2),(b >> 2));
70 }
71
setmode(GrVideoMode * mp,int noclear)72 static int setmode(GrVideoMode *mp,int noclear)
73 {
74 vga_setmode(mp->mode);
75 if (mp->extinfo->flags & GR_VMODEF_LINEAR) {
76 if (vga_setlinearaddressing() == -1)
77 return(FALSE);
78 }
79 mp->extinfo->frame = (char *)vga_getgraphmem();
80 return(TRUE);
81 }
82
settext(GrVideoMode * mp,int noclear)83 static int settext(GrVideoMode *mp,int noclear)
84 {
85 vga_setmode(mp->mode);
86 return(TRUE);
87 }
88
89 GrVideoModeExt _GrViDrvEGAVGAtextModeExt = {
90 GR_frameText, /* frame driver */
91 NULL, /* frame driver override */
92 NULL, /* frame buffer address */
93 { 6, 6, 6 }, /* color precisions */
94 { 0, 0, 0 }, /* color component bit positions */
95 0, /* mode flag bits */
96 settext, /* mode set */
97 NULL, /* virtual size set */
98 NULL, /* virtual scroll */
99 NULL, /* bank set function */
100 NULL, /* double bank set function */
101 NULL, /* color loader */
102 };
103
104 static GrVideoModeExt exts[NUM_EXTS];
105 static GrVideoMode modes[NUM_MODES] = {
106 /* pres. bpp wdt hgt mode scan priv. &ext */
107 { TRUE, 4, 80, 25, TEXT, 160, 0, &_GrViDrvEGAVGAtextModeExt },
108 { 0 }
109 };
110
build_video_mode(vga_modeinfo * ip,GrVideoMode * mp,GrVideoModeExt * ep)111 static int build_video_mode(
112 vga_modeinfo *ip,
113 GrVideoMode *mp,
114 GrVideoModeExt *ep
115 ){
116 mp->present = TRUE;
117 mp->width = ip->width;
118 mp->height = ip->height;
119 mp->lineoffset = ip->linewidth;
120 mp->extinfo = NULL;
121 mp->privdata = 0;
122 ep->drv = NULL;
123 ep->frame = NULL; /* filled in after mode set */
124 ep->flags = 0;
125 ep->setup = setmode;
126 ep->setvsize = NULL; /* tbd */
127 ep->scroll = NULL; /* tbd */
128 ep->setbank = isEGA ? NULL : vga_setpage;
129 ep->setrwbanks = (ip->flags & HAVE_RWPAGE) ? setrwbanks : NULL;
130 ep->loadcolor = NULL;
131 switch(ip->colors) {
132 #ifdef INOUTP_FRAMEDRIVERS
133 case 2:
134 mp->bpp = 1;
135 ep->mode = GR_frameEGAVGA1;
136 ep->cprec[0] =
137 ep->cprec[1] =
138 ep->cprec[2] = 1;
139 ep->cpos[0] =
140 ep->cpos[1] =
141 ep->cpos[2] = 0;
142 break;
143 case 16:
144 mp->bpp = 4;
145 ep->mode = isEGA ? GR_frameEGA4 : GR_frameSVGA4;
146 ep->cprec[0] =
147 ep->cprec[1] =
148 ep->cprec[2] = isEGA ? 2 : 6;
149 ep->cpos[0] =
150 ep->cpos[1] =
151 ep->cpos[2] = 0;
152 ep->loadcolor = loadcolor;
153 break;
154 #endif
155 case 256:
156 mp->bpp = 8;
157 if (ip->flags & IS_MODEX)
158 #ifdef INOUTP_FRAMEDRIVERS
159 ep->mode = GR_frameVGA8X;
160 #else
161 return(FALSE);
162 #endif
163 else
164 if (ip->flags & CAPABLE_LINEAR) {
165 ep->mode = GR_frameSVGA8_LFB;
166 ep->flags|= GR_VMODEF_LINEAR;
167 } else
168 ep->mode = GR_frameSVGA8;
169 ep->cprec[0] =
170 ep->cprec[1] =
171 ep->cprec[2] = 6;
172 ep->cpos[0] =
173 ep->cpos[1] =
174 ep->cpos[2] = 0;
175 ep->loadcolor = loadcolor;
176 break;
177 case 32*1024:
178 mp->bpp = 15;
179 if (ip->flags & CAPABLE_LINEAR) {
180 ep->mode = GR_frameSVGA16_LFB;
181 ep->flags|= GR_VMODEF_LINEAR;
182 } else
183 ep->mode = GR_frameSVGA16;
184 ep->cprec[0] =
185 ep->cprec[1] =
186 ep->cprec[2] = 5;
187 ep->cpos[0] = 10;
188 ep->cpos[1] = 5;
189 ep->cpos[2] = 0;
190 break;
191 case 64*1024:
192 mp->bpp = 16;
193 if (ip->flags & CAPABLE_LINEAR) {
194 ep->mode = GR_frameSVGA16_LFB;
195 ep->flags|= GR_VMODEF_LINEAR;
196 } else
197 ep->mode = GR_frameSVGA16;
198 ep->cprec[0] = 5;
199 ep->cprec[1] = 6;
200 ep->cprec[2] = 5;
201 ep->cpos[0] = 11;
202 ep->cpos[1] = 5;
203 ep->cpos[2] = 0;
204 break;
205 case 16*1024*1024:
206 mp->bpp = 24;
207 if (ip->flags & CAPABLE_LINEAR) {
208 ep->mode = GR_frameSVGA24_LFB;
209 ep->flags|= GR_VMODEF_LINEAR;
210 } else
211 ep->mode = GR_frameSVGA24;
212 ep->cprec[0] =
213 ep->cprec[1] =
214 ep->cprec[2] = 8;
215 ep->cpos[0] = 16;
216 ep->cpos[1] = 8;
217 ep->cpos[2] = 0;
218 if(ip->bytesperpixel == 3) break;
219 mp->bpp = 32;
220 ep->mode = (ip->flags & CAPABLE_LINEAR) ? GR_frameSVGA32L_LFB
221 : GR_frameSVGA32L;
222 if(!(ip->flags & RGB_MISORDERED)) break;
223 ep->cpos[0] = 24;
224 ep->cpos[1] = 16;
225 ep->cpos[2] = 8;
226 ep->mode = (ip->flags & CAPABLE_LINEAR) ? GR_frameSVGA32H_LFB
227 : GR_frameSVGA32H;
228 break;
229 default:
230 return(FALSE);
231 }
232 return(TRUE);
233 }
234
add_video_mode(GrVideoMode * mp,GrVideoModeExt * ep,GrVideoMode ** mpp,GrVideoModeExt ** epp)235 static void add_video_mode(
236 GrVideoMode *mp, GrVideoModeExt *ep,
237 GrVideoMode **mpp,GrVideoModeExt **epp
238 ){
239 if(*mpp < &modes[NUM_MODES]) {
240 if(!mp->extinfo) {
241 GrVideoModeExt *etp = &exts[0];
242 while(etp < *epp) {
243 if(memcmp(etp,ep,sizeof(GrVideoModeExt)) == 0) {
244 mp->extinfo = etp;
245 break;
246 }
247 etp++;
248 }
249 if(!mp->extinfo) {
250 if(etp >= &exts[NUM_EXTS]) return;
251 sttcopy(etp,ep);
252 mp->extinfo = etp;
253 *epp = ++etp;
254 }
255 }
256 sttcopy(*mpp,mp);
257 (*mpp)++;
258 }
259 }
260
init(char * options)261 static int init(char *options)
262 {
263 if(detect()) {
264 vga_modeinfo *mdinfo;
265 GrVideoMode mode,*modep = &modes[1];
266 GrVideoModeExt ext, *extp = &exts[0];
267 int mindex;
268 memzero(modep,(sizeof(modes) - sizeof(modes[0])));
269 for(mindex = G320x200x16; mindex <= GLASTMODE; mindex++) {
270 if(!(vga_hasmode(mindex))) continue;
271 if(!(mdinfo = vga_getmodeinfo(mindex))) continue;
272 if(!(build_video_mode(mdinfo,&mode,&ext))) continue;
273 mode.mode = mindex;
274 add_video_mode(&mode,&ext,&modep,&extp);
275 }
276 _GrVideoDriverSVGALIB.adapter = isEGA ? GR_EGA : GR_VGA;
277 return(TRUE);
278 }
279 return(FALSE);
280 }
281
282 GrVideoDriver _GrVideoDriverSVGALIB = {
283 "svgalib", /* name */
284 GR_VGA, /* adapter type */
285 NULL, /* inherit modes from this driver */
286 modes, /* mode table */
287 itemsof(modes), /* # of modes */
288 detect, /* detection routine */
289 init, /* initialization routine */
290 reset, /* reset routine */
291 _gr_selectmode, /* standard mode select routine */
292 0 /* no additional capabilities */
293 };
294
295