Subversion Repositories shark

Rev

Rev 1063 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1063 tullio 1
 
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation; either version 2 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program; if not, write to the Free Software
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 *
17
 */
18
 
2 pj 19
#include <ll/i386/hw-data.h>
20
#include <ll/i386/mem.h>
21
#include <ll/i386/cons.h>
22
#include <ll/sys/ll/ll-func.h>
23
 
635 giacomo 24
#include "drivers/gd.h"
2 pj 25
 
26
#include "drivers/s3.h"
27
#include "drivers/trident.h"
28
#include "drivers/vesa.h"
29
#include "drivers/chips.h"
30
 
31
BYTE bus, dev;
32
ModeInfoBlock vbemi;
33
BYTE actbank;
34
BYTE type;
35
 
36
DWORD flb=0;
37
int linear;
38
BYTE trylinear;
39
/*BYTE gmode = FALSE;*/
40
 
41
#define NMODES 13
42
static struct gmode allmodes[NMODES] = {
43
        {640, 400, 640, 8, 0x100},
44
        {640, 480, 640, 8, 0x101},
45
        {800, 600, 800, 8, 0x103},
46
        {1024, 768, 1024, 8, 0x105},
47
        {640, 480, 1280, 15, 0x110},
48
        {800, 600, 1600, 15, 0x113},
49
        {1024, 768, 2048, 15, 0x116},
50
        {640, 480, 1280, 16, 0x111},
51
        {800, 600, 1600, 16, 0x114},
52
        {1024, 768, 2048, 16, 0x117},
53
        {640, 480, 1920, 24, 0x112},
54
        {800, 600, 2400, 24, 0x115},
55
        {1024, 768, 3072, 24, 0x118}
56
};
57
static struct gmode actualmode;
58
 
59
 
60
static int myceil(float f)
61
{
62
                int i = (int) f;
63
                float f1 = f - i;
64
 
65
                if (f1 != 0) {
66
                                return i + 1;
67
                } else {
68
                                return i;
69
                }
70
}
71
 
72
/************************************************************************/
73
/*          GD Common Interface             */
74
/************************************************************************/
75
int gd_init(WORD flags)
76
{
77
        memset(&actualmode, 0, sizeof(struct gmode));
78
        type = UNKNOWN;
79
 
80
        /* VESA driver needs the V86 Mode... */
444 giacomo 81
        vm86_init();
2 pj 82
 
83
        /* First, check VESA... */
84
        if (vbe_getinfo() == 1) {
85
                type = VESA;
86
                if (flags & NOLINEAR) {
87
                        trylinear = 0;
88
                } else {
89
                        trylinear = 1;
90
                }
444 giacomo 91
                return 1;
2 pj 92
        }
93
 
94
        /* Then, the other graph cards... Override VESA!!! */
95
        if (trident_test() == 1) {
96
                type = TRIDENT;
97
                trylinear = 0;
98
        }
99
 
100
        if (s3_test() == 1) {
101
                type = S3;
102
                if (flags & NOLINEAR) {
103
                        trylinear = 0;
104
                } else {
105
                        trylinear = 1;
106
                }
107
                return 1;
108
        }
109
 
110
        if (type == UNKNOWN) {
111
                return -1;
112
        }
444 giacomo 113
 
2 pj 114
        return -2;
115
}
116
 
117
void gd_showmodeinfo(void)
118
{
119
        cprintf("Mode number %x\n", actualmode.modenum);
120
        cprintf("MaxX: %u\n", actualmode.xdim);
121
        cprintf("MaxY: %u\n", actualmode.ydim);
122
        cprintf("BPR:  %u\n", actualmode.bpr);
123
}
124
 
125
void gd_showinfo(void)
126
{
127
        DWORD addr;
128
 
129
        addr = gd_getflb();
130
 
131
        if (addr != 0) {
132
                cprintf ("\t gd: Frame Linear Buffer @ %lx (%luM)\n",
133
                        addr, (addr / 0x1000000));
134
        }
135
 
136
        if (type == VESA) {
137
                cprintf("Vesa SVGA card\n");
138
                vbe_showinfo();
139
        }
140
        if (type == TRIDENT) {
141
                cprintf("Trident graphic card\n");
142
                trident_showinfo();
143
        }
144
 
145
        if (type == S3) {
146
                cprintf("S3 graphic card\n");
147
                s3_showinfo();
148
        }
149
}
150
 
151
int gd_setmode(WORD mode)
152
{
153
        WORD app;
154
        int i;
155
#ifndef VM86
156
        BYTE p1, p2;
157
#endif
158
 
159
        if (mode == 0) {
160
                X_REGS16 inregs, outregs;
161
                X_SREGS16 sregs;
162
 
163
                if (actualmode.modenum != 0) {
164
                        inregs.x.ax = 0x03;
165
#ifndef VM86
166
                        p1 = inp(0x21);
167
                        p2 = inp(0xA1);
168
                        outp(0x21,0xFF);
169
                        outp(0xA1,0xFF);
170
                        X_callBIOS(0x10, &inregs, &outregs, &sregs);
171
                        outp(0x21,p1);
172
                        outp(0xA1,p2);
173
#else
174
                        vm86_callBIOS(0x10, &inregs, &outregs, &sregs);
175
#endif
176
                }
177
                return 1;
178
        }
179
 
180
        for (i = 0; i < NMODES; i++) {
181
                if ((mode == allmodes[i].modenum)) {
182
                        memcpy(&actualmode, &(allmodes[i]), sizeof(struct gmode));
183
                }
184
        }
185
 
186
        if (type == VESA) {
444 giacomo 187
 
2 pj 188
                if (vbe_getmodeinfo(&vbemi, mode) < 0) {
444 giacomo 189
                        return -1;
190
                }
2 pj 191
 
192
                app = mode;
193
                if (trylinear) {
194
                        /*  try linear...   */
195
                        mode = mode | 0x4000;
196
                        linear = TRUE;
197
                        if (vbe_setmode(mode) == 1) {
198
                                return linear;
199
                        }
200
                }
201
                actbank = 0;
202
                Load_Write_Bank_256(0);
203
                linear = FALSE;
204
                mode = app;
205
                if (vbe_setmode(mode) < 0) {
206
                        return -1;
207
                }
208
                return linear;
209
        }
210
 
211
        if (type == S3) {
212
/* Still use VESA to open graph... */
213
                if (vbe_getmodeinfo(&vbemi, mode) < 0) {
214
                        return -1;
215
                }
216
                if (vbe_setmode(mode) < 0) {
217
                        return -1;
218
                }
219
                if ((flb != 0) && trylinear) {
220
                        linear = TRUE;
221
                        s3_linear(flb);
222
                        return TRUE;
223
                }
224
                linear = FALSE;
225
                actbank = 0;
226
                Load_Write_Bank_256(0);
227
                return FALSE;
228
        }
229
 
230
        if (type == TRIDENT) {
231
/* Still use VESA to open graph... */
232
        if (vbe_getmodeinfo(&vbemi, mode) < 0) {
233
                return -1;
234
        }
235
        if (vbe_setmode(mode) < 0) {
236
                return -1;
237
        }
238
 
239
        actbank = 0;
240
        Load_Write_Bank_256(0);
241
        return FALSE;
242
        }
243
 
244
        return -2;
245
}
246
 
247
DWORD gd_getflb(void)
248
{
249
        if (type == VESA) {
250
        return vbe_getflb();
251
        }
252
        if (type == S3) {
253
        return flb;
254
        }
255
        return 0;
256
}
257
 
258
DWORD gd_getmem(void)
259
{
260
        if (type == VESA) {
261
        return vbe_getmem();
262
        }
263
        if (type == S3) {
264
        return s3_getmem();
265
        }
266
        if (type == TRIDENT) {
267
        return trident_getmem();
268
        }
269
 
270
        return 0;
271
}
272
 
273
WORD gd_getbpr(void)
274
{
275
        if (actualmode.bpr) return actualmode.bpr;
276
        return -2;
277
}
278
 
51 pj 279
int gd_getmodeinfo(grx_vga_modeinfo *m)
2 pj 280
{
281
        if (actualmode.modenum == 0) {
282
        return -1;
283
        }
284
 
285
        m->width = actualmode.xdim;
286
        m->height = actualmode.ydim;
287
        m->bytesperpixel = (myceil((float)actualmode.bpp / 8));
288
/*    m->colors = myexp(2, actualmode.bpp); */
289
        m->colors = 1 << actualmode.bpp;
290
        m->linewidth = gd_getbpr();
291
        m->maxlogicalwidth = gd_getbpr(); /* 4 the moment... */
292
        m->startaddressrange = 0;   /* don't know :( */
293
        m->maxpixels = gd_getmem() / m->bytesperpixel;
294
        m->haveblit = 0;
295
        m->flags = 0;
296
 
297
        /* Extended fields: */
298
        m->chiptype = type;     /* Chiptype detected */
299
        m->memory = gd_getmem();
300
        m->linewidth_unit = 0;  /* don't know :( */
301
        if (linear) {
302
        m->linear_aperture = (LIN_ADDR)gd_getflb();
303
        m->aperture_size = gd_getmem();
304
        } else {
305
        m->linear_aperture = 0;
306
        m->aperture_size = 0xFFFF;
307
        }
308
        m->set_aperture_page = NULL;
309
        m->extensions = NULL;
310
        return 1;
311
}
312
 
313
void Load_Write_Bank_256(BYTE bank)
314
{
315
        if (bank != actbank) {
316
        actbank = bank;
317
        if (type == VESA) {
318
                if (vbe_setbank(&vbemi, bank) < 0)
319
                        ll_abort(259);
320
        }
321
        if (type == S3) {
322
                s3_setpage(bank);
323
        }
324
        if (type == TRIDENT) {
325
                trident_setpage(bank);
326
        }
327
        }
328
}
329
 
330
/************************************************************************/
331
/*          BANK HANDLING FUNCS             */
332
/************************************************************************/
333
 
334
LIN_ADDR start_address(WORD bpr, WORD x, WORD y)
335
{
336
        LIN_ADDR a;
337
 
338
        a = (LIN_ADDR)(y * bpr +x);
339
        return a;
340
}
341
 
342
void Seg_Off_256(WORD x, WORD y, WORD pitch, WORD *offs, WORD *seg)
343
{
344
        DWORD a;
345
 
346
        a = y * pitch + x;
347
        *offs = a & 0x0000FFFF;
348
        *seg = a >> 16;
349
}
350
 
351
void Seg_Off_Hi(WORD x, WORD y, WORD pitch, WORD *offs, WORD *seg)
352
{
353
        DWORD a;
354
 
355
        a = y * pitch + x * 2;
356
        *offs = a & 0x0000FFFF;
357
        *seg = a >> 16;
358
}
359
 
360
int gd_modenum(WORD x, WORD y, BYTE depth)
361
{
362
        int  mode, i;
363
 
364
        mode = -1;
365
 
366
        for (i = 0; i < NMODES; i++) {
367
        if ((depth == allmodes[i].bpp) && (x == allmodes[i].xdim) && (y == allmodes[i].ydim)) {
368
                mode = allmodes[i].modenum;
369
        } else {
370
        }
371
        }
372
 
373
        if ((mode != -1) && (vbe_checkmode(mode) != -1))
374
                return mode;
375
        return -1;
376
}