summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorAaron Campbell <aaron@cvs.openbsd.org>1999-09-06 00:12:41 +0000
committerAaron Campbell <aaron@cvs.openbsd.org>1999-09-06 00:12:41 +0000
commit5a62cd9616ed6003bb80b5ea059f93b7df501b4e (patch)
tree02e6bee514174c4ec97ff20a48cc6e6b1afac396 /sys/arch
parentfd7828d77426587c17477b91a61261c53380bfdb (diff)
Add scrollback support to the pcvt (i386 only) console driver.
Press LEFT_SHIFT+PGUP/PGDN to navigate. Number of buffered pages is currently only configurable by editing sys/arch/i386/isa/pcvt/pcvt_hdr.h and changing the SCROLLBACK_PAGES constant. You must add "option PCVT_SCROLLBACK" to your kernel config file to enable this support, or uncomment it from sys/arch/i386/conf/GENERIC. Known issues: - Few little buglets when switching line (font) or column modes in scon(1). - Can't hold down LEFT_SHIFT+PGUP/PGDN keys. This will be fixed... Idea from Linux, code by me.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/conf/GENERIC4
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_drv.c8
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_ext.c14
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_hdr.h23
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_kbd.c141
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_out.c86
6 files changed, 267 insertions, 9 deletions
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC
index 550965e35ff..d9e04e5c5b1 100644
--- a/sys/arch/i386/conf/GENERIC
+++ b/sys/arch/i386/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.126 1999/08/31 07:55:01 fgsch Exp $
+# $OpenBSD: GENERIC,v 1.127 1999/09/06 00:12:39 aaron Exp $
# $NetBSD: GENERIC,v 1.48 1996/05/20 18:17:23 mrg Exp $
#
# GENERIC -- everything that's currently supported
@@ -31,6 +31,8 @@ option COMPAT_LINUX # binary compatibility with Linux
option COMPAT_FREEBSD # binary compatibility with FreeBSD
option COMPAT_BSDOS # binary compatibility with BSD/OS
+#option PCVT_SCROLLBACK # pcvt console scrollback support
+
maxusers 32 # estimated number of users
config bsd swap generic
diff --git a/sys/arch/i386/isa/pcvt/pcvt_drv.c b/sys/arch/i386/isa/pcvt/pcvt_drv.c
index 33f2adde5e1..1ae909417d9 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_drv.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_drv.c,v 1.22 1998/11/20 15:57:25 deraadt Exp $ */
+/* $OpenBSD: pcvt_drv.c,v 1.23 1999/09/06 00:12:39 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -706,7 +706,13 @@ pcstart(register struct tty *tp)
*/
while ((len = q_to_b(&tp->t_outq, buf, PCVT_PCBURST)) != 0)
+ {
+#ifdef PCVT_SCROLLBACK
+ if (vs[minor(tp->t_dev)].scrolling)
+ sgetc(31337);
+#endif
sput(&buf[0], 0, len, minor(tp->t_dev));
+ }
s = spltty();
diff --git a/sys/arch/i386/isa/pcvt/pcvt_ext.c b/sys/arch/i386/isa/pcvt/pcvt_ext.c
index c9a89c09bf3..1bb3c492ff1 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_ext.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_ext.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_ext.c,v 1.17 1998/09/28 03:00:27 downsj Exp $ */
+/* $OpenBSD: pcvt_ext.c,v 1.18 1999/09/06 00:12:40 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -2552,6 +2552,18 @@ vgapage(int new_screen)
{
/* we are committed */
vt_switch_pending = 0;
+#ifdef PCVT_SCROLLBACK
+ if (vsp->Scrollback)
+ {
+ vsp->scrolling = 0;
+ fillw(user_attr | ' ', (caddr_t)vsp->Scrollback,
+ vsp->screen_rowsize * vsp->maxcol *
+ SCROLLBACK_PAGES);
+ bcopy(vsp->Crtat, vsp->Scrollback,
+ vsp->screen_rows * vsp->maxcol * CHR);
+ vsp->scr_offset = vsp->row - 1;
+ }
+#endif
}
}
return 0;
diff --git a/sys/arch/i386/isa/pcvt/pcvt_hdr.h b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
index c59a577030b..5d3bf399143 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_hdr.h
+++ b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_hdr.h,v 1.21 1998/09/06 23:00:03 niklas Exp $ */
+/* $OpenBSD: pcvt_hdr.h,v 1.22 1999/09/06 00:12:40 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -603,6 +603,13 @@
#define SYS_FKL 0 /* in hp mode, sys-fkls are active */
#define USR_FKL 1 /* in hp mode, user-fkls are active */
+#ifdef PCVT_SCROLLBACK
+
+/* scrollback buffer size (in pages) */
+#define SCROLLBACK_PAGES 8
+
+#endif
+
/* variables */
#ifdef EXTERN
@@ -646,6 +653,12 @@ struct rgb {
typedef struct video_state {
u_short *Crtat; /* video page start addr */
u_short *Memory; /* malloc'ed memory start address */
+#ifdef PCVT_SCROLLBACK
+ u_short *Scrollback; /* scrollback buffer */
+ u_short scr_offset; /* current scrollback offset (lines) */
+ short scrolling; /* current scrollback page */
+ u_short max_off; /* maximum scrollback offset */
+#endif
struct tty *vs_tty; /* pointer to this screen's tty */
u_char maxcol; /* 80 or 132 cols on screen */
u_char row, col; /* current cursor position */
@@ -821,6 +834,10 @@ struct tty *pcconsp; /* ptr to current device, see pcattach() */
u_short *Crtat; /* screen start address */
+#ifdef PCVT_SCROLLBACK
+u_short *Scrollbuffer; /* scrollback buffer */
+#endif
+
#if PCVT_EMU_MOUSE
struct mousestat mouse = {{0}};
struct mousedefs mousedef = {0x3b, 0x3c, 0x3d, 0, 250000};
@@ -978,6 +995,10 @@ extern u_char vga_family;
extern u_char keyboard_is_initialized;
extern u_char kbd_polling;
+#ifdef PCVT_SCROLLBACK
+extern u_short *Scrollbuffer;
+#endif
+
#if PCVT_SHOWKEYS
extern u_char keyboard_show;
#endif /* PCVT_SHOWKEYS */
diff --git a/sys/arch/i386/isa/pcvt/pcvt_kbd.c b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
index 293955e4ef3..369ff540929 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_kbd.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_kbd.c,v 1.20 1999/07/06 07:59:54 deraadt Exp $ */
+/* $OpenBSD: pcvt_kbd.c,v 1.21 1999/09/06 00:12:40 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -115,6 +115,13 @@ static int tpmrate = KBD_TPD500|KBD_TPM100;
static u_char altkpflag = 0;
static u_short altkpval = 0;
+#ifdef PCVT_SCROLLBACK
+static u_short *scrollback_savedscreen = (u_short *)0;
+static size_t scrnsv_size = (size_t)-1;
+static void scrollback_save_screen ( void );
+static void scrollback_restore_screen ( void );
+#endif
+
extern int kbd_reset;
#if PCVT_SHOWKEYS
@@ -1088,6 +1095,13 @@ loop:
#if PCVT_KBD_FIFO
+#ifdef PCVT_SCROLLBACK
+ if (noblock == 31337) {
+ vsp->scrolling = 1;
+ goto scroll_reset;
+ }
+#endif
+
/* see if there is data from the keyboard available either from */
/* the keyboard fifo or from the 8042 keyboard controller */
@@ -1413,7 +1427,7 @@ no_mouse_event:
#if PCVT_SHOWKEYS
showkey (' ', dt);
-#endif /* PCVT_SHOWKEYS */
+#endif /* PCVT_SHOWKEYS */
/* lets look what we got */
switch(dt)
@@ -1474,6 +1488,98 @@ regular:
kbd_status.extended = kbd_status.ext1 = 0;
+#ifdef PCVT_SCROLLBACK
+ if ((key == 85) && shift_down && kbd_lastkey != 85)
+ {
+ if (vsp->scr_offset >= (vsp->screen_rows - 1))
+ {
+ if (!vsp->scrolling)
+ {
+ vsp->scrolling += vsp->screen_rows - 1;
+ if (vsp->Scrollback)
+ {
+ scrollback_save_screen();
+ if (vsp->scr_offset == vsp->max_off)
+ {
+ bcopy(vsp->Scrollback +
+ vsp->maxcol,
+ vsp->Scrollback,
+ vsp->maxcol *
+ vsp->max_off * CHR);
+ vsp->scr_offset--;
+ }
+ bcopy(vsp->Crtat + vsp->cur_offset -
+ vsp->col, vsp->Scrollback +
+ ((vsp->scr_offset + 1) *
+ vsp->maxcol), vsp->maxcol * CHR);
+ }
+
+ if (vsp->cursor_on)
+ sw_cursor(0);
+ }
+
+ vsp->scrolling += vsp->screen_rows - 1;
+ if (vsp->scrolling > vsp->scr_offset)
+ vsp->scrolling = vsp->scr_offset;
+
+ bcopy(vsp->Scrollback + ((vsp->scr_offset -
+ vsp->scrolling) * vsp->maxcol), vsp->Crtat,
+ vsp->screen_rows * vsp->maxcol * CHR);
+ }
+
+ kbd_lastkey = 85;
+ goto loop;
+ }
+ else if ((key == 86) && shift_down && kbd_lastkey != 86)
+ {
+scroll_reset:
+ if (vsp->scrolling > 0)
+ {
+ vsp->scrolling -= vsp->screen_rows - 1;
+ if (vsp->scrolling < 0)
+ vsp->scrolling = 0;
+
+ if (vsp->scrolling <= vsp->screen_rows)
+ {
+ vsp->scrolling = 0;
+ scrollback_restore_screen();
+ }
+ else
+ {
+ bcopy(vsp->Scrollback + ((vsp->scr_offset -
+ vsp->scrolling) * vsp->maxcol),
+ vsp->Crtat, vsp->screen_rows *
+ vsp->maxcol * CHR);
+ }
+ }
+
+ if (vsp->scrolling == 0)
+ {
+ if (vsp->cursor_on)
+ {
+ sw_cursor(1);
+ }
+ }
+
+ if (noblock == 31337)
+ return NULL;
+
+ if (key != 86)
+ goto regular;
+ else
+ {
+ kbd_lastkey = 86;
+ goto loop;
+ }
+ }
+ else if (vsp->scrolling && key != 128 && key != 44 && key != 85 &&
+ key != 86)
+ {
+ vsp->scrolling = 1;
+ goto scroll_reset;
+ }
+#endif
+
if(kbd_reset && (key == 76) && ctrl_down && (meta_down||altgr_down)) {
printf("\nconsole halt requested: going down.\n");
kbd_reset = 0;
@@ -3043,4 +3149,35 @@ cfkey12(void)
#endif /* NVT > 0 */
+#ifdef PCVT_SCROLLBACK
+static void
+scrollback_save_screen(void)
+{
+ int x = spltty();
+ register size_t s;
+
+ s = sizeof(u_short) * vsp->screen_rowsize * vsp->maxcol;
+
+ if (scrollback_savedscreen)
+ free(scrollback_savedscreen, M_TEMP);
+
+ scrnsv_size = s;
+
+ if (!(scrollback_savedscreen = (u_short *)malloc(s, M_TEMP, M_NOWAIT)))
+ {
+ splx(x);
+ return;
+ }
+ bcopy(vsp->Crtat, scrollback_savedscreen, scrnsv_size);
+ splx(x);
+}
+
+static void
+scrollback_restore_screen(void)
+{
+ if (scrollback_savedscreen)
+ bcopy(scrollback_savedscreen, vsp->Crtat, scrnsv_size);
+}
+#endif
+
/* ------------------------------- EOF -------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_out.c b/sys/arch/i386/isa/pcvt/pcvt_out.c
index e6e9d232d20..734e19f2426 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_out.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_out.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_out.c,v 1.7 1999/01/13 07:26:02 niklas Exp $ */
+/* $OpenBSD: pcvt_out.c,v 1.8 1999/09/06 00:12:40 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -80,6 +80,9 @@ static void wrfkl ( int num, u_char *string, struct video_state *svsp );
static void writefkl ( int num, u_char *string, struct video_state *svsp );
static __inline void write_char (struct video_state *, u_short, u_short ch);
+#ifdef PCVT_SCROLLBACK
+static int check_scrollback ( struct video_state *svsp );
+#endif
/*---------------------------------------------------------------------------*
* do character set transformation and write to display memory (inline)
@@ -147,6 +150,9 @@ void
sput (u_char *s, U_char kernel, int len, int page)
{
register struct video_state *svsp;
+#ifdef PCVT_SCROLLBACK
+ int extra;
+#endif
u_short attrib;
u_short ch;
@@ -269,6 +275,20 @@ sput (u_char *s, U_char kernel, int len, int page)
case 0x0a: /* LF */
case 0x0b: /* VT */
case 0x0c: /* FF */
+#ifdef PCVT_SCROLLBACK
+ if (check_scrollback(svsp))
+ {
+ extra = (svsp->cur_offset %
+ svsp->maxcol) ?
+ svsp->col : 0;
+ bcopy(svsp->Crtat +
+ svsp->cur_offset - extra,
+ svsp->Scrollback +
+ (svsp->scr_offset *
+ svsp->maxcol),
+ svsp->maxcol * CHR);
+ }
+#endif
if(svsp->lnm)
{
svsp->cur_offset -= svsp->col;
@@ -421,6 +441,18 @@ sput (u_char *s, U_char kernel, int len, int page)
svsp->cur_offset++;
svsp->col = 0;
svsp->lastchar = 0;
+#ifdef PCVT_SCROLLBACK
+ if (check_scrollback(svsp))
+ {
+ bcopy(svsp->Crtat +
+ svsp->cur_offset -
+ svsp->maxcol,
+ svsp->Scrollback +
+ (svsp->scr_offset *
+ svsp->maxcol),
+ svsp->maxcol * CHR);
+ }
+#endif
check_scroll(svsp);
}
@@ -813,6 +845,11 @@ sput (u_char *s, U_char kernel, int len, int page)
case 'K': /* erase line */
vt_clreol(svsp);
svsp->state = STATE_INIT;
+#ifdef PCVT_SCROLLBACK
+ if (svsp->scr_offset > 0 &&
+ svsp == vsp)
+ svsp->scr_offset--;
+#endif
break;
case 'L': /* insert line */
@@ -1094,6 +1131,11 @@ vt_coldinit(void)
{
svsp->Crtat = Crtat; /* all same until malloc'ed */
svsp->Memory = Crtat; /* until malloc'ed */
+#ifdef PCVT_SCROLLBACK
+ svsp->Scrollback = 0; /* until malloc'ed */
+ svsp->scr_offset = 0; /* scrollback offset (lines) */
+ svsp->scrolling = 0; /* current scrollback page */
+#endif
svsp->cur_offset = 0; /* cursor offset */
svsp->c_attr = user_attr; /* non-kernel attributes */
svsp->bell_on = 1; /* enable bell */
@@ -1128,6 +1170,9 @@ vt_coldinit(void)
#endif /* PCVT_24LINESDEF */
svsp->screen_rowsize = 25; /* default 25 rows on screen */
+#ifdef PCVT_SCROLLBACK
+ svsp->max_off = svsp->screen_rowsize * SCROLLBACK_PAGES - 1;
+#endif
svsp->scrr_beg = 0; /* scrolling region begin row*/
svsp->scrr_len = svsp->screen_rows; /* scrolling region length*/
svsp->scrr_end = svsp->scrr_len - 1;/* scrolling region end */
@@ -1361,6 +1406,15 @@ vt_coldmalloc(void)
MAXROW_VGA * MAXCOL_VGA * CHR;
}
+#ifdef PCVT_SCROLLBACK
+ if ((Scrollbuffer = (u_short *)malloc(vs[0].maxcol *
+ vs[0].screen_rowsize * SCROLLBACK_PAGES * CHR * 2, M_DEVBUF,
+ M_WAITOK)) == NULL)
+ {
+ printf("pcvt: scrollback memory malloc failed\n");
+ }
+#endif
+
for(nscr = 0; nscr < PCVT_NSCREENS; nscr++)
{
if((vs[nscr].Memory =
@@ -1372,6 +1426,9 @@ vt_coldmalloc(void)
PCVT_NSCREENS, nscr);
break;
}
+#ifdef PCVT_SCROLLBACK
+ vs[nscr].Scrollback = Scrollbuffer;
+#endif
if(nscr != 0)
{
vs[nscr].Crtat = vs[nscr].Memory;
@@ -1423,6 +1480,29 @@ check_scroll(struct video_state *svsp)
}
}
+#ifdef PCVT_SCROLLBACK
+static int
+check_scrollback(struct video_state *svsp)
+{
+ /* still waiting for scrollback memory or not on current page */
+ if (!svsp->Scrollback || svsp != vsp)
+ return 0;
+
+ /* remove first line of scrollback buffer to make room for new line */
+ if (svsp->scr_offset == svsp->max_off)
+ {
+ bcopy(svsp->Scrollback + svsp->maxcol, svsp->Scrollback,
+ svsp->maxcol * svsp->max_off * CHR);
+ }
+ else
+ {
+ /* still room left, increase scroll offset (lines) */
+ svsp->scr_offset++;
+ }
+ return 1;
+}
+#endif
+
/*---------------------------------------------------------------------------*
* write to one user function key label
*---------------------------------------------------------------------------*/
@@ -1877,8 +1957,8 @@ vt_col(struct video_state *svsp, int cols)
clr_parms(svsp); /* escape parameter init */
svsp->state = STATE_INIT; /* initial state */
- svsp->col = 0; /* init row */
- svsp->row = 0; /* init col */
+ svsp->col = 0; /* init col */
+ svsp->row = 0; /* init row */
svsp->cur_offset = 0; /* cursor offset init */
svsp->sc_flag = 0; /* invalidate saved cursor position */
svsp->scrr_beg = 0; /* reset scrolling region */