summaryrefslogtreecommitdiffstats
path: root/drivers/char/console.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /drivers/char/console.c
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'drivers/char/console.c')
-rw-r--r--drivers/char/console.c1329
1 files changed, 644 insertions, 685 deletions
diff --git a/drivers/char/console.c b/drivers/char/console.c
index 027551dfa..070dc9bf3 100644
--- a/drivers/char/console.c
+++ b/drivers/char/console.c
@@ -2,22 +2,20 @@
* linux/drivers/char/console.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
- * MIPS support by Ralf Baechle and Andreas Busse
*/
-
/*
* console.c
*
* This module exports the console io functions:
- *
+ *
* 'void do_keyboard_interrupt(void)'
*
- * 'int vc_allocate(unsigned int console)'
+ * 'int vc_allocate(unsigned int console)'
* 'int vc_cons_allocated(unsigned int console)'
* 'int vc_resize(unsigned long lines, unsigned long cols)'
* 'void vc_disallocate(unsigned int currcons)'
*
- * 'long con_init(long)'
+ * 'unsigned long con_init(unsigned long)'
* 'int con_open(struct tty_struct *tty, struct file * filp)'
* 'void con_write(struct tty_struct * tty)'
* 'void console_print(const char * b)'
@@ -34,25 +32,19 @@
* 'void scrollback(int lines)'
* 'void scrollfront(int lines)'
*
- * 'int con_get_font(char *)'
- * 'int con_set_font(char *)'
- *
* 'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)'
* 'int mouse_reporting(void)'
*
* Hopefully this will be a rather complete VT102 implementation.
*
* Beeping thanks to John T Kohl.
- *
+ *
* Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
* Chars, and VT100 enhancements by Peter MacDonald.
*
* Copy and paste function by Andrew Haylett,
* some enhancements by Alessandro Rubini.
*
- * User definable mapping table and font loading by Eugene G. Crosser,
- * <crosser@pccross.msk.su>
- *
* Code to check for different video-cards mostly by Galen Hunt,
* <g-hunt@ee.utah.edu>
*
@@ -65,17 +57,28 @@
* Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
* <poe@daimi.aau.dk>
*
+ * MIPS support by Ralf Baechle, Andreas Busse and Wayne Hodgen.
+ *
+ * User-defined bell sound, new setterm control sequences and printk
+ * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
+ *
*/
#define BLANK 0x0020
-#define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
/* A bitmap for codes <32. A bit of 1 indicates that the code
* corresponding to that bit number invokes some special action
* (such as cursor movement) and should not be displayed as a
* glyph unless the disp_ctrl mode is explicitly enabled.
*/
-#define CTRL_ACTION 0xd00ff80
+#define CTRL_ACTION 0x0d00ff81
+#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
+
+/*
+ * Here is the default bell parameters: 750HZ, 1/8th of a second
+ */
+#define DEFAULT_BELL_PITCH 750
+#define DEFAULT_BELL_DURATION (HZ/8)
/*
* NOTE!!! We sometimes disable and enable interrupts for a short while
@@ -98,28 +101,30 @@
#include <linux/major.h>
#include <linux/mm.h>
#include <linux/ioport.h>
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+#endif
-#if defined(CONFIG_ACER_PICA_61) || defined(CONFIG_MIPS_MAGNUM_4000)
+#ifdef __mips__
#include <asm/bootinfo.h>
/*
* The video control ports are mapped at virtual address
- * 0xe0200000 for the onboard S3 card
+ * 0xe0200000 for the onboard S3 card of the Acer; M700 and Magnum 4000
+ * don't have ports at all.
*/
-#if 0
-#define PORT_BASE 0xe0200000
-#endif
+#define PORT_BASE video_port_base
+unsigned long video_port_base;
#endif
#include <asm/io.h>
-#include <asm/slots.h>
#include <asm/system.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/bitops.h>
#include "kbd_kern.h"
#include "vt_kern.h"
#include "consolemap.h"
#include "selection.h"
-
+#include "console_struct.h"
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -130,232 +135,181 @@ static int console_refcount;
static struct tty_struct *console_table[MAX_NR_CONSOLES];
static struct termios *console_termios[MAX_NR_CONSOLES];
static struct termios *console_termios_locked[MAX_NR_CONSOLES];
-
-#define NPAR 16
+unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
+struct vc vc_cons [MAX_NR_CONSOLES];
static void con_setsize(unsigned long rows, unsigned long cols);
-static void vc_init(unsigned int console, unsigned long rows, unsigned long cols,
- int do_clear);
-static void get_scrmem(int currcons);
-static void set_scrmem(int currcons, long offset);
+static void vc_init(unsigned int console, unsigned long rows,
+ unsigned long cols, int do_clear);
+extern void get_scrmem(int currcons);
+extern void set_scrmem(int currcons, long offset);
static void set_origin(int currcons);
static void blank_screen(void);
static void unblank_screen(void);
-void poke_blanked_console(void);
+extern void change_console(unsigned int);
+extern void poke_blanked_console(void);
static void gotoxy(int currcons, int new_x, int new_y);
static void save_cur(int currcons);
-static inline void set_cursor(int currcons);
+extern void set_cursor(int currcons);
+extern void hide_cursor(void);
static void reset_terminal(int currcons, int do_clear);
extern void reset_vc(unsigned int new_console);
extern void vt_init(void);
extern void register_console(void (*proc)(const char *));
extern void vesa_blank(void);
extern void vesa_unblank(void);
+extern void vesa_powerdown(void);
extern void compute_shiftstate(void);
-extern int conv_uni_to_pc(unsigned long ucs);
+extern void reset_palette(int currcons);
+extern void set_palette(void);
+extern unsigned long con_type_init(unsigned long, const char **);
+extern int set_get_cmap(unsigned char *, int);
+extern int set_get_font(unsigned char *, int, int);
/* Description of the hardware situation */
-static unsigned char video_type; /* Type of display being used */
-static unsigned long video_mem_base; /* Base of video memory */
-static unsigned long video_mem_term; /* End of video memory */
-static unsigned char video_page; /* Initial video page (unused) */
- /* these two also used in vesa_blank.c */
- unsigned short video_port_reg; /* Video register select port */
- unsigned short video_port_val; /* Video register value port */
- /* these three also used in selection.c */
- unsigned long video_num_columns; /* Number of text columns */
- unsigned long video_num_lines; /* Number of text lines */
- unsigned long video_size_row;
-static unsigned long video_screen_size;
-static int can_do_color = 0;
-static int printable = 0; /* Is console ready for printing? */
-
-static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
-
-static int console_blanked = 0;
+unsigned char video_type; /* Type of display being used */
+unsigned long video_mem_base; /* Base of video memory */
+unsigned long video_mem_term; /* End of video memory */
+unsigned short video_port_reg; /* Video register select port */
+unsigned short video_port_val; /* Video register value port */
+unsigned long video_num_columns; /* Number of text columns */
+unsigned long video_num_lines; /* Number of text lines */
+unsigned long video_size_row;
+unsigned long video_screen_size;
+
+int can_do_color = 0;
+static int printable = 0; /* Is console ready for printing? */
+
+int video_mode_512ch = 0; /* 512-character mode */
+unsigned long video_font_height; /* Height of current screen font */
+unsigned long video_scan_lines; /* Number of scan lines on screen */
+unsigned long default_font_height; /* Height of default screen font */
+int video_font_is_default = 1;
+static unsigned short console_charmask = 0x0ff;
+
+/* used by kbd_bh - set by keyboard_interrupt */
+ int do_poke_blanked_console = 0;
+ int console_blanked = 0;
static int blankinterval = 10*60*HZ;
+static int vesa_off_interval = 0;
static long blank_origin, blank__origin, unblank_origin;
-struct vc_data {
- unsigned long vc_screenbuf_size;
- unsigned short vc_video_erase_char; /* Background erase character */
- unsigned char vc_attr; /* Current attributes */
- unsigned char vc_def_color; /* Default colors */
- unsigned char vc_color; /* Foreground & background */
- unsigned char vc_s_color; /* Saved foreground & background */
- unsigned char vc_ulcolor; /* Colour for underline mode */
- unsigned char vc_halfcolor; /* Colour for half intensity mode */
- unsigned long vc_origin; /* Used for EGA/VGA fast scroll */
- unsigned long vc_scr_end; /* Used for EGA/VGA fast scroll */
- unsigned long vc_pos;
- unsigned long vc_x,vc_y;
- unsigned long vc_top,vc_bottom;
- unsigned long vc_state;
- unsigned long vc_npar,vc_par[NPAR];
- unsigned long vc_video_mem_start; /* Start of video RAM */
- unsigned long vc_video_mem_end; /* End of video RAM (sort of) */
- unsigned long vc_saved_x;
- unsigned long vc_saved_y;
- /* mode flags */
- unsigned long vc_charset : 1; /* Character set G0 / G1 */
- unsigned long vc_s_charset : 1; /* Saved character set */
- unsigned long vc_disp_ctrl : 1; /* Display chars < 32? */
- unsigned long vc_toggle_meta : 1; /* Toggle high bit? */
- unsigned long vc_decscnm : 1; /* Screen Mode */
- unsigned long vc_decom : 1; /* Origin Mode */
- unsigned long vc_decawm : 1; /* Autowrap Mode */
- unsigned long vc_deccm : 1; /* Cursor Visible */
- unsigned long vc_decim : 1; /* Insert Mode */
- unsigned long vc_deccolm : 1; /* 80/132 Column Mode */
- /* attribute flags */
- unsigned long vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
- unsigned long vc_underline : 1;
- unsigned long vc_blink : 1;
- unsigned long vc_reverse : 1;
- unsigned long vc_s_intensity : 2; /* saved rendition */
- unsigned long vc_s_underline : 1;
- unsigned long vc_s_blink : 1;
- unsigned long vc_s_reverse : 1;
- /* misc */
- unsigned long vc_ques : 1;
- unsigned long vc_need_wrap : 1;
- unsigned long vc_has_scrolled : 1; /* Info for unblank_screen */
- unsigned long vc_kmalloced : 1; /* kfree_s() needed */
- unsigned long vc_report_mouse : 2;
- unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */
- unsigned char vc_utf_count;
- unsigned long vc_utf_char;
- unsigned long vc_tab_stop[5]; /* Tab stops. 160 columns. */
- unsigned char * vc_translate;
- unsigned char vc_G0_charset;
- unsigned char vc_G1_charset;
- unsigned char vc_saved_G0;
- unsigned char vc_saved_G1;
- /* additional information is in vt_kern.h */
-};
-
-static struct vc {
- struct vc_data *d;
-
- /* might add scrmem, vt_struct, kbd at some time,
- to have everything in one place - the disadvantage
- would be that vc_cons etc can no longer be static */
-} vc_cons [MAX_NR_CONSOLES];
+
+#ifdef CONFIG_SERIAL_ECHO
+
+#include <linux/serial_reg.h>
+
+extern int serial_echo_init (int base);
+extern int serial_echo_print (const char *s);
/*
- * Fontsize for graphic console
+ * this defines the address for the port to which printk echoing is done
+ * when CONFIG_SERIAL_ECHO is defined
*/
-#define FONTSIZE_X 8 /* 8 pixels wide */
-#define FONTSIZE_Y 16 /* 16 pixels high */
+#define SERIAL_ECHO_PORT 0x3f8 /* COM1 */
-#ifdef CONFIG_MIPS_MAGNUM_4000
-extern unsigned char font[];
-static unsigned video_res_x;
-static int graph_mode = 0; /* true for graphic consoles */
+static int serial_echo_port = 0;
-/*
- * print a character to a graphics console.
- * FIXME: slooooow
+#define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port)
+#define serial_echo_inb(a) inb((a)+serial_echo_port)
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+/* Wait for transmitter & holding register to empty */
+#define WAIT_FOR_XMITR \
+ do { \
+ lsr = serial_echo_inb(UART_LSR); \
+ } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
+
+/* These two functions abstract the actual communications with the
+ * debug port. This is so we can change the underlying communications
+ * mechanism without modifying the rest of the code.
*/
-static inline void
-gscr_pchar(unsigned char c, unsigned char *ptr)
+int
+serial_echo_print(const char *s)
{
- unsigned char *faddr;
- int i,j;
+ int lsr, ier;
+ int i;
+
+ if (!serial_echo_port) return (0);
+
+ /*
+ * First save the IER then disable the interrupts
+ */
+ ier = serial_echo_inb(UART_IER);
+ serial_echo_outb(0x00, UART_IER);
- faddr = font + (c<<7); /* 128 bytes/char */
- for (i=0; i<FONTSIZE_Y; i++) {
- for (j=0; j<FONTSIZE_X; j++) {
- *(ptr+j) = *(faddr++);
+ /*
+ * Now, do each character
+ */
+ for (i = 0; *s; i++, s++) {
+ WAIT_FOR_XMITR;
+
+ /* Send the character out. */
+ serial_echo_outb(*s, UART_TX);
+
+ /* if a LF, also do CR... */
+ if (*s == 10) {
+ WAIT_FOR_XMITR;
+ serial_echo_outb(13, UART_TX);
}
- ptr += video_res_x;
}
-}
-#else
-const int graph_mode = 0;
-#endif /* CONFIG_MIPS_MAGNUM_4000 */
-
-#define screenbuf_size (vc_cons[currcons].d->vc_screenbuf_size)
-#define origin (vc_cons[currcons].d->vc_origin)
-#define scr_end (vc_cons[currcons].d->vc_scr_end)
-#define pos (vc_cons[currcons].d->vc_pos)
-#define top (vc_cons[currcons].d->vc_top)
-#define bottom (vc_cons[currcons].d->vc_bottom)
-#define x (vc_cons[currcons].d->vc_x)
-#define y (vc_cons[currcons].d->vc_y)
-#define vc_state (vc_cons[currcons].d->vc_state)
-#define npar (vc_cons[currcons].d->vc_npar)
-#define par (vc_cons[currcons].d->vc_par)
-#define ques (vc_cons[currcons].d->vc_ques)
-#define attr (vc_cons[currcons].d->vc_attr)
-#define saved_x (vc_cons[currcons].d->vc_saved_x)
-#define saved_y (vc_cons[currcons].d->vc_saved_y)
-#define translate (vc_cons[currcons].d->vc_translate)
-#define G0_charset (vc_cons[currcons].d->vc_G0_charset)
-#define G1_charset (vc_cons[currcons].d->vc_G1_charset)
-#define saved_G0 (vc_cons[currcons].d->vc_saved_G0)
-#define saved_G1 (vc_cons[currcons].d->vc_saved_G1)
-#define utf (vc_cons[currcons].d->vc_utf)
-#define utf_count (vc_cons[currcons].d->vc_utf_count)
-#define utf_char (vc_cons[currcons].d->vc_utf_char)
-#define video_mem_start (vc_cons[currcons].d->vc_video_mem_start)
-#define video_mem_end (vc_cons[currcons].d->vc_video_mem_end)
-#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)
-#define disp_ctrl (vc_cons[currcons].d->vc_disp_ctrl)
-#define toggle_meta (vc_cons[currcons].d->vc_toggle_meta)
-#define decscnm (vc_cons[currcons].d->vc_decscnm)
-#define decom (vc_cons[currcons].d->vc_decom)
-#define decawm (vc_cons[currcons].d->vc_decawm)
-#define deccm (vc_cons[currcons].d->vc_deccm)
-#define decim (vc_cons[currcons].d->vc_decim)
-#define deccolm (vc_cons[currcons].d->vc_deccolm)
-#define need_wrap (vc_cons[currcons].d->vc_need_wrap)
-#define has_scrolled (vc_cons[currcons].d->vc_has_scrolled)
-#define kmalloced (vc_cons[currcons].d->vc_kmalloced)
-#define report_mouse (vc_cons[currcons].d->vc_report_mouse)
-#define color (vc_cons[currcons].d->vc_color)
-#define s_color (vc_cons[currcons].d->vc_s_color)
-#define def_color (vc_cons[currcons].d->vc_def_color)
-#define foreground (color & 0x0f)
-#define background (color & 0xf0)
-#define charset (vc_cons[currcons].d->vc_charset)
-#define s_charset (vc_cons[currcons].d->vc_s_charset)
-#define intensity (vc_cons[currcons].d->vc_intensity)
-#define underline (vc_cons[currcons].d->vc_underline)
-#define blink (vc_cons[currcons].d->vc_blink)
-#define reverse (vc_cons[currcons].d->vc_reverse)
-#define s_intensity (vc_cons[currcons].d->vc_s_intensity)
-#define s_underline (vc_cons[currcons].d->vc_s_underline)
-#define s_blink (vc_cons[currcons].d->vc_s_blink)
-#define s_reverse (vc_cons[currcons].d->vc_s_reverse)
-#define ulcolor (vc_cons[currcons].d->vc_ulcolor)
-#define halfcolor (vc_cons[currcons].d->vc_halfcolor)
-#define tab_stop (vc_cons[currcons].d->vc_tab_stop)
-
-#define vcmode (vt_cons[currcons]->vc_mode)
-#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct))
-
-static void memsetw(void * s, unsigned short c, unsigned int count)
-{
- unsigned short * addr = (unsigned short *) s;
- count /= 2;
- while (count) {
- count--;
- scr_writew(c, addr++);
- }
+ /*
+ * Finally, Wait for transmitter & holding register to empty
+ * and restore the IER
+ */
+ do {
+ lsr = serial_echo_inb(UART_LSR);
+ } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
+ serial_echo_outb(ier, UART_IER);
+
+ return (0);
}
-static inline void memcpyw(unsigned short *to, unsigned short *from,
- unsigned int count)
+
+int
+serial_echo_init(int base)
{
- count /= 2;
- while (count) {
- count--;
- scr_writew(scr_readw(from++), to++);
- }
+ int comstat, hi, lo;
+
+ if (base != 0x2f8 && base != 0x3f8) {
+ serial_echo_port = 0;
+ return (0);
+ } else
+ serial_echo_port = base;
+
+ /*
+ * read the Divisor Latch
+ */
+ comstat = serial_echo_inb(UART_LCR);
+ serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR);
+ hi = serial_echo_inb(UART_DLM);
+ lo = serial_echo_inb(UART_DLL);
+ serial_echo_outb(comstat, UART_LCR);
+
+ /*
+ * now do hardwired init
+ */
+ serial_echo_outb(0x03, UART_LCR); /* No parity, 8 data bits, 1 stop */
+ serial_echo_outb(0x83, UART_LCR); /* Access divisor latch */
+ serial_echo_outb(0x00, UART_DLM); /* 9600 baud */
+ serial_echo_outb(0x0c, UART_DLL);
+ serial_echo_outb(0x03, UART_LCR); /* Done with divisor */
+
+ /* Prior to disabling interrupts, read the LSR and RBR
+ * registers
+ */
+ comstat = serial_echo_inb(UART_LSR); /* COM? LSR */
+ comstat = serial_echo_inb(UART_RX); /* COM? RBR */
+ serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */
+
+ return(0);
}
+#endif /* CONFIG_SERIAL_ECHO */
+
+
int vc_cons_allocated(unsigned int i)
{
return (i < MAX_NR_CONSOLES && vc_cons[i].d);
@@ -364,7 +318,7 @@ int vc_cons_allocated(unsigned int i)
int vc_allocate(unsigned int i) /* return 0 on success */
{
if (i >= MAX_NR_CONSOLES)
- return -ENODEV;
+ return -ENXIO;
if (!vc_cons[i].d) {
long p, q;
@@ -522,9 +476,17 @@ void vc_disallocate(unsigned int currcons)
#define VT100ID "\033[?1;2c"
#define VT102ID "\033[?6c"
-static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
+unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
8,12,10,14, 9,13,11,15 };
+/* the default colour table, for VGA+ colour systems */
+int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
+ 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
+int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
+ 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
+int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
+ 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
+
/*
* gotoxy() must verify all boundaries, because the arguments
* might also be negative. If the given position is out of
@@ -532,7 +494,7 @@ static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
*/
static void gotoxy(int currcons, int new_x, int new_y)
{
- int max_y;
+ int min_y, max_y;
if (new_x < 0)
x = 0;
@@ -542,70 +504,100 @@ static void gotoxy(int currcons, int new_x, int new_y)
else
x = new_x;
if (decom) {
- new_y += top;
+ min_y = top;
max_y = bottom;
- } else
+ } else {
+ min_y = 0;
max_y = video_num_lines;
- if (new_y < 0)
- y = 0;
- else
- if (new_y >= max_y)
- y = max_y - 1;
- else
- y = new_y;
- if (graph_mode)
- pos = origin + y*video_size_row + x*FONTSIZE_X;
+ }
+ if (new_y < min_y)
+ y = min_y;
+ else if (new_y >= max_y)
+ y = max_y - 1;
else
- pos = origin + y*video_size_row + (x<<1);
+ y = new_y;
+ pos = origin + y*video_size_row + (x<<1);
need_wrap = 0;
}
-/*
- * *Very* limited hardware scrollback support..
- */
-static unsigned short __real_origin;
-static unsigned short __origin; /* offset of currently displayed screen */
-
-static inline void __set_origin(unsigned short offset)
+/* for absolute user moves, when decom is set */
+static void gotoxay(int currcons, int new_x, int new_y)
{
- unsigned long flags;
+ gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
+}
- clear_selection();
+/*
+ * Hardware scrollback support
+ */
+extern void __set_origin(unsigned short);
+unsigned short __real_origin; /* offset of non-scrolled screen */
+unsigned short __origin; /* offset of currently displayed screen */
+unsigned char has_wrapped; /* all of videomem is data of fg_console */
+static unsigned char hardscroll_enabled;
+static unsigned char hardscroll_disabled_by_init = 0;
+
+void no_scroll(char *str, int *ints)
+{
+ /*
+ * Disabling scrollback is required for the Braillex ib80-piezo
+ * Braille reader made by F.H. Papenmeier (Germany).
+ * Use the "no-scroll" bootflag.
+ */
+ hardscroll_disabled_by_init = 1;
+ hardscroll_enabled = 0;
+}
+
+static void scrolldelta(int lines)
+{
+ int new_origin;
+ int last_origin_rel = (((video_mem_term - video_mem_base)
+ / video_num_columns / 2) - (video_num_lines - 1)) * video_num_columns;
+
+ new_origin = __origin + lines * video_num_columns;
+ if (__origin > __real_origin)
+ new_origin -= last_origin_rel;
+ if (new_origin < 0) {
+ int s_top = __real_origin + video_num_lines*video_num_columns;
+ new_origin += last_origin_rel;
+ if (new_origin < s_top)
+ new_origin = s_top;
+ if (new_origin > last_origin_rel - video_num_columns
+ || has_wrapped == 0)
+ new_origin = 0;
+ else {
+ unsigned short * d = (unsigned short *) video_mem_base;
+ unsigned short * s = d + last_origin_rel;
+ int count = (video_num_lines-1)*video_num_columns;
+ while (count) {
+ count--;
+ scr_writew(scr_readw(d++),s++);
+ }
+ }
+ } else if (new_origin > __real_origin)
+ new_origin = __real_origin;
- save_flags(flags); cli();
- __origin = offset;
- outb_p(12, video_port_reg);
- outb_p(offset >> 8, video_port_val);
- outb_p(13, video_port_reg);
- outb_p(offset, video_port_val);
- restore_flags(flags);
+ __set_origin(new_origin);
}
void scrollback(int lines)
{
if (!lines)
lines = video_num_lines/2;
- lines *= video_num_columns;
- lines = __origin - lines;
- if (lines < 0)
- lines = 0;
- __set_origin(lines);
+ scrolldelta(-lines);
}
void scrollfront(int lines)
{
if (!lines)
lines = video_num_lines/2;
- lines *= video_num_columns;
- lines = __origin + lines;
- if (lines > __real_origin)
- lines = __real_origin;
- __set_origin(lines);
+ scrolldelta(lines);
}
static void set_origin(int currcons)
{
- if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
+ if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_VGAC &&
+ video_type != VIDEO_TYPE_EGAM && video_type != VIDEO_TYPE_PICA_S3 &&
+ video_type != VIDEO_TYPE_SNI_RM)
return;
if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
return;
@@ -613,54 +605,33 @@ static void set_origin(int currcons)
__set_origin(__real_origin);
}
-/*
- * Put the cursor just beyond the end of the display adaptor memory.
- */
-static inline 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... */
- outb_p(14, video_port_reg);
- outb_p(0xff&((video_mem_term-video_mem_base)>>9), video_port_val);
- outb_p(15, video_port_reg);
- outb_p(0xff&((video_mem_term-video_mem_base)>>1), video_port_val);
-}
-
-static inline void set_cursor(int currcons)
+void scrup(int currcons, unsigned int t, unsigned int b)
{
- unsigned long flags;
+ int hardscroll = hardscroll_enabled;
- if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
- return;
- if (__real_origin != __origin)
- __set_origin(__real_origin);
- save_flags(flags); cli();
- if (deccm) {
- outb_p(14, video_port_reg);
- outb_p(0xff&((pos-video_mem_base)>>9), video_port_val);
- outb_p(15, video_port_reg);
- outb_p(0xff&((pos-video_mem_base)>>1), video_port_val);
- } else
- hide_cursor();
- restore_flags(flags);
-}
-
-static void scrup(int currcons, unsigned int t, unsigned int b)
-{
- int hardscroll = 1;
-
if (b > video_num_lines || t >= b)
return;
- if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
- hardscroll = 0;
- else if (t || b != video_num_lines)
+ if (t || b != video_num_lines)
hardscroll = 0;
if (hardscroll) {
origin += video_size_row;
pos += video_size_row;
scr_end += video_size_row;
- if (scr_end > video_mem_end) {
+#if 0
+ /*
+ * Aiiiieee. This check works for Alpha and Intel, but
+ * not for MIPS boxes ... The #ifdef is a temporary fix
+ * for MIPSes that is slooow.
+ */
+ if (origin >= last_origin || origin < video_mem_base) { /*}*/
+ if (scr_end > video_mem_end) { /*}*/
+#endif
+ /*
+ * Is the end of the area to scroll outside of the video RAM?
+ * If so, just do normal softscroll. The second part of the
+ * expression is important for some non-Intel architectures.
+ */
+ if (scr_end > video_mem_end || scr_end < video_mem_base) {
unsigned short * d = (unsigned short *) video_mem_start;
unsigned short * s = (unsigned short *) origin;
unsigned int count;
@@ -679,7 +650,9 @@ static void scrup(int currcons, unsigned int t, unsigned int b)
pos -= origin-video_mem_start;
origin = video_mem_start;
has_scrolled = 1;
- } else {
+ if (currcons == fg_console)
+ has_wrapped = 1;
+ } else {
unsigned short * d;
unsigned int count;
@@ -691,22 +664,7 @@ static void scrup(int currcons, unsigned int t, unsigned int b)
}
}
set_origin(currcons);
- } else if (graph_mode) {
- unsigned int * d = (unsigned int *) (origin+video_size_row*t);
- unsigned int * s = (unsigned int *) (origin+video_size_row*(t+1));
- unsigned int count = (b-t-1) * (video_size_row >> 2);
-
- while (count) {
- count--;
- *(d++) = *(s++);
- }
- count = video_size_row >> 2;
- while (count) {
- count--;
- *(d++) = (video_erase_char << 16) | video_erase_char;
- }
- }
- else {
+ } else {
unsigned short * d = (unsigned short *) (origin+video_size_row*t);
unsigned short * s = (unsigned short *) (origin+video_size_row*(t+1));
unsigned int count = (b-t-1) * video_num_columns;
@@ -722,8 +680,9 @@ static void scrup(int currcons, unsigned int t, unsigned int b)
}
}
}
-
-static void scrdown(int currcons, unsigned int t, unsigned int b)
+
+void
+scrdown(int currcons, unsigned int t, unsigned int b)
{
unsigned short *d, *s;
unsigned int count;
@@ -775,20 +734,14 @@ static void ri(int currcons)
static inline void cr(int currcons)
{
- if (graph_mode)
- pos -= x*FONTSIZE_X;
- else
- pos -= x<<1;
+ pos -= x<<1;
need_wrap = x = 0;
}
static inline void bs(int currcons)
{
if (x) {
- if (graph_mode)
- pos -= FONTSIZE_X;
- else
- pos -= 2;
+ pos -= 2;
x--;
need_wrap = 0;
}
@@ -854,7 +807,7 @@ static void csi_K(int currcons, int vpar)
}
need_wrap = 0;
}
-
+
static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
{ /* not vt100? */
unsigned long count;
@@ -872,7 +825,7 @@ static void csi_X(int currcons, int vpar) /* erase the following vpar positions
}
need_wrap = 0;
}
-
+
static void update_attr(int currcons)
{
attr = color;
@@ -898,10 +851,6 @@ static void update_attr(int currcons)
video_erase_char = (reverse_video_char(color) << 8) | ' ';
else
video_erase_char = (color << 8) | ' ';
-#ifdef CONFIG_MIPS_MAGNUM_4000
- if (boot_info.machtype == MACH_MIPS_MAGNUM_4000)
- video_erase_char = 0x0404;
-#endif
}
static void default_attr(int currcons)
@@ -949,10 +898,10 @@ static void csi_m(int currcons)
toggle_meta = 0;
break;
case 11: /* ANSI X3.64-1979 (SCO-ish?)
- * Select first alternate font, let's
+ * Select first alternate font, lets
* chars < 32 be displayed as ROM chars.
*/
- translate = set_translate(NULL_MAP);
+ translate = set_translate(IBMPC_MAP);
disp_ctrl = 1;
toggle_meta = 0;
break;
@@ -960,7 +909,7 @@ static void csi_m(int currcons)
* Select second alternate font, toggle
* high bit before displaying as ROM char.
*/
- translate = set_translate(NULL_MAP);
+ translate = set_translate(IBMPC_MAP);
disp_ctrl = 1;
toggle_meta = 1;
break;
@@ -999,7 +948,7 @@ static void csi_m(int currcons)
default:
if (par[i] >= 30 && par[i] <= 37)
color = color_table[par[i]-30]
- | background;
+ | background;
else if (par[i] >= 40 && par[i] <= 47)
color = (color_table[par[i]-40]<<4)
| foreground;
@@ -1008,7 +957,7 @@ static void csi_m(int currcons)
update_attr(currcons);
}
-static void respond_string(char * p, struct tty_struct * tty)
+static void respond_string(const char * p, struct tty_struct * tty)
{
while (*p) {
tty_insert_flip_char(tty, *p, 0);
@@ -1105,6 +1054,14 @@ unsigned short screen_word(int currcons, int offset, int viewed)
return scr_readw(screenpos(currcons, offset, viewed));
}
+/* used by selection - convert a screen word to a glyph number */
+int scrw2glyph(unsigned short scr_word)
+{
+ return ( video_mode_512ch )
+ ? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
+ : scr_word & 0x00ff;
+}
+
/* used by vcs - note the word offset */
unsigned short *screen_pos(int currcons, int w_offset, int viewed)
{
@@ -1152,7 +1109,7 @@ static void set_mode(int currcons, int on_off)
break;
case 6: /* Origin relative/absolute */
decom = on_off;
- gotoxy(currcons,0,0);
+ gotoxay(currcons,0,0);
break;
case 7: /* Autowrap on/off */
decawm = on_off;
@@ -1215,6 +1172,29 @@ static void setterm_command(int currcons)
blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
poke_blanked_console();
break;
+ case 10: /* set bell frequency in Hz */
+ if (npar >= 1)
+ bell_pitch = par[1];
+ else
+ bell_pitch = DEFAULT_BELL_PITCH;
+ break;
+ case 11: /* set bell duration in msec */
+ if (npar >= 1)
+ bell_duration = (par[1] < 2000) ?
+ par[1]*HZ/1000 : 0;
+ else
+ bell_duration = DEFAULT_BELL_DURATION;
+ break;
+ case 12: /* bring specified console to the front */
+ if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
+ update_screen(par[1]-1);
+ break;
+ case 13: /* unblank the screen */
+ unblank_screen();
+ break;
+ case 14: /* set vesa powerdown interval */
+ vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+ break;
}
}
@@ -1328,8 +1308,9 @@ static void restore_cur(int currcons)
need_wrap = 0;
}
-enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
- EShash, ESsetG0, ESsetG1, ESpercent, ESignore };
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
+ EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
+ ESpalette };
static void reset_terminal(int currcons, int do_clear)
{
@@ -1337,8 +1318,8 @@ static void reset_terminal(int currcons, int do_clear)
bottom = video_num_lines;
vc_state = ESnormal;
ques = 0;
- translate = set_translate(NORM_MAP);
- G0_charset = NORM_MAP;
+ translate = set_translate(LAT1_MAP);
+ G0_charset = LAT1_MAP;
G1_charset = GRAF_MAP;
charset = 0;
need_wrap = 0;
@@ -1360,6 +1341,7 @@ static void reset_terminal(int currcons, int do_clear)
clr_kbd(kbdapplic);
clr_kbd(lnm);
kbd_table[currcons].lockstate = 0;
+ kbd_table[currcons].slockstate = 0;
kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
set_leds();
@@ -1373,6 +1355,9 @@ static void reset_terminal(int currcons, int do_clear)
tab_stop[3] =
tab_stop[4] = 0x01010101;
+ bell_pitch = DEFAULT_BELL_PITCH;
+ bell_duration = DEFAULT_BELL_DURATION;
+
gotoxy(currcons,0,0);
save_cur(currcons);
if (do_clear)
@@ -1409,8 +1394,18 @@ static void con_start(struct tty_struct *tty)
set_leds();
}
-static int con_write(struct tty_struct * tty, int from_user,
- unsigned char *buf, int count)
+static void con_flush_chars(struct tty_struct *tty)
+{
+ unsigned int currcons;
+ struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+ currcons = vt->vc_num;
+ if (vcmode != KD_GRAPHICS)
+ set_cursor(currcons);
+}
+
+static int do_con_write(struct tty_struct * tty, int from_user,
+ const unsigned char *buf, int count)
{
int c, tc, ok, n = 0;
unsigned int currcons;
@@ -1430,20 +1425,25 @@ static int con_write(struct tty_struct * tty, int from_user,
if (currcons == sel_cons)
clear_selection();
- disable_bh(KEYBOARD_BH);
+ disable_bh(CONSOLE_BH);
while (!tty->stopped && count) {
- c = from_user ? get_user(buf) : *buf;
+ enable_bh(CONSOLE_BH);
+ if (from_user)
+ get_user(c, buf);
+ else
+ c = *buf;
buf++; n++; count--;
+ disable_bh(CONSOLE_BH);
if (utf) {
/* Combine UTF-8 into Unicode */
/* Incomplete characters silently ignored */
- if(c > 0x7f) {
+ if(c > 0x7f) {
if (utf_count > 0 && (c & 0xc0) == 0x80) {
utf_char = (utf_char << 6) | (c & 0x3f);
utf_count--;
if (utf_count == 0)
- c = utf_char;
+ tc = c = utf_char;
else continue;
} else {
if ((c & 0xe0) == 0xc0) {
@@ -1452,66 +1452,72 @@ static int con_write(struct tty_struct * tty, int from_user,
} else if ((c & 0xf0) == 0xe0) {
utf_count = 2;
utf_char = (c & 0x0f);
+ } else if ((c & 0xf8) == 0xf0) {
+ utf_count = 3;
+ utf_char = (c & 0x07);
+ } else if ((c & 0xfc) == 0xf8) {
+ utf_count = 4;
+ utf_char = (c & 0x03);
+ } else if ((c & 0xfe) == 0xfc) {
+ utf_count = 5;
+ utf_char = (c & 0x01);
} else
utf_count = 0;
continue;
- }
- } else
- utf_count = 0;
-
- /* Now try to find out how to display it */
- tc = conv_uni_to_pc(c);
- if (tc == -1 || tc == -2)
- continue;
- if (tc == -3 || tc == -4) { /* hashtable not valid */
- /* or symbol not found */
- tc = (c <= 0xff) ? translate[c] : 040;
- ok = 0;
- } else
- ok = 1;
+ }
+ } else {
+ tc = c;
+ utf_count = 0;
+ }
} else { /* no utf */
- tc = translate[toggle_meta ? (c|0x80) : c];
- ok = 0;
+ tc = translate[toggle_meta ? (c|0x80) : c];
}
- /* If the original code was < 32 we only allow a
- * glyph to be displayed if the code is not normally
- * used (such as for cursor movement) or if the
- * disp_ctrl mode has been explicitly enabled.
- * Note: ESC is *never* allowed to be displayed as
- * that would disable all escape sequences!
- */
- if (!ok && tc && (c >= 32 || (disp_ctrl && c != 0x1b)
- || !((CTRL_ACTION >> c) & 1)))
- ok = 1;
+ /* If the original code was a control character we
+ * only allow a glyph to be displayed if the code is
+ * not normally used (such as for cursor movement) or
+ * if the disp_ctrl mode has been explicitly enabled.
+ * Certain characters (as given by the CTRL_ALWAYS
+ * bitmap) are always displayed as control characters,
+ * as the console would be pretty useless without
+ * them; to display an arbitrary font position use the
+ * direct-to-font zone in UTF-8 mode.
+ */
+ ok = tc && (c >= 32 ||
+ (!utf && !(((disp_ctrl ? CTRL_ALWAYS
+ : CTRL_ACTION) >> c) & 1)))
+ && (c != 127 || disp_ctrl)
+ && (c != 128+27);
if (vc_state == ESnormal && ok) {
+ /* Now try to find out how to display it */
+ tc = conv_uni_to_pc(tc);
+ if ( tc == -4 ) {
+ /* If we got -4 (not found) then see if we have
+ defined a replacement character (U+FFFD) */
+ tc = conv_uni_to_pc(0xfffd);
+ } else if ( tc == -3 ) {
+ /* Bad hash table -- hope for the best */
+ tc = c;
+ }
+ if (tc & ~console_charmask)
+ continue; /* Conversion failed */
+
if (need_wrap) {
cr(currcons);
lf(currcons);
}
if (decim)
insert_char(currcons);
-#ifdef CONFIG_MIPS_MAGNUM_4000
- if (graph_mode) {
- gscr_pchar(tc, (unsigned char *)pos);
- if (x == video_num_columns - 1)
- need_wrap = 1;
- else {
- x++;
- pos += FONTSIZE_X;
- }
- }
- else /* graph_mode */
-#endif
- {
- scr_writew((attr << 8) + tc, (unsigned short *) pos);
- if (x == video_num_columns - 1)
- need_wrap = decawm;
- else {
- x++;
- pos+=2;
- }
+ scr_writew( video_mode_512ch ?
+ ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
+ (tc & 0x0ff) : (attr << 8) + tc,
+ (unsigned short *) pos);
+ if (x == video_num_columns - 1)
+ need_wrap = decawm;
+ else {
+ x++;
+ pos+=2;
}
continue;
}
@@ -1521,8 +1527,11 @@ static int con_write(struct tty_struct * tty, int from_user,
* of an escape sequence.
*/
switch (c) {
+ case 0:
+ continue;
case 7:
- kd_mksound(0x637, HZ/8);
+ if (bell_duration)
+ kd_mksound(bell_pitch, bell_duration);
continue;
case 8:
bs(currcons);
@@ -1573,6 +1582,9 @@ static int con_write(struct tty_struct * tty, int from_user,
case '[':
vc_state = ESsquare;
continue;
+ case ']':
+ vc_state = ESnonstd;
+ continue;
case '%':
vc_state = ESpercent;
continue;
@@ -1616,7 +1628,37 @@ static int con_write(struct tty_struct * tty, int from_user,
case '=': /* Appl. keypad */
set_kbd(kbdapplic);
continue;
- }
+ }
+ continue;
+ case ESnonstd:
+ if (c=='P') { /* palette escape sequence */
+ for (npar=0; npar<NPAR; npar++)
+ par[npar] = 0 ;
+ npar = 0 ;
+ vc_state = ESpalette;
+ continue;
+ } else if (c=='R') { /* reset palette */
+ reset_palette (currcons);
+ vc_state = ESnormal;
+ } else
+ vc_state = ESnormal;
+ continue;
+ case ESpalette:
+ if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
+ par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
+ if (npar==7) {
+ int i = par[0]*3, j = 1;
+ palette[i] = 16*par[j++];
+ palette[i++] += par[j++];
+ palette[i] = 16*par[j++];
+ palette[i++] += par[j++];
+ palette[i] = 16*par[j++];
+ palette[i] += par[j];
+ set_palette() ;
+ vc_state = ESnormal;
+ }
+ } else
+ vc_state = ESnormal;
continue;
case ESsquare:
for(npar = 0 ; npar < NPAR ; npar++)
@@ -1691,12 +1733,12 @@ static int con_write(struct tty_struct * tty, int from_user,
continue;
case 'd':
if (par[0]) par[0]--;
- gotoxy(currcons,x,par[0]);
+ gotoxay(currcons,x,par[0]);
continue;
case 'H': case 'f':
if (par[0]) par[0]--;
if (par[1]) par[1]--;
- gotoxy(currcons,par[1],par[0]);
+ gotoxay(currcons,par[1],par[0]);
continue;
case 'J':
csi_J(currcons,par[0]);
@@ -1747,7 +1789,7 @@ static int con_write(struct tty_struct * tty, int from_user,
par[1] <= video_num_lines) {
top=par[0]-1;
bottom=par[1];
- gotoxy(currcons,0,0);
+ gotoxay(currcons,0,0);
}
continue;
case 's':
@@ -1797,9 +1839,9 @@ static int con_write(struct tty_struct * tty, int from_user,
if (c == '0')
G0_charset = GRAF_MAP;
else if (c == 'B')
- G0_charset = NORM_MAP;
+ G0_charset = LAT1_MAP;
else if (c == 'U')
- G0_charset = NULL_MAP;
+ G0_charset = IBMPC_MAP;
else if (c == 'K')
G0_charset = USER_MAP;
if (charset == 0)
@@ -1810,9 +1852,9 @@ static int con_write(struct tty_struct * tty, int from_user,
if (c == '0')
G1_charset = GRAF_MAP;
else if (c == 'B')
- G1_charset = NORM_MAP;
+ G1_charset = LAT1_MAP;
else if (c == 'U')
- G1_charset = NULL_MAP;
+ G1_charset = IBMPC_MAP;
else if (c == 'K')
G1_charset = USER_MAP;
if (charset == 1)
@@ -1823,12 +1865,26 @@ static int con_write(struct tty_struct * tty, int from_user,
vc_state = ESnormal;
}
}
- if (vcmode != KD_GRAPHICS)
- set_cursor(currcons);
- enable_bh(KEYBOARD_BH);
+ enable_bh(CONSOLE_BH);
return n;
}
+static int con_write(struct tty_struct * tty, int from_user,
+ const unsigned char *buf, int count)
+{
+ int retval;
+
+ retval = do_con_write(tty, from_user, buf, count);
+ con_flush_chars(tty);
+
+ return retval;
+}
+
+static void con_put_char(struct tty_struct *tty, unsigned char ch)
+{
+ do_con_write(tty, 0, &ch, 1);
+}
+
static int con_write_room(struct tty_struct *tty)
{
if (tty->stopped)
@@ -1847,6 +1903,7 @@ void poke_blanked_console(void)
if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
return;
if (console_blanked) {
+ timer_table[BLANK_TIMER].fn = unblank_screen;
timer_table[BLANK_TIMER].expires = 0;
timer_active |= 1<<BLANK_TIMER;
} else if (blankinterval) {
@@ -1865,12 +1922,19 @@ void console_print(const char * b)
return; /* console not yet initialized */
printing = 1;
+ if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
+ currcons = kmsg_redirect - 1;
+
if (!vc_cons_allocated(currcons)) {
/* impossible */
printk("console_print: tty %d not allocated ??\n", currcons+1);
return;
}
+#ifdef CONFIG_SERIAL_ECHO
+ serial_echo_print(b);
+#endif /* CONFIG_SERIAL_ECHO */
+
while ((c = *(b++)) != 0) {
if (c == 10 || c == 13 || need_wrap) {
if (c != 13)
@@ -1879,28 +1943,17 @@ void console_print(const char * b)
if (c == 10 || c == 13)
continue;
}
-#ifdef CONFIG_MIPS_MAGNUM_4000
- if (graph_mode)
- {
- gscr_pchar(c, (unsigned char *) pos);
- if (x == video_num_columns - 1) {
- need_wrap = 1;
- continue;
- }
- x++;
- pos += FONTSIZE_X;
+ if (c == 8) { /* backspace */
+ bs(currcons);
+ continue;
}
- else
-#endif
- {
- scr_writew((attr << 8) + c, (unsigned short *) pos);
- if (x == video_num_columns - 1) {
- need_wrap = 1;
- continue;
- }
- x++;
- pos+=2;
+ scr_writew((attr << 8) + c, (unsigned short *) pos);
+ if (x == video_num_columns - 1) {
+ need_wrap = 1;
+ continue;
}
+ x++;
+ pos+=2;
}
set_cursor(currcons);
poke_blanked_console();
@@ -1926,19 +1979,22 @@ static void con_unthrottle(struct tty_struct *tty)
static void vc_init(unsigned int currcons, unsigned long rows, unsigned long cols, int do_clear)
{
long base = (long) vc_scrbuf[currcons];
+ int j, k ;
video_num_columns = cols;
video_num_lines = rows;
- if (graph_mode)
- video_size_row = cols * FONTSIZE_X * FONTSIZE_Y;
- else
- video_size_row = cols<<1;
+ video_size_row = cols<<1;
video_screen_size = video_num_lines * video_size_row;
pos = origin = video_mem_start = base;
scr_end = base + video_screen_size;
video_mem_end = base + video_screen_size;
reset_vc(currcons);
+ for (j=k=0; j<16; j++) {
+ vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
+ vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
+ vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
+ }
def_color = 0x07; /* white */
ulcolor = 0x0f; /* bold white */
halfcolor = 0x08; /* grey */
@@ -1950,14 +2006,38 @@ static void con_setsize(unsigned long rows, unsigned long cols)
{
video_num_lines = rows;
video_num_columns = cols;
- if (graph_mode)
- video_size_row = cols * FONTSIZE_X * FONTSIZE_Y;
- else
- video_size_row = 2 * cols;
+ video_size_row = 2 * cols;
video_screen_size = video_num_lines * video_size_row;
}
+
+/*
+ * This is the console switching bottom half handler.
+ *
+ * Doing console switching in a bottom half handler allows
+ * us to do the switches asynchronously (needed when we want
+ * to switch due to a keyboard interrupt), while still giving
+ * us the option to easily disable it to avoid races when we
+ * need to write to the console.
+ */
+static void console_bh(void)
+{
+ if (want_console >= 0) {
+ if (want_console != fg_console) {
+ change_console(want_console);
+ /* we only changed when the console had already
+ been allocated - a new console is not created
+ in an interrupt routine */
+ }
+ want_console = -1;
+ }
+ if (do_poke_blanked_console) { /* do not unblank for a LED change */
+ do_poke_blanked_console = 0;
+ poke_blanked_console();
+ }
+}
+
/*
- * long con_init(long);
+ * unsigned long con_init(unsigned long);
*
* This routine initializes console interrupts, and does nothing
* else. If you want the screen to clear, call tty_write with
@@ -1966,12 +2046,13 @@ static void con_setsize(unsigned long rows, unsigned long cols)
* Reads the information preserved by setup.s to determine the current display
* type and sets everything accordingly.
*/
-long con_init(long kmem_start)
+unsigned long con_init(unsigned long kmem_start)
{
- char *display_desc = "????";
+ const char *display_desc = "????";
int currcons = 0;
int orig_x = ORIG_X;
int orig_y = ORIG_Y;
+
memset(&console_driver, 0, sizeof(struct tty_driver));
console_driver.magic = TTY_DRIVER_MAGIC;
console_driver.name = "tty";
@@ -1981,7 +2062,7 @@ long con_init(long kmem_start)
console_driver.num = MAX_NR_CONSOLES;
console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
console_driver.init_termios = tty_std_termios;
- console_driver.flags = TTY_DRIVER_REAL_RAW;
+ console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
console_driver.refcount = &console_refcount;
console_driver.table = console_table;
console_driver.termios = console_termios;
@@ -1990,123 +2071,42 @@ long con_init(long kmem_start)
console_driver.open = con_open;
console_driver.write = con_write;
console_driver.write_room = con_write_room;
+ console_driver.put_char = con_put_char;
+ console_driver.flush_chars = con_flush_chars;
console_driver.chars_in_buffer = con_chars_in_buffer;
console_driver.ioctl = vt_ioctl;
console_driver.stop = con_stop;
console_driver.start = con_start;
console_driver.throttle = con_throttle;
console_driver.unthrottle = con_unthrottle;
-
+
if (tty_register_driver(&console_driver))
panic("Couldn't register console driver\n");
-
+
con_setsize(ORIG_VIDEO_LINES, ORIG_VIDEO_COLS);
- video_page = ORIG_VIDEO_PAGE; /* never used */
timer_table[BLANK_TIMER].fn = blank_screen;
timer_table[BLANK_TIMER].expires = 0;
if (blankinterval) {
- timer_table[BLANK_TIMER].expires = jiffies+blankinterval;
+ timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
timer_active |= 1<<BLANK_TIMER;
}
-#ifdef CONFIG_ACER_PICA_61
- /*
- * This type of video is only available as 64bit on board display for
- * MIPS machines based on the PICA chipset. If the loader has detected
- * such a machine assume that we use that type of video.
- */
- if (boot_info.machtype == MACH_ACER_PICA_61)
- {
- can_do_color = 1;
- video_port_reg = 0x3d4;
- video_port_val = 0x3d5;
- video_type = VIDEO_TYPE_PICA_S3;
- video_mem_base = boot_info.vram_base;
- video_mem_term = video_mem_base + 0x8000;
- display_desc = "PICA-S3";
- /*
- * Don't request a region - the video ports are outside of
- * the normal port address range.
- */
- }
- else
-#endif
-#ifdef CONFIG_MIPS_MAGNUM_4000
- /*
- * This type of video is only available as 64bit on board display for
- * MIPS Magnum 4000 machines. If the loader has detected such a machine
- * assume that we use that type of video.
- */
- if (boot_info.machtype == MACH_MIPS_MAGNUM_4000)
- {
- can_do_color = 1; /* always in colour graphics mode */
- graph_mode = 1; /* no text mode available */
- video_port_reg = 0x3d4; /* the usual (senseless) assumption... */
- video_port_val = 0x3d5;
- video_type = VIDEO_TYPE_MIPS_G364;
- video_mem_base = boot_info.vram_base;
- video_mem_term = video_mem_base;
- video_res_x = video_num_columns * FONTSIZE_X;
- display_desc = "MIPS-G364";
-
- /*
- * Don't request a region - the video ports are outside of
- * the normal port address range.
- */
- }
- else
-#endif
- if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */
- {
- video_mem_base = SLOTSPACE + 0xb0000;
- video_port_reg = 0x3b4;
- video_port_val = 0x3b5;
- if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
- {
- video_type = VIDEO_TYPE_EGAM;
- video_mem_term = SLOTSPACE + 0xb8000;
- display_desc = "EGA+";
- request_region(0x3b4,2,"ega+");
- }
- else
- {
- video_type = VIDEO_TYPE_MDA;
- video_mem_term = SLOTSPACE + 0xb2000;
- display_desc = "*MDA";
- request_region(0x3b4,2,"mda");
- request_region(0x3b8,1,"mda");
- request_region(0x3bf,1,"mda");
-
- }
- }
- else /* If not, it is color. */
- {
- can_do_color = 1;
- video_mem_base = SLOTSPACE + 0xb8000;
- video_port_reg = 0x3d4;
- video_port_val = 0x3d5;
- if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
- {
- video_type = VIDEO_TYPE_EGAC;
- video_mem_term = SLOTSPACE + 0xc0000;
- display_desc = "EGA+";
- request_region(0x3d4,2,"ega+");
- }
- else
- {
- video_type = VIDEO_TYPE_CGA;
- video_mem_term = SLOTSPACE + 0xba000;
- display_desc = "*CGA";
- request_region(0x3d4,2,"cga");
- }
- }
+ kmem_start = con_type_init(kmem_start, &display_desc);
- /* Initialize the variables used for scrolling (mostly EGA/VGA) */
+ hardscroll_enabled = (hardscroll_disabled_by_init ? 0 :
+ (video_type == VIDEO_TYPE_EGAC
+ || video_type == VIDEO_TYPE_VGAC
+ || video_type == VIDEO_TYPE_EGAM
+ || video_type == VIDEO_TYPE_PICA_S3
+ || video_type == VIDEO_TYPE_SNI_RM));
+ has_wrapped = 0 ;
/* Due to kmalloc roundup allocating statically is more efficient -
so provide MIN_NR_CONSOLES for people with very little memory */
for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
+ int j, k ;
+
vc_cons[currcons].d = (struct vc_data *) kmem_start;
kmem_start += sizeof(struct vc_data);
vt_cons[currcons] = (struct vt_struct *) kmem_start;
@@ -2115,7 +2115,12 @@ long con_init(long kmem_start)
kmem_start += video_screen_size;
kmalloced = 0;
screenbuf_size = video_screen_size;
- vc_init(currcons, video_num_lines, video_num_columns, currcons);
+ vc_init(currcons, video_num_lines, video_num_columns, currcons);
+ for (j=k=0; j<16; j++) {
+ vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
+ vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
+ vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
+ }
}
currcons = fg_console = 0;
@@ -2127,73 +2132,72 @@ long con_init(long kmem_start)
gotoxy(currcons,orig_x,orig_y);
set_origin(currcons);
csi_J(currcons, 0);
+
+ /* Figure out the size of the screen and screen font so we
+ can figure out the appropriate screen size should we load
+ a different font */
+
printable = 1;
+ if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC
+ || video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC )
+ {
+ default_font_height = video_font_height = ORIG_VIDEO_POINTS;
+ /* This may be suboptimal but is a safe bet - go with it */
+ video_scan_lines = video_font_height * video_num_lines;
+
+#ifdef CONFIG_SERIAL_ECHO
+ serial_echo_init(SERIAL_ECHO_PORT);
+#endif /* CONFIG_SERIAL_ECHO */
+
+ printk("Console: %ld point font, %ld scans\n",
+ video_font_height, video_scan_lines);
+ }
+#if defined(CONFIG_ACER_PICA_61) || defined(CONFIG_SNI_RM200_PCI)
+ else if (video_type == VIDEO_TYPE_PICA_S3 ||
+ video_type == VIDEO_TYPE_SNI_RM)
+ {
+ /*
+ * Fixme: we should detect this. But still 16 is a reasonable
+ * assumption.
+ */
+ default_font_height = video_font_height = 16;
+ /* This may be suboptimal but is a safe bet - go with it */
+ video_scan_lines = video_font_height * video_num_lines;
+
+#ifdef CONFIG_SERIAL_ECHO
+ serial_echo_init(SERIAL_ECHO_PORT);
+#endif /* CONFIG_SERIAL_ECHO */
+
+ printk("Console: %ld point font, %ld scans\n",
+ video_font_height, video_scan_lines);
+ }
+#endif
+
printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
can_do_color ? "colour" : "mono",
- display_desc,
- video_num_columns,video_num_lines,
- MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
- register_console(console_print);
+ display_desc, video_num_columns, video_num_lines,
+ MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s",
+ MAX_NR_CONSOLES);
+
+ /*
+ * can't register TGA yet, because PCI bus probe has *not* taken
+ * place before con_init() gets called. Trigger the real TGA hw
+ * initialization and register_console() event from
+ * within the bus probing code... :-(
+ */
+ if (video_type != VIDEO_TYPE_TGAC)
+ register_console(console_print);
+
+ init_bh(CONSOLE_BH, console_bh);
return kmem_start;
}
-static void get_scrmem(int currcons)
+void vesa_powerdown_screen(void)
{
- 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;
- if (graph_mode)
- pos = origin + y*video_size_row + x*FONTSIZE_X;
- else
- pos = origin + y*video_size_row + (x<<1);
-}
-
-static 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;
- if (graph_mode)
- pos = origin + y*video_size_row + x*FONTSIZE_X;
- else
- pos = origin + y*video_size_row + (x<<1);
+ timer_active &= ~(1<<BLANK_TIMER);
+ timer_table[BLANK_TIMER].fn = unblank_screen;
+
+ vesa_powerdown();
}
void do_blank_screen(int nopowersave)
@@ -2203,8 +2207,14 @@ void do_blank_screen(int nopowersave)
if (console_blanked)
return;
- timer_active &= ~(1<<BLANK_TIMER);
- timer_table[BLANK_TIMER].fn = unblank_screen;
+ if(vesa_off_interval && !nopowersave) {
+ timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
+ timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
+ timer_active |= (1<<BLANK_TIMER);
+ } else {
+ timer_active &= ~(1<<BLANK_TIMER);
+ timer_table[BLANK_TIMER].fn = unblank_screen;
+ }
/* try not to lose information by blanking, and not to waste memory */
currcons = fg_console;
@@ -2214,10 +2224,15 @@ void do_blank_screen(int nopowersave)
set_origin(fg_console);
get_scrmem(fg_console);
unblank_origin = origin;
- memsetw((void *)blank_origin, BLANK, video_mem_term-blank_origin);
+ memsetw((void *)blank_origin, BLANK,
+ 2*video_num_lines*video_num_columns);
hide_cursor();
console_blanked = fg_console + 1;
+#ifdef CONFIG_APM
+ if (apm_display_blank())
+ return;
+#endif
if(!nopowersave)
vesa_blank();
}
@@ -2260,6 +2275,10 @@ void do_unblank_screen(void)
__set_origin(blank__origin);
vesa_unblank();
+#ifdef CONFIG_APM
+ if (apm_display_unblank())
+ return;
+#endif
}
/*
@@ -2297,7 +2316,7 @@ void update_screen(int new_console)
console_blanked = -1; /* no longer of the form console+1 */
fg_console = new_console; /* this is the only (nonzero) assignment to fg_console */
/* consequently, fg_console will always be allocated */
- set_scrmem(fg_console, 0);
+ set_scrmem(fg_console, 0);
set_origin(fg_console);
set_cursor(fg_console);
set_leds();
@@ -2314,14 +2333,14 @@ int con_open(struct tty_struct *tty, struct file * filp)
int i;
idx = MINOR(tty->device) - tty->driver.minor_start;
-
+
i = vc_allocate(idx);
if (i)
return i;
vt_cons[idx]->vc_num = idx;
tty->driver_data = vt_cons[idx];
-
+
if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
tty->winsize.ws_row = video_num_lines;
tty->winsize.ws_col = video_num_columns;
@@ -2331,96 +2350,29 @@ int con_open(struct tty_struct *tty, struct file * filp)
/*
- * 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).
+ * Load palette into the EGA/VGA DAC registers. arg points to a colour
+ * map, 3 bytes per colour, 16 colours, range from 0 to 255.
*/
-#define colourmap ((char *)(SLOTSPACE + 0xa0000))
-/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
- should use 0xA0000 for the bwmap as well.. */
-#define blackwmap ((char *)(SLOTSPACE + 0xa0000))
-#define cmapsz 8192
-#define seq_port_reg (0x3c4)
-#define seq_port_val (0x3c5)
-#define gr_port_reg (0x3ce)
-#define gr_port_val (0x3cf)
-
-static int set_get_font(char * arg, int set)
+int con_set_cmap (unsigned char *arg)
{
-#ifdef CAN_LOAD_EGA_FONTS
- int i;
- char *charmap;
- int beg;
-
- /* no use to "load" CGA... */
-
- if (video_type == VIDEO_TYPE_EGAC) {
- charmap = colourmap;
- beg = 0x0e;
- } else if (video_type == VIDEO_TYPE_EGAM) {
- charmap = blackwmap;
- beg = 0x0a;
- } else
- return -EINVAL;
-
- i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
- if (i)
- return i;
+ return set_get_cmap (arg,1);
+}
- 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 (set)
- for (i=0; i<cmapsz ; i++)
- scr_writeb(get_user(arg + i), 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 */
- 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 */
- sti();
+int con_get_cmap (unsigned char *arg)
+{
+ return set_get_cmap (arg,0);
+}
- return 0;
-#else
- return -EINVAL;
-#endif
+void reset_palette (int currcons)
+{
+ int j, k ;
+ for (j=k=0; j<16; j++) {
+ palette[k++] = default_red[j];
+ palette[k++] = default_grn[j];
+ palette[k++] = default_blu[j];
+ }
+ set_palette() ;
}
/*
@@ -2429,13 +2381,20 @@ static int set_get_font(char * arg, int set)
* 8xH fonts (0 < H <= 32).
*/
-int con_set_font (char *arg)
+int con_set_font (char *arg, int ch512)
{
- hashtable_contents_valid = 0;
- return set_get_font (arg,1);
+ int i;
+
+ i = set_get_font (arg,1,ch512);
+ if ( !i ) {
+ hashtable_contents_valid = 0;
+ video_mode_512ch = ch512;
+ console_charmask = ch512 ? 0x1ff : 0x0ff;
+ }
+ return i;
}
int con_get_font (char *arg)
{
- return set_get_font (arg,0);
+ return set_get_font (arg,0,video_mode_512ch);
}