Subversion Repositories shark

Rev

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

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