Import 2.4.0-test5pre5
[davej-history.git] / drivers / video / fbcon-hga.c
blob7d6767dee79b69261b522afffa69f0993573cec3
1 /*
2 * linux/drivers/video/fbcon-hga.c -- Low level frame buffer operations for
3 * the Hercules graphics adaptor
5 * Created 25 Nov 1999 by Ferenc Bakonyi (fero@drama.obuda.kando.hu)
6 * Based on fbcon-mfb.c by Geert Uytterhoeven
8 * History:
10 * - Revision 0.1.0 (6 Dec 1999): comment changes
11 * - First release (25 Nov 1999)
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file COPYING in the main directory of this archive for
15 * more details.
18 #include <linux/module.h>
19 #include <linux/tty.h>
20 #include <linux/console.h>
21 #include <linux/string.h>
22 #include <linux/fb.h>
24 #include <video/fbcon.h>
25 #include <video/fbcon-hga.h>
27 #if 0
28 #define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
29 #else
30 #define DPRINTK(args...)
31 #endif
33 #define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
36 * Hercules monochrome
39 static inline u8* rowaddr(struct display *p, u_int row)
41 return p->screen_base + HGA_ROWADDR(row);
44 void fbcon_hga_setup(struct display *p)
46 DPRINTK("fbcon_hga_setup: ll:%d\n", (int)p->line_length);
48 p->next_line = p->line_length;
49 p->next_plane = 0;
52 void fbcon_hga_bmove(struct display *p, int sy, int sx, int dy, int dx,
53 int height, int width)
55 u8 *src, *dest;
56 u_int rows, y1, y2;
58 #if 0
59 if (sx == 0 && dx == 0 && width == p->next_line) {
60 src = p->screen_base+sy*fontheight(p)*width;
61 dest = p->screen_base+dy*fontheight(p)*width;
62 fb_memmove(dest, src, height*fontheight(p)*width);
63 } else
64 #endif
65 if (dy <= sy) {
66 y1 = sy*fontheight(p);
67 y2 = dy*fontheight(p);
68 for (rows = height*fontheight(p); rows--; ) {
69 src = rowaddr(p, y1)+sx;
70 dest = rowaddr(p, y2)+dx;
71 fb_memmove(dest, src, width);
72 y1++;
73 y2++;
75 } else {
76 y1 = (sy+height)*fontheight(p)-1;
77 y2 = (dy+height)*fontheight(p)-1;
78 for (rows = height*fontheight(p); rows--;) {
79 src = rowaddr(p, y1)+sx;
80 dest = rowaddr(p, y2)+dx;
81 fb_memmove(dest, src, width);
82 y1--;
83 y2--;
88 void fbcon_hga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
89 int height, int width)
91 u8 *dest;
92 u_int rows, y;
93 int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
95 DPRINTK("fbcon_hga_clear: sx:%d, sy:%d, height:%d, width:%d\n", sx, sy, height, width);
97 y = sy*fontheight(p);
98 #if 0
99 if (sx == 0 && width == p->next_line) {
100 if (inverse) {
101 fb_memset255(dest, height*fontheight(p)*width);
102 } else {
103 fb_memclear(dest, height*fontheight(p)*width);
105 } else
106 #endif
107 for (rows = height*fontheight(p); rows--; y++) {
108 dest = rowaddr(p, y)+sx;
109 if (inverse) {
110 fb_memset255(dest, width);
111 } else {
112 fb_memclear(dest, width);
117 void fbcon_hga_putc(struct vc_data *conp, struct display *p, int c, int yy,
118 int xx)
120 u8 *dest, *cdat;
121 u_int rows, y, bold, revs, underl;
122 u8 d;
124 cdat = p->fontdata+(c&p->charmask)*fontheight(p);
125 bold = attr_bold(p, c);
126 revs = attr_reverse(p, c);
127 underl = attr_underline(p, c);
128 y = yy*fontheight(p);
130 for (rows = fontheight(p); rows--; y++) {
131 d = *cdat++;
132 if (underl && !rows)
133 d = 0xff;
134 else if (bold)
135 d |= d>>1;
136 if (revs)
137 d = ~d;
138 dest = rowaddr(p, y)+xx;
139 *dest = d;
143 void fbcon_hga_putcs(struct vc_data *conp, struct display *p,
144 const unsigned short *s, int count, int yy, int xx)
146 u8 *dest, *cdat;
147 u_int rows, y, y0, bold, revs, underl;
148 u8 d;
149 u16 c;
151 bold = attr_bold(p,scr_readw(s));
152 revs = attr_reverse(p,scr_readw(s));
153 underl = attr_underline(p,scr_readw(s));
154 y0 = yy*fontheight(p);
156 while (count--) {
157 c = scr_readw(s++) & p->charmask;
158 cdat = p->fontdata+c*fontheight(p);
159 y = y0;
160 for (rows = fontheight(p); rows--; y++) {
161 d = *cdat++;
162 if (underl && !rows)
163 d = 0xff;
164 else if (bold)
165 d |= d>>1;
166 if (revs)
167 d = ~d;
168 dest = rowaddr(p, y)+xx;
169 *dest = d;
171 xx++;
175 void fbcon_hga_revc(struct display *p, int xx, int yy)
177 u8 *dest;
178 u_int rows, y;
180 y = yy*fontheight(p);
181 for (rows = fontheight(p); rows--; y++) {
182 dest = rowaddr(p, y)+xx;
183 *dest = ~*dest;
187 void fbcon_hga_clear_margins(struct vc_data *conp, struct display *p,
188 int bottom_only)
190 u8 *dest;
191 u_int height, y;
192 int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
194 DPRINTK("fbcon_hga_clear_margins: enter\n");
196 /* No need to handle right margin. */
198 y = conp->vc_rows * fontheight(p);
199 for (height = p->var.yres - y; height-- > 0; y++) {
200 DPRINTK("fbcon_hga_clear_margins: y:%d, height:%d\n", y, height);
201 dest = rowaddr(p, y);
202 if (inverse) {
203 fb_memset255(dest, p->next_line);
204 } else {
205 fb_memclear(dest, p->next_line);
212 * `switch' for the low level operations
215 struct display_switch fbcon_hga = {
216 setup: fbcon_hga_setup,
217 bmove: fbcon_hga_bmove,
218 clear: fbcon_hga_clear,
219 putc: fbcon_hga_putc,
220 putcs: fbcon_hga_putcs,
221 revc: fbcon_hga_revc,
222 clear_margins: fbcon_hga_clear_margins,
223 fontwidthmask: FONTWIDTH(8)
227 #ifdef MODULE
228 int init_module(void)
230 return 0;
233 void cleanup_module(void)
236 #endif /* MODULE */
240 * Visible symbols for modules
243 EXPORT_SYMBOL(fbcon_hga);
244 EXPORT_SYMBOL(fbcon_hga_setup);
245 EXPORT_SYMBOL(fbcon_hga_bmove);
246 EXPORT_SYMBOL(fbcon_hga_clear);
247 EXPORT_SYMBOL(fbcon_hga_putc);
248 EXPORT_SYMBOL(fbcon_hga_putcs);
249 EXPORT_SYMBOL(fbcon_hga_revc);
250 EXPORT_SYMBOL(fbcon_hga_clear_margins);