diff options
Diffstat (limited to 'sys/i386/isa/syscons.c')
| -rw-r--r-- | sys/i386/isa/syscons.c | 1509 |
1 files changed, 867 insertions, 642 deletions
diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c index f77190c8f85c..afd5f468fc54 100644 --- a/sys/i386/isa/syscons.c +++ b/sys/i386/isa/syscons.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 1992-1994 Søren Schmidt * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * @@ -33,17 +34,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)pccons.c 5.11 (Berkeley) 5/21/91 - * from: @(#)syscons.c 1.0 930928 - * $Id: syscons.c,v 1.14 1993/10/18 02:19:54 jkh Exp $ + * from:@(#)syscons.c 1.3 940129 + * $Id: syscons.c,v 1.35.2.2 1994/05/03 07:01:43 rgrimes Exp $ * - * Heavily modified by Søren Schmidt (sos@login.dkuug.dk) to provide: - * - * virtual consoles, SYSV ioctl's, ANSI emulation */ -#define STAR_SAVER -/* #define FAT_CURSOR /* This breaks on some CGA displays */ +#if !defined(__FreeBSD__) +#define FAT_CURSOR +#endif #include "param.h" #include "conf.h" @@ -57,22 +55,22 @@ #include "kernel.h" #include "syslog.h" #include "errno.h" -#include "machine/console.h" #include "malloc.h" -#include "i386/isa/icu.h" #include "i386/isa/isa.h" #include "i386/isa/isa_device.h" -#include "machine/pc/display.h" +#include "i386/isa/timerreg.h" #include "i386/i386/cons.h" +#include "machine/console.h" #include "machine/psl.h" #include "machine/frame.h" -#include "sc.h" -#include "ddb.h" +#include "machine/pc/display.h" #include "iso8859.font" #include "kbdtables.h" +#include "sc.h" #if NSC > 0 -#ifndef NCONS + +#if !defined(NCONS) #define NCONS 12 #endif @@ -84,12 +82,8 @@ #define SWITCH_WAIT_REL 0x00040 #define SWITCH_WAIT_ACQ 0x00080 -/* virtual video memory addresses */ -#define MONO_BUF (KERNBASE + 0xB0000) -#define CGA_BUF (KERNBASE + 0xB8000) -#define VGA_BUF (KERNBASE + 0xA0000) +/* video hardware memory addresses */ #define VIDEOMEM 0x000A0000 -#define MEMSIZE 0x00020000 /* misc defines */ #define MAX_ESC_PAR 3 @@ -97,9 +91,10 @@ #define TEXT80x50 2 #define COL 80 #define ROW 25 -#ifndef XTALSPEED -#define XTALSPEED 1193182 /* should be in isa.h */ -#endif +#define BELL_DURATION 5 +#define BELL_PITCH 800 +#define TIMER_FREQ 1193182 /* should be in isa.h */ +#define PCBURST 128 /* defines related to hardware addresses */ #define MONO_BASE 0x3B4 /* crt controller base mono */ @@ -114,27 +109,35 @@ #define GDCIDX IO_VGA+0x0E /* graph data controller idx */ #define GDCREG IO_VGA+0x0F /* graph data controller data */ +/* special characters */ +#define cntlc 0x03 +#define cntld 0x04 +#define bs 0x08 +#define lf 0x0a +#define cr 0x0d +#define del 0x7f + typedef struct term_stat { int esc; /* processing escape sequence */ - int n_par; /* # of parameters to ESC */ - int last_par; /* last parameter # */ - int par[MAX_ESC_PAR]; /* contains ESC parameters */ - int attr; /* current attributes */ + int num_param; /* # of parameters to ESC */ + int last_param; /* last parameter # */ + int param[MAX_ESC_PAR]; /* contains ESC parameters */ + int cur_attr; /* current attributes */ int std_attr; /* normal attributes */ int rev_attr; /* reverse attributes */ } term_stat; typedef struct scr_stat { u_short *crt_base; /* address of screen memory */ - u_short *scr; /* buffer when off screen */ + u_short *scr_buf; /* buffer when off screen */ u_short *crtat; /* cursor address */ - int posx; /* current X position */ - int posy; /* current Y position */ - int max_posx; /* X size */ - int max_posy; /* X size */ + int xpos; /* current X position */ + int ypos; /* current Y position */ + int xsize; /* X size */ + int ysize; /* Y size */ term_stat term; /* terminal emulation stuff */ char cursor_start; /* cursor start line # */ - char cursor_end; /* cursor start end # */ + char cursor_end; /* cursor end line # */ u_char border; /* border color */ u_short bell_duration; u_short bell_pitch; @@ -160,56 +163,36 @@ static default_attr kernel_default = { (FG_BLACK | BG_LIGHTGREY) << 8 }; -static default_attr *current_default; +#define CONSOLE_BUFFER_SIZE 1024 +int console_buffer_count; +char console_buffer[CONSOLE_BUFFER_SIZE]; -static scr_stat cons_scr_stat[NCONS]; -static scr_stat *cur_scr_stat = &cons_scr_stat[0]; -static scr_stat *new_scp, *old_scp; +static scr_stat console[NCONS]; +static scr_stat *cur_console = &console[0]; +static scr_stat *new_scp, *old_scp; static term_stat kernel_console; +static default_attr *current_default; static int switch_in_progress = 0; - -u_short *Crtat = (u_short *)MONO_BUF; static u_short *crtat = 0; static u_int crtc_addr = MONO_BASE; static char crtc_vga = 0; -static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0; +static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0; static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0; static char palette[3*256]; static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int cur_cursor_pos = -1; -static char in_putc, nx_scr; +static char in_putc = 0; +static char polling = 0; +static int delayed_next_scr; static char saved_console = -1; /* saved console number */ static long scrn_blank_time = 0; /* screen saver timout value */ static int scrn_blanked = 0; /* screen saver active flag */ +static int scrn_saver = 0; /* screen saver routine */ static long scrn_time_stamp; static u_char scr_map[256]; - -struct tty pccons[NCONS]; -struct tty *cur_pccons = &pccons[0]; -struct tty *new_pccons; - extern int hz; extern struct timeval time; -#define CSF_ACTIVE 0x1 /* timeout active */ -#define CSF_POLLING 0x2 /* polling for input */ - -struct pcconsoftc { - char cs_flags; - char cs_lastc; /* last char sent */ - int cs_timo; /* timeouts since interrupt */ - u_long cs_wedgecnt; /* times restarted */ -} pcconsoftc = {0, 0, 0, 0}; - - -/* special characters */ -#define bs 8 -#define lf 10 -#define cr 13 -#define cntlc 3 -#define del 0177 -#define cntld 4 - /* function prototypes */ int pcprobe(struct isa_device *dev); int pcattach(struct isa_device *dev); @@ -219,44 +202,108 @@ int pcread(dev_t dev, struct uio *uio, int flag); int pcwrite(dev_t dev, struct uio *uio, int flag); int pcparam(struct tty *tp, struct termios *t); int pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p); -int pcxint(dev_t dev); -int pcstart(struct tty *tp); -int pccnprobe(struct consdev *cp); -int pccninit(struct consdev *cp); -int pccnputc(dev_t dev, char c); +void pcxint(dev_t dev); +void pcstart(struct tty *tp); +void pccnprobe(struct consdev *cp); +void pccninit(struct consdev *cp); +void pccnputc(dev_t dev, char c); int pccngetc(dev_t dev); -int scintr(dev_t dev, int irq, int cpl); -void scrn_saver(int test); -static struct tty *get_pccons(dev_t dev); +void scintr(int unit); +int pcmmap(dev_t dev, int offset, int nprot); +u_int sgetc(int noblock); +int getchar(void); +static void scinit(void); +static void scput(u_char c); +static u_int scgetc(int noblock); +static struct tty *get_tty_ptr(dev_t dev); static scr_stat *get_scr_stat(dev_t dev); -static int get_scr_num(scr_stat *scp); +static int get_scr_num(); static void cursor_shape(int start, int end); static void get_cursor_shape(int *start, int *end); -static void cursor_pos(void); +static void cursor_pos(int force); static void clear_screen(scr_stat *scp); -static switch_scr(u_int next_scr); +static int switch_scr(u_int next_scr); static void exchange_scr(void); static void move_crsr(scr_stat *scp, int x, int y); static void move_up(u_short *s, u_short *d, u_int len); static void move_down(u_short *s, u_short *d, u_int len); static void scan_esc(scr_stat *scp, u_char c); static void ansi_put(scr_stat *scp, u_char c); -void consinit(void); -static void sput(u_char c); static u_char *get_fstr(u_int c, u_int *len); -static update_leds(int which); -void reset_cpu(void); -u_int sgetc(int noblock); -int pcmmap(dev_t dev, int offset, int nprot); -int getchar(void); +static void update_leds(int which); static void kbd_wait(void); static void kbd_cmd(u_char command); +static void kbd_cmd2(u_char command, u_char arg); +static int kbd_reply(void); static void set_mode(scr_stat *scp); static void set_border(int color); -static load_font(int segment, int size, char* font); +static void load_font(int segment, int size, char* font); static void save_palette(void); static void load_palette(void); -static change_winsize(struct tty *tp, int x, int y); +static void change_winsize(struct tty *tp, int x, int y); + + +/* available screen savers */ + +static void none_saver(int test); +static void blank_saver(int test); +static void fade_saver(int test); +static void star_saver(int test); +static void snake_saver(int test); + +static const struct { + char *name; + void (*routine)(); +} screen_savers[] = { + { "none", none_saver }, /* 0 */ + { "blank", blank_saver }, /* 1 */ + { "fade", fade_saver }, /* 2 */ + { "star", star_saver }, /* 3 */ + { "snake", snake_saver }, /* 4 */ +}; +#define SCRN_SAVER(arg) (*screen_savers[scrn_saver].routine)(arg) +#define NUM_SCRN_SAVERS (sizeof(screen_savers) / sizeof(screen_savers[0])) + +/* OS specific stuff */ + +#if defined(NetBSD) +#define VIRTUAL_TTY(x) pc_tty[x] ? (pc_tty[x]) : (pc_tty[x] = ttymalloc()) +#define CONSOLE_TTY pc_tty[NCONS] ? (pc_tty[NCONS]) : (pc_tty[NCONS] = ttymalloc()) +#define frametype struct trapframe +#define eflags tf_eflags +extern u_short *Crtat; +struct tty *pc_tty[NCONS+1]; +int ttrstrt(); +#endif + +#if defined(__FreeBSD__) +#define frametype struct trapframe +#define eflags tf_eflags +#define timeout_t timeout_func_t +#define MONO_BUF (KERNBASE+0xB0000) +#define CGA_BUF (KERNBASE+0xB8000) +#endif + +#if defined(__386BSD__) && !defined(__FreeBSD__) +#define frametype struct syscframe +#define eflags sf_eflags +#define timeout_t caddr_t +#define MONO_BUF (0xFE0B0000) +#define CGA_BUF (0xFE0B8000) +#endif + +#if defined(__386BSD__) || defined(__FreeBSD__) +#define VIRTUAL_TTY(x) &pccons[x] +#define CONSOLE_TTY &pccons[NCONS] +u_short *Crtat = (u_short *)MONO_BUF; +struct tty pccons[NCONS+1]; +void consinit(void) {scinit();} +#include "ddb.h" +#if NDDB > 0 +#define DDB 1 +#endif +#endif + struct isa_driver scdriver = { pcprobe, pcattach, "sc", @@ -265,25 +312,19 @@ struct isa_driver scdriver = { int pcprobe(struct isa_device *dev) { - u_char c; - int again = 0; - /* Enable interrupts and keyboard controller */ kbd_wait(); outb(KB_STAT, KB_WRITE); kbd_cmd(0x4D); /* Start keyboard stuff RESET */ - kbd_cmd(KB_RESET); - while ((c=inb(KB_DATA)) != KB_ACK) { - if ((c == 0xFE) || (c == 0xFF)) { - if (!again) - printf("KEYBOARD disconnected: RECONNECT \n"); - kbd_cmd(KB_RESET); - again = 1; - } + for (;;) { + kbd_cmd(KB_RESET); + if (kbd_reply() == KB_ACK && /* command accepted */ + kbd_reply() == 0xaa) /* self test passed */ + break; + printf("Keyboard reset failed\n"); } - kbd_wait(); return (IO_KBDSIZE); } @@ -293,6 +334,7 @@ int pcattach(struct isa_device *dev) scr_stat *scp; int start = -1, end = -1, i; + printf("sc%d: ", dev->id_unit); if (crtc_vga) if (crtc_addr == MONO_BASE) printf("VGA mono"); @@ -308,12 +350,12 @@ int pcattach(struct isa_device *dev) printf(" <%d virtual consoles>\n", NCONS); else printf("\n"); -#ifdef FAT_CURSOR +#if defined(FAT_CURSOR) start = 0; end = 18; -#endif if (crtc_vga) { -#ifndef FAT_CURSOR +#else + if (crtc_vga) { get_cursor_shape(&start, &end); #endif save_palette(); @@ -323,76 +365,82 @@ int pcattach(struct isa_device *dev) } current_default = &user_default; for (i = 0; i < NCONS; i++) { - scp = &cons_scr_stat[i]; - scp->scr = (u_short *)malloc(COL * ROW * 2, M_DEVBUF, M_NOWAIT); + scp = &console[i]; + scp->scr_buf = (u_short *)malloc(COL * ROW * 2, M_DEVBUF, M_NOWAIT); scp->mode = TEXT80x25; scp->term.esc = 0; scp->term.std_attr = current_default->std_attr; scp->term.rev_attr = current_default->rev_attr; - scp->term.attr = scp->term.std_attr; + scp->term.cur_attr = scp->term.std_attr; scp->border = BG_BLACK; scp->cursor_start = start; scp->cursor_end = end; - scp->max_posx = COL; - scp->max_posy = ROW; - scp->bell_pitch = 800; - scp->bell_duration = 10; + scp->xsize = COL; + scp->ysize = ROW; + scp->bell_pitch = BELL_PITCH; + scp->bell_duration = BELL_DURATION; scp->status = 0; scp->pid = 0; scp->proc = NULL; scp->smode.mode = VT_AUTO; if (i > 0) { - scp->crt_base = scp->crtat = scp->scr; - fillw(scp->term.attr|scr_map[0x20], scp->scr, COL*ROW); + scp->crt_base = scp->crtat = scp->scr_buf; + fillw(scp->term.cur_attr|scr_map[0x20], scp->scr_buf, COL*ROW); } } /* get cursor going */ -#ifdef FAT_CURSOR - cursor_shape(cons_scr_stat[0].cursor_start, - cons_scr_stat[0].cursor_end); +#if defined(FAT_CURSOR) + cursor_shape(console[0].cursor_start, + console[0].cursor_end); #endif - cursor_pos(); + cursor_pos(1); + return 0; } -static struct tty *get_pccons(dev_t dev) +static struct tty *get_tty_ptr(dev_t dev) { - int i = minor(dev); + int unit = minor(dev); - if (i >= NCONS) + if (unit > NCONS) return(NULL); - return(&pccons[i]); + if (unit == NCONS) + return(CONSOLE_TTY); + return(VIRTUAL_TTY(unit)); } static scr_stat *get_scr_stat(dev_t dev) { - int i = minor(dev); + int unit = minor(dev); - if (i >= NCONS) + if (unit > NCONS) return(NULL); - return(&cons_scr_stat[i]); + if (unit == NCONS) + return(&console[0]); + return(&console[unit]); } -static int get_scr_num(scr_stat *scp) /* allways call with legal scp !! */ +static int get_scr_num() { int i = 0; - while ((i < NCONS) && (cur_scr_stat != &cons_scr_stat[i])) i++; - return i; + while ((i < NCONS) && (cur_console != &console[i])) i++; + return i < NCONS ? i : 0; } -pcopen(dev_t dev, int flag, int mode, struct proc *p) +int pcopen(dev_t dev, int flag, int mode, struct proc *p) { - struct tty *tp = get_pccons(dev); + struct tty *tp = get_tty_ptr(dev); if (!tp) return(ENXIO); + tp->t_oproc = pcstart; tp->t_param = pcparam; tp->t_dev = dev; - if ((tp->t_state & TS_ISOPEN) == 0) { + if (!(tp->t_state & TS_ISOPEN)) { tp->t_state |= TS_WOPEN; ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; @@ -405,30 +453,39 @@ pcopen(dev_t dev, int flag, int mode, struct proc *p) } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) return(EBUSY); tp->t_state |= TS_CARR_ON; + tp->t_cflag |= CLOCAL; +#if defined(__FreeBSD__) + return((*linesw[tp->t_line].l_open)(dev, tp, 0)); +#else return((*linesw[tp->t_line].l_open)(dev, tp)); +#endif } -pcclose(dev_t dev, int flag, int mode, struct proc *p) +int pcclose(dev_t dev, int flag, int mode, struct proc *p) { - struct tty *tp = get_pccons(dev); + struct tty *tp = get_tty_ptr(dev); struct scr_stat *scp; if (!tp) return(ENXIO); - scp = get_scr_stat(tp->t_dev); - scp->pid = 0; - scp->proc = NULL; - scp->smode.mode = VT_AUTO; + if (minor(dev) < NCONS) { + scp = get_scr_stat(tp->t_dev); + if (scp->status & SWITCH_WAIT_ACQ) + wakeup((caddr_t)&scp->smode); + scp->pid = 0; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + } (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); return(0); } -pcread(dev_t dev, struct uio *uio, int flag) +int pcread(dev_t dev, struct uio *uio, int flag) { - struct tty *tp = get_pccons(dev); + struct tty *tp = get_tty_ptr(dev); if (!tp) return(ENXIO); @@ -436,9 +493,9 @@ pcread(dev_t dev, struct uio *uio, int flag) } -pcwrite(dev_t dev, struct uio *uio, int flag) +int pcwrite(dev_t dev, struct uio *uio, int flag) { - struct tty *tp = get_pccons(dev); + struct tty *tp = get_tty_ptr(dev); if (!tp) return(ENXIO); @@ -450,36 +507,51 @@ pcwrite(dev_t dev, struct uio *uio, int flag) * Got a console interrupt, keyboard action ! * Catch the character, and see who it goes to. */ -scintr(dev_t dev, int irq, int cpl) +void scintr(int unit) { + static struct tty *cur_tty; int c, len; u_char *cp; /* make screensaver happy */ scrn_time_stamp = time.tv_sec; if (scrn_blanked) - scrn_saver(0); - c = sgetc(1); - if (c & 0x100) - return; - if ((cur_pccons->t_state & TS_ISOPEN) == 0) - return; - if (pcconsoftc.cs_flags & CSF_POLLING) + SCRN_SAVER(0); + + c = scgetc(1); + + cur_tty = VIRTUAL_TTY(get_scr_num()); + if (!(cur_tty->t_state & TS_ISOPEN)) + cur_tty = CONSOLE_TTY; + + if (!(cur_tty->t_state & TS_ISOPEN) || polling) return; - if (c < 0x100) - (*linesw[cur_pccons->t_line].l_rint)(c & 0xFF, cur_pccons); - else if (cp = get_fstr((u_int)c, (u_int *)&len)) { - while (len-- > 0) - (*linesw[cur_pccons->t_line].l_rint) - (*cp++ & 0xFF, cur_pccons); - } + + switch (c & 0xff00) { + case 0x0000: /* normal key */ + (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty); + break; + case NOKEY: /* nothing there */ + break; + case FKEY: /* function key, return string */ + if (cp = get_fstr((u_int)c, (u_int *)&len)) { + while (len-- > 0) + (*linesw[cur_tty->t_line].l_rint) + (*cp++ & 0xFF, cur_tty); + } + break; + case MKEY: /* meta is active, prepend ESC */ + (*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty); + (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty); + break; + } } /* * Set line parameters */ -pcparam(struct tty *tp, struct termios *t) +int pcparam(struct tty *tp, struct termios *t) { int cflag = t->c_cflag; @@ -487,18 +559,18 @@ pcparam(struct tty *tp, struct termios *t) tp->t_ispeed = t->c_ispeed; tp->t_ospeed = t->c_ospeed; tp->t_cflag = cflag; - return(0); + return 0; } -pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) +int pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) { int i, error; struct tty *tp; - struct syscframe *fp; + frametype *fp; scr_stat *scp; - tp = get_pccons(dev); + tp = get_tty_ptr(dev); if (!tp) return ENXIO; scp = get_scr_stat(tp->t_dev); @@ -508,49 +580,69 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ scrn_blank_time = *(int*)data; return 0; - + case CONS_SSAVER: /* set screen saver */ + { + register ssaver_t *sav = (ssaver_t *)data; + if (sav->num < 0 || sav->num >= NUM_SCRN_SAVERS) + return EIO; + SCRN_SAVER(0); + scrn_saver = sav->num; + scrn_blank_time = sav->time; + return 0; + } + case CONS_GSAVER: /* get screen saver info */ + { + register ssaver_t *sav = (ssaver_t *)data; + if (sav->num < 0) + sav->num = scrn_saver; + else if (sav->num >= NUM_SCRN_SAVERS) + return EIO; + sav->time = scrn_blank_time; + strcpy(sav->name, screen_savers[sav->num].name); + return 0; + } case CONS_80x25TEXT: /* set 80x25 text mode */ if (!crtc_vga) return ENXIO; scp->mode = TEXT80x25; - scp->max_posy = 25; - free(scp->scr, M_DEVBUF); - scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + scp->ysize = 25; + free(scp->scr_buf, M_DEVBUF); + scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*2, M_DEVBUF, M_NOWAIT); - if (scp != cur_scr_stat) - scp->crt_base = scp->scr; + if (scp != cur_console) + scp->crt_base = scp->scr_buf; set_mode(scp); clear_screen(scp); - change_winsize(tp, scp->max_posx, scp->max_posy); + change_winsize(tp, scp->xsize, scp->ysize); return 0; case CONS_80x50TEXT: /* set 80x50 text mode */ if (!crtc_vga) return ENXIO; scp->mode = TEXT80x50; - scp->max_posy = 50; - free(scp->scr, M_DEVBUF); - scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + scp->ysize = 50; + free(scp->scr_buf, M_DEVBUF); + scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*2, M_DEVBUF, M_NOWAIT); - if (scp != cur_scr_stat) - scp->crt_base = scp->scr; + if (scp != cur_console) + scp->crt_base = scp->scr_buf; set_mode(scp); clear_screen(scp); - change_winsize(tp, scp->max_posx, scp->max_posy); + change_winsize(tp, scp->xsize, scp->ysize); return 0; case CONS_GETVERS: /* get version number */ - *(int*)data = 0x100; /* version 1.0 */ + *(int*)data = 0x103; /* version 1.3 */ return 0; case CONS_GETINFO: /* get current (virtual) console info */ if (*data == sizeof(struct vid_info)) { vid_info_t *ptr = (vid_info_t*)data; - ptr->m_num = get_scr_num(scp); - ptr->mv_col = scp->posx; - ptr->mv_row = scp->posy; - ptr->mv_csz = scp->max_posx; - ptr->mv_rsz = scp->max_posy; + ptr->m_num = get_scr_num(); + ptr->mv_col = scp->xpos; + ptr->mv_row = scp->ypos; + ptr->mv_csz = scp->xsize; + ptr->mv_rsz = scp->ysize; ptr->mv_norm.fore = (scp->term.std_attr & 0x0f00)>>8; ptr->mv_norm.back = (scp->term.std_attr & 0xf000)>>12; ptr->mv_rev.fore = (scp->term.rev_attr & 0x0f00)>>8; @@ -614,17 +706,14 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) /* NOT REACHED */ case VT_OPENQRY: /* return free virtual console */ - for (i = 0; i < NCONS; i++) - if (!(pccons[i].t_state & TS_ISOPEN)) { + for (i = 0; i < NCONS; i++) { + tp = VIRTUAL_TTY(i); + if (!(tp->t_state & TS_ISOPEN)) { *data = i + 1; return 0; } + } return EINVAL; - /* NOT REACHED */ - - case VT_GETACTIVE: /* return number of active virtual console */ - *data = get_scr_num(scp) + 1; - return 0; case VT_ACTIVATE: /* switch to screen *data */ return switch_scr((*data) - 1); @@ -635,26 +724,29 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (minor(dev) == (*data) - 1) return 0; if (*data == 0) { - if (scp == cur_scr_stat) + if (scp == cur_console) return 0; - while ((error=tsleep(&scp->smode, - PZERO|PCATCH, "waitvt", 0)) - == ERESTART) ; + while ((error=tsleep((caddr_t)&scp->smode, + PZERO|PCATCH, "waitvt", 0)) == ERESTART) ; } else - while ((error=tsleep(&cons_scr_stat[*data].smode, - PZERO|PCATCH, "waitvt", 0)) - == ERESTART) ; + while ((error=tsleep( + (caddr_t)&console[*(data-1)].smode, + PZERO|PCATCH, "waitvt", 0)) == ERESTART) ; return error; + case VT_GETACTIVE: + *data = get_scr_num()+1; + return 0; + case KDENABIO: /* allow io operations */ - fp = (struct syscframe *)p->p_regs; - fp->sf_eflags |= PSL_IOPL; + fp = (frametype *)p->p_regs; + fp->eflags |= PSL_IOPL; return 0; case KDDISABIO: /* disallow io operations (default) */ - fp = (struct syscframe *)p->p_regs; - fp->sf_eflags &= ~PSL_IOPL; + fp = (frametype *)p->p_regs; + fp->eflags &= ~PSL_IOPL; return 0; case KDSETMODE: /* set current mode of this (virtual) console */ @@ -692,7 +784,7 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (!crtc_vga) return ENXIO; scp->border = *data; - if (scp == cur_scr_stat) + if (scp == cur_console) set_border(scp->border); return 0; @@ -700,7 +792,7 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (*data >= 0 && *data <= LOCK_KEY_MASK) { scp->status &= ~LOCK_KEY_MASK; scp->status |= *data; - if (scp == cur_scr_stat) + if (scp == cur_console) update_leds(scp->status & LED_MASK); return 0; } @@ -711,12 +803,10 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; case KDSETRAD: /* set keyboard repeat & delay rates */ - if (*(u_char*)data < 0x80) { - kbd_cmd(KB_SETRAD); - kbd_cmd(*data & 0x7f); - return 0; - } - return EINVAL; + if (*data & 0x80) + return EINVAL; + kbd_cmd2(KB_SETRAD, *data); + return 0; case KDSKBMODE: /* set keyboard mode */ switch (*data) { @@ -725,6 +815,8 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; case K_XLATE: /* switch to XLT ascii mode */ + if (scp == cur_console && scp->status == KBD_RAW_MODE) + shfts = ctls = alts = agrs = metas = 0; scp->status &= ~KBD_RAW_MODE; return 0; default: @@ -737,21 +829,22 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; case KDMKTONE: /* sound the bell */ - if (scp == cur_scr_stat) + if (scp == cur_console) sysbeep(scp->bell_pitch, scp->bell_duration); return 0; case KIOCSOUND: /* make tone (*data) hz */ - if (scp == cur_scr_stat) { + if (scp == cur_console) { if (*(int*)data) { - int pitch = XTALSPEED/(*(int*)data); + int pitch = TIMER_FREQ/(*(int*)data); /* enable counter 2 */ outb(0x61, inb(0x61) | 3); /* set command for counter 2, 2 byte write */ - outb(0x43, 0xb6); + outb(TIMER_MODE, + TIMER_SEL2|TIMER_16BIT|TIMER_SQWAVE); /* set pitch */ - outb(0x42, pitch); - outb(0x42, (pitch>>8)); + outb(TIMER_CNTR2, pitch); + outb(TIMER_CNTR2, (pitch>>8)); } else { /* disable counter 2 */ @@ -768,7 +861,7 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (*data >= 0 && *data <= LED_MASK) { scp->status &= ~LED_MASK; scp->status |= *data; - if (scp == cur_scr_stat) + if (scp == cur_console) update_leds(scp->status & LED_MASK); return 0; } @@ -859,10 +952,10 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) case CONSOLE_X_MODE_ON: /* just to be compatible */ if (saved_console < 0) { - saved_console = get_scr_num(cur_scr_stat); + saved_console = get_scr_num(); switch_scr(minor(dev)); - fp = (struct syscframe *)p->p_regs; - fp->sf_eflags |= PSL_IOPL; + fp = (frametype *)p->p_regs; + fp->eflags |= PSL_IOPL; scp->status |= UNKNOWN_MODE; scp->status |= KBD_RAW_MODE; return 0; @@ -870,8 +963,8 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return EAGAIN; case CONSOLE_X_MODE_OFF:/* just to be compatible */ - fp = (struct syscframe *)p->p_regs; - fp->sf_eflags &= ~PSL_IOPL; + fp = (frametype *)p->p_regs; + fp->eflags &= ~PSL_IOPL; if (crtc_vga) { load_font(0, 16, font_8x16); load_font(1, 8, font_8x8); @@ -893,9 +986,10 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) * is the duration in msec. */ if (data) - sysbeep(XTALSPEED/((int*)data)[0], ((int*)data)[1]*hz/3000); + sysbeep(TIMER_FREQ/((int*)data)[0], + ((int*)data)[1]*hz/3000); else - sysbeep(0x31b, hz/4); + sysbeep(scp->bell_pitch, scp->bell_duration); return 0; default: @@ -912,25 +1006,64 @@ pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) } -pcxint(dev_t dev) +void pcxint(dev_t dev) { - pccons[minor(dev)].t_state &= ~TS_BUSY; - pcconsoftc.cs_timo = 0; - if (pccons[minor(dev)].t_line) - (*linesw[pccons[minor(dev)].t_line].l_start) - (&pccons[minor(dev)]); + struct tty *tp = get_tty_ptr(dev); + + if (!tp) + return; + tp->t_state &= ~TS_BUSY; + if (tp->t_line) + (*linesw[tp->t_line].l_start)(tp); else - pcstart(&pccons[minor(dev)]); + pcstart(tp); } -pcstart(struct tty *tp) +void pcstart(struct tty *tp) { - int c, s; +#if defined(NetBSD) + struct clist *rbp; + int i, s, len; + u_char buf[PCBURST]; + scr_stat *scp = get_scr_stat(tp->t_dev); + + if (scp->status & SLKED) + return; + s = spltty(); + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) { + tp->t_state |= TS_BUSY; + splx(s); + rbp = &tp->t_outq; + len = q_to_b(rbp, buf, PCBURST); + for (i=0; i<len; i++) + if (buf[i]) ansi_put(scp, buf[i]); + s = spltty(); + tp->t_state &= ~TS_BUSY; + if (rbp->c_cc) { + tp->t_state |= TS_TIMEOUT; + timeout((timeout_t)ttrstrt, (caddr_t)tp, 1); + } + if (rbp->c_cc <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)rbp); + } + selwakeup(&tp->t_wsel); + } + } + splx(s); + +#else /* __FreeBSD__ & __386BSD__ */ + + int c, s, len, i; scr_stat *scp = get_scr_stat(tp->t_dev); + u_char buf[PCBURST]; + if (scp->status & SLKED) + return; s = spltty(); - if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) { for (;;) { if (RB_LEN(&tp->t_out) <= tp->t_lowat) { if (tp->t_state & TS_ASLEEP) { @@ -948,77 +1081,125 @@ pcstart(struct tty *tp) break; if (scp->status & SLKED) break; - c = getc(&tp->t_out); + len = 0; + while( len < PCBURST) { + c = getc(&tp->t_out); + if (c == -1) + break; + buf[len++] = c; + } tp->t_state |= TS_BUSY; splx(s); - ansi_put(scp, c); + for(i=0;i<len;i++) + ansi_put(scp, buf[i]); s = spltty(); tp->t_state &= ~TS_BUSY; } + tp->t_state |= TS_BUSY; + if( in_putc == 0) { + int i; + for(i=0;i<console_buffer_count;i++) { + scput(console_buffer[i]); + } + console_buffer_count = 0; + } + tp->t_state &= ~TS_BUSY; + } splx(s); +#endif } -pccnprobe(struct consdev *cp) +void pccnprobe(struct consdev *cp) { int maj; /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) - if (cdevsw[maj].d_open == pcopen) + if ((void*)cdevsw[maj].d_open == (void*)pcopen) break; /* initialize required fields */ - cp->cn_dev = makedev(maj, 0); - cp->cn_tp = &pccons[0]; + cp->cn_dev = makedev(maj, NCONS); cp->cn_pri = CN_INTERNAL; +#if defined(__FreeBSD__) || defined(__386BSD__) + cp->cn_tp = CONSOLE_TTY; +#endif } -pccninit(struct consdev *cp) +void pccninit(struct consdev *cp) { + scinit(); } -pccnputc(dev_t dev, char c) +void pccnputc(dev_t dev, char c) { - int pos; - - if (cur_scr_stat->status & UNKNOWN_MODE) - return; if (c == '\n') - sput('\r'); - sput(c); - pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; - if (pos != cur_cursor_pos) { - cur_cursor_pos = pos; - outb(crtc_addr,14); - outb(crtc_addr+1,pos >> 8); - outb(crtc_addr,15); - outb(crtc_addr+1,pos&0xff); + scput('\r'); + scput(c); + if (cur_console == &console[0]) { + int pos = cur_console->crtat - cur_console->crt_base; + if (pos != cur_cursor_pos) { + cur_cursor_pos = pos; + outb(crtc_addr,14); + outb(crtc_addr+1,pos >> 8); + outb(crtc_addr,15); + outb(crtc_addr+1,pos&0xff); + } } } -pccngetc(dev_t dev) +int pccngetc(dev_t dev) { - int c, s; - - s = spltty(); /* block scintr while we poll */ - c = sgetc(0); + int s = spltty(); /* block scintr while we poll */ + int c = scgetc(0); splx(s); if (c == '\r') c = '\n'; return(c); } -#if !defined(STAR_SAVER) && !defined(SNAKE_SAVER) +static void none_saver(int test) +{ +} -void scrn_saver(int test) +static void fade_saver(int test) { - u_char val; + static int count = 0; + int i; if (test) { scrn_blanked = 1; + if (count < 64) { + outb(PIXMASK, 0xFF); /* no pixelmask */ + outb(PALWADR, 0x00); + outb(PALDATA, 0); + outb(PALDATA, 0); + outb(PALDATA, 0); + for (i = 3; i < 768; i++) { + if (palette[i] - count > 15) + outb(PALDATA, palette[i]-count); + else + outb(PALDATA, 15); + } + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x20); /* enable palette */ + count++; + } + } + else { + count = scrn_blanked = 0; + load_palette(); + } +} + +static void blank_saver(int test) +{ + u_char val; + if (test) { + scrn_blanked = 1; outb(TSIDX, 0x01); val = inb(TSREG); outb(TSIDX, 0x01); outb(TSREG, val | 0x20); } @@ -1028,17 +1209,14 @@ void scrn_saver(int test) outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); } } -#endif -#if defined(STAR_SAVER) || defined(SNAKE_SAVER) static u_long rand_next = 1; -static rand() +static int rand() { return ((rand_next = rand_next * 1103515245 + 12345) & 0x7FFFFFFF); } -#endif -#ifdef STAR_SAVER + /* * Alternate saver that got its inspiration from a well known utility * package for an unfamous OS. @@ -1046,9 +1224,9 @@ static rand() #define NUM_STARS 50 -void scrn_saver(int test) +static void star_saver(int test) { - scr_stat *scp = cur_scr_stat; + scr_stat *scp = cur_console; int cell, i; char pattern[] = {"...........++++*** "}; char colors[] = {FG_DARKGREY, FG_LIGHTGREY, @@ -1057,12 +1235,12 @@ void scrn_saver(int test) if (test) { if (!scrn_blanked) { - bcopy(Crtat, scp->scr, - scp->max_posx * scp->max_posy * 2); + bcopy(Crtat, scp->scr_buf, + scp->xsize * scp->ysize * 2); fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], Crtat, - scp->max_posx * scp->max_posy); + scp->xsize * scp->ysize); set_border(0); - i = scp->max_posy * scp->max_posx + 5; + i = scp->ysize * scp->xsize + 5; outb(crtc_addr, 14); outb(crtc_addr+1, i >> 8); outb(crtc_addr, 15); @@ -1070,7 +1248,7 @@ void scrn_saver(int test) scrn_blanked = 1; for(i=0; i<NUM_STARS; i++) { stars[i][0] = - rand() % (scp->max_posx*scp->max_posy); + rand() % (scp->xsize*scp->ysize); stars[i][1] = 0; } } @@ -1079,48 +1257,44 @@ void scrn_saver(int test) scr_map[pattern[stars[cell][1]]] | colors[rand()%sizeof(colors)] << 8; if ((stars[cell][1]+=(rand()%4)) >= sizeof(pattern)-1) { - stars[cell][0] = rand() % (scp->max_posx*scp->max_posy); + stars[cell][0] = rand() % (scp->xsize*scp->ysize); stars[cell][1] = 0; } } else { if (scrn_blanked) { - bcopy(scp->scr, Crtat, scp->max_posx*scp->max_posy*2); + bcopy(scp->scr_buf, Crtat, scp->xsize*scp->ysize*2); cur_cursor_pos = -1; set_border(scp->border); scrn_blanked = 0; } } } -#endif -#ifdef SNAKE_SAVER -/* - * alternative screen saver for cards that do not like blanking - */ -void scrn_saver(int test) + +static void snake_saver(int test) { const char saves[] = {"FreeBSD"}; static u_char *savs[sizeof(saves)-1]; static int dirx, diry; int f; - scr_stat *scp = cur_scr_stat; + scr_stat *scp = cur_console; if (test) { if (!scrn_blanked) { - bcopy(Crtat, scp->scr, - scp->max_posx * scp->max_posy * 2); - fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], Crtat, - scp->max_posx * scp->max_posy); + bcopy(Crtat, scp->scr_buf, + scp->xsize * scp->ysize * 2); + fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], + Crtat, scp->xsize * scp->ysize); set_border(0); - dirx = (scp->posx ? 1 : -1); - diry = (scp->posy ? - scp->max_posx : -scp->max_posx); + dirx = (scp->xpos ? 1 : -1); + diry = (scp->ypos ? + scp->xsize : -scp->xsize); for (f=0; f< sizeof(saves)-1; f++) savs[f] = (u_char *)Crtat + 2 * - (scp->posx+scp->posy*scp->max_posx); + (scp->xpos+scp->ypos*scp->xsize); *(savs[0]) = scr_map[*saves]; - f = scp->max_posy * scp->max_posx + 5; + f = scp->ysize * scp->xsize + 5; outb(crtc_addr, 14); outb(crtc_addr+1, f >> 8); outb(crtc_addr, 15); @@ -1134,12 +1308,12 @@ void scrn_saver(int test) for (f=sizeof(saves)-2; f > 0; f--) savs[f] = savs[f-1]; f = (savs[0] - (u_char *)Crtat) / 2; - if ((f % scp->max_posx) == 0 || - (f % scp->max_posx) == scp->max_posx - 1 || + if ((f % scp->xsize) == 0 || + (f % scp->xsize) == scp->xsize - 1 || (rand() % 50) == 0) dirx = -dirx; - if ((f / scp->max_posx) == 0 || - (f / scp->max_posx) == scp->max_posy - 1 || + if ((f / scp->xsize) == 0 || + (f / scp->xsize) == scp->ysize - 1 || (rand() % 20) == 0) diry = -diry; savs[0] += 2*dirx + 2*diry; @@ -1148,15 +1322,14 @@ void scrn_saver(int test) } else { if (scrn_blanked) { - bcopy(scp->scr, Crtat, - scp->max_posx * scp->max_posy * 2); + bcopy(scp->scr_buf, Crtat, + scp->xsize * scp->ysize * 2); cur_cursor_pos = -1; set_border(scp->border); scrn_blanked = 0; } } } -#endif static void cursor_shape(int start, int end) { @@ -1167,6 +1340,7 @@ static void cursor_shape(int start, int end) } +#if !defined(FAT_CURSOR) static void get_cursor_shape(int *start, int *end) { outb(crtc_addr, 10); @@ -1174,58 +1348,69 @@ static void get_cursor_shape(int *start, int *end) outb(crtc_addr, 11); *end = inb(crtc_addr+1) & 0x1F; } +#endif -static void cursor_pos(void) +static void cursor_pos(int force) { int pos; - if (cur_scr_stat->status & UNKNOWN_MODE) + if (cur_console->status & UNKNOWN_MODE) return; if (scrn_blank_time && (time.tv_sec > scrn_time_stamp+scrn_blank_time)) - scrn_saver(1); - pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; - if (!scrn_blanked && pos != cur_cursor_pos) { + SCRN_SAVER(1); + pos = cur_console->crtat - cur_console->crt_base; + if (force || (!scrn_blanked && pos != cur_cursor_pos)) { cur_cursor_pos = pos; outb(crtc_addr, 14); outb(crtc_addr+1, pos>>8); outb(crtc_addr, 15); outb(crtc_addr+1, pos&0xff); } - timeout(cursor_pos, 0, hz/20); + timeout((timeout_t)cursor_pos, 0, hz/20); } static void clear_screen(scr_stat *scp) { move_crsr(scp, 0, 0); - fillw(scp->term.attr | scr_map[0x20], scp->crt_base, - scp->max_posx * scp->max_posy); + fillw(scp->term.cur_attr | scr_map[0x20], scp->crt_base, + scp->xsize * scp->ysize); } -static switch_scr(u_int next_scr) +static int switch_scr(u_int next_scr) { - if (in_putc) { /* don't switch if in putc */ - nx_scr = next_scr+1; + if (in_putc) { /* delay switch if in putc */ + delayed_next_scr = next_scr+1; return 0; } if (switch_in_progress && - (cur_scr_stat->proc != pfind(cur_scr_stat->pid))) + (cur_console->proc != pfind(cur_console->pid))) switch_in_progress = 0; - if (next_scr >= NCONS || switch_in_progress) { - sysbeep(800, hz/4); - return -1; + + if (next_scr >= NCONS || switch_in_progress) { + sysbeep(BELL_PITCH, BELL_DURATION); + return EINVAL; + } + + /* is the wanted virtual console open ? */ + if (next_scr) { + struct tty *tp = VIRTUAL_TTY(next_scr); + if (!(tp->t_state & TS_ISOPEN)) { + sysbeep(BELL_PITCH, BELL_DURATION); + return EINVAL; + } } + switch_in_progress = 1; - old_scp = cur_scr_stat; - new_scp = &cons_scr_stat[next_scr]; - wakeup(&new_scp->smode); + old_scp = cur_console; + new_scp = &console[next_scr]; + wakeup((caddr_t)&new_scp->smode); if (new_scp == old_scp) { switch_in_progress = 0; return 0; } - new_pccons = &pccons[next_scr]; /* has controlling process died? */ if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid))) @@ -1253,32 +1438,32 @@ static switch_scr(u_int next_scr) static void exchange_scr(void) { - bcopy(Crtat, old_scp->scr, old_scp->max_posx * old_scp->max_posy * 2); - old_scp->crt_base = old_scp->scr; - move_crsr(old_scp, old_scp->posx, old_scp->posy); - cur_scr_stat = new_scp; - cur_pccons = new_pccons; - if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE) - shfts = ctls = alts = 0; - update_leds(new_scp->status & LED_MASK); + struct tty *tp; + + bcopy(Crtat, old_scp->scr_buf, old_scp->xsize * old_scp->ysize * 2); + old_scp->crt_base = old_scp->scr_buf; + move_crsr(old_scp, old_scp->xpos, old_scp->ypos); + cur_console = new_scp; set_mode(new_scp); new_scp->crt_base = Crtat; - move_crsr(new_scp, new_scp->posx, new_scp->posy); - bcopy(new_scp->scr, Crtat, new_scp->max_posx * new_scp->max_posy * 2); - nx_scr = 0; + move_crsr(new_scp, new_scp->xpos, new_scp->ypos); + bcopy(new_scp->scr_buf, Crtat, new_scp->xsize * new_scp->ysize * 2); + update_leds(new_scp->status & LED_MASK); + if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE) + shfts = ctls = alts = agrs = metas = 0; + delayed_next_scr = 0; } static void move_crsr(scr_stat *scp, int x, int y) { - if (x < 0 || y < 0 || x >= scp->max_posx || y >= scp->max_posy) + if (x < 0 || y < 0 || x >= scp->xsize || y >= scp->ysize) return; - scp->posx = x; - scp->posy = y; - scp->crtat = scp->crt_base + scp->posy * scp->max_posx + scp->posx; + scp->xpos = x; + scp->ypos = y; + scp->crtat = scp->crt_base + scp->ypos * scp->xsize + scp->xpos; } - static void move_up(u_short *s, u_short *d, u_int len) { s += len; @@ -1287,14 +1472,12 @@ static void move_up(u_short *s, u_short *d, u_int len) *--d = *--s; } - static void move_down(u_short *s, u_short *d, u_int len) { while (len-- > 0) *d++ = *s++; } - static void scan_esc(scr_stat *scp, u_char c) { static u_char ansi_col[16] = @@ -1307,21 +1490,21 @@ static void scan_esc(scr_stat *scp, u_char c) case '[': /* Start ESC [ sequence */ scp->term.esc = 2; - scp->term.last_par = -1; - for (i = scp->term.n_par; i < MAX_ESC_PAR; i++) - scp->term.par[i] = 1; - scp->term.n_par = 0; + scp->term.last_param = -1; + for (i = scp->term.num_param; i < MAX_ESC_PAR; i++) + scp->term.param[i] = 1; + scp->term.num_param = 0; return; case 'M': /* Move cursor up 1 line, scroll if at top */ - if (scp->posy > 0) - move_crsr(scp, scp->posx, scp->posy - 1); + if (scp->ypos > 0) + move_crsr(scp, scp->xpos, scp->ypos - 1); else { move_up(scp->crt_base, - scp->crt_base + scp->max_posx, - (scp->max_posy - 1) * scp->max_posx); - fillw(scp->term.attr | scr_map[0x20], - scp->crt_base, scp->max_posx); + scp->crt_base + scp->xsize, + (scp->ysize - 1) * scp->xsize); + fillw(scp->term.cur_attr | scr_map[0x20], + scp->crt_base, scp->xsize); } break; #if notyet @@ -1336,86 +1519,86 @@ static void scan_esc(scr_stat *scp, u_char c) } else if (scp->term.esc == 2) { if (c >= '0' && c <= '9') { - if (scp->term.n_par < MAX_ESC_PAR) { - if (scp->term.last_par != scp->term.n_par) { - scp->term.last_par = scp->term.n_par; - scp->term.par[scp->term.n_par] = 0; + if (scp->term.num_param < MAX_ESC_PAR) { + if (scp->term.last_param != scp->term.num_param) { + scp->term.last_param = scp->term.num_param; + scp->term.param[scp->term.num_param] = 0; } else - scp->term.par[scp->term.n_par] *= 10; - scp->term.par[scp->term.n_par] += c - '0'; + scp->term.param[scp->term.num_param] *= 10; + scp->term.param[scp->term.num_param] += c - '0'; return; } } - scp->term.n_par = scp->term.last_par + 1; + scp->term.num_param = scp->term.last_param + 1; switch (c) { case ';': - if (scp->term.n_par < MAX_ESC_PAR) + if (scp->term.num_param < MAX_ESC_PAR) return; break; case '=': scp->term.esc = 3; - scp->term.last_par = -1; - for (i = scp->term.n_par; i < MAX_ESC_PAR; i++) - scp->term.par[i] = 1; - scp->term.n_par = 0; + scp->term.last_param = -1; + for (i = scp->term.num_param; i < MAX_ESC_PAR; i++) + scp->term.param[i] = 1; + scp->term.num_param = 0; return; case 'A': /* up n rows */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, scp->posx, scp->posy - n); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, scp->xpos, scp->ypos - n); break; case 'B': /* down n rows */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, scp->posx, scp->posy + n); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, scp->xpos, scp->ypos + n); break; case 'C': /* right n columns */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, scp->posx + n, scp->posy); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, scp->xpos + n, scp->ypos); break; case 'D': /* left n columns */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, scp->posx - n, scp->posy); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, scp->xpos - n, scp->ypos); break; case 'E': /* cursor to start of line n lines down */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, 0, scp->posy + n); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->ypos + n); break; case 'F': /* cursor to start of line n lines up */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, 0, scp->posy - n); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->ypos - n); break; case 'f': /* System V consoles .. */ case 'H': /* Cursor move */ - if (scp->term.n_par == 0) + if (scp->term.num_param == 0) move_crsr(scp, 0, 0); - else if (scp->term.n_par == 2) - move_crsr(scp, scp->term.par[1] - 1, - scp->term.par[0] - 1); + else if (scp->term.num_param == 2) + move_crsr(scp, scp->term.param[1] - 1, + scp->term.param[0] - 1); break; case 'J': /* Clear all or part of display */ - if (scp->term.n_par == 0) + if (scp->term.num_param == 0) n = 0; else - n = scp->term.par[0]; + n = scp->term.param[0]; switch (n) { case 0: /* clear form cursor to end of display */ - fillw(scp->term.attr | scr_map[0x20], + fillw(scp->term.cur_attr | scr_map[0x20], scp->crtat, scp->crt_base + - scp->max_posx * scp->max_posy - + scp->xsize * scp->ysize - scp->crtat); break; case 1: /* clear from beginning of display to cursor */ - fillw(scp->term.attr | scr_map[0x20], + fillw(scp->term.cur_attr | scr_map[0x20], scp->crt_base, scp->crtat - scp->crt_base); break; @@ -1426,291 +1609,297 @@ static void scan_esc(scr_stat *scp, u_char c) break; case 'K': /* Clear all or part of line */ - if (scp->term.n_par == 0) + if (scp->term.num_param == 0) n = 0; else - n = scp->term.par[0]; + n = scp->term.param[0]; switch (n) { case 0: /* clear form cursor to end of line */ - fillw(scp->term.attr | scr_map[0x20], - scp->crtat, scp->max_posx - scp->posx); + fillw(scp->term.cur_attr | scr_map[0x20], + scp->crtat, scp->xsize - scp->xpos); break; case 1: /* clear from beginning of line to cursor */ - fillw(scp->term.attr|scr_map[0x20], - scp->crtat - (scp->max_posx - scp->posx), - (scp->max_posx - scp->posx) + 1); + fillw(scp->term.cur_attr|scr_map[0x20], + scp->crtat - (scp->xsize - scp->xpos), + (scp->xsize - scp->xpos) + 1); break; case 2: /* clear entire line */ - fillw(scp->term.attr|scr_map[0x20], - scp->crtat - (scp->max_posx - scp->posx), - scp->max_posx); + fillw(scp->term.cur_attr|scr_map[0x20], + scp->crtat - (scp->xsize - scp->xpos), + scp->xsize); break; } break; case 'L': /* Insert n lines */ - n = scp->term.par[0]; if (n < 1) n = 1; - if (n > scp->max_posy - scp->posy) - n = scp->max_posy - scp->posy; - src = scp->crt_base + scp->posy * scp->max_posx; - dst = src + n * scp->max_posx; - count = scp->max_posy - (scp->posy + n); - move_up(src, dst, count * scp->max_posx); - fillw(scp->term.attr | scr_map[0x20], src, - n * scp->max_posx); + n = scp->term.param[0]; if (n < 1) n = 1; + if (n > scp->ysize - scp->ypos) + n = scp->ysize - scp->ypos; + src = scp->crt_base + scp->ypos * scp->xsize; + dst = src + n * scp->xsize; + count = scp->ysize - (scp->ypos + n); + move_up(src, dst, count * scp->xsize); + fillw(scp->term.cur_attr | scr_map[0x20], src, + n * scp->xsize); break; case 'M': /* Delete n lines */ - n = scp->term.par[0]; if (n < 1) n = 1; - if (n > scp->max_posy - scp->posy) - n = scp->max_posy - scp->posy; - dst = scp->crt_base + scp->posy * scp->max_posx; - src = dst + n * scp->max_posx; - count = scp->max_posy - (scp->posy + n); - move_down(src, dst, count * scp->max_posx); - src = dst + count * scp->max_posx; - fillw(scp->term.attr | scr_map[0x20], src, - n * scp->max_posx); + n = scp->term.param[0]; if (n < 1) n = 1; + if (n > scp->ysize - scp->ypos) + n = scp->ysize - scp->ypos; + dst = scp->crt_base + scp->ypos * scp->xsize; + src = dst + n * scp->xsize; + count = scp->ysize - (scp->ypos + n); + move_down(src, dst, count * scp->xsize); + src = dst + count * scp->xsize; + fillw(scp->term.cur_attr | scr_map[0x20], src, + n * scp->xsize); break; case 'P': /* Delete n chars */ - n = scp->term.par[0]; if (n < 1) n = 1; - if (n > scp->max_posx - scp->posx) - n = scp->max_posx - scp->posx; + n = scp->term.param[0]; if (n < 1) n = 1; + if (n > scp->xsize - scp->xpos) + n = scp->xsize - scp->xpos; dst = scp->crtat; src = dst + n; - count = scp->max_posx - (scp->posx + n); + count = scp->xsize - (scp->xpos + n); move_down(src, dst, count); src = dst + count; - fillw(scp->term.attr | scr_map[0x20], src, n); + fillw(scp->term.cur_attr | scr_map[0x20], src, n); break; case '@': /* Insert n chars */ - n = scp->term.par[0]; if (n < 1) n = 1; - if (n > scp->max_posx - scp->posx) - n = scp->max_posx - scp->posx; + n = scp->term.param[0]; if (n < 1) n = 1; + if (n > scp->xsize - scp->xpos) + n = scp->xsize - scp->xpos; src = scp->crtat; dst = src + n; - count = scp->max_posx - (scp->posx + n); + count = scp->xsize - (scp->xpos + n); move_up(src, dst, count); - fillw(scp->term.attr | scr_map[0x20], src, n); + fillw(scp->term.cur_attr | scr_map[0x20], src, n); break; case 'S': /* scroll up n lines */ - n = scp->term.par[0]; if (n < 1) n = 1; - bcopy(scp->crt_base + (scp->max_posx * n), + n = scp->term.param[0]; if (n < 1) n = 1; + if (n > scp->ypos) + n = scp->ypos; + bcopy(scp->crt_base + (scp->xsize * n), scp->crt_base, - scp->max_posx * (scp->max_posy - n) * + scp->xsize * (scp->ysize - n) * sizeof(u_short)); - fillw(scp->term.attr | scr_map[0x20], - scp->crt_base + scp->max_posx * - (scp->max_posy - 1), - scp->max_posx); + fillw(scp->term.cur_attr | scr_map[0x20], + scp->crt_base + scp->xsize * + (scp->ysize - 1), + scp->xsize); break; case 'T': /* scroll down n lines */ - n = scp->term.par[0]; if (n < 1) n = 1; + n = scp->term.param[0]; if (n < 1) n = 1; + if (n > scp->ysize - scp->ypos) + n = scp->ysize - scp->ypos; bcopy(scp->crt_base, - scp->crt_base + (scp->max_posx * n), - scp->max_posx * (scp->max_posy - n) * + scp->crt_base + (scp->xsize * n), + scp->xsize * (scp->ysize - n) * sizeof(u_short)); - fillw(scp->term.attr | scr_map[0x20], scp->crt_base, - scp->max_posx); + fillw(scp->term.cur_attr | scr_map[0x20], + scp->crt_base, scp->xsize); break; case 'X': /* delete n characters in line */ - n = scp->term.par[0]; if (n < 1) n = 1; - fillw(scp->term.attr | scr_map[0x20], - scp->crt_base + scp->posx + - ((scp->max_posx*scp->posy) * sizeof(u_short)), n); + n = scp->term.param[0]; if (n < 1) n = 1; + if (n > scp->xsize - scp->xpos) + n = scp->xsize - scp->xpos; + fillw(scp->term.cur_attr | scr_map[0x20], + scp->crt_base + scp->xpos + + ((scp->xsize*scp->ypos) * sizeof(u_short)), n); break; case 'Z': /* move n tabs backwards */ - n = scp->term.par[0]; if (n < 1) n = 1; - if ((i = scp->posx & 0xf8) == scp->posx) + n = scp->term.param[0]; if (n < 1) n = 1; + if ((i = scp->xpos & 0xf8) == scp->xpos) i -= 8*n; else i -= 8*(n-1); if (i < 0) i = 0; - move_crsr(scp, i, scp->posy); + move_crsr(scp, i, scp->ypos); break; case '`': /* move cursor to column n */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, n, scp->posy); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, n, scp->ypos); break; case 'a': /* move cursor n columns to the right */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, scp->posx + n, scp->posy); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, scp->xpos + n, scp->ypos); break; case 'd': /* move cursor to row n */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, scp->posx, n); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, scp->xpos, n); break; case 'e': /* move cursor n rows down */ - n = scp->term.par[0]; if (n < 1) n = 1; - move_crsr(scp, scp->posx, scp->posy + n); + n = scp->term.param[0]; if (n < 1) n = 1; + move_crsr(scp, scp->xpos, scp->ypos + n); break; case 'm': /* change attribute */ - if (scp->term.n_par == 0) + if (scp->term.num_param == 0) n = 0; else - n = scp->term.par[0]; + n = scp->term.param[0]; switch (n) { case 0: /* back to normal */ - scp->term.attr = scp->term.std_attr; + scp->term.cur_attr = scp->term.std_attr; break; case 1: /* highlight (bold) */ - scp->term.attr &= 0xFF00; - scp->term.attr |= 0x0800; + scp->term.cur_attr &= 0xFF00; + scp->term.cur_attr |= 0x0800; break; case 4: /* highlight (underline) */ - scp->term.attr &= 0x0F00; - scp->term.attr |= 0x0800; + scp->term.cur_attr &= 0x0F00; + scp->term.cur_attr |= 0x0800; break; case 5: /* blink */ - scp->term.attr &= 0xFF00; - scp->term.attr |= 0x8000; + scp->term.cur_attr &= 0xFF00; + scp->term.cur_attr |= 0x8000; break; case 7: /* reverse video */ - scp->term.attr = scp->term.rev_attr; + scp->term.cur_attr = scp->term.rev_attr; break; case 30: case 31: case 32: case 33: /* set fg color */ case 34: case 35: case 36: case 37: - scp->term.attr = (scp->term.attr & 0xF0FF) + scp->term.cur_attr = (scp->term.cur_attr & 0xF0FF) | (ansi_col[(n - 30) & 7] << 8); break; case 40: case 41: case 42: case 43: /* set bg color */ case 44: case 45: case 46: case 47: - scp->term.attr = (scp->term.attr & 0x0FFF) + scp->term.cur_attr = (scp->term.cur_attr & 0x0FFF) | (ansi_col[(n - 40) & 7] << 12); break; } break; case 'x': - if (scp->term.n_par == 0) + if (scp->term.num_param == 0) n = 0; else - n = scp->term.par[0]; + n = scp->term.param[0]; switch (n) { case 0: /* reset attributes */ - scp->term.attr = scp->term.std_attr = + scp->term.cur_attr = scp->term.std_attr = current_default->std_attr; scp->term.rev_attr = current_default->rev_attr; break; case 1: /* set ansi background */ - scp->term.attr = scp->term.std_attr = + scp->term.cur_attr = scp->term.std_attr = (scp->term.std_attr & 0x0F00) | - (ansi_col[(scp->term.par[1])&0x0F]<<12); + (ansi_col[(scp->term.param[1])&0x0F]<<12); break; case 2: /* set ansi foreground */ - scp->term.attr = scp->term.std_attr = + scp->term.cur_attr = scp->term.std_attr = (scp->term.std_attr & 0xF000) | - (ansi_col[(scp->term.par[1])&0x0F]<<8); + (ansi_col[(scp->term.param[1])&0x0F]<<8); break; case 3: /* set ansi attribute directly */ - scp->term.attr = scp->term.std_attr = - (scp->term.par[1]&0xFF)<<8; + scp->term.cur_attr = scp->term.std_attr = + (scp->term.param[1]&0xFF)<<8; break; case 5: /* set ansi reverse video background */ scp->term.rev_attr = (scp->term.rev_attr & 0x0F00) | - (ansi_col[(scp->term.par[1])&0x0F]<<12); + (ansi_col[(scp->term.param[1])&0x0F]<<12); break; case 6: /* set ansi reverse video foreground */ scp->term.rev_attr = (scp->term.rev_attr & 0xF000) | - (ansi_col[(scp->term.par[1])&0x0F]<<8); + (ansi_col[(scp->term.param[1])&0x0F]<<8); break; case 7: /* set ansi reverse video directly */ - scp->term.rev_attr = (scp->term.par[1]&0xFF)<<8; + scp->term.rev_attr = (scp->term.param[1]&0xFF)<<8; break; } break; case 'z': /* switch to (virtual) console n */ - if (scp->term.n_par == 1) - switch_scr(scp->term.par[0]); + if (scp->term.num_param == 1) + switch_scr(scp->term.param[0]); break; } } else if (scp->term.esc == 3) { if (c >= '0' && c <= '9') { - if (scp->term.n_par < MAX_ESC_PAR) { - if (scp->term.last_par != scp->term.n_par) { - scp->term.last_par = scp->term.n_par; - scp->term.par[scp->term.n_par] = 0; + if (scp->term.num_param < MAX_ESC_PAR) { + if (scp->term.last_param != scp->term.num_param) { + scp->term.last_param = scp->term.num_param; + scp->term.param[scp->term.num_param] = 0; } else - scp->term.par[scp->term.n_par] *= 10; - scp->term.par[scp->term.n_par] += c - '0'; + scp->term.param[scp->term.num_param] *= 10; + scp->term.param[scp->term.num_param] += c - '0'; return; } } - scp->term.n_par = scp->term.last_par + 1; + scp->term.num_param = scp->term.last_param + 1; switch (c) { case ';': - if (scp->term.n_par < MAX_ESC_PAR) + if (scp->term.num_param < MAX_ESC_PAR) return; break; case 'A': /* set display border color */ - if (scp->term.n_par == 1) - scp->border=scp->term.par[0] & 0xff; - if (scp == cur_scr_stat) + if (scp->term.num_param == 1) + scp->border=scp->term.param[0] & 0xff; + if (scp == cur_console) set_border(scp->border); break; case 'B': /* set bell pitch and duration */ - if (scp->term.n_par == 2) { - scp->bell_pitch = scp->term.par[0]; - scp->bell_duration = scp->term.par[1]*10; + if (scp->term.num_param == 2) { + scp->bell_pitch = scp->term.param[0]; + scp->bell_duration = scp->term.param[1]*10; } break; case 'C': /* set cursor shape (start & end line) */ - if (scp->term.n_par == 2) { - scp->cursor_start = scp->term.par[0] & 0x1F; - scp->cursor_end = scp->term.par[1] & 0x1F; - if (scp == cur_scr_stat) + if (scp->term.num_param == 2) { + scp->cursor_start = scp->term.param[0] & 0x1F; + scp->cursor_end = scp->term.param[1] & 0x1F; + if (scp == cur_console) cursor_shape(scp->cursor_start, scp->cursor_end); } break; case 'F': /* set ansi foreground */ - if (scp->term.n_par == 1) - scp->term.attr = scp->term.std_attr = + if (scp->term.num_param == 1) + scp->term.cur_attr = scp->term.std_attr = (scp->term.std_attr & 0xF000) - | ((scp->term.par[0] & 0x0F) << 8); + | ((scp->term.param[0] & 0x0F) << 8); break; case 'G': /* set ansi background */ - if (scp->term.n_par == 1) - scp->term.attr = scp->term.std_attr = + if (scp->term.num_param == 1) + scp->term.cur_attr = scp->term.std_attr = (scp->term.std_attr & 0x0F00) - | ((scp->term.par[0] & 0x0F) << 12); + | ((scp->term.param[0] & 0x0F) << 12); break; case 'H': /* set ansi reverse video foreground */ - if (scp->term.n_par == 1) + if (scp->term.num_param == 1) scp->term.rev_attr = (scp->term.rev_attr & 0xF000) - | ((scp->term.par[0] & 0x0F) << 8); + | ((scp->term.param[0] & 0x0F) << 8); break; case 'I': /* set ansi reverse video background */ - if (scp->term.n_par == 1) + if (scp->term.num_param == 1) scp->term.rev_attr = (scp->term.rev_attr & 0x0F00) - | ((scp->term.par[0] & 0x0F) << 12); + | ((scp->term.param[0] & 0x0F) << 12); break; } } @@ -1724,10 +1913,10 @@ static void ansi_put(scr_stat *scp, u_char c) return; /* make screensaver happy */ - if (scp == cur_scr_stat) { + if (scp == cur_console) { scrn_time_stamp = time.tv_sec; if (scrn_blanked) - scrn_saver(0); + SCRN_SAVER(0); } in_putc++; if (scp->term.esc) @@ -1735,70 +1924,69 @@ static void ansi_put(scr_stat *scp, u_char c) else switch(c) { case 0x1B: /* start escape sequence */ scp->term.esc = 1; - scp->term.n_par = 0; + scp->term.num_param = 0; break; case 0x07: - if (scp == cur_scr_stat) + if (scp == cur_console) sysbeep(scp->bell_pitch, scp->bell_duration); break; case '\t': /* non-destructive tab */ - scp->crtat += (8 - scp->posx % 8); - scp->posx += (8 - scp->posx % 8); + scp->crtat += (8 - scp->xpos % 8); + scp->xpos += (8 - scp->xpos % 8); break; case '\b': /* non-destructive backspace */ if (scp->crtat > scp->crt_base) { scp->crtat--; - if (scp->posx > 0) - scp->posx--; + if (scp->xpos > 0) + scp->xpos--; else { - scp->posx += scp->max_posx - 1; - scp->posy--; + scp->xpos += scp->xsize - 1; + scp->ypos--; } } break; case '\r': /* return to pos 0 */ - move_crsr(scp, 0, scp->posy); + move_crsr(scp, 0, scp->ypos); break; case '\n': /* newline, same pos */ - scp->crtat += scp->max_posx; - scp->posy++; + scp->crtat += scp->xsize; + scp->ypos++; break; case '\f': /* form feed, clears screen */ clear_screen(scp); break; default: /* Print only printables */ - *scp->crtat = (scp->term.attr | scr_map[c]); + *scp->crtat = (scp->term.cur_attr | scr_map[c]); scp->crtat++; - if (++scp->posx >= scp->max_posx) { - scp->posx = 0; - scp->posy++; + if (++scp->xpos >= scp->xsize) { + scp->xpos = 0; + scp->ypos++; } break; } - if (scp->crtat >= scp->crt_base + scp->max_posy * scp->max_posx) { - bcopy(scp->crt_base + scp->max_posx, scp->crt_base, - scp->max_posx * (scp->max_posy - 1) * sizeof(u_short)); - fillw(scp->term.attr | scr_map[0x20], - scp->crt_base + scp->max_posx * (scp->max_posy - 1), - scp->max_posx); - scp->crtat -= scp->max_posx; - scp->posy--; + if (scp->crtat >= scp->crt_base + scp->ysize * scp->xsize) { + bcopy(scp->crt_base + scp->xsize, scp->crt_base, + scp->xsize * (scp->ysize - 1) * sizeof(u_short)); + fillw(scp->term.cur_attr | scr_map[0x20], + scp->crt_base + scp->xsize * (scp->ysize - 1), + scp->xsize); + scp->crtat -= scp->xsize; + scp->ypos--; } in_putc--; - if (nx_scr) - switch_scr(nx_scr - 1); + if (delayed_next_scr) + switch_scr(delayed_next_scr - 1); } - -void consinit(void) +static void scinit(void) { u_short volatile *cp = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short), was; unsigned cursorat; int i; /* - * catch that once in a blue moon occurence when consinit is called + * catch that once in a blue moon occurence when scinit is called * TWICE, adding the CGA_BUF offset again -> poooff */ if (crtat != 0) @@ -1806,7 +1994,7 @@ void consinit(void) /* * Crtat initialized to point to MONO buffer, if not present change * to CGA_BUF offset. ONLY ADD the difference since locore.s adds - * in the remapped offset at the right time + * in the remapped offset at the "right" time */ was = *cp; *cp = (u_short) 0xA55A; @@ -1831,48 +2019,55 @@ void consinit(void) crtc_vga = 1; current_default = &user_default; - cons_scr_stat[0].crtat = crtat; - cons_scr_stat[0].crt_base = Crtat; - cons_scr_stat[0].term.esc = 0; - cons_scr_stat[0].term.std_attr = current_default->std_attr; - cons_scr_stat[0].term.rev_attr = current_default->rev_attr; - cons_scr_stat[0].term.attr = current_default->std_attr; - cons_scr_stat[0].posx = cursorat % COL; - cons_scr_stat[0].posy = cursorat / COL; - cons_scr_stat[0].border = BG_BLACK;; - cons_scr_stat[0].max_posx = COL; - cons_scr_stat[0].max_posy = ROW; - cons_scr_stat[0].status = 0; - cons_scr_stat[0].pid = 0; - cons_scr_stat[0].proc = NULL; - cons_scr_stat[0].smode.mode = VT_AUTO; - cons_scr_stat[0].bell_pitch = 800; - cons_scr_stat[0].bell_duration = 10; + console[0].crtat = crtat; + console[0].crt_base = Crtat; + console[0].term.esc = 0; + console[0].term.std_attr = current_default->std_attr; + console[0].term.rev_attr = current_default->rev_attr; + console[0].term.cur_attr = current_default->std_attr; + console[0].xpos = cursorat % COL; + console[0].ypos = cursorat / COL; + console[0].border = BG_BLACK;; + console[0].xsize = COL; + console[0].ysize = ROW; + console[0].status = 0; + console[0].pid = 0; + console[0].proc = NULL; + console[0].smode.mode = VT_AUTO; + console[0].bell_pitch = BELL_PITCH; + console[0].bell_duration = BELL_DURATION; kernel_console.esc = 0; kernel_console.std_attr = kernel_default.std_attr; kernel_console.rev_attr = kernel_default.rev_attr; - kernel_console.attr = kernel_default.std_attr; - /* initialize mapscrn array to */ + kernel_console.cur_attr = kernel_default.std_attr; + /* initialize mapscrn array to a one to one map */ for (i=0; i<sizeof(scr_map); i++) scr_map[i] = i; - clear_screen(&cons_scr_stat[0]); + clear_screen(&console[0]); } -static void sput(u_char c) +static void scput(u_char c) { - scr_stat *scp = &cons_scr_stat[0]; + scr_stat *scp = &console[0]; term_stat save; if (crtat == 0) - consinit(); - save = scp->term; - scp->term = kernel_console; - current_default = &kernel_default; - ansi_put(scp, c); - kernel_console = scp->term; - current_default = &user_default; - scp->term = save; + scinit(); + if( in_putc == 0) { + ++in_putc; + save = scp->term; + scp->term = kernel_console; + current_default = &kernel_default; + ansi_put(scp, c); + kernel_console = scp->term; + current_default = &user_default; + scp->term = save; + --in_putc; + } else { + if( console_buffer_count < CONSOLE_BUFFER_SIZE) + console_buffer[console_buffer_count++] = c; + } } @@ -1890,31 +2085,19 @@ static u_char *get_fstr(u_int c, u_int *len) } -static update_leds(int which) +static void update_leds(int which) { - u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; - - kbd_cmd(KB_SETLEDS); /* LED Command */ - kbd_cmd(xlate_leds[which & LED_MASK]); - kbd_wait(); -} - + static u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; -volatile void reset_cpu(void) -{ - while (1) { - kbd_cmd(KB_RESET_CPU); /* Reset Command */ - DELAY(4000000); - kbd_cmd(KB_RESET); /* Keyboard Reset Command */ - } + kbd_cmd2(KB_SETLEDS, xlate_leds[which & LED_MASK]); } - - + + /* - * sgetc(noblock) : get a character from the keyboard. - * If noblock = 0 wait until a key is gotten. Otherwise return a 0x100. + * scgetc(noblock) : get a character from the keyboard. + * If noblock = 0 wait until a key is gotten. Otherwise return NOKEY. */ -u_int sgetc(int noblock) +u_int scgetc(int noblock) { u_char val, code, release; u_int state, action; @@ -1928,30 +2111,16 @@ next_code: if (inb(KB_STAT) & KB_BUF_FULL) val = inb(KB_DATA); else if (noblock) - return(0x100); + return(NOKEY); else goto next_code; - if (cur_scr_stat->status & KBD_RAW_MODE) + if (cur_console->status & KBD_RAW_MODE) return val; code = val & 0x7F; release = val & 0x80; - /* Check for cntl-alt-del */ - if ((code == 83) && ctls && alts) - cpu_reset(); -#if NDDB > 0 - /* Check for cntl-alt-esc */ - if ((val == 1) && ctls && alts) { - /* if debugger called, try to switch to console 0 */ - if (cur_scr_stat->smode.mode == VT_AUTO && - cons_scr_stat[0].smode.mode == VT_AUTO) - switch_scr(0); - Debugger(); - return(0x100); - } -#endif switch (esc_flag) { case 0x00: /* normal scancode */ switch(code) { @@ -1959,7 +2128,7 @@ next_code: if (release && compose) { compose = 0; if (chr > 255) { - sysbeep(500, hz/4); + sysbeep(BELL_PITCH, BELL_DURATION); chr = 0; } } @@ -2071,7 +2240,7 @@ next_code: default: if (chr) { compose = chr = 0; - sysbeep(500, hz/4); + sysbeep(BELL_PITCH, BELL_DURATION); goto next_code; } break; @@ -2079,12 +2248,12 @@ next_code: } state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0)); - if ((!agrs && (cur_scr_stat->status & ALKED)) - || (agrs && !(cur_scr_stat->status & ALKED))) + if ((!agrs && (cur_console->status & ALKED)) + || (agrs && !(cur_console->status & ALKED))) code += ALTGR_OFFSET; key = &key_map.key[code]; - if ( ((key->flgs & FLAG_LOCK_C) && (cur_scr_stat->status & CLKED)) - || ((key->flgs & FLAG_LOCK_N) && (cur_scr_stat->status & NLKED)) ) + if ( ((key->flgs & FLAG_LOCK_C) && (cur_console->status & CLKED)) + || ((key->flgs & FLAG_LOCK_N) && (cur_console->status & NLKED)) ) state ^= 1; /* Check for make/break */ @@ -2125,12 +2294,15 @@ next_code: case ALK: alkcnt = 0; break; + case META: + metas = 0; + break; } } if (chr && !compose) { action = chr; chr = 0; - return (action); + return(action); } } else { /* key pressed */ @@ -2140,46 +2312,66 @@ next_code: case NLK: if (!nlkcnt) { nlkcnt++; - if (cur_scr_stat->status & NLKED) - cur_scr_stat->status &= ~NLKED; + if (cur_console->status & NLKED) + cur_console->status &= ~NLKED; else - cur_scr_stat->status |= NLKED; - update_leds(cur_scr_stat->status & LED_MASK); + cur_console->status |= NLKED; + update_leds(cur_console->status & LED_MASK); } break; case CLK: if (!clkcnt) { clkcnt++; - if (cur_scr_stat->status & CLKED) - cur_scr_stat->status &= ~CLKED; + if (cur_console->status & CLKED) + cur_console->status &= ~CLKED; else - cur_scr_stat->status |= CLKED; - update_leds(cur_scr_stat->status & LED_MASK); + cur_console->status |= CLKED; + update_leds(cur_console->status & LED_MASK); } break; case SLK: if (!slkcnt) { slkcnt++; - if (cur_scr_stat->status & SLKED) { - cur_scr_stat->status &= ~SLKED; - pcstart(&pccons[get_scr_num(cur_scr_stat)]); + if (cur_console->status & SLKED) { + cur_console->status &= ~SLKED; + pcstart(VIRTUAL_TTY(get_scr_num())); } else - cur_scr_stat->status |= SLKED; - update_leds(cur_scr_stat->status & LED_MASK); + cur_console->status |= SLKED; + update_leds(cur_console->status & LED_MASK); } break; case ALK: if (!alkcnt) { alkcnt++; - if (cur_scr_stat->status & ALKED) - cur_scr_stat->status &= ~ALKED; + if (cur_console->status & ALKED) + cur_console->status &= ~ALKED; else - cur_scr_stat->status |= ALKED; + cur_console->status |= ALKED; } break; /* NON-LOCKING KEYS */ + case NOP: + break; + case RBT: +#if defined(__FreeBSD__) + shutdown_nice(); +#else + cpu_reset(); +#endif + break; + case DBG: +#if DDB > 0 /* try to switch to console 0 */ + if (cur_console->smode.mode == VT_AUTO && + console[0].smode.mode == VT_AUTO) + switch_scr(0); + Debugger("manual escape to debugger"); + return(NOKEY); +#else + printf("No debugger in kernel\n"); +#endif + break; case LSH: shfts |= 1; break; @@ -2201,67 +2393,68 @@ next_code: case ASH: agrs = 1; break; - case NOP: + case META: + metas = 1; + break; + case NEXT: + switch_scr((get_scr_num()+1)%NCONS); break; default: if (action >= F_SCR && action <= L_SCR) { switch_scr(action - F_SCR); break; } - if (action >= F_FN && action <= L_FN) { - return(action | FKEY); - } + if (action >= F_FN && action <= L_FN) + action |= FKEY; return(action); } } - else return(action); + else { + if (metas) + action |= MKEY; + return(action); + } } goto next_code; } -/* July '93, jkh. Added in for init_main.c */ -void cons_highlight() -{ - cons_scr_stat[0].term.attr &= 0xFF00; - cons_scr_stat[0].term.attr |= 0x0800; -} - -void cons_normal() -{ - cons_scr_stat[0].term.attr = cons_scr_stat[0].term.std_attr; -} int getchar(void) { - char thechar; + u_char thechar; int s; - pcconsoftc.cs_flags |= CSF_POLLING; + polling = 1; s = splhigh(); - sput('>'); - thechar = (char) sgetc(0); - pcconsoftc.cs_flags &= ~CSF_POLLING; + scput('>'); + thechar = (u_char) scgetc(0); + polling = 0; splx(s); switch (thechar) { default: if (thechar >= scr_map[0x20]) - sput(thechar); + scput(thechar); return(thechar); case cr: case lf: - sput(cr); sput(lf); + scput(cr); scput(lf); return(lf); case bs: case del: - sput(bs); sput(scr_map[0x20]); sput(bs); + scput(bs); scput(scr_map[0x20]); scput(bs); return(thechar); case cntld: - sput('^'); sput('D'); sput('\r'); sput('\n'); + scput('^'); scput('D'); scput('\r'); scput('\n'); return(0); } } +u_int sgetc(int noblock) +{ + return (scgetc(noblock) & 0xff); +} + int pcmmap(dev_t dev, int offset, int nprot) { if (offset > 0x20000) @@ -2273,9 +2466,12 @@ int pcmmap(dev_t dev, int offset, int nprot) static void kbd_wait(void) { int i; - for (i=0; i<10000; i++) + + for (i=0; i<1000; i++) { /* up to 10 msec */ if ((inb(KB_STAT) & KB_READY) == 0) break; + DELAY (10); + } } @@ -2286,17 +2482,46 @@ static void kbd_cmd(u_char command) } +static void kbd_cmd2(u_char command, u_char arg) +{ + int r, s = spltty(); + do { + kbd_cmd(command); + r = kbd_reply(); + if (r == KB_ACK) { + kbd_cmd(arg & 0x7f); + r = kbd_reply(); + } + } while (r != KB_ACK); + splx(s); +} + + +static int kbd_reply() +{ + int i; + + kbd_wait(); + for (i=0; i<60000; i++) { /* at least 300 msec, 600 msec enough */ + if (inb(KB_STAT) & KB_BUF_FULL) + return ((u_char) inb(KB_DATA)); + DELAY (10); + } + return(-1); +} + + static void set_mode(scr_stat *scp) { u_char byte; int s; - if (scp != cur_scr_stat) + if (scp != cur_console) return; /* (re)activate cursor */ - untimeout(cursor_pos, 0); - cursor_pos(); + untimeout((timeout_t)cursor_pos, 0); + cursor_pos(1); /* change cursor type if set */ if (scp->cursor_start != -1 && scp->cursor_end != -1) @@ -2320,7 +2545,7 @@ static void set_mode(scr_stat *scp) outb(TSIDX, 0x03); outb(TSREG, 0x05); /* select font 1 */ break; default: - return; + break; } splx(s); @@ -2338,7 +2563,7 @@ static void set_border(int color) outb(ATC, 0x20); /* enable Palette */ } -static load_font(int segment, int size, char* font) +static void load_font(int segment, int size, char* font) { int ch, line, s; u_char val; @@ -2403,7 +2628,7 @@ static void save_palette(void) } -static change_winsize(struct tty *tp, int x, int y) +static void change_winsize(struct tty *tp, int x, int y) { if (tp->t_winsize.ws_col != x || tp->t_winsize.ws_row != y) { tp->t_winsize.ws_col = x; |
