patch-2.3.50 linux/drivers/video/fbcon-hga.c

Next file: linux/drivers/video/fbcon.c
Previous file: linux/drivers/video/fbcmap.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.49/linux/drivers/video/fbcon-hga.c linux/drivers/video/fbcon-hga.c
@@ -0,0 +1,245 @@
+/*
+ *  linux/drivers/video/fbcon-hga.c -- Low level frame buffer operations for
+ *				       the Hercules graphics adaptor
+ *
+ *	Created 25 Nov 1999 by Ferenc Bakonyi (fero@drama.obuda.kando.hu)
+ *	Based on fbcon-mfb.c by Geert Uytterhoeven
+ *
+ * History:
+ *
+ * - Revision 0.1.0 (6 Dec 1999): comment changes
+ * - First release (25 Nov 1999)
+ * 
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-hga.h>
+
+#if 0
+#define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
+#else
+#define DPRINTK(args...)
+#endif
+
+#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
+
+    /*
+     *  Hercules monochrome
+     */
+
+static inline u8* rowaddr(struct display *p, u_int row)
+{
+	return p->screen_base + HGA_ROWADDR(row);
+}
+	
+void fbcon_hga_setup(struct display *p)
+{
+	DPRINTK("fbcon_hga_setup: ll:%d\n", (int)p->line_length);
+
+	p->next_line = p->line_length;
+	p->next_plane = 0;
+}
+
+void fbcon_hga_bmove(struct display *p, int sy, int sx, int dy, int dx,
+		     int height, int width)
+{
+	u8 *src, *dest;
+	u_int rows, y1, y2;
+	
+#if 0
+	if (sx == 0 && dx == 0 && width == p->next_line) {
+		src = p->screen_base+sy*fontheight(p)*width;
+		dest = p->screen_base+dy*fontheight(p)*width;
+		fb_memmove(dest, src, height*fontheight(p)*width);
+	} else 
+#endif
+	if (dy <= sy) {
+		y1 = sy*fontheight(p);
+		y2 = dy*fontheight(p);
+		for (rows = height*fontheight(p); rows--; ) {
+			src = rowaddr(p, y1)+sx;
+			dest = rowaddr(p, y2)+dx;
+			fb_memmove(dest, src, width);
+			y1++;
+			y2++;
+		}
+	} else {
+		y1 = (sy+height)*fontheight(p)-1;
+		y2 = (dy+height)*fontheight(p)-1;
+		for (rows = height*fontheight(p); rows--;) {
+			src = rowaddr(p, y1)+sx;
+			dest = rowaddr(p, y2)+dx;
+			fb_memmove(dest, src, width);
+			y1--;
+			y2--;
+		}
+	}
+}
+
+void fbcon_hga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
+		     int height, int width)
+{
+	u8 *dest;
+	u_int rows, y;
+	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
+
+	DPRINTK("fbcon_hga_clear: sx:%d, sy:%d, height:%d, width:%d\n", sx, sy, height, width);
+	
+	y = sy*fontheight(p);
+#if 0
+	if (sx == 0 && width == p->next_line) {
+		if (inverse) {
+			fb_memset255(dest, height*fontheight(p)*width);
+		} else {
+			fb_memclear(dest, height*fontheight(p)*width);
+		}
+	} else
+#endif	    
+	for (rows = height*fontheight(p); rows--; y++) {
+		dest = rowaddr(p, y)+sx;
+		if (inverse) {
+			fb_memset255(dest, width);
+		} else {
+			fb_memclear(dest, width);
+		}
+	}
+}
+
+void fbcon_hga_putc(struct vc_data *conp, struct display *p, int c, int yy,
+		    int xx)
+{
+	u8 *dest, *cdat;
+	u_int rows, y, bold, revs, underl;
+	u8 d;
+
+	cdat = p->fontdata+(c&p->charmask)*fontheight(p);
+	bold = attr_bold(p, c);
+	revs = attr_reverse(p, c);
+	underl = attr_underline(p, c);
+	y = yy*fontheight(p);
+
+	for (rows = fontheight(p); rows--; y++) {
+		d = *cdat++;
+		if (underl && !rows)
+			d = 0xff;
+		else if (bold)
+			d |= d>>1;
+		if (revs)
+			d = ~d;
+		dest = rowaddr(p, y)+xx;
+		*dest = d;
+	}
+}
+
+void fbcon_hga_putcs(struct vc_data *conp, struct display *p, 
+		     const unsigned short *s, int count, int yy, int xx)
+{
+	u8 *dest, *cdat;
+	u_int rows, y, y0, bold, revs, underl;
+	u8 d;
+	u16 c;
+	
+	bold = attr_bold(p,scr_readw(s));
+	revs = attr_reverse(p,scr_readw(s));
+	underl = attr_underline(p,scr_readw(s));
+	y0 = yy*fontheight(p);
+
+	while (count--) {
+		c = scr_readw(s++) & p->charmask;
+		cdat = p->fontdata+c*fontheight(p);
+		y = y0;
+		for (rows = fontheight(p); rows--; y++) {
+			d = *cdat++;
+	    		if (underl && !rows)
+				d = 0xff;
+	    		else if (bold)
+				d |= d>>1;
+	    		if (revs)
+				d = ~d;
+			dest = rowaddr(p, y)+xx;
+	    		*dest = d;
+		}
+		xx++;
+	}
+}
+
+void fbcon_hga_revc(struct display *p, int xx, int yy)
+{
+	u8 *dest;
+	u_int rows, y;
+
+	y = yy*fontheight(p);
+	for (rows = fontheight(p); rows--; y++) {
+		dest = rowaddr(p, y)+xx;
+		*dest = ~*dest;
+	}
+}
+
+void fbcon_hga_clear_margins(struct vc_data *conp, struct display *p,
+			     int bottom_only)
+{
+	u8 *dest;
+	u_int height, y;
+	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
+
+	DPRINTK("fbcon_hga_clear_margins: enter\n");
+
+	/* No need to handle right margin. */
+
+	y = conp->vc_rows * fontheight(p);
+	for (height = p->var.yres - y; height-- > 0; y++) {
+		DPRINTK("fbcon_hga_clear_margins: y:%d, height:%d\n", y, height);
+		dest = rowaddr(p, y);
+		if (inverse) {
+			fb_memset255(dest, p->next_line);
+		} else {
+			fb_memclear(dest, p->next_line);
+		}
+	}
+}
+
+
+	/*
+	 *  `switch' for the low level operations
+	 */
+
+struct display_switch fbcon_hga = {
+	fbcon_hga_setup, fbcon_hga_bmove, fbcon_hga_clear, fbcon_hga_putc,
+	fbcon_hga_putcs, fbcon_hga_revc, NULL, NULL, fbcon_hga_clear_margins,
+	FONTWIDTH(8)
+};
+
+
+#ifdef MODULE
+int init_module(void)
+{
+	return 0;
+}
+
+void cleanup_module(void)
+{
+}
+#endif /* MODULE */
+
+
+	/*
+	 *  Visible symbols for modules
+	 */
+
+EXPORT_SYMBOL(fbcon_hga);
+EXPORT_SYMBOL(fbcon_hga_setup);
+EXPORT_SYMBOL(fbcon_hga_bmove);
+EXPORT_SYMBOL(fbcon_hga_clear);
+EXPORT_SYMBOL(fbcon_hga_putc);
+EXPORT_SYMBOL(fbcon_hga_putcs);
+EXPORT_SYMBOL(fbcon_hga_revc);
+EXPORT_SYMBOL(fbcon_hga_clear_margins);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)