fbcon-vga.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/video/fbcon-vga.c -- Low level frame buffer operations for
  3.  *        VGA characters/attributes
  4.  *
  5.  * Created 28 Mar 1998 by Geert Uytterhoeven
  6.  * Monochrome attributes added May 1998 by Andrew Apted
  7.  *
  8.  *  This file is subject to the terms and conditions of the GNU General Public
  9.  *  License.  See the file COPYING in the main directory of this archive for
  10.  *  more details.
  11.  */
  12. #include <linux/module.h>
  13. #include <linux/tty.h>
  14. #include <linux/console.h>
  15. #include <linux/string.h>
  16. #include <linux/fb.h>
  17. #include <asm/io.h>
  18. #include <video/fbcon.h>
  19. #include <video/fbcon-vga.h>
  20.     /*
  21.      *  VGA screen access
  22.      */ 
  23. static inline void vga_writew(u16 val, u16 *addr)
  24. {
  25. #ifdef __powerpc__
  26.     st_le16(addr, val);
  27. #else
  28.     writew(val, (unsigned long)addr);
  29. #endif /* !__powerpc__ */
  30. }
  31. static inline u16 vga_readw(u16 *addr)
  32. {
  33. #ifdef __powerpc__
  34.     return ld_le16(addr);
  35. #else
  36.     return readw((unsigned long)addr);
  37. #endif /* !__powerpc__ */
  38. }
  39. static inline void vga_memsetw(void *s, u16 c, unsigned int count)
  40. {
  41.     u16 *addr = (u16 *)s;
  42.     while (count) {
  43. count--;
  44. vga_writew(c, addr++);
  45.     }
  46. }
  47. static inline void vga_memmovew(u16 *to, u16 *from, unsigned int count)
  48. {
  49.     if (to < from) {
  50. while (count) {
  51.     count--;
  52.     vga_writew(vga_readw(from++), to++);
  53. }
  54.     } else {
  55. from += count;
  56. to += count;
  57. while (count) {
  58.     count--;
  59.     vga_writew(vga_readw(--from), --to);
  60. }
  61.     }
  62. }
  63.     /*
  64.      *  VGA characters/attributes
  65.      */
  66. static inline u16 fbcon_vga_attr(struct display *p,
  67.  unsigned short s)
  68. {
  69.         /* Underline and reverse-video are mutually exclusive on MDA.
  70.          * Since reverse-video is used for cursors and selected areas, 
  71.  * it takes precedence.
  72.          */
  73. return (attr_reverse(p, s) ? 0x7000 :
  74. (attr_underline(p, s) ? 0x0100 : 0x0700)) |
  75.        (attr_bold(p, s) ? 0x0800 : 0) |
  76.        (attr_blink(p, s) ? 0x8000 : 0);
  77. }
  78. void fbcon_vga_setup(struct display *p)
  79. {
  80.     p->next_line = p->line_length;
  81.     p->next_plane = 0;
  82. }
  83. void fbcon_vga_bmove(struct display *p, int sy, int sx, int dy, int dx,
  84.      int height, int width)
  85. {
  86.     u16 *src, *dst;
  87.     int rows;
  88.     if (sx == 0 && dx == 0 && width == p->next_line/2) {
  89. src = (u16 *)(p->screen_base+sy*p->next_line);
  90. dst = (u16 *)(p->screen_base+dy*p->next_line);
  91. vga_memmovew(dst, src, height*width);
  92.     } else if (dy < sy || (dy == sy && dx < sx)) {
  93. src = (u16 *)(p->screen_base+sy*p->next_line+sx*2);
  94. dst = (u16 *)(p->screen_base+dy*p->next_line+dx*2);
  95. for (rows = height; rows-- ;) {
  96.     vga_memmovew(dst, src, width);
  97.     src += p->next_line/2;
  98.     dst += p->next_line/2;
  99. }
  100.     } else {
  101. src = (u16 *)(p->screen_base+(sy+height-1)*p->next_line+sx*2);
  102. dst = (u16 *)(p->screen_base+(dy+height-1)*p->next_line+dx*2);
  103. for (rows = height; rows-- ;) {
  104.     vga_memmovew(dst, src, width);
  105.     src -= p->next_line/2;
  106.     dst -= p->next_line/2;
  107. }
  108.     }
  109. }
  110. void fbcon_vga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
  111.      int height, int width)
  112. {
  113.     u16 *dest = (u16 *)(p->screen_base+sy*p->next_line+sx*2);
  114.     int rows;
  115.     if (sx == 0 && width*2 == p->next_line)      
  116. vga_memsetw(dest, conp->vc_video_erase_char, height*width);
  117.     else
  118. for (rows = height; rows-- ; dest += p->next_line/2)
  119.     vga_memsetw(dest, conp->vc_video_erase_char, width);
  120. }
  121. void fbcon_vga_putc(struct vc_data *conp, struct display *p, int c, int y,
  122.     int x)
  123. {
  124.     u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
  125.     if (conp->vc_can_do_color)
  126.      vga_writew(c, dst);
  127.     else
  128.      vga_writew(fbcon_vga_attr(p, c) | (c & 0xff), dst);
  129. }
  130. void fbcon_vga_putcs(struct vc_data *conp, struct display *p, 
  131.      const unsigned short *s, int count, int y, int x)
  132. {
  133.     u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
  134.     u16 sattr;
  135.     if (conp->vc_can_do_color)
  136.      while (count--)
  137.          vga_writew(scr_readw(s++), dst++);
  138.     else {
  139.         sattr = fbcon_vga_attr(p, scr_readw(s));
  140.         while (count--)
  141.     vga_writew(sattr | ((int) (scr_readw(s++)) & 0xff), dst++);
  142.     }
  143. }
  144. void fbcon_vga_revc(struct display *p, int x, int y)
  145. {
  146.     u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
  147.     u16 val = vga_readw(dst);
  148.     val = (val & 0x88ff) | ((val<<4) & 0x7000) | ((val>>4) & 0x0700);
  149.     vga_writew(val, dst);
  150. }
  151.     /*
  152.      *  `switch' for the low level operations
  153.      */
  154. struct display_switch fbcon_vga = {
  155.     setup: fbcon_vga_setup,
  156.     bmove: fbcon_vga_bmove,
  157.     clear: fbcon_vga_clear,
  158.     putc: fbcon_vga_putc,
  159.     putcs: fbcon_vga_putcs,
  160.     revc: fbcon_vga_revc,
  161.     fontwidthmask: FONTWIDTH(8)
  162. };
  163. #ifdef MODULE
  164. MODULE_LICENSE("GPL");
  165. int init_module(void)
  166. {
  167.     return 0;
  168. }
  169. void cleanup_module(void)
  170. {}
  171. #endif /* MODULE */
  172.     /*
  173.      *  Visible symbols for modules
  174.      */
  175. EXPORT_SYMBOL(fbcon_vga);
  176. EXPORT_SYMBOL(fbcon_vga_setup);
  177. EXPORT_SYMBOL(fbcon_vga_bmove);
  178. EXPORT_SYMBOL(fbcon_vga_clear);
  179. EXPORT_SYMBOL(fbcon_vga_putc);
  180. EXPORT_SYMBOL(fbcon_vga_putcs);
  181. EXPORT_SYMBOL(fbcon_vga_revc);