summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1999-06-24 10:51:40 +0000
committerkato <kato@FreeBSD.org>1999-06-24 10:51:40 +0000
commit2e2fe43a357a07fe5a62764e2d21d93dd709f407 (patch)
tree4fd299a6d70722066b5c33820fff20f0284d4c11 /sys
parent4859384f0d8a6d9a04c7f3c535176758cd205454 (diff)
downloadFreeBSD-src-2e2fe43a357a07fe5a62764e2d21d93dd709f407.zip
FreeBSD-src-2e2fe43a357a07fe5a62764e2d21d93dd709f407.tar.gz
PC98 part of the second phase of syscons reorganization.
Submitted by: yokota
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files.pc9814
-rw-r--r--sys/pc98/cbus/gdc.c319
-rw-r--r--sys/pc98/cbus/sc_machdep.h61
-rw-r--r--sys/pc98/cbus/scgdcrndr.c180
-rw-r--r--sys/pc98/cbus/scvtb.c364
-rw-r--r--sys/pc98/cbus/sio.c4
-rw-r--r--sys/pc98/cbus/syscons_cbus.c193
-rw-r--r--sys/pc98/conf/files.pc9814
-rw-r--r--sys/pc98/pc98/pc98gdc.c319
-rw-r--r--sys/pc98/pc98/sc_machdep.h61
-rw-r--r--sys/pc98/pc98/scgdcrndr.c180
-rw-r--r--sys/pc98/pc98/scvtbpc98.c364
-rw-r--r--sys/pc98/pc98/sio.c4
-rw-r--r--sys/pc98/pc98/syscons.c4823
-rw-r--r--sys/pc98/pc98/syscons_pc98.c193
15 files changed, 4056 insertions, 3037 deletions
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index 3943b78..2bcc99b 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.98 1999/06/18 14:48:19 kato Exp $
+# $Id: files.pc98,v 1.99 1999/06/21 11:11:39 kato Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -21,11 +21,6 @@ linux_assym.h optional compat_linux \
no-obj no-implicit-rule before-depend \
clean "linux_assym.h"
#
-font8x16.o optional std8x16font \
- compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \
- no-implicit-rule before-depend \
- clean "${STD8X16FONT}-8x16 font8x16.c"
-#
atkbdmap.h optional atkbd_dflt_keymap \
compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \
no-obj no-implicit-rule before-depend \
@@ -280,7 +275,12 @@ i386/isa/spigot.c optional spigot device-driver
pc98/pc98/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
pc98/pc98/syscons.c optional sc device-driver
-pc98/pc98/scvidctl.c optional sc device-driver
+pc98/pc98/syscons_pc98.c optional sc device-driver
+dev/syscons/schistory.c optional sc device-driver
+dev/syscons/scmouse.c optional sc device-driver
+pc98/pc98/scgdcrndr.c optional sc device-driver
+dev/syscons/scvidctl.c optional sc device-driver
+pc98/pc98/scvtbpc98.c optional sc device-driver
i386/isa/tw.c optional tw device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
diff --git a/sys/pc98/cbus/gdc.c b/sys/pc98/cbus/gdc.c
index a6efd2a..e98f35e 100644
--- a/sys/pc98/cbus/gdc.c
+++ b/sys/pc98/cbus/gdc.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pc98gdc.c,v 1.8 1999/05/09 04:56:42 kato Exp $
+ * $Id: pc98gdc.c,v 1.9 1999/05/30 16:53:20 phk Exp $
*/
#include "gdc.h"
@@ -72,7 +72,7 @@ typedef struct gdc_softc {
#define GDC_SOFTC(unit) \
((gdc_softc_t *)devclass_get_softc(gdc_devclass, unit))
-devclass_t gdc_devclass;
+static devclass_t gdc_devclass;
static int gdcprobe(device_t dev);
static int gdc_attach(device_t dev);
@@ -99,13 +99,15 @@ static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
static d_open_t gdcopen;
static d_close_t gdcclose;
static d_read_t gdcread;
+static d_write_t gdcwrite;
static d_ioctl_t gdcioctl;
+static d_mmap_t gdcmmap;
static struct cdevsw vga_cdevsw = {
/* open */ gdcopen,
/* close */ gdcclose,
- /* read */ noread,
- /* write */ nowrite,
+ /* read */ gdcread,
+ /* write */ gdcwrite,
/* ioctl */ gdcioctl,
/* stop */ nostop,
/* reset */ noreset,
@@ -139,9 +141,24 @@ static int
gdc_attach(device_t dev)
{
gdc_softc_t *sc;
+ int error;
sc = device_get_softc(dev);
- return gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
+ error = gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
+ if (error)
+ return error;
+
+#ifdef FB_INSTALL_CDEV
+ /* attach a virtual frame buffer device */
+ error = fb_attach(makedev(0, GDC_MKMINOR(unit)), sc->adp, &gdc_cdevsw);
+ if (error)
+ return error;
+#endif /* FB_INSTALL_CDEV */
+
+ if (bootverbose)
+ (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose);
+
+ return 0;
}
static int
@@ -152,7 +169,7 @@ gdc_probe_unit(int unit, gdc_softc_t *sc, int flags)
bzero(sc, sizeof(*sc));
sw = vid_get_switch(DRIVER_NAME);
if (sw == NULL)
- return 0;
+ return ENXIO;
return (*sw->probe)(unit, &sc->adp, NULL, flags);
}
@@ -160,30 +177,78 @@ static int
gdc_attach_unit(int unit, gdc_softc_t *sc, int flags)
{
video_switch_t *sw;
- int error;
sw = vid_get_switch(DRIVER_NAME);
if (sw == NULL)
return ENXIO;
+ return (*sw->init)(unit, sc->adp, flags);
+}
- error = (*sw->init)(unit, sc->adp, flags);
- if (error)
- return ENXIO;
+/* cdev driver functions */
#ifdef FB_INSTALL_CDEV
- /* attach a virtual frame buffer device */
- error = fb_attach(makedev(0, GDC_MKMINOR(unit)), scp->adp,
- &vga_cdevsw);
- if (error)
- return error;
-#endif /* FB_INSTALL_CDEV */
- if (bootverbose)
- (*sw->diag)(sc->adp, bootverbose);
+static int
+gdcopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ gdc_softc_t *sc;
- return 0;
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+ if (mode & (O_CREAT | O_APPEND | O_TRUNC))
+ return ENODEV;
+
+ return genfbopen(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+static int
+gdcclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbclose(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+static int
+gdcread(dev_t dev, struct uio *uio, int flag)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+static int
+gdcwrite(dev_t dev, struct uio *uio, int flag)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+static int
+gdcioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, p);
}
+static int
+gdcmmap(dev_t dev, vm_offset_t offset, int prot)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbmmap(&sc->gensc, sc->adp, offset, prot);
+}
+
+#endif /* FB_INSTALL_CDEV */
+
/* LOW-LEVEL */
#include <machine/clock.h>
@@ -213,7 +278,7 @@ static video_adapter_t adapter_init_value[] = {
V_ADP_COLOR | V_ADP_MODECHANGE | V_ADP_BORDER,
IO_GDC1, 16, TEXT_GDC, /* va_io*, XXX */
VIDEO_BUF_BASE, VIDEO_BUF_SIZE, /* va_mem* */
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, /* va_window* */
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, /* va_window* */
0, 0, /* va_buffer, va_buffer_size */
0, M_PC98_80x25, 0, /* va_*mode* */
},
@@ -224,6 +289,7 @@ static video_adapter_t biosadapter[1];
/* video driver declarations */
static int gdc_configure(int flags);
static int gdc_nop(void);
+static int gdc_err(video_adapter_t *adp, ...);
static vi_probe_t gdc_probe;
static vi_init_t gdc_init;
static vi_get_info_t gdc_get_info;
@@ -235,11 +301,11 @@ static vi_load_state_t gdc_load_state;
static vi_read_hw_cursor_t gdc_read_hw_cursor;
static vi_set_hw_cursor_t gdc_set_hw_cursor;
static vi_set_hw_cursor_shape_t gdc_set_hw_cursor_shape;
-static vi_mmap_t gdc_mmap;
+static vi_blank_display_t gdc_blank_display;
+static vi_mmap_t gdc_mmap_buf;
+static vi_ioctl_t gdc_dev_ioctl;
static vi_diag_t gdc_diag;
-static int gdc_err(video_adapter_t *adp, ...);
-
static video_switch_t gdcvidsw = {
gdc_probe,
gdc_init,
@@ -258,8 +324,14 @@ static video_switch_t gdcvidsw = {
gdc_read_hw_cursor,
gdc_set_hw_cursor,
gdc_set_hw_cursor_shape,
- (vi_blank_display_t *)gdc_nop,
- gdc_mmap,
+ gdc_blank_display,
+ gdc_mmap_buf,
+ gdc_dev_ioctl,
+ (vi_clear_t *)gdc_err,
+ (vi_fill_rect_t *)gdc_err,
+ (vi_bitblt_t *)gdc_err,
+ (int (*)(void))gdc_err,
+ (int (*)(void))gdc_err,
gdc_diag,
};
@@ -271,15 +343,15 @@ VIDEO_DRIVER(gdc, gdcvidsw, gdc_configure);
static video_info_t bios_vmode[] = {
{ M_PC98_80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
#ifdef LINE30
{ M_PC98_80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
#endif
{ EOT },
};
-static int init_done = FALSE;
+static int gdc_init_done = FALSE;
/* local functions */
static int map_gen_mode_num(int type, int color, int mode);
@@ -287,7 +359,7 @@ static int probe_adapters(void);
static void dump_buffer(u_char *buf, size_t len);
#define prologue(adp, flag, err) \
- if (!init_done || !((adp)->va_flags & (flag))) \
+ if (!gdc_init_done || !((adp)->va_flags & (flag))) \
return (err)
/* a backdoor for the console driver */
@@ -336,9 +408,9 @@ probe_adapters(void)
video_info_t info;
/* do this test only once */
- if (init_done)
+ if (gdc_init_done)
return 1;
- init_done = TRUE;
+ gdc_init_done = TRUE;
biosadapter[0] = adapter_init_value[0];
biosadapter[0].va_flags |= V_ADP_PROBED;
@@ -547,6 +619,12 @@ gdc_nop(void)
}
static int
+gdc_err(video_adapter_t *adp, ...)
+{
+ return ENODEV;
+}
+
+static int
gdc_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
{
probe_adapters();
@@ -587,8 +665,8 @@ gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
{
int i;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode);
for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
@@ -596,10 +674,11 @@ gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
continue;
if (mode == bios_vmode[i].vi_mode) {
*info = bios_vmode[i];
+ info->vi_buffer_size = info->vi_window_size*info->vi_planes;
return 0;
}
}
- return 1;
+ return EINVAL;
}
/*
@@ -614,7 +693,7 @@ gdc_query_mode(video_adapter_t *adp, video_info_t *info)
video_info_t buf;
int i;
- if (!init_done)
+ if (!gdc_init_done)
return -1;
for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
@@ -661,16 +740,16 @@ gdc_set_mode(video_adapter_t *adp, int mode)
{
video_info_t info;
- prologue(adp, V_ADP_MODECHANGE, 1);
+ prologue(adp, V_ADP_MODECHANGE, ENODEV);
mode = map_gen_mode_num(adp->va_type,
adp->va_flags & V_ADP_COLOR, mode);
if (gdc_get_info(adp, mode, &info))
- return 1;
+ return EINVAL;
#ifdef LINE30
switch (info.vi_mode) {
- case M_PC98_80x25: /* VGA TEXT MODES */
+ case M_PC98_80x25: /* GDC TEXT MODES */
initialize_gdc(T25_G400);
break;
case M_PC98_80x30:
@@ -744,7 +823,7 @@ gdc_set_border(video_adapter_t *adp, int color)
static int
gdc_save_state(video_adapter_t *adp, void *p, size_t size)
{
- return 1;
+ return ENODEV;
}
/*
@@ -754,7 +833,7 @@ gdc_save_state(video_adapter_t *adp, void *p, size_t size)
static int
gdc_load_state(video_adapter_t *adp, void *p)
{
- return 1;
+ return ENODEV;
}
/*
@@ -767,11 +846,11 @@ gdc_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
u_int16_t off;
int s;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
+ return ENODEV;
s = spltty();
master_gdc_cmd(0xe0); /* _GDC_CSRR */
@@ -802,14 +881,30 @@ gdc_set_hw_cursor(video_adapter_t *adp, int col, int row)
u_int16_t off;
int s;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
if ((col == -1) && (row == -1)) {
off = -1;
+ /* XXX */
+ if (epson_machine_id == 0x20) {
+ s = spltty();
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ splx(s);
+ }
} else {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
+ return ENODEV;
+ /* XXX */
+ if (epson_machine_id == 0x20) {
+ s = spltty();
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ splx(s);
+ }
off = row*adp->va_info.vi_width + col;
}
@@ -834,6 +929,9 @@ gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
int end;
int s;
+ if (!gdc_init_done)
+ return ENXIO;
+
start = celsize - (base + height);
end = celsize - base - 1;
/*
@@ -846,28 +944,76 @@ gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
--end;
s = spltty();
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ if (height > 0)
+ outb(0x0c17, inb(0xc17) | 0x08);
+ else
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
master_gdc_cmd(0x4b); /* _GDC_CSRFORM */
master_gdc_prm(((height > 0) ? 0x80 : 0) /* cursor on/off */
- | (celsize - 1) & 0x1f); /* cel size */
+ | ((celsize - 1) & 0x1f)); /* cel size */
master_gdc_word_prm(((end & 0x1f) << 11) /* end line */
| (12 << 6) /* blink rate */
| (blink ? 0x20 : 0) /* blink on/off */
| (start & 0x1f)); /* start line */
splx(s);
- return 1;
+ return 0;
}
-static void
-dump_buffer(u_char *buf, size_t len)
+/*
+ * blank_display()
+ * Put the display in power save/power off mode.
+ */
+static int
+gdc_blank_display(video_adapter_t *adp, int mode)
{
- int i;
+ int s;
- for(i = 0; i < len;) {
- printf("%02x ", buf[i]);
- if ((++i % 16) == 0)
- printf("\n");
+ if (!gdc_init_done)
+ return ENXIO;
+
+ s = splhigh();
+ switch (mode) {
+ case V_DISPLAY_SUSPEND:
+ case V_DISPLAY_STAND_BY:
+ /*
+ * FIXME: I don't know how to put the display into `suspend'
+ * or `stand-by' mode via GDC...
+ */
+ /* FALL THROUGH */
+
+ case V_DISPLAY_BLANK:
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ outb(0xc17, inb(0xc17) & ~0x08);
+ outb(0xc16, inb(0xc16) & ~0x02);
+ outb(0x43f, 0x40);
+ } else {
+ while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
+ ;
+ outb(TEXT_GDC + 2, 0xc); /* text off */
+ }
+ break;
+
+ case V_DISPLAY_ON:
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ outb(0xc17, inb(0xc17) | 0x08);
+ outb(0xc16, inb(0xc16) | 0x02);
+ outb(0x43f, 0x40);
+ } else {
+ while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
+ ;
+ outb(TEXT_GDC + 2, 0xd); /* text on */
+ }
+ break;
}
+ splx(s);
+ return 0;
}
/*
@@ -875,11 +1021,58 @@ dump_buffer(u_char *buf, size_t len)
* Mmap frame buffer.
*/
static int
-gdc_mmap(video_adapter_t *adp, vm_offset_t offset)
+gdc_mmap_buf(video_adapter_t *adp, vm_offset_t offset, int prot)
{
- if (offset > 0x48000 - PAGE_SIZE)
+ /* FIXME: is this correct? XXX */
+ if (offset > VIDEO_BUF_SIZE - PAGE_SIZE)
return -1;
- return i386_btop((VIDEO_BUF_BASE + offset));
+ return i386_btop(adp->va_info.vi_window + offset);
+}
+
+static int
+gdc_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
+{
+ switch (cmd) {
+ case FBIO_GETWINORG: /* get frame buffer window origin */
+ *(u_int *)arg = 0;
+ return 0;
+
+ case FBIO_SETWINORG: /* set frame buffer window origin */
+ case FBIO_SETDISPSTART: /* set display start address */
+ case FBIO_SETLINEWIDTH: /* set scan line length in pixel */
+ case FBIO_GETPALETTE: /* get color palette */
+ case FBIO_SETPALETTE: /* set color palette */
+ case FBIOGETCMAP: /* get color palette */
+ case FBIOPUTCMAP: /* set color palette */
+ return ENODEV;
+
+ case FBIOGTYPE: /* get frame buffer type info. */
+ ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type);
+ ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height;
+ ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width;
+ ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth;
+ if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8))
+ ((struct fbtype *)arg)->fb_cmsize = 0;
+ else
+ ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth;
+ ((struct fbtype *)arg)->fb_size = adp->va_buffer_size;
+ return 0;
+
+ default:
+ return fb_commonioctl(adp, cmd, arg);
+ }
+}
+
+static void
+dump_buffer(u_char *buf, size_t len)
+{
+ int i;
+
+ for(i = 0; i < len;) {
+ printf("%02x ", buf[i]);
+ if ((++i % 16) == 0)
+ printf("\n");
+ }
}
/*
@@ -894,8 +1087,8 @@ gdc_diag(video_adapter_t *adp, int level)
int i;
#endif
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
fb_dump_adp_info(DRIVER_NAME, adp, level);
@@ -912,10 +1105,4 @@ gdc_diag(video_adapter_t *adp, int level)
return 0;
}
-static int
-gdc_err(video_adapter_t *adp, ...)
-{
- return 0;
-}
-
#endif /* NGDC > 0 */
diff --git a/sys/pc98/cbus/sc_machdep.h b/sys/pc98/cbus/sc_machdep.h
new file mode 100644
index 0000000..59cdf56
--- /dev/null
+++ b/sys/pc98/cbus/sc_machdep.h
@@ -0,0 +1,61 @@
+/*-
+ * $Id: $
+ */
+
+#ifndef _PC98_PC98_SC_MACHDEP_H_
+#define _PC98_PC98_SC_MACHDEP_H_
+
+#undef SC_ALT_MOUSE_IMAGE
+#undef SC_DFLT_FONT
+#undef SC_MOUSE_CHAR
+#undef SC_PIXEL_MODE
+#undef SC_NO_FONT_LOADING
+#define SC_NO_FONT_LOADING 1
+#undef SC_NO_PALETTE_LOADING
+#define SC_NO_PALETTE_LOADING 1
+
+#ifndef SC_KERNEL_CONS_ATTR
+#define SC_KERNEL_CONS_ATTR (FG_LIGHTGREY | BG_BLACK)
+#endif
+
+#define KANJI 1
+
+#define BELL_DURATION 5
+#define BELL_PITCH_8M 1339
+#define BELL_PITCH_5M 1678
+
+#define UJIS 0
+#define SJIS 1
+
+#define PRINTABLE(c) ((c) > 0x1b || ((c) > 0x0f && (c) < 0x1b) \
+ || (c) < 0x07)
+
+#define ISMOUSEAVAIL(af) (1)
+#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
+#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE)
+
+#ifdef KANJI
+
+#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee))
+#define IS_KTYPE_KANA(A) ((A) & 0x11)
+#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0)
+
+#define _SCR_MD_STAT_DECLARED_
+typedef struct {
+ u_char kanji_1st_char;
+ u_char kanji_type;
+#define KTYPE_ASCII 0 /* ASCII */
+#define KTYPE_KANA 1 /* HANKAKU */
+#define KTYPE_JKANA 0x10 /* JIS HANKAKU */
+#define KTYPE_7JIS 0x20 /* JIS */
+#define KTYPE_SJIS 2 /* Shift JIS */
+#define KTYPE_UJIS 4 /* UJIS */
+#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */
+#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */
+#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */
+#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */
+} scr_md_stat_t;
+
+#endif /* KANJI */
+
+#endif /* !_PC98_PC98_SC_MACHDEP_H_ */
diff --git a/sys/pc98/cbus/scgdcrndr.c b/sys/pc98/cbus/scgdcrndr.c
new file mode 100644
index 0000000..e1ce7b8
--- /dev/null
+++ b/sys/pc98/cbus/scgdcrndr.c
@@ -0,0 +1,180 @@
+/*-
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "gdc.h"
+#include "opt_syscons.h"
+#include "opt_gdc.h"
+
+#if NSC > 0 && NGDC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#ifndef SC_RENDER_DEBUG
+#define SC_RENDER_DEBUG 0
+#endif
+
+static vr_clear_t gdc_txtclear;
+static vr_draw_border_t gdc_txtborder;
+static vr_draw_t gdc_txtdraw;
+static vr_set_cursor_t gdc_txtcursor_shape;
+static vr_draw_cursor_t gdc_txtcursor;
+#ifndef SC_NO_CUTPASTE
+static vr_draw_mouse_t gdc_txtmouse;
+#else
+#define gdc_txtmouse (vr_draw_mouse_t *)gdc_nop
+#endif
+
+#ifndef SC_NO_MODE_CHANGE
+static vr_draw_border_t gdc_grborder;
+#endif
+
+static void gdc_nop(scr_stat *scp, ...);
+
+static sc_rndr_sw_t txtrndrsw = {
+ gdc_txtclear,
+ gdc_txtborder,
+ gdc_txtdraw,
+ gdc_txtcursor_shape,
+ gdc_txtcursor,
+ (vr_blink_cursor_t *)gdc_nop,
+ (vr_set_mouse_t *)gdc_nop,
+ gdc_txtmouse,
+};
+RENDERER(gdc, 0, txtrndrsw);
+
+#ifndef SC_NO_MODE_CHANGE
+static sc_rndr_sw_t grrndrsw = {
+ (vr_clear_t *)gdc_nop,
+ gdc_grborder,
+ (vr_draw_t *)gdc_nop,
+ (vr_set_cursor_t *)gdc_nop,
+ (vr_draw_cursor_t *)gdc_nop,
+ (vr_blink_cursor_t *)gdc_nop,
+ (vr_set_mouse_t *)gdc_nop,
+ (vr_draw_mouse_t *)gdc_nop,
+};
+RENDERER(gdc, GRAPHICS_MODE, grrndrsw);
+#endif /* SC_NO_MODE_CHANGE */
+
+static void
+gdc_nop(scr_stat *scp, ...)
+{
+}
+
+/* text mode renderer */
+
+static void
+gdc_txtclear(scr_stat *scp, int c, int attr)
+{
+ sc_vtb_clear(&scp->scr, c, attr);
+}
+
+static void
+gdc_txtborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+static void
+gdc_txtdraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t p;
+ int c;
+ int a;
+
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+
+ if (flip) {
+ p = sc_vtb_pointer(&scp->scr, from);
+ for (; count-- > 0; ++from) {
+ c = sc_vtb_getc(&scp->vtb, from);
+ a = sc_vtb_geta(&scp->vtb, from) ^ 0x4;
+ sc_vtb_putchar(&scp->scr, p, c, a);
+ }
+ } else {
+ sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
+ }
+}
+
+static void
+gdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
+{
+ if (base < 0 || base >= scp->font_size)
+ return;
+ /* the caller may set height <= 0 in order to disable the cursor */
+ (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
+ base, height,
+ scp->font_size, blink);
+}
+
+static void
+gdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
+{
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
+ at%scp->xsize, at/scp->xsize);
+ } else {
+ if (scp->status & VR_CURSOR_ON)
+ (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
+ -1, -1);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+}
+
+#ifndef SC_NO_CUTPASTE
+
+static void
+draw_txtmouse(scr_stat *scp, int x, int y)
+{
+ int at;
+
+ at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ sc_vtb_putc(&scp->scr, at,
+ sc_vtb_getc(&scp->scr, at),
+ sc_vtb_geta(&scp->scr, at) ^ 0x4);
+}
+
+static void
+remove_txtmouse(scr_stat *scp, int x, int y)
+{
+}
+
+static void
+gdc_txtmouse(scr_stat *scp, int x, int y, int on)
+{
+ if (on)
+ draw_txtmouse(scp, x, y);
+ else
+ remove_txtmouse(scp, x, y);
+}
+
+#endif /* SC_NO_CUTPASTE */
+
+#ifndef SC_NO_MODE_CHANGE
+
+/* graphics mode renderer */
+
+static void
+gdc_grborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+#endif /* SC_NO_MODE_CHANGE */
+
+#endif /* NSC > 0 && NGDC > 0 */
diff --git a/sys/pc98/cbus/scvtb.c b/sys/pc98/cbus/scvtb.c
new file mode 100644
index 0000000..64f4cb6
--- /dev/null
+++ b/sys/pc98/cbus/scvtb.c
@@ -0,0 +1,364 @@
+/*-
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#define ATTR_OFFSET 0x2000
+
+#define vtb_wrap(vtb, at, offset) \
+ (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
+
+static u_int16_t at2pc98(u_int16_t attr);
+static vm_offset_t sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
+
+static u_int16_t
+at2pc98(u_int16_t attr)
+{
+ static u_char ibmpc_to_pc98[16] = {
+ 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
+ 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
+ };
+ static u_char ibmpc_to_pc98rev[16] = {
+ 0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5,
+ 0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
+ };
+ u_char fg_at, bg_at;
+ u_int16_t at;
+
+ if (attr & 0x00FF)
+ return (attr);
+
+ fg_at = ((attr >> 8) & 0x0F);
+ bg_at = ((attr >> 12) & 0x0F);
+
+ if (bg_at) {
+ if (bg_at & 0x08) {
+ if (bg_at & 0x07) {
+ /* reverse & blink */
+ at = ibmpc_to_pc98rev[bg_at] | 0x02;
+ } else {
+ /* normal & blink */
+ at = ibmpc_to_pc98[fg_at] | 0x02;
+ }
+ } else {
+ /* reverse */
+ at = ibmpc_to_pc98rev[bg_at];
+ }
+ } else {
+ /* normal */
+ at = ibmpc_to_pc98[fg_at];
+ }
+ at |= attr;
+ return (at);
+}
+
+void
+sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
+{
+ vtb->vtb_flags = 0;
+ vtb->vtb_type = type;
+ vtb->vtb_cols = cols;
+ vtb->vtb_rows = rows;
+ vtb->vtb_size = cols*rows;
+ vtb->vtb_buffer = NULL;
+ vtb->vtb_tail = 0;
+
+ switch (type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if ((buf == NULL) && (cols*rows != 0)) {
+ vtb->vtb_buffer =
+ (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
+ M_DEVBUF,
+ (wait) ? M_WAITOK : M_NOWAIT);
+ if (vtb->vtb_buffer != NULL) {
+ bzero((void *)sc_vtb_pointer(vtb, 0),
+ cols*rows*sizeof(u_int16_t)*2);
+ }
+ } else {
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ }
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ case VTB_FRAMEBUFFER:
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+sc_vtb_destroy(sc_vtb_t *vtb)
+{
+ vm_offset_t p;
+
+ vtb->vtb_flags = 0;
+ vtb->vtb_cols = 0;
+ vtb->vtb_rows = 0;
+ vtb->vtb_size = 0;
+ vtb->vtb_tail = 0;
+
+ p = vtb->vtb_buffer;
+ vtb->vtb_buffer = NULL;
+ switch (vtb->vtb_type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if (p != NULL)
+ free((void *)p, M_DEVBUF);
+ break;
+ default:
+ break;
+ }
+ vtb->vtb_type = VTB_INVALID;
+}
+
+size_t
+sc_vtb_size(int cols, int rows)
+{
+ return (size_t)(cols*rows*sizeof(u_int16_t)*2);
+}
+
+int
+sc_vtb_getc(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
+ else
+ return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
+}
+
+int
+sc_vtb_geta(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
+ else
+ return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
+}
+
+void
+sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ writew(sc_vtb_pointer(vtb, at), c);
+ writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
+ } else {
+ *(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
+ *(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
+ }
+}
+
+vm_offset_t
+sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ writew(p, c);
+ writew(p + ATTR_OFFSET, at2pc98(a));
+ } else {
+ *(u_int16_t *)p = c;
+ *(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
+ }
+ return (p + sizeof(u_int16_t));
+}
+
+vm_offset_t
+sc_vtb_pointer(sc_vtb_t *vtb, int at)
+{
+ return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
+}
+
+static vm_offset_t
+sc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
+{
+ return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
+ + ((vtb->vtb_type == VTB_FRAMEBUFFER) ?
+ ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
+}
+
+int
+sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
+{
+ return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
+}
+
+void
+sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+ fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+ fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
+ }
+}
+
+void
+sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
+{
+ if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_toio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
+ (void *)sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ }
+}
+
+void
+sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
+{
+ int len;
+
+ if (vtb2->vtb_type != VTB_RINGBUFFER)
+ return;
+
+ while (count > 0) {
+ len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
+ if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
+ (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ }
+ from += len;
+ count -= len;
+ vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
+ }
+}
+
+void
+sc_vtb_seek(sc_vtb_t *vtb, int pos)
+{
+ vtb->vtb_tail = pos%vtb->vtb_size;
+}
+
+void
+sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at), count);
+ fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
+ fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
+ }
+}
+
+void
+sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ int len;
+
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ len = vtb->vtb_size - at - count;
+ if (len > 0) {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at + count),
+ sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
+ sc_vtb_attr_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at + count),
+ (void *)sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
+ (void *)sc_vtb_attr_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ fillw_io(at2pc98(attr),
+ sc_vtb_attr_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ fillw(at2pc98(attr),
+ (void *)sc_vtb_attr_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ }
+}
+
+void
+sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size) {
+ count = vtb->vtb_size - at;
+ } else {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at),
+ sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ bcopy_io(sc_vtb_attr_pointer(vtb, at),
+ sc_vtb_attr_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at),
+ (void *)sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb, at),
+ (void *)sc_vtb_attr_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at), count);
+ fillw_io(at2pc98(attr),
+ sc_vtb_attr_pointer(vtb, at), count);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
+ fillw(at2pc98(attr),
+ (void *)sc_vtb_attr_pointer(vtb, at), count);
+ }
+}
+
+#endif /* NSC */
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index c09af65..40fdd2c 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sio.c,v 1.96 1999/05/11 08:38:28 kato Exp $
+ * $Id: sio.c,v 1.97 1999/05/30 16:53:22 phk Exp $
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* from: i386/isa sio.c,v 1.234
*/
@@ -3931,7 +3931,7 @@ static cn_checkc_t siocncheckc;
static cn_getc_t siocngetc;
static cn_putc_t siocnputc;
-CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc);
/* To get the GDB related variables */
#if DDB > 0
diff --git a/sys/pc98/cbus/syscons_cbus.c b/sys/pc98/cbus/syscons_cbus.c
new file mode 100644
index 0000000..5bca2d0
--- /dev/null
+++ b/sys/pc98/cbus/syscons_cbus.c
@@ -0,0 +1,193 @@
+/*-
+ * $Id: $
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/cons.h>
+#include <machine/console.h>
+#include <machine/clock.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <dev/syscons/syscons.h>
+
+#include <i386/isa/timerreg.h>
+
+#include <isa/isavar.h>
+
+static devclass_t sc_devclass;
+
+static int scprobe(device_t dev);
+static int scattach(device_t dev);
+static int scresume(device_t dev);
+
+static device_method_t sc_methods[] = {
+ DEVMETHOD(device_probe, scprobe),
+ DEVMETHOD(device_attach, scattach),
+ DEVMETHOD(device_resume, scresume),
+ { 0, 0 }
+};
+
+static driver_t sc_driver = {
+ SC_DRIVER_NAME,
+ sc_methods,
+ 1, /* XXX */
+};
+
+static sc_softc_t main_softc = { 0, 0, 0, -1, NULL, -1, NULL, };
+
+static int
+scprobe(device_t dev)
+{
+ /* No pnp support */
+ if (isa_get_vendorid(dev))
+ return (ENXIO);
+
+ device_set_desc(dev, "System console");
+ return sc_probe_unit(device_get_unit(dev), isa_get_flags(dev));
+}
+
+static int
+scattach(device_t dev)
+{
+ return sc_attach_unit(device_get_unit(dev), isa_get_flags(dev));
+}
+
+static int
+scresume(device_t dev)
+{
+ return sc_resume_unit(device_get_unit(dev));
+}
+
+int
+sc_max_unit(void)
+{
+ return devclass_get_maxunit(sc_devclass);
+}
+
+sc_softc_t
+*sc_get_softc(int unit, int flags)
+{
+ sc_softc_t *sc;
+
+ if ((unit < 0) || (unit >= NSC))
+ return NULL;
+ if (flags & SC_KERNEL_CONSOLE) {
+ /* FIXME: clear if it is wired to another unit! */
+ main_softc.unit = unit;
+ return &main_softc;
+ } else {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, unit);
+ if (!(sc->flags & SC_INIT_DONE)) {
+ sc->unit = unit;
+ sc->keyboard = -1;
+ sc->adapter = -1;
+ }
+ return sc;
+ }
+}
+
+sc_softc_t
+*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
+{
+ sc_softc_t *sc;
+ int units;
+ int i;
+
+ sc = &main_softc;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ units = devclass_get_maxunit(sc_devclass);
+ for (i = 0; i < units; ++i) {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, i);
+ if (sc == NULL)
+ continue;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ }
+ return NULL;
+}
+
+int
+sc_get_cons_priority(int *unit, int *flags)
+{
+ int disabled;
+ int u, f;
+ int i;
+
+ *unit = -1;
+ for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) {
+ u = resource_query_unit(i);
+ if ((resource_int_value(SC_DRIVER_NAME, u, "disabled",
+ &disabled) == 0) && disabled)
+ continue;
+ if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
+ f = 0;
+ if (f & SC_KERNEL_CONSOLE) {
+ /* the user designates this unit to be the console */
+ *unit = u;
+ *flags = f;
+ break;
+ }
+ if (*unit < 0) {
+ /* ...otherwise remember the first found unit */
+ *unit = u;
+ *flags = f;
+ }
+ }
+ if ((i < 0) && (*unit < 0))
+ return CN_DEAD;
+ return CN_INTERNAL;
+}
+
+void
+sc_get_bios_values(bios_values_t *values)
+{
+ values->cursor_start = 0;
+ values->cursor_end = 16;
+ values->shift_state = 0;
+ if (pc98_machine_type & M_8M)
+ values->bell_pitch = BELL_PITCH_8M;
+ else
+ values->bell_pitch = BELL_PITCH_5M;
+}
+
+int
+sc_tone(int herz)
+{
+ int pitch;
+
+ if (herz) {
+ /* enable counter 1 */
+ outb(0x35, inb(0x35) & 0xf7);
+ /* set command for counter 1, 2 byte write */
+ if (acquire_timer1(TIMER_16BIT | TIMER_SQWAVE))
+ return EBUSY;
+ /* set pitch */
+ pitch = timer_freq/herz;
+ outb(TIMER_CNTR1, pitch);
+ outb(TIMER_CNTR1, pitch >> 8);
+ } else {
+ /* disable counter 1 */
+ outb(0x35, inb(0x35) | 0x08);
+ release_timer1();
+ }
+ return 0;
+}
+
+DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
+
+#endif /* NSC > 0 */
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index 3943b78..2bcc99b 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.98 1999/06/18 14:48:19 kato Exp $
+# $Id: files.pc98,v 1.99 1999/06/21 11:11:39 kato Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -21,11 +21,6 @@ linux_assym.h optional compat_linux \
no-obj no-implicit-rule before-depend \
clean "linux_assym.h"
#
-font8x16.o optional std8x16font \
- compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \
- no-implicit-rule before-depend \
- clean "${STD8X16FONT}-8x16 font8x16.c"
-#
atkbdmap.h optional atkbd_dflt_keymap \
compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \
no-obj no-implicit-rule before-depend \
@@ -280,7 +275,12 @@ i386/isa/spigot.c optional spigot device-driver
pc98/pc98/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
pc98/pc98/syscons.c optional sc device-driver
-pc98/pc98/scvidctl.c optional sc device-driver
+pc98/pc98/syscons_pc98.c optional sc device-driver
+dev/syscons/schistory.c optional sc device-driver
+dev/syscons/scmouse.c optional sc device-driver
+pc98/pc98/scgdcrndr.c optional sc device-driver
+dev/syscons/scvidctl.c optional sc device-driver
+pc98/pc98/scvtbpc98.c optional sc device-driver
i386/isa/tw.c optional tw device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
diff --git a/sys/pc98/pc98/pc98gdc.c b/sys/pc98/pc98/pc98gdc.c
index a6efd2a..e98f35e 100644
--- a/sys/pc98/pc98/pc98gdc.c
+++ b/sys/pc98/pc98/pc98gdc.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pc98gdc.c,v 1.8 1999/05/09 04:56:42 kato Exp $
+ * $Id: pc98gdc.c,v 1.9 1999/05/30 16:53:20 phk Exp $
*/
#include "gdc.h"
@@ -72,7 +72,7 @@ typedef struct gdc_softc {
#define GDC_SOFTC(unit) \
((gdc_softc_t *)devclass_get_softc(gdc_devclass, unit))
-devclass_t gdc_devclass;
+static devclass_t gdc_devclass;
static int gdcprobe(device_t dev);
static int gdc_attach(device_t dev);
@@ -99,13 +99,15 @@ static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
static d_open_t gdcopen;
static d_close_t gdcclose;
static d_read_t gdcread;
+static d_write_t gdcwrite;
static d_ioctl_t gdcioctl;
+static d_mmap_t gdcmmap;
static struct cdevsw vga_cdevsw = {
/* open */ gdcopen,
/* close */ gdcclose,
- /* read */ noread,
- /* write */ nowrite,
+ /* read */ gdcread,
+ /* write */ gdcwrite,
/* ioctl */ gdcioctl,
/* stop */ nostop,
/* reset */ noreset,
@@ -139,9 +141,24 @@ static int
gdc_attach(device_t dev)
{
gdc_softc_t *sc;
+ int error;
sc = device_get_softc(dev);
- return gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
+ error = gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
+ if (error)
+ return error;
+
+#ifdef FB_INSTALL_CDEV
+ /* attach a virtual frame buffer device */
+ error = fb_attach(makedev(0, GDC_MKMINOR(unit)), sc->adp, &gdc_cdevsw);
+ if (error)
+ return error;
+#endif /* FB_INSTALL_CDEV */
+
+ if (bootverbose)
+ (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose);
+
+ return 0;
}
static int
@@ -152,7 +169,7 @@ gdc_probe_unit(int unit, gdc_softc_t *sc, int flags)
bzero(sc, sizeof(*sc));
sw = vid_get_switch(DRIVER_NAME);
if (sw == NULL)
- return 0;
+ return ENXIO;
return (*sw->probe)(unit, &sc->adp, NULL, flags);
}
@@ -160,30 +177,78 @@ static int
gdc_attach_unit(int unit, gdc_softc_t *sc, int flags)
{
video_switch_t *sw;
- int error;
sw = vid_get_switch(DRIVER_NAME);
if (sw == NULL)
return ENXIO;
+ return (*sw->init)(unit, sc->adp, flags);
+}
- error = (*sw->init)(unit, sc->adp, flags);
- if (error)
- return ENXIO;
+/* cdev driver functions */
#ifdef FB_INSTALL_CDEV
- /* attach a virtual frame buffer device */
- error = fb_attach(makedev(0, GDC_MKMINOR(unit)), scp->adp,
- &vga_cdevsw);
- if (error)
- return error;
-#endif /* FB_INSTALL_CDEV */
- if (bootverbose)
- (*sw->diag)(sc->adp, bootverbose);
+static int
+gdcopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ gdc_softc_t *sc;
- return 0;
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+ if (mode & (O_CREAT | O_APPEND | O_TRUNC))
+ return ENODEV;
+
+ return genfbopen(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+static int
+gdcclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbclose(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+static int
+gdcread(dev_t dev, struct uio *uio, int flag)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+static int
+gdcwrite(dev_t dev, struct uio *uio, int flag)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+static int
+gdcioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, p);
}
+static int
+gdcmmap(dev_t dev, vm_offset_t offset, int prot)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbmmap(&sc->gensc, sc->adp, offset, prot);
+}
+
+#endif /* FB_INSTALL_CDEV */
+
/* LOW-LEVEL */
#include <machine/clock.h>
@@ -213,7 +278,7 @@ static video_adapter_t adapter_init_value[] = {
V_ADP_COLOR | V_ADP_MODECHANGE | V_ADP_BORDER,
IO_GDC1, 16, TEXT_GDC, /* va_io*, XXX */
VIDEO_BUF_BASE, VIDEO_BUF_SIZE, /* va_mem* */
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, /* va_window* */
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, /* va_window* */
0, 0, /* va_buffer, va_buffer_size */
0, M_PC98_80x25, 0, /* va_*mode* */
},
@@ -224,6 +289,7 @@ static video_adapter_t biosadapter[1];
/* video driver declarations */
static int gdc_configure(int flags);
static int gdc_nop(void);
+static int gdc_err(video_adapter_t *adp, ...);
static vi_probe_t gdc_probe;
static vi_init_t gdc_init;
static vi_get_info_t gdc_get_info;
@@ -235,11 +301,11 @@ static vi_load_state_t gdc_load_state;
static vi_read_hw_cursor_t gdc_read_hw_cursor;
static vi_set_hw_cursor_t gdc_set_hw_cursor;
static vi_set_hw_cursor_shape_t gdc_set_hw_cursor_shape;
-static vi_mmap_t gdc_mmap;
+static vi_blank_display_t gdc_blank_display;
+static vi_mmap_t gdc_mmap_buf;
+static vi_ioctl_t gdc_dev_ioctl;
static vi_diag_t gdc_diag;
-static int gdc_err(video_adapter_t *adp, ...);
-
static video_switch_t gdcvidsw = {
gdc_probe,
gdc_init,
@@ -258,8 +324,14 @@ static video_switch_t gdcvidsw = {
gdc_read_hw_cursor,
gdc_set_hw_cursor,
gdc_set_hw_cursor_shape,
- (vi_blank_display_t *)gdc_nop,
- gdc_mmap,
+ gdc_blank_display,
+ gdc_mmap_buf,
+ gdc_dev_ioctl,
+ (vi_clear_t *)gdc_err,
+ (vi_fill_rect_t *)gdc_err,
+ (vi_bitblt_t *)gdc_err,
+ (int (*)(void))gdc_err,
+ (int (*)(void))gdc_err,
gdc_diag,
};
@@ -271,15 +343,15 @@ VIDEO_DRIVER(gdc, gdcvidsw, gdc_configure);
static video_info_t bios_vmode[] = {
{ M_PC98_80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
#ifdef LINE30
{ M_PC98_80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
#endif
{ EOT },
};
-static int init_done = FALSE;
+static int gdc_init_done = FALSE;
/* local functions */
static int map_gen_mode_num(int type, int color, int mode);
@@ -287,7 +359,7 @@ static int probe_adapters(void);
static void dump_buffer(u_char *buf, size_t len);
#define prologue(adp, flag, err) \
- if (!init_done || !((adp)->va_flags & (flag))) \
+ if (!gdc_init_done || !((adp)->va_flags & (flag))) \
return (err)
/* a backdoor for the console driver */
@@ -336,9 +408,9 @@ probe_adapters(void)
video_info_t info;
/* do this test only once */
- if (init_done)
+ if (gdc_init_done)
return 1;
- init_done = TRUE;
+ gdc_init_done = TRUE;
biosadapter[0] = adapter_init_value[0];
biosadapter[0].va_flags |= V_ADP_PROBED;
@@ -547,6 +619,12 @@ gdc_nop(void)
}
static int
+gdc_err(video_adapter_t *adp, ...)
+{
+ return ENODEV;
+}
+
+static int
gdc_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
{
probe_adapters();
@@ -587,8 +665,8 @@ gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
{
int i;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode);
for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
@@ -596,10 +674,11 @@ gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
continue;
if (mode == bios_vmode[i].vi_mode) {
*info = bios_vmode[i];
+ info->vi_buffer_size = info->vi_window_size*info->vi_planes;
return 0;
}
}
- return 1;
+ return EINVAL;
}
/*
@@ -614,7 +693,7 @@ gdc_query_mode(video_adapter_t *adp, video_info_t *info)
video_info_t buf;
int i;
- if (!init_done)
+ if (!gdc_init_done)
return -1;
for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
@@ -661,16 +740,16 @@ gdc_set_mode(video_adapter_t *adp, int mode)
{
video_info_t info;
- prologue(adp, V_ADP_MODECHANGE, 1);
+ prologue(adp, V_ADP_MODECHANGE, ENODEV);
mode = map_gen_mode_num(adp->va_type,
adp->va_flags & V_ADP_COLOR, mode);
if (gdc_get_info(adp, mode, &info))
- return 1;
+ return EINVAL;
#ifdef LINE30
switch (info.vi_mode) {
- case M_PC98_80x25: /* VGA TEXT MODES */
+ case M_PC98_80x25: /* GDC TEXT MODES */
initialize_gdc(T25_G400);
break;
case M_PC98_80x30:
@@ -744,7 +823,7 @@ gdc_set_border(video_adapter_t *adp, int color)
static int
gdc_save_state(video_adapter_t *adp, void *p, size_t size)
{
- return 1;
+ return ENODEV;
}
/*
@@ -754,7 +833,7 @@ gdc_save_state(video_adapter_t *adp, void *p, size_t size)
static int
gdc_load_state(video_adapter_t *adp, void *p)
{
- return 1;
+ return ENODEV;
}
/*
@@ -767,11 +846,11 @@ gdc_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
u_int16_t off;
int s;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
+ return ENODEV;
s = spltty();
master_gdc_cmd(0xe0); /* _GDC_CSRR */
@@ -802,14 +881,30 @@ gdc_set_hw_cursor(video_adapter_t *adp, int col, int row)
u_int16_t off;
int s;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
if ((col == -1) && (row == -1)) {
off = -1;
+ /* XXX */
+ if (epson_machine_id == 0x20) {
+ s = spltty();
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ splx(s);
+ }
} else {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
+ return ENODEV;
+ /* XXX */
+ if (epson_machine_id == 0x20) {
+ s = spltty();
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ splx(s);
+ }
off = row*adp->va_info.vi_width + col;
}
@@ -834,6 +929,9 @@ gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
int end;
int s;
+ if (!gdc_init_done)
+ return ENXIO;
+
start = celsize - (base + height);
end = celsize - base - 1;
/*
@@ -846,28 +944,76 @@ gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
--end;
s = spltty();
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ if (height > 0)
+ outb(0x0c17, inb(0xc17) | 0x08);
+ else
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
master_gdc_cmd(0x4b); /* _GDC_CSRFORM */
master_gdc_prm(((height > 0) ? 0x80 : 0) /* cursor on/off */
- | (celsize - 1) & 0x1f); /* cel size */
+ | ((celsize - 1) & 0x1f)); /* cel size */
master_gdc_word_prm(((end & 0x1f) << 11) /* end line */
| (12 << 6) /* blink rate */
| (blink ? 0x20 : 0) /* blink on/off */
| (start & 0x1f)); /* start line */
splx(s);
- return 1;
+ return 0;
}
-static void
-dump_buffer(u_char *buf, size_t len)
+/*
+ * blank_display()
+ * Put the display in power save/power off mode.
+ */
+static int
+gdc_blank_display(video_adapter_t *adp, int mode)
{
- int i;
+ int s;
- for(i = 0; i < len;) {
- printf("%02x ", buf[i]);
- if ((++i % 16) == 0)
- printf("\n");
+ if (!gdc_init_done)
+ return ENXIO;
+
+ s = splhigh();
+ switch (mode) {
+ case V_DISPLAY_SUSPEND:
+ case V_DISPLAY_STAND_BY:
+ /*
+ * FIXME: I don't know how to put the display into `suspend'
+ * or `stand-by' mode via GDC...
+ */
+ /* FALL THROUGH */
+
+ case V_DISPLAY_BLANK:
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ outb(0xc17, inb(0xc17) & ~0x08);
+ outb(0xc16, inb(0xc16) & ~0x02);
+ outb(0x43f, 0x40);
+ } else {
+ while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
+ ;
+ outb(TEXT_GDC + 2, 0xc); /* text off */
+ }
+ break;
+
+ case V_DISPLAY_ON:
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ outb(0xc17, inb(0xc17) | 0x08);
+ outb(0xc16, inb(0xc16) | 0x02);
+ outb(0x43f, 0x40);
+ } else {
+ while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
+ ;
+ outb(TEXT_GDC + 2, 0xd); /* text on */
+ }
+ break;
}
+ splx(s);
+ return 0;
}
/*
@@ -875,11 +1021,58 @@ dump_buffer(u_char *buf, size_t len)
* Mmap frame buffer.
*/
static int
-gdc_mmap(video_adapter_t *adp, vm_offset_t offset)
+gdc_mmap_buf(video_adapter_t *adp, vm_offset_t offset, int prot)
{
- if (offset > 0x48000 - PAGE_SIZE)
+ /* FIXME: is this correct? XXX */
+ if (offset > VIDEO_BUF_SIZE - PAGE_SIZE)
return -1;
- return i386_btop((VIDEO_BUF_BASE + offset));
+ return i386_btop(adp->va_info.vi_window + offset);
+}
+
+static int
+gdc_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
+{
+ switch (cmd) {
+ case FBIO_GETWINORG: /* get frame buffer window origin */
+ *(u_int *)arg = 0;
+ return 0;
+
+ case FBIO_SETWINORG: /* set frame buffer window origin */
+ case FBIO_SETDISPSTART: /* set display start address */
+ case FBIO_SETLINEWIDTH: /* set scan line length in pixel */
+ case FBIO_GETPALETTE: /* get color palette */
+ case FBIO_SETPALETTE: /* set color palette */
+ case FBIOGETCMAP: /* get color palette */
+ case FBIOPUTCMAP: /* set color palette */
+ return ENODEV;
+
+ case FBIOGTYPE: /* get frame buffer type info. */
+ ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type);
+ ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height;
+ ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width;
+ ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth;
+ if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8))
+ ((struct fbtype *)arg)->fb_cmsize = 0;
+ else
+ ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth;
+ ((struct fbtype *)arg)->fb_size = adp->va_buffer_size;
+ return 0;
+
+ default:
+ return fb_commonioctl(adp, cmd, arg);
+ }
+}
+
+static void
+dump_buffer(u_char *buf, size_t len)
+{
+ int i;
+
+ for(i = 0; i < len;) {
+ printf("%02x ", buf[i]);
+ if ((++i % 16) == 0)
+ printf("\n");
+ }
}
/*
@@ -894,8 +1087,8 @@ gdc_diag(video_adapter_t *adp, int level)
int i;
#endif
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
fb_dump_adp_info(DRIVER_NAME, adp, level);
@@ -912,10 +1105,4 @@ gdc_diag(video_adapter_t *adp, int level)
return 0;
}
-static int
-gdc_err(video_adapter_t *adp, ...)
-{
- return 0;
-}
-
#endif /* NGDC > 0 */
diff --git a/sys/pc98/pc98/sc_machdep.h b/sys/pc98/pc98/sc_machdep.h
new file mode 100644
index 0000000..59cdf56
--- /dev/null
+++ b/sys/pc98/pc98/sc_machdep.h
@@ -0,0 +1,61 @@
+/*-
+ * $Id: $
+ */
+
+#ifndef _PC98_PC98_SC_MACHDEP_H_
+#define _PC98_PC98_SC_MACHDEP_H_
+
+#undef SC_ALT_MOUSE_IMAGE
+#undef SC_DFLT_FONT
+#undef SC_MOUSE_CHAR
+#undef SC_PIXEL_MODE
+#undef SC_NO_FONT_LOADING
+#define SC_NO_FONT_LOADING 1
+#undef SC_NO_PALETTE_LOADING
+#define SC_NO_PALETTE_LOADING 1
+
+#ifndef SC_KERNEL_CONS_ATTR
+#define SC_KERNEL_CONS_ATTR (FG_LIGHTGREY | BG_BLACK)
+#endif
+
+#define KANJI 1
+
+#define BELL_DURATION 5
+#define BELL_PITCH_8M 1339
+#define BELL_PITCH_5M 1678
+
+#define UJIS 0
+#define SJIS 1
+
+#define PRINTABLE(c) ((c) > 0x1b || ((c) > 0x0f && (c) < 0x1b) \
+ || (c) < 0x07)
+
+#define ISMOUSEAVAIL(af) (1)
+#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
+#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE)
+
+#ifdef KANJI
+
+#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee))
+#define IS_KTYPE_KANA(A) ((A) & 0x11)
+#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0)
+
+#define _SCR_MD_STAT_DECLARED_
+typedef struct {
+ u_char kanji_1st_char;
+ u_char kanji_type;
+#define KTYPE_ASCII 0 /* ASCII */
+#define KTYPE_KANA 1 /* HANKAKU */
+#define KTYPE_JKANA 0x10 /* JIS HANKAKU */
+#define KTYPE_7JIS 0x20 /* JIS */
+#define KTYPE_SJIS 2 /* Shift JIS */
+#define KTYPE_UJIS 4 /* UJIS */
+#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */
+#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */
+#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */
+#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */
+} scr_md_stat_t;
+
+#endif /* KANJI */
+
+#endif /* !_PC98_PC98_SC_MACHDEP_H_ */
diff --git a/sys/pc98/pc98/scgdcrndr.c b/sys/pc98/pc98/scgdcrndr.c
new file mode 100644
index 0000000..e1ce7b8
--- /dev/null
+++ b/sys/pc98/pc98/scgdcrndr.c
@@ -0,0 +1,180 @@
+/*-
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "gdc.h"
+#include "opt_syscons.h"
+#include "opt_gdc.h"
+
+#if NSC > 0 && NGDC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#ifndef SC_RENDER_DEBUG
+#define SC_RENDER_DEBUG 0
+#endif
+
+static vr_clear_t gdc_txtclear;
+static vr_draw_border_t gdc_txtborder;
+static vr_draw_t gdc_txtdraw;
+static vr_set_cursor_t gdc_txtcursor_shape;
+static vr_draw_cursor_t gdc_txtcursor;
+#ifndef SC_NO_CUTPASTE
+static vr_draw_mouse_t gdc_txtmouse;
+#else
+#define gdc_txtmouse (vr_draw_mouse_t *)gdc_nop
+#endif
+
+#ifndef SC_NO_MODE_CHANGE
+static vr_draw_border_t gdc_grborder;
+#endif
+
+static void gdc_nop(scr_stat *scp, ...);
+
+static sc_rndr_sw_t txtrndrsw = {
+ gdc_txtclear,
+ gdc_txtborder,
+ gdc_txtdraw,
+ gdc_txtcursor_shape,
+ gdc_txtcursor,
+ (vr_blink_cursor_t *)gdc_nop,
+ (vr_set_mouse_t *)gdc_nop,
+ gdc_txtmouse,
+};
+RENDERER(gdc, 0, txtrndrsw);
+
+#ifndef SC_NO_MODE_CHANGE
+static sc_rndr_sw_t grrndrsw = {
+ (vr_clear_t *)gdc_nop,
+ gdc_grborder,
+ (vr_draw_t *)gdc_nop,
+ (vr_set_cursor_t *)gdc_nop,
+ (vr_draw_cursor_t *)gdc_nop,
+ (vr_blink_cursor_t *)gdc_nop,
+ (vr_set_mouse_t *)gdc_nop,
+ (vr_draw_mouse_t *)gdc_nop,
+};
+RENDERER(gdc, GRAPHICS_MODE, grrndrsw);
+#endif /* SC_NO_MODE_CHANGE */
+
+static void
+gdc_nop(scr_stat *scp, ...)
+{
+}
+
+/* text mode renderer */
+
+static void
+gdc_txtclear(scr_stat *scp, int c, int attr)
+{
+ sc_vtb_clear(&scp->scr, c, attr);
+}
+
+static void
+gdc_txtborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+static void
+gdc_txtdraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t p;
+ int c;
+ int a;
+
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+
+ if (flip) {
+ p = sc_vtb_pointer(&scp->scr, from);
+ for (; count-- > 0; ++from) {
+ c = sc_vtb_getc(&scp->vtb, from);
+ a = sc_vtb_geta(&scp->vtb, from) ^ 0x4;
+ sc_vtb_putchar(&scp->scr, p, c, a);
+ }
+ } else {
+ sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
+ }
+}
+
+static void
+gdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
+{
+ if (base < 0 || base >= scp->font_size)
+ return;
+ /* the caller may set height <= 0 in order to disable the cursor */
+ (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
+ base, height,
+ scp->font_size, blink);
+}
+
+static void
+gdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
+{
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
+ at%scp->xsize, at/scp->xsize);
+ } else {
+ if (scp->status & VR_CURSOR_ON)
+ (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
+ -1, -1);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+}
+
+#ifndef SC_NO_CUTPASTE
+
+static void
+draw_txtmouse(scr_stat *scp, int x, int y)
+{
+ int at;
+
+ at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ sc_vtb_putc(&scp->scr, at,
+ sc_vtb_getc(&scp->scr, at),
+ sc_vtb_geta(&scp->scr, at) ^ 0x4);
+}
+
+static void
+remove_txtmouse(scr_stat *scp, int x, int y)
+{
+}
+
+static void
+gdc_txtmouse(scr_stat *scp, int x, int y, int on)
+{
+ if (on)
+ draw_txtmouse(scp, x, y);
+ else
+ remove_txtmouse(scp, x, y);
+}
+
+#endif /* SC_NO_CUTPASTE */
+
+#ifndef SC_NO_MODE_CHANGE
+
+/* graphics mode renderer */
+
+static void
+gdc_grborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+#endif /* SC_NO_MODE_CHANGE */
+
+#endif /* NSC > 0 && NGDC > 0 */
diff --git a/sys/pc98/pc98/scvtbpc98.c b/sys/pc98/pc98/scvtbpc98.c
new file mode 100644
index 0000000..64f4cb6
--- /dev/null
+++ b/sys/pc98/pc98/scvtbpc98.c
@@ -0,0 +1,364 @@
+/*-
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#define ATTR_OFFSET 0x2000
+
+#define vtb_wrap(vtb, at, offset) \
+ (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
+
+static u_int16_t at2pc98(u_int16_t attr);
+static vm_offset_t sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
+
+static u_int16_t
+at2pc98(u_int16_t attr)
+{
+ static u_char ibmpc_to_pc98[16] = {
+ 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
+ 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
+ };
+ static u_char ibmpc_to_pc98rev[16] = {
+ 0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5,
+ 0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
+ };
+ u_char fg_at, bg_at;
+ u_int16_t at;
+
+ if (attr & 0x00FF)
+ return (attr);
+
+ fg_at = ((attr >> 8) & 0x0F);
+ bg_at = ((attr >> 12) & 0x0F);
+
+ if (bg_at) {
+ if (bg_at & 0x08) {
+ if (bg_at & 0x07) {
+ /* reverse & blink */
+ at = ibmpc_to_pc98rev[bg_at] | 0x02;
+ } else {
+ /* normal & blink */
+ at = ibmpc_to_pc98[fg_at] | 0x02;
+ }
+ } else {
+ /* reverse */
+ at = ibmpc_to_pc98rev[bg_at];
+ }
+ } else {
+ /* normal */
+ at = ibmpc_to_pc98[fg_at];
+ }
+ at |= attr;
+ return (at);
+}
+
+void
+sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
+{
+ vtb->vtb_flags = 0;
+ vtb->vtb_type = type;
+ vtb->vtb_cols = cols;
+ vtb->vtb_rows = rows;
+ vtb->vtb_size = cols*rows;
+ vtb->vtb_buffer = NULL;
+ vtb->vtb_tail = 0;
+
+ switch (type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if ((buf == NULL) && (cols*rows != 0)) {
+ vtb->vtb_buffer =
+ (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
+ M_DEVBUF,
+ (wait) ? M_WAITOK : M_NOWAIT);
+ if (vtb->vtb_buffer != NULL) {
+ bzero((void *)sc_vtb_pointer(vtb, 0),
+ cols*rows*sizeof(u_int16_t)*2);
+ }
+ } else {
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ }
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ case VTB_FRAMEBUFFER:
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+sc_vtb_destroy(sc_vtb_t *vtb)
+{
+ vm_offset_t p;
+
+ vtb->vtb_flags = 0;
+ vtb->vtb_cols = 0;
+ vtb->vtb_rows = 0;
+ vtb->vtb_size = 0;
+ vtb->vtb_tail = 0;
+
+ p = vtb->vtb_buffer;
+ vtb->vtb_buffer = NULL;
+ switch (vtb->vtb_type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if (p != NULL)
+ free((void *)p, M_DEVBUF);
+ break;
+ default:
+ break;
+ }
+ vtb->vtb_type = VTB_INVALID;
+}
+
+size_t
+sc_vtb_size(int cols, int rows)
+{
+ return (size_t)(cols*rows*sizeof(u_int16_t)*2);
+}
+
+int
+sc_vtb_getc(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
+ else
+ return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
+}
+
+int
+sc_vtb_geta(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
+ else
+ return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
+}
+
+void
+sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ writew(sc_vtb_pointer(vtb, at), c);
+ writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
+ } else {
+ *(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
+ *(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
+ }
+}
+
+vm_offset_t
+sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ writew(p, c);
+ writew(p + ATTR_OFFSET, at2pc98(a));
+ } else {
+ *(u_int16_t *)p = c;
+ *(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
+ }
+ return (p + sizeof(u_int16_t));
+}
+
+vm_offset_t
+sc_vtb_pointer(sc_vtb_t *vtb, int at)
+{
+ return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
+}
+
+static vm_offset_t
+sc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
+{
+ return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
+ + ((vtb->vtb_type == VTB_FRAMEBUFFER) ?
+ ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
+}
+
+int
+sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
+{
+ return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
+}
+
+void
+sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+ fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+ fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
+ }
+}
+
+void
+sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
+{
+ if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_toio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
+ (void *)sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ }
+}
+
+void
+sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
+{
+ int len;
+
+ if (vtb2->vtb_type != VTB_RINGBUFFER)
+ return;
+
+ while (count > 0) {
+ len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
+ if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
+ (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ }
+ from += len;
+ count -= len;
+ vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
+ }
+}
+
+void
+sc_vtb_seek(sc_vtb_t *vtb, int pos)
+{
+ vtb->vtb_tail = pos%vtb->vtb_size;
+}
+
+void
+sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at), count);
+ fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
+ fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
+ }
+}
+
+void
+sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ int len;
+
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ len = vtb->vtb_size - at - count;
+ if (len > 0) {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at + count),
+ sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
+ sc_vtb_attr_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at + count),
+ (void *)sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
+ (void *)sc_vtb_attr_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ fillw_io(at2pc98(attr),
+ sc_vtb_attr_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ fillw(at2pc98(attr),
+ (void *)sc_vtb_attr_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ }
+}
+
+void
+sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size) {
+ count = vtb->vtb_size - at;
+ } else {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at),
+ sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ bcopy_io(sc_vtb_attr_pointer(vtb, at),
+ sc_vtb_attr_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at),
+ (void *)sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb, at),
+ (void *)sc_vtb_attr_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at), count);
+ fillw_io(at2pc98(attr),
+ sc_vtb_attr_pointer(vtb, at), count);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
+ fillw(at2pc98(attr),
+ (void *)sc_vtb_attr_pointer(vtb, at), count);
+ }
+}
+
+#endif /* NSC */
diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c
index c09af65..40fdd2c 100644
--- a/sys/pc98/pc98/sio.c
+++ b/sys/pc98/pc98/sio.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sio.c,v 1.96 1999/05/11 08:38:28 kato Exp $
+ * $Id: sio.c,v 1.97 1999/05/30 16:53:22 phk Exp $
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* from: i386/isa sio.c,v 1.234
*/
@@ -3931,7 +3931,7 @@ static cn_checkc_t siocncheckc;
static cn_getc_t siocngetc;
static cn_putc_t siocnputc;
-CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc);
/* To get the GDB related variables */
#if DDB > 0
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index c7b7250..3703e71 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -25,23 +25,23 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.120 1999/05/31 11:28:41 phk Exp $
+ * $Id: syscons.c,v 1.121 1999/06/03 13:50:54 kato Exp $
*/
#include "sc.h"
#include "splash.h"
-#include "apm.h"
+#include "opt_syscons.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
-#include "opt_syscons.h"
+#ifdef __i386__
+#include "apm.h"
+#endif
#if NSC > 0
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/conf.h>
-#include <sys/module.h>
-#include <sys/bus.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/tty.h>
@@ -51,63 +51,21 @@
#include <sys/devfsext.h>
#endif
-#include <machine/bootinfo.h>
#include <machine/clock.h>
#include <machine/cons.h>
#include <machine/console.h>
-#include <machine/mouse.h>
-#include <machine/md_var.h>
#include <machine/psl.h>
-#include <machine/frame.h>
#include <machine/pc/display.h>
-#include <machine/pc/vesa.h>
+#ifdef __i386__
#include <machine/apm_bios.h>
+#include <machine/frame.h>
#include <machine/random.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
+#endif
#include <dev/kbd/kbdreg.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
-
-#ifdef PC98
-#define KANJI
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/timerreg.h>
-#include <pc98/pc98/syscons.h>
-#include <isa/isavar.h>
-#else
-#include <dev/fb/vgareg.h>
#include <dev/syscons/syscons.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/timerreg.h>
-#endif /* PC98 */
-
-#if !defined(MAXCONS)
-#define MAXCONS 16
-#endif
-
-#if !defined(SC_MAX_HISTORY_SIZE)
-#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS)
-#endif
-
-#if !defined(SC_HISTORY_SIZE)
-#define SC_HISTORY_SIZE (ROW * 4)
-#endif
-
-#if (SC_HISTORY_SIZE * MAXCONS) > SC_MAX_HISTORY_SIZE
-#undef SC_MAX_HISTORY_SIZE
-#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS)
-#endif
-
-#if !defined(SC_MOUSE_CHAR)
-#define SC_MOUSE_CHAR (0xd0)
-#endif
#define COLD 0
#define WARM 1
@@ -115,264 +73,140 @@
#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */
#define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */
-/* for backward compatibility */
-#define OLD_CONS_MOUSECTL _IOWR('c', 10, old_mouse_info_t)
-
-typedef struct old_mouse_data {
- int x;
- int y;
- int buttons;
-} old_mouse_data_t;
-
-typedef struct old_mouse_info {
- int operation;
- union {
- struct old_mouse_data data;
- struct mouse_mode mode;
- } u;
-} old_mouse_info_t;
+#define KEYCODE_BS 0x0e /* "<-- Backspace" key, XXX */
static default_attr user_default = {
- (FG_LIGHTGREY | BG_BLACK) << 8,
- (FG_BLACK | BG_LIGHTGREY) << 8
+ SC_NORM_ATTR << 8,
+ SC_NORM_REV_ATTR << 8,
};
-#ifdef PC98
static default_attr kernel_default = {
- (FG_LIGHTGREY | BG_BLACK) << 8,
- (FG_BLACK | BG_LIGHTGREY) << 8
+ SC_KERNEL_CONS_ATTR << 8,
+ SC_KERNEL_CONS_REV_ATTR << 8,
};
-#else
-static default_attr kernel_default = {
- (FG_WHITE | BG_BLACK) << 8,
- (FG_BLACK | BG_LIGHTGREY) << 8
-};
-#endif /* PC98 */
-static scr_stat main_console;
-static scr_stat *console[MAXCONS];
+static int sc_console_unit = -1;
+static scr_stat *sc_console;
#ifdef DEVFS
-static void *sc_devfs_token[MAXCONS];
static void *sc_mouse_devfs_token;
static void *sc_console_devfs_token;
#endif
- scr_stat *cur_console;
-static scr_stat *new_scp, *old_scp;
static term_stat kernel_console;
static default_attr *current_default;
-static int sc_flags;
+
static char init_done = COLD;
-static u_short sc_buffer[ROW*COL];
static char shutdown_in_progress = FALSE;
-static char font_loading_in_progress = FALSE;
-static char switch_in_progress = FALSE;
-static char write_in_progress = FALSE;
-static char blink_in_progress = FALSE;
-static int blinkrate = 0;
-static int adapter = -1;
-static int keyboard = -1;
-static keyboard_t *kbd;
-static int delayed_next_scr = FALSE;
-static long scrn_blank_time = 0; /* screen saver timeout value */
-static int scrn_blanked = FALSE; /* screen saver active flag */
-static long scrn_time_stamp;
+static char sc_malloc = FALSE;
+
static int saver_mode = CONS_LKM_SAVER; /* LKM/user saver */
static int run_scrn_saver = FALSE; /* should run the saver? */
-static int scrn_idle = FALSE; /* about to run the saver */
-static int scrn_saver_failed;
- u_char scr_map[256];
- u_char scr_rmap[256];
-static int initial_video_mode; /* initial video mode # */
- int fonts_loaded = 0
-#ifdef STD8X16FONT
- | FONT_16
-#endif
- ;
+static long scrn_blank_time = 0; /* screen saver timeout value */
+static int scrn_blanked; /* # of blanked screen */
+static int sticky_splash = FALSE;
- u_char font_8[256*8];
- u_char font_14[256*14];
-#ifdef STD8X16FONT
-extern
-#endif
- u_char font_16[256*16];
- u_char palette[256*3];
-static u_char *cut_buffer;
-static int cut_buffer_size;
-static int mouse_level; /* sysmouse protocol level */
-static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 };
-#ifndef PC98
-static u_short mouse_and_mask[16] = {
- 0xc000, 0xe000, 0xf000, 0xf800,
- 0xfc00, 0xfe00, 0xff00, 0xff80,
- 0xfe00, 0x1e00, 0x1f00, 0x0f00,
- 0x0f00, 0x0000, 0x0000, 0x0000
- };
-static u_short mouse_or_mask[16] = {
- 0x0000, 0x4000, 0x6000, 0x7000,
- 0x7800, 0x7c00, 0x7e00, 0x6800,
- 0x0c00, 0x0c00, 0x0600, 0x0600,
- 0x0000, 0x0000, 0x0000, 0x0000
- };
-#endif
+static void none_saver(sc_softc_t *sc, int blank) { }
+static void (*current_saver)(sc_softc_t *, int) = none_saver;
- int sc_history_size = SC_HISTORY_SIZE;
-static int extra_history_size =
- SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS;
-
-static void none_saver(int blank) { }
-static void (*current_saver)(int blank) = none_saver;
- d_ioctl_t *sc_user_ioctl;
-
-static int sticky_splash = FALSE;
-static struct {
- u_int8_t cursor_start;
- u_int8_t cursor_end;
- u_int8_t shift_state;
- } bios_value;
-
-/* OS specific stuff */
-#ifdef not_yet_done
-#define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x]))
-struct CONSOLE_TTY (sccons[MAXCONS] = ttymalloc(sccons[MAXCONS]))
-struct MOUSE_TTY (sccons[MAXCONS+1] = ttymalloc(sccons[MAXCONS+1]))
-struct tty *sccons[MAXCONS+2];
-#else
-#define VIRTUAL_TTY(x) &sccons[x]
-#define CONSOLE_TTY &sccons[MAXCONS]
-#define MOUSE_TTY &sccons[MAXCONS+1]
-static struct tty sccons[MAXCONS+2];
+#if !defined(SC_NO_FONT_LOADING) && defined(SC_DFLT_FONT)
+#include "font.h"
#endif
+
+ d_ioctl_t *sc_user_ioctl;
+
+static bios_values_t bios_value;
+
+static struct tty sccons[2];
#define SC_MOUSE 128
-#define SC_CONSOLE 255
-u_short *Crtat;
+#define SC_CONSOLECTL 255
+
#ifdef PC98
-u_short *Atrat;
static u_char default_kanji = UJIS;
#endif
-static const int nsccons = MAXCONS+2;
-#define WRAPHIST(scp, pointer, offset)\
- ((scp)->history + ((((pointer) - (scp)->history) + (scp)->history_size \
- + (offset)) % (scp)->history_size))
-#ifdef PC98
-#define WRAPHIST_A(scp, pointer, offset)\
- ((scp->his_atr) + ((((pointer) - (scp->his_atr)) + (scp)->history_size \
- + (offset)) % (scp)->history_size))
-#endif
-#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
-
-/* some useful macros */
-#define kbd_read_char(kbd, wait) \
- (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait))
-#define kbd_check_char(kbd) \
- (*kbdsw[(kbd)->kb_index]->check_char)((kbd))
-#define kbd_enable(kbd) \
- (*kbdsw[(kbd)->kb_index]->enable)((kbd))
-#define kbd_disable(kbd) \
- (*kbdsw[(kbd)->kb_index]->disable)((kbd))
-#define kbd_lock(kbd, lockf) \
- (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf))
-#define kbd_ioctl(kbd, cmd, arg) \
- (((kbd) == NULL) ? \
- ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg)))
-#define kbd_clear_state(kbd) \
- (*kbdsw[(kbd)->kb_index]->clear_state)((kbd))
-#define kbd_get_fkeystr(kbd, fkey, len) \
- (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len))
-#define kbd_poll(kbd, on) \
- (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
+#define VIRTUAL_TTY(sc, x) (&((sc)->tty[(x) - (sc)->first_vty]))
+#define CONSOLE_TTY (&sccons[0])
+#define MOUSE_TTY (&sccons[1])
+
+#define debugger FALSE
+
+#ifdef __i386__
+#ifdef DDB
+extern int in_Debugger;
+#undef debugger
+#define debugger in_Debugger
+#endif /* DDB */
+#endif /* __i386__ */
/* prototypes */
-static int scattach(device_t dev);
-static kbd_callback_func_t sckbdevent;
-static int scparam(struct tty *tp, struct termios *t);
-static int scprobe(device_t dev);
static int scvidprobe(int unit, int flags, int cons);
static int sckbdprobe(int unit, int flags, int cons);
+static void scmeminit(void *arg);
+static int scdevtounit(dev_t dev);
+static kbd_callback_func_t sckbdevent;
+static int scparam(struct tty *tp, struct termios *t);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
-static void scinit(void);
+static void scinit(int unit, int flags);
+static void scterm(int unit, int flags);
static void scshutdown(int howto, void *arg);
-static u_int scgetc(keyboard_t *kbd, u_int flags);
+static u_int scgetc(sc_softc_t *sc, u_int flags);
#define SCGETC_CN 1
#define SCGETC_NONBLOCK 2
static int sccngetch(int flags);
static void sccnupdate(scr_stat *scp);
-static scr_stat *alloc_scp(void);
-static void init_scp(scr_stat *scp);
-static void get_bios_values(void);
-static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark);
-static int get_scr_num(void);
+static scr_stat *alloc_scp(sc_softc_t *sc, int vty);
+static void init_scp(sc_softc_t *sc, int vty, scr_stat *scp);
static timeout_t scrn_timer;
+static int and_region(int *s1, int *e1, int s2, int e2);
static void scrn_update(scr_stat *scp, int show_cursor);
+
#if NSPLASH > 0
-static int scsplash_callback(int);
-static void scsplash_saver(int show);
-static int add_scrn_saver(void (*this_saver)(int));
-static int remove_scrn_saver(void (*this_saver)(int));
+static int scsplash_callback(int event, void *arg);
+static void scsplash_saver(sc_softc_t *sc, int show);
+static int add_scrn_saver(void (*this_saver)(sc_softc_t *, int));
+static int remove_scrn_saver(void (*this_saver)(sc_softc_t *, int));
static int set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border);
static int restore_scrn_saver_mode(scr_stat *scp, int changemode);
-static void stop_scrn_saver(void (*saver)(int));
-static int wait_scrn_saver_stop(void);
+static void stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int));
+static int wait_scrn_saver_stop(sc_softc_t *sc);
#define scsplash_stick(stick) (sticky_splash = (stick))
-#else
+#else /* !NSPLASH */
#define scsplash_stick(stick)
#endif /* NSPLASH */
-static int switch_scr(scr_stat *scp, u_int next_scr);
-static void exchange_scr(void);
+
+static int switch_scr(sc_softc_t *sc, u_int next_scr);
+static int do_switch_scr(sc_softc_t *sc, int s);
+static int vt_proc_alive(scr_stat *scp);
+static int signal_vt_rel(scr_stat *scp);
+static int signal_vt_acq(scr_stat *scp);
+static void exchange_scr(sc_softc_t *sc);
static void scan_esc(scr_stat *scp, u_char c);
static void ansi_put(scr_stat *scp, u_char *buf, int len);
-static void draw_cursor_image(scr_stat *scp);
-static void remove_cursor_image(scr_stat *scp);
+static void draw_cursor_image(scr_stat *scp);
+static void remove_cursor_image(scr_stat *scp);
+static void update_cursor_image(scr_stat *scp);
static void move_crsr(scr_stat *scp, int x, int y);
-static void history_to_screen(scr_stat *scp);
-static int history_up_line(scr_stat *scp);
-static int history_down_line(scr_stat *scp);
static int mask2attr(struct term_stat *term);
static int save_kbd_state(scr_stat *scp);
-static int update_kbd_state(int state, int mask);
-static int update_kbd_leds(int which);
-static void set_destructive_cursor(scr_stat *scp);
-static void set_mouse_pos(scr_stat *scp);
-static int skip_spc_right(scr_stat *scp, u_short *p);
-static int skip_spc_left(scr_stat *scp, u_short *p);
-static void mouse_cut(scr_stat *scp);
-static void mouse_cut_start(scr_stat *scp);
-static void mouse_cut_end(scr_stat *scp);
-static void mouse_cut_word(scr_stat *scp);
-static void mouse_cut_line(scr_stat *scp);
-static void mouse_cut_extend(scr_stat *scp);
-static void mouse_paste(scr_stat *scp);
-static void draw_mouse_image(scr_stat *scp);
-static void remove_mouse_image(scr_stat *scp);
-static void draw_cutmarking(scr_stat *scp);
-static void remove_cutmarking(scr_stat *scp);
+static int update_kbd_state(scr_stat *scp, int state, int mask);
+static int update_kbd_leds(scr_stat *scp, int which);
static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
+#define CDEV_MAJOR 12
+
static cn_probe_t sccnprobe;
static cn_init_t sccninit;
static cn_getc_t sccngetc;
static cn_checkc_t sccncheckc;
static cn_putc_t sccnputc;
+static cn_term_t sccnterm;
-CONS_DRIVER(sc, sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc);
-
-devclass_t sc_devclass;
-
-static device_method_t sc_methods[] = {
- DEVMETHOD(device_probe, scprobe),
- DEVMETHOD(device_attach, scattach),
- { 0, 0 }
-};
-
-static driver_t sc_driver = {
- "sc",
- sc_methods,
- 1, /* XXX */
-};
+#if __alpha__
+void sccnattach(void);
+#endif
-DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
+CONS_DRIVER(sc, sccnprobe, sccninit, sccnterm, sccngetc, sccncheckc, sccnputc);
static d_open_t scopen;
static d_close_t scclose;
@@ -381,7 +215,6 @@ static d_write_t scwrite;
static d_ioctl_t scioctl;
static d_mmap_t scmmap;
-#define CDEV_MAJOR 12
static struct cdevsw sc_cdevsw = {
/* open */ scopen,
/* close */ scclose,
@@ -404,147 +237,9 @@ static struct cdevsw sc_cdevsw = {
/* bmaj */ -1
};
-#ifdef PC98
-static u_char ibmpc_to_pc98[16] =
- { 0x01,0x21,0x81,0xa1,0x41,0x61,0xc1,0xe1, 0x09,0x29,0x89,0xa9,0x49,0x69,0xc9,0xe9 };
-static u_char ibmpc_to_pc98rev[16] =
- { 0x05,0x25,0x85,0xa5,0x45,0x65,0xc5,0xe5, 0x0d,0x2d,0x8d,0xad,0x4d,0x6d,0xcd,0xed };
-
-unsigned int
-at2pc98(unsigned int attr)
-{
- unsigned char fg_at, bg_at;
- unsigned int at;
-
- fg_at = ((attr >> 8) & 0x0F);
- bg_at = ((attr >> 8) & 0xF0);
-
- if (bg_at) {
- if (bg_at & 0x80) {
- if (bg_at & 0x70) {
- /* reverse & blink */
- at = ibmpc_to_pc98rev[bg_at >> 4] | 0x02;
- } else {
- /* normal & blink */
- at = ibmpc_to_pc98[fg_at] | 0x02;
- }
- } else {
- /* reverse */
- at = ibmpc_to_pc98rev[bg_at >> 4];
- }
- } else {
- /* normal */
- at = ibmpc_to_pc98[fg_at];
- }
- at |= ((fg_at|bg_at) << 8);
- return (at);
-}
-#endif
-
-static void
-draw_cursor_image(scr_stat *scp)
-{
-#ifdef PC98
- (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, scp->xpos, scp->ypos);
-#else
- u_short cursor_image;
- u_short *ptr;
- u_short prev_image;
-
- if (ISPIXELSC(scp)) {
- sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf,
- scp->cursor_pos - scp->scr_buf, 1);
- return;
- }
-
- ptr = (u_short *)(scp->adp->va_window)
- + (scp->cursor_pos - scp->scr_buf);
-
- /* do we have a destructive cursor ? */
- if (sc_flags & CHAR_CURSOR) {
- prev_image = scp->cursor_saveunder;
- cursor_image = *ptr & 0x00ff;
- if (cursor_image == DEAD_CHAR)
- cursor_image = prev_image & 0x00ff;
- cursor_image |= *(scp->cursor_pos) & 0xff00;
- scp->cursor_saveunder = cursor_image;
- /* update the cursor bitmap if the char under the cursor has changed */
- if (prev_image != cursor_image)
- set_destructive_cursor(scp);
- /* modify cursor_image */
- if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){
- /*
- * When the mouse pointer is at the same position as the cursor,
- * the cursor bitmap needs to be updated even if the char under
- * the cursor hasn't changed, because the mouse pionter may
- * have moved by a few dots within the cursor cel.
- */
- if ((prev_image == cursor_image)
- && (cursor_image != *(scp->cursor_pos)))
- set_destructive_cursor(scp);
- cursor_image &= 0xff00;
- cursor_image |= DEAD_CHAR;
- }
- } else {
- cursor_image = (*(ptr) & 0x00ff) | *(scp->cursor_pos) & 0xff00;
- scp->cursor_saveunder = cursor_image;
- if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){
- if ((cursor_image & 0x7000) == 0x7000) {
- cursor_image &= 0x8fff;
- if(!(cursor_image & 0x0700))
- cursor_image |= 0x0700;
- } else {
- cursor_image |= 0x7000;
- if ((cursor_image & 0x0700) == 0x0700)
- cursor_image &= 0xf0ff;
- }
- }
- }
- *ptr = cursor_image;
-#endif
-}
-
-static void
-remove_cursor_image(scr_stat *scp)
-{
-#ifndef PC98
- if (ISPIXELSC(scp))
- sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
- scp->cursor_oldpos - scp->scr_buf, 0);
- else
- *((u_short *)(scp->adp->va_window)
- + (scp->cursor_oldpos - scp->scr_buf))
- = scp->cursor_saveunder;
-#endif
-}
-
-static void
-move_crsr(scr_stat *scp, int x, int y)
-{
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
- if (x >= scp->xsize)
- x = scp->xsize-1;
- if (y >= scp->ysize)
- y = scp->ysize-1;
- scp->xpos = x;
- scp->ypos = y;
- scp->cursor_pos = scp->scr_buf + scp->ypos * scp->xsize + scp->xpos;
-#ifdef PC98
- scp->cursor_atr = scp->atr_buf + scp->ypos * scp->xsize + scp->xpos;
-#endif
-}
-
-static int
-scprobe(device_t dev)
+int
+sc_probe_unit(int unit, int flags)
{
- int unit = device_get_unit(dev);
- int flags = isa_get_flags(dev);
-
- device_set_desc(dev, "System console");
-
if (!scvidprobe(unit, flags, FALSE)) {
if (bootverbose)
printf("sc%d: no video adapter is found.\n", unit);
@@ -558,8 +253,6 @@ scprobe(device_t dev)
static int
scvidprobe(int unit, int flags, int cons)
{
- video_adapter_t *adp;
-
/*
* Access the video adapter driver through the back door!
* Video adapter drivers need to be configured before syscons.
@@ -569,21 +262,7 @@ scvidprobe(int unit, int flags, int cons)
*/
vid_configure(cons ? VIO_PROBE_ONLY : 0);
- /* allocate a frame buffer */
- if (adapter < 0) {
- adapter = vid_allocate("*", -1, (void *)&adapter);
- if (adapter < 0)
- return FALSE;
- }
- adp = vid_get_adapter(adapter); /* shouldn't fail */
-
- Crtat = (u_short *)adp->va_window;
-#ifdef PC98
- Atrat = Crtat + ATTR_OFFSET;
-#endif
- initial_video_mode = adp->va_initial_mode;
-
- return TRUE;
+ return (vid_find_adapter("*", unit) >= 0);
}
/* probe the keyboard, return TRUE if found */
@@ -593,182 +272,241 @@ sckbdprobe(int unit, int flags, int cons)
/* access the keyboard driver through the backdoor! */
kbd_configure(cons ? KB_CONF_PROBE_ONLY : 0);
- /* allocate a keyboard and register the keyboard event handler */
- if (keyboard < 0) {
- keyboard = kbd_allocate("*", -1, (void *)&keyboard, sckbdevent, NULL);
- if (keyboard < 0)
- return FALSE;
- }
- kbd = kbd_get_keyboard(keyboard); /* shouldn't fail */
-
- return TRUE;
+ return (kbd_find_keyboard("*", unit) >= 0);
}
-#if NAPM > 0
-static int
-scresume(void *dummy)
+static char
+*adapter_name(video_adapter_t *adp)
{
- if (kbd != NULL)
- kbd_clear_state(kbd);
- return 0;
+ static struct {
+ int type;
+ char *name[2];
+ } names[] = {
+ { KD_MONO, { "MDA", "MDA" } },
+ { KD_HERCULES, { "Hercules", "Hercules" } },
+ { KD_CGA, { "CGA", "CGA" } },
+ { KD_EGA, { "EGA", "EGA (mono)" } },
+ { KD_VGA, { "VGA", "VGA (mono)" } },
+ { KD_PC98, { "PC-98x1", "PC-98x1" } },
+ { KD_TGA, { "TGA", "TGA" } },
+ { -1, { "Unknown", "Unknown" } },
+ };
+ int i;
+
+ for (i = 0; names[i].type != -1; ++i)
+ if (names[i].type == adp->va_type)
+ break;
+ return names[i].name[(adp->va_flags & V_ADP_COLOR) ? 0 : 1];
}
-#endif
-static int
-scattach(device_t dev)
+int
+sc_attach_unit(int unit, int flags)
{
+ sc_softc_t *sc;
scr_stat *scp;
-#if defined(VESA)
+#ifdef SC_PIXEL_MODE
video_info_t info;
#endif
- dev_t cdev = makedev(CDEV_MAJOR, 0);
#ifdef DEVFS
int vc;
#endif
- scinit();
- scp = console[0];
- sc_flags = isa_get_flags(dev);
- if (!ISFONTAVAIL(scp->adp->va_flags))
- sc_flags &= ~CHAR_CURSOR;
-
- /* copy temporary buffer to final buffer */
- scp->scr_buf = NULL;
-#ifdef PC98
- scp->atr_buf = NULL;
-#endif
- sc_alloc_scr_buffer(scp, FALSE, FALSE);
- bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short));
-#ifdef PC98
- bcopy(Atrat, scp->atr_buf, scp->xsize*scp->ysize*sizeof(u_short));
-#endif
-
- /* cut buffer is available only when the mouse pointer is used */
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, FALSE);
+ scmeminit(NULL); /* XXX */
- /* initialize history buffer & pointers */
- sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE);
+ flags &= ~SC_KERNEL_CONSOLE;
+ if (sc_console_unit == unit)
+ flags |= SC_KERNEL_CONSOLE;
+ scinit(unit, flags);
+ sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
+ sc->config = flags;
+ scp = sc->console[0];
+ if (sc_console == NULL) /* sc_console_unit < 0 */
+ sc_console = scp;
-#if defined(VESA)
- if ((sc_flags & VESA800X600)
- && ((*vidsw[scp->ad]->get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
+#ifdef SC_PIXEL_MODE
+ if ((sc->config & SC_VESA800X600)
+ && ((*vidsw[sc->adapter]->get_info)(sc->adp, M_VESA_800x600, &info) == 0)) {
#if NSPLASH > 0
- splash_term(scp->adp);
+ if (sc->flags & SC_SPLASH_SCRN)
+ splash_term(sc->adp);
#endif
sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
- initial_video_mode = M_VESA_800x600;
+ sc->initial_mode = M_VESA_800x600;
#if NSPLASH > 0
/* put up the splash again! */
- splash_init(scp->adp, scsplash_callback);
+ if (sc->flags & SC_SPLASH_SCRN)
+ splash_init(sc->adp, scsplash_callback, sc);
#endif
}
-#endif /* VESA */
+#endif /* SC_PIXEL_MODE */
- /* initialize cursor stuff */
+ /* initialize cursor */
if (!ISGRAPHSC(scp))
- draw_cursor_image(scp);
+ update_cursor_image(scp);
/* get screen update going */
- scrn_timer((void *)TRUE);
+ scrn_timer(sc);
/* set up the keyboard */
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
- update_kbd_state(scp->status, LOCK_MASK);
+ kbd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ update_kbd_state(scp, scp->status, LOCK_MASK);
+ printf("sc%d: %s <%d virtual consoles, flags=0x%x>\n",
+ unit, adapter_name(sc->adp), sc->vtys, sc->config);
if (bootverbose) {
- printf("sc%d:", device_get_unit(dev));
- if (adapter >= 0)
- printf(" fb%d", adapter);
- if (keyboard >= 0)
- printf(" kbd%d", keyboard);
+ printf("sc%d:", unit);
+ if (sc->adapter >= 0)
+ printf(" fb%d", sc->adapter);
+ if (sc->keyboard >= 0)
+ printf(" kbd%d", sc->keyboard);
printf("\n");
}
- printf("sc%d: ", device_get_unit(dev));
- switch(scp->adp->va_type) {
-#ifdef PC98
- case KD_PC98:
- printf(" <text mode>");
- break;
-#else
- case KD_VGA:
- printf("VGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
- break;
- case KD_EGA:
- printf("EGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
- break;
- case KD_CGA:
- printf("CGA");
- break;
- case KD_MONO:
- case KD_HERCULES:
- default:
- printf("MDA/Hercules");
- break;
-#endif /* PC98 */
+
+ /* register a shutdown callback for the kernel console */
+ if (sc_console_unit == unit)
+ at_shutdown(scshutdown, (void *)unit, SHUTDOWN_PRE_SYNC);
+
+ /*
+ * syscons's cdevsw must be registered from here. As syscons and
+ * pcvt share the same major number, their cdevsw cannot be
+ * registered at module loading/initialization time or by SYSINIT.
+ */
+ cdevsw_add(&sc_cdevsw); /* XXX do this just once... */
+
+#ifdef DEVFS
+ for (vc = sc->first_vty; vc < sc->first_vty + sc->vtys; vc++)
+ sc->devfs_token[vc] = devfs_add_devswf(&sc_cdevsw, vc,
+ DV_CHR, UID_ROOT, GID_WHEEL,
+ 0600, "ttyv%r", vc);
+ if (scp == sc_console) {
+#ifndef SC_NO_SYSMOUSE
+ sc_mouse_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_MOUSE,
+ DV_CHR, UID_ROOT, GID_WHEEL,
+ 0600, "sysmouse");
+#endif /* SC_NO_SYSMOUSE */
+ sc_console_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_CONSOLECTL,
+ DV_CHR, UID_ROOT, GID_WHEEL,
+ 0600, "consolectl");
}
- printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, sc_flags);
+#endif /* DEVFS */
-#if NAPM > 0
- scp->r_hook.ah_fun = scresume;
- scp->r_hook.ah_arg = NULL;
- scp->r_hook.ah_name = "system keyboard";
- scp->r_hook.ah_order = APM_MID_ORDER;
- apm_hook_establish(APM_HOOK_RESUME , &scp->r_hook);
-#endif
+ return 0;
+}
- at_shutdown(scshutdown, NULL, SHUTDOWN_PRE_SYNC);
+static void
+scmeminit(void *arg)
+{
+ if (sc_malloc)
+ return;
+ sc_malloc = TRUE;
- cdevsw_add(&sc_cdevsw);
+ /*
+ * As soon as malloc() becomes functional, we had better allocate
+ * various buffers for the kernel console.
+ */
-#ifdef DEVFS
- for (vc = 0; vc < MAXCONS; vc++)
- sc_devfs_token[vc] = devfs_add_devswf(&sc_cdevsw, vc, DV_CHR,
- UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc);
- sc_mouse_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_MOUSE, DV_CHR,
- UID_ROOT, GID_WHEEL, 0600, "sysmouse");
- sc_console_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_CONSOLE, DV_CHR,
- UID_ROOT, GID_WHEEL, 0600, "consolectl");
+ if (sc_console_unit < 0)
+ return;
+
+ /* copy the temporary buffer to the final buffer */
+ sc_alloc_scr_buffer(sc_console, FALSE, FALSE);
+
+#ifndef SC_NO_CUTPASTE
+ /* cut buffer is available only when the mouse pointer is used */
+ if (ISMOUSEAVAIL(sc_console->sc->adp->va_flags))
+ sc_alloc_cut_buffer(sc_console, FALSE);
#endif
+
+#ifndef SC_NO_HISTORY
+ /* initialize history buffer & pointers */
+ sc_alloc_history_buffer(sc_console, 0, FALSE);
+#endif
+}
+
+/* XXX */
+SYSINIT(sc_mem, SI_SUB_KMEM, SI_ORDER_ANY, scmeminit, NULL);
+
+int
+sc_resume_unit(int unit)
+{
+ /* XXX should be moved to the keyboard driver? */
+ sc_softc_t *sc;
+
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+ if (sc->kbd != NULL)
+ kbd_clear_state(sc->kbd);
return 0;
}
struct tty
*scdevtotty(dev_t dev)
{
- int unit = minor(dev);
+ sc_softc_t *sc;
+ int vty = SC_VTY(dev);
+ int unit;
if (init_done == COLD)
- return(NULL);
- if (unit == SC_CONSOLE)
+ return NULL;
+
+ if (vty == SC_CONSOLECTL)
return CONSOLE_TTY;
- if (unit == SC_MOUSE)
+#ifndef SC_NO_SYSMOUSE
+ if (vty == SC_MOUSE)
return MOUSE_TTY;
- if (unit >= MAXCONS || unit < 0)
- return(NULL);
- return VIRTUAL_TTY(unit);
+#endif
+
+ unit = scdevtounit(dev);
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+ if (sc == NULL)
+ return NULL;
+ return VIRTUAL_TTY(sc, vty);
+}
+
+static int
+scdevtounit(dev_t dev)
+{
+ int vty = SC_VTY(dev);
+
+ if (vty == SC_CONSOLECTL)
+ return ((sc_console != NULL) ? sc_console->sc->unit : -1);
+ else if (vty == SC_MOUSE)
+ return -1;
+ else if ((vty < 0) || (vty >= MAXCONS*sc_max_unit()))
+ return -1;
+ else
+ return vty/MAXCONS;
}
int
scopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct tty *tp = scdevtotty(dev);
+ int unit = scdevtounit(dev);
+ sc_softc_t *sc;
keyarg_t key;
if (!tp)
return(ENXIO);
- tp->t_oproc = (minor(dev) == SC_MOUSE) ? scmousestart : scstart;
+ DPRINTF(5, ("scopen: dev:%d, unit:%d, vty:%d\n",
+ dev, unit, SC_VTY(dev)));
+
+ /* sc == NULL, if SC_VTY(dev) == SC_MOUSE */
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+
+ tp->t_oproc = (SC_VTY(dev) == SC_MOUSE) ? scmousestart : scstart;
tp->t_param = scparam;
tp->t_dev = dev;
if (!(tp->t_state & TS_ISOPEN)) {
ttychars(tp);
/* Use the current setting of the <-- key as default VERASE. */
/* If the Delete key is preferable, an stty is necessary */
- key.keynum = 0x0e; /* how do we know this magic number... XXX */
- kbd_ioctl(kbd, GIO_KEYMAPENT, (caddr_t)&key);
- tp->t_cc[VERASE] = key.key.map[0];
+ if (sc != NULL) {
+ key.keynum = KEYCODE_BS;
+ kbd_ioctl(sc->kbd, GIO_KEYMAPENT, (caddr_t)&key);
+ tp->t_cc[VERASE] = key.key.map[0];
+ }
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
tp->t_cflag = TTYDEF_CFLAG;
@@ -776,20 +514,29 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
scparam(tp, &tp->t_termios);
(*linesw[tp->t_line].l_modem)(tp, 1);
- if (minor(dev) == SC_MOUSE)
- mouse_level = 0; /* XXX */
+#ifndef SC_NO_SYSMOUSE
+ if (SC_VTY(dev) == SC_MOUSE)
+ sc_mouse_set_level(0); /* XXX */
+#endif
}
else
if (tp->t_state & TS_XCLUDE && suser(p))
return(EBUSY);
- if (minor(dev) < MAXCONS && !console[minor(dev)]) {
- console[minor(dev)] = alloc_scp();
- if (ISGRAPHSC(console[minor(dev)]))
- sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16);
- }
- if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
- tp->t_winsize.ws_col = console[minor(dev)]->xsize;
- tp->t_winsize.ws_row = console[minor(dev)]->ysize;
+ if ((SC_VTY(dev) != SC_CONSOLECTL) && (SC_VTY(dev) != SC_MOUSE)) {
+ /* assert(sc != NULL) */
+ if (sc->console[SC_VTY(dev) - sc->first_vty] == NULL) {
+ sc->console[SC_VTY(dev) - sc->first_vty]
+ = alloc_scp(sc, SC_VTY(dev));
+ if (ISGRAPHSC(sc->console[SC_VTY(dev) - sc->first_vty]))
+ sc_set_pixel_mode(sc->console[SC_VTY(dev) - sc->first_vty],
+ NULL, COL, ROW, 16);
+ }
+ if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
+ tp->t_winsize.ws_col
+ = sc->console[SC_VTY(dev) - sc->first_vty]->xsize;
+ tp->t_winsize.ws_row
+ = sc->console[SC_VTY(dev) - sc->first_vty]->ysize;
+ }
}
return ((*linesw[tp->t_line].l_open)(dev, tp));
}
@@ -799,13 +546,29 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct tty *tp = scdevtotty(dev);
struct scr_stat *scp;
+ int s;
if (!tp)
return(ENXIO);
- if (minor(dev) < MAXCONS) {
+ if ((SC_VTY(dev) != SC_CONSOLECTL) && (SC_VTY(dev) != SC_MOUSE)) {
scp = sc_get_scr_stat(tp->t_dev);
- if (scp->status & SWITCH_WAIT_ACQ)
- wakeup((caddr_t)&scp->smode);
+ /* were we in the middle of the VT switching process? */
+ DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit));
+ s = spltty();
+ if ((scp == scp->sc->cur_scp) && (scp->sc->unit == sc_console_unit))
+ cons_unavail = FALSE;
+ if (scp->status & SWITCH_WAIT_REL) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_REL, "));
+ scp->status &= ~SWITCH_WAIT_REL;
+ do_switch_scr(scp->sc, s);
+ }
+ if (scp->status & SWITCH_WAIT_ACQ) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_ACQ, "));
+ scp->status &= ~SWITCH_WAIT_ACQ;
+ scp->sc->switch_in_progress = 0;
+ }
#if not_yet_done
if (scp == &main_console) {
scp->pid = 0;
@@ -813,27 +576,25 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
scp->smode.mode = VT_AUTO;
}
else {
- free(scp->scr_buf, M_DEVBUF);
-#ifdef PC98
- free(scp->atr_buf, M_DEVBUF);
- if (scp->his_atr != NULL)
- free(scp->his_atr, M_DEVBUF);
-#endif
+ sc_vtb_destroy(&scp->vtb);
+ sc_vtb_destroy(&scp->scr);
if (scp->history != NULL) {
+ /* XXX not quite correct */
+ sc_vtb_destroy(scp->history);
free(scp->history, M_DEVBUF);
- if (scp->history_size / scp->xsize
- > imax(sc_history_size, scp->ysize))
- extra_history_size += scp->history_size / scp->xsize
- - imax(sc_history_size, scp->ysize);
}
free(scp, M_DEVBUF);
- console[minor(dev)] = NULL;
+ sc->console[SC_VTY(dev) - sc->first_vty] = NULL;
}
#else
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
#endif
+ scp->kbd_mode = K_XLATE;
+ if (scp == scp->sc->cur_scp)
+ kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ DPRINTF(5, ("done.\n"));
}
spltty();
(*linesw[tp->t_line].l_close)(tp, flag);
@@ -866,19 +627,21 @@ scwrite(dev_t dev, struct uio *uio, int flag)
static int
sckbdevent(keyboard_t *thiskbd, int event, void *arg)
{
- static struct tty *cur_tty;
+ sc_softc_t *sc;
+ struct tty *cur_tty;
int c;
size_t len;
u_char *cp;
- /* assert(thiskbd == kbd) */
+ sc = (sc_softc_t *)arg;
+ /* assert(thiskbd == sc->kbd) */
switch (event) {
case KBDIO_KEYINPUT:
break;
case KBDIO_UNLOADING:
- kbd = NULL;
- kbd_release(thiskbd, (void *)&keyboard);
+ sc->kbd = NULL;
+ kbd_release(thiskbd, (void *)&sc->keyboard);
return 0;
default:
return EINVAL;
@@ -889,9 +652,10 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
* I don't think this is nessesary, and it doesn't fix
* the Xaccel-2.1 keyboard hang, but it can't hurt. XXX
*/
- while ((c = scgetc(thiskbd, SCGETC_NONBLOCK)) != NOKEY) {
+ while ((c = scgetc(sc, SCGETC_NONBLOCK)) != NOKEY) {
- cur_tty = VIRTUAL_TTY(get_scr_num());
+ cur_tty = VIRTUAL_TTY(sc, sc->cur_scp->index);
+ /* XXX */
if (!(cur_tty->t_state & TS_ISOPEN))
if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN))
continue;
@@ -919,10 +683,13 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
}
}
- if (cur_console->status & MOUSE_VISIBLE) {
- remove_mouse_image(cur_console);
- cur_console->status &= ~MOUSE_VISIBLE;
+#ifndef SC_NO_CUTPASTE
+ if (sc->cur_scp->status & MOUSE_VISIBLE) {
+ sc_remove_mouse_image(sc->cur_scp);
+ sc->cur_scp->status &= ~MOUSE_VISIBLE;
}
+#endif /* SC_NO_CUTPASTE */
+
return 0;
}
@@ -938,17 +705,16 @@ scparam(struct tty *tp, struct termios *t)
int
scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
- u_int delta_ehs;
int error;
int i;
struct tty *tp;
+ sc_softc_t *sc;
scr_stat *scp;
int s;
tp = scdevtotty(dev);
if (!tp)
return ENXIO;
- scp = sc_get_scr_stat(tp->t_dev);
/* If there is a user_ioctl function call that first */
if (sc_user_ioctl) {
@@ -961,6 +727,32 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (error != ENOIOCTL)
return error;
+#ifndef SC_NO_HISTORY
+ error = sc_hist_ioctl(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+#endif
+
+#ifndef SC_NO_SYSMOUSE
+ error = sc_mouse_ioctl(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ if (SC_VTY(dev) == SC_MOUSE) {
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ error = ttioctl(tp, cmd, data, flag);
+ if (error != ENOIOCTL)
+ return error;
+ return ENOTTY;
+ }
+#endif
+
+ scp = sc_get_scr_stat(tp->t_dev);
+ /* assert(scp != NULL) */
+ /* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */
+ sc = scp->sc;
+
switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */
@@ -968,7 +760,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case GIO_COLOR: /* is this a color console ? */
- *(int *)data = (scp->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
+ *(int *)data = (sc->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
return 0;
case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
@@ -981,463 +773,44 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_CURSORTYPE: /* set cursor type blink/noblink */
+ if (!ISGRAPHSC(sc->cur_scp))
+ remove_cursor_image(sc->cur_scp);
if ((*(int*)data) & 0x01)
- sc_flags |= BLINK_CURSOR;
+ sc->flags |= SC_BLINK_CURSOR;
else
- sc_flags &= ~BLINK_CURSOR;
+ sc->flags &= ~SC_BLINK_CURSOR;
if ((*(int*)data) & 0x02) {
- if (!ISFONTAVAIL(scp->adp->va_flags))
- return ENXIO;
- sc_flags |= CHAR_CURSOR;
+ sc->flags |= SC_CHAR_CURSOR;
} else
- sc_flags &= ~CHAR_CURSOR;
+ sc->flags &= ~SC_CHAR_CURSOR;
/*
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!ISGRAPHSC(cur_console)) {
+ if (!ISGRAPHSC(sc->cur_scp)) {
s = spltty();
- remove_cursor_image(cur_console);
- if (sc_flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- draw_cursor_image(cur_console);
+ sc_set_cursor_image(sc->cur_scp);
+ draw_cursor_image(sc->cur_scp);
splx(s);
}
return 0;
case CONS_BELLTYPE: /* set bell type sound/visual */
if ((*(int *)data) & 0x01)
- sc_flags |= VISUAL_BELL;
+ sc->flags |= SC_VISUAL_BELL;
else
- sc_flags &= ~VISUAL_BELL;
+ sc->flags &= ~SC_VISUAL_BELL;
if ((*(int *)data) & 0x02)
- sc_flags |= QUIET_BELL;
- else
- sc_flags &= ~QUIET_BELL;
- return 0;
-
- case CONS_HISTORY: /* set history size */
- if (*(int *)data > 0) {
- int lines; /* buffer size to allocate */
- int lines0; /* current buffer size */
-
- lines = imax(*(int *)data, scp->ysize);
- lines0 = (scp->history != NULL) ?
- scp->history_size / scp->xsize : scp->ysize;
- if (lines0 > imax(sc_history_size, scp->ysize))
- delta_ehs = lines0 - imax(sc_history_size, scp->ysize);
- else
- delta_ehs = 0;
- /*
- * syscons unconditionally allocates buffers upto SC_HISTORY_SIZE
- * lines or scp->ysize lines, whichever is larger. A value
- * greater than that is allowed, subject to extra_history_size.
- */
- if (lines > imax(sc_history_size, scp->ysize))
- if (lines - imax(sc_history_size, scp->ysize) >
- extra_history_size + delta_ehs)
- return EINVAL;
- if (cur_console->status & BUFFER_SAVED)
- return EBUSY;
- sc_alloc_history_buffer(scp, lines, delta_ehs, TRUE);
- return 0;
- }
+ sc->flags |= SC_QUIET_BELL;
else
- return EINVAL;
-
- case CONS_MOUSECTL: /* control mouse arrow */
- case OLD_CONS_MOUSECTL:
- {
- /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
- static int butmap[8] = {
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON1UP,
- 0,
- };
- mouse_info_t *mouse = (mouse_info_t*)data;
- mouse_info_t buf;
-
-#ifndef PC98
- /* FIXME: */
- if (!ISMOUSEAVAIL(scp->adp->va_flags))
- return ENODEV;
-#endif
-
- if (cmd == OLD_CONS_MOUSECTL) {
- static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
- old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
-
- mouse = &buf;
- mouse->operation = old_mouse->operation;
- switch (mouse->operation) {
- case MOUSE_MODE:
- mouse->u.mode = old_mouse->u.mode;
- break;
- case MOUSE_SHOW:
- case MOUSE_HIDE:
- break;
- case MOUSE_MOVEABS:
- case MOUSE_MOVEREL:
- case MOUSE_ACTION:
- mouse->u.data.x = old_mouse->u.data.x;
- mouse->u.data.y = old_mouse->u.data.y;
- mouse->u.data.z = 0;
- mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7];
- break;
- case MOUSE_GETINFO:
- old_mouse->u.data.x = scp->mouse_xpos;
- old_mouse->u.data.y = scp->mouse_ypos;
- old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7];
- break;
- default:
- return EINVAL;
- }
- }
-
- switch (mouse->operation) {
- case MOUSE_MODE:
- if (ISSIGVALID(mouse->u.mode.signal)) {
- scp->mouse_signal = mouse->u.mode.signal;
- scp->mouse_proc = p;
- scp->mouse_pid = p->p_pid;
- }
- else {
- scp->mouse_signal = 0;
- scp->mouse_proc = NULL;
- scp->mouse_pid = 0;
- }
- return 0;
-
- case MOUSE_SHOW:
- if (ISTEXTSC(scp) && !(scp->status & MOUSE_ENABLED)) {
- scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE);
- scp->mouse_oldpos = scp->mouse_pos;
- mark_all(scp);
- return 0;
- }
- else
- return EINVAL;
- break;
-
- case MOUSE_HIDE:
- if (ISTEXTSC(scp) && (scp->status & MOUSE_ENABLED)) {
- scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
- mark_all(scp);
- return 0;
- }
- else
- return EINVAL;
- break;
-
- case MOUSE_MOVEABS:
- scp->mouse_xpos = mouse->u.data.x;
- scp->mouse_ypos = mouse->u.data.y;
- set_mouse_pos(scp);
- break;
-
- case MOUSE_MOVEREL:
- scp->mouse_xpos += mouse->u.data.x;
- scp->mouse_ypos += mouse->u.data.y;
- set_mouse_pos(scp);
- break;
-
- case MOUSE_GETINFO:
- mouse->u.data.x = scp->mouse_xpos;
- mouse->u.data.y = scp->mouse_ypos;
- mouse->u.data.z = 0;
- mouse->u.data.buttons = scp->mouse_buttons;
- return 0;
-
- case MOUSE_ACTION:
- case MOUSE_MOTION_EVENT:
- /* this should maybe only be settable from /dev/consolectl SOS */
- /* send out mouse event on /dev/sysmouse */
-
- mouse_status.dx += mouse->u.data.x;
- mouse_status.dy += mouse->u.data.y;
- mouse_status.dz += mouse->u.data.z;
- if (mouse->operation == MOUSE_ACTION)
- mouse_status.button = mouse->u.data.buttons;
- mouse_status.flags |=
- ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ?
- MOUSE_POSCHANGED : 0)
- | (mouse_status.obutton ^ mouse_status.button);
- if (mouse_status.flags == 0)
- return 0;
-
- if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
- cur_console->status |= MOUSE_VISIBLE;
-
- if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
- u_char buf[MOUSE_SYS_PACKETSIZE];
- int j;
-
- /* the first five bytes are compatible with MouseSystems' */
- buf[0] = MOUSE_MSC_SYNC
- | butmap[mouse_status.button & MOUSE_STDBUTTONS];
- j = imax(imin(mouse->u.data.x, 255), -256);
- buf[1] = j >> 1;
- buf[3] = j - buf[1];
- j = -imax(imin(mouse->u.data.y, 255), -256);
- buf[2] = j >> 1;
- buf[4] = j - buf[2];
- for (j = 0; j < MOUSE_MSC_PACKETSIZE; j++)
- (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY);
- if (mouse_level >= 1) { /* extended part */
- j = imax(imin(mouse->u.data.z, 127), -128);
- buf[5] = (j >> 1) & 0x7f;
- buf[6] = (j - (j >> 1)) & 0x7f;
- /* buttons 4-10 */
- buf[7] = (~mouse_status.button >> 3) & 0x7f;
- for (j = MOUSE_MSC_PACKETSIZE;
- j < MOUSE_SYS_PACKETSIZE; j++)
- (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY);
- }
- }
-
- if (cur_console->mouse_signal) {
- cur_console->mouse_buttons = mouse->u.data.buttons;
- /* has controlling process died? */
- if (cur_console->mouse_proc &&
- (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){
- cur_console->mouse_signal = 0;
- cur_console->mouse_proc = NULL;
- cur_console->mouse_pid = 0;
- }
- else
- psignal(cur_console->mouse_proc, cur_console->mouse_signal);
- }
- else if (mouse->operation == MOUSE_ACTION && cut_buffer != NULL) {
- /* process button presses */
- if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) &&
- ISTEXTSC(cur_console)) {
- cur_console->mouse_buttons = mouse->u.data.buttons;
- if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN)
- mouse_cut_start(cur_console);
- else
- mouse_cut_end(cur_console);
- if (cur_console->mouse_buttons & MOUSE_BUTTON2DOWN ||
- cur_console->mouse_buttons & MOUSE_BUTTON3DOWN)
- mouse_paste(cur_console);
- }
- }
-
- if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
- cur_console->mouse_xpos += mouse->u.data.x;
- cur_console->mouse_ypos += mouse->u.data.y;
- set_mouse_pos(cur_console);
- }
-
- break;
-
- case MOUSE_BUTTON_EVENT:
- if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
- return EINVAL;
- if (mouse->u.event.value < 0)
- return EINVAL;
-
- if (mouse->u.event.value > 0) {
- cur_console->mouse_buttons |= mouse->u.event.id;
- mouse_status.button |= mouse->u.event.id;
- } else {
- cur_console->mouse_buttons &= ~mouse->u.event.id;
- mouse_status.button &= ~mouse->u.event.id;
- }
- mouse_status.flags |= mouse_status.obutton ^ mouse_status.button;
- if (mouse_status.flags == 0)
- return 0;
-
- if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
- cur_console->status |= MOUSE_VISIBLE;
-
- if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
- u_char buf[8];
- int i;
-
- buf[0] = MOUSE_MSC_SYNC
- | butmap[mouse_status.button & MOUSE_STDBUTTONS];
- buf[7] = (~mouse_status.button >> 3) & 0x7f;
- buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
- for (i = 0;
- i < ((mouse_level >= 1) ? MOUSE_SYS_PACKETSIZE
- : MOUSE_MSC_PACKETSIZE); i++)
- (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[i],MOUSE_TTY);
- }
-
- if (cur_console->mouse_signal) {
- if (cur_console->mouse_proc &&
- (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){
- cur_console->mouse_signal = 0;
- cur_console->mouse_proc = NULL;
- cur_console->mouse_pid = 0;
- }
- else
- psignal(cur_console->mouse_proc, cur_console->mouse_signal);
- break;
- }
-
- if (!ISTEXTSC(cur_console) || (cut_buffer == NULL))
- break;
-
- switch (mouse->u.event.id) {
- case MOUSE_BUTTON1DOWN:
- switch (mouse->u.event.value % 4) {
- case 0: /* up */
- mouse_cut_end(cur_console);
- break;
- case 1:
- mouse_cut_start(cur_console);
- break;
- case 2:
- mouse_cut_word(cur_console);
- break;
- case 3:
- mouse_cut_line(cur_console);
- break;
- }
- break;
- case MOUSE_BUTTON2DOWN:
- switch (mouse->u.event.value) {
- case 0: /* up */
- break;
- default:
- mouse_paste(cur_console);
- break;
- }
- break;
- case MOUSE_BUTTON3DOWN:
- switch (mouse->u.event.value) {
- case 0: /* up */
- if (!(cur_console->mouse_buttons & MOUSE_BUTTON1DOWN))
- mouse_cut_end(cur_console);
- break;
- default:
- mouse_cut_extend(cur_console);
- break;
- }
- break;
- }
- break;
-
- default:
- return EINVAL;
- }
- /* make screensaver happy */
- sc_touch_scrn_saver();
- return 0;
- }
-
- /* MOUSE_XXX: /dev/sysmouse ioctls */
- case MOUSE_GETHWINFO: /* get device information */
- {
- mousehw_t *hw = (mousehw_t *)data;
-
- if (tp != MOUSE_TTY)
- return ENOTTY;
- hw->buttons = 10; /* XXX unknown */
- hw->iftype = MOUSE_IF_SYSMOUSE;
- hw->type = MOUSE_MOUSE;
- hw->model = MOUSE_MODEL_GENERIC;
- hw->hwid = 0;
+ sc->flags &= ~SC_QUIET_BELL;
return 0;
- }
-
- case MOUSE_GETMODE: /* get protocol/mode */
- {
- mousemode_t *mode = (mousemode_t *)data;
-
- if (tp != MOUSE_TTY)
- return ENOTTY;
- mode->level = mouse_level;
- switch (mode->level) {
- case 0:
- /* at this level, sysmouse emulates MouseSystems protocol */
- mode->protocol = MOUSE_PROTO_MSC;
- mode->rate = -1; /* unknown */
- mode->resolution = -1; /* unknown */
- mode->accelfactor = 0; /* disabled */
- mode->packetsize = MOUSE_MSC_PACKETSIZE;
- mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
- mode->syncmask[1] = MOUSE_MSC_SYNC;
- break;
-
- case 1:
- /* at this level, sysmouse uses its own protocol */
- mode->protocol = MOUSE_PROTO_SYSMOUSE;
- mode->rate = -1;
- mode->resolution = -1;
- mode->accelfactor = 0;
- mode->packetsize = MOUSE_SYS_PACKETSIZE;
- mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
- mode->syncmask[1] = MOUSE_SYS_SYNC;
- break;
- }
- return 0;
- }
-
- case MOUSE_SETMODE: /* set protocol/mode */
- {
- mousemode_t *mode = (mousemode_t *)data;
-
- if (tp != MOUSE_TTY)
- return ENOTTY;
- if ((mode->level < 0) || (mode->level > 1))
- return EINVAL;
- mouse_level = mode->level;
- return 0;
- }
-
- case MOUSE_GETLEVEL: /* get operation level */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- *(int *)data = mouse_level;
- return 0;
-
- case MOUSE_SETLEVEL: /* set operation level */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- if ((*(int *)data < 0) || (*(int *)data > 1))
- return EINVAL;
- mouse_level = *(int *)data;
- return 0;
-
- case MOUSE_GETSTATUS: /* get accumulated mouse events */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- s = spltty();
- *(mousestatus_t *)data = mouse_status;
- mouse_status.flags = 0;
- mouse_status.obutton = mouse_status.button;
- mouse_status.dx = 0;
- mouse_status.dy = 0;
- mouse_status.dz = 0;
- splx(s);
- return 0;
-
-#if notyet
- case MOUSE_GETVARS: /* get internal mouse variables */
- case MOUSE_SETVARS: /* set internal mouse variables */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- return ENODEV;
-#endif
-
- case MOUSE_READSTATE: /* read status from the device */
- case MOUSE_READDATA: /* read data from the device */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- return ENODEV;
case CONS_GETINFO: /* get current (virtual) console info */
{
vid_info_t *ptr = (vid_info_t*)data;
if (ptr->size == sizeof(struct vid_info)) {
- ptr->m_num = get_scr_num();
+ ptr->m_num = sc->cur_scp->index;
ptr->mv_col = scp->xpos;
ptr->mv_row = scp->ypos;
ptr->mv_csz = scp->xsize;
@@ -1449,7 +822,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
ptr->mv_grfc.fore = 0; /* not supported */
ptr->mv_grfc.back = 0; /* not supported */
ptr->mv_ovscan = scp->border;
- if (scp == cur_console)
+ if (scp == sc->cur_scp)
save_kbd_state(scp);
ptr->mk_keylock = scp->status & LOCK_MASK;
return 0;
@@ -1471,9 +844,9 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* graphics mode in the current screen, we should say that the
* screen has been idle.
*/
- *(int *)data = scrn_idle
- && (!ISGRAPHSC(cur_console)
- || (cur_console->status & SAVER_RUNNING));
+ *(int *)data = (sc->flags & SC_SCRN_IDLE)
+ && (!ISGRAPHSC(sc->cur_scp)
+ || (sc->cur_scp->status & SAVER_RUNNING));
return 0;
case CONS_SAVERMODE: /* set saver mode */
@@ -1484,11 +857,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
saver_mode = *(int *)data;
s = spltty();
#if NSPLASH > 0
- if ((error = wait_scrn_saver_stop())) {
+ if ((error = wait_scrn_saver_stop(NULL))) {
splx(s);
return error;
}
#endif /* NSPLASH */
+ run_scrn_saver = TRUE;
scp->status |= SAVER_RUNNING;
scsplash_stick(TRUE);
splx(s);
@@ -1513,7 +887,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
s = spltty();
run_scrn_saver = (*(int *)data != 0);
if (run_scrn_saver)
- scrn_time_stamp -= scrn_blank_time;
+ sc->scrn_time_stamp -= scrn_blank_time;
splx(s);
return 0;
@@ -1522,16 +896,51 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
struct vt_mode *mode;
mode = (struct vt_mode *)data;
- if (ISSIGVALID(mode->relsig) && ISSIGVALID(mode->acqsig) &&
- ISSIGVALID(mode->frsig)) {
- bcopy(data, &scp->smode, sizeof(struct vt_mode));
- if (scp->smode.mode == VT_PROCESS) {
- scp->proc = p;
- scp->pid = scp->proc->p_pid;
+ DPRINTF(5, ("sc%d: VT_SETMODE ", sc->unit));
+ if (scp->smode.mode == VT_PROCESS) {
+ if (scp->proc == pfind(scp->pid) && scp->proc != p) {
+ DPRINTF(5, ("error EPERM\n"));
+ return EPERM;
}
- return 0;
- } else
- return EINVAL;
+ }
+ s = spltty();
+ if (mode->mode == VT_AUTO) {
+ scp->smode.mode = VT_AUTO;
+ scp->proc = NULL;
+ scp->pid = 0;
+ DPRINTF(5, ("VT_AUTO, "));
+ if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit))
+ cons_unavail = FALSE;
+ /* were we in the middle of the vty switching process? */
+ if (scp->status & SWITCH_WAIT_REL) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_REL, "));
+ scp->status &= ~SWITCH_WAIT_REL;
+ s = do_switch_scr(sc, s);
+ }
+ if (scp->status & SWITCH_WAIT_ACQ) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_ACQ, "));
+ scp->status &= ~SWITCH_WAIT_ACQ;
+ sc->switch_in_progress = 0;
+ }
+ } else {
+ if (!ISSIGVALID(mode->relsig) || !ISSIGVALID(mode->acqsig)
+ || !ISSIGVALID(mode->frsig)) {
+ splx(s);
+ DPRINTF(5, ("error EINVAL\n"));
+ return EINVAL;
+ }
+ DPRINTF(5, ("VT_PROCESS %d, ", p->p_pid));
+ bcopy(data, &scp->smode, sizeof(struct vt_mode));
+ scp->proc = p;
+ scp->pid = scp->proc->p_pid;
+ if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit))
+ cons_unavail = TRUE;
+ }
+ splx(s);
+ DPRINTF(5, ("\n"));
+ return 0;
}
case VT_GETMODE: /* get screen switcher mode */
@@ -1539,45 +948,58 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case VT_RELDISP: /* screen switcher ioctl */
+ s = spltty();
+ /*
+ * This must be the current vty which is in the VT_PROCESS
+ * switching mode...
+ */
+ if ((scp != sc->cur_scp) || (scp->smode.mode != VT_PROCESS)) {
+ splx(s);
+ return EINVAL;
+ }
+ /* ...and this process is controlling it. */
+ if (scp->proc != p) {
+ splx(s);
+ return EPERM;
+ }
+ error = EINVAL;
switch(*(int *)data) {
case VT_FALSE: /* user refuses to release screen, abort */
- if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
- old_scp->status &= ~SWITCH_WAIT_REL;
- switch_in_progress = FALSE;
- return 0;
+ if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
+ sc->old_scp->status &= ~SWITCH_WAIT_REL;
+ sc->switch_in_progress = 0;
+ DPRINTF(5, ("sc%d: VT_FALSE\n", sc->unit));
+ error = 0;
}
- return EINVAL;
+ break;
case VT_TRUE: /* user has released screen, go on */
- if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
+ if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
scp->status &= ~SWITCH_WAIT_REL;
- exchange_scr();
- if (new_scp->smode.mode == VT_PROCESS) {
- new_scp->status |= SWITCH_WAIT_ACQ;
- psignal(new_scp->proc, new_scp->smode.acqsig);
- }
- else
- switch_in_progress = FALSE;
- return 0;
+ s = do_switch_scr(sc, s);
+ DPRINTF(5, ("sc%d: VT_TRUE\n", sc->unit));
+ error = 0;
}
- return EINVAL;
+ break;
case VT_ACKACQ: /* acquire acknowledged, switch completed */
- if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) {
+ if ((scp == sc->new_scp) && (scp->status & SWITCH_WAIT_ACQ)) {
scp->status &= ~SWITCH_WAIT_ACQ;
- switch_in_progress = FALSE;
- return 0;
+ sc->switch_in_progress = 0;
+ DPRINTF(5, ("sc%d: VT_ACKACQ\n", sc->unit));
+ error = 0;
}
- return EINVAL;
+ break;
default:
- return EINVAL;
+ break;
}
- /* NOT REACHED */
+ splx(s);
+ return error;
case VT_OPENQRY: /* return free virtual console */
- for (i = 0; i < MAXCONS; i++) {
- tp = VIRTUAL_TTY(i);
+ for (i = sc->first_vty; i < sc->first_vty + sc->vtys; i++) {
+ tp = VIRTUAL_TTY(sc, i);
if (!(tp->t_state & TS_ISOPEN)) {
*(int *)data = i + 1;
return 0;
@@ -1587,32 +1009,33 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case VT_ACTIVATE: /* switch to screen *data */
s = spltty();
- sc_clean_up(cur_console);
+ sc_clean_up(sc->cur_scp);
splx(s);
- return switch_scr(scp, *(int *)data - 1);
+ return switch_scr(sc, *(int *)data - 1);
case VT_WAITACTIVE: /* wait for switch to occur */
- if (*(int *)data > MAXCONS || *(int *)data < 0)
+ if ((*(int *)data >= sc->first_vty + sc->vtys)
+ || (*(int *)data < sc->first_vty))
return EINVAL;
s = spltty();
- error = sc_clean_up(cur_console);
+ error = sc_clean_up(sc->cur_scp);
splx(s);
if (error)
return error;
- if (minor(dev) == *(int *)data - 1)
+ if (*(int *)data != 0)
+ scp = sc->console[*(int *)data - 1 - sc->first_vty];
+ if (scp == scp->sc->cur_scp)
return 0;
- if (*(int *)data == 0) {
- if (scp == cur_console)
- return 0;
- }
- else
- scp = console[*(int *)data - 1];
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
"waitvt", 0)) == ERESTART) ;
return error;
- case VT_GETACTIVE:
- *(int *)data = get_scr_num()+1;
+ case VT_GETACTIVE: /* get active vty # */
+ *(int *)data = sc->cur_scp->index + 1;
+ return 0;
+
+ case VT_GETINDEX: /* get this vty # */
+ *(int *)data = scp->index + 1;
return 0;
case KDENABIO: /* allow io operations */
@@ -1621,11 +1044,15 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return error;
if (securelevel > 0)
return EPERM;
+#ifdef __i386__
p->p_md.md_regs->tf_eflags |= PSL_IOPL;
+#endif
return 0;
case KDDISABIO: /* disallow io operations (default) */
+#ifdef __i386__
p->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
+#endif
return 0;
case KDSKBSTATE: /* set keyboard state (locks) */
@@ -1633,20 +1060,26 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
scp->status &= ~LOCK_MASK;
scp->status |= *(int *)data;
- if (scp == cur_console)
- update_kbd_state(scp->status, LOCK_MASK);
+ if (scp == sc->cur_scp)
+ update_kbd_state(scp, scp->status, LOCK_MASK);
return 0;
case KDGKBSTATE: /* get keyboard state (locks) */
- if (scp == cur_console)
+ if (scp == sc->cur_scp)
save_kbd_state(scp);
*(int *)data = scp->status & LOCK_MASK;
return 0;
- case KDSETRAD: /* set keyboard repeat & delay rates */
+ case KDSETREPEAT: /* set keyboard repeat & delay rates (new) */
+ error = kbd_ioctl(sc->kbd, cmd, data);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ return error;
+
+ case KDSETRAD: /* set keyboard repeat & delay rates (old) */
if (*(int *)data & ~0x7f)
return EINVAL;
- error = kbd_ioctl(kbd, KDSETRAD, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL)
error = ENODEV;
return error;
@@ -1657,8 +1090,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case K_RAW: /* switch to RAW scancode mode */
case K_CODE: /* switch to CODE mode */
scp->kbd_mode = *(int *)data;
- if (scp == cur_console)
- kbd_ioctl(kbd, cmd, data);
+ if (scp == sc->cur_scp)
+ kbd_ioctl(sc->kbd, cmd, data);
return 0;
default:
return EINVAL;
@@ -1670,7 +1103,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KDGKBINFO:
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL)
error = ENODEV;
return error;
@@ -1684,49 +1117,16 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KIOCSOUND: /* make tone (*data) hz */
- if (scp == cur_console) {
- if (*(int*)data) {
- int pitch = timer_freq / *(int*)data;
-
-#ifdef PC98
- /* enable counter 1 */
- outb(0x35, inb(0x35) & 0xf7);
- /* set command for counter 1, 2 byte write */
- if (acquire_timer1(TIMER_16BIT|TIMER_SQWAVE)) {
- return EBUSY;
- }
- /* set pitch */
- outb(TIMER_CNTR1, pitch);
- outb(TIMER_CNTR1, (pitch>>8));
-#else
- /* set command for counter 2, 2 byte write */
- if (acquire_timer2(TIMER_16BIT|TIMER_SQWAVE))
- return EBUSY;
-
- /* set pitch */
- outb(TIMER_CNTR2, pitch);
- outb(TIMER_CNTR2, (pitch>>8));
-
- /* enable counter 2 output to speaker */
- outb(IO_PPI, inb(IO_PPI) | 3);
-#endif
- }
- else {
-#ifdef PC98
- /* disable counter 1 */
- outb(0x35, inb(0x35) | 0x08);
- release_timer1();
-#else
- /* disable counter 2 output to speaker */
- outb(IO_PPI, inb(IO_PPI) & 0xFC);
- release_timer2();
-#endif
- }
+ if (scp == sc->cur_scp) {
+ if (*(int *)data)
+ return sc_tone(*(int *)data);
+ else
+ return sc_tone(0);
}
return 0;
case KDGKBTYPE: /* get keyboard type */
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL) {
/* always return something? XXX */
*(int *)data = 0;
@@ -1738,12 +1138,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
scp->status &= ~LED_MASK;
scp->status |= *(int *)data;
- if (scp == cur_console)
- update_kbd_leds(scp->status);
+ if (scp == sc->cur_scp)
+ update_kbd_leds(scp, scp->status);
return 0;
case KDGETLED: /* get keyboard LED status */
- if (scp == cur_console)
+ if (scp == sc->cur_scp)
save_kbd_state(scp);
*(int *)data = scp->status & LED_MASK;
return 0;
@@ -1759,19 +1159,21 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
}
error = 0;
- if (kbd != newkbd) {
+ if (sc->kbd != newkbd) {
i = kbd_allocate(newkbd->kb_name, newkbd->kb_unit,
- (void *)&keyboard, sckbdevent, NULL);
+ (void *)&sc->keyboard, sckbdevent, sc);
/* i == newkbd->kb_index */
if (i >= 0) {
- if (kbd != NULL) {
- save_kbd_state(cur_console);
- kbd_release(kbd, (void *)&keyboard);
+ if (sc->kbd != NULL) {
+ save_kbd_state(sc->cur_scp);
+ kbd_release(sc->kbd, (void *)&sc->keyboard);
}
- kbd = kbd_get_keyboard(i); /* kbd == newkbd */
- keyboard = i;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
- update_kbd_state(cur_console->status, LOCK_MASK);
+ sc->kbd = kbd_get_keyboard(i); /* sc->kbd == newkbd */
+ sc->keyboard = i;
+ kbd_ioctl(sc->kbd, KDSKBMODE,
+ (caddr_t)&sc->cur_scp->kbd_mode);
+ update_kbd_state(sc->cur_scp, sc->cur_scp->status,
+ LOCK_MASK);
} else {
error = EPERM; /* XXX */
}
@@ -1783,25 +1185,26 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case CONS_RELKBD: /* release the current keyboard */
s = spltty();
error = 0;
- if (kbd != NULL) {
- save_kbd_state(cur_console);
- error = kbd_release(kbd, (void *)&keyboard);
+ if (sc->kbd != NULL) {
+ save_kbd_state(sc->cur_scp);
+ error = kbd_release(sc->kbd, (void *)&sc->keyboard);
if (error == 0) {
- kbd = NULL;
- keyboard = -1;
+ sc->kbd = NULL;
+ sc->keyboard = -1;
}
}
splx(s);
return error;
-
+
case GIO_SCRNMAP: /* get output translation table */
- bcopy(&scr_map, data, sizeof(scr_map));
+ bcopy(&sc->scr_map, data, sizeof(sc->scr_map));
return 0;
case PIO_SCRNMAP: /* set output translation table */
- bcopy(data, &scr_map, sizeof(scr_map));
- for (i=0; i<sizeof(scr_map); i++)
- scr_rmap[scr_map[i]] = i;
+ bcopy(data, &sc->scr_map, sizeof(sc->scr_map));
+ for (i=0; i<sizeof(sc->scr_map); i++) {
+ sc->scr_rmap[sc->scr_map[i]] = i;
+ }
return 0;
case GIO_KEYMAP: /* get keyboard translation table */
@@ -1810,89 +1213,95 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case PIO_DEADKEYMAP: /* set accent key translation table */
case GETFKEY: /* get function key string */
case SETFKEY: /* set function key string */
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL)
error = ENODEV;
return error;
+#ifndef SC_NO_FONT_LOADING
+
case PIO_FONT8x8: /* set 8x8 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- bcopy(data, font_8, 8*256);
- fonts_loaded |= FONT_8;
+ bcopy(data, sc->font_8, 8*256);
+ sc->fonts_loaded |= FONT_8;
/*
* FONT KLUDGE
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x8.
*/
- if (ISTEXTSC(cur_console) && (cur_console->font_size < 14))
- copy_font(cur_console, LOAD, 8, font_8);
+ if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size < 14))
+ copy_font(sc->cur_scp, LOAD, 8, sc->font_8);
return 0;
case GIO_FONT8x8: /* get 8x8 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- if (fonts_loaded & FONT_8) {
- bcopy(font_8, data, 8*256);
+ if (sc->fonts_loaded & FONT_8) {
+ bcopy(sc->font_8, data, 8*256);
return 0;
}
else
return ENXIO;
case PIO_FONT8x14: /* set 8x14 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- bcopy(data, font_14, 14*256);
- fonts_loaded |= FONT_14;
+ bcopy(data, sc->font_14, 14*256);
+ sc->fonts_loaded |= FONT_14;
/*
* FONT KLUDGE
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x14.
*/
- if (ISTEXTSC(cur_console)
- && (cur_console->font_size >= 14) && (cur_console->font_size < 16))
- copy_font(cur_console, LOAD, 14, font_14);
+ if (ISTEXTSC(sc->cur_scp)
+ && (sc->cur_scp->font_size >= 14)
+ && (sc->cur_scp->font_size < 16))
+ copy_font(sc->cur_scp, LOAD, 14, sc->font_14);
return 0;
case GIO_FONT8x14: /* get 8x14 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- if (fonts_loaded & FONT_14) {
- bcopy(font_14, data, 14*256);
+ if (sc->fonts_loaded & FONT_14) {
+ bcopy(sc->font_14, data, 14*256);
return 0;
}
else
return ENXIO;
case PIO_FONT8x16: /* set 8x16 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- bcopy(data, font_16, 16*256);
- fonts_loaded |= FONT_16;
+ bcopy(data, sc->font_16, 16*256);
+ sc->fonts_loaded |= FONT_16;
/*
* FONT KLUDGE
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x16.
*/
- if (ISTEXTSC(cur_console) && (cur_console->font_size >= 16))
- copy_font(cur_console, LOAD, 16, font_16);
+ if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size >= 16))
+ copy_font(sc->cur_scp, LOAD, 16, sc->font_16);
return 0;
case GIO_FONT8x16: /* get 8x16 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- if (fonts_loaded & FONT_16) {
- bcopy(font_16, data, 16*256);
+ if (sc->fonts_loaded & FONT_16) {
+ bcopy(sc->font_16, data, 16*256);
return 0;
}
else
return ENXIO;
+#endif /* SC_NO_FONT_LOADING */
+
#ifdef PC98
- case ADJUST_CLOCK: /* /dev/rtc for 98note resume */
+ case ADJUST_CLOCK: /* /dev/rtc for 98note resume */
inittodr(0);
return 0;
#endif
+
default:
break;
}
@@ -1914,8 +1323,8 @@ scstart(struct tty *tp)
u_char buf[PCBURST];
scr_stat *scp = sc_get_scr_stat(tp->t_dev);
- if (scp->status & SLKED || blink_in_progress)
- return; /* XXX who repeats the call when the above flags are cleared? */
+ if (scp->status & SLKED || scp->sc->blink_in_progress)
+ return;
s = spltty();
if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
tp->t_state |= TS_BUSY;
@@ -1955,79 +1364,134 @@ scmousestart(struct tty *tp)
static void
sccnprobe(struct consdev *cp)
{
-#if 0
- struct isa_device *dvp;
+#if __i386__
+ int unit;
+ int flags;
- /*
- * Take control if we are the highest priority enabled display device.
- */
- dvp = find_display();
- if (dvp == NULL || dvp->id_driver != &scdriver) {
- cp->cn_pri = CN_DEAD;
- return;
- }
+ cp->cn_pri = sc_get_cons_priority(&unit, &flags);
- if (!scvidprobe(dvp->id_unit, dvp->id_flags, TRUE)) {
- cp->cn_pri = CN_DEAD;
- return;
- }
- sckbdprobe(dvp->id_unit, dvp->id_flags, TRUE);
-#else
- if (!scvidprobe(0, 0, TRUE)) {
+ /* a video card is always required */
+ if (!scvidprobe(unit, flags, TRUE))
cp->cn_pri = CN_DEAD;
+
+ /* syscons will become console even when there is no keyboard */
+ sckbdprobe(unit, flags, TRUE);
+
+ if (cp->cn_pri == CN_DEAD)
return;
- }
- sckbdprobe(0, 0, TRUE);
-#endif
/* initialize required fields */
- cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
- cp->cn_pri = CN_INTERNAL;
+ cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLECTL);
+#endif /* __i386__ */
+
+#if __alpha__
+ /*
+ * alpha use sccnattach() rather than cnprobe()/cninit()/cnterm()
+ * interface to install the console. Always return CN_DEAD from
+ * here.
+ */
+ cp->cn_pri = CN_DEAD;
+#endif /* __alpha__ */
}
static void
sccninit(struct consdev *cp)
{
- scinit();
+#if __i386__
+ int unit;
+ int flags;
+
+ sc_get_cons_priority(&unit, &flags);
+ scinit(unit, flags | SC_KERNEL_CONSOLE);
+ sc_console_unit = unit;
+ sc_console = sc_get_softc(unit, SC_KERNEL_CONSOLE)->console[0];
+#endif /* __i386__ */
+
+#if __alpha__
+ /* SHOULDN'T REACH HERE */
+#endif /* __alpha__ */
+}
+
+static void
+sccnterm(struct consdev *cp)
+{
+ /* we are not the kernel console any more, release everything */
+
+ if (sc_console_unit < 0)
+ return; /* shouldn't happen */
+
+#if __i386__
+ scterm(sc_console_unit, SC_KERNEL_CONSOLE);
+ sc_console_unit = -1;
+ sc_console = NULL;
+#endif /* __i386__ */
+
+#if __alpha__
+ /* do nothing XXX */
+#endif /* __alpha__ */
+}
+
+#ifdef __alpha__
+
+extern struct consdev *cn_tab;
+
+void
+sccnattach(void)
+{
+ static struct consdev consdev;
+ int unit;
+ int flags;
+
+ bcopy(&sc_consdev, &consdev, sizeof(sc_consdev));
+ consdev.cn_pri = sc_get_cons_priority(&unit, &flags);
+
+ /* a video card is always required */
+ if (!scvidprobe(unit, flags, TRUE))
+ consdev.cn_pri = CN_DEAD;
+
+ /* alpha doesn't allow the console being without a keyboard... Why? */
+ if (!sckbdprobe(unit, flags, TRUE))
+ consdev.cn_pri = CN_DEAD;
+
+ if (consdev.cn_pri == CN_DEAD)
+ return;
+
+ scinit(unit, flags | SC_KERNEL_CONSOLE);
+ sc_console_unit = unit;
+ sc_console = sc_get_softc(unit, SC_KERNEL_CONSOLE)->console[0];
+ consdev.cn_dev = makedev(CDEV_MAJOR, 0);
+ cn_tab = &consdev;
}
+#endif /* __alpha__ */
+
static void
sccnputc(dev_t dev, int c)
{
u_char buf[1];
- scr_stat *scp = console[0];
+ scr_stat *scp = sc_console;
term_stat save = scp->term;
- u_short *p;
int s;
- int i;
- if (scp == cur_console && scp->status & SLKED) {
+ /* assert(sc_console != NULL) */
+
+#ifndef SC_NO_HISTORY
+ if (scp == scp->sc->cur_scp && scp->status & SLKED) {
scp->status &= ~SLKED;
- update_kbd_state(scp->status, SLKED);
- if (cur_console->status & BUFFER_SAVED) {
- p = cur_console->history_save;
- for (i = 0; i < cur_console->ysize; ++i) {
- bcopy(p, cur_console->scr_buf + (cur_console->xsize*i),
- cur_console->xsize*sizeof(u_short));
- p += cur_console->xsize;
- if (p + cur_console->xsize
- > cur_console->history + cur_console->history_size)
- p = cur_console->history;
- }
- cur_console->status &= ~BUFFER_SAVED;
- cur_console->history_head = cur_console->history_save;
- cur_console->status |= CURSOR_ENABLED;
- mark_all(cur_console);
+ update_kbd_state(scp, scp->status, SLKED);
+ if (scp->status & BUFFER_SAVED) {
+ if (!sc_hist_restore(scp))
+ sc_remove_cutmarking(scp);
+ scp->status &= ~BUFFER_SAVED;
+ scp->status |= CURSOR_ENABLED;
+ draw_cursor_image(scp);
}
-#if 1 /* XXX */
- scstart(VIRTUAL_TTY(get_scr_num()));
-#endif
+ scstart(VIRTUAL_TTY(scp->sc, scp->index));
}
+#endif /* !SC_NO_HISTORY */
scp->term = kernel_console;
current_default = &kernel_default;
- if (scp == cur_console && !ISGRAPHSC(scp))
- remove_cursor_image(scp);
buf[0] = c;
ansi_put(scp, buf, 1);
kernel_console = scp->term;
@@ -2054,18 +1518,30 @@ sccncheckc(dev_t dev)
static int
sccngetch(int flags)
{
+ static struct fkeytab fkey;
+ static int fkeycp;
+ scr_stat *scp;
+ u_char *p;
int cur_mode;
int s = spltty(); /* block sckbdevent and scrn_timer while we poll */
int c;
+ /* assert(sc_console != NULL) */
+
/*
* Stop the screen saver and update the screen if necessary.
* What if we have been running in the screen saver code... XXX
*/
sc_touch_scrn_saver();
- sccnupdate(cur_console);
+ scp = sc_console->sc->cur_scp; /* XXX */
+ sccnupdate(scp);
+
+ if (fkeycp < fkey.len) {
+ splx(s);
+ return fkey.str[fkeycp++];
+ }
- if (kbd == NULL) {
+ if (scp->sc->kbd == NULL) {
splx(s);
return -1;
}
@@ -2074,26 +1550,33 @@ sccngetch(int flags)
* Make sure the keyboard is accessible even when the kbd device
* driver is disabled.
*/
- kbd_enable(kbd);
+ kbd_enable(scp->sc->kbd);
/* we shall always use the keyboard in the XLATE mode here */
- cur_mode = cur_console->kbd_mode;
- cur_console->kbd_mode = K_XLATE;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
+ cur_mode = scp->kbd_mode;
+ scp->kbd_mode = K_XLATE;
+ kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
- kbd_poll(kbd, TRUE);
- c = scgetc(kbd, SCGETC_CN | flags);
- kbd_poll(kbd, FALSE);
+ kbd_poll(scp->sc->kbd, TRUE);
+ c = scgetc(scp->sc, SCGETC_CN | flags);
+ kbd_poll(scp->sc->kbd, FALSE);
- cur_console->kbd_mode = cur_mode;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
- kbd_disable(kbd);
+ scp->kbd_mode = cur_mode;
+ kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ kbd_disable(scp->sc->kbd);
splx(s);
switch (KEYFLAGS(c)) {
case 0: /* normal char */
return KEYCHAR(c);
case FKEY: /* function key */
+ p = kbd_get_fkeystr(scp->sc->kbd, KEYCHAR(c), (size_t *)&fkeycp);
+ fkey.len = fkeycp;
+ if ((p != NULL) && (fkey.len > 0)) {
+ bcopy(p, fkey.str, fkey.len);
+ fkeycp = 1;
+ return fkey.str[0];
+ }
return c; /* XXX */
case NOKEY:
case ERRKEY:
@@ -2108,24 +1591,30 @@ sccnupdate(scr_stat *scp)
{
/* this is a cut-down version of scrn_timer()... */
- if (font_loading_in_progress)
+ if (scp->sc->font_loading_in_progress || scp->sc->videoio_in_progress)
return;
- if (panicstr || shutdown_in_progress) {
+ if (debugger || panicstr || shutdown_in_progress) {
sc_touch_scrn_saver();
- } else if (scp != cur_console) {
+ } else if (scp != scp->sc->cur_scp) {
return;
}
if (!run_scrn_saver)
- scrn_idle = FALSE;
+ scp->sc->flags &= ~SC_SCRN_IDLE;
#if NSPLASH > 0
- if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked)
- stop_scrn_saver(current_saver);
+ if ((saver_mode != CONS_LKM_SAVER) || !(scp->sc->flags & SC_SCRN_IDLE))
+ if (scp->sc->flags & SC_SCRN_BLANKED)
+ stop_scrn_saver(scp->sc, current_saver);
#endif /* NSPLASH */
- if (scp != cur_console || blink_in_progress || switch_in_progress)
+
+ if (scp != scp->sc->cur_scp || scp->sc->blink_in_progress
+ || scp->sc->switch_in_progress)
return;
+ /*
+ * FIXME: unlike scrn_timer(), we call scrn_update() from here even
+ * when write_in_progress is non-zero. XXX
+ */
if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
@@ -2134,128 +1623,214 @@ sccnupdate(scr_stat *scp)
scr_stat
*sc_get_scr_stat(dev_t dev)
{
- int unit = minor(dev);
-
- if (unit == SC_CONSOLE)
- return console[0];
- if (unit >= MAXCONS || unit < 0)
- return(NULL);
- return console[unit];
-}
-
-static int
-get_scr_num()
-{
- int i = 0;
-
- while ((i < MAXCONS) && (cur_console != console[i]))
- i++;
- return i < MAXCONS ? i : 0;
+ sc_softc_t *sc;
+ int vty = SC_VTY(dev);
+ int unit;
+
+ if (vty < 0)
+ return NULL;
+ if (vty == SC_CONSOLECTL)
+ return sc_console;
+
+ unit = scdevtounit(dev);
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+ if (sc == NULL)
+ return NULL;
+ if ((sc->first_vty <= vty) && (vty < sc->first_vty + sc->vtys))
+ return sc->console[vty - sc->first_vty];
+ return NULL;
}
static void
scrn_timer(void *arg)
{
+#ifndef PC98
+ static int kbd_interval = 0;
+#endif
struct timeval tv;
+ sc_softc_t *sc;
scr_stat *scp;
+ int again;
int s;
- /* don't do anything when we are touching font */
- if (font_loading_in_progress) {
- if (arg)
- timeout(scrn_timer, (void *)TRUE, hz / 10);
+ again = (arg != NULL);
+ if (arg != NULL)
+ sc = (sc_softc_t *)arg;
+ else if (sc_console != NULL)
+ sc = sc_console->sc;
+ else
+ return;
+
+ /* don't do anything when we are performing some I/O operations */
+ if (sc->font_loading_in_progress || sc->videoio_in_progress) {
+ if (again)
+ timeout(scrn_timer, sc, hz / 10);
return;
}
s = spltty();
+#ifndef PC98
+ if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) {
+ /* try to allocate a keyboard automatically */
+ if (++kbd_interval >= 25) {
+ sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard,
+ sckbdevent, sc);
+ if (sc->keyboard >= 0) {
+ sc->kbd = kbd_get_keyboard(sc->keyboard);
+ kbd_ioctl(sc->kbd, KDSKBMODE,
+ (caddr_t)&sc->cur_scp->kbd_mode);
+ update_kbd_state(sc->cur_scp, sc->cur_scp->status,
+ LOCK_MASK);
+ }
+ kbd_interval = 0;
+ }
+ }
+#endif /* PC98 */
+
+ /* find the vty to update */
+ scp = sc->cur_scp;
+
/* should we stop the screen saver? */
getmicrouptime(&tv);
- if (panicstr || shutdown_in_progress)
+ if (debugger || panicstr || shutdown_in_progress)
sc_touch_scrn_saver();
if (run_scrn_saver) {
- scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time);
+ if (tv.tv_sec > sc->scrn_time_stamp + scrn_blank_time)
+ sc->flags |= SC_SCRN_IDLE;
+ else
+ sc->flags &= ~SC_SCRN_IDLE;
} else {
- scrn_time_stamp = tv.tv_sec;
- scrn_idle = FALSE;
+ sc->scrn_time_stamp = tv.tv_sec;
+ sc->flags &= ~SC_SCRN_IDLE;
if (scrn_blank_time > 0)
run_scrn_saver = TRUE;
}
#if NSPLASH > 0
- if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked)
- stop_scrn_saver(current_saver);
+ if ((saver_mode != CONS_LKM_SAVER) || !(sc->flags & SC_SCRN_IDLE))
+ if (sc->flags & SC_SCRN_BLANKED)
+ stop_scrn_saver(sc, current_saver);
#endif /* NSPLASH */
+
/* should we just return ? */
- if (blink_in_progress || switch_in_progress) {
- if (arg)
- timeout(scrn_timer, (void *)TRUE, hz / 10);
+ if (sc->blink_in_progress || sc->switch_in_progress
+ || sc->write_in_progress) {
+ if (again)
+ timeout(scrn_timer, sc, hz / 10);
splx(s);
return;
}
/* Update the screen */
- scp = cur_console;
+ scp = sc->cur_scp; /* cur_scp may have changed... */
if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
+#if NSPLASH > 0
/* should we activate the screen saver? */
- if ((saver_mode == CONS_LKM_SAVER) && scrn_idle)
- if (!ISGRAPHSC(scp) || scrn_blanked)
- (*current_saver)(TRUE);
+ if ((saver_mode == CONS_LKM_SAVER) && (sc->flags & SC_SCRN_IDLE))
+ if (!ISGRAPHSC(scp) || (sc->flags & SC_SCRN_BLANKED))
+ (*current_saver)(sc, TRUE);
+#endif /* NSPLASH */
- if (arg)
- timeout(scrn_timer, (void *)TRUE, hz / 25);
+ if (again)
+ timeout(scrn_timer, sc, hz / 25);
splx(s);
}
+static int
+and_region(int *s1, int *e1, int s2, int e2)
+{
+ if (*e1 < s2 || e2 < *s1)
+ return FALSE;
+ *s1 = imax(*s1, s2);
+ *e1 = imin(*e1, e2);
+ return TRUE;
+}
+
static void
scrn_update(scr_stat *scp, int show_cursor)
{
- /* update screen image */
- if (scp->start <= scp->end) {
- sc_bcopy(scp, scp->scr_buf, scp->start, scp->end, 0);
-#ifdef PC98
- generic_bcopy(scp->atr_buf + scp->start, Atrat + scp->start,
- (1 + scp->end - scp->start) * sizeof(u_short));
+ int start;
+ int end;
+ int s;
+ int e;
+
+ /* assert(scp == scp->sc->cur_scp) */
+
+ ++scp->sc->videoio_in_progress;
+
+#ifndef SC_NO_CUTPASTE
+ /* remove the previous mouse pointer image if necessary */
+ if ((scp->status & (MOUSE_VISIBLE | MOUSE_MOVED))
+ == (MOUSE_VISIBLE | MOUSE_MOVED)) {
+ /* FIXME: I don't like this... XXX */
+ sc_remove_mouse_image(scp);
+ if (scp->end >= scp->xsize*scp->ysize)
+ scp->end = scp->xsize*scp->ysize - 1;
+ }
+#endif /* !SC_NO_CUTPASTE */
+
+#if 1
+ /* debug: XXX */
+ if (scp->end >= scp->xsize*scp->ysize) {
+ printf("scrn_update(): scp->end %d > size_of_screen!!\n", scp->end);
+ scp->end = scp->xsize*scp->ysize - 1;
+ }
+ if (scp->start < 0) {
+ printf("scrn_update(): scp->start %d < 0\n", scp->start);
+ scp->start = 0;
+ }
#endif
+
+ /* update screen image */
+ if (scp->start <= scp->end) {
+ if (scp->mouse_cut_end >= 0) {
+ /* there is a marked region for cut & paste */
+ if (scp->mouse_cut_start <= scp->mouse_cut_end) {
+ start = scp->mouse_cut_start;
+ end = scp->mouse_cut_end;
+ } else {
+ start = scp->mouse_cut_end;
+ end = scp->mouse_cut_start - 1;
+ }
+ s = start;
+ e = end;
+ /* does the cut-mark region overlap with the update region? */
+ if (and_region(&s, &e, scp->start, scp->end)) {
+ (*scp->rndr->draw)(scp, s, e - s + 1, TRUE);
+ s = 0;
+ e = start - 1;
+ if (and_region(&s, &e, scp->start, scp->end))
+ (*scp->rndr->draw)(scp, s, e - s + 1, FALSE);
+ s = end + 1;
+ e = scp->xsize*scp->ysize - 1;
+ if (and_region(&s, &e, scp->start, scp->end))
+ (*scp->rndr->draw)(scp, s, e - s + 1, FALSE);
+ } else {
+ (*scp->rndr->draw)(scp, scp->start,
+ scp->end - scp->start + 1, FALSE);
+ }
+ } else {
+ (*scp->rndr->draw)(scp, scp->start,
+ scp->end - scp->start + 1, FALSE);
+ }
}
/* we are not to show the cursor and the mouse pointer... */
if (!show_cursor) {
scp->end = 0;
scp->start = scp->xsize*scp->ysize - 1;
+ --scp->sc->videoio_in_progress;
return;
}
- /* update "pseudo" mouse pointer image */
- if (scp->status & MOUSE_VISIBLE) {
- /* did mouse move since last time ? */
- if (scp->status & MOUSE_MOVED) {
- /* do we need to remove old mouse pointer image ? */
- if (scp->mouse_cut_start != NULL ||
- (scp->mouse_pos-scp->scr_buf) <= scp->start ||
- (scp->mouse_pos+scp->xsize + 1 - scp->scr_buf) >= scp->end) {
- remove_mouse_image(scp);
- }
- scp->status &= ~MOUSE_MOVED;
- draw_mouse_image(scp);
- }
- else {
- /* mouse didn't move, has it been overwritten ? */
- if ((scp->mouse_pos+scp->xsize + 1 - scp->scr_buf) >= scp->start &&
- (scp->mouse_pos - scp->scr_buf) <= scp->end) {
- draw_mouse_image(scp);
- }
- }
- }
-
/* update cursor image */
if (scp->status & CURSOR_ENABLED) {
/* did cursor move since last time ? */
if (scp->cursor_pos != scp->cursor_oldpos) {
/* do we need to remove old cursor image ? */
- if ((scp->cursor_oldpos - scp->scr_buf) < scp->start ||
- ((scp->cursor_oldpos - scp->scr_buf) > scp->end)) {
+ if (scp->cursor_oldpos < scp->start ||
+ scp->cursor_oldpos > scp->end) {
remove_cursor_image(scp);
}
scp->cursor_oldpos = scp->cursor_pos;
@@ -2263,40 +1838,64 @@ scrn_update(scr_stat *scp, int show_cursor)
}
else {
/* cursor didn't move, has it been overwritten ? */
- if (scp->cursor_pos - scp->scr_buf >= scp->start &&
- scp->cursor_pos - scp->scr_buf <= scp->end) {
+ if (scp->cursor_pos >= scp->start && scp->cursor_pos <= scp->end) {
draw_cursor_image(scp);
} else {
/* if its a blinking cursor, we may have to update it */
- if (sc_flags & BLINK_CURSOR)
- draw_cursor_image(scp);
+ if (scp->sc->flags & SC_BLINK_CURSOR)
+ (*scp->rndr->blink_cursor)(scp, scp->cursor_pos,
+ sc_inside_cutmark(scp,
+ scp->cursor_pos));
}
}
- blinkrate++;
}
- if (scp->mouse_cut_start != NULL)
- draw_cutmarking(scp);
+#ifndef SC_NO_CUTPASTE
+ /* update "pseudo" mouse pointer image */
+ if (scp->status & MOUSE_VISIBLE) {
+ /* did mouse move since last time ? */
+ if (scp->status & MOUSE_MOVED) {
+ /* the previous pointer image has been removed, see above */
+ scp->status &= ~MOUSE_MOVED;
+ sc_draw_mouse_image(scp);
+ } else {
+ /* mouse didn't move, has it been overwritten ? */
+ if (scp->mouse_pos + scp->xsize + 1 >= scp->start &&
+ scp->mouse_pos <= scp->end) {
+ sc_draw_mouse_image(scp);
+ } else if (scp->cursor_pos == scp->mouse_pos ||
+ scp->cursor_pos == scp->mouse_pos + 1 ||
+ scp->cursor_pos == scp->mouse_pos + scp->xsize ||
+ scp->cursor_pos == scp->mouse_pos + scp->xsize + 1) {
+ sc_draw_mouse_image(scp);
+ }
+ }
+ }
+#endif /* SC_NO_CUTPASTE */
scp->end = 0;
scp->start = scp->xsize*scp->ysize - 1;
+
+ --scp->sc->videoio_in_progress;
}
#if NSPLASH > 0
-
static int
-scsplash_callback(int event)
+scsplash_callback(int event, void *arg)
{
+ sc_softc_t *sc;
int error;
+ sc = (sc_softc_t *)arg;
+
switch (event) {
case SPLASH_INIT:
- scrn_saver_failed = FALSE;
if (add_scrn_saver(scsplash_saver) == 0) {
+ sc->flags &= ~SC_SAVER_FAILED;
run_scrn_saver = TRUE;
if (cold && !(boothowto & (RB_VERBOSE | RB_CONFIG))) {
scsplash_stick(TRUE);
- (*current_saver)(TRUE);
+ (*current_saver)(sc, TRUE);
}
}
return 0;
@@ -2316,7 +1915,7 @@ scsplash_callback(int event)
}
static void
-scsplash_saver(int show)
+scsplash_saver(sc_softc_t *sc, int show)
{
static int busy = FALSE;
scr_stat *scp;
@@ -2325,38 +1924,37 @@ scsplash_saver(int show)
return;
busy = TRUE;
- scp = cur_console;
+ scp = sc->cur_scp;
if (show) {
- if (!scrn_saver_failed) {
- if (!scrn_blanked)
+ if (!(sc->flags & SC_SAVER_FAILED)) {
+ if (!(sc->flags & SC_SCRN_BLANKED))
set_scrn_saver_mode(scp, -1, NULL, 0);
- switch (splash(scp->adp, TRUE)) {
+ switch (splash(sc->adp, TRUE)) {
case 0: /* succeeded */
- scrn_blanked = TRUE;
break;
case EAGAIN: /* try later */
restore_scrn_saver_mode(scp, FALSE);
+ sc_touch_scrn_saver(); /* XXX */
break;
default:
- scrn_saver_failed = TRUE;
+ sc->flags |= SC_SAVER_FAILED;
scsplash_stick(FALSE);
- printf("scsplash_saver(): failed to put up the image\n");
restore_scrn_saver_mode(scp, TRUE);
+ printf("scsplash_saver(): failed to put up the image\n");
break;
}
}
} else if (!sticky_splash) {
- if (scrn_blanked && (splash(scp->adp, FALSE) == 0)) {
+ if ((sc->flags & SC_SCRN_BLANKED) && (splash(sc->adp, FALSE) == 0))
restore_scrn_saver_mode(scp, TRUE);
- scrn_blanked = FALSE;
- }
}
busy = FALSE;
}
static int
-add_scrn_saver(void (*this_saver)(int))
+add_scrn_saver(void (*this_saver)(sc_softc_t *, int))
{
+#if 0
int error;
if (current_saver != none_saver) {
@@ -2364,6 +1962,9 @@ add_scrn_saver(void (*this_saver)(int))
if (error)
return error;
}
+#endif
+ if (current_saver != none_saver)
+ return EBUSY;
run_scrn_saver = FALSE;
saver_mode = CONS_LKM_SAVER;
@@ -2372,11 +1973,12 @@ add_scrn_saver(void (*this_saver)(int))
}
static int
-remove_scrn_saver(void (*this_saver)(int))
+remove_scrn_saver(void (*this_saver)(sc_softc_t *, int))
{
if (current_saver != this_saver)
return EINVAL;
+#if 0
/*
* In order to prevent `current_saver' from being called by
* the timeout routine `scrn_timer()' while we manipulate
@@ -2386,8 +1988,15 @@ remove_scrn_saver(void (*this_saver)(int))
current_saver = none_saver;
if (scrn_blanked)
stop_scrn_saver(this_saver);
+#endif
+
+ /* unblank all blanked screens */
+ wait_scrn_saver_stop(NULL);
+ if (scrn_blanked)
+ return EBUSY;
- return (scrn_blanked ? EBUSY : 0);
+ current_saver = none_saver;
+ return 0;
}
static int
@@ -2395,21 +2004,27 @@ set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border)
{
int s;
- /* assert(scp == cur_console) */
+ /* assert(scp == scp->sc->cur_scp) */
s = spltty();
+ if (!ISGRAPHSC(scp))
+ remove_cursor_image(scp);
scp->splash_save_mode = scp->mode;
scp->splash_save_status = scp->status & (GRAPHICS_MODE | PIXEL_MODE);
scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
scp->status |= (UNKNOWN_MODE | SAVER_RUNNING);
+ scp->sc->flags |= SC_SCRN_BLANKED;
+ ++scrn_blanked;
splx(s);
if (mode < 0)
return 0;
scp->mode = mode;
if (set_mode(scp) == 0) {
- if (scp->adp->va_info.vi_flags & V_INFO_GRAPHICS)
+ if (scp->sc->adp->va_info.vi_flags & V_INFO_GRAPHICS)
scp->status |= GRAPHICS_MODE;
+#ifndef SC_NO_PALETTE_LOADING
if (pal != NULL)
- load_palette(scp->adp, pal);
+ load_palette(scp->sc->adp, pal);
+#endif
set_border(scp, border);
return 0;
} else {
@@ -2429,19 +2044,26 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode)
int status;
int s;
- /* assert(scp == cur_console) */
+ /* assert(scp == scp->sc->cur_scp) */
s = spltty();
mode = scp->mode;
status = scp->status;
scp->mode = scp->splash_save_mode;
scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING);
scp->status |= scp->splash_save_status;
+ scp->sc->flags &= ~SC_SCRN_BLANKED;
if (!changemode) {
+ if (!ISGRAPHSC(scp))
+ draw_cursor_image(scp);
+ --scrn_blanked;
splx(s);
return 0;
}
if (set_mode(scp) == 0) {
- load_palette(scp->adp, palette);
+#ifndef SC_NO_PALETTE_LOADING
+ load_palette(scp->sc->adp, scp->sc->palette);
+#endif
+ --scrn_blanked;
splx(s);
return 0;
} else {
@@ -2453,35 +2075,38 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode)
}
static void
-stop_scrn_saver(void (*saver)(int))
+stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int))
{
- (*saver)(FALSE);
+ (*saver)(sc, FALSE);
run_scrn_saver = FALSE;
/* the screen saver may have chosen not to stop after all... */
- if (scrn_blanked)
+ if (sc->flags & SC_SCRN_BLANKED)
return;
- mark_all(cur_console);
- if (delayed_next_scr)
- switch_scr(cur_console, delayed_next_scr - 1);
+ mark_all(sc->cur_scp);
+ if (sc->delayed_next_scr)
+ switch_scr(sc, sc->delayed_next_scr - 1);
wakeup((caddr_t)&scrn_blanked);
}
static int
-wait_scrn_saver_stop(void)
+wait_scrn_saver_stop(sc_softc_t *sc)
{
int error = 0;
- while (scrn_blanked) {
+ while (scrn_blanked > 0) {
run_scrn_saver = FALSE;
+ if (sc && !(sc->flags & SC_SCRN_BLANKED)) {
+ error = 0;
+ break;
+ }
error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0);
- run_scrn_saver = FALSE;
- if (error != ERESTART)
+ if ((error != 0) && (error != ERESTART))
break;
}
+ run_scrn_saver = FALSE;
return error;
}
-
#endif /* NSPLASH */
void
@@ -2496,112 +2121,301 @@ sc_clear_screen(scr_stat *scp)
{
move_crsr(scp, 0, 0);
scp->cursor_oldpos = scp->cursor_pos;
-#ifdef PC98
- fillw(scr_map[0x20], scp->scr_buf,
- scp->xsize * scp->ysize);
- fillw(at2pc98(scp->term.cur_color), scp->atr_buf,
- scp->xsize * scp->ysize);
-#else
- fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf,
- scp->xsize * scp->ysize);
-#endif
+ sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
}
static int
-switch_scr(scr_stat *scp, u_int next_scr)
+switch_scr(sc_softc_t *sc, u_int next_scr)
{
- /* delay switch if actively updating screen */
- if (scrn_blanked || write_in_progress || blink_in_progress) {
- delayed_next_scr = next_scr+1;
+ struct tty *tp;
+ int s;
+
+ DPRINTF(5, ("sc0: switch_scr() %d ", next_scr + 1));
+
+ /* delay switch if the screen is blanked or being updated */
+ if ((sc->flags & SC_SCRN_BLANKED) || sc->write_in_progress
+ || sc->blink_in_progress || sc->videoio_in_progress) {
+ sc->delayed_next_scr = next_scr + 1;
sc_touch_scrn_saver();
+ DPRINTF(5, ("switch delayed\n"));
return 0;
}
- if (switch_in_progress && (cur_console->proc != pfind(cur_console->pid)))
- switch_in_progress = FALSE;
+ s = spltty();
- if (next_scr >= MAXCONS || switch_in_progress ||
- (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) {
- do_bell(scp, BELL_PITCH, BELL_DURATION);
+ /* we are in the middle of the vty switching process... */
+ if (sc->switch_in_progress
+ && (sc->cur_scp->smode.mode == VT_PROCESS)
+ && sc->cur_scp->proc) {
+ if (sc->cur_scp->proc != pfind(sc->cur_scp->pid)) {
+ /*
+ * The controlling process has died!!. Do some clean up.
+ * NOTE:`cur_scp->proc' and `cur_scp->smode.mode'
+ * are not reset here yet; they will be cleared later.
+ */
+ DPRINTF(5, ("cur_scp controlling process %d died, ",
+ sc->cur_scp->pid));
+ if (sc->cur_scp->status & SWITCH_WAIT_REL) {
+ /*
+ * Force the previous switch to finish, but return now
+ * with error.
+ */
+ DPRINTF(5, ("reset WAIT_REL, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_REL;
+ s = do_switch_scr(sc, s);
+ splx(s);
+ DPRINTF(5, ("finishing previous switch\n"));
+ return EINVAL;
+ } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
+ /* let's assume screen switch has been completed. */
+ DPRINTF(5, ("reset WAIT_ACQ, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
+ sc->switch_in_progress = 0;
+ } else {
+ /*
+ * We are in between screen release and acquisition, and
+ * reached here via scgetc() or scrn_timer() which has
+ * interrupted exchange_scr(). Don't do anything stupid.
+ */
+ DPRINTF(5, ("waiting nothing, "));
+ }
+ } else {
+ /*
+ * The controlling process is alive, but not responding...
+ * It is either buggy or it may be just taking time.
+ * The following code is a gross kludge to cope with this
+ * problem for which there is no clean solution. XXX
+ */
+ if (sc->cur_scp->status & SWITCH_WAIT_REL) {
+ switch (sc->switch_in_progress++) {
+ case 1:
+ break;
+ case 2:
+ DPRINTF(5, ("sending relsig again, "));
+ signal_vt_rel(sc->cur_scp);
+ break;
+ case 3:
+ break;
+ case 4:
+ default:
+ /*
+ * Clear the flag and force the previous switch to finish,
+ * but return now with error.
+ */
+ DPRINTF(5, ("force reset WAIT_REL, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_REL;
+ s = do_switch_scr(sc, s);
+ splx(s);
+ DPRINTF(5, ("force finishing previous switch\n"));
+ return EINVAL;
+ }
+ } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
+ switch (sc->switch_in_progress++) {
+ case 1:
+ break;
+ case 2:
+ DPRINTF(5, ("sending acqsig again, "));
+ signal_vt_acq(sc->cur_scp);
+ break;
+ case 3:
+ break;
+ case 4:
+ default:
+ /* clear the flag and finish the previous switch */
+ DPRINTF(5, ("force reset WAIT_ACQ, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
+ sc->switch_in_progress = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Return error if an invalid argument is given, or vty switch
+ * is still in progress.
+ */
+ if ((next_scr < sc->first_vty) || (next_scr >= sc->first_vty + sc->vtys)
+ || sc->switch_in_progress) {
+ splx(s);
+ do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ DPRINTF(5, ("error 1\n"));
+ return EINVAL;
+ }
+
+ /*
+ * Don't allow switching away from the graphics mode vty
+ * if the switch mode is VT_AUTO, unless the next vty is the same
+ * as the current or the current vty has been closed (but showing).
+ */
+ tp = VIRTUAL_TTY(sc, sc->cur_scp->index);
+ if ((sc->cur_scp->index != next_scr)
+ && (tp->t_state & TS_ISOPEN)
+ && (sc->cur_scp->smode.mode == VT_AUTO)
+ && ISGRAPHSC(sc->cur_scp)) {
+ splx(s);
+ do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ DPRINTF(5, ("error, graphics mode\n"));
return EINVAL;
}
- /* is the wanted virtual console open ? */
- if (next_scr) {
- struct tty *tp = VIRTUAL_TTY(next_scr);
+ /*
+ * Is the wanted vty open? Don't allow switching to a closed vty.
+ * Note that we always allow the user to switch to the kernel
+ * console even if it is closed.
+ */
+ if ((sc_console == NULL) || (next_scr != sc_console->index)) {
+ tp = VIRTUAL_TTY(sc, next_scr);
if (!(tp->t_state & TS_ISOPEN)) {
- do_bell(scp, BELL_PITCH, BELL_DURATION);
+ splx(s);
+ do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ DPRINTF(5, ("error 2, requested vty isn't open!\n"));
return EINVAL;
}
}
- switch_in_progress = TRUE;
- old_scp = cur_console;
- new_scp = console[next_scr];
- wakeup((caddr_t)&new_scp->smode);
- if (new_scp == old_scp) {
- switch_in_progress = FALSE;
- delayed_next_scr = FALSE;
+ /* this is the start of vty switching process... */
+ ++sc->switch_in_progress;
+ sc->delayed_next_scr = 0;
+ sc->old_scp = sc->cur_scp;
+ sc->new_scp = sc->console[next_scr - sc->first_vty];
+ if (sc->new_scp == sc->old_scp) {
+ sc->switch_in_progress = 0;
+ wakeup((caddr_t)&sc->new_scp->smode);
+ splx(s);
+ DPRINTF(5, ("switch done (new == old)\n"));
return 0;
}
/* has controlling process died? */
- if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid)))
- old_scp->smode.mode = VT_AUTO;
- if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid)))
- new_scp->smode.mode = VT_AUTO;
-
- /* check the modes and switch appropriately */
- if (old_scp->smode.mode == VT_PROCESS) {
- old_scp->status |= SWITCH_WAIT_REL;
- psignal(old_scp->proc, old_scp->smode.relsig);
+ vt_proc_alive(sc->old_scp);
+ vt_proc_alive(sc->new_scp);
+
+ /* wait for the controlling process to release the screen, if necessary */
+ if (signal_vt_rel(sc->old_scp)) {
+ splx(s);
+ return 0;
}
- else {
- exchange_scr();
- if (new_scp->smode.mode == VT_PROCESS) {
- new_scp->status |= SWITCH_WAIT_ACQ;
- psignal(new_scp->proc, new_scp->smode.acqsig);
- }
- else
- switch_in_progress = FALSE;
+
+ /* go set up the new vty screen */
+ splx(s);
+ exchange_scr(sc);
+ s = spltty();
+
+ /* wake up processes waiting for this vty */
+ wakeup((caddr_t)&sc->cur_scp->smode);
+
+ /* wait for the controlling process to acknowledge, if necessary */
+ if (signal_vt_acq(sc->cur_scp)) {
+ splx(s);
+ return 0;
}
+
+ sc->switch_in_progress = 0;
+ if (sc->unit == sc_console_unit)
+ cons_unavail = FALSE;
+ splx(s);
+ DPRINTF(5, ("switch done\n"));
+
return 0;
}
+static int
+do_switch_scr(sc_softc_t *sc, int s)
+{
+ vt_proc_alive(sc->new_scp);
+
+ splx(s);
+ exchange_scr(sc);
+ s = spltty();
+ /* sc->cur_scp == sc->new_scp */
+ wakeup((caddr_t)&sc->cur_scp->smode);
+
+ /* wait for the controlling process to acknowledge, if necessary */
+ if (!signal_vt_acq(sc->cur_scp)) {
+ sc->switch_in_progress = 0;
+ if (sc->unit == sc_console_unit)
+ cons_unavail = FALSE;
+ }
+
+ return s;
+}
+
+static int
+vt_proc_alive(scr_stat *scp)
+{
+ if (scp->proc) {
+ if (scp->proc == pfind(scp->pid))
+ return TRUE;
+ scp->proc = NULL;
+ scp->smode.mode = VT_AUTO;
+ DPRINTF(5, ("vt controlling process %d died\n", scp->pid));
+ }
+ return FALSE;
+}
+
+static int
+signal_vt_rel(scr_stat *scp)
+{
+ if (scp->smode.mode != VT_PROCESS)
+ return FALSE;
+ scp->status |= SWITCH_WAIT_REL;
+ psignal(scp->proc, scp->smode.relsig);
+ DPRINTF(5, ("sending relsig to %d\n", scp->pid));
+ return TRUE;
+}
+
+static int
+signal_vt_acq(scr_stat *scp)
+{
+ if (scp->smode.mode != VT_PROCESS)
+ return FALSE;
+ if (scp->sc->unit == sc_console_unit)
+ cons_unavail = TRUE;
+ scp->status |= SWITCH_WAIT_ACQ;
+ psignal(scp->proc, scp->smode.acqsig);
+ DPRINTF(5, ("sending acqsig to %d\n", scp->pid));
+ return TRUE;
+}
+
static void
-exchange_scr(void)
+exchange_scr(sc_softc_t *sc)
{
+ scr_stat *scp;
+
/* save the current state of video and keyboard */
- move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
- if (old_scp->kbd_mode == K_XLATE)
- save_kbd_state(old_scp);
-
+ move_crsr(sc->old_scp, sc->old_scp->xpos, sc->old_scp->ypos);
+ if (sc->old_scp->kbd_mode == K_XLATE)
+ save_kbd_state(sc->old_scp);
+
/* set up the video for the new screen */
- cur_console = new_scp;
+ scp = sc->cur_scp = sc->new_scp;
#ifdef PC98
- if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp) || ISUNKNOWNSC(new_scp))
+ if (sc->old_scp->mode != scp->mode || ISUNKNOWNSC(sc->old_scp) || ISUNKNOWNSC(sc->new_scp))
#else
- if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp))
+ if (sc->old_scp->mode != scp->mode || ISUNKNOWNSC(sc->old_scp))
#endif
- set_mode(new_scp);
- move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
-#ifndef PC98
- if (ISTEXTSC(new_scp) && (sc_flags & CHAR_CURSOR))
- set_destructive_cursor(new_scp);
- if (ISGRAPHSC(old_scp))
- load_palette(new_scp->adp, palette);
+ set_mode(scp);
+ else
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+ (void *)sc->adp->va_window, FALSE);
+ move_crsr(scp, scp->xpos, scp->ypos);
+ if (!ISGRAPHSC(scp))
+ sc_set_cursor_image(scp);
+#ifndef SC_NO_PALETTE_LOADING
+ if (ISGRAPHSC(sc->old_scp))
+ load_palette(sc->adp, sc->palette);
#endif
- set_border(new_scp, new_scp->border);
+ set_border(scp, scp->border);
/* set up the keyboard for the new screen */
- if (old_scp->kbd_mode != new_scp->kbd_mode)
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&new_scp->kbd_mode);
- update_kbd_state(new_scp->status, LOCK_MASK);
+ if (sc->old_scp->kbd_mode != scp->kbd_mode)
+ kbd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ update_kbd_state(scp, scp->status, LOCK_MASK);
- delayed_next_scr = FALSE;
- mark_all(new_scp);
+ mark_all(scp);
}
static void
@@ -2609,25 +2423,24 @@ scan_esc(scr_stat *scp, u_char c)
{
static u_char ansi_col[16] =
{0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15};
+ sc_softc_t *sc;
int i, n;
- u_short *src, *dst, count;
-#ifdef PC98
- u_short *src_attr, *dst_attr;
-#endif
+ int count;
+ sc = scp->sc;
if (scp->term.esc == 1) { /* seen ESC */
#ifdef KANJI
- switch (scp->kanji_type) {
+ switch (scp->md.kanji_type) {
case KTYPE_KANIN: /* Kanji Invoke sequence */
switch (c) {
case 'B':
case '@':
- scp->kanji_type = KTYPE_7JIS;
+ scp->md.kanji_type = KTYPE_7JIS;
scp->term.esc = 0;
- scp->kanji_1st_char = 0;
+ scp->md.kanji_1st_char = 0;
return;
default:
- scp->kanji_type = KTYPE_ASCII;
+ scp->md.kanji_type = KTYPE_ASCII;
scp->term.esc = 0;
break;
}
@@ -2637,17 +2450,17 @@ scan_esc(scr_stat *scp, u_char c)
case 'J':
case 'B':
case 'H':
- scp->kanji_type = KTYPE_ASCII;
+ scp->md.kanji_type = KTYPE_ASCII;
scp->term.esc = 0;
- scp->kanji_1st_char = 0;
+ scp->md.kanji_1st_char = 0;
return;
case 'I':
- scp->kanji_type = KTYPE_JKANA;
+ scp->md.kanji_type = KTYPE_JKANA;
scp->term.esc = 0;
- scp->kanji_1st_char = 0;
+ scp->md.kanji_1st_char = 0;
return;
default:
- scp->kanji_type = KTYPE_ASCII;
+ scp->md.kanji_type = KTYPE_ASCII;
scp->term.esc = 0;
break;
}
@@ -2655,7 +2468,7 @@ scan_esc(scr_stat *scp, u_char c)
default:
break;
}
-#endif
+#endif /* KANJI */
switch (c) {
case '7': /* Save cursor position */
@@ -2678,7 +2491,7 @@ scan_esc(scr_stat *scp, u_char c)
#ifdef KANJI
case '$': /* Kanji Invoke sequence */
- scp->kanji_type = KTYPE_KANIN;
+ scp->md.kanji_type = KTYPE_KANIN;
return;
#endif
@@ -2686,21 +2499,8 @@ scan_esc(scr_stat *scp, u_char c)
if (scp->ypos > 0)
move_crsr(scp, scp->xpos, scp->ypos - 1);
else {
-#ifdef PC98
- bcopy(scp->scr_buf, scp->scr_buf + scp->xsize,
- (scp->ysize - 1) * scp->xsize * sizeof(u_short));
- bcopy(scp->atr_buf, scp->atr_buf + scp->xsize,
- (scp->ysize - 1) * scp->xsize * sizeof(u_short));
- fillw(scr_map[0x20],
- scp->scr_buf, scp->xsize);
- fillw(at2pc98(scp->term.cur_color),
- scp->atr_buf, scp->xsize);
-#else
- bcopy(scp->scr_buf, scp->scr_buf + scp->xsize,
- (scp->ysize - 1) * scp->xsize * sizeof(u_short));
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf, scp->xsize);
-#endif
+ sc_vtb_ins(&scp->vtb, 0, scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
}
break;
@@ -2715,7 +2515,7 @@ scan_esc(scr_stat *scp, u_char c)
case '(': /* iso-2022: designate 94 character set to G0 */
#ifdef KANJI
- scp->kanji_type = KTYPE_ASCIN;
+ scp->md.kanji_type = KTYPE_ASCIN;
#else
scp->term.esc = 5;
#endif
@@ -2796,57 +2596,24 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0];
switch (n) {
case 0: /* clear form cursor to end of display */
-#ifdef PC98
- fillw(scr_map[0x20],
- scp->cursor_pos,
- scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos);
- fillw(at2pc98(scp->term.cur_color),
- scp->cursor_atr,
- scp->atr_buf + scp->xsize * scp->ysize - scp->cursor_atr);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos,
- scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos,
+ scp->xsize * scp->ysize - scp->cursor_pos,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
mark_for_update(scp, scp->xsize * scp->ysize - 1);
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
break;
case 1: /* clear from beginning of display to cursor */
-#ifdef PC98
- fillw(scr_map[0x20],
- scp->scr_buf,
- scp->cursor_pos - scp->scr_buf);
- fillw(at2pc98(scp->term.cur_color),
- scp->atr_buf,
- scp->cursor_atr - scp->atr_buf);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf,
- scp->cursor_pos - scp->scr_buf);
-#endif
- mark_for_update(scp, 0);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
- remove_cutmarking(scp);
+ sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, 0);
+ mark_for_update(scp, scp->cursor_pos);
+ sc_remove_cutmarking(scp);
break;
case 2: /* clear entire display */
-#ifdef PC98
- fillw(scr_map[0x20], scp->scr_buf,
- scp->xsize * scp->ysize);
- fillw(at2pc98(scp->term.cur_color), scp->atr_buf,
- scp->xsize * scp->ysize);
-#else
- fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf,
- scp->xsize * scp->ysize);
-#endif
+ sc_vtb_clear(&scp->vtb, sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
break;
}
break;
@@ -2858,61 +2625,24 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0];
switch (n) {
case 0: /* clear form cursor to end of line */
-#ifdef PC98
- fillw(scr_map[0x20],
- scp->cursor_pos,
- scp->xsize - scp->xpos);
- fillw(at2pc98(scp->term.cur_color),
- scp->cursor_atr,
- scp->xsize - scp->xpos);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos,
- scp->xsize - scp->xpos);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf +
- scp->xsize - 1 - scp->xpos);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf +
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos,
+ scp->xsize - scp->xpos,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos +
scp->xsize - 1 - scp->xpos);
-#endif
break;
case 1: /* clear from beginning of line to cursor */
-#ifdef PC98
- fillw(scr_map[0x20],
- scp->cursor_pos - scp->xpos,
- scp->xpos + 1);
- fillw(at2pc98(scp->term.cur_color),
- scp->cursor_atr - scp->xpos,
- scp->xpos + 1);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos - scp->xpos,
- scp->xpos + 1);
-#endif
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
+ scp->xpos + 1,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
break;
case 2: /* clear entire line */
-#ifdef PC98
- fillw(scr_map[0x20],
- scp->cursor_pos - scp->xpos,
- scp->xsize);
- fillw(at2pc98(scp->term.cur_color),
- scp->cursor_atr - scp->xpos,
- scp->xsize);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos - scp->xpos,
- scp->xsize);
-#endif
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
+ scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1);
break;
@@ -2923,22 +2653,8 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize - scp->ypos)
n = scp->ysize - scp->ypos;
- src = scp->scr_buf + scp->ypos * scp->xsize;
- dst = src + n * scp->xsize;
- count = scp->ysize - (scp->ypos + n);
- bcopy(src, dst, count * scp->xsize * sizeof(u_short));
-#ifdef PC98
- src_attr = scp->atr_buf + scp->ypos * scp->xsize;
- dst_attr = src_attr + n * scp->xsize;
- bcopy(src_attr, dst_attr, count * scp->xsize * sizeof(u_short));
- fillw(scr_map[0x20], src,
- n * scp->xsize);
- fillw(at2pc98(scp->term.cur_color), src_attr,
- n * scp->xsize);
-#else
- fillw(scp->term.cur_color | scr_map[0x20], src,
- n * scp->xsize);
-#endif
+ sc_vtb_ins(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
@@ -2947,24 +2663,8 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize - scp->ypos)
n = scp->ysize - scp->ypos;
- dst = scp->scr_buf + scp->ypos * scp->xsize;
- src = dst + n * scp->xsize;
- count = scp->ysize - (scp->ypos + n);
- bcopy(src, dst, count * scp->xsize * sizeof(u_short));
- src = dst + count * scp->xsize;
-#ifdef PC98
- dst_attr = scp->atr_buf + scp->ypos * scp->xsize;
- src_attr = dst_attr + n * scp->xsize;
- bcopy(src_attr, dst_attr, count * scp->xsize * sizeof(u_short));
- src_attr = dst_attr + count * scp->xsize;
- fillw(scr_map[0x20], src,
- n * scp->xsize);
- fillw(at2pc98(scp->term.cur_color), src_attr,
- n * scp->xsize);
-#else
- fillw(scp->term.cur_color | scr_map[0x20], src,
- n * scp->xsize);
-#endif
+ sc_vtb_delete(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
@@ -2973,80 +2673,30 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos)
n = scp->xsize - scp->xpos;
- dst = scp->cursor_pos;
- src = dst + n;
count = scp->xsize - (scp->xpos + n);
- bcopy(src, dst, count * sizeof(u_short));
- src = dst + count;
-#ifdef PC98
- dst_attr = scp->cursor_atr;
- src_attr = dst_attr + n;
- bcopy(src_attr, dst_attr, count * sizeof(u_short));
- src_attr = dst_attr + count;
- fillw(scr_map[0x20], src, n);
- fillw(at2pc98(scp->term.cur_color), src_attr, n);
-#else
- fillw(scp->term.cur_color | scr_map[0x20], src, n);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count - 1);
-#endif
+ sc_vtb_delete(&scp->vtb, scp->cursor_pos, n,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n + count - 1);
break;
case '@': /* Insert n chars */
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos)
n = scp->xsize - scp->xpos;
- src = scp->cursor_pos;
- dst = src + n;
count = scp->xsize - (scp->xpos + n);
- bcopy(src, dst, count * sizeof(u_short));
-#ifdef PC98
- src_attr = scp->cursor_atr;
- dst_attr = src_attr + n;
- bcopy(src_attr, dst_attr, count * sizeof(u_short));
- fillw(scr_map[0x20], src, n);
- fillw(at2pc98(scp->term.cur_color), src_attr, n);
-#else
- fillw(scp->term.cur_color | scr_map[0x20], src, n);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count - 1);
-#endif
+ sc_vtb_ins(&scp->vtb, scp->cursor_pos, n,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n + count - 1);
break;
case 'S': /* scroll up n lines */
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize)
n = scp->ysize;
- bcopy(scp->scr_buf + (scp->xsize * n),
- scp->scr_buf,
- scp->xsize * (scp->ysize - n) * sizeof(u_short));
-#ifdef PC98
- bcopy(scp->atr_buf + (scp->xsize * n),
- scp->atr_buf,
- scp->xsize * (scp->ysize - n) * sizeof(u_short));
- fillw(scr_map[0x20],
- scp->scr_buf + scp->xsize * (scp->ysize - n),
- scp->xsize * n);
- fillw(at2pc98(scp->term.cur_color),
- scp->atr_buf + scp->xsize * (scp->ysize - n),
- scp->xsize * n);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf + scp->xsize * (scp->ysize - n),
- scp->xsize * n);
-#endif
+ sc_vtb_delete(&scp->vtb, 0, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
break;
@@ -3054,23 +2704,8 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize)
n = scp->ysize;
- bcopy(scp->scr_buf,
- scp->scr_buf + (scp->xsize * n),
- scp->xsize * (scp->ysize - n) *
- sizeof(u_short));
-#ifdef PC98
- bcopy(scp->atr_buf,
- scp->atr_buf + (scp->xsize * n),
- scp->xsize * (scp->ysize - n) *
- sizeof(u_short));
- fillw(scr_map[0x20],
- scp->scr_buf, scp->xsize * n);
- fillw(at2pc98(scp->term.cur_color),
- scp->atr_buf, scp->xsize * n);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf, scp->xsize * n);
-#endif
+ sc_vtb_ins(&scp->vtb, 0, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
break;
@@ -3078,23 +2713,10 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos)
n = scp->xsize - scp->xpos;
-#ifdef PC98
- fillw(scr_map[0x20],
- scp->cursor_pos, n);
- fillw(at2pc98(scp->term.cur_color),
- scp->cursor_atr, n);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos, n);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n - 1);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n - 1);
-#endif
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n - 1);
break;
case 'Z': /* move n tabs backwards */
@@ -3243,7 +2865,7 @@ scan_esc(scr_stat *scp, u_char c)
case 'z': /* switch to (virtual) console n */
if (scp->term.num_param == 1)
- switch_scr(scp, scp->term.param[0]);
+ switch_scr(sc, scp->term.param[0]);
break;
}
}
@@ -3271,8 +2893,8 @@ scan_esc(scr_stat *scp, u_char c)
case 'A': /* set display border color */
if (scp->term.num_param == 1) {
scp->border=scp->term.param[0] & 0xff;
- if (scp == cur_console)
- set_border(cur_console, scp->border);
+ if (scp == sc->cur_scp)
+ set_border(scp, scp->border);
}
break;
@@ -3284,38 +2906,32 @@ scan_esc(scr_stat *scp, u_char c)
break;
case 'C': /* set cursor type & shape */
+ if (!ISGRAPHSC(sc->cur_scp))
+ remove_cursor_image(sc->cur_scp);
if (scp->term.num_param == 1) {
if (scp->term.param[0] & 0x01)
- sc_flags |= BLINK_CURSOR;
+ sc->flags |= SC_BLINK_CURSOR;
else
- sc_flags &= ~BLINK_CURSOR;
-#ifdef PC98
+ sc->flags &= ~SC_BLINK_CURSOR;
if (scp->term.param[0] & 0x02)
- sc_flags |= CHAR_CURSOR;
- else
- sc_flags &= ~CHAR_CURSOR;
-#else /* PC98 */
- if ((scp->term.param[0] & 0x02)
- && ISFONTAVAIL(scp->adp->va_flags))
- sc_flags |= CHAR_CURSOR;
+ sc->flags |= SC_CHAR_CURSOR;
else
- sc_flags &= ~CHAR_CURSOR;
-#endif /* PC98 */
+ sc->flags &= ~SC_CHAR_CURSOR;
}
else if (scp->term.num_param == 2) {
- scp->cursor_start = scp->term.param[0] & 0x1F;
- scp->cursor_end = scp->term.param[1] & 0x1F;
+ sc->cursor_base = scp->font_size
+ - (scp->term.param[1] & 0x1F) - 1;
+ sc->cursor_height = (scp->term.param[1] & 0x1F)
+ - (scp->term.param[0] & 0x1F) + 1;
}
/*
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!ISGRAPHSC(cur_console)) {
+ if (!ISGRAPHSC(sc->cur_scp)) {
i = spltty();
- remove_cursor_image(cur_console);
- if (sc_flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- draw_cursor_image(cur_console);
+ sc_set_cursor_image(sc->cur_scp);
+ draw_cursor_image(sc->cur_scp);
splx(i);
}
break;
@@ -3544,77 +3160,90 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l)
return (tmp);
}
-#endif
+#endif /* KANJI */
static void
ansi_put(scr_stat *scp, u_char *buf, int len)
{
u_char *ptr = buf;
#ifdef KANJI
- u_short i, kanji_code;
+ u_short kanji_code;
#endif
/* make screensaver happy */
- if (!sticky_splash && scp == cur_console)
+ if (!sticky_splash && scp == scp->sc->cur_scp)
run_scrn_saver = FALSE;
- write_in_progress++;
outloop:
+ scp->sc->write_in_progress++;
if (scp->term.esc) {
scan_esc(scp, *ptr++);
len--;
}
else if (PRINTABLE(*ptr)) { /* Print only printables */
-#ifndef PC98
- int cnt = len <= (scp->xsize-scp->xpos) ? len : (scp->xsize-scp->xpos);
+ vm_offset_t p;
+ u_char *map;
+ int attr;
+ int i;
+#ifdef KANJI
+ u_char c;
+#else
+ int cnt;
#endif
- u_short cur_attr = scp->term.cur_attr;
- u_short *cursor_pos = scp->cursor_pos;
-#ifdef PC98
- u_char c = *ptr;
- u_short *cursor_atr = scp->cursor_atr;
+
+ p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
+ map = scp->sc->scr_map;
+ attr = scp->term.cur_attr;
+
#ifdef KANJI
- if (scp->kanji_1st_char == 0) {
- scp->kanji_type = iskanji1(scp->kanji_type, c);
- if (!IS_KTYPE_ASCII_or_HANKAKU(scp->kanji_type)) {
+ c = *ptr;
+ if (scp->md.kanji_1st_char == 0) {
+ scp->md.kanji_type = iskanji1(scp->md.kanji_type, c);
+ if (!IS_KTYPE_ASCII_or_HANKAKU(scp->md.kanji_type)) {
/* not Ascii & not HANKAKU */
- scp->kanji_1st_char = c;
- ptr++; len--;
+ scp->md.kanji_1st_char = c;
goto kanji_end;
} else {
- scp->kanji_1st_char = 0;
+ scp->md.kanji_1st_char = 0;
}
} else {
- if ((scp->kanji_type = iskanji2(scp->kanji_type, c)) & 0xee) {
+ if ((scp->md.kanji_type = iskanji2(scp->md.kanji_type, c)) & 0xee) {
/* print kanji on TEXT VRAM */
- kanji_code = kanji_convert(scp->kanji_type, c, scp->kanji_1st_char);
+ kanji_code = kanji_convert(scp->md.kanji_type, c, scp->md.kanji_1st_char);
+ mark_for_update(scp, scp->cursor_pos);
for (i=0; i<2; i++){
/* *cursor_pos = (kanji_code | (i*0x80)); */
- *cursor_pos = kanji_code | ((i==0) ? 0x00 : 0x80);
- *cursor_atr = (at2pc98(cur_attr));
- cursor_pos++;
- cursor_atr++;
+ p = sc_vtb_putchar(&scp->vtb, p,
+ kanji_code | ((i == 0) ? 0x00 : 0x80),
+ attr);
+ ++scp->cursor_pos;
if (++scp->xpos >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
}
}
- KTYPE_MASK_CTRL(scp->kanji_type);
- scp->kanji_1st_char = 0;
- ptr++; len--;
+ mark_for_update(scp, scp->cursor_pos - 1);
+ KTYPE_MASK_CTRL(scp->md.kanji_type);
+ scp->md.kanji_1st_char = 0;
goto kanji_end;
} else {
- scp->kanji_1st_char = 0;
+ scp->md.kanji_1st_char = 0;
}
}
- if (IS_KTYPE_KANA(scp->kanji_type))
+ if (IS_KTYPE_KANA(scp->md.kanji_type))
c |= 0x80;
- KTYPE_MASK_CTRL(scp->kanji_type);
-#endif /* KANJI */
- *cursor_pos++ = (scr_map[c]);
- *cursor_atr++ = at2pc98(cur_attr);
- ptr++;
-#else
+ KTYPE_MASK_CTRL(scp->md.kanji_type);
+ sc_vtb_putchar(&scp->vtb, p, map[c], attr);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos);
+ ++scp->cursor_pos;
+ ++scp->xpos;
+kanji_end:
+ ++ptr;
+ --len;
+#else /* !KANJI */
+ cnt = (len <= scp->xsize - scp->xpos) ? len : (scp->xsize - scp->xpos);
+ i = cnt;
do {
/*
* gcc-2.6.3 generates poor (un)sign extension code. Casting the
@@ -3623,28 +3252,17 @@ outloop:
* (+ cache misses) on i486's.
*/
#define UCVP(ucp) ((u_char volatile *)(ucp))
- *cursor_pos++ = UCVP(scr_map)[*UCVP(ptr)] | cur_attr;
- ptr++;
- cnt--;
- } while (cnt && PRINTABLE(*ptr));
-#endif /* PC98 */
- len -= (cursor_pos - scp->cursor_pos);
- scp->xpos += (cursor_pos - scp->cursor_pos);
-#ifdef KANJI
-kanji_end:
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
- mark_for_update(scp, cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, cursor_atr - scp->atr_buf);
-#endif
- scp->cursor_pos = cursor_pos;
-#ifdef PC98
- scp->cursor_atr = cursor_atr;
-#endif
+ p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], attr);
+ ++ptr;
+ --i;
+ } while (i > 0 && PRINTABLE(*ptr));
+ len -= cnt - i;
+ mark_for_update(scp, scp->cursor_pos);
+ scp->cursor_pos += cnt - i;
+ mark_for_update(scp, scp->cursor_pos - 1);
+ scp->xpos += cnt - i;
+#endif /* KANJI */
+
if (scp->xpos >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
@@ -3657,19 +3275,10 @@ kanji_end:
break;
case 0x08: /* non-destructive backspace */
- if (scp->cursor_pos > scp->scr_buf) {
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ if (scp->cursor_pos > 0) {
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos--;
-#ifdef PC98
- scp->cursor_atr--;
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
if (scp->xpos > 0)
scp->xpos--;
else {
@@ -3680,18 +3289,9 @@ kanji_end:
break;
case 0x09: /* non-destructive tab */
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos += (8 - scp->xpos % 8u);
-#ifdef PC98
- scp->cursor_atr += (8 - scp->xpos % 8u);
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
if ((scp->xpos += (8 - scp->xpos % 8u)) >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
@@ -3699,18 +3299,9 @@ kanji_end:
break;
case 0x0a: /* newline, same pos */
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos += scp->xsize;
-#ifdef PC98
- scp->cursor_atr += scp->xsize;
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
scp->ypos++;
break;
@@ -3719,34 +3310,25 @@ kanji_end:
break;
case 0x0d: /* return, return to pos 0 */
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos -= scp->xpos;
-#ifdef PC98
- scp->cursor_atr -= scp->xpos;
-#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
-#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
-#endif
+ mark_for_update(scp, scp->cursor_pos);
scp->xpos = 0;
break;
#ifdef PC98
case 0x0e: /* ^N */
- scp->kanji_type = KTYPE_JKANA;
+ scp->md.kanji_type = KTYPE_JKANA;
scp->term.esc = 0;
- scp->kanji_1st_char = 0;
+ scp->md.kanji_1st_char = 0;
break;
case 0x0f: /* ^O */
- scp->kanji_type = KTYPE_ASCII;
+ scp->md.kanji_type = KTYPE_ASCII;
scp->term.esc = 0;
- scp->kanji_1st_char = 0;
+ scp->md.kanji_1st_char = 0;
break;
-#endif
+#endif /* PC98 */
case 0x1b: /* start escape sequence */
scp->term.esc = 1;
@@ -3756,161 +3338,381 @@ kanji_end:
ptr++; len--;
}
/* do we have to scroll ?? */
- if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) {
- remove_cutmarking(scp);
- if (scp->history != NULL) {
- bcopy(scp->scr_buf, scp->history_head,
- scp->xsize * sizeof(u_short));
- scp->history_head += scp->xsize;
-#ifdef PC98
- bcopy(scp->atr_buf, scp->his_atr_head,
- scp->xsize * sizeof(u_short));
- scp->his_atr_head += scp->xsize;
-#endif
- if (scp->history_head + scp->xsize >
- scp->history + scp->history_size)
-#ifdef PC98
- {
-#endif
- scp->history_head = scp->history;
-#ifdef PC98
- scp->his_atr_head = scp->his_atr;
- }
-#endif
- }
- bcopy(scp->scr_buf + scp->xsize, scp->scr_buf,
- scp->xsize * (scp->ysize - 1) * sizeof(u_short));
-#ifdef PC98
- bcopy(scp->atr_buf + scp->xsize, scp->atr_buf,
- scp->xsize * (scp->ysize - 1) * sizeof(u_short));
- fillw(scr_map[0x20],
- scp->scr_buf + scp->xsize * (scp->ysize - 1),
- scp->xsize);
- fillw(at2pc98(scp->term.cur_color),
- scp->atr_buf + scp->xsize * (scp->ysize - 1),
- scp->xsize);
-#else
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf + scp->xsize * (scp->ysize - 1),
- scp->xsize);
-#endif
-
+ if (scp->cursor_pos >= scp->ysize * scp->xsize) {
+ sc_remove_cutmarking(scp);
+#ifndef SC_NO_HISTORY
+ if (scp->history != NULL)
+ sc_hist_save_one_line(scp, 0);
+#endif
+ sc_vtb_delete(&scp->vtb, 0, scp->xsize,
+ scp->sc->scr_map[0x20], scp->term.cur_color);
scp->cursor_pos -= scp->xsize;
-#ifdef PC98
- scp->cursor_atr -= scp->xsize;
-#endif
scp->ypos--;
mark_all(scp);
}
+ scp->sc->write_in_progress--;
if (len)
goto outloop;
- write_in_progress--;
- if (delayed_next_scr)
- switch_scr(scp, delayed_next_scr - 1);
+ if (scp->sc->delayed_next_scr)
+ switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
+}
+
+static void
+draw_cursor_image(scr_stat *scp)
+{
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_pos,
+ scp->sc->flags & SC_BLINK_CURSOR, TRUE,
+ sc_inside_cutmark(scp, scp->cursor_pos));
+ --scp->sc->videoio_in_progress;
}
static void
-scinit(void)
+remove_cursor_image(scr_stat *scp)
+{
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos,
+ scp->sc->flags & SC_BLINK_CURSOR, FALSE,
+ sc_inside_cutmark(scp, scp->cursor_oldpos));
+ --scp->sc->videoio_in_progress;
+}
+
+static void
+update_cursor_image(scr_stat *scp)
{
+ int blink;
+
+ if (scp->sc->flags & SC_CHAR_CURSOR) {
+ scp->cursor_base = scp->sc->cursor_base;
+ scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size);
+ } else {
+ scp->cursor_base = 0;
+ scp->cursor_height = scp->font_size;
+ }
+ blink = scp->sc->flags & SC_BLINK_CURSOR;
+
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos, blink, FALSE,
+ sc_inside_cutmark(scp, scp->cursor_pos));
+ (*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height, blink);
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_pos, blink, TRUE,
+ sc_inside_cutmark(scp, scp->cursor_pos));
+ --scp->sc->videoio_in_progress;
+}
+
+void
+sc_set_cursor_image(scr_stat *scp)
+{
+ if (scp->sc->flags & SC_CHAR_CURSOR) {
+ scp->cursor_base = scp->sc->cursor_base;
+ scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size);
+ } else {
+ scp->cursor_base = 0;
+ scp->cursor_height = scp->font_size;
+ }
+
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height,
+ scp->sc->flags & SC_BLINK_CURSOR);
+ --scp->sc->videoio_in_progress;
+}
+
+static void
+move_crsr(scr_stat *scp, int x, int y)
+{
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+ if (x >= scp->xsize)
+ x = scp->xsize-1;
+ if (y >= scp->ysize)
+ y = scp->ysize-1;
+ scp->xpos = x;
+ scp->ypos = y;
+ scp->cursor_pos = scp->ypos * scp->xsize + scp->xpos;
+}
+
+static void
+scinit(int unit, int flags)
+{
+ /*
+ * When syscons is being initialized as the kernel console, malloc()
+ * is not yet functional, because various kernel structures has not been
+ * fully initialized yet. Therefore, we need to declare the following
+ * static buffers for the console. This is less than ideal,
+ * but is necessry evil for the time being. XXX
+ */
+ static scr_stat main_console;
+ static scr_stat *main_vtys[MAXCONS];
+ static struct tty main_tty[MAXCONS];
+#ifndef PC98
+ static u_short sc_buffer[ROW*COL]; /* XXX */
+#else
+ static u_short sc_buffer[ROW*COL*2];/* XXX */
+#endif
+#ifdef DEVFS
+ static void *main_devfs_token[MAXCONS];
+#endif
+#ifndef SC_NO_FONT_LOADING
+ static u_char font_8[256*8];
+ static u_char font_14[256*14];
+ static u_char font_16[256*16];
+#endif
+
+ sc_softc_t *sc;
+ scr_stat *scp;
video_adapter_t *adp;
int col;
int row;
- u_int i;
+ int i;
- if (init_done != COLD)
- return;
+ /* one time initialization */
+ if (init_done == COLD) {
+ sc_get_bios_values(&bios_value);
+ current_default = &user_default;
+ /* kernel console attributes */
+ kernel_console.esc = 0;
+ kernel_console.attr_mask = NORMAL_ATTR;
+ kernel_console.cur_attr =
+ kernel_console.cur_color = kernel_console.std_color =
+ kernel_default.std_color;
+ kernel_console.rev_color = kernel_default.rev_color;
+ }
init_done = WARM;
- get_bios_values();
+ /*
+ * Allocate resources. Even if we are being called for the second
+ * time, we must allocate them again, because they might have
+ * disappeared...
+ */
+ sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
+ adp = NULL;
+ if (sc->adapter >= 0) {
+ vid_release(sc->adp, (void *)&sc->adapter);
+ adp = sc->adp;
+ sc->adp = NULL;
+ }
+ if (sc->keyboard >= 0) {
+ DPRINTF(5, ("sc%d: releasing kbd%d\n", unit, sc->keyboard));
+ i = kbd_release(sc->kbd, (void *)&sc->keyboard);
+ DPRINTF(5, ("sc%d: kbd_release returned %d\n", unit, i));
+ if (sc->kbd != NULL) {
+ DPRINTF(5, ("sc%d: kbd != NULL!, index:%d, minor:%d, flags:0x%x\n",
+ unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags));
+ }
+ sc->kbd = NULL;
+ }
+ sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter);
+ sc->adp = vid_get_adapter(sc->adapter);
+ /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */
+ sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard,
+ sckbdevent, sc);
+ DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard));
+ sc->kbd = kbd_get_keyboard(sc->keyboard);
+ if (sc->kbd != NULL) {
+ DPRINTF(1, ("sc%d: kbd index:%d, minor:%d, flags:0x%x\n",
+ unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags));
+ }
+
+ if (!(sc->flags & SC_INIT_DONE) || (adp != sc->adp)) {
-#ifdef PC98
- if (pc98_machine_type & M_8M)
- BELL_PITCH = 1339;
- else
- BELL_PITCH = 1678;
+ sc->initial_mode = sc->adp->va_initial_mode;
+
+#ifndef SC_NO_FONT_LOADING
+ if (flags & SC_KERNEL_CONSOLE) {
+ sc->font_8 = font_8;
+ sc->font_14 = font_14;
+ sc->font_16 = font_16;
+ } else if (sc->font_8 == NULL) {
+ /* assert(sc_malloc) */
+ sc->font_8 = malloc(sizeof(font_8), M_DEVBUF, M_WAITOK);
+ sc->font_14 = malloc(sizeof(font_14), M_DEVBUF, M_WAITOK);
+ sc->font_16 = malloc(sizeof(font_16), M_DEVBUF, M_WAITOK);
+ }
#endif
- /* extract the hardware cursor location and hide the cursor for now */
- adp = vid_get_adapter(adapter);
- (*vidsw[adapter]->read_hw_cursor)(adp, &col, &row);
-#ifndef PC98
- (*vidsw[adapter]->set_hw_cursor)(adp, -1, -1);
+ /* extract the hardware cursor location and hide the cursor for now */
+ (*vidsw[sc->adapter]->read_hw_cursor)(sc->adp, &col, &row);
+ (*vidsw[sc->adapter]->set_hw_cursor)(sc->adp, -1, -1);
+
+ /* set up the first console */
+ sc->first_vty = unit*MAXCONS;
+ if (flags & SC_KERNEL_CONSOLE) {
+ sc->vtys = sizeof(main_vtys)/sizeof(main_vtys[0]);
+ sc->tty = main_tty;
+#ifdef DEVFS
+ sc->devfs_token = main_devfs_token;
#endif
+ sc->console = main_vtys;
+ scp = main_vtys[0] = &main_console;
+ init_scp(sc, sc->first_vty, scp);
+ sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize, scp->ysize,
+ (void *)sc_buffer, FALSE);
+ } else {
+ /* assert(sc_malloc) */
+ sc->vtys = MAXCONS;
+ sc->tty = malloc(sizeof(struct tty)*MAXCONS, M_DEVBUF, M_WAITOK);
+ bzero(sc->tty, sizeof(struct tty)*MAXCONS);
+#ifdef DEVFS
+ sc->devfs_token = malloc(sizeof(void *)*MAXCONS,
+ M_DEVBUF, M_WAITOK);
+#endif
+ sc->console = malloc(sizeof(struct scr_stat *)*MAXCONS,
+ M_DEVBUF, M_WAITOK);
+ scp = sc->console[0] = alloc_scp(sc, sc->first_vty);
+ }
+ sc->cur_scp = scp;
+
+ /* copy screen to temporary buffer */
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+ (void *)scp->sc->adp->va_window, FALSE);
+ if (ISTEXTSC(scp))
+ sc_vtb_copy(&scp->scr, 0, &scp->vtb, 0, scp->xsize*scp->ysize);
+
+ /* move cursors to the initial positions */
+ scp->mouse_pos = scp->mouse_oldpos = 0;
+ if (col >= scp->xsize)
+ col = 0;
+ if (row >= scp->ysize)
+ row = scp->ysize - 1;
+ scp->xpos = col;
+ scp->ypos = row;
+ scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
+ if (bios_value.cursor_end < scp->font_size)
+ sc->cursor_base = scp->font_size - bios_value.cursor_end - 1;
+ else
+ sc->cursor_base = 0;
+ i = bios_value.cursor_end - bios_value.cursor_start + 1;
+ sc->cursor_height = imin(i, scp->font_size);
+ if (!ISGRAPHSC(scp)) {
+ sc_set_cursor_image(scp);
+ draw_cursor_image(scp);
+ }
- /* set up the first console */
- current_default = &user_default;
- console[0] = &main_console;
- init_scp(console[0]);
- cur_console = console[0];
-
- /* copy screen to temporary buffer */
- if (ISTEXTSC(console[0]))
- generic_bcopy((ushort *)(console[0]->adp->va_window), sc_buffer,
- console[0]->xsize * console[0]->ysize * sizeof(u_short));
-
- console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
- = sc_buffer;
- if (col >= console[0]->xsize)
- col = 0;
- if (row >= console[0]->ysize)
- row = console[0]->ysize - 1;
- console[0]->xpos = col;
- console[0]->ypos = row;
- console[0]->cursor_pos = console[0]->cursor_oldpos =
- sc_buffer + row*console[0]->xsize + col;
-#ifndef PC98
- console[0]->cursor_saveunder = *console[0]->cursor_pos;
-#else
- console[0]->atr_buf = Atrat;
- console[0]->cursor_atr = Atrat + row*console[0]->xsize + col;
+ /* save font and palette */
+#ifndef SC_NO_FONT_LOADING
+ sc->fonts_loaded = 0;
+ if (ISFONTAVAIL(sc->adp->va_flags)) {
+#ifdef SC_DFLT_FONT
+ bcopy(dflt_font_8, sc->font_8, sizeof(dflt_font_8));
+ bcopy(dflt_font_14, sc->font_14, sizeof(dflt_font_14));
+ bcopy(dflt_font_16, sc->font_16, sizeof(dflt_font_16));
+ sc->fonts_loaded = FONT_16 | FONT_14 | FONT_8;
+ if (scp->font_size < 14) {
+ copy_font(scp, LOAD, 8, sc->font_8);
+ sc->fonts_loaded = FONT_8;
+ } else if (scp->font_size >= 16) {
+ copy_font(scp, LOAD, 16, sc->font_16);
+ sc->fonts_loaded = FONT_16;
+ } else {
+ copy_font(scp, LOAD, 14, sc->font_14);
+ sc->fonts_loaded = FONT_14;
+ }
+#else /* !SC_DFLT_FONT */
+ if (scp->font_size < 14) {
+ copy_font(scp, SAVE, 8, sc->font_8);
+ sc->fonts_loaded = FONT_8;
+ } else if (scp->font_size >= 16) {
+ copy_font(scp, SAVE, 16, sc->font_16);
+ sc->fonts_loaded = FONT_16;
+ } else {
+ copy_font(scp, SAVE, 14, sc->font_14);
+ sc->fonts_loaded = FONT_14;
+ }
+#endif /* SC_DFLT_FONT */
+ /* FONT KLUDGE: always use the font page #0. XXX */
+ (*vidsw[sc->adapter]->show_font)(sc->adp, 0);
+ }
+#endif /* !SC_NO_FONT_LOADING */
+
+#ifndef SC_NO_PALETTE_LOADING
+ save_palette(sc->adp, sc->palette);
#endif
- for (i=1; i<MAXCONS; i++)
- console[i] = NULL;
- kernel_console.esc = 0;
- kernel_console.attr_mask = NORMAL_ATTR;
- kernel_console.cur_attr =
- kernel_console.cur_color = kernel_console.std_color =
- kernel_default.std_color;
- kernel_console.rev_color = kernel_default.rev_color;
- /* initialize mapscrn arrays to a one to one map */
- for (i=0; i<sizeof(scr_map); i++) {
- scr_map[i] = scr_rmap[i] = i;
+#if NSPLASH > 0
+ if (!(sc->flags & SC_SPLASH_SCRN) && (flags & SC_KERNEL_CONSOLE)) {
+ /* we are ready to put up the splash image! */
+ splash_init(sc->adp, scsplash_callback, sc);
+ sc->flags |= SC_SPLASH_SCRN;
+ }
+#endif /* NSPLASH */
}
+
+ /* the rest is not necessary, if we have done it once */
+ if (sc->flags & SC_INIT_DONE)
+ return;
+
+ /* clear structures */
+ for (i = 1; i < sc->vtys; i++)
+ sc->console[i] = NULL;
+
+ /* initialize mapscrn arrays to a one to one map */
+ for (i = 0; i < sizeof(sc->scr_map); i++)
+ sc->scr_map[i] = sc->scr_rmap[i] = i;
#ifdef PC98
- scr_map[0x5c] = (u_char)0xfc; /* for backslash */
+ sc->scr_map[0x5c] = (u_char)0xfc; /* for backslash */
#endif
- /* Save font and palette */
- if (ISFONTAVAIL(cur_console->adp->va_flags)) {
- if (fonts_loaded & FONT_16) {
- copy_font(cur_console, LOAD, 16, font_16);
- } else {
- copy_font(cur_console, SAVE, 16, font_16);
- fonts_loaded = FONT_16;
- set_destructive_cursor(cur_console);
- }
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- (*vidsw[cur_console->ad]->show_font)(cur_console->adp, 0);
- }
- save_palette(cur_console->adp, palette);
+ sc->flags |= SC_INIT_DONE;
+}
+
+static void
+scterm(int unit, int flags)
+{
+ sc_softc_t *sc;
+
+ sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
+ if (sc == NULL)
+ return; /* shouldn't happen */
#if NSPLASH > 0
- /* we are ready to put up the splash image! */
- splash_init(cur_console->adp, scsplash_callback);
+ /* this console is no longer available for the splash screen */
+ if (sc->flags & SC_SPLASH_SCRN) {
+ splash_term(sc->adp);
+ sc->flags &= ~SC_SPLASH_SCRN;
+ }
+#endif /* NSPLASH */
+
+ /* release the keyboard and the video card */
+ if (sc->keyboard >= 0)
+ kbd_release(sc->kbd, &sc->keyboard);
+ if (sc->adapter >= 0)
+ vid_release(sc->adp, &sc->adapter);
+
+ /* clear the structure */
+ if (!(flags & SC_KERNEL_CONSOLE)) {
+ free(sc->console, M_DEVBUF);
+ free(sc->tty, M_DEVBUF);
+#ifdef DEVFS
+ free(sc->devfs_token, M_DEVBUF);
#endif
+#ifndef SC_NO_FONT_LOADING
+ free(sc->font_8, M_DEVBUF);
+ free(sc->font_14, M_DEVBUF);
+ free(sc->font_16, M_DEVBUF);
+#endif
+ /* XXX vtb, history */
+ }
+ bzero(sc, sizeof(*sc));
+ sc->keyboard = -1;
+ sc->adapter = -1;
}
static void
scshutdown(int howto, void *arg)
{
+ /* assert(sc_console != NULL) */
+
sc_touch_scrn_saver();
- if (!cold && cur_console->smode.mode == VT_AUTO
- && console[0]->smode.mode == VT_AUTO)
- switch_scr(cur_console, 0);
+ if (!cold && sc_console
+ && sc_console->sc->cur_scp->smode.mode == VT_AUTO
+ && sc_console->smode.mode == VT_AUTO)
+ switch_scr(sc_console->sc, sc_console->index);
shutdown_in_progress = TRUE;
}
@@ -3921,143 +3723,82 @@ sc_clean_up(scr_stat *scp)
sc_touch_scrn_saver();
#if NSPLASH > 0
- if ((error = wait_scrn_saver_stop()))
+ if ((error = wait_scrn_saver_stop(scp->sc)))
return error;
#endif /* NSPLASH */
scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
return 0;
}
void
-sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear)
+sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard)
{
- if (scp->scr_buf)
- free(scp->scr_buf, M_DEVBUF);
- scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
-#ifdef PC98
- if (scp->atr_buf)
- free(scp->atr_buf, M_DEVBUF);
- scp->atr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
-#endif
+ sc_vtb_t new;
+ sc_vtb_t old;
+ int s;
- if (clear) {
+ old = scp->vtb;
+ sc_vtb_init(&new, VTB_MEMORY, scp->xsize, scp->ysize, NULL, wait);
+ if (!discard && (old.vtb_flags & VTB_VALID)) {
+ /* retain the current cursor position and buffer contants */
+ scp->cursor_oldpos = scp->cursor_pos;
+ /*
+ * This works only if the old buffer has the same size as or larger
+ * than the new one. XXX
+ */
+ sc_vtb_copy(&old, 0, &new, 0, scp->xsize*scp->ysize);
+ scp->vtb = new;
+ } else {
/* clear the screen and move the text cursor to the top-left position */
+ s = splhigh();
+ scp->vtb = new;
sc_clear_screen(scp);
- } else {
- /* retain the current cursor position, but adjust pointers */
- move_crsr(scp, scp->xpos, scp->ypos);
- scp->cursor_oldpos = scp->cursor_pos;
+ splx(s);
+ sc_vtb_destroy(&old);
}
+#ifndef SC_NO_SYSMOUSE
/* move the mouse cursor at the center of the screen */
- sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
-}
-
-void
-sc_alloc_cut_buffer(scr_stat *scp, int wait)
-{
- if ((cut_buffer == NULL)
- || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
- if (cut_buffer != NULL)
- free(cut_buffer, M_DEVBUF);
- cut_buffer_size = scp->xsize * scp->ysize + 1;
- cut_buffer = (u_char *)malloc(cut_buffer_size,
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- if (cut_buffer != NULL)
- cut_buffer[0] = '\0';
- }
-}
-
-void
-sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
-{
- u_short *usp;
-#ifdef PC98
- u_short *atr_usp;
-#endif
-
- if (lines < scp->ysize)
- lines = scp->ysize;
-
- usp = scp->history;
- scp->history = NULL;
- if (usp != NULL) {
- free(usp, M_DEVBUF);
- if (extra > 0)
- extra_history_size += extra;
- }
-#ifdef PC98
- atr_usp = scp->his_atr;
- scp->his_atr = NULL;
- if (atr_usp != NULL)
- free(atr_usp, M_DEVBUF);
-#endif
-
- scp->history_size = lines * scp->xsize;
- if (lines > imax(sc_history_size, scp->ysize))
- extra_history_size -= lines - imax(sc_history_size, scp->ysize);
- usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- if (usp != NULL)
- bzero(usp, scp->history_size * sizeof(u_short));
- scp->history_head = scp->history_pos = usp;
- scp->history = usp;
-#ifdef PC98
- atr_usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- if (atr_usp != NULL)
- bzero(atr_usp, scp->history_size * sizeof(u_short));
- scp->his_atr_head = scp->his_atr_pos = atr_usp;
- scp->his_atr = atr_usp;
+ sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
#endif
}
static scr_stat
-*alloc_scp()
+*alloc_scp(sc_softc_t *sc, int vty)
{
scr_stat *scp;
+ /* assert(sc_malloc) */
+
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
- init_scp(scp);
+ init_scp(sc, vty, scp);
+
sc_alloc_scr_buffer(scp, TRUE, TRUE);
-#ifdef PC98
- sc_alloc_cut_buffer(scp, TRUE);
-#else /* PC98 */
- if (ISMOUSEAVAIL(scp->adp->va_flags))
+
+#ifndef SC_NO_SYSMOUSE
+ if (ISMOUSEAVAIL(sc->adp->va_flags))
sc_alloc_cut_buffer(scp, TRUE);
-#endif /* PC98 */
- sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE);
-/* SOS
-#ifndef PC98
- if (scp->adp->va_flags & V_ADP_MODECHANGE)
#endif
- set_mode(scp);
-*/
- sc_clear_screen(scp);
-#ifndef PC98
- scp->cursor_saveunder = *scp->cursor_pos;
+
+#ifndef SC_NO_HISTORY
+ sc_alloc_history_buffer(scp, 0, TRUE);
#endif
+
+ sc_clear_screen(scp);
return scp;
}
static void
-init_scp(scr_stat *scp)
+init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
{
video_info_t info;
- scp->ad = adapter;
- scp->adp = vid_get_adapter(scp->ad);
- (*vidsw[scp->ad]->get_info)(scp->adp, initial_video_mode, &info);
-
+ scp->index = vty;
+ scp->sc = sc;
scp->status = 0;
- scp->mode = initial_video_mode;
- scp->scr_buf = NULL;
-#ifdef PC98
- scp->atr_buf = NULL;
-#endif
+ scp->mode = sc->initial_mode;
+ (*vidsw[sc->adapter]->get_info)(sc->adp, scp->mode, &info);
if (info.vi_flags & V_INFO_GRAPHICS) {
scp->status |= GRAPHICS_MODE;
scp->xpixel = info.vi_width;
@@ -4065,17 +3806,41 @@ init_scp(scr_stat *scp)
scp->xsize = info.vi_width/8;
scp->ysize = info.vi_height/info.vi_cheight;
scp->font_size = FONT_NONE;
+ scp->font = NULL;
} else {
scp->xsize = info.vi_width;
scp->ysize = info.vi_height;
scp->xpixel = scp->xsize*8;
scp->ypixel = scp->ysize*info.vi_cheight;
- scp->font_size = info.vi_cheight;
+ if (info.vi_cheight < 14) {
+ scp->font_size = 8;
+#ifndef SC_NO_FONT_LOADING
+ scp->font = sc->font_8;
+#else
+ scp->font = NULL;
+#endif
+ } else if (info.vi_cheight >= 16) {
+ scp->font_size = 16;
+#ifndef SC_NO_FONT_LOADING
+ scp->font = sc->font_16;
+#else
+ scp->font = NULL;
+#endif
+ } else {
+ scp->font_size = 14;
+#ifndef SC_NO_FONT_LOADING
+ scp->font = sc->font_14;
+#else
+ scp->font = NULL;
+#endif
+ }
}
+ sc_vtb_init(&scp->vtb, VTB_MEMORY, 0, 0, NULL, FALSE);
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE);
scp->xoff = scp->yoff = 0;
scp->xpos = scp->ypos = 0;
scp->saved_xpos = scp->saved_ypos = -1;
- scp->start = scp->xsize * scp->ysize;
+ scp->start = scp->xsize * scp->ysize - 1;
scp->end = 0;
scp->term.esc = 0;
scp->term.attr_mask = NORMAL_ATTR;
@@ -4084,100 +3849,34 @@ init_scp(scr_stat *scp)
current_default->std_color;
scp->term.rev_color = current_default->rev_color;
scp->border = BG_BLACK;
- scp->cursor_start = bios_value.cursor_start;
- scp->cursor_end = bios_value.cursor_end;
- scp->mouse_xpos = scp->xsize*8/2;
- scp->mouse_ypos = scp->ysize*scp->font_size/2;
- scp->mouse_cut_start = scp->mouse_cut_end = NULL;
+ scp->cursor_base = sc->cursor_base;
+ scp->cursor_height = imin(sc->cursor_height, scp->font_size);
+ scp->mouse_xpos = scp->xoff*8 + scp->xsize*8/2;
+ scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size/2;
+ scp->mouse_cut_start = scp->xsize*scp->ysize;
+ scp->mouse_cut_end = -1;
scp->mouse_signal = 0;
scp->mouse_pid = 0;
scp->mouse_proc = NULL;
scp->kbd_mode = K_XLATE;
- scp->bell_pitch = BELL_PITCH;
+ scp->bell_pitch = bios_value.bell_pitch;
scp->bell_duration = BELL_DURATION;
-#ifndef PC98
- scp->status |= (bios_value.shift_state & 0x20) ? NLKED : 0;
-#endif
+ scp->status |= (bios_value.shift_state & NLKED);
scp->status |= CURSOR_ENABLED;
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
- scp->history_head = scp->history_pos = scp->history = NULL;
-#ifdef PC98
- scp->his_atr_head = scp->his_atr_pos = scp->his_atr = NULL;
-#endif
- scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize;
+ scp->history = NULL;
+ scp->history_pos = 0;
+ scp->history_size = 0;
#ifdef KANJI
- scp->kanji_1st_char = 0;
- scp->kanji_type = KTYPE_ASCII;
+ scp->md.kanji_1st_char = 0;
+ scp->md.kanji_type = KTYPE_ASCII;
#endif
-}
-static void
-get_bios_values(void)
-{
-#ifdef PC98
- bios_value.cursor_start = 0;
- bios_value.cursor_end = 0;
- bios_value.shift_state = 0;
-#else /* !PC98 */
- bios_value.cursor_start = *(u_int8_t *)pa_to_va(0x461);
- bios_value.cursor_end = *(u_int8_t *)pa_to_va(0x460);
- bios_value.shift_state = *(u_int8_t *)pa_to_va(0x417);
-#endif
-}
-
-static void
-history_to_screen(scr_stat *scp)
-{
- int i;
-
- for (i=0; i<scp->ysize; i++)
-#ifdef PC98
- {
-#endif
- bcopy(scp->history + (((scp->history_pos - scp->history) +
- scp->history_size-((i+1)*scp->xsize))%scp->history_size),
- scp->scr_buf + (scp->xsize * (scp->ysize-1 - i)),
- scp->xsize * sizeof(u_short));
-#ifdef PC98
- bcopy(scp->his_atr + (((scp->his_atr_pos - scp->his_atr) +
- scp->history_size-((i+1)*scp->xsize))%scp->history_size),
- scp->atr_buf + (scp->xsize * (scp->ysize-1 - i)),
- scp->xsize * sizeof(u_short)); }
-#endif
- mark_all(scp);
-}
-
-static int
-history_up_line(scr_stat *scp)
-{
- if (WRAPHIST(scp, scp->history_pos, -(scp->xsize*scp->ysize)) !=
- scp->history_head) {
- scp->history_pos = WRAPHIST(scp, scp->history_pos, -scp->xsize);
-#ifdef PC98
- scp->his_atr_pos = WRAPHIST_A(scp, scp->his_atr_pos, -scp->xsize);
-#endif
- history_to_screen(scp);
- return 0;
- }
- else
- return -1;
-}
-
-static int
-history_down_line(scr_stat *scp)
-{
- if (scp->history_pos != scp->history_head) {
- scp->history_pos = WRAPHIST(scp, scp->history_pos, scp->xsize);
-#ifdef PC98
- scp->his_atr_pos = WRAPHIST_A(scp, scp->his_atr_pos, scp->xsize);
-#endif
- history_to_screen(scp);
- return 0;
- }
- else
- return -1;
+ /* what if the following call fails... XXX */
+ scp->rndr = sc_render_match(scp, scp->sc->adp,
+ scp->status & (GRAPHICS_MODE | PIXEL_MODE));
}
/*
@@ -4187,26 +3886,30 @@ history_down_line(scr_stat *scp)
* return NOKEY if there is nothing there.
*/
static u_int
-scgetc(keyboard_t *kbd, u_int flags)
+scgetc(sc_softc_t *sc, u_int flags)
{
+ scr_stat *scp;
u_int c;
int this_scr;
int f;
int i;
- if (kbd == NULL)
+ if (sc->kbd == NULL)
return NOKEY;
next_code:
+#if 1
/* I don't like this, but... XXX */
if (flags & SCGETC_CN)
- sccnupdate(cur_console);
+ sccnupdate(sc->cur_scp);
+#endif
+ scp = sc->cur_scp;
/* first see if there is something in the keyboard port */
for (;;) {
- c = kbd_read_char(kbd, !(flags & SCGETC_NONBLOCK));
+ c = kbd_read_char(sc->kbd, !(flags & SCGETC_NONBLOCK));
if (c == ERRKEY) {
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
} else if (c == NOKEY)
return c;
else
@@ -4217,112 +3920,73 @@ next_code:
if (!(c & RELKEY))
sc_touch_scrn_saver();
+#ifdef __i386__
if (!(flags & SCGETC_CN))
/* do the /dev/random device a favour */
add_keyboard_randomness(c);
+#endif
- if (cur_console->kbd_mode != K_XLATE)
+ if (scp->kbd_mode != K_XLATE)
return KEYCHAR(c);
/* if scroll-lock pressed allow history browsing */
- if (!ISGRAPHSC(cur_console) && cur_console->history
- && cur_console->status & SLKED) {
+ if (!ISGRAPHSC(scp) && scp->history && scp->status & SLKED) {
- cur_console->status &= ~CURSOR_ENABLED;
- if (!(cur_console->status & BUFFER_SAVED)) {
- cur_console->status |= BUFFER_SAVED;
- cur_console->history_save = cur_console->history_head;
-#ifdef PC98
- cur_console->his_atr_save = cur_console->his_atr_head;
-#endif
+ scp->status &= ~CURSOR_ENABLED;
+ remove_cursor_image(scp);
- /* copy screen into top of history buffer */
- for (i=0; i<cur_console->ysize; i++) {
- bcopy(cur_console->scr_buf + (cur_console->xsize * i),
- cur_console->history_head,
- cur_console->xsize * sizeof(u_short));
- cur_console->history_head += cur_console->xsize;
-#ifdef PC98
- bcopy(cur_console->atr_buf + (cur_console->xsize * i),
- cur_console->his_atr_head,
- cur_console->xsize * sizeof(u_short));
- cur_console->his_atr_head += cur_console->xsize;
-#endif
- if (cur_console->history_head + cur_console->xsize >
- cur_console->history + cur_console->history_size)
-#ifdef PC98
- {
- cur_console->history_head=cur_console->history;
- cur_console->his_atr_head=cur_console->his_atr;
- }
-#else
- cur_console->history_head=cur_console->history;
-#endif
- }
- cur_console->history_pos = cur_console->history_head;
-#ifdef PC98
- cur_console->his_atr_pos = cur_console->his_atr_head;
-#endif
- history_to_screen(cur_console);
+#ifndef SC_NO_HISTORY
+ if (!(scp->status & BUFFER_SAVED)) {
+ scp->status |= BUFFER_SAVED;
+ sc_hist_save(scp);
}
switch (c) {
/* FIXME: key codes */
case SPCLKEY | FKEY | F(49): /* home key */
- remove_cutmarking(cur_console);
- cur_console->history_pos = cur_console->history_head;
-#ifdef PC98
- cur_console->his_atr_pos = cur_console->his_atr_head;
-#endif
- history_to_screen(cur_console);
+ sc_remove_cutmarking(scp);
+ sc_hist_home(scp);
goto next_code;
case SPCLKEY | FKEY | F(57): /* end key */
- remove_cutmarking(cur_console);
- cur_console->history_pos =
- WRAPHIST(cur_console, cur_console->history_head,
- cur_console->xsize*cur_console->ysize);
-#ifdef PC98
- cur_console->his_atr_pos =
- WRAPHIST_A(cur_console, cur_console->his_atr_head,
- cur_console->xsize*cur_console->ysize);
-#endif
- history_to_screen(cur_console);
+ sc_remove_cutmarking(scp);
+ sc_hist_end(scp);
goto next_code;
case SPCLKEY | FKEY | F(50): /* up arrow key */
- remove_cutmarking(cur_console);
- if (history_up_line(cur_console))
+ sc_remove_cutmarking(scp);
+ if (sc_hist_up_line(scp))
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
goto next_code;
case SPCLKEY | FKEY | F(58): /* down arrow key */
- remove_cutmarking(cur_console);
- if (history_down_line(cur_console))
+ sc_remove_cutmarking(scp);
+ if (sc_hist_down_line(scp))
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
goto next_code;
case SPCLKEY | FKEY | F(51): /* page up key */
- remove_cutmarking(cur_console);
- for (i=0; i<cur_console->ysize; i++)
- if (history_up_line(cur_console)) {
+ sc_remove_cutmarking(scp);
+ for (i=0; i<scp->ysize; i++)
+ if (sc_hist_up_line(scp)) {
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
break;
}
goto next_code;
case SPCLKEY | FKEY | F(59): /* page down key */
- remove_cutmarking(cur_console);
- for (i=0; i<cur_console->ysize; i++)
- if (history_down_line(cur_console)) {
+ sc_remove_cutmarking(scp);
+ for (i=0; i<scp->ysize; i++)
+ if (sc_hist_down_line(scp)) {
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
break;
}
goto next_code;
}
+#endif /* SC_NO_HISTORY */
}
/*
@@ -4341,53 +4005,22 @@ next_code:
case NLK: case CLK: case ALK:
break;
case SLK:
- kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&f);
+ kbd_ioctl(sc->kbd, KDGKBSTATE, (caddr_t)&f);
if (f & SLKED) {
- cur_console->status |= SLKED;
+ scp->status |= SLKED;
} else {
- if (cur_console->status & SLKED) {
- cur_console->status &= ~SLKED;
- if (cur_console->status & BUFFER_SAVED) {
- int i;
- u_short *ptr = cur_console->history_save;
-#ifdef PC98
- u_short *ptr_a = cur_console->his_atr_save;
-#endif
-
- for (i=0; i<cur_console->ysize; i++) {
- bcopy(ptr,
- cur_console->scr_buf +
- (cur_console->xsize*i),
- cur_console->xsize * sizeof(u_short));
- ptr += cur_console->xsize;
-#ifdef PC98
- bcopy(ptr_a,
- cur_console->atr_buf +
- (cur_console->xsize*i),
- cur_console->xsize * sizeof(u_short));
- ptr_a += cur_console->xsize;
-#endif
- if (ptr + cur_console->xsize >
- cur_console->history +
- cur_console->history_size)
-#ifdef PC98
- {
- ptr = cur_console->history;
- ptr_a = cur_console->his_atr;
- }
-#else
- ptr = cur_console->history;
-#endif
- }
- cur_console->status &= ~BUFFER_SAVED;
- cur_console->history_head=cur_console->history_save;
-#ifdef PC98
- cur_console->his_atr_head=cur_console->his_atr_save;
-#endif
- cur_console->status |= CURSOR_ENABLED;
- mark_all(cur_console);
+ if (scp->status & SLKED) {
+ scp->status &= ~SLKED;
+#ifndef SC_NO_HISTORY
+ if (scp->status & BUFFER_SAVED) {
+ if (!sc_hist_restore(scp))
+ sc_remove_cutmarking(scp);
+ scp->status &= ~BUFFER_SAVED;
+ scp->status |= CURSOR_ENABLED;
+ draw_cursor_image(scp);
}
- scstart(VIRTUAL_TTY(get_scr_num()));
+#endif
+ scstart(VIRTUAL_TTY(sc, scp->index));
}
}
break;
@@ -4399,27 +4032,29 @@ next_code:
break;
case BTAB:
- return c;
+ if (!(sc->flags & SC_SCRN_BLANKED))
+ return c;
+ break;
case SPSC:
+#if NSPLASH > 0
/* force activatation/deactivation of the screen saver */
- if (!scrn_blanked) {
+ if (!(sc->flags & SC_SCRN_BLANKED)) {
run_scrn_saver = TRUE;
- scrn_time_stamp -= scrn_blank_time;
+ sc->scrn_time_stamp -= scrn_blank_time;
}
-#if NSPLASH > 0
if (cold) {
/*
* While devices are being probed, the screen saver need
* to be invoked explictly. XXX
*/
- if (scrn_blanked) {
+ if (sc->flags & SC_SCRN_BLANKED) {
scsplash_stick(FALSE);
- stop_scrn_saver(current_saver);
+ stop_scrn_saver(sc, current_saver);
} else {
- if (!ISGRAPHSC(cur_console)) {
+ if (!ISGRAPHSC(scp)) {
scsplash_stick(TRUE);
- (*current_saver)(TRUE);
+ (*current_saver)(sc, TRUE);
}
}
}
@@ -4446,28 +4081,53 @@ next_code:
#endif
case DBG:
-#ifdef DDB /* try to switch to console 0 */
- /*
- * TRY to make sure the screen saver is stopped,
- * and the screen is updated before switching to
- * the vty0.
- */
- scrn_timer((void *)FALSE);
- if (cur_console->smode.mode == VT_AUTO &&
- console[0]->smode.mode == VT_AUTO)
- switch_scr(cur_console, 0);
+#ifndef SC_DISABLE_DDBKEY
+#ifdef DDB
+ if (debugger)
+ break;
+ /* try to switch to the kernel console screen */
+ if (sc_console) {
+ /*
+ * TRY to make sure the screen saver is stopped,
+ * and the screen is updated before switching to
+ * the vty0.
+ */
+ scrn_timer(NULL);
+ if (!cold
+ && sc_console->sc->cur_scp->smode.mode == VT_AUTO
+ && sc_console->smode.mode == VT_AUTO)
+ switch_scr(sc_console->sc, sc_console->index);
+ }
Debugger("manual escape to debugger");
#else
printf("No debugger in kernel\n");
#endif
+#else /* SC_DISABLE_DDBKEY */
+ /* do nothing */
+#endif /* SC_DISABLE_DDBKEY */
break;
case NEXT:
- this_scr = get_scr_num();
- for (i = this_scr + 1; i != this_scr; i = (i + 1)%MAXCONS) {
- struct tty *tp = VIRTUAL_TTY(i);
+ this_scr = scp->index;
+ for (i = (this_scr - sc->first_vty + 1)%sc->vtys;
+ sc->first_vty + i != this_scr;
+ i = (i + 1)%sc->vtys) {
+ struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
+ if (tp->t_state & TS_ISOPEN) {
+ switch_scr(scp->sc, sc->first_vty + i);
+ break;
+ }
+ }
+ break;
+
+ case PREV:
+ this_scr = scp->index;
+ for (i = (this_scr - sc->first_vty + sc->vtys - 1)%sc->vtys;
+ sc->first_vty + i != this_scr;
+ i = (i + sc->vtys - 1)%sc->vtys) {
+ struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
if (tp->t_state & TS_ISOPEN) {
- switch_scr(cur_console, i);
+ switch_scr(scp->sc, sc->first_vty + i);
break;
}
}
@@ -4475,16 +4135,19 @@ next_code:
default:
if (KEYCHAR(c) >= F_SCR && KEYCHAR(c) <= L_SCR) {
- switch_scr(cur_console, KEYCHAR(c) - F_SCR);
+ switch_scr(scp->sc, sc->first_vty + KEYCHAR(c) - F_SCR);
break;
}
/* assert(c & FKEY) */
- return c;
+ if (!(sc->flags & SC_SCRN_BLANKED))
+ return c;
+ break;
}
/* goto next_code */
} else {
/* regular keys (maybe MKEY is set) */
- return c;
+ if (!(sc->flags & SC_SCRN_BLANKED))
+ return c;
}
}
@@ -4501,7 +4164,7 @@ scmmap(dev_t dev, vm_offset_t offset, int nprot)
if (!tp)
return ENXIO;
scp = sc_get_scr_stat(tp->t_dev);
- return (*vidsw[scp->ad]->mmap)(scp->adp, offset);
+ return (*vidsw[scp->sc->adapter]->mmap)(scp->sc->adp, offset, nprot);
}
/*
@@ -4539,7 +4202,7 @@ save_kbd_state(scr_stat *scp)
int state;
int error;
- error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ error = kbd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state);
if (error == ENOIOCTL)
error = ENODEV;
if (error == 0) {
@@ -4550,13 +4213,13 @@ save_kbd_state(scr_stat *scp)
}
static int
-update_kbd_state(int new_bits, int mask)
+update_kbd_state(scr_stat *scp, int new_bits, int mask)
{
int state;
int error;
if (mask != LOCK_MASK) {
- error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ error = kbd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state);
if (error == ENOIOCTL)
error = ENODEV;
if (error)
@@ -4566,19 +4229,19 @@ update_kbd_state(int new_bits, int mask)
} else {
state = new_bits & LOCK_MASK;
}
- error = kbd_ioctl(kbd, KDSKBSTATE, (caddr_t)&state);
+ error = kbd_ioctl(scp->sc->kbd, KDSKBSTATE, (caddr_t)&state);
if (error == ENOIOCTL)
error = ENODEV;
return error;
}
static int
-update_kbd_leds(int which)
+update_kbd_leds(scr_stat *scp, int which)
{
int error;
which &= LOCK_MASK;
- error = kbd_ioctl(kbd, KDSETLED, (caddr_t)&which);
+ error = kbd_ioctl(scp->sc->kbd, KDSETLED, (caddr_t)&which);
if (error == ENOIOCTL)
error = ENODEV;
return error;
@@ -4590,17 +4253,15 @@ set_mode(scr_stat *scp)
video_info_t info;
/* reject unsupported mode */
- if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info))
+ if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info))
return 1;
/* if this vty is not currently showing, do nothing */
- if (scp != cur_console)
+ if (scp != scp->sc->cur_scp)
return 0;
/* setup video hardware for the given mode */
- (*vidsw[scp->ad]->set_mode)(scp->adp, scp->mode);
- Crtat = (u_short *)scp->adp->va_window;
-
+ (*vidsw[scp->sc->adapter]->set_mode)(scp->sc->adp, scp->mode);
#ifdef PC98
if (scp->status & UNKNOWN_MODE) {
while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
@@ -4611,21 +4272,23 @@ set_mode(scr_stat *scp)
outb(0x62, 0xd); /* text off */
outb(0xA2, 0xc); /* graphics on */
}
-#endif
+#endif /* PC98 */
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+ (void *)scp->sc->adp->va_window, FALSE);
-#ifndef PC98
+#ifndef SC_NO_FONT_LOADING
+ /* load appropriate font */
if (!(scp->status & GRAPHICS_MODE)) {
- /* load appropriate font */
- if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->adp->va_flags)) {
+ if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->sc->adp->va_flags)) {
if (scp->font_size < 14) {
- if (fonts_loaded & FONT_8)
- copy_font(scp, LOAD, 8, font_8);
+ if (scp->sc->fonts_loaded & FONT_8)
+ copy_font(scp, LOAD, 8, scp->sc->font_8);
} else if (scp->font_size >= 16) {
- if (fonts_loaded & FONT_16)
- copy_font(scp, LOAD, 16, font_16);
+ if (scp->sc->fonts_loaded & FONT_16)
+ copy_font(scp, LOAD, 16, scp->sc->font_16);
} else {
- if (fonts_loaded & FONT_14)
- copy_font(scp, LOAD, 14, font_14);
+ if (scp->sc->fonts_loaded & FONT_14)
+ copy_font(scp, LOAD, 14, scp->sc->font_14);
}
/*
* FONT KLUDGE:
@@ -4634,21 +4297,14 @@ set_mode(scr_stat *scp)
* Somehow we cannot show the font in other font pages on
* some video cards... XXX
*/
- (*vidsw[scp->ad]->show_font)(scp->adp, 0);
+ (*vidsw[scp->sc->adapter]->show_font)(scp->sc->adp, 0);
}
mark_all(scp);
}
+#endif /* !SC_NO_FONT_LOADING */
- if (scp->status & PIXEL_MODE)
- generic_bzero((u_char *)(scp->adp->va_window),
- scp->xpixel*scp->ypixel/8);
-#endif
set_border(scp, scp->border);
-
-#ifndef PC98
- /* move hardware cursor out of the way */
- (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1);
-#endif
+ sc_set_cursor_image(scp);
return 0;
}
@@ -4656,47 +4312,12 @@ set_mode(scr_stat *scp)
void
set_border(scr_stat *scp, int color)
{
-#ifndef PC98
- u_char *p;
- int xoff;
- int yoff;
- int xlen;
- int ylen;
- int i;
-
- (*vidsw[scp->ad]->set_border)(scp->adp, color);
-
- if (scp->status & PIXEL_MODE) {
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
- outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
- p = (u_char *)(scp->adp->va_window);
- xoff = scp->xoff;
- yoff = scp->yoff*scp->font_size;
- xlen = scp->xpixel/8;
- ylen = scp->ysize*scp->font_size;
- if (yoff > 0) {
- generic_bzero(p, xlen*yoff);
- generic_bzero(p + xlen*(yoff + ylen),
- xlen*scp->ypixel - xlen*(yoff + ylen));
- }
- if (xoff > 0) {
- for (i = 0; i < ylen; ++i) {
- generic_bzero(p + xlen*(yoff + i), xoff);
- generic_bzero(p + xlen*(yoff + i) + xoff + scp->xsize,
- xlen - xoff - scp->xsize);
- }
- }
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
- }
-#else /* PC98 */
- (*vidsw[scp->ad]->set_border)(scp->adp, color);
-#endif /* PC98 */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_border)(scp, color);
+ --scp->sc->videoio_in_progress;
}
+#ifndef SC_NO_FONT_LOADING
void
copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
{
@@ -4707,488 +4328,41 @@ copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
* Somehow we cannot show the font in other font pages on
* some video cards... XXX
*/
- font_loading_in_progress = TRUE;
+ scp->sc->font_loading_in_progress = TRUE;
if (operation == LOAD) {
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, buf, 0, 256);
- if (sc_flags & CHAR_CURSOR)
- set_destructive_cursor(scp);
+ (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, font_size,
+ buf, 0, 256);
} else if (operation == SAVE) {
- (*vidsw[scp->ad]->save_font)(scp->adp, 0, font_size, buf, 0, 256);
+ (*vidsw[scp->sc->adapter]->save_font)(scp->sc->adp, 0, font_size,
+ buf, 0, 256);
}
- font_loading_in_progress = FALSE;
+ scp->sc->font_loading_in_progress = FALSE;
}
+#endif /* !SC_NO_FONT_LOADING */
-static void
-set_destructive_cursor(scr_stat *scp)
+#ifndef SC_NO_SYSMOUSE
+struct tty
+*sc_get_mouse_tty(void)
{
-#ifndef PC98
- u_char cursor[32];
- u_char *font_buffer;
- int font_size;
- int crtc_addr;
- int i;
-
- if (!ISFONTAVAIL(scp->adp->va_flags)
- || (scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
- return;
-
- if (scp->font_size < 14) {
- font_buffer = font_8;
- font_size = 8;
- } else if (scp->font_size >= 16) {
- font_buffer = font_16;
- font_size = 16;
- } else {
- font_buffer = font_14;
- font_size = 14;
- }
-
- if (scp->status & MOUSE_VISIBLE) {
- if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR)
- bcopy(&scp->mouse_cursor[0], cursor, scp->font_size);
- else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 1)
- bcopy(&scp->mouse_cursor[32], cursor, scp->font_size);
- else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 2)
- bcopy(&scp->mouse_cursor[64], cursor, scp->font_size);
- else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 3)
- bcopy(&scp->mouse_cursor[96], cursor, scp->font_size);
- else
- bcopy(font_buffer+((scp->cursor_saveunder & 0xff)*scp->font_size),
- cursor, scp->font_size);
- }
- else
- bcopy(font_buffer + ((scp->cursor_saveunder & 0xff) * scp->font_size),
- cursor, scp->font_size);
- for (i=0; i<32; i++)
- if ((i >= scp->cursor_start && i <= scp->cursor_end) ||
- (scp->cursor_start >= scp->font_size && i == scp->font_size - 1))
- cursor[i] |= 0xff;
-#if 1
- crtc_addr = scp->adp->va_crtc_addr;
- while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
-#endif
- font_loading_in_progress = TRUE;
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1);
- font_loading_in_progress = FALSE;
-#endif
+ return MOUSE_TTY;
}
+#endif /* !SC_NO_SYSMOUSE */
+#ifndef SC_NO_CUTPASTE
void
-sc_move_mouse(scr_stat *scp, int x, int y)
-{
- scp->mouse_xpos = x;
- scp->mouse_ypos = y;
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + (y / scp->font_size) * scp->xsize + x / 8;
-}
-
-static void
-set_mouse_pos(scr_stat *scp)
-{
- static int last_xpos = -1, last_ypos = -1;
-
- if (scp->mouse_xpos < 0)
- scp->mouse_xpos = 0;
- if (scp->mouse_ypos < 0)
- scp->mouse_ypos = 0;
- if (!ISTEXTSC(scp)) {
- if (scp->mouse_xpos > scp->xpixel-1)
- scp->mouse_xpos = scp->xpixel-1;
- if (scp->mouse_ypos > scp->ypixel-1)
- scp->mouse_ypos = scp->ypixel-1;
- return;
- }
- if (scp->mouse_xpos > (scp->xsize*8)-1)
- scp->mouse_xpos = (scp->xsize*8)-1;
- if (scp->mouse_ypos > (scp->ysize*scp->font_size)-1)
- scp->mouse_ypos = (scp->ysize*scp->font_size)-1;
-
- if (scp->mouse_xpos != last_xpos || scp->mouse_ypos != last_ypos) {
- scp->status |= MOUSE_MOVED;
-
- scp->mouse_pos = scp->scr_buf +
- ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8);
-
- if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
- mouse_cut(scp);
- }
-}
-
-#define isspace(c) (((c) & 0xff) == ' ')
-
-static int
-skip_spc_right(scr_stat *scp, u_short *p)
+sc_paste(scr_stat *scp, u_char *p, int count)
{
- int i;
-
- for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) {
- if (!isspace(*p))
- break;
- ++p;
- }
- return i;
-}
-
-static int
-skip_spc_left(scr_stat *scp, u_short *p)
-{
- int i;
-
- for (i = (p-- - scp->scr_buf) % scp->xsize - 1; i >= 0; --i) {
- if (!isspace(*p))
- break;
- --p;
- }
- return i;
-}
-
-static void
-mouse_cut(scr_stat *scp)
-{
- u_short *end;
- u_short *p;
- int i = 0;
- int j = 0;
-
- scp->mouse_cut_end = (scp->mouse_pos >= scp->mouse_cut_start) ?
- scp->mouse_pos + 1 : scp->mouse_pos;
- end = (scp->mouse_cut_start > scp->mouse_cut_end) ?
- scp->mouse_cut_start : scp->mouse_cut_end;
- for (p = (scp->mouse_cut_start > scp->mouse_cut_end) ?
- scp->mouse_cut_end : scp->mouse_cut_start; p < end; ++p) {
- cut_buffer[i] = *p & 0xff;
- /* remember the position of the last non-space char */
- if (!isspace(cut_buffer[i++]))
- j = i;
- /* trim trailing blank when crossing lines */
- if (((p - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) {
- cut_buffer[j++] = '\r';
- i = j;
- }
- }
- cut_buffer[i] = '\0';
-
- /* scan towards the end of the last line */
- --p;
- for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) {
- if (!isspace(*p))
- break;
- ++p;
- }
- /* if there is nothing but blank chars, trim them, but mark towards eol */
- if (i >= scp->xsize) {
- if (scp->mouse_cut_start > scp->mouse_cut_end)
- scp->mouse_cut_start = p;
- else
- scp->mouse_cut_end = p;
- cut_buffer[j++] = '\r';
- cut_buffer[j] = '\0';
- }
-
- mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf);
- mark_for_update(scp, scp->mouse_cut_end - scp->scr_buf);
-}
-
-static void
-mouse_cut_start(scr_stat *scp)
-{
- int i;
-
- if (scp->status & MOUSE_VISIBLE) {
- if (scp->mouse_pos == scp->mouse_cut_start &&
- scp->mouse_cut_start == scp->mouse_cut_end - 1) {
- cut_buffer[0] = '\0';
- remove_cutmarking(scp);
- } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
- /* if the pointer is on trailing blank chars, mark towards eol */
- i = skip_spc_left(scp, scp->mouse_pos) + 1;
- scp->mouse_cut_start = scp->scr_buf +
- ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize + i;
- scp->mouse_cut_end = scp->scr_buf +
- ((scp->mouse_pos - scp->scr_buf) / scp->xsize + 1) * scp->xsize;
- cut_buffer[0] = '\r';
- cut_buffer[1] = '\0';
- scp->status |= MOUSE_CUTTING;
- } else {
- scp->mouse_cut_start = scp->mouse_pos;
- scp->mouse_cut_end = scp->mouse_cut_start + 1;
- cut_buffer[0] = *scp->mouse_cut_start & 0xff;
- cut_buffer[1] = '\0';
- scp->status |= MOUSE_CUTTING;
- }
- mark_all(scp);
- /* delete all other screens cut markings */
- for (i=0; i<MAXCONS; i++) {
- if (console[i] == NULL || console[i] == scp)
- continue;
- remove_cutmarking(console[i]);
- }
- }
-}
-
-static void
-mouse_cut_end(scr_stat *scp)
-{
- if (scp->status & MOUSE_VISIBLE) {
- scp->status &= ~MOUSE_CUTTING;
- }
-}
-
-static void
-mouse_cut_word(scr_stat *scp)
-{
- u_short *p;
- u_short *sol;
- u_short *eol;
- int i;
-
- /*
- * Because we don't have locale information in the kernel,
- * we only distinguish space char and non-space chars. Punctuation
- * chars, symbols and other regular chars are all treated alike.
- */
- if (scp->status & MOUSE_VISIBLE) {
- sol = scp->scr_buf
- + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize;
- eol = sol + scp->xsize;
- if (isspace(*scp->mouse_pos)) {
- for (p = scp->mouse_pos; p >= sol; --p)
- if (!isspace(*p))
- break;
- scp->mouse_cut_start = ++p;
- for (p = scp->mouse_pos; p < eol; ++p)
- if (!isspace(*p))
- break;
- scp->mouse_cut_end = p;
- } else {
- for (p = scp->mouse_pos; p >= sol; --p)
- if (isspace(*p))
- break;
- scp->mouse_cut_start = ++p;
- for (p = scp->mouse_pos; p < eol; ++p)
- if (isspace(*p))
- break;
- scp->mouse_cut_end = p;
- }
- for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p)
- cut_buffer[i++] = *p & 0xff;
- cut_buffer[i] = '\0';
- scp->status |= MOUSE_CUTTING;
- }
-}
-
-static void
-mouse_cut_line(scr_stat *scp)
-{
- u_short *p;
- int i;
-
- if (scp->status & MOUSE_VISIBLE) {
- scp->mouse_cut_start = scp->scr_buf
- + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize;
- scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize;
- for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p)
- cut_buffer[i++] = *p & 0xff;
- cut_buffer[i++] = '\r';
- cut_buffer[i] = '\0';
- scp->status |= MOUSE_CUTTING;
- }
-}
-
-static void
-mouse_cut_extend(scr_stat *scp)
-{
- if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
- && (scp->mouse_cut_start != NULL)) {
- mouse_cut(scp);
- scp->status |= MOUSE_CUTTING;
- }
-}
+ struct tty *tp;
+ u_char *rmap;
-static void
-mouse_paste(scr_stat *scp)
-{
if (scp->status & MOUSE_VISIBLE) {
- struct tty *tp;
- u_char *ptr = cut_buffer;
-
- tp = VIRTUAL_TTY(get_scr_num());
- while (*ptr)
- (*linesw[tp->t_line].l_rint)(scr_rmap[*ptr++], tp);
+ tp = VIRTUAL_TTY(scp->sc, scp->sc->cur_scp->index);
+ rmap = scp->sc->scr_rmap;
+ for (; count > 0; --count)
+ (*linesw[tp->t_line].l_rint)(rmap[*p++], tp);
}
}
-
-static void
-draw_mouse_image(scr_stat *scp)
-{
-#ifdef PC98
- *(Atrat + (scp->mouse_pos - scp->scr_buf)) ^= 0x4; /* reverse bit */
-#else
- u_short buffer[32];
- u_short xoffset, yoffset;
- u_short *crt_pos = (u_short *)(scp->adp->va_window)
- + (scp->mouse_pos - scp->scr_buf);
- u_char *font_buffer;
- int font_size;
- int crtc_addr;
- int i;
-
- if (scp->font_size < 14) {
- font_buffer = font_8;
- font_size = 8;
- } else if (scp->font_size >= 16) {
- font_buffer = font_16;
- font_size = 16;
- } else {
- font_buffer = font_14;
- font_size = 14;
- }
-
- xoffset = scp->mouse_xpos % 8;
- yoffset = scp->mouse_ypos % scp->font_size;
-
- /* prepare mousepointer char's bitmaps */
- bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
- &scp->mouse_cursor[0], font_size);
- bcopy(font_buffer + ((*(scp->mouse_pos+1) & 0xff) * font_size),
- &scp->mouse_cursor[32], font_size);
- bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize) & 0xff) * font_size),
- &scp->mouse_cursor[64], font_size);
- bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize+1) & 0xff) * font_size),
- &scp->mouse_cursor[96], font_size);
- for (i=0; i<font_size; i++) {
- buffer[i] = scp->mouse_cursor[i]<<8 | scp->mouse_cursor[i+32];
- buffer[i+font_size]=scp->mouse_cursor[i+64]<<8|scp->mouse_cursor[i+96];
- }
-
- /* now and-or in the mousepointer image */
- for (i=0; i<16; i++) {
- buffer[i+yoffset] =
- ( buffer[i+yoffset] & ~(mouse_and_mask[i] >> xoffset))
- | (mouse_or_mask[i] >> xoffset);
- }
- for (i=0; i<font_size; i++) {
- scp->mouse_cursor[i] = (buffer[i] & 0xff00) >> 8;
- scp->mouse_cursor[i+32] = buffer[i] & 0xff;
- scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
- scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
- }
-#endif
-
- scp->mouse_oldpos = scp->mouse_pos;
-#ifndef PC98
-#if 1
- /* wait for vertical retrace to avoid jitter on some videocards */
- crtc_addr = scp->adp->va_crtc_addr;
- while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ;
-#endif
- font_loading_in_progress = TRUE;
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, 32, scp->mouse_cursor,
- SC_MOUSE_CHAR, 4);
- font_loading_in_progress = FALSE;
-
- *(crt_pos) = (*(scp->mouse_pos) & 0xff00) | SC_MOUSE_CHAR;
- *(crt_pos+scp->xsize) =
- (*(scp->mouse_pos + scp->xsize) & 0xff00) | (SC_MOUSE_CHAR + 2);
- if (scp->mouse_xpos < (scp->xsize-1)*8) {
- *(crt_pos + 1) = (*(scp->mouse_pos + 1) & 0xff00) | (SC_MOUSE_CHAR + 1);
- *(crt_pos+scp->xsize + 1) =
- (*(scp->mouse_pos + scp->xsize + 1) & 0xff00) | (SC_MOUSE_CHAR + 3);
- }
-#endif
- mark_for_update(scp, scp->mouse_pos - scp->scr_buf);
-#ifndef PC98
- mark_for_update(scp, scp->mouse_pos + scp->xsize + 1 - scp->scr_buf);
-#endif
-}
-
-static void
-remove_mouse_image(scr_stat *scp)
-{
- u_short *crt_pos;
-
- if (!ISTEXTSC(scp))
- return;
-
-#ifdef PC98
- crt_pos = Atrat + (scp->mouse_oldpos - scp->scr_buf);
-#else
- crt_pos = (u_short *)(scp->adp->va_window)
- + (scp->mouse_oldpos - scp->scr_buf);
-#endif
-
-#ifdef PC98
- *(crt_pos) = *(scp->atr_buf + (scp->mouse_oldpos - scp->scr_buf));
-#else
- *(crt_pos) = *(scp->mouse_oldpos);
- *(crt_pos+1) = *(scp->mouse_oldpos+1);
- *(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize);
- *(crt_pos+scp->xsize+1) = *(scp->mouse_oldpos+scp->xsize+1);
-#endif
- mark_for_update(scp, scp->mouse_oldpos - scp->scr_buf);
-#ifndef PC98
- mark_for_update(scp, scp->mouse_oldpos + scp->xsize + 1 - scp->scr_buf);
-#endif
-}
-
-static void
-draw_cutmarking(scr_stat *scp)
-{
- u_short *crt_pos;
- u_short *ptr;
- u_short och, nch;
-
-#ifdef PC98
- crt_pos = Atrat;
-#else
- crt_pos = (u_short *)(scp->adp->va_window);
-#endif
- for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) {
- nch = och = *(crt_pos + (ptr - scp->scr_buf));
- /* are we outside the selected area ? */
- if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ?
- scp->mouse_cut_end : scp->mouse_cut_start) ||
- ptr >= (scp->mouse_cut_start > scp->mouse_cut_end ?
- scp->mouse_cut_start : scp->mouse_cut_end)) {
-#ifdef PC98
- if (ptr != scp->mouse_pos)
- nch = *(scp->atr_buf + (ptr - scp->scr_buf));
- else
- nch = *(scp->atr_buf + (ptr - scp->scr_buf)) ^ 0x4;
-#else
- if (ptr != scp->cursor_pos)
- nch = (och & 0xff) | (*ptr & 0xff00);
-#endif
- }
- else {
-#ifdef PC98
- if (ptr != scp->mouse_pos)
- nch = *(scp->atr_buf + (ptr - scp->scr_buf)) ^ 0x4; /* reverse bit */
-#else
- /* are we clear of the cursor image ? */
- if (ptr != scp->cursor_pos)
- nch = (och & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4;
- else {
- if (sc_flags & CHAR_CURSOR)
- nch = (och & 0x88ff)|(*ptr & 0x7000)>>4|(*ptr & 0x0700)<<4;
- else
- if (!(sc_flags & BLINK_CURSOR))
- nch = (och & 0xff) | (*ptr & 0xff00);
- }
-#endif
- }
- if (nch != och)
- *(crt_pos + (ptr - scp->scr_buf)) = nch;
- }
-}
-
-static void
-remove_cutmarking(scr_stat *scp)
-{
- scp->mouse_cut_start = scp->mouse_cut_end = NULL;
- scp->status &= ~MOUSE_CUTTING;
- mark_all(scp);
-}
+#endif /* SC_NO_CUTPASTE */
static void
do_bell(scr_stat *scp, int pitch, int duration)
@@ -5196,18 +4370,18 @@ do_bell(scr_stat *scp, int pitch, int duration)
if (cold || shutdown_in_progress)
return;
- if (scp != cur_console && (sc_flags & QUIET_BELL))
+ if (scp != scp->sc->cur_scp && (scp->sc->flags & SC_QUIET_BELL))
return;
- if (sc_flags & VISUAL_BELL) {
- if (blink_in_progress)
+ if (scp->sc->flags & SC_VISUAL_BELL) {
+ if (scp->sc->blink_in_progress)
return;
- blink_in_progress = 4;
- if (scp != cur_console)
- blink_in_progress += 2;
- blink_screen(cur_console);
+ scp->sc->blink_in_progress = 3;
+ if (scp != scp->sc->cur_scp)
+ scp->sc->blink_in_progress += 2;
+ blink_screen(scp->sc->cur_scp);
} else {
- if (scp != cur_console)
+ if (scp != scp->sc->cur_scp)
pitch *= 2;
sysbeep(pitch, duration);
}
@@ -5218,144 +4392,19 @@ blink_screen(void *arg)
{
scr_stat *scp = arg;
- if (!ISTEXTSC(scp) || (blink_in_progress <= 1)) {
- blink_in_progress = FALSE;
+ if (ISGRAPHSC(scp) || (scp->sc->blink_in_progress <= 1)) {
+ scp->sc->blink_in_progress = 0;
mark_all(scp);
- if (delayed_next_scr)
- switch_scr(scp, delayed_next_scr - 1);
+ scstart(VIRTUAL_TTY(scp->sc, scp->index));
+ if (scp->sc->delayed_next_scr)
+ switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
}
else {
-#ifdef PC98
- if (blink_in_progress & 1){
- fillw(scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
- fillw(at2pc98(kernel_default.std_color),
- Atrat, scp->xsize * scp->ysize);
- } else {
- fillw(scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
- fillw(at2pc98(kernel_default.rev_color),
- Atrat, scp->xsize * scp->ysize);
- }
-#else
- if (blink_in_progress & 1)
- fillw(kernel_default.std_color | scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
- else
- fillw(kernel_default.rev_color | scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
-#endif
- blink_in_progress--;
+ (*scp->rndr->draw)(scp, 0, scp->xsize*scp->ysize,
+ scp->sc->blink_in_progress & 1);
+ scp->sc->blink_in_progress--;
timeout(blink_screen, scp, hz / 10);
}
}
-void
-sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
-{
-#ifdef PC98
- if (ISTEXTSC(scp))
- generic_bcopy(p + from, (u_short *)(scp->adp->va_window) + from,
- (to - from + 1)*sizeof(u_short));
-#else /* PC98 */
- u_char *font;
- u_char volatile *d;
- u_char *e;
- u_char *f;
- int font_size;
- int line_length;
- int xsize;
- u_short bg;
- int i, j;
- u_char c;
-
- if (ISTEXTSC(scp)) {
- generic_bcopy(p + from, (u_short *)(scp->adp->va_window) + from,
- (to - from + 1)*sizeof(u_short));
- } else /* if ISPIXELSC(scp) */ {
- if (mark)
- mark = 255;
- font_size = scp->font_size;
- if (font_size < 14)
- font = font_8;
- else if (font_size >= 16)
- font = font_16;
- else
- font = font_14;
- line_length = scp->xpixel/8;
- xsize = scp->xsize;
- d = (u_char *)(scp->adp->va_window)
- + scp->xoff + scp->yoff*font_size*line_length
- + (from%xsize) + font_size*line_length*(from/xsize);
-
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- bg = -1;
- for (i = from ; i <= to ; i++) {
- /* set background color in EGA/VGA latch */
- if (bg != (p[i] & 0xf000)) {
- bg = (p[i] & 0xf000);
- outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
- outw(GDCIDX, 0xff08); /* bit mask */
- *d = 0;
- c = *d; /* set the background color in the latch */
- }
- /* foreground color */
- outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
- e = (u_char *)d;
- f = &font[(p[i] & 0x00ff)*font_size];
- for (j = 0 ; j < font_size; j++, f++) {
- outw(GDCIDX, ((*f^mark) << 8) | 0x08); /* bit mask */
- *e = 0;
- e += line_length;
- }
- d++;
- if ((i % xsize) == xsize - 1)
- d += scp->xoff*2 + (font_size - 1)*line_length;
- }
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
-
-#if 0 /* VGA only */
- outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
- bg = -1;
- for (i = from ; i <= to ; i++) {
- /* set background color in EGA/VGA latch */
- if (bg != (p[i] & 0xf000)) {
- bg = (p[i] & 0xf000);
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
- *d = 0;
- c = *d; /* set the background color in the latch */
- outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
- }
- /* foreground color */
- outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
- e = (u_char *)d;
- f = &font[(p[i] & 0x00ff)*font_size];
- for (j = 0 ; j < font_size; j++, f++) {
- *e = *f^mark;
- e += line_length;
- }
- d++;
- if ((i % xsize) == xsize - 1)
- d += scp->xoff*2 + (font_size - 1)*line_length;
- }
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
-#endif /* 0 */
- }
-#endif /* PC98 */
-}
-
#endif /* NSC */
diff --git a/sys/pc98/pc98/syscons_pc98.c b/sys/pc98/pc98/syscons_pc98.c
new file mode 100644
index 0000000..5bca2d0
--- /dev/null
+++ b/sys/pc98/pc98/syscons_pc98.c
@@ -0,0 +1,193 @@
+/*-
+ * $Id: $
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/cons.h>
+#include <machine/console.h>
+#include <machine/clock.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <dev/syscons/syscons.h>
+
+#include <i386/isa/timerreg.h>
+
+#include <isa/isavar.h>
+
+static devclass_t sc_devclass;
+
+static int scprobe(device_t dev);
+static int scattach(device_t dev);
+static int scresume(device_t dev);
+
+static device_method_t sc_methods[] = {
+ DEVMETHOD(device_probe, scprobe),
+ DEVMETHOD(device_attach, scattach),
+ DEVMETHOD(device_resume, scresume),
+ { 0, 0 }
+};
+
+static driver_t sc_driver = {
+ SC_DRIVER_NAME,
+ sc_methods,
+ 1, /* XXX */
+};
+
+static sc_softc_t main_softc = { 0, 0, 0, -1, NULL, -1, NULL, };
+
+static int
+scprobe(device_t dev)
+{
+ /* No pnp support */
+ if (isa_get_vendorid(dev))
+ return (ENXIO);
+
+ device_set_desc(dev, "System console");
+ return sc_probe_unit(device_get_unit(dev), isa_get_flags(dev));
+}
+
+static int
+scattach(device_t dev)
+{
+ return sc_attach_unit(device_get_unit(dev), isa_get_flags(dev));
+}
+
+static int
+scresume(device_t dev)
+{
+ return sc_resume_unit(device_get_unit(dev));
+}
+
+int
+sc_max_unit(void)
+{
+ return devclass_get_maxunit(sc_devclass);
+}
+
+sc_softc_t
+*sc_get_softc(int unit, int flags)
+{
+ sc_softc_t *sc;
+
+ if ((unit < 0) || (unit >= NSC))
+ return NULL;
+ if (flags & SC_KERNEL_CONSOLE) {
+ /* FIXME: clear if it is wired to another unit! */
+ main_softc.unit = unit;
+ return &main_softc;
+ } else {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, unit);
+ if (!(sc->flags & SC_INIT_DONE)) {
+ sc->unit = unit;
+ sc->keyboard = -1;
+ sc->adapter = -1;
+ }
+ return sc;
+ }
+}
+
+sc_softc_t
+*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
+{
+ sc_softc_t *sc;
+ int units;
+ int i;
+
+ sc = &main_softc;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ units = devclass_get_maxunit(sc_devclass);
+ for (i = 0; i < units; ++i) {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, i);
+ if (sc == NULL)
+ continue;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ }
+ return NULL;
+}
+
+int
+sc_get_cons_priority(int *unit, int *flags)
+{
+ int disabled;
+ int u, f;
+ int i;
+
+ *unit = -1;
+ for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) {
+ u = resource_query_unit(i);
+ if ((resource_int_value(SC_DRIVER_NAME, u, "disabled",
+ &disabled) == 0) && disabled)
+ continue;
+ if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
+ f = 0;
+ if (f & SC_KERNEL_CONSOLE) {
+ /* the user designates this unit to be the console */
+ *unit = u;
+ *flags = f;
+ break;
+ }
+ if (*unit < 0) {
+ /* ...otherwise remember the first found unit */
+ *unit = u;
+ *flags = f;
+ }
+ }
+ if ((i < 0) && (*unit < 0))
+ return CN_DEAD;
+ return CN_INTERNAL;
+}
+
+void
+sc_get_bios_values(bios_values_t *values)
+{
+ values->cursor_start = 0;
+ values->cursor_end = 16;
+ values->shift_state = 0;
+ if (pc98_machine_type & M_8M)
+ values->bell_pitch = BELL_PITCH_8M;
+ else
+ values->bell_pitch = BELL_PITCH_5M;
+}
+
+int
+sc_tone(int herz)
+{
+ int pitch;
+
+ if (herz) {
+ /* enable counter 1 */
+ outb(0x35, inb(0x35) & 0xf7);
+ /* set command for counter 1, 2 byte write */
+ if (acquire_timer1(TIMER_16BIT | TIMER_SQWAVE))
+ return EBUSY;
+ /* set pitch */
+ pitch = timer_freq/herz;
+ outb(TIMER_CNTR1, pitch);
+ outb(TIMER_CNTR1, pitch >> 8);
+ } else {
+ /* disable counter 1 */
+ outb(0x35, inb(0x35) | 0x08);
+ release_timer1();
+ }
+ return 0;
+}
+
+DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
+
+#endif /* NSC > 0 */
OpenPOWER on IntegriCloud