patch-2.1.107 linux/drivers/char/vga.c
Next file: linux/drivers/char/vt.c
Previous file: linux/drivers/char/vesa_blank.c
Back to the patch index
Back to the overall index
- Lines: 636
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
v2.1.106/linux/drivers/char/vga.c
- Orig date:
Tue Dec 9 12:23:52 1997
diff -u --recursive --new-file v2.1.106/linux/drivers/char/vga.c linux/drivers/char/vga.c
@@ -1,635 +0,0 @@
-/*
- * linux/drivers/char/vga.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- * 1995 Jay Estabrook
- */
-
-/*
- * vga.c
- *
- * This module exports the console low-level io support for VGA
- *
- * 'int con_get_font(char *data)'
- * 'int con_set_font(char *data, int ch512)'
- * 'int con_adjust_height(int fontheight)'
- *
- * 'int con_get_cmap(char *)'
- * 'int con_set_cmap(char *)'
- *
- * 'int reset_palette(int currcons)'
- * 'void set_palette(void)'
- *
- * User definable mapping table and font loading by Eugene G. Crosser,
- * <crosser@pccross.msk.su>
- *
- * Improved loadable font/UTF-8 support by H. Peter Anvin
- * Feb-Sep 1995 <peter.anvin@linux.org>
- *
- * Colour palette handling, by Simon Tatham
- * 17-Jun-95 <sgt20@cam.ac.uk>
- *
- * if 512 char mode is already enabled don't re-enable it,
- * because it causes screen to flicker, by Mitja Horvat
- * 5-May-96 <mitja.horvat@guest.arnes.si>
- *
- * Use 2 outw instead of 4 outb_p to reduce erroneous text
- * flashing on RHS of screen during heavy console scrolling .
- * Oct 1996, Paul Gortmaker.
- *
- */
-
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/kd.h>
-#include <linux/malloc.h>
-#include <linux/major.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/bitops.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/consolemap.h>
-#include <linux/selection.h>
-#include <linux/console_struct.h>
-
-#define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
-#define CAN_LOAD_PALETTE /* undefine if the user must not do this */
-
-#define dac_reg (0x3c8)
-#define dac_val (0x3c9)
-
-#ifdef __powerpc__
-#define VGA_OFFSET 0xC0000000;
-#else
-#define VGA_OFFSET 0x0
-#endif
-
-/*
- * By replacing the four outb_p with two back to back outw, we can reduce
- * the window of opportunity to see text mislocated to the RHS of the
- * console during heavy scrolling activity. However there is the remote
- * possibility that some pre-dinosaur hardware won't like the back to back
- * I/O. Since the Xservers get away with it, we should be able to as well.
- */
-static inline void write_vga(unsigned char reg, unsigned int val)
-{
-#ifndef SLOW_VGA
- unsigned int v1, v2;
-
- v1 = reg + (val & 0xff00);
- v2 = reg + 1 + ((val << 8) & 0xff00);
- outw(v1, video_port_reg);
- outw(v2, video_port_reg);
-#else
- outb_p(reg, video_port_reg);
- outb_p(val >> 8, video_port_val);
- outb_p(reg+1, video_port_reg);
- outb_p(val & 0xff, video_port_val);
-#endif
-}
-
-void
-set_palette (void)
-{
- int i, j ;
-
- if (video_type != VIDEO_TYPE_VGAC || console_blanked ||
- vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
- return ;
-
- for (i=j=0; i<16; i++) {
- outb_p (color_table[i], dac_reg) ;
- outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
- outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
- outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
- }
-}
-
-void
-__set_origin(unsigned short offset)
-{
- clear_selection();
-
- __origin = offset;
- write_vga(12, offset);
-}
-
-/*
- * Put the cursor just beyond the end of the display adaptor memory.
- */
-void
-hide_cursor(void)
-{
- /* This is inefficient, we could just put the cursor at 0xffff,
- but perhaps the delays due to the inefficiency are useful for
- some hardware... */
- write_vga(14, (video_mem_term - video_mem_base - 1)>>1);
-}
-
-void
-set_cursor(int currcons)
-{
- if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
- return;
- if (__real_origin != __origin)
- __set_origin(__real_origin);
- if (deccm) {
- write_vga(14, (pos - video_mem_base)>>1);
- } else
- hide_cursor();
-}
-
-__initfunc(int con_is_present(void))
-{
- unsigned short saved;
- unsigned short *p;
-
- /*
- * Find out if there is a graphics card present.
- * Are there smarter methods around?
- */
- p = (unsigned short *) video_mem_base;
- saved = scr_readw(p);
- scr_writew(0xAA55, p);
- if (scr_readw(p) != 0xAA55) {
- scr_writew(saved, p);
- return 0;
- }
- scr_writew(0x55AA, p);
- if (scr_readw(p) != 0x55AA) {
- scr_writew(saved, p);
- return 0;
- }
- scr_writew(saved, p);
- return 1;
-}
-
-__initfunc(unsigned long
-con_type_init(unsigned long kmem_start, const char **display_desc))
-{
- if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */
- {
- video_mem_base = 0xb0000 + VGA_OFFSET;
- video_port_reg = 0x3b4;
- video_port_val = 0x3b5;
- if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
- {
- video_type = VIDEO_TYPE_EGAM;
- video_mem_term = 0xb8000 + VGA_OFFSET;
- *display_desc = "EGA+";
- request_region(0x3b0,16,"ega");
- }
- else
- {
- video_type = VIDEO_TYPE_MDA;
- video_mem_term = 0xb2000 + VGA_OFFSET;
- *display_desc = "*MDA";
- request_region(0x3b0,12,"mda");
- request_region(0x3bf, 1,"mda");
- }
- }
- else /* If not, it is color. */
- {
- can_do_color = 1;
- video_mem_base = 0xb8000 + VGA_OFFSET;
- video_port_reg = 0x3d4;
- video_port_val = 0x3d5;
- if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
- {
- int i ;
-
- video_mem_term = 0xc0000 + VGA_OFFSET;
-
- if (!ORIG_VIDEO_ISVGA) {
- video_type = VIDEO_TYPE_EGAC;
- *display_desc = "EGA";
- request_region(0x3c0,32,"ega");
- } else {
- video_type = VIDEO_TYPE_VGAC;
- *display_desc = "VGA+";
- request_region(0x3c0,32,"vga+");
-
-#ifdef VGA_CAN_DO_64KB
- /*
- * get 64K rather than 32K of video RAM.
- * This doesn't actually work on all "VGA"
- * controllers (it seems like setting MM=01
- * and COE=1 isn't necessarily a good idea)
- */
- video_mem_base = 0xa0000 + VGA_OFFSET;
- video_mem_term = 0xb0000 + VGA_OFFSET;
- outb_p (6, 0x3ce) ;
- outb_p (6, 0x3cf) ;
-#endif
-
- /*
- * Normalise the palette registers, to point
- * the 16 screen colours to the first 16
- * DAC entries.
- */
-
- for (i=0; i<16; i++) {
- inb_p (0x3da) ;
- outb_p (i, 0x3c0) ;
- outb_p (i, 0x3c0) ;
- }
- outb_p (0x20, 0x3c0) ;
-
- /* now set the DAC registers back to their
- * default values */
-
- for (i=0; i<16; i++) {
- outb_p (color_table[i], 0x3c8) ;
- outb_p (default_red[i], 0x3c9) ;
- outb_p (default_grn[i], 0x3c9) ;
- outb_p (default_blu[i], 0x3c9) ;
- }
- }
- }
- else
- {
- video_type = VIDEO_TYPE_CGA;
- video_mem_term = 0xba000 + VGA_OFFSET;
- *display_desc = "*CGA";
- request_region(0x3d4,2,"cga");
- }
- }
- return kmem_start;
-}
-
-__initfunc(void
-con_type_init_finish(void))
-{
-}
-
-void
-get_scrmem(int currcons)
-{
- memcpyw((unsigned short *)vc_scrbuf[currcons],
- (unsigned short *)origin, video_screen_size);
- origin = video_mem_start = (unsigned long)vc_scrbuf[currcons];
- scr_end = video_mem_end = video_mem_start + video_screen_size;
- pos = origin + y*video_size_row + (x<<1);
-}
-
-void
-set_scrmem(int currcons, long offset)
-{
-#ifdef CONFIG_HGA
- /* This works with XFree86 1.2, 1.3 and 2.0
- This code could be extended and made more generally useful if we could
- determine the actual video mode. It appears that this should be
- possible on a genuine Hercules card, but I (WM) haven't been able to
- read from any of the required registers on my clone card.
- */
- /* This code should work with Hercules and MDA cards. */
- if (video_type == VIDEO_TYPE_MDA)
- {
- if (vcmode == KD_TEXT)
- {
- /* Ensure that the card is in text mode. */
- int i;
- static char herc_txt_tbl[12] = {
- 0x61,0x50,0x52,0x0f,0x19,6,0x19,0x19,2,0x0d,0x0b,0x0c };
- outb_p(0, 0x3bf); /* Back to power-on defaults */
- outb_p(0, 0x3b8); /* Blank the screen, select page 0, etc */
- for ( i = 0 ; i < 12 ; i++ )
- {
- outb_p(i, 0x3b4);
- outb_p(herc_txt_tbl[i], 0x3b5);
- }
- }
-#define HGA_BLINKER_ON 0x20
-#define HGA_SCREEN_ON 8
- /* Make sure that the hardware is not blanked */
- outb_p(HGA_BLINKER_ON | HGA_SCREEN_ON, 0x3b8);
- }
-#endif CONFIG_HGA
-
- if (video_mem_term - video_mem_base < offset + video_screen_size)
- offset = 0; /* strange ... */
- memcpyw((unsigned short *)(video_mem_base + offset),
- (unsigned short *) origin, video_screen_size);
- video_mem_start = video_mem_base;
- video_mem_end = video_mem_term;
- origin = video_mem_base + offset;
- scr_end = origin + video_screen_size;
- pos = origin + y*video_size_row + (x<<1);
- has_wrapped = 0;
-}
-
-/*
- * PIO_FONT support.
- *
- * The font loading code goes back to the codepage package by
- * Joel Hoffman (joel@wam.umd.edu). (He reports that the original
- * reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
- * Video Systems_ by Richard Wilton. 1987. Microsoft Press".)
- *
- * Change for certain monochrome monitors by Yury Shevchuck
- * (sizif@botik.yaroslavl.su).
- */
-
-#define colourmap ((char *)0xa0000)
-/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
- should use 0xA0000 for the bwmap as well.. */
-#define blackwmap ((char *)0xa0000)
-#define cmapsz 8192
-#define attrib_port (0x3c0)
-#define seq_port_reg (0x3c4)
-#define seq_port_val (0x3c5)
-#define gr_port_reg (0x3ce)
-#define gr_port_val (0x3cf)
-
-int
-set_get_font(char * arg, int set, int ch512)
-{
-#ifdef CAN_LOAD_EGA_FONTS
- static int ch512enabled = 0;
- int i;
- char *charmap;
- int beg;
- unsigned short video_port_status = video_port_reg + 6;
- int font_select = 0x00;
-
- /* no use to "load" CGA... */
-
- if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_VGAC) {
- charmap = colourmap;
- beg = 0x0e;
-#ifdef VGA_CAN_DO_64KB
- if (video_type == VIDEO_TYPE_VGAC)
- beg = 0x06;
-#endif
- } else if (video_type == VIDEO_TYPE_EGAM) {
- charmap = blackwmap;
- beg = 0x0a;
- } else
- return -EINVAL;
-
- if (arg)
- {
- i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg,
- ch512 ? 2*cmapsz : cmapsz);
- if (i)
- return i;
- }
- else
- ch512 = 0; /* Default font is always 256 */
-
-#ifdef BROKEN_GRAPHICS_PROGRAMS
- /*
- * All fonts are loaded in slot 0 (0:1 for 512 ch)
- */
-
- if (!arg)
- return -EINVAL; /* Return to default font not supported */
-
- video_font_is_default = 0;
- font_select = ch512 ? 0x04 : 0x00;
-#else
- /*
- * The default font is kept in slot 0 and is never touched.
- * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch)
- */
-
- if (set)
- {
- video_font_is_default = !arg;
- font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00;
- }
-
- if ( !video_font_is_default )
- charmap += 4*cmapsz;
-#endif
-
- cli();
- outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
- outb_p( 0x01, seq_port_val ); /* Synchronous reset */
- outb_p( 0x02, seq_port_reg );
- outb_p( 0x04, seq_port_val ); /* CPU writes only to map 2 */
- outb_p( 0x04, seq_port_reg );
- outb_p( 0x07, seq_port_val ); /* Sequential addressing */
- outb_p( 0x00, seq_port_reg );
- outb_p( 0x03, seq_port_val ); /* Clear synchronous reset */
-
- outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
- outb_p( 0x02, gr_port_val ); /* select map 2 */
- outb_p( 0x05, gr_port_reg );
- outb_p( 0x00, gr_port_val ); /* disable odd-even addressing */
- outb_p( 0x06, gr_port_reg );
- outb_p( 0x00, gr_port_val ); /* map start at A000:0000 */
- sti();
-
- if (arg)
- {
- if (set)
- for (i=0; i<cmapsz ; i++) {
- char c;
- get_user(c, arg + i);
- scr_writeb(c, charmap + i);
- }
- else
- for (i=0; i<cmapsz ; i++)
- put_user(scr_readb(charmap + i), arg + i);
-
-
- /*
- * In 512-character mode, the character map is not contiguous if
- * we want to remain EGA compatible -- which we do
- */
-
- if (ch512)
- {
- charmap += 2*cmapsz;
- arg += cmapsz;
- if (set)
- for (i=0; i<cmapsz ; i++) {
- char c;
- get_user(c, arg+i);
- scr_writeb(c, charmap+i);
- }
- else
- for (i=0; i<cmapsz ; i++)
- put_user(scr_readb(charmap+i), arg+i);
- }
- }
-
- cli();
- outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
- outb_p( 0x01, seq_port_val ); /* Synchronous reset */
- outb_p( 0x02, seq_port_reg );
- outb_p( 0x03, seq_port_val ); /* CPU writes to maps 0 and 1 */
- outb_p( 0x04, seq_port_reg );
- outb_p( 0x03, seq_port_val ); /* odd-even addressing */
- if (set)
- {
- outb_p( 0x03, seq_port_reg ); /* Character Map Select */
- outb_p( font_select, seq_port_val );
- }
- outb_p( 0x00, seq_port_reg );
- outb_p( 0x03, seq_port_val ); /* clear synchronous reset */
-
- outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
- outb_p( 0x00, gr_port_val ); /* select map 0 for CPU */
- outb_p( 0x05, gr_port_reg );
- outb_p( 0x10, gr_port_val ); /* enable even-odd addressing */
- outb_p( 0x06, gr_port_reg );
- outb_p( beg, gr_port_val ); /* map starts at b800:0 or b000:0 */
-
- /* if 512 char mode is already enabled don't re-enable it. */
- if ((set)&&(ch512!=ch512enabled)) /* attribute controller */
- {
- ch512enabled=ch512;
- /* 256-char: enable intensity bit
- 512-char: disable intensity bit */
- inb_p( video_port_status ); /* clear address flip-flop */
- outb_p ( 0x12, attrib_port ); /* color plane enable register */
- outb_p ( ch512 ? 0x07 : 0x0f, attrib_port );
- /* Wilton (1987) mentions the following; I don't know what
- it means, but it works, and it appears necessary */
- inb_p( video_port_status );
- outb_p ( 0x20, attrib_port );
- }
- sti();
-
- return 0;
-#else
- return -EINVAL;
-#endif
-}
-
-/*
- * Adjust the screen to fit a font of a certain height
- *
- * Returns < 0 for error, 0 if nothing changed, and the number
- * of lines on the adjusted console if changed.
- */
-int
-con_adjust_height(unsigned long fontheight)
-{
- int rows, maxscan;
- unsigned char ovr, vde, fsr, curs, cure;
-
- if (fontheight > 32 || (video_type != VIDEO_TYPE_VGAC &&
- video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM))
- return -EINVAL;
-
- if ( fontheight == video_font_height || fontheight == 0 )
- return 0;
-
- video_font_height = fontheight;
-
- rows = video_scan_lines/fontheight; /* Number of video rows we end up with */
- maxscan = rows*fontheight - 1; /* Scan lines to actually display-1 */
-
- /* Reprogram the CRTC for the new font size
- Note: the attempt to read the overflow register will fail
- on an EGA, but using 0xff for the previous value appears to
- be OK for EGA text modes in the range 257-512 scan lines, so I
- guess we don't need to worry about it.
-
- The same applies for the spill bits in the font size and cursor
- registers; they are write-only on EGA, but it appears that they
- are all don't care bits on EGA, so I guess it doesn't matter. */
-
- cli();
- outb_p( 0x07, video_port_reg ); /* CRTC overflow register */
- ovr = inb_p(video_port_val);
- outb_p( 0x09, video_port_reg ); /* Font size register */
- fsr = inb_p(video_port_val);
- outb_p( 0x0a, video_port_reg ); /* Cursor start */
- curs = inb_p(video_port_val);
- outb_p( 0x0b, video_port_reg ); /* Cursor end */
- cure = inb_p(video_port_val);
- sti();
-
- vde = maxscan & 0xff; /* Vertical display end reg */
- ovr = (ovr & 0xbd) + /* Overflow register */
- ((maxscan & 0x100) >> 7) +
- ((maxscan & 0x200) >> 3);
- fsr = (fsr & 0xe0) + (fontheight-1); /* Font size register */
- curs = (curs & 0xc0) + fontheight - (fontheight < 10 ? 2 : 3);
- cure = (cure & 0xe0) + fontheight - (fontheight < 10 ? 1 : 2);
-
- cli();
- outb_p( 0x07, video_port_reg ); /* CRTC overflow register */
- outb_p( ovr, video_port_val );
- outb_p( 0x09, video_port_reg ); /* Font size */
- outb_p( fsr, video_port_val );
- outb_p( 0x0a, video_port_reg ); /* Cursor start */
- outb_p( curs, video_port_val );
- outb_p( 0x0b, video_port_reg ); /* Cursor end */
- outb_p( cure, video_port_val );
- outb_p( 0x12, video_port_reg ); /* Vertical display limit */
- outb_p( vde, video_port_val );
- sti();
-
- if ( rows == video_num_lines ) {
- /* Change didn't affect number of lines -- no need to scare
- the rest of the world */
- return 0;
- }
-
- vc_resize(rows, 0); /* Adjust console size */
-
- return rows;
-}
-
-int
-set_get_cmap(unsigned char * arg, int set) {
-#ifdef CAN_LOAD_PALETTE
- int i;
-
- /* no use to set colourmaps in less than colour VGA */
-
- if (video_type != VIDEO_TYPE_VGAC)
- return -EINVAL;
-
- i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, 16*3);
- if (i)
- return i;
-
- for (i=0; i<16; i++) {
- if (set) {
- get_user(default_red[i], arg++) ;
- get_user(default_grn[i], arg++) ;
- get_user(default_blu[i], arg++) ;
- } else {
- put_user (default_red[i], arg++) ;
- put_user (default_grn[i], arg++) ;
- put_user (default_blu[i], arg++) ;
- }
- }
- if (set) {
- for (i=0; i<MAX_NR_CONSOLES; i++)
- if (vc_cons_allocated(i)) {
- int j, k ;
- for (j=k=0; j<16; j++) {
- vc_cons[i].d->vc_palette[k++] = default_red[j];
- vc_cons[i].d->vc_palette[k++] = default_grn[j];
- vc_cons[i].d->vc_palette[k++] = default_blu[j];
- }
- }
- set_palette() ;
- }
-
- return 0;
-#else
- return -EINVAL;
-#endif
-}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov