OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [video/] [fbcon-vga-planes.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/drivers/video/fbcon-vga-planes.c -- Low level frame buffer operations
3
 *                                for VGA 4-plane modes
4
 *
5
 * Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
6
 * Based on code by Michael Schmitz
7
 * Based on the old macfb.c 4bpp code by Alan Cox
8
 *
9
 * This file is subject to the terms and conditions of the GNU General
10
 * Public License.  See the file COPYING in the main directory of this
11
 * archive for more details.  */
12
 
13
#include <linux/module.h>
14
#include <linux/tty.h>
15
#include <linux/console.h>
16
#include <linux/string.h>
17
#include <linux/fb.h>
18
#include <linux/vt_buffer.h>
19
 
20
#include <asm/io.h>
21
 
22
#include <video/fbcon.h>
23
#include <video/fbcon-vga-planes.h>
24
 
25
#define GRAPHICS_ADDR_REG 0x3ce         /* Graphics address register. */
26
#define GRAPHICS_DATA_REG 0x3cf         /* Graphics data register. */
27
 
28
#define SET_RESET_INDEX 0               /* Set/Reset Register index. */
29
#define ENABLE_SET_RESET_INDEX 1        /* Enable Set/Reset Register index. */
30
#define DATA_ROTATE_INDEX 3             /* Data Rotate Register index. */
31
#define GRAPHICS_MODE_INDEX 5           /* Graphics Mode Register index. */
32
#define BIT_MASK_INDEX 8                /* Bit Mask Register index. */
33
 
34
/* The VGA's weird architecture often requires that we read a byte and
35
   write a byte to the same location.  It doesn't matter *what* byte
36
   we write, however.  This is because all the action goes on behind
37
   the scenes in the VGA's 32-bit latch register, and reading and writing
38
   video memory just invokes latch behavior.
39
 
40
   To avoid race conditions (is this necessary?), reading and writing
41
   the memory byte should be done with a single instruction.  One
42
   suitable instruction is the x86 bitwise OR.  The following
43
   read-modify-write routine should optimize to one such bitwise
44
   OR. */
45
static inline void rmw(volatile char *p)
46
{
47
        readb(p);
48
        writeb(1, p);
49
}
50
 
51
/* Set the Graphics Mode Register.  Bits 0-1 are write mode, bit 3 is
52
   read mode. */
53
static inline void setmode(int mode)
54
{
55
        outb(GRAPHICS_MODE_INDEX, GRAPHICS_ADDR_REG);
56
        outb(mode, GRAPHICS_DATA_REG);
57
}
58
 
59
/* Select the Bit Mask Register. */
60
static inline void selectmask(void)
61
{
62
        outb(BIT_MASK_INDEX, GRAPHICS_ADDR_REG);
63
}
64
 
65
/* Set the value of the Bit Mask Register.  It must already have been
66
   selected with selectmask(). */
67
static inline void setmask(int mask)
68
{
69
        outb(mask, GRAPHICS_DATA_REG);
70
}
71
 
72
/* Set the Data Rotate Register.  Bits 0-2 are rotate count, bits 3-4
73
   are logical operation (0=NOP, 1=AND, 2=OR, 3=XOR). */
74
static inline void setop(int op)
75
{
76
        outb(DATA_ROTATE_INDEX, GRAPHICS_ADDR_REG);
77
        outb(op, GRAPHICS_DATA_REG);
78
}
79
 
80
/* Set the Enable Set/Reset Register.  The code here always uses value
81
   0xf for this register.  */
82
static inline void setsr(int sr)
83
{
84
        outb(ENABLE_SET_RESET_INDEX, GRAPHICS_ADDR_REG);
85
        outb(sr, GRAPHICS_DATA_REG);
86
}
87
 
88
/* Set the Set/Reset Register. */
89
static inline void setcolor(int color)
90
{
91
        outb(SET_RESET_INDEX, GRAPHICS_ADDR_REG);
92
        outb(color, GRAPHICS_DATA_REG);
93
}
94
 
95
/* Set the value in the Graphics Address Register. */
96
static inline void setindex(int index)
97
{
98
        outb(index, GRAPHICS_ADDR_REG);
99
}
100
 
101
void fbcon_vga_planes_setup(struct display *p)
102
{
103
}
104
 
105
void fbcon_vga_planes_bmove(struct display *p, int sy, int sx, int dy, int dx,
106
                   int height, int width)
107
{
108
        char *src;
109
        char *dest;
110
        int line_ofs;
111
        int x;
112
 
113
        setmode(1);
114
        setop(0);
115
        setsr(0xf);
116
 
117
        sy *= fontheight(p);
118
        dy *= fontheight(p);
119
        height *= fontheight(p);
120
 
121
        if (dy < sy || (dy == sy && dx < sx)) {
122
                line_ofs = p->line_length - width;
123
                dest = p->screen_base + dx + dy * p->line_length;
124
                src = p->screen_base + sx + sy * p->line_length;
125
                while (height--) {
126
                        for (x = 0; x < width; x++) {
127
                                readb(src);
128
                                writeb(0, dest);
129
                                dest++;
130
                                src++;
131
                        }
132
                        src += line_ofs;
133
                        dest += line_ofs;
134
                }
135
        } else {
136
                line_ofs = p->line_length - width;
137
                dest = p->screen_base + dx + width + (dy + height - 1) * p->line_length;
138
                src = p->screen_base + sx + width + (sy + height - 1) * p->line_length;
139
                while (height--) {
140
                        for (x = 0; x < width; x++) {
141
                                dest--;
142
                                src--;
143
                                readb(src);
144
                                writeb(0, dest);
145
                        }
146
                        src -= line_ofs;
147
                        dest -= line_ofs;
148
                }
149
        }
150
}
151
 
152
void fbcon_vga_planes_clear(struct vc_data *conp, struct display *p, int sy, int sx,
153
                   int height, int width)
154
{
155
        int line_ofs = p->line_length - width;
156
        char *where;
157
        int x;
158
 
159
        setmode(0);
160
        setop(0);
161
        setsr(0xf);
162
        setcolor(attr_bgcol_ec(p, conp));
163
        selectmask();
164
 
165
        setmask(0xff);
166
 
167
        sy *= fontheight(p);
168
        height *= fontheight(p);
169
 
170
        where = p->screen_base + sx + sy * p->line_length;
171
        while (height--) {
172
                for (x = 0; x < width; x++) {
173
                        writeb(0, where);
174
                        where++;
175
                }
176
                where += line_ofs;
177
        }
178
}
179
 
180
void fbcon_ega_planes_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
181
{
182
        int fg = attr_fgcol(p,c);
183
        int bg = attr_bgcol(p,c);
184
 
185
        int y;
186
        u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
187
        char *where = p->screen_base + xx + yy * p->line_length * fontheight(p);
188
 
189
        setmode(0);
190
        setop(0);
191
        setsr(0xf);
192
        setcolor(bg);
193
        selectmask();
194
 
195
        setmask(0xff);
196
        for (y = 0; y < fontheight(p); y++, where += p->line_length)
197
                rmw(where);
198
 
199
        where -= p->line_length * y;
200
        setcolor(fg);
201
        selectmask();
202
        for (y = 0; y < fontheight(p); y++, where += p->line_length)
203
                if (cdat[y]) {
204
                        setmask(cdat[y]);
205
                        rmw(where);
206
                }
207
}
208
 
209
void fbcon_vga_planes_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
210
{
211
        int fg = attr_fgcol(p,c);
212
        int bg = attr_bgcol(p,c);
213
 
214
        int y;
215
        u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
216
        char *where = p->screen_base + xx + yy * p->line_length * fontheight(p);
217
 
218
        setmode(2);
219
        setop(0);
220
        setsr(0xf);
221
        setcolor(fg);
222
        selectmask();
223
 
224
        setmask(0xff);
225
        writeb(bg, where);
226
        rmb();
227
        readb(where); /* fill latches */
228
        setmode(3);
229
        wmb();
230
        for (y = 0; y < fontheight(p); y++, where += p->line_length)
231
                writeb(cdat[y], where);
232
        wmb();
233
}
234
 
235
/* 28.50 in my test */
236
void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
237
                   int count, int yy, int xx)
238
{
239
        u16 c = scr_readw(s);
240
        int fg = attr_fgcol(p, c);
241
        int bg = attr_bgcol(p, c);
242
 
243
        char *where;
244
        int n;
245
 
246
        setmode(2);
247
        setop(0);
248
        selectmask();
249
 
250
        setmask(0xff);
251
        where = p->screen_base + xx + yy * p->line_length * fontheight(p);
252
        writeb(bg, where);
253
        rmb();
254
        readb(where); /* fill latches */
255
        wmb();
256
        selectmask();
257
        for (n = 0; n < count; n++) {
258
                int c = scr_readw(s++) & p->charmask;
259
                u8 *cdat = p->fontdata + c * fontheight(p);
260
                u8 *end = cdat + fontheight(p);
261
 
262
                while (cdat < end) {
263
                        outb(*cdat++, GRAPHICS_DATA_REG);
264
                        wmb();
265
                        writeb(fg, where);
266
                        where += p->line_length;
267
                }
268
                where += 1 - p->line_length * fontheight(p);
269
        }
270
 
271
        wmb();
272
}
273
 
274
/* 6.96 in my test */
275
void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
276
                   int count, int yy, int xx)
277
{
278
        u16 c = scr_readw(s);
279
        int fg = attr_fgcol(p, c);
280
        int bg = attr_bgcol(p, c);
281
 
282
        char *where;
283
        int n;
284
 
285
        setmode(2);
286
        setop(0);
287
        setsr(0xf);
288
        setcolor(fg);
289
        selectmask();
290
 
291
        setmask(0xff);
292
        where = p->screen_base + xx + yy * p->line_length * fontheight(p);
293
        writeb(bg, where);
294
        rmb();
295
        readb(where); /* fill latches */
296
        setmode(3);
297
        wmb();
298
        for (n = 0; n < count; n++) {
299
                int y;
300
                int c = scr_readw(s++) & p->charmask;
301
                u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
302
 
303
                for (y = 0; y < fontheight(p); y++, cdat++) {
304
                        writeb (*cdat, where);
305
                        where += p->line_length;
306
                }
307
                where += 1 - p->line_length * fontheight(p);
308
        }
309
 
310
        wmb();
311
}
312
 
313
void fbcon_vga_planes_revc(struct display *p, int xx, int yy)
314
{
315
        char *where = p->screen_base + xx + yy * p->line_length * fontheight(p);
316
        int y;
317
 
318
        setmode(0);
319
        setop(0x18);
320
        setsr(0xf);
321
        setcolor(0xf);
322
        selectmask();
323
 
324
        setmask(0xff);
325
        for (y = 0; y < fontheight(p); y++) {
326
                rmw(where);
327
                where += p->line_length;
328
        }
329
}
330
 
331
struct display_switch fbcon_vga_planes = {
332
    setup:              fbcon_vga_planes_setup,
333
    bmove:              fbcon_vga_planes_bmove,
334
    clear:              fbcon_vga_planes_clear,
335
    putc:               fbcon_vga_planes_putc,
336
    putcs:              fbcon_vga_planes_putcs,
337
    revc:               fbcon_vga_planes_revc,
338
    fontwidthmask:      FONTWIDTH(8)
339
};
340
 
341
struct display_switch fbcon_ega_planes = {
342
    setup:              fbcon_vga_planes_setup,
343
    bmove:              fbcon_vga_planes_bmove,
344
    clear:              fbcon_vga_planes_clear,
345
    putc:               fbcon_ega_planes_putc,
346
    putcs:              fbcon_ega_planes_putcs,
347
    revc:               fbcon_vga_planes_revc,
348
    fontwidthmask:      FONTWIDTH(8)
349
};
350
 
351
#ifdef MODULE
352
MODULE_LICENSE("GPL");
353
 
354
int init_module(void)
355
{
356
    return 0;
357
}
358
 
359
void cleanup_module(void)
360
{}
361
#endif /* MODULE */
362
 
363
 
364
    /*
365
     *  Visible symbols for modules
366
     */
367
 
368
EXPORT_SYMBOL(fbcon_vga_planes);
369
EXPORT_SYMBOL(fbcon_vga_planes_setup);
370
EXPORT_SYMBOL(fbcon_vga_planes_bmove);
371
EXPORT_SYMBOL(fbcon_vga_planes_clear);
372
EXPORT_SYMBOL(fbcon_vga_planes_putc);
373
EXPORT_SYMBOL(fbcon_vga_planes_putcs);
374
EXPORT_SYMBOL(fbcon_vga_planes_revc);
375
 
376
EXPORT_SYMBOL(fbcon_ega_planes);
377
EXPORT_SYMBOL(fbcon_ega_planes_putc);
378
EXPORT_SYMBOL(fbcon_ega_planes_putcs);
379
 
380
/*
381
 * Overrides for Emacs so that we follow Linus's tabbing style.
382
 * ---------------------------------------------------------------------------
383
 * Local variables:
384
 * c-basic-offset: 8
385
 * End:
386
 */
387
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.