aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKATO Takenori <kato@FreeBSD.org>1999-01-18 08:38:08 +0000
committerKATO Takenori <kato@FreeBSD.org>1999-01-18 08:38:08 +0000
commit1835ec221977f16054131550a8a1ffe34bf7c77c (patch)
tree98054c837e6678a4ef2fb55ac5f992e6047da121
parent0fe90303e009a85f7507eb4466459ace277c5e07 (diff)
Notes
-rw-r--r--sys/conf/files.pc9812
-rw-r--r--sys/conf/options.pc9818
-rw-r--r--sys/pc98/cbus/gdc.c859
-rw-r--r--sys/pc98/cbus/pckbd.c983
-rw-r--r--sys/pc98/conf/GENERIC14
-rw-r--r--sys/pc98/conf/GENERIC9814
-rw-r--r--sys/pc98/conf/files.pc9812
-rw-r--r--sys/pc98/conf/options.pc9818
-rw-r--r--sys/pc98/pc98/pc98gdc.c859
-rw-r--r--sys/pc98/pc98/pc98kbd.c983
-rw-r--r--sys/pc98/pc98/scvidctl.c191
-rw-r--r--sys/pc98/pc98/syscons.c2137
-rw-r--r--sys/pc98/pc98/syscons.h33
13 files changed, 4602 insertions, 1531 deletions
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index e5cc7f5d726a..bc9bfa758fec 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.78 1998/12/31 11:38:52 kato Exp $
+# $Id: files.pc98,v 1.79 1999/01/04 08:07:47 kato Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -26,6 +26,11 @@ font8x16.o optional std8x16font \
no-implicit-rule before-depend \
clean "${STD8X16FONT}-8x16 font8x16.c"
#
+dev/fb/fb.c optional fb device-driver
+dev/fb/fb.c optional gdc device-driver
+dev/fb/splash.c optional splash
+dev/kbd/kbd.c optional kbd device-driver
+dev/kbd/kbd.c optional pckbd device-driver
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
i386/eisa/dpt_eisa.c optional eisa dpt device-driver
@@ -141,15 +146,14 @@ i386/isa/intr_machdep.c standard
pc98/pc98/pc98.c optional isa device-driver
i386/isa/istallion.c optional stli device-driver
i386/isa/joy.c optional joy device-driver
-i386/isa/kbdio.c optional psm device-driver
-i386/isa/kbdio.c optional sc device-driver
-i386/isa/kbdio.c optional vt device-driver
+pc98/pc98/pc98kbd.c optional pckbd device-driver
i386/isa/loran.c optional loran device-driver
pc98/pc98/lpt.c optional lpt device-driver
i386/isa/labpc.c optional labpc device-driver
i386/isa/mcd.c optional mcd device-driver
pc98/pc98/mse.c optional mse device-driver
pc98/pc98/npx.c mandatory npx device-driver
+pc98/pc98/pc98gdc.c optional gdc device-driver
pc98/pc98/pcaudio.c optional pca device-driver
i386/isa/matcd/matcd.c optional matcd device-driver
i386/isa/pcibus.c optional pci device-driver
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index 7f8e5e24e8f5..22c264c07e3a 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.76 1998/12/30 08:03:03 kato Exp $
+# $Id: options.pc98,v 1.77 1999/01/04 08:09:15 kato Exp $
DISABLE_PSE
IDE_DELAY
@@ -64,27 +64,29 @@ I486_CPU opt_global.h
I586_CPU opt_global.h
I686_CPU opt_global.h
-SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
-SLOW_VGA opt_syscons.h
STD8X16FONT opt_syscons.h
SC_HISTORY_SIZE opt_syscons.h
SC_DISABLE_REBOOT opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
-SC_ALT_SEQACCESS opt_syscons.h
+
+FB_INSTALL_CDEV opt_fb.h
VESA opt_vesa.h
+GDC opt_gdc.h
+
PSM_HOOKAPM opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
PCIC_RESUME_RESET opt_pcic.h
-KBD_RESETDELAY opt_kbdio.h
-KBD_MAXRETRY opt_kbdio.h
-KBD_MAXWAIT opt_kbdio.h
-KBDIO_DEBUG opt_kbdio.h
+KBD_INSTALL_CDEV opt_kbd.h
+KBD_MAXRETRY opt_kbd.h
+KBD_MAXWAIT opt_kbd.h
+KBD_RESETDELAY opt_kbd.h
+KBDIO_DEBUG opt_kbd.h
ATAPI opt_atapi.h
ATAPI_STATIC opt_atapi.h
diff --git a/sys/pc98/cbus/gdc.c b/sys/pc98/cbus/gdc.c
new file mode 100644
index 000000000000..006072b26c20
--- /dev/null
+++ b/sys/pc98/cbus/gdc.c
@@ -0,0 +1,859 @@
+#define TEXT_GDC IO_GDC1 /* 0x60 */
+#define ROW 25
+#define COL 80
+/*-
+ * $Id$
+ */
+
+#include "gdc.h"
+#include "opt_gdc.h"
+#include "opt_fb.h"
+#include "opt_syscons.h"
+
+#if NGDC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+#include <machine/pc/bios.h>
+
+#include <dev/fb/fbreg.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <i386/isa/isa_device.h>
+
+#define DRIVER_NAME "gdc"
+
+/* cdev driver declaration */
+
+#define GDC_UNIT(dev) minor(dev)
+#define GDC_MKMINOR(unit) (unit)
+
+static int gdcprobe(struct isa_device *dev);
+static int gdc_attach(struct isa_device *dev);
+static void gdc_drvinit(void *unused);
+
+struct isa_driver gdcdriver = {
+ gdcprobe,
+ gdc_attach,
+ DRIVER_NAME,
+ 0,
+};
+
+typedef struct gdc_softc {
+ video_adapter_t *adp;
+} gdc_softc_t;
+
+static int gdc_probe_unit(int unit, gdc_softc_t *sc, int flags);
+static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
+
+#define GDC_SOFTC(unit) (gdc_softc[unit])
+
+static gdc_softc_t *gdc_softc[NGDC];
+
+#if FB_INSTALL_CDEV
+
+static d_open_t gdcopen;
+static d_close_t gdcclose;
+static d_read_t gdcread;
+static d_ioctl_t gdcioctl;
+
+static struct cdevsw vga_cdevsw = {
+ gdcopen, gdcclose, noread, nowrite, /* ?? */
+ gdcioctl, nostop, nullreset, nodevtotty,
+ seltrue, nommap, NULL, DRIVER_NAME,
+ NULL, -1, nodump, nopsize,
+};
+
+#endif /* FB_INSTALL_CDEV */
+
+static int
+gdcprobe(struct isa_device *dev)
+{
+ gdc_softc_t *sc;
+ int error;
+
+ if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
+ return 0;
+ sc = gdc_softc[dev->id_unit]
+ = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
+ if (sc == NULL)
+ return 0;
+
+ error = gdc_probe_unit(dev->id_unit, sc, dev->id_flags);
+ if (error) {
+ gdc_softc[dev->id_unit] = NULL;
+ free(sc, M_DEVBUF);
+ return 0;
+ }
+
+ dev->id_iobase = sc->adp->va_io_base;
+ dev->id_maddr = (caddr_t)BIOS_PADDRTOVADDR(sc->adp->va_mem_base);
+ dev->id_msize = sc->adp->va_mem_size;
+
+ return sc->adp->va_io_size;
+}
+
+static int
+gdc_attach(struct isa_device *dev)
+{
+ gdc_softc_t *sc;
+
+ if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
+ return 0;
+ sc = gdc_softc[dev->id_unit];
+ if (sc == NULL)
+ return 0;
+
+ return ((gdc_attach_unit(dev->id_unit, sc, dev->id_flags)) ? 0 : 1);
+}
+
+static int
+gdc_probe_unit(int unit, gdc_softc_t *sc, int flags)
+{
+ video_switch_t *sw;
+
+ bzero(sc, sizeof(*sc));
+ sw = vid_get_switch(DRIVER_NAME);
+ if (sw == NULL)
+ return 0;
+ return (*sw->probe)(unit, &sc->adp, NULL, flags);
+}
+
+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;
+
+ error = (*sw->init)(unit, sc->adp, flags);
+ if (error)
+ return ENXIO;
+
+#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);
+
+ return 0;
+}
+
+/* LOW-LEVEL */
+
+#include <machine/clock.h>
+
+#include <pc98/pc98/30line.h>
+
+#define TEXT_BUF_BASE 0x000a0000
+#define TEXT_BUF_SIZE 0x00008000
+#define GRAPHICS_BUF_BASE 0x000a8000
+#define GRAPHICS_BUF_SIZE 0x00040000
+#define VIDEO_BUF_BASE 0x000a0000
+#define VIDEO_BUF_SIZE 0x00048000
+
+#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED)
+#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED)
+#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED)
+
+/*
+ * NOTE: `va_window' should have a virtual address, but is initialized
+ * with a physical address in the following table, they will be
+ * converted at run-time.
+ */
+static video_adapter_t adapter_init_value[] = {
+ { 0,
+ KD_PC98, "gdc", /* va_type, va_name */
+ 0, 0, /* va_unit, va_minor */
+ 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* */
+ 0, 0, /* va_buffer, va_buffer_size */
+ 0, M_PC98_80x25, 0, 0, /* va_*mode* */
+ NULL },
+};
+
+static video_adapter_t biosadapter[1];
+
+/* video driver declarations */
+static int gdc_configure(int flags);
+static int gdc_nop(void);
+static vi_probe_t gdc_probe;
+static vi_init_t gdc_init;
+static vi_get_info_t gdc_get_info;
+static vi_query_mode_t gdc_query_mode;
+static vi_set_mode_t gdc_set_mode;
+static vi_set_border_t gdc_set_border;
+static vi_save_state_t gdc_save_state;
+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_diag_t gdc_diag;
+
+static int gdc_err(video_adapter_t *adp, ...);
+
+static video_switch_t gdcvidsw = {
+ gdc_probe,
+ gdc_init,
+ gdc_get_info,
+ gdc_query_mode,
+ gdc_set_mode,
+ (vi_save_font_t *)gdc_err,
+ (vi_load_font_t *)gdc_err,
+ (vi_show_font_t *)gdc_err,
+ (vi_save_palette_t *)gdc_err,
+ (vi_load_palette_t *)gdc_err,
+ gdc_set_border,
+ gdc_save_state,
+ gdc_load_state,
+ (vi_set_win_org_t *)gdc_err,
+ gdc_read_hw_cursor,
+ gdc_set_hw_cursor,
+ gdc_set_hw_cursor_shape,
+ (vi_blank_display_t *)gdc_nop,
+ gdc_mmap,
+ gdc_diag,
+};
+
+VIDEO_DRIVER(gdc, gdcvidsw, gdc_configure);
+
+/* GDC BIOS standard video modes */
+#define EOT (-1)
+#define NA (-2)
+
+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 },
+#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 },
+#endif
+ { EOT },
+};
+
+static int init_done = FALSE;
+
+/* local functions */
+static int map_gen_mode_num(int type, int color, int mode);
+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))) \
+ return (err)
+
+/* a backdoor for the console driver */
+static int
+gdc_configure(int flags)
+{
+ probe_adapters();
+ biosadapter[0].va_flags |= V_ADP_INITIALIZED;
+ if (!config_done(&biosadapter[0])) {
+ if (vid_register(&biosadapter[0]) < 0)
+ return 1;
+ biosadapter[0].va_flags |= V_ADP_REGISTERED;
+ }
+
+ return 1;
+}
+
+/* local subroutines */
+
+/* map a generic video mode to a known mode number */
+static int
+map_gen_mode_num(int type, int color, int mode)
+{
+ static struct {
+ int from;
+ int to;
+ } mode_map[] = {
+ { M_TEXT_80x25, M_PC98_80x25, },
+#ifdef LINE30
+ { M_TEXT_80x30, M_PC98_80x30, },
+#endif
+ };
+ int i;
+
+ for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
+ if (mode_map[i].from == mode)
+ return mode_map[i].to;
+ }
+ return mode;
+}
+
+/* probe video adapters and return the number of detected adapters */
+static int
+probe_adapters(void)
+{
+ video_info_t info;
+
+ /* do this test only once */
+ if (init_done)
+ return 1;
+ init_done = TRUE;
+
+ biosadapter[0] = adapter_init_value[0];
+ biosadapter[0].va_flags |= V_ADP_PROBED;
+ biosadapter[0].va_initial_mode = biosadapter[0].va_initial_bios_mode;
+
+ master_gdc_wait_vsync();
+ master_gdc_cmd(_GDC_START); /* text ON */
+ gdc_wait_vsync();
+ gdc_cmd(_GDC_STOP); /* graphics OFF */
+
+ gdc_get_info(&biosadapter[0], biosadapter[0].va_initial_mode, &info);
+ biosadapter[0].va_mode_flags = info.vi_flags;
+ biosadapter[0].va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ biosadapter[0].va_window_size = info.vi_window_size;
+ biosadapter[0].va_window_gran = info.vi_window_gran;
+ biosadapter[0].va_buffer = 0;
+ biosadapter[0].va_buffer_size = 0;
+
+ return 1;
+}
+
+static void master_gdc_cmd(unsigned int cmd)
+{
+ while ( (inb(IO_GDC1) & 2) != 0);
+ outb(IO_GDC1+2, cmd);
+}
+
+static void master_gdc_prm(unsigned int pmtr)
+{
+ while ( (inb(IO_GDC1) & 2) != 0);
+ outb(IO_GDC1, pmtr);
+}
+
+static void master_gdc_word_prm(unsigned int wpmtr)
+{
+ master_gdc_prm(wpmtr & 0x00ff);
+ master_gdc_prm((wpmtr >> 8) & 0x00ff);
+}
+
+static void master_gdc_fifo_empty(void)
+{
+ while ( (inb(IO_GDC1) & 4) == 0);
+}
+
+static void master_gdc_wait_vsync(void)
+{
+ while ( (inb(IO_GDC1) & 0x20) != 0);
+ while ( (inb(IO_GDC1) & 0x20) == 0);
+}
+
+static void gdc_cmd(unsigned int cmd)
+{
+ while ( (inb(IO_GDC2) & 2) != 0);
+ outb( IO_GDC2+2, cmd);
+}
+
+static void gdc_prm(unsigned int pmtr)
+{
+ while ( (inb(IO_GDC2) & 2) != 0);
+ outb( IO_GDC2, pmtr);
+}
+
+static void gdc_word_prm(unsigned int wpmtr)
+{
+ gdc_prm(wpmtr & 0x00ff);
+ gdc_prm((wpmtr >> 8) & 0x00ff);
+}
+
+static void gdc_fifo_empty(void)
+{
+ while ( (inb(IO_GDC2) & 0x04) == 0);
+}
+
+static void gdc_wait_vsync(void)
+{
+ while ( (inb(IO_GDC2) & 0x20) != 0);
+ while ( (inb(IO_GDC2) & 0x20) == 0);
+}
+
+static int check_gdc_clock(void)
+{
+ if ((inb(IO_SYSPORT) & 0x80) == 0){
+ return _5MHZ;
+ } else {
+ return _2_5MHZ;
+ }
+}
+
+static void initialize_gdc(unsigned int mode)
+{
+ /* start 30line initialize */
+ int m_mode,s_mode,gdc_clock;
+ gdc_clock = check_gdc_clock();
+
+ if (mode == T25_G400){
+ m_mode = _25L;
+ }else{
+ m_mode = _30L;
+ }
+
+ s_mode = 2*mode+gdc_clock;
+
+ gdc_INFO = m_mode;
+
+ master_gdc_cmd(_GDC_RESET);
+ master_gdc_cmd(_GDC_MASTER);
+ gdc_cmd(_GDC_RESET);
+ gdc_cmd(_GDC_SLAVE);
+
+ /* GDC Master */
+ master_gdc_cmd(_GDC_SYNC);
+ master_gdc_prm(0x00); /* flush less */ /* text & graph */
+ master_gdc_prm(master_param[m_mode][GDC_CR]);
+ master_gdc_word_prm(((master_param[m_mode][GDC_HFP] << 10)
+ + (master_param[m_mode][GDC_VS] << 5)
+ + master_param[m_mode][GDC_HS]));
+ master_gdc_prm(master_param[m_mode][GDC_HBP]);
+ master_gdc_prm(master_param[m_mode][GDC_VFP]);
+ master_gdc_word_prm(((master_param[m_mode][GDC_VBP] << 10)
+ + (master_param[m_mode][GDC_LF])));
+ master_gdc_fifo_empty();
+ master_gdc_cmd(_GDC_PITCH);
+ master_gdc_prm(MasterPCH);
+ master_gdc_fifo_empty();
+
+ /* GDC slave */
+ gdc_cmd(_GDC_SYNC);
+ gdc_prm(0x06);
+ gdc_prm(slave_param[s_mode][GDC_CR]);
+ gdc_word_prm((slave_param[s_mode][GDC_HFP] << 10)
+ + (slave_param[s_mode][GDC_VS] << 5)
+ + (slave_param[s_mode][GDC_HS]));
+ gdc_prm(slave_param[s_mode][GDC_HBP]);
+ gdc_prm(slave_param[s_mode][GDC_VFP]);
+ gdc_word_prm((slave_param[s_mode][GDC_VBP] << 10)
+ + (slave_param[s_mode][GDC_LF]));
+ gdc_fifo_empty();
+ gdc_cmd(_GDC_PITCH);
+ gdc_prm(SlavePCH[gdc_clock]);
+ gdc_fifo_empty();
+
+ /* set Master GDC scroll param */
+ master_gdc_wait_vsync();
+ master_gdc_wait_vsync();
+ master_gdc_wait_vsync();
+ master_gdc_cmd(_GDC_SCROLL);
+ master_gdc_word_prm(0);
+ master_gdc_word_prm((master_param[m_mode][GDC_LF] << 4) | 0x0000);
+ master_gdc_fifo_empty();
+
+ /* set Slave GDC scroll param */
+ gdc_wait_vsync();
+ gdc_cmd(_GDC_SCROLL);
+ gdc_word_prm(0);
+ if (gdc_clock == _5MHZ){
+ gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
+ }else{
+ gdc_word_prm(SlaveScrlLF[mode] << 4);
+ }
+ gdc_fifo_empty();
+
+ gdc_word_prm(0);
+ if (gdc_clock == _5MHZ){
+ gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
+ }else{
+ gdc_word_prm(SlaveScrlLF[mode] << 4);
+ }
+ gdc_fifo_empty();
+
+ /* sync start */
+ gdc_cmd(_GDC_STOP);
+
+ gdc_wait_vsync();
+ gdc_wait_vsync();
+ gdc_wait_vsync();
+
+ master_gdc_cmd(_GDC_START);
+}
+
+/* entry points */
+
+static int
+gdc_nop(void)
+{
+ return 0;
+}
+
+static int
+gdc_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
+{
+ probe_adapters();
+ if (unit >= 1)
+ return ENXIO;
+
+ *adpp = &biosadapter[unit];
+
+ return 0;
+}
+
+static int
+gdc_init(int unit, video_adapter_t *adp, int flags)
+{
+ if ((unit >= 1) || (adp == NULL) || !probe_done(adp))
+ return ENXIO;
+
+ if (!init_done(adp)) {
+ /* nothing to do really... */
+ adp->va_flags |= V_ADP_INITIALIZED;
+ }
+
+ if (!config_done(adp)) {
+ if (vid_register(adp) < 0)
+ return ENXIO;
+ adp->va_flags |= V_ADP_REGISTERED;
+ }
+
+ return 0;
+}
+
+/*
+ * get_info():
+ * Return the video_info structure of the requested video mode.
+ */
+static int
+gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+ int i;
+
+ if (!init_done)
+ return 1;
+
+ 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) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+ if (mode == bios_vmode[i].vi_mode) {
+ *info = bios_vmode[i];
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * query_mode():
+ * Find a video mode matching the requested parameters.
+ * Fields filled with 0 are considered "don't care" fields and
+ * match any modes.
+ */
+static int
+gdc_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+ video_info_t buf;
+ int i;
+
+ if (!init_done)
+ return -1;
+
+ for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+
+ if ((info->vi_width != 0)
+ && (info->vi_width != bios_vmode[i].vi_width))
+ continue;
+ if ((info->vi_height != 0)
+ && (info->vi_height != bios_vmode[i].vi_height))
+ continue;
+ if ((info->vi_cwidth != 0)
+ && (info->vi_cwidth != bios_vmode[i].vi_cwidth))
+ continue;
+ if ((info->vi_cheight != 0)
+ && (info->vi_cheight != bios_vmode[i].vi_cheight))
+ continue;
+ if ((info->vi_depth != 0)
+ && (info->vi_depth != bios_vmode[i].vi_depth))
+ continue;
+ if ((info->vi_planes != 0)
+ && (info->vi_planes != bios_vmode[i].vi_planes))
+ continue;
+ /* XXX: should check pixel format, memory model */
+ if ((info->vi_flags != 0)
+ && (info->vi_flags != bios_vmode[i].vi_flags))
+ continue;
+
+ /* verify if this mode is supported on this adapter */
+ if (gdc_get_info(adp, bios_vmode[i].vi_mode, &buf))
+ continue;
+ return bios_vmode[i].vi_mode;
+ }
+ return -1;
+}
+
+/*
+ * set_mode():
+ * Change the video mode.
+ */
+static int
+gdc_set_mode(video_adapter_t *adp, int mode)
+{
+ video_info_t info;
+
+ prologue(adp, V_ADP_MODECHANGE, 1);
+
+ mode = map_gen_mode_num(adp->va_type,
+ adp->va_flags & V_ADP_COLOR, mode);
+ if (gdc_get_info(adp, mode, &info))
+ return 1;
+
+#ifdef LINE30
+ switch (scp->mode) {
+ case M_PC98_80x25: /* VGA TEXT MODES */
+ initialize_gdc(T25_G400);
+ break;
+ case M_PC98_80x30:
+ initialize_gdc(T30_G400);
+ break;
+ default:
+ break;
+ }
+#endif
+
+ adp->va_mode = mode;
+ adp->va_mode_flags = info.vi_flags;
+ adp->va_flags &= ~V_ADP_COLOR;
+ adp->va_flags |=
+ (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
+#if 0
+ adp->va_crtc_addr =
+ (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
+#endif
+ adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ adp->va_window_size = info.vi_window_size;
+ adp->va_window_gran = info.vi_window_gran;
+ if (info.vi_buffer_size == 0) {
+ adp->va_buffer = 0;
+ adp->va_buffer_size = 0;
+ } else {
+ adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
+ adp->va_buffer_size = info.vi_buffer_size;
+ }
+
+ /* move hardware cursor out of the way */
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
+
+ return 0;
+}
+
+/*
+ * set_border():
+ * Change the border color.
+ */
+static int
+gdc_set_border(video_adapter_t *adp, int color)
+{
+ outb(0x6c, color << 4);
+ return 0;
+}
+
+/*
+ * save_state():
+ * Read video card register values.
+ */
+static int
+gdc_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+ return 1;
+}
+
+/*
+ * load_state():
+ * Set video card registers at once.
+ */
+static int
+gdc_load_state(video_adapter_t *adp, void *p)
+{
+ return 1;
+}
+
+/*
+ * read_hw_cursor():
+ * Read the position of the hardware text cursor.
+ */
+static int
+gdc_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+ video_info_t info;
+ u_int16_t off;
+ int s;
+
+ if (!init_done)
+ return 1;
+
+ (*vidsw[adp->va_index]->get_info)(adp, adp->va_mode, &info);
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ return 1;
+
+ s = spltty();
+ master_gdc_cmd(0xe0); /* _GDC_CSRR */
+ while((inb(TEXT_GDC + 0) & 0x1) == 0) {} /* GDC wait */
+ off = inb(TEXT_GDC + 2); /* EADl */
+ off |= (inb(TEXT_GDC + 2) << 8); /* EADh */
+ inb(TEXT_GDC + 2); /* dummy */
+ inb(TEXT_GDC + 2); /* dummy */
+ inb(TEXT_GDC + 2); /* dummy */
+ splx(s);
+
+ if (off >= ROW*COL)
+ off = 0;
+ *row = off / info.vi_width;
+ *col = off % info.vi_width;
+
+ return 0;
+}
+
+/*
+ * set_hw_cursor():
+ * Move the hardware text cursor. If col and row are both -1,
+ * the cursor won't be shown.
+ */
+static int
+gdc_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+ video_info_t info;
+ u_int16_t off;
+ int s;
+
+ if (!init_done)
+ return 1;
+
+ if ((col == -1) && (row == -1)) {
+ off = -1;
+ } else {
+ (*vidsw[adp->va_index]->get_info)(adp, adp->va_mode, &info);
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ return 1;
+ off = row*info.vi_width + col;
+ }
+
+ s = spltty();
+ master_gdc_cmd(0x49); /* _GDC_CSRW */
+ master_gdc_word_prm(off);
+ splx(s);
+
+ return 0;
+}
+
+/*
+ * set_hw_cursor_shape():
+ * Change the shape of the hardware text cursor. If the height is zero
+ * or negative, the cursor won't be shown.
+ */
+static int
+gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+ int celsize, int blink)
+{
+ int start;
+ int end;
+ int s;
+
+ start = celsize - (base + height);
+ end = celsize - base - 1;
+ /*
+ * muPD7220 GDC has anomaly that if end == celsize - 1 then start
+ * must be 0, otherwise the cursor won't be correctly shown
+ * in the first row in the screen. We shall set end to celsize - 2;
+ * if end == celsize -1 && start > 0. XXX
+ */
+ if ((end == celsize - 1) && (start > 0))
+ --end;
+
+ s = spltty();
+ master_gdc_cmd(0x4b); /* _GDC_CSRFORM */
+ master_gdc_prm(((height > 0) ? 0x80 : 0) /* cursor on/off */
+ | (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;
+}
+
+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");
+ }
+}
+
+/*
+ * mmap():
+ * Mmap frame buffer.
+ */
+static int
+gdc_mmap(video_adapter_t *adp, vm_offset_t offset)
+{
+ if (offset > 0x48000 - PAGE_SIZE)
+ return -1;
+ return i386_btop((VIDEO_BUF_BASE + offset));
+}
+
+/*
+ * diag():
+ * Print some information about the video adapter and video modes,
+ * with requested level of details.
+ */
+static int
+gdc_diag(video_adapter_t *adp, int level)
+{
+ video_info_t info;
+ int i;
+
+ if (!init_done)
+ return 1;
+
+ fb_dump_adp_info(DRIVER_NAME, adp, level);
+
+#if FB_DEBUG > 1
+ for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+ if (get_mode_param(bios_vmode[i].vi_mode) == NULL)
+ continue;
+ fb_dump_mode_info(DRIVER_NAME, adp, &bios_vmode[i], level);
+ }
+#endif
+
+ return 0;
+}
+
+static int
+gdc_err(video_adapter_t *adp, ...)
+{
+ return 0;
+}
+
+#endif /* NGDC > 0 */
diff --git a/sys/pc98/cbus/pckbd.c b/sys/pc98/cbus/pckbd.c
new file mode 100644
index 000000000000..8b1a13cc29d9
--- /dev/null
+++ b/sys/pc98/cbus/pckbd.c
@@ -0,0 +1,983 @@
+/*-
+ * $Id$
+ */
+
+#include "pckbd.h"
+#include "opt_kbd.h"
+#include "opt_devfs.h"
+
+#if NPCKBD > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/fcntl.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+
+#include <machine/resource.h>
+
+#include <dev/kbd/kbdreg.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#ifdef __i386__
+#include <i386/isa/isa_device.h>
+#endif
+
+#define DRIVER_NAME "pckbd"
+
+/* device configuration flags */
+#define KB_CONF_FAIL_IF_NO_KBD (1 << 0) /* don't install if no kbd is found */
+
+/* some macros */
+#define PC98KBD_UNIT(dev) minor(dev)
+#define PC98KBD_MKMINOR(unit) (unit)
+
+/* cdev driver declaration */
+
+typedef struct pckbd_softc {
+ short flags;
+#define PC98KBD_ATTACHED (1 << 0)
+ keyboard_t *kbd;
+#ifdef KBD_INSTALL_CDEV
+ genkbd_softc_t gensc;
+#endif
+} pckbd_softc_t;
+
+#define PC98KBD_SOFTC(unit) pckbd_softc[(unit)]
+
+static pckbd_softc_t *pckbd_softc[NPCKBD];
+
+static int pckbdprobe(struct isa_device *dev);
+static int pckbdattach(struct isa_device *dev);
+
+static ointhand2_t pckbd_isa_intr;
+
+/* driver declaration for isa_devtab_tty[] */
+struct isa_driver pckbddriver = {
+ pckbdprobe,
+ pckbdattach,
+ DRIVER_NAME,
+ 0,
+};
+
+static int pckbd_probe_unit(int unit, pckbd_softc_t *sc,
+ int port, int irq, int flags);
+static int pckbd_attach_unit(int unit, pckbd_softc_t *sc);
+static timeout_t pckbd_timeout;
+
+#ifdef KBD_INSTALL_CDEV
+
+static d_open_t pckbdopen;
+static d_close_t pckbdclose;
+static d_read_t pckbdread;
+static d_ioctl_t pckbdioctl;
+static d_poll_t pckbdpoll;
+
+static struct cdevsw pckbd_cdevsw = {
+ pckbdopen, pckbdclose, pckbdread, nowrite,
+ pckbdioctl, nostop, nullreset, nodevtotty,
+ pckbdpoll, nommap, NULL, DRIVER_NAME,
+ NULL, -1,
+};
+
+#endif /* KBD_INSTALL_CDEV */
+
+static int
+pckbdprobe(struct isa_device *dev)
+{
+ pckbd_softc_t *sc;
+ int error;
+
+ if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
+ return 0;
+ sc = pckbd_softc[dev->id_unit];
+ if (sc == NULL) {
+ sc = pckbd_softc[dev->id_unit]
+ = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
+ if (sc == NULL)
+ return 0;
+ bzero(sc, sizeof(*sc));
+ }
+
+ /* try to find a keyboard */
+ error = pckbd_probe_unit(dev->id_unit, sc, dev->id_iobase,
+ dev->id_irq, dev->id_flags);
+ if (error)
+ return 0;
+
+ /* declare our interrupt handler */
+ dev->id_ointr = pckbd_isa_intr;
+
+ return IO_KBDSIZE;
+}
+
+static int
+pckbdattach(struct isa_device *dev)
+{
+ pckbd_softc_t *sc;
+
+ if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
+ return 0;
+ sc = pckbd_softc[dev->id_unit];
+ if (sc == NULL)
+ return 0;
+
+ return ((pckbd_attach_unit(dev->id_unit, sc)) ? 0 : 1);
+}
+
+static void
+pckbd_isa_intr(int unit)
+{
+ keyboard_t *kbd;
+
+ kbd = pckbd_softc[unit]->kbd;
+ (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
+}
+
+static int
+pckbd_probe_unit(int unit, pckbd_softc_t *sc, int port, int irq, int flags)
+{
+ keyboard_switch_t *sw;
+ int args[2];
+
+ if (sc->flags & PC98KBD_ATTACHED)
+ return 0;
+
+ sw = kbd_get_switch(DRIVER_NAME);
+ if (sw == NULL)
+ return ENXIO;
+
+ args[0] = port;
+ args[1] = irq;
+ return (*sw->probe)(unit, &sc->kbd, args, flags);
+}
+
+static int
+pckbd_attach_unit(int unit, pckbd_softc_t *sc)
+{
+ keyboard_switch_t *sw;
+ int error;
+
+ if (sc->flags & PC98KBD_ATTACHED)
+ return 0;
+
+ sw = kbd_get_switch(DRIVER_NAME);
+ if (sw == NULL)
+ return ENXIO;
+
+ /* reset, initialize and enable the device */
+ error = (*sw->init)(sc->kbd);
+ if (error)
+ return ENXIO;
+ (*sw->enable)(sc->kbd);
+
+#ifdef KBD_INSTALL_CDEV
+ /* attach a virtual keyboard cdev */
+ error = kbd_attach(makedev(0, PC98KBD_MKMINOR(unit)), sc->kbd,
+ &pckbd_cdevsw);
+ if (error)
+ return error;
+#endif /* KBD_INSTALL_CDEV */
+
+ /*
+ * This is a kludge to compensate for lost keyboard interrupts.
+ * A similar code used to be in syscons. See below. XXX
+ */
+ pckbd_timeout(sc->kbd);
+
+ if (bootverbose)
+ (*sw->diag)(sc->kbd, bootverbose);
+
+ sc->flags |= PC98KBD_ATTACHED;
+ return 0;
+}
+
+static void
+pckbd_timeout(void *arg)
+{
+ keyboard_t *kbd;
+ int s;
+
+ /* The following comments are extracted from syscons.c (1.287) */
+ /*
+ * With release 2.1 of the Xaccel server, the keyboard is left
+ * hanging pretty often. Apparently an interrupt from the
+ * keyboard is lost, and I don't know why (yet).
+ * This ugly hack calls scintr if input is ready for the keyboard
+ * and conveniently hides the problem. XXX
+ */
+ /*
+ * Try removing anything stuck in the keyboard controller; whether
+ * it's a keyboard scan code or mouse data. `scintr()' doesn't
+ * read the mouse data directly, but `kbdio' routines will, as a
+ * side effect.
+ */
+ s = spltty();
+ kbd = (keyboard_t *)arg;
+ if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) {
+ /*
+ * We have seen the lock flag is not set. Let's reset
+ * the flag early, otherwise the LED update routine fails
+ * which may want the lock during the interrupt routine.
+ */
+ (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE);
+ if ((*kbdsw[kbd->kb_index]->check_char)(kbd))
+ (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
+ }
+ splx(s);
+ timeout(pckbd_timeout, arg, hz/10);
+}
+
+/* cdev driver functions */
+
+#ifdef KBD_INSTALL_CDEV
+
+static int
+pckbdopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ pckbd_softc_t *sc;
+ int unit;
+
+ unit = PC98KBD_UNIT(dev);
+ if ((unit >= NPCKBD) || ((sc = PC98KBD_SOFTC(unit)) == NULL))
+ return ENXIO;
+ if (mode & (FWRITE | O_CREAT | O_APPEND | O_TRUNC))
+ return ENODEV;
+
+ /* FIXME: set the initial input mode (K_XLATE?) and lock state? */
+ return genkbdopen(&sc->gensc, sc->kbd, flag, mode, p);
+}
+
+static int
+pckbdclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdclose(&sc->gensc, sc->kbd, flag, mode, p);
+}
+
+static int
+pckbdread(dev_t dev, struct uio *uio, int flag)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdread(&sc->gensc, sc->kbd, uio, flag);
+}
+
+static int
+pckbdioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdioctl(&sc->gensc, sc->kbd, cmd, arg, flag, p);
+}
+
+static int
+pckbdpoll(dev_t dev, int event, struct proc *p)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdpoll(&sc->gensc, sc->kbd, event, p);
+}
+
+#endif /* KBD_INSTALL_CDEV */
+
+/* LOW-LEVEL */
+
+#include <machine/limits.h>
+#include <machine/console.h>
+#include <machine/clock.h>
+
+#define PC98KBD_DEFAULT 0
+
+typedef caddr_t KBDC;
+
+typedef struct pckbd_state {
+ KBDC kbdc; /* keyboard controller */
+ int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
+ int ks_flags; /* flags */
+#define COMPOSE (1 << 0)
+ int ks_state; /* shift/lock key state */
+ int ks_accents; /* accent key index (> 0) */
+ u_int ks_composed_char; /* composed char code (> 0) */
+} pckbd_state_t;
+
+/* keyboard driver declaration */
+static int pckbd_configure(int flags);
+static kbd_probe_t pckbd_probe;
+static kbd_init_t pckbd_init;
+static kbd_term_t pckbd_term;
+static kbd_intr_t pckbd_intr;
+static kbd_test_if_t pckbd_test_if;
+static kbd_enable_t pckbd_enable;
+static kbd_disable_t pckbd_disable;
+static kbd_read_t pckbd_read;
+static kbd_check_t pckbd_check;
+static kbd_read_char_t pckbd_read_char;
+static kbd_check_char_t pckbd_check_char;
+static kbd_ioctl_t pckbd_ioctl;
+static kbd_lock_t pckbd_lock;
+static kbd_clear_state_t pckbd_clear_state;
+static kbd_get_state_t pckbd_get_state;
+static kbd_set_state_t pckbd_set_state;
+
+keyboard_switch_t pckbdsw = {
+ pckbd_probe,
+ pckbd_init,
+ pckbd_term,
+ pckbd_intr,
+ pckbd_test_if,
+ pckbd_enable,
+ pckbd_disable,
+ pckbd_read,
+ pckbd_check,
+ pckbd_read_char,
+ pckbd_check_char,
+ pckbd_ioctl,
+ pckbd_lock,
+ pckbd_clear_state,
+ pckbd_get_state,
+ pckbd_set_state,
+ genkbd_get_fkeystr,
+ genkbd_diag,
+};
+
+KEYBOARD_DRIVER(pckbd, pckbdsw, pckbd_configure);
+
+struct kbdc_softc {
+ int port; /* base port address */
+ int lock; /* FIXME: XXX not quite a semaphore... */
+};
+
+/* local functions */
+static int probe_keyboard(KBDC kbdc, int flags);
+static int init_keyboard(KBDC kbdc, int *type, int flags);
+static KBDC kbdc_open(int port);
+static int kbdc_lock(KBDC kbdc, int lock);
+static int kbdc_data_ready(KBDC kbdc);
+static int read_kbd_data(KBDC kbdc);
+static int read_kbd_data_no_wait(KBDC kbdc);
+static int wait_for_kbd_data(struct kbdc_softc *kbdc);
+
+/* local variables */
+
+/* the initial key map, accent map and fkey strings */
+#include <i386/isa/kbdtables.h>
+
+/* structures for the default keyboard */
+static keyboard_t default_kbd;
+static pckbd_state_t default_kbd_state;
+static keymap_t default_keymap;
+static accentmap_t default_accentmap;
+static fkeytab_t default_fkeytab[NUM_FKEYS];
+
+/*
+ * The back door to the keyboard driver!
+ * This function is called by the console driver, via the kbdio module,
+ * to tickle keyboard drivers when the low-level console is being initialized.
+ * Almost nothing in the kernel has been initialied yet. Try to probe
+ * keyboards if possible.
+ * NOTE: because of the way the low-level conole is initialized, this routine
+ * may be called more than once!!
+ */
+static int
+pckbd_configure(int flags)
+{
+ keyboard_t *kbd;
+ KBDC kbdc;
+ int arg[2];
+ struct isa_device *dev;
+
+ /* XXX: a kludge to obtain the device configuration flags */
+ dev = find_isadev(isa_devtab_tty, &pckbddriver, 0);
+ if (dev != NULL)
+ flags |= dev->id_flags;
+
+ /* probe the default keyboard */
+ arg[0] = -1;
+ arg[1] = -1;
+ if (pckbd_probe(PC98KBD_DEFAULT, &kbd, arg, flags))
+ return 0;
+
+ /* initialize it */
+ kbdc = ((pckbd_state_t *)kbd->kb_data)->kbdc;
+ if (!(flags & KB_CONF_PROBE_ONLY) && !KBD_IS_PROBED(kbd)) {
+ if (KBD_HAS_DEVICE(kbd)
+ && init_keyboard(kbdc, &kbd->kb_type, flags)
+ && (flags & KB_CONF_FAIL_IF_NO_KBD))
+ return 0;
+ KBD_INIT_DONE(kbd);
+ }
+
+ /* and register */
+ if (!KBD_IS_CONFIGURED(kbd)) {
+ if (kbd_register(kbd) < 0)
+ return 0;
+ KBD_CONFIG_DONE(kbd);
+ }
+
+ return 1; /* return the number of found keyboards */
+}
+
+/* low-level functions */
+
+/* initialize the keyboard_t structure and try to detect a keyboard */
+static int
+pckbd_probe(int unit, keyboard_t **kbdp, void *arg, int flags)
+{
+ keyboard_t *kbd;
+ pckbd_state_t *state;
+ keymap_t *keymap;
+ accentmap_t *accmap;
+ fkeytab_t *fkeymap;
+ int fkeymap_size;
+ KBDC kbdc;
+ int *data = (int *)arg;
+
+ if (unit != PC98KBD_DEFAULT)
+ return ENXIO;
+
+ *kbdp = kbd = &default_kbd;
+ if (KBD_IS_PROBED(kbd))
+ return 0;
+ state = &default_kbd_state;
+ keymap = &default_keymap;
+ accmap = &default_accentmap;
+ fkeymap = default_fkeytab;
+ fkeymap_size = sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
+
+ state->kbdc = kbdc = kbdc_open(data[0]);
+ if (kbdc == NULL)
+ return ENXIO;
+ kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags, data[0],
+ IO_KBDSIZE);
+ bcopy(&key_map, keymap, sizeof(key_map));
+ bcopy(&accent_map, accmap, sizeof(accent_map));
+ bcopy(fkey_tab, fkeymap,
+ imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
+ kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
+ kbd->kb_data = (void *)state;
+
+ if (probe_keyboard(kbdc, flags)) {
+ if (flags & KB_CONF_FAIL_IF_NO_KBD)
+ return ENXIO;
+ } else {
+ KBD_FOUND_DEVICE(kbd);
+ }
+ pckbd_clear_state(kbd);
+ state->ks_mode = K_XLATE;
+
+ KBD_PROBE_DONE(kbd);
+ return 0;
+}
+
+/* reset and initialize the device */
+static int
+pckbd_init(keyboard_t *kbd)
+{
+ KBDC kbdc;
+
+ if ((kbd == NULL) || !KBD_IS_PROBED(kbd))
+ return ENXIO; /* shouldn't happen */
+ kbdc = ((pckbd_state_t *)kbd->kb_data)->kbdc;
+ if (kbdc == NULL)
+ return ENXIO; /* shouldn't happen */
+
+ if (!KBD_IS_INITIALIZED(kbd)) {
+ if (KBD_HAS_DEVICE(kbd)
+ && init_keyboard(kbdc, &kbd->kb_type, kbd->kb_config)
+ && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
+ return ENXIO;
+ pckbd_ioctl(kbd, KDSETLED,
+ (caddr_t)&((pckbd_state_t *)(kbd->kb_data))->ks_state);
+ KBD_INIT_DONE(kbd);
+ }
+ if (!KBD_IS_CONFIGURED(kbd)) {
+ if (kbd_register(kbd) < 0)
+ return ENXIO;
+ KBD_CONFIG_DONE(kbd);
+ }
+
+ return 0;
+}
+
+/* finish using this keyboard */
+static int
+pckbd_term(keyboard_t *kbd)
+{
+ kbd_unregister(kbd);
+ return 0;
+}
+
+/* keyboard interrupt routine */
+static int
+pckbd_intr(keyboard_t *kbd, void *arg)
+{
+ int c;
+
+ if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
+ /* let the callback function to process the input */
+ (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
+ kbd->kb_callback.kc_arg);
+ } else {
+ /* read and discard the input; no one is waiting for input */
+ do {
+ c = pckbd_read_char(kbd, FALSE);
+ } while (c != NOKEY);
+ }
+ return 0;
+}
+
+/* test the interface to the device */
+static int
+pckbd_test_if(keyboard_t *kbd)
+{
+ return 0;
+}
+
+/*
+ * Enable the access to the device; until this function is called,
+ * the client cannot read from the keyboard.
+ */
+static int
+pckbd_enable(keyboard_t *kbd)
+{
+ int s;
+
+ s = spltty();
+ KBD_ACTIVATE(kbd);
+ splx(s);
+ return 0;
+}
+
+/* disallow the access to the device */
+static int
+pckbd_disable(keyboard_t *kbd)
+{
+ int s;
+
+ s = spltty();
+ KBD_DEACTIVATE(kbd);
+ splx(s);
+ return 0;
+}
+
+/* read one byte from the keyboard if it's allowed */
+static int
+pckbd_read(keyboard_t *kbd, int wait)
+{
+ int c;
+
+ if (wait)
+ c = read_kbd_data(((pckbd_state_t *)kbd->kb_data)->kbdc);
+ else
+ c = read_kbd_data_no_wait(((pckbd_state_t *)kbd->kb_data)->kbdc);
+ return (KBD_IS_ACTIVE(kbd) ? c : -1);
+}
+
+/* check if data is waiting */
+static int
+pckbd_check(keyboard_t *kbd)
+{
+ if (!KBD_IS_ACTIVE(kbd))
+ return FALSE;
+ return kbdc_data_ready(((pckbd_state_t *)kbd->kb_data)->kbdc);
+}
+
+/* read char from the keyboard */
+static u_int
+pckbd_read_char(keyboard_t *kbd, int wait)
+{
+ pckbd_state_t *state;
+ u_int action;
+ int scancode;
+ int keycode;
+
+ state = (pckbd_state_t *)kbd->kb_data;
+next_code:
+ /* do we have a composed char to return? */
+ if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
+ action = state->ks_composed_char;
+ state->ks_composed_char = 0;
+ if (action > UCHAR_MAX)
+ return ERRKEY;
+ return action;
+ }
+
+ /* see if there is something in the keyboard port */
+ if (wait) {
+ do {
+ scancode = read_kbd_data(state->kbdc);
+ } while (scancode == -1);
+ } else {
+ scancode = read_kbd_data_no_wait(state->kbdc);
+ if (scancode == -1)
+ return NOKEY;
+ }
+
+ /* return the byte as is for the K_RAW mode */
+ if (state->ks_mode == K_RAW)
+ return scancode;
+
+ /* translate the scan code into a keycode */
+ keycode = scancode & 0x7F;
+ switch(scancode) {
+ case 0xF3: /* GRPH (compose key) released */
+ if (state->ks_flags & COMPOSE) {
+ state->ks_flags &= ~COMPOSE;
+ if (state->ks_composed_char > UCHAR_MAX)
+ state->ks_composed_char = 0;
+ }
+ break;
+ case 0x73: /* GRPH (compose key) pressed */
+ if (!(state->ks_flags & COMPOSE)) {
+ state->ks_flags |= COMPOSE;
+ state->ks_composed_char = 0;
+ }
+ break;
+ }
+
+ /* return the key code in the K_CODE mode */
+ if (state->ks_mode == K_CODE)
+ return (keycode | (scancode & 0x80));
+
+ /* compose a character code */
+ if (state->ks_flags & COMPOSE) {
+ switch (scancode) {
+ /* key pressed, process it */
+ case 0x42: case 0x43: case 0x44: /* keypad 7,8,9 */
+ state->ks_composed_char *= 10;
+ state->ks_composed_char += scancode - 0x3B;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+ case 0x46: case 0x47: case 0x48: /* keypad 4,5,6 */
+ state->ks_composed_char *= 10;
+ state->ks_composed_char += scancode - 0x42;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+ case 0x4A: case 0x4B: case 0x4C: /* keypad 1,2,3 */
+ state->ks_composed_char *= 10;
+ state->ks_composed_char += scancode - 0x49;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+ case 0x4E: /* keypad 0 */
+ state->ks_composed_char *= 10;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+
+ /* key released, no interest here */
+ case 0xC2: case 0xC3: case 0xC4: /* keypad 7,8,9 */
+ case 0xC6: case 0xC7: case 0xC8: /* keypad 4,5,6 */
+ case 0xCA: case 0xCB: case 0xCC: /* keypad 1,2,3 */
+ case 0xCE: /* keypad 0 */
+ goto next_code;
+
+ case 0x73: /* GRPH key */
+ break;
+
+ default:
+ if (state->ks_composed_char > 0) {
+ state->ks_flags &= ~COMPOSE;
+ state->ks_composed_char = 0;
+ return ERRKEY;
+ }
+ break;
+ }
+ }
+
+ /* keycode to key action */
+ action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
+ &state->ks_state, &state->ks_accents);
+ if (action == NOKEY)
+ goto next_code;
+ else
+ return action;
+}
+
+/* check if char is waiting */
+static int
+pckbd_check_char(keyboard_t *kbd)
+{
+ pckbd_state_t *state;
+
+ if (!KBD_IS_ACTIVE(kbd))
+ return FALSE;
+ state = (pckbd_state_t *)kbd->kb_data;
+ if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
+ return TRUE;
+ return kbdc_data_ready(state->kbdc);
+}
+
+/* some useful control functions */
+static int
+pckbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
+{
+ pckbd_state_t *state = kbd->kb_data;
+ int s;
+ int i;
+
+ s = spltty();
+ switch (cmd) {
+
+ case KDGKBMODE: /* get keyboard mode */
+ *(int *)arg = state->ks_mode;
+ break;
+ case KDSKBMODE: /* set keyboard mode */
+ switch (*(int *)arg) {
+ case K_XLATE:
+ if (state->ks_mode != K_XLATE) {
+ /* make lock key state and LED state match */
+ state->ks_state &= ~LOCK_MASK;
+ state->ks_state |= KBD_LED_VAL(kbd);
+ }
+ /* FALL THROUGH */
+ case K_RAW:
+ case K_CODE:
+ if (state->ks_mode != *(int *)arg) {
+ pckbd_clear_state(kbd);
+ state->ks_mode = *(int *)arg;
+ }
+ break;
+ default:
+ splx(s);
+ return EINVAL;
+ }
+ break;
+
+ case KDGETLED: /* get keyboard LED */
+ *(int *)arg = KBD_LED_VAL(kbd);
+ break;
+ case KDSETLED: /* set keyboard LED */
+ /* NOTE: lock key state in ks_state won't be changed */
+ if (*(int *)arg & ~LOCK_MASK) {
+ splx(s);
+ return EINVAL;
+ }
+ i = *(int *)arg;
+ /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
+ if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
+ if (i & ALKED)
+ i |= CLKED;
+ else
+ i &= ~CLKED;
+ }
+ KBD_LED_VAL(kbd) = *(int *)arg;
+ break;
+
+ case KDGKBSTATE: /* get lock key state */
+ *(int *)arg = state->ks_state & LOCK_MASK;
+ break;
+ case KDSKBSTATE: /* set lock key state */
+ if (*(int *)arg & ~LOCK_MASK) {
+ splx(s);
+ return EINVAL;
+ }
+ state->ks_state &= ~LOCK_MASK;
+ state->ks_state |= *(int *)arg;
+ splx(s);
+ /* set LEDs and quit */
+ return pckbd_ioctl(kbd, KDSETLED, arg);
+
+ case KDSETRAD: /* set keyboard repeat rate */
+ break;
+
+ case PIO_KEYMAP: /* set keyboard translation table */
+ case PIO_KEYMAPENT: /* set keyboard translation table entry */
+ case PIO_DEADKEYMAP: /* set accent key translation table */
+ state->ks_accents = 0;
+ /* FALL THROUGH */
+ default:
+ splx(s);
+ return genkbd_commonioctl(kbd, cmd, arg);
+ }
+
+ splx(s);
+ return 0;
+}
+
+/* lock the access to the keyboard */
+static int
+pckbd_lock(keyboard_t *kbd, int lock)
+{
+ return kbdc_lock(((pckbd_state_t *)kbd->kb_data)->kbdc, lock);
+}
+
+/* clear the internal state of the keyboard */
+static void
+pckbd_clear_state(keyboard_t *kbd)
+{
+ pckbd_state_t *state;
+
+ state = (pckbd_state_t *)kbd->kb_data;
+ state->ks_flags = 0;
+ state->ks_state &= LOCK_MASK; /* preserve locking key state */
+ state->ks_accents = 0;
+ state->ks_composed_char = 0;
+}
+
+/* save the internal state */
+static int
+pckbd_get_state(keyboard_t *kbd, void *buf, size_t len)
+{
+ if (len == 0)
+ return sizeof(pckbd_state_t);
+ if (len < sizeof(pckbd_state_t))
+ return -1;
+ bcopy(kbd->kb_data, buf, sizeof(pckbd_state_t));
+ return 0;
+}
+
+/* set the internal state */
+static int
+pckbd_set_state(keyboard_t *kbd, void *buf, size_t len)
+{
+ if (len < sizeof(pckbd_state_t))
+ return ENOMEM;
+ if (((pckbd_state_t *)kbd->kb_data)->kbdc
+ != ((pckbd_state_t *)buf)->kbdc)
+ return ENOMEM;
+ bcopy(buf, kbd->kb_data, sizeof(pckbd_state_t));
+ return 0;
+}
+
+/* local functions */
+
+static int
+probe_keyboard(KBDC kbdc, int flags)
+{
+ return 0;
+}
+
+static int
+init_keyboard(KBDC kbdc, int *type, int flags)
+{
+ *type = KB_OTHER;
+ return 0;
+}
+
+/* keyboard I/O routines */
+
+/* retry count */
+#ifndef KBD_MAXRETRY
+#define KBD_MAXRETRY 3
+#endif
+
+/* timing parameters */
+#ifndef KBD_RESETDELAY
+#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
+#endif
+#ifndef KBD_MAXWAIT
+#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
+#endif
+
+/* I/O recovery time */
+#define KBDC_DELAYTIME 37
+#define KBDD_DELAYTIME 37
+
+/* I/O ports */
+#define KBD_STATUS_PORT 2 /* status port, read */
+#define KBD_DATA_PORT 0 /* data port, read */
+
+/* status bits (KBD_STATUS_PORT) */
+#define KBDS_BUFFER_FULL 0x0002
+
+/* macros */
+
+#define kbdcp(p) ((struct kbdc_softc *)(p))
+
+/* local variables */
+
+static struct kbdc_softc kbdc_softc[NPCKBD] = { { 0 }, };
+
+/* associate a port number with a KBDC */
+
+static KBDC
+kbdc_open(int port)
+{
+ if (port <= 0)
+ port = IO_KBD;
+
+ if (NPCKBD) {
+ /* PC-98 has only one keyboard I/F */
+ kbdc_softc[0].port = port;
+ kbdc_softc[0].lock = FALSE;
+ return (KBDC)&kbdc_softc[0];
+ }
+ return NULL; /* You didn't include sc driver in your config file */
+}
+
+/* set/reset polling lock */
+static int
+kbdc_lock(KBDC p, int lock)
+{
+ int prevlock;
+
+ prevlock = kbdcp(p)->lock;
+ kbdcp(p)->lock = lock;
+
+ return (prevlock != lock);
+}
+
+/* check if any data is waiting to be processed */
+static int
+kbdc_data_ready(KBDC p)
+{
+ return (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL);
+}
+
+/* wait for data from the keyboard */
+static int
+wait_for_kbd_data(struct kbdc_softc *kbdc)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+ int port = kbdc->port;
+
+ while (!(inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)) {
+ DELAY(KBDD_DELAYTIME);
+ DELAY(KBDC_DELAYTIME);
+ if (--retry < 0)
+ return 0;
+ }
+ DELAY(KBDD_DELAYTIME);
+ return 1;
+}
+
+/* read one byte from the keyboard */
+static int
+read_kbd_data(KBDC p)
+{
+ if (!wait_for_kbd_data(kbdcp(p)))
+ return -1; /* timeout */
+ DELAY(KBDC_DELAYTIME);
+ return inb(kbdcp(p)->port + KBD_DATA_PORT);
+}
+
+/* read one byte from the keyboard, but return immediately if
+ * no data is waiting
+ */
+static int
+read_kbd_data_no_wait(KBDC p)
+{
+ if (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL) {
+ DELAY(KBDD_DELAYTIME);
+ return inb(kbdcp(p)->port + KBD_DATA_PORT);
+ }
+ return -1; /* no data */
+}
+
+#endif /* NPCKBD > 0 */
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index e8d354fe7811..87d05b6cdad8 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.61 1998/12/30 07:46:23 kato Exp $
+# $Id: GENERIC98,v 1.62 1999/01/16 13:20:42 kato Exp $
# GENERIC98 -- Generic PC98 machine with WD/SCSI disks
@@ -41,7 +41,7 @@ options SCSI_DELAY=15000 #Be pessimistic about Joe SCSI device
options EPSON_BOUNCEDMA #use bounce buufer for 15-16M
#options EPSON_MEMWIN #EPSON memory window support
options UCONSOLE #Allow users to grab the console
-options "LINE30"
+#options "LINE30"
options FAILSAFE #Be conservative
options USERCONFIG #boot -c editor
options VISUAL_USERCONFIG #visual boot -c editor
@@ -126,7 +126,15 @@ device cd0 #Only need one of these, the code dynamically grows
controller matcd0 at isa? port? bio
-device sc0 at isa? port IO_KBD tty irq 1
+# keyboard driver
+device pckbd0 at isa? port IO_KBD tty irq 1
+#options KBD_INSTALL_CDEV
+
+device gdc0 at isa?
+
+#pseudo-device splash
+
+device sc0 at isa? tty
device npx0 at isa? port IO_NPX irq 8
diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98
index e8d354fe7811..87d05b6cdad8 100644
--- a/sys/pc98/conf/GENERIC98
+++ b/sys/pc98/conf/GENERIC98
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.61 1998/12/30 07:46:23 kato Exp $
+# $Id: GENERIC98,v 1.62 1999/01/16 13:20:42 kato Exp $
# GENERIC98 -- Generic PC98 machine with WD/SCSI disks
@@ -41,7 +41,7 @@ options SCSI_DELAY=15000 #Be pessimistic about Joe SCSI device
options EPSON_BOUNCEDMA #use bounce buufer for 15-16M
#options EPSON_MEMWIN #EPSON memory window support
options UCONSOLE #Allow users to grab the console
-options "LINE30"
+#options "LINE30"
options FAILSAFE #Be conservative
options USERCONFIG #boot -c editor
options VISUAL_USERCONFIG #visual boot -c editor
@@ -126,7 +126,15 @@ device cd0 #Only need one of these, the code dynamically grows
controller matcd0 at isa? port? bio
-device sc0 at isa? port IO_KBD tty irq 1
+# keyboard driver
+device pckbd0 at isa? port IO_KBD tty irq 1
+#options KBD_INSTALL_CDEV
+
+device gdc0 at isa?
+
+#pseudo-device splash
+
+device sc0 at isa? tty
device npx0 at isa? port IO_NPX irq 8
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index e5cc7f5d726a..bc9bfa758fec 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.78 1998/12/31 11:38:52 kato Exp $
+# $Id: files.pc98,v 1.79 1999/01/04 08:07:47 kato Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -26,6 +26,11 @@ font8x16.o optional std8x16font \
no-implicit-rule before-depend \
clean "${STD8X16FONT}-8x16 font8x16.c"
#
+dev/fb/fb.c optional fb device-driver
+dev/fb/fb.c optional gdc device-driver
+dev/fb/splash.c optional splash
+dev/kbd/kbd.c optional kbd device-driver
+dev/kbd/kbd.c optional pckbd device-driver
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
i386/eisa/dpt_eisa.c optional eisa dpt device-driver
@@ -141,15 +146,14 @@ i386/isa/intr_machdep.c standard
pc98/pc98/pc98.c optional isa device-driver
i386/isa/istallion.c optional stli device-driver
i386/isa/joy.c optional joy device-driver
-i386/isa/kbdio.c optional psm device-driver
-i386/isa/kbdio.c optional sc device-driver
-i386/isa/kbdio.c optional vt device-driver
+pc98/pc98/pc98kbd.c optional pckbd device-driver
i386/isa/loran.c optional loran device-driver
pc98/pc98/lpt.c optional lpt device-driver
i386/isa/labpc.c optional labpc device-driver
i386/isa/mcd.c optional mcd device-driver
pc98/pc98/mse.c optional mse device-driver
pc98/pc98/npx.c mandatory npx device-driver
+pc98/pc98/pc98gdc.c optional gdc device-driver
pc98/pc98/pcaudio.c optional pca device-driver
i386/isa/matcd/matcd.c optional matcd device-driver
i386/isa/pcibus.c optional pci device-driver
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index 7f8e5e24e8f5..22c264c07e3a 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.76 1998/12/30 08:03:03 kato Exp $
+# $Id: options.pc98,v 1.77 1999/01/04 08:09:15 kato Exp $
DISABLE_PSE
IDE_DELAY
@@ -64,27 +64,29 @@ I486_CPU opt_global.h
I586_CPU opt_global.h
I686_CPU opt_global.h
-SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
-SLOW_VGA opt_syscons.h
STD8X16FONT opt_syscons.h
SC_HISTORY_SIZE opt_syscons.h
SC_DISABLE_REBOOT opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
-SC_ALT_SEQACCESS opt_syscons.h
+
+FB_INSTALL_CDEV opt_fb.h
VESA opt_vesa.h
+GDC opt_gdc.h
+
PSM_HOOKAPM opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
PCIC_RESUME_RESET opt_pcic.h
-KBD_RESETDELAY opt_kbdio.h
-KBD_MAXRETRY opt_kbdio.h
-KBD_MAXWAIT opt_kbdio.h
-KBDIO_DEBUG opt_kbdio.h
+KBD_INSTALL_CDEV opt_kbd.h
+KBD_MAXRETRY opt_kbd.h
+KBD_MAXWAIT opt_kbd.h
+KBD_RESETDELAY opt_kbd.h
+KBDIO_DEBUG opt_kbd.h
ATAPI opt_atapi.h
ATAPI_STATIC opt_atapi.h
diff --git a/sys/pc98/pc98/pc98gdc.c b/sys/pc98/pc98/pc98gdc.c
new file mode 100644
index 000000000000..006072b26c20
--- /dev/null
+++ b/sys/pc98/pc98/pc98gdc.c
@@ -0,0 +1,859 @@
+#define TEXT_GDC IO_GDC1 /* 0x60 */
+#define ROW 25
+#define COL 80
+/*-
+ * $Id$
+ */
+
+#include "gdc.h"
+#include "opt_gdc.h"
+#include "opt_fb.h"
+#include "opt_syscons.h"
+
+#if NGDC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+#include <machine/pc/bios.h>
+
+#include <dev/fb/fbreg.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <i386/isa/isa_device.h>
+
+#define DRIVER_NAME "gdc"
+
+/* cdev driver declaration */
+
+#define GDC_UNIT(dev) minor(dev)
+#define GDC_MKMINOR(unit) (unit)
+
+static int gdcprobe(struct isa_device *dev);
+static int gdc_attach(struct isa_device *dev);
+static void gdc_drvinit(void *unused);
+
+struct isa_driver gdcdriver = {
+ gdcprobe,
+ gdc_attach,
+ DRIVER_NAME,
+ 0,
+};
+
+typedef struct gdc_softc {
+ video_adapter_t *adp;
+} gdc_softc_t;
+
+static int gdc_probe_unit(int unit, gdc_softc_t *sc, int flags);
+static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
+
+#define GDC_SOFTC(unit) (gdc_softc[unit])
+
+static gdc_softc_t *gdc_softc[NGDC];
+
+#if FB_INSTALL_CDEV
+
+static d_open_t gdcopen;
+static d_close_t gdcclose;
+static d_read_t gdcread;
+static d_ioctl_t gdcioctl;
+
+static struct cdevsw vga_cdevsw = {
+ gdcopen, gdcclose, noread, nowrite, /* ?? */
+ gdcioctl, nostop, nullreset, nodevtotty,
+ seltrue, nommap, NULL, DRIVER_NAME,
+ NULL, -1, nodump, nopsize,
+};
+
+#endif /* FB_INSTALL_CDEV */
+
+static int
+gdcprobe(struct isa_device *dev)
+{
+ gdc_softc_t *sc;
+ int error;
+
+ if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
+ return 0;
+ sc = gdc_softc[dev->id_unit]
+ = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
+ if (sc == NULL)
+ return 0;
+
+ error = gdc_probe_unit(dev->id_unit, sc, dev->id_flags);
+ if (error) {
+ gdc_softc[dev->id_unit] = NULL;
+ free(sc, M_DEVBUF);
+ return 0;
+ }
+
+ dev->id_iobase = sc->adp->va_io_base;
+ dev->id_maddr = (caddr_t)BIOS_PADDRTOVADDR(sc->adp->va_mem_base);
+ dev->id_msize = sc->adp->va_mem_size;
+
+ return sc->adp->va_io_size;
+}
+
+static int
+gdc_attach(struct isa_device *dev)
+{
+ gdc_softc_t *sc;
+
+ if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
+ return 0;
+ sc = gdc_softc[dev->id_unit];
+ if (sc == NULL)
+ return 0;
+
+ return ((gdc_attach_unit(dev->id_unit, sc, dev->id_flags)) ? 0 : 1);
+}
+
+static int
+gdc_probe_unit(int unit, gdc_softc_t *sc, int flags)
+{
+ video_switch_t *sw;
+
+ bzero(sc, sizeof(*sc));
+ sw = vid_get_switch(DRIVER_NAME);
+ if (sw == NULL)
+ return 0;
+ return (*sw->probe)(unit, &sc->adp, NULL, flags);
+}
+
+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;
+
+ error = (*sw->init)(unit, sc->adp, flags);
+ if (error)
+ return ENXIO;
+
+#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);
+
+ return 0;
+}
+
+/* LOW-LEVEL */
+
+#include <machine/clock.h>
+
+#include <pc98/pc98/30line.h>
+
+#define TEXT_BUF_BASE 0x000a0000
+#define TEXT_BUF_SIZE 0x00008000
+#define GRAPHICS_BUF_BASE 0x000a8000
+#define GRAPHICS_BUF_SIZE 0x00040000
+#define VIDEO_BUF_BASE 0x000a0000
+#define VIDEO_BUF_SIZE 0x00048000
+
+#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED)
+#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED)
+#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED)
+
+/*
+ * NOTE: `va_window' should have a virtual address, but is initialized
+ * with a physical address in the following table, they will be
+ * converted at run-time.
+ */
+static video_adapter_t adapter_init_value[] = {
+ { 0,
+ KD_PC98, "gdc", /* va_type, va_name */
+ 0, 0, /* va_unit, va_minor */
+ 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* */
+ 0, 0, /* va_buffer, va_buffer_size */
+ 0, M_PC98_80x25, 0, 0, /* va_*mode* */
+ NULL },
+};
+
+static video_adapter_t biosadapter[1];
+
+/* video driver declarations */
+static int gdc_configure(int flags);
+static int gdc_nop(void);
+static vi_probe_t gdc_probe;
+static vi_init_t gdc_init;
+static vi_get_info_t gdc_get_info;
+static vi_query_mode_t gdc_query_mode;
+static vi_set_mode_t gdc_set_mode;
+static vi_set_border_t gdc_set_border;
+static vi_save_state_t gdc_save_state;
+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_diag_t gdc_diag;
+
+static int gdc_err(video_adapter_t *adp, ...);
+
+static video_switch_t gdcvidsw = {
+ gdc_probe,
+ gdc_init,
+ gdc_get_info,
+ gdc_query_mode,
+ gdc_set_mode,
+ (vi_save_font_t *)gdc_err,
+ (vi_load_font_t *)gdc_err,
+ (vi_show_font_t *)gdc_err,
+ (vi_save_palette_t *)gdc_err,
+ (vi_load_palette_t *)gdc_err,
+ gdc_set_border,
+ gdc_save_state,
+ gdc_load_state,
+ (vi_set_win_org_t *)gdc_err,
+ gdc_read_hw_cursor,
+ gdc_set_hw_cursor,
+ gdc_set_hw_cursor_shape,
+ (vi_blank_display_t *)gdc_nop,
+ gdc_mmap,
+ gdc_diag,
+};
+
+VIDEO_DRIVER(gdc, gdcvidsw, gdc_configure);
+
+/* GDC BIOS standard video modes */
+#define EOT (-1)
+#define NA (-2)
+
+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 },
+#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 },
+#endif
+ { EOT },
+};
+
+static int init_done = FALSE;
+
+/* local functions */
+static int map_gen_mode_num(int type, int color, int mode);
+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))) \
+ return (err)
+
+/* a backdoor for the console driver */
+static int
+gdc_configure(int flags)
+{
+ probe_adapters();
+ biosadapter[0].va_flags |= V_ADP_INITIALIZED;
+ if (!config_done(&biosadapter[0])) {
+ if (vid_register(&biosadapter[0]) < 0)
+ return 1;
+ biosadapter[0].va_flags |= V_ADP_REGISTERED;
+ }
+
+ return 1;
+}
+
+/* local subroutines */
+
+/* map a generic video mode to a known mode number */
+static int
+map_gen_mode_num(int type, int color, int mode)
+{
+ static struct {
+ int from;
+ int to;
+ } mode_map[] = {
+ { M_TEXT_80x25, M_PC98_80x25, },
+#ifdef LINE30
+ { M_TEXT_80x30, M_PC98_80x30, },
+#endif
+ };
+ int i;
+
+ for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
+ if (mode_map[i].from == mode)
+ return mode_map[i].to;
+ }
+ return mode;
+}
+
+/* probe video adapters and return the number of detected adapters */
+static int
+probe_adapters(void)
+{
+ video_info_t info;
+
+ /* do this test only once */
+ if (init_done)
+ return 1;
+ init_done = TRUE;
+
+ biosadapter[0] = adapter_init_value[0];
+ biosadapter[0].va_flags |= V_ADP_PROBED;
+ biosadapter[0].va_initial_mode = biosadapter[0].va_initial_bios_mode;
+
+ master_gdc_wait_vsync();
+ master_gdc_cmd(_GDC_START); /* text ON */
+ gdc_wait_vsync();
+ gdc_cmd(_GDC_STOP); /* graphics OFF */
+
+ gdc_get_info(&biosadapter[0], biosadapter[0].va_initial_mode, &info);
+ biosadapter[0].va_mode_flags = info.vi_flags;
+ biosadapter[0].va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ biosadapter[0].va_window_size = info.vi_window_size;
+ biosadapter[0].va_window_gran = info.vi_window_gran;
+ biosadapter[0].va_buffer = 0;
+ biosadapter[0].va_buffer_size = 0;
+
+ return 1;
+}
+
+static void master_gdc_cmd(unsigned int cmd)
+{
+ while ( (inb(IO_GDC1) & 2) != 0);
+ outb(IO_GDC1+2, cmd);
+}
+
+static void master_gdc_prm(unsigned int pmtr)
+{
+ while ( (inb(IO_GDC1) & 2) != 0);
+ outb(IO_GDC1, pmtr);
+}
+
+static void master_gdc_word_prm(unsigned int wpmtr)
+{
+ master_gdc_prm(wpmtr & 0x00ff);
+ master_gdc_prm((wpmtr >> 8) & 0x00ff);
+}
+
+static void master_gdc_fifo_empty(void)
+{
+ while ( (inb(IO_GDC1) & 4) == 0);
+}
+
+static void master_gdc_wait_vsync(void)
+{
+ while ( (inb(IO_GDC1) & 0x20) != 0);
+ while ( (inb(IO_GDC1) & 0x20) == 0);
+}
+
+static void gdc_cmd(unsigned int cmd)
+{
+ while ( (inb(IO_GDC2) & 2) != 0);
+ outb( IO_GDC2+2, cmd);
+}
+
+static void gdc_prm(unsigned int pmtr)
+{
+ while ( (inb(IO_GDC2) & 2) != 0);
+ outb( IO_GDC2, pmtr);
+}
+
+static void gdc_word_prm(unsigned int wpmtr)
+{
+ gdc_prm(wpmtr & 0x00ff);
+ gdc_prm((wpmtr >> 8) & 0x00ff);
+}
+
+static void gdc_fifo_empty(void)
+{
+ while ( (inb(IO_GDC2) & 0x04) == 0);
+}
+
+static void gdc_wait_vsync(void)
+{
+ while ( (inb(IO_GDC2) & 0x20) != 0);
+ while ( (inb(IO_GDC2) & 0x20) == 0);
+}
+
+static int check_gdc_clock(void)
+{
+ if ((inb(IO_SYSPORT) & 0x80) == 0){
+ return _5MHZ;
+ } else {
+ return _2_5MHZ;
+ }
+}
+
+static void initialize_gdc(unsigned int mode)
+{
+ /* start 30line initialize */
+ int m_mode,s_mode,gdc_clock;
+ gdc_clock = check_gdc_clock();
+
+ if (mode == T25_G400){
+ m_mode = _25L;
+ }else{
+ m_mode = _30L;
+ }
+
+ s_mode = 2*mode+gdc_clock;
+
+ gdc_INFO = m_mode;
+
+ master_gdc_cmd(_GDC_RESET);
+ master_gdc_cmd(_GDC_MASTER);
+ gdc_cmd(_GDC_RESET);
+ gdc_cmd(_GDC_SLAVE);
+
+ /* GDC Master */
+ master_gdc_cmd(_GDC_SYNC);
+ master_gdc_prm(0x00); /* flush less */ /* text & graph */
+ master_gdc_prm(master_param[m_mode][GDC_CR]);
+ master_gdc_word_prm(((master_param[m_mode][GDC_HFP] << 10)
+ + (master_param[m_mode][GDC_VS] << 5)
+ + master_param[m_mode][GDC_HS]));
+ master_gdc_prm(master_param[m_mode][GDC_HBP]);
+ master_gdc_prm(master_param[m_mode][GDC_VFP]);
+ master_gdc_word_prm(((master_param[m_mode][GDC_VBP] << 10)
+ + (master_param[m_mode][GDC_LF])));
+ master_gdc_fifo_empty();
+ master_gdc_cmd(_GDC_PITCH);
+ master_gdc_prm(MasterPCH);
+ master_gdc_fifo_empty();
+
+ /* GDC slave */
+ gdc_cmd(_GDC_SYNC);
+ gdc_prm(0x06);
+ gdc_prm(slave_param[s_mode][GDC_CR]);
+ gdc_word_prm((slave_param[s_mode][GDC_HFP] << 10)
+ + (slave_param[s_mode][GDC_VS] << 5)
+ + (slave_param[s_mode][GDC_HS]));
+ gdc_prm(slave_param[s_mode][GDC_HBP]);
+ gdc_prm(slave_param[s_mode][GDC_VFP]);
+ gdc_word_prm((slave_param[s_mode][GDC_VBP] << 10)
+ + (slave_param[s_mode][GDC_LF]));
+ gdc_fifo_empty();
+ gdc_cmd(_GDC_PITCH);
+ gdc_prm(SlavePCH[gdc_clock]);
+ gdc_fifo_empty();
+
+ /* set Master GDC scroll param */
+ master_gdc_wait_vsync();
+ master_gdc_wait_vsync();
+ master_gdc_wait_vsync();
+ master_gdc_cmd(_GDC_SCROLL);
+ master_gdc_word_prm(0);
+ master_gdc_word_prm((master_param[m_mode][GDC_LF] << 4) | 0x0000);
+ master_gdc_fifo_empty();
+
+ /* set Slave GDC scroll param */
+ gdc_wait_vsync();
+ gdc_cmd(_GDC_SCROLL);
+ gdc_word_prm(0);
+ if (gdc_clock == _5MHZ){
+ gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
+ }else{
+ gdc_word_prm(SlaveScrlLF[mode] << 4);
+ }
+ gdc_fifo_empty();
+
+ gdc_word_prm(0);
+ if (gdc_clock == _5MHZ){
+ gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
+ }else{
+ gdc_word_prm(SlaveScrlLF[mode] << 4);
+ }
+ gdc_fifo_empty();
+
+ /* sync start */
+ gdc_cmd(_GDC_STOP);
+
+ gdc_wait_vsync();
+ gdc_wait_vsync();
+ gdc_wait_vsync();
+
+ master_gdc_cmd(_GDC_START);
+}
+
+/* entry points */
+
+static int
+gdc_nop(void)
+{
+ return 0;
+}
+
+static int
+gdc_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
+{
+ probe_adapters();
+ if (unit >= 1)
+ return ENXIO;
+
+ *adpp = &biosadapter[unit];
+
+ return 0;
+}
+
+static int
+gdc_init(int unit, video_adapter_t *adp, int flags)
+{
+ if ((unit >= 1) || (adp == NULL) || !probe_done(adp))
+ return ENXIO;
+
+ if (!init_done(adp)) {
+ /* nothing to do really... */
+ adp->va_flags |= V_ADP_INITIALIZED;
+ }
+
+ if (!config_done(adp)) {
+ if (vid_register(adp) < 0)
+ return ENXIO;
+ adp->va_flags |= V_ADP_REGISTERED;
+ }
+
+ return 0;
+}
+
+/*
+ * get_info():
+ * Return the video_info structure of the requested video mode.
+ */
+static int
+gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+ int i;
+
+ if (!init_done)
+ return 1;
+
+ 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) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+ if (mode == bios_vmode[i].vi_mode) {
+ *info = bios_vmode[i];
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * query_mode():
+ * Find a video mode matching the requested parameters.
+ * Fields filled with 0 are considered "don't care" fields and
+ * match any modes.
+ */
+static int
+gdc_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+ video_info_t buf;
+ int i;
+
+ if (!init_done)
+ return -1;
+
+ for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+
+ if ((info->vi_width != 0)
+ && (info->vi_width != bios_vmode[i].vi_width))
+ continue;
+ if ((info->vi_height != 0)
+ && (info->vi_height != bios_vmode[i].vi_height))
+ continue;
+ if ((info->vi_cwidth != 0)
+ && (info->vi_cwidth != bios_vmode[i].vi_cwidth))
+ continue;
+ if ((info->vi_cheight != 0)
+ && (info->vi_cheight != bios_vmode[i].vi_cheight))
+ continue;
+ if ((info->vi_depth != 0)
+ && (info->vi_depth != bios_vmode[i].vi_depth))
+ continue;
+ if ((info->vi_planes != 0)
+ && (info->vi_planes != bios_vmode[i].vi_planes))
+ continue;
+ /* XXX: should check pixel format, memory model */
+ if ((info->vi_flags != 0)
+ && (info->vi_flags != bios_vmode[i].vi_flags))
+ continue;
+
+ /* verify if this mode is supported on this adapter */
+ if (gdc_get_info(adp, bios_vmode[i].vi_mode, &buf))
+ continue;
+ return bios_vmode[i].vi_mode;
+ }
+ return -1;
+}
+
+/*
+ * set_mode():
+ * Change the video mode.
+ */
+static int
+gdc_set_mode(video_adapter_t *adp, int mode)
+{
+ video_info_t info;
+
+ prologue(adp, V_ADP_MODECHANGE, 1);
+
+ mode = map_gen_mode_num(adp->va_type,
+ adp->va_flags & V_ADP_COLOR, mode);
+ if (gdc_get_info(adp, mode, &info))
+ return 1;
+
+#ifdef LINE30
+ switch (scp->mode) {
+ case M_PC98_80x25: /* VGA TEXT MODES */
+ initialize_gdc(T25_G400);
+ break;
+ case M_PC98_80x30:
+ initialize_gdc(T30_G400);
+ break;
+ default:
+ break;
+ }
+#endif
+
+ adp->va_mode = mode;
+ adp->va_mode_flags = info.vi_flags;
+ adp->va_flags &= ~V_ADP_COLOR;
+ adp->va_flags |=
+ (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
+#if 0
+ adp->va_crtc_addr =
+ (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
+#endif
+ adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ adp->va_window_size = info.vi_window_size;
+ adp->va_window_gran = info.vi_window_gran;
+ if (info.vi_buffer_size == 0) {
+ adp->va_buffer = 0;
+ adp->va_buffer_size = 0;
+ } else {
+ adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
+ adp->va_buffer_size = info.vi_buffer_size;
+ }
+
+ /* move hardware cursor out of the way */
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
+
+ return 0;
+}
+
+/*
+ * set_border():
+ * Change the border color.
+ */
+static int
+gdc_set_border(video_adapter_t *adp, int color)
+{
+ outb(0x6c, color << 4);
+ return 0;
+}
+
+/*
+ * save_state():
+ * Read video card register values.
+ */
+static int
+gdc_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+ return 1;
+}
+
+/*
+ * load_state():
+ * Set video card registers at once.
+ */
+static int
+gdc_load_state(video_adapter_t *adp, void *p)
+{
+ return 1;
+}
+
+/*
+ * read_hw_cursor():
+ * Read the position of the hardware text cursor.
+ */
+static int
+gdc_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+ video_info_t info;
+ u_int16_t off;
+ int s;
+
+ if (!init_done)
+ return 1;
+
+ (*vidsw[adp->va_index]->get_info)(adp, adp->va_mode, &info);
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ return 1;
+
+ s = spltty();
+ master_gdc_cmd(0xe0); /* _GDC_CSRR */
+ while((inb(TEXT_GDC + 0) & 0x1) == 0) {} /* GDC wait */
+ off = inb(TEXT_GDC + 2); /* EADl */
+ off |= (inb(TEXT_GDC + 2) << 8); /* EADh */
+ inb(TEXT_GDC + 2); /* dummy */
+ inb(TEXT_GDC + 2); /* dummy */
+ inb(TEXT_GDC + 2); /* dummy */
+ splx(s);
+
+ if (off >= ROW*COL)
+ off = 0;
+ *row = off / info.vi_width;
+ *col = off % info.vi_width;
+
+ return 0;
+}
+
+/*
+ * set_hw_cursor():
+ * Move the hardware text cursor. If col and row are both -1,
+ * the cursor won't be shown.
+ */
+static int
+gdc_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+ video_info_t info;
+ u_int16_t off;
+ int s;
+
+ if (!init_done)
+ return 1;
+
+ if ((col == -1) && (row == -1)) {
+ off = -1;
+ } else {
+ (*vidsw[adp->va_index]->get_info)(adp, adp->va_mode, &info);
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ return 1;
+ off = row*info.vi_width + col;
+ }
+
+ s = spltty();
+ master_gdc_cmd(0x49); /* _GDC_CSRW */
+ master_gdc_word_prm(off);
+ splx(s);
+
+ return 0;
+}
+
+/*
+ * set_hw_cursor_shape():
+ * Change the shape of the hardware text cursor. If the height is zero
+ * or negative, the cursor won't be shown.
+ */
+static int
+gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+ int celsize, int blink)
+{
+ int start;
+ int end;
+ int s;
+
+ start = celsize - (base + height);
+ end = celsize - base - 1;
+ /*
+ * muPD7220 GDC has anomaly that if end == celsize - 1 then start
+ * must be 0, otherwise the cursor won't be correctly shown
+ * in the first row in the screen. We shall set end to celsize - 2;
+ * if end == celsize -1 && start > 0. XXX
+ */
+ if ((end == celsize - 1) && (start > 0))
+ --end;
+
+ s = spltty();
+ master_gdc_cmd(0x4b); /* _GDC_CSRFORM */
+ master_gdc_prm(((height > 0) ? 0x80 : 0) /* cursor on/off */
+ | (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;
+}
+
+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");
+ }
+}
+
+/*
+ * mmap():
+ * Mmap frame buffer.
+ */
+static int
+gdc_mmap(video_adapter_t *adp, vm_offset_t offset)
+{
+ if (offset > 0x48000 - PAGE_SIZE)
+ return -1;
+ return i386_btop((VIDEO_BUF_BASE + offset));
+}
+
+/*
+ * diag():
+ * Print some information about the video adapter and video modes,
+ * with requested level of details.
+ */
+static int
+gdc_diag(video_adapter_t *adp, int level)
+{
+ video_info_t info;
+ int i;
+
+ if (!init_done)
+ return 1;
+
+ fb_dump_adp_info(DRIVER_NAME, adp, level);
+
+#if FB_DEBUG > 1
+ for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+ if (get_mode_param(bios_vmode[i].vi_mode) == NULL)
+ continue;
+ fb_dump_mode_info(DRIVER_NAME, adp, &bios_vmode[i], level);
+ }
+#endif
+
+ return 0;
+}
+
+static int
+gdc_err(video_adapter_t *adp, ...)
+{
+ return 0;
+}
+
+#endif /* NGDC > 0 */
diff --git a/sys/pc98/pc98/pc98kbd.c b/sys/pc98/pc98/pc98kbd.c
new file mode 100644
index 000000000000..8b1a13cc29d9
--- /dev/null
+++ b/sys/pc98/pc98/pc98kbd.c
@@ -0,0 +1,983 @@
+/*-
+ * $Id$
+ */
+
+#include "pckbd.h"
+#include "opt_kbd.h"
+#include "opt_devfs.h"
+
+#if NPCKBD > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/fcntl.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+
+#include <machine/resource.h>
+
+#include <dev/kbd/kbdreg.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#ifdef __i386__
+#include <i386/isa/isa_device.h>
+#endif
+
+#define DRIVER_NAME "pckbd"
+
+/* device configuration flags */
+#define KB_CONF_FAIL_IF_NO_KBD (1 << 0) /* don't install if no kbd is found */
+
+/* some macros */
+#define PC98KBD_UNIT(dev) minor(dev)
+#define PC98KBD_MKMINOR(unit) (unit)
+
+/* cdev driver declaration */
+
+typedef struct pckbd_softc {
+ short flags;
+#define PC98KBD_ATTACHED (1 << 0)
+ keyboard_t *kbd;
+#ifdef KBD_INSTALL_CDEV
+ genkbd_softc_t gensc;
+#endif
+} pckbd_softc_t;
+
+#define PC98KBD_SOFTC(unit) pckbd_softc[(unit)]
+
+static pckbd_softc_t *pckbd_softc[NPCKBD];
+
+static int pckbdprobe(struct isa_device *dev);
+static int pckbdattach(struct isa_device *dev);
+
+static ointhand2_t pckbd_isa_intr;
+
+/* driver declaration for isa_devtab_tty[] */
+struct isa_driver pckbddriver = {
+ pckbdprobe,
+ pckbdattach,
+ DRIVER_NAME,
+ 0,
+};
+
+static int pckbd_probe_unit(int unit, pckbd_softc_t *sc,
+ int port, int irq, int flags);
+static int pckbd_attach_unit(int unit, pckbd_softc_t *sc);
+static timeout_t pckbd_timeout;
+
+#ifdef KBD_INSTALL_CDEV
+
+static d_open_t pckbdopen;
+static d_close_t pckbdclose;
+static d_read_t pckbdread;
+static d_ioctl_t pckbdioctl;
+static d_poll_t pckbdpoll;
+
+static struct cdevsw pckbd_cdevsw = {
+ pckbdopen, pckbdclose, pckbdread, nowrite,
+ pckbdioctl, nostop, nullreset, nodevtotty,
+ pckbdpoll, nommap, NULL, DRIVER_NAME,
+ NULL, -1,
+};
+
+#endif /* KBD_INSTALL_CDEV */
+
+static int
+pckbdprobe(struct isa_device *dev)
+{
+ pckbd_softc_t *sc;
+ int error;
+
+ if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
+ return 0;
+ sc = pckbd_softc[dev->id_unit];
+ if (sc == NULL) {
+ sc = pckbd_softc[dev->id_unit]
+ = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
+ if (sc == NULL)
+ return 0;
+ bzero(sc, sizeof(*sc));
+ }
+
+ /* try to find a keyboard */
+ error = pckbd_probe_unit(dev->id_unit, sc, dev->id_iobase,
+ dev->id_irq, dev->id_flags);
+ if (error)
+ return 0;
+
+ /* declare our interrupt handler */
+ dev->id_ointr = pckbd_isa_intr;
+
+ return IO_KBDSIZE;
+}
+
+static int
+pckbdattach(struct isa_device *dev)
+{
+ pckbd_softc_t *sc;
+
+ if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
+ return 0;
+ sc = pckbd_softc[dev->id_unit];
+ if (sc == NULL)
+ return 0;
+
+ return ((pckbd_attach_unit(dev->id_unit, sc)) ? 0 : 1);
+}
+
+static void
+pckbd_isa_intr(int unit)
+{
+ keyboard_t *kbd;
+
+ kbd = pckbd_softc[unit]->kbd;
+ (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
+}
+
+static int
+pckbd_probe_unit(int unit, pckbd_softc_t *sc, int port, int irq, int flags)
+{
+ keyboard_switch_t *sw;
+ int args[2];
+
+ if (sc->flags & PC98KBD_ATTACHED)
+ return 0;
+
+ sw = kbd_get_switch(DRIVER_NAME);
+ if (sw == NULL)
+ return ENXIO;
+
+ args[0] = port;
+ args[1] = irq;
+ return (*sw->probe)(unit, &sc->kbd, args, flags);
+}
+
+static int
+pckbd_attach_unit(int unit, pckbd_softc_t *sc)
+{
+ keyboard_switch_t *sw;
+ int error;
+
+ if (sc->flags & PC98KBD_ATTACHED)
+ return 0;
+
+ sw = kbd_get_switch(DRIVER_NAME);
+ if (sw == NULL)
+ return ENXIO;
+
+ /* reset, initialize and enable the device */
+ error = (*sw->init)(sc->kbd);
+ if (error)
+ return ENXIO;
+ (*sw->enable)(sc->kbd);
+
+#ifdef KBD_INSTALL_CDEV
+ /* attach a virtual keyboard cdev */
+ error = kbd_attach(makedev(0, PC98KBD_MKMINOR(unit)), sc->kbd,
+ &pckbd_cdevsw);
+ if (error)
+ return error;
+#endif /* KBD_INSTALL_CDEV */
+
+ /*
+ * This is a kludge to compensate for lost keyboard interrupts.
+ * A similar code used to be in syscons. See below. XXX
+ */
+ pckbd_timeout(sc->kbd);
+
+ if (bootverbose)
+ (*sw->diag)(sc->kbd, bootverbose);
+
+ sc->flags |= PC98KBD_ATTACHED;
+ return 0;
+}
+
+static void
+pckbd_timeout(void *arg)
+{
+ keyboard_t *kbd;
+ int s;
+
+ /* The following comments are extracted from syscons.c (1.287) */
+ /*
+ * With release 2.1 of the Xaccel server, the keyboard is left
+ * hanging pretty often. Apparently an interrupt from the
+ * keyboard is lost, and I don't know why (yet).
+ * This ugly hack calls scintr if input is ready for the keyboard
+ * and conveniently hides the problem. XXX
+ */
+ /*
+ * Try removing anything stuck in the keyboard controller; whether
+ * it's a keyboard scan code or mouse data. `scintr()' doesn't
+ * read the mouse data directly, but `kbdio' routines will, as a
+ * side effect.
+ */
+ s = spltty();
+ kbd = (keyboard_t *)arg;
+ if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) {
+ /*
+ * We have seen the lock flag is not set. Let's reset
+ * the flag early, otherwise the LED update routine fails
+ * which may want the lock during the interrupt routine.
+ */
+ (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE);
+ if ((*kbdsw[kbd->kb_index]->check_char)(kbd))
+ (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
+ }
+ splx(s);
+ timeout(pckbd_timeout, arg, hz/10);
+}
+
+/* cdev driver functions */
+
+#ifdef KBD_INSTALL_CDEV
+
+static int
+pckbdopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ pckbd_softc_t *sc;
+ int unit;
+
+ unit = PC98KBD_UNIT(dev);
+ if ((unit >= NPCKBD) || ((sc = PC98KBD_SOFTC(unit)) == NULL))
+ return ENXIO;
+ if (mode & (FWRITE | O_CREAT | O_APPEND | O_TRUNC))
+ return ENODEV;
+
+ /* FIXME: set the initial input mode (K_XLATE?) and lock state? */
+ return genkbdopen(&sc->gensc, sc->kbd, flag, mode, p);
+}
+
+static int
+pckbdclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdclose(&sc->gensc, sc->kbd, flag, mode, p);
+}
+
+static int
+pckbdread(dev_t dev, struct uio *uio, int flag)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdread(&sc->gensc, sc->kbd, uio, flag);
+}
+
+static int
+pckbdioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdioctl(&sc->gensc, sc->kbd, cmd, arg, flag, p);
+}
+
+static int
+pckbdpoll(dev_t dev, int event, struct proc *p)
+{
+ pckbd_softc_t *sc;
+
+ sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
+ return genkbdpoll(&sc->gensc, sc->kbd, event, p);
+}
+
+#endif /* KBD_INSTALL_CDEV */
+
+/* LOW-LEVEL */
+
+#include <machine/limits.h>
+#include <machine/console.h>
+#include <machine/clock.h>
+
+#define PC98KBD_DEFAULT 0
+
+typedef caddr_t KBDC;
+
+typedef struct pckbd_state {
+ KBDC kbdc; /* keyboard controller */
+ int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
+ int ks_flags; /* flags */
+#define COMPOSE (1 << 0)
+ int ks_state; /* shift/lock key state */
+ int ks_accents; /* accent key index (> 0) */
+ u_int ks_composed_char; /* composed char code (> 0) */
+} pckbd_state_t;
+
+/* keyboard driver declaration */
+static int pckbd_configure(int flags);
+static kbd_probe_t pckbd_probe;
+static kbd_init_t pckbd_init;
+static kbd_term_t pckbd_term;
+static kbd_intr_t pckbd_intr;
+static kbd_test_if_t pckbd_test_if;
+static kbd_enable_t pckbd_enable;
+static kbd_disable_t pckbd_disable;
+static kbd_read_t pckbd_read;
+static kbd_check_t pckbd_check;
+static kbd_read_char_t pckbd_read_char;
+static kbd_check_char_t pckbd_check_char;
+static kbd_ioctl_t pckbd_ioctl;
+static kbd_lock_t pckbd_lock;
+static kbd_clear_state_t pckbd_clear_state;
+static kbd_get_state_t pckbd_get_state;
+static kbd_set_state_t pckbd_set_state;
+
+keyboard_switch_t pckbdsw = {
+ pckbd_probe,
+ pckbd_init,
+ pckbd_term,
+ pckbd_intr,
+ pckbd_test_if,
+ pckbd_enable,
+ pckbd_disable,
+ pckbd_read,
+ pckbd_check,
+ pckbd_read_char,
+ pckbd_check_char,
+ pckbd_ioctl,
+ pckbd_lock,
+ pckbd_clear_state,
+ pckbd_get_state,
+ pckbd_set_state,
+ genkbd_get_fkeystr,
+ genkbd_diag,
+};
+
+KEYBOARD_DRIVER(pckbd, pckbdsw, pckbd_configure);
+
+struct kbdc_softc {
+ int port; /* base port address */
+ int lock; /* FIXME: XXX not quite a semaphore... */
+};
+
+/* local functions */
+static int probe_keyboard(KBDC kbdc, int flags);
+static int init_keyboard(KBDC kbdc, int *type, int flags);
+static KBDC kbdc_open(int port);
+static int kbdc_lock(KBDC kbdc, int lock);
+static int kbdc_data_ready(KBDC kbdc);
+static int read_kbd_data(KBDC kbdc);
+static int read_kbd_data_no_wait(KBDC kbdc);
+static int wait_for_kbd_data(struct kbdc_softc *kbdc);
+
+/* local variables */
+
+/* the initial key map, accent map and fkey strings */
+#include <i386/isa/kbdtables.h>
+
+/* structures for the default keyboard */
+static keyboard_t default_kbd;
+static pckbd_state_t default_kbd_state;
+static keymap_t default_keymap;
+static accentmap_t default_accentmap;
+static fkeytab_t default_fkeytab[NUM_FKEYS];
+
+/*
+ * The back door to the keyboard driver!
+ * This function is called by the console driver, via the kbdio module,
+ * to tickle keyboard drivers when the low-level console is being initialized.
+ * Almost nothing in the kernel has been initialied yet. Try to probe
+ * keyboards if possible.
+ * NOTE: because of the way the low-level conole is initialized, this routine
+ * may be called more than once!!
+ */
+static int
+pckbd_configure(int flags)
+{
+ keyboard_t *kbd;
+ KBDC kbdc;
+ int arg[2];
+ struct isa_device *dev;
+
+ /* XXX: a kludge to obtain the device configuration flags */
+ dev = find_isadev(isa_devtab_tty, &pckbddriver, 0);
+ if (dev != NULL)
+ flags |= dev->id_flags;
+
+ /* probe the default keyboard */
+ arg[0] = -1;
+ arg[1] = -1;
+ if (pckbd_probe(PC98KBD_DEFAULT, &kbd, arg, flags))
+ return 0;
+
+ /* initialize it */
+ kbdc = ((pckbd_state_t *)kbd->kb_data)->kbdc;
+ if (!(flags & KB_CONF_PROBE_ONLY) && !KBD_IS_PROBED(kbd)) {
+ if (KBD_HAS_DEVICE(kbd)
+ && init_keyboard(kbdc, &kbd->kb_type, flags)
+ && (flags & KB_CONF_FAIL_IF_NO_KBD))
+ return 0;
+ KBD_INIT_DONE(kbd);
+ }
+
+ /* and register */
+ if (!KBD_IS_CONFIGURED(kbd)) {
+ if (kbd_register(kbd) < 0)
+ return 0;
+ KBD_CONFIG_DONE(kbd);
+ }
+
+ return 1; /* return the number of found keyboards */
+}
+
+/* low-level functions */
+
+/* initialize the keyboard_t structure and try to detect a keyboard */
+static int
+pckbd_probe(int unit, keyboard_t **kbdp, void *arg, int flags)
+{
+ keyboard_t *kbd;
+ pckbd_state_t *state;
+ keymap_t *keymap;
+ accentmap_t *accmap;
+ fkeytab_t *fkeymap;
+ int fkeymap_size;
+ KBDC kbdc;
+ int *data = (int *)arg;
+
+ if (unit != PC98KBD_DEFAULT)
+ return ENXIO;
+
+ *kbdp = kbd = &default_kbd;
+ if (KBD_IS_PROBED(kbd))
+ return 0;
+ state = &default_kbd_state;
+ keymap = &default_keymap;
+ accmap = &default_accentmap;
+ fkeymap = default_fkeytab;
+ fkeymap_size = sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
+
+ state->kbdc = kbdc = kbdc_open(data[0]);
+ if (kbdc == NULL)
+ return ENXIO;
+ kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags, data[0],
+ IO_KBDSIZE);
+ bcopy(&key_map, keymap, sizeof(key_map));
+ bcopy(&accent_map, accmap, sizeof(accent_map));
+ bcopy(fkey_tab, fkeymap,
+ imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
+ kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
+ kbd->kb_data = (void *)state;
+
+ if (probe_keyboard(kbdc, flags)) {
+ if (flags & KB_CONF_FAIL_IF_NO_KBD)
+ return ENXIO;
+ } else {
+ KBD_FOUND_DEVICE(kbd);
+ }
+ pckbd_clear_state(kbd);
+ state->ks_mode = K_XLATE;
+
+ KBD_PROBE_DONE(kbd);
+ return 0;
+}
+
+/* reset and initialize the device */
+static int
+pckbd_init(keyboard_t *kbd)
+{
+ KBDC kbdc;
+
+ if ((kbd == NULL) || !KBD_IS_PROBED(kbd))
+ return ENXIO; /* shouldn't happen */
+ kbdc = ((pckbd_state_t *)kbd->kb_data)->kbdc;
+ if (kbdc == NULL)
+ return ENXIO; /* shouldn't happen */
+
+ if (!KBD_IS_INITIALIZED(kbd)) {
+ if (KBD_HAS_DEVICE(kbd)
+ && init_keyboard(kbdc, &kbd->kb_type, kbd->kb_config)
+ && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
+ return ENXIO;
+ pckbd_ioctl(kbd, KDSETLED,
+ (caddr_t)&((pckbd_state_t *)(kbd->kb_data))->ks_state);
+ KBD_INIT_DONE(kbd);
+ }
+ if (!KBD_IS_CONFIGURED(kbd)) {
+ if (kbd_register(kbd) < 0)
+ return ENXIO;
+ KBD_CONFIG_DONE(kbd);
+ }
+
+ return 0;
+}
+
+/* finish using this keyboard */
+static int
+pckbd_term(keyboard_t *kbd)
+{
+ kbd_unregister(kbd);
+ return 0;
+}
+
+/* keyboard interrupt routine */
+static int
+pckbd_intr(keyboard_t *kbd, void *arg)
+{
+ int c;
+
+ if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
+ /* let the callback function to process the input */
+ (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
+ kbd->kb_callback.kc_arg);
+ } else {
+ /* read and discard the input; no one is waiting for input */
+ do {
+ c = pckbd_read_char(kbd, FALSE);
+ } while (c != NOKEY);
+ }
+ return 0;
+}
+
+/* test the interface to the device */
+static int
+pckbd_test_if(keyboard_t *kbd)
+{
+ return 0;
+}
+
+/*
+ * Enable the access to the device; until this function is called,
+ * the client cannot read from the keyboard.
+ */
+static int
+pckbd_enable(keyboard_t *kbd)
+{
+ int s;
+
+ s = spltty();
+ KBD_ACTIVATE(kbd);
+ splx(s);
+ return 0;
+}
+
+/* disallow the access to the device */
+static int
+pckbd_disable(keyboard_t *kbd)
+{
+ int s;
+
+ s = spltty();
+ KBD_DEACTIVATE(kbd);
+ splx(s);
+ return 0;
+}
+
+/* read one byte from the keyboard if it's allowed */
+static int
+pckbd_read(keyboard_t *kbd, int wait)
+{
+ int c;
+
+ if (wait)
+ c = read_kbd_data(((pckbd_state_t *)kbd->kb_data)->kbdc);
+ else
+ c = read_kbd_data_no_wait(((pckbd_state_t *)kbd->kb_data)->kbdc);
+ return (KBD_IS_ACTIVE(kbd) ? c : -1);
+}
+
+/* check if data is waiting */
+static int
+pckbd_check(keyboard_t *kbd)
+{
+ if (!KBD_IS_ACTIVE(kbd))
+ return FALSE;
+ return kbdc_data_ready(((pckbd_state_t *)kbd->kb_data)->kbdc);
+}
+
+/* read char from the keyboard */
+static u_int
+pckbd_read_char(keyboard_t *kbd, int wait)
+{
+ pckbd_state_t *state;
+ u_int action;
+ int scancode;
+ int keycode;
+
+ state = (pckbd_state_t *)kbd->kb_data;
+next_code:
+ /* do we have a composed char to return? */
+ if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
+ action = state->ks_composed_char;
+ state->ks_composed_char = 0;
+ if (action > UCHAR_MAX)
+ return ERRKEY;
+ return action;
+ }
+
+ /* see if there is something in the keyboard port */
+ if (wait) {
+ do {
+ scancode = read_kbd_data(state->kbdc);
+ } while (scancode == -1);
+ } else {
+ scancode = read_kbd_data_no_wait(state->kbdc);
+ if (scancode == -1)
+ return NOKEY;
+ }
+
+ /* return the byte as is for the K_RAW mode */
+ if (state->ks_mode == K_RAW)
+ return scancode;
+
+ /* translate the scan code into a keycode */
+ keycode = scancode & 0x7F;
+ switch(scancode) {
+ case 0xF3: /* GRPH (compose key) released */
+ if (state->ks_flags & COMPOSE) {
+ state->ks_flags &= ~COMPOSE;
+ if (state->ks_composed_char > UCHAR_MAX)
+ state->ks_composed_char = 0;
+ }
+ break;
+ case 0x73: /* GRPH (compose key) pressed */
+ if (!(state->ks_flags & COMPOSE)) {
+ state->ks_flags |= COMPOSE;
+ state->ks_composed_char = 0;
+ }
+ break;
+ }
+
+ /* return the key code in the K_CODE mode */
+ if (state->ks_mode == K_CODE)
+ return (keycode | (scancode & 0x80));
+
+ /* compose a character code */
+ if (state->ks_flags & COMPOSE) {
+ switch (scancode) {
+ /* key pressed, process it */
+ case 0x42: case 0x43: case 0x44: /* keypad 7,8,9 */
+ state->ks_composed_char *= 10;
+ state->ks_composed_char += scancode - 0x3B;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+ case 0x46: case 0x47: case 0x48: /* keypad 4,5,6 */
+ state->ks_composed_char *= 10;
+ state->ks_composed_char += scancode - 0x42;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+ case 0x4A: case 0x4B: case 0x4C: /* keypad 1,2,3 */
+ state->ks_composed_char *= 10;
+ state->ks_composed_char += scancode - 0x49;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+ case 0x4E: /* keypad 0 */
+ state->ks_composed_char *= 10;
+ if (state->ks_composed_char > UCHAR_MAX)
+ return ERRKEY;
+ goto next_code;
+
+ /* key released, no interest here */
+ case 0xC2: case 0xC3: case 0xC4: /* keypad 7,8,9 */
+ case 0xC6: case 0xC7: case 0xC8: /* keypad 4,5,6 */
+ case 0xCA: case 0xCB: case 0xCC: /* keypad 1,2,3 */
+ case 0xCE: /* keypad 0 */
+ goto next_code;
+
+ case 0x73: /* GRPH key */
+ break;
+
+ default:
+ if (state->ks_composed_char > 0) {
+ state->ks_flags &= ~COMPOSE;
+ state->ks_composed_char = 0;
+ return ERRKEY;
+ }
+ break;
+ }
+ }
+
+ /* keycode to key action */
+ action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
+ &state->ks_state, &state->ks_accents);
+ if (action == NOKEY)
+ goto next_code;
+ else
+ return action;
+}
+
+/* check if char is waiting */
+static int
+pckbd_check_char(keyboard_t *kbd)
+{
+ pckbd_state_t *state;
+
+ if (!KBD_IS_ACTIVE(kbd))
+ return FALSE;
+ state = (pckbd_state_t *)kbd->kb_data;
+ if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
+ return TRUE;
+ return kbdc_data_ready(state->kbdc);
+}
+
+/* some useful control functions */
+static int
+pckbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
+{
+ pckbd_state_t *state = kbd->kb_data;
+ int s;
+ int i;
+
+ s = spltty();
+ switch (cmd) {
+
+ case KDGKBMODE: /* get keyboard mode */
+ *(int *)arg = state->ks_mode;
+ break;
+ case KDSKBMODE: /* set keyboard mode */
+ switch (*(int *)arg) {
+ case K_XLATE:
+ if (state->ks_mode != K_XLATE) {
+ /* make lock key state and LED state match */
+ state->ks_state &= ~LOCK_MASK;
+ state->ks_state |= KBD_LED_VAL(kbd);
+ }
+ /* FALL THROUGH */
+ case K_RAW:
+ case K_CODE:
+ if (state->ks_mode != *(int *)arg) {
+ pckbd_clear_state(kbd);
+ state->ks_mode = *(int *)arg;
+ }
+ break;
+ default:
+ splx(s);
+ return EINVAL;
+ }
+ break;
+
+ case KDGETLED: /* get keyboard LED */
+ *(int *)arg = KBD_LED_VAL(kbd);
+ break;
+ case KDSETLED: /* set keyboard LED */
+ /* NOTE: lock key state in ks_state won't be changed */
+ if (*(int *)arg & ~LOCK_MASK) {
+ splx(s);
+ return EINVAL;
+ }
+ i = *(int *)arg;
+ /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
+ if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
+ if (i & ALKED)
+ i |= CLKED;
+ else
+ i &= ~CLKED;
+ }
+ KBD_LED_VAL(kbd) = *(int *)arg;
+ break;
+
+ case KDGKBSTATE: /* get lock key state */
+ *(int *)arg = state->ks_state & LOCK_MASK;
+ break;
+ case KDSKBSTATE: /* set lock key state */
+ if (*(int *)arg & ~LOCK_MASK) {
+ splx(s);
+ return EINVAL;
+ }
+ state->ks_state &= ~LOCK_MASK;
+ state->ks_state |= *(int *)arg;
+ splx(s);
+ /* set LEDs and quit */
+ return pckbd_ioctl(kbd, KDSETLED, arg);
+
+ case KDSETRAD: /* set keyboard repeat rate */
+ break;
+
+ case PIO_KEYMAP: /* set keyboard translation table */
+ case PIO_KEYMAPENT: /* set keyboard translation table entry */
+ case PIO_DEADKEYMAP: /* set accent key translation table */
+ state->ks_accents = 0;
+ /* FALL THROUGH */
+ default:
+ splx(s);
+ return genkbd_commonioctl(kbd, cmd, arg);
+ }
+
+ splx(s);
+ return 0;
+}
+
+/* lock the access to the keyboard */
+static int
+pckbd_lock(keyboard_t *kbd, int lock)
+{
+ return kbdc_lock(((pckbd_state_t *)kbd->kb_data)->kbdc, lock);
+}
+
+/* clear the internal state of the keyboard */
+static void
+pckbd_clear_state(keyboard_t *kbd)
+{
+ pckbd_state_t *state;
+
+ state = (pckbd_state_t *)kbd->kb_data;
+ state->ks_flags = 0;
+ state->ks_state &= LOCK_MASK; /* preserve locking key state */
+ state->ks_accents = 0;
+ state->ks_composed_char = 0;
+}
+
+/* save the internal state */
+static int
+pckbd_get_state(keyboard_t *kbd, void *buf, size_t len)
+{
+ if (len == 0)
+ return sizeof(pckbd_state_t);
+ if (len < sizeof(pckbd_state_t))
+ return -1;
+ bcopy(kbd->kb_data, buf, sizeof(pckbd_state_t));
+ return 0;
+}
+
+/* set the internal state */
+static int
+pckbd_set_state(keyboard_t *kbd, void *buf, size_t len)
+{
+ if (len < sizeof(pckbd_state_t))
+ return ENOMEM;
+ if (((pckbd_state_t *)kbd->kb_data)->kbdc
+ != ((pckbd_state_t *)buf)->kbdc)
+ return ENOMEM;
+ bcopy(buf, kbd->kb_data, sizeof(pckbd_state_t));
+ return 0;
+}
+
+/* local functions */
+
+static int
+probe_keyboard(KBDC kbdc, int flags)
+{
+ return 0;
+}
+
+static int
+init_keyboard(KBDC kbdc, int *type, int flags)
+{
+ *type = KB_OTHER;
+ return 0;
+}
+
+/* keyboard I/O routines */
+
+/* retry count */
+#ifndef KBD_MAXRETRY
+#define KBD_MAXRETRY 3
+#endif
+
+/* timing parameters */
+#ifndef KBD_RESETDELAY
+#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
+#endif
+#ifndef KBD_MAXWAIT
+#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
+#endif
+
+/* I/O recovery time */
+#define KBDC_DELAYTIME 37
+#define KBDD_DELAYTIME 37
+
+/* I/O ports */
+#define KBD_STATUS_PORT 2 /* status port, read */
+#define KBD_DATA_PORT 0 /* data port, read */
+
+/* status bits (KBD_STATUS_PORT) */
+#define KBDS_BUFFER_FULL 0x0002
+
+/* macros */
+
+#define kbdcp(p) ((struct kbdc_softc *)(p))
+
+/* local variables */
+
+static struct kbdc_softc kbdc_softc[NPCKBD] = { { 0 }, };
+
+/* associate a port number with a KBDC */
+
+static KBDC
+kbdc_open(int port)
+{
+ if (port <= 0)
+ port = IO_KBD;
+
+ if (NPCKBD) {
+ /* PC-98 has only one keyboard I/F */
+ kbdc_softc[0].port = port;
+ kbdc_softc[0].lock = FALSE;
+ return (KBDC)&kbdc_softc[0];
+ }
+ return NULL; /* You didn't include sc driver in your config file */
+}
+
+/* set/reset polling lock */
+static int
+kbdc_lock(KBDC p, int lock)
+{
+ int prevlock;
+
+ prevlock = kbdcp(p)->lock;
+ kbdcp(p)->lock = lock;
+
+ return (prevlock != lock);
+}
+
+/* check if any data is waiting to be processed */
+static int
+kbdc_data_ready(KBDC p)
+{
+ return (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL);
+}
+
+/* wait for data from the keyboard */
+static int
+wait_for_kbd_data(struct kbdc_softc *kbdc)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+ int port = kbdc->port;
+
+ while (!(inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)) {
+ DELAY(KBDD_DELAYTIME);
+ DELAY(KBDC_DELAYTIME);
+ if (--retry < 0)
+ return 0;
+ }
+ DELAY(KBDD_DELAYTIME);
+ return 1;
+}
+
+/* read one byte from the keyboard */
+static int
+read_kbd_data(KBDC p)
+{
+ if (!wait_for_kbd_data(kbdcp(p)))
+ return -1; /* timeout */
+ DELAY(KBDC_DELAYTIME);
+ return inb(kbdcp(p)->port + KBD_DATA_PORT);
+}
+
+/* read one byte from the keyboard, but return immediately if
+ * no data is waiting
+ */
+static int
+read_kbd_data_no_wait(KBDC p)
+{
+ if (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL) {
+ DELAY(KBDD_DELAYTIME);
+ return inb(kbdcp(p)->port + KBD_DATA_PORT);
+ }
+ return -1; /* no data */
+}
+
+#endif /* NPCKBD > 0 */
diff --git a/sys/pc98/pc98/scvidctl.c b/sys/pc98/pc98/scvidctl.c
index 2a5cecc75916..77eba9811ce8 100644
--- a/sys/pc98/pc98/scvidctl.c
+++ b/sys/pc98/pc98/scvidctl.c
@@ -23,7 +23,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: scvidctl.c,v 1.5 1998/10/01 11:39:18 yokota Exp $
+ * $Id: scvidctl.c,v 1.1 1998/12/16 14:57:37 kato Exp $
*/
#include "sc.h"
@@ -40,33 +40,53 @@
#include <machine/apm_bios.h>
#include <machine/console.h>
-#include <i386/isa/videoio.h>
-#include <i386/isa/syscons.h>
+#include <dev/fb/fbreg.h>
-/* video ioctl */
+#include <pc98/pc98/syscons.h>
+/* for compatibility with previous versions */
+typedef struct old_video_adapter {
+ int va_index;
+ int va_type;
+ int va_flags;
+#define V_ADP_COLOR (1<<0)
+#define V_ADP_MODECHANGE (1<<1)
+#define V_ADP_STATESAVE (1<<2)
+#define V_ADP_STATELOAD (1<<3)
+#define V_ADP_FONT (1<<4)
+#define V_ADP_PALETTE (1<<5)
+#define V_ADP_BORDER (1<<6)
+#define V_ADP_VESA (1<<7)
+ int va_crtc_addr;
+ u_int va_window; /* virtual address */
+ size_t va_window_size;
+ size_t va_window_gran;
+ u_int va_buffer; /* virtual address */
+ size_t va_buffer_size;
+ int va_initial_mode;
+ int va_initial_bios_mode;
+ int va_mode;
+} old_video_adapter_t;
+
+#define OLD_CONS_ADPINFO _IOWR('c', 101, old_video_adapter_t)
+
+/* variables */
extern scr_stat *cur_console;
extern int fonts_loaded;
extern int sc_history_size;
extern u_char palette[];
-#ifdef PC98
-extern char crtc_type;
-#endif /* PC98 */
-#ifndef PC98
int
sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
int fontsize)
{
- video_adapter_t *adp;
video_info_t info;
int error;
int s;
int i;
- if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
return ENODEV;
- adp = get_adapter(scp);
/* adjust argument values */
if (fontsize <= 0)
@@ -112,12 +132,14 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
scp->font_size = fontsize;
scp->xsize = xsize;
scp->ysize = ysize;
+ scp->xoff = 0;
+ scp->yoff = 0;
scp->xpixel = scp->xsize*8;
scp->ypixel = scp->ysize*fontsize;
/* allocate buffers */
sc_alloc_scr_buffer(scp, TRUE, TRUE);
- if (ISMOUSEAVAIL(adp->va_flags))
+ if (ISMOUSEAVAIL(scp->adp->va_flags))
sc_alloc_cut_buffer(scp, FALSE);
sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
splx(s);
@@ -137,20 +159,16 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
return 0;
}
-#endif /* PC98 */
-#ifndef PC98
int
sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
{
- video_adapter_t *adp;
video_info_t info;
int error;
int s;
- if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
return ENODEV;
- adp = get_adapter(scp);
/* stop screen saver, etc */
s = spltty();
@@ -163,6 +181,8 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
scp->status &= ~PIXEL_MODE;
scp->mode = mode;
+ scp->xoff = 0;
+ scp->yoff = 0;
scp->xpixel = info.vi_width;
scp->ypixel = info.vi_height;
scp->xsize = info.vi_width/8;
@@ -188,22 +208,18 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
return 0;
}
-#endif /* PC98 */
-#ifndef PC98
int
sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
int fontsize)
{
- video_adapter_t *adp;
video_info_t info;
int error;
int s;
int i;
- if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
+ if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info))
return ENODEV; /* this shouldn't happen */
- adp = get_adapter(scp);
#ifdef SC_VIDEO_DEBUG
if (scp->scr_buf != NULL) {
@@ -238,7 +254,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
scp->mode, xsize, ysize, fontsize);
printf("set_pixel_mode(): window:%x, %dx%d, xoff:%d, yoff:%d\n",
- adp->va_window, info.vi_width, info.vi_height,
+ scp->adp->va_window, info.vi_width, info.vi_height,
(info.vi_width/8 - xsize)/2,
(info.vi_height/fontsize - ysize)/2);
}
@@ -282,7 +298,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
/* allocate buffers */
sc_alloc_scr_buffer(scp, TRUE, TRUE);
- if (ISMOUSEAVAIL(adp->va_flags))
+ if (ISMOUSEAVAIL(scp->adp->va_flags))
sc_alloc_cut_buffer(scp, FALSE);
sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
splx(s);
@@ -307,15 +323,11 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
return 0;
}
-#endif /* PC98 */
int
sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
{
scr_stat *scp;
-#ifndef PC98
- video_adapter_t *adp;
-#endif
int error;
int s;
@@ -324,47 +336,85 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
switch (cmd) {
case CONS_CURRENT: /* get current adapter type */
-#ifdef PC98
- *(int *)data = crtc_type;
-#else /* PC98 */
- adp = get_adapter(scp);
- *(int *)data = adp->va_type;
-#endif /* PC98 */
+ if (scp->adp == NULL)
+ return ENODEV;
+ *(int *)data = scp->adp->va_type;
return 0;
-#ifndef PC98
case CONS_CURRENTADP: /* get current adapter index */
- *(int *)data = scp->adp;
+ *(int *)data = scp->ad;
+ return 0;
+
+ case OLD_CONS_ADPINFO: /* adapter information */
+ if (scp->adp == NULL)
+ return ENODEV;
+ ((old_video_adapter_t *)data)->va_index = scp->adp->va_index;
+ ((old_video_adapter_t *)data)->va_type = scp->adp->va_type;
+ ((old_video_adapter_t *)data)->va_flags = scp->adp->va_flags;
+ ((old_video_adapter_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr;
+ ((old_video_adapter_t *)data)->va_window = scp->adp->va_window;
+ ((old_video_adapter_t *)data)->va_window_size
+ = scp->adp->va_window_size;
+ ((old_video_adapter_t *)data)->va_window_gran
+ = scp->adp->va_window_gran;
+ ((old_video_adapter_t *)data)->va_buffer = scp->adp->va_buffer;
+ ((old_video_adapter_t *)data)->va_buffer_size
+ = scp->adp->va_buffer_size;
+ ((old_video_adapter_t *)data)->va_mode = scp->adp->va_mode;
+ ((old_video_adapter_t *)data)->va_initial_mode
+ = scp->adp->va_initial_mode;
+ ((old_video_adapter_t *)data)->va_initial_bios_mode
+ = scp->adp->va_initial_bios_mode;
return 0;
case CONS_ADPINFO: /* adapter information */
- adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index);
- if (adp == NULL)
+ if (scp->adp == NULL)
return ENODEV;
- bcopy(adp, data, sizeof(*adp));
+ ((video_adapter_info_t *)data)->va_index = scp->adp->va_index;
+ ((video_adapter_info_t *)data)->va_type = scp->adp->va_type;
+ bcopy(scp->adp->va_name, ((video_adapter_info_t *)data)->va_name,
+ imin(strlen(scp->adp->va_name) + 1,
+ sizeof(((video_adapter_info_t *)data)->va_name)));
+ ((video_adapter_info_t *)data)->va_unit = scp->adp->va_unit;
+ ((video_adapter_info_t *)data)->va_flags = scp->adp->va_flags;
+ ((video_adapter_info_t *)data)->va_io_base = scp->adp->va_io_base;
+ ((video_adapter_info_t *)data)->va_io_size = scp->adp->va_io_size;
+ ((video_adapter_info_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr;
+ ((video_adapter_info_t *)data)->va_mem_base = scp->adp->va_mem_base;
+ ((video_adapter_info_t *)data)->va_mem_size = scp->adp->va_mem_size;
+ ((video_adapter_info_t *)data)->va_window = scp->adp->va_window;
+ ((video_adapter_info_t *)data)->va_window_size
+ = scp->adp->va_window_size;
+ ((video_adapter_info_t *)data)->va_window_gran
+ = scp->adp->va_window_gran;
+ ((video_adapter_info_t *)data)->va_buffer = scp->adp->va_buffer;
+ ((video_adapter_info_t *)data)->va_buffer_size
+ = scp->adp->va_buffer_size;
+ ((video_adapter_info_t *)data)->va_mode = scp->adp->va_mode;
+ ((video_adapter_info_t *)data)->va_mode_flags = scp->adp->va_mode_flags;
+ ((video_adapter_info_t *)data)->va_initial_mode
+ = scp->adp->va_initial_mode;
+ ((video_adapter_info_t *)data)->va_initial_bios_mode
+ = scp->adp->va_initial_bios_mode;
return 0;
-#endif /* PC98 */
case CONS_GET: /* get current video mode */
*(int *)data = scp->mode;
return 0;
-#ifndef PC98
case CONS_MODEINFO: /* get mode information */
- return ((*biosvidsw.get_info)(scp->adp,
+ return ((*vidsw[scp->ad]->get_info)(scp->adp,
((video_info_t *)data)->vi_mode, (video_info_t *)data)
? ENODEV : 0);
case CONS_FINDMODE: /* find a matching video mode */
- return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data)
+ return ((*vidsw[scp->ad]->query_mode)(scp->adp, (video_info_t *)data)
? ENODEV : 0);
case CONS_SETWINORG:
- return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data)
+ return ((*vidsw[scp->ad]->set_win_org)(scp->adp, *(u_int *)data)
? ENODEV : 0);
-#endif /* PC98 */
-#ifndef PC98
/* generic text modes */
case SW_TEXT_80x25: case SW_TEXT_80x30:
case SW_TEXT_80x43: case SW_TEXT_80x50:
@@ -383,8 +433,13 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case SW_ENH_B80x25: case SW_ENH_C80x25:
case SW_ENH_B80x43: case SW_ENH_C80x43:
case SW_EGAMONO80x25:
- adp = get_adapter(scp);
- if (!(adp->va_flags & V_ADP_MODECHANGE))
+
+#ifdef PC98
+ /* PC98 TEXT MODES */
+ case SW_PC98_80x25:
+ case SW_PC98_80x30:
+#endif
+ if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
@@ -394,15 +449,12 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case SW_CG640x350: case SW_ENH_CG640:
case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
case SW_VGA_MODEX:
- adp = get_adapter(scp);
- if (!(adp->va_flags & V_ADP_MODECHANGE))
+ if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
return sc_set_graphics_mode(scp, tp, cmd & 0xff);
-#endif /* PC98 */
case KDSETMODE: /* set current mode of this (virtual) console */
switch (*(int *)data) {
-#ifndef PC98
case KD_TEXT: /* switch to TEXT (known) mode */
/*
* If scp->mode is of graphics modes, we don't know which
@@ -412,8 +464,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
/* restore fonts & palette ! */
#if 0
- adp = get_adapter(scp);
- if (ISFONTAVAIL(adp->va_flags)
+ if (ISFONTAVAIL(scp->adp->va_flags)
&& !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
/*
* FONT KLUDGE
@@ -427,13 +478,13 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
copy_font(scp, LOAD, 16, font_16);
}
#endif
- load_palette(scp, palette);
+ load_palette(scp->adp, palette);
/* move hardware cursor out of the way */
- (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
+ (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1);
/* FALL THROUGH */
-#endif
+
case KD_TEXT1: /* switch to TEXT (known) mode */
/*
* If scp->mode is of graphics modes, we don't know which
@@ -446,20 +497,24 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
return error;
}
+#ifndef PC98
scp->status |= UNKNOWN_MODE;
splx(s);
/* no restore fonts & palette */
-#ifdef PC98
- scp->status &= ~UNKNOWN_MODE;
-#else
if (scp == cur_console)
-#endif
set_mode(scp);
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;
+#else /* PC98 */
+ scp->status &= ~UNKNOWN_MODE;
+ /* no restore fonts & palette */
+ if (scp == cur_console)
+ set_mode(scp);
+ sc_clear_screen(scp);
+ splx(s);
+#endif /* PC98 */
return 0;
-#ifndef PC98
case KD_PIXEL: /* pixel (raster) display */
if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
return EINVAL;
@@ -475,12 +530,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
if (scp == cur_console) {
set_mode(scp);
- load_palette(scp, palette);
+ load_palette(scp->adp, palette);
}
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;
return 0;
-#endif /* PC98 */
case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
s = spltty();
@@ -489,10 +543,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
return error;
}
scp->status |= UNKNOWN_MODE;
+ splx(s);
#ifdef PC98
- set_mode(scp);
+ if (scp == cur_console)
+ set_mode(scp);
#endif
- splx(s);
return 0;
default:
@@ -500,13 +555,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
}
/* NOT REACHED */
-#ifndef PC98
case KDRASTER: /* set pixel (raster) display mode */
if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
return ENODEV;
return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
((int *)data)[2]);
-#endif /* PC98 */
case KDGETMODE: /* get current mode of this (virtual) console */
/*
@@ -519,7 +572,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case KDSBORDER: /* set border color of this (virtual) console */
scp->border = *data;
if (scp == cur_console)
- set_border(cur_console, scp->border);
+ set_border(scp, scp->border);
return 0;
}
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index 67742dd208df..c0054c0811d3 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -25,10 +25,11 @@
* (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.105 1999/01/08 16:09:23 kato Exp $
+ * $Id: syscons.c,v 1.106 1999/01/17 15:42:27 kato Exp $
*/
#include "sc.h"
+#include "splash.h"
#include "apm.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
@@ -67,30 +68,25 @@
#include <vm/vm_param.h>
#include <vm/pmap.h>
+#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 <i386/isa/kbdtables.h>
-#include <i386/isa/kbdio.h>
-#include <i386/isa/videoio.h>
#include <pc98/pc98/syscons.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>
-#include <i386/isa/kbdtables.h>
-#include <i386/isa/kbdio.h>
-#include <i386/isa/videoio.h>
-#include <i386/isa/syscons.h>
#endif /* PC98 */
-#if defined(PC98) && defined(LINE30)
-#include <pc98/pc98/30line.h>
-#endif
-
#if !defined(MAXCONS)
#define MAXCONS 16
#endif
@@ -135,10 +131,6 @@ typedef struct old_mouse_info {
} u;
} old_mouse_info_t;
-/* XXX use sc_bcopy where video memory is concerned */
-extern void generic_bcopy(const void *, void *, size_t);
-extern void generic_bzero(void *, size_t);
-
static default_attr user_default = {
(FG_LIGHTGREY | BG_BLACK) << 8,
(FG_BLACK | BG_LIGHTGREY) << 8
@@ -168,8 +160,6 @@ static scr_stat *new_scp, *old_scp;
static term_stat kernel_console;
static default_attr *current_default;
static int sc_flags;
-static int sc_port = IO_KBD;
-static KBDC sc_kbdc = NULL;
static char init_done = COLD;
static u_short sc_buffer[ROW*COL];
static char shutdown_in_progress = FALSE;
@@ -178,33 +168,19 @@ static char switch_in_progress = FALSE;
static char write_in_progress = FALSE;
static char blink_in_progress = FALSE;
static int blinkrate = 0;
-#ifndef PC98
- u_int crtc_addr = MONO_BASE;
-#endif
- char crtc_type = KD_MONO;
-static char crtc_vga = FALSE;
-static int adp_flags;
-static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
-static u_char accents = 0;
-#ifdef PC98
-static u_char nlkcnt = 0, slkcnt = 0, alkcnt = 0;
-#else
-static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
-#endif
-static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab);
+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 */
- int scrn_blanked = 0; /* screen saver active flag */
+static int scrn_blanked = FALSE; /* screen saver active flag */
static long scrn_time_stamp;
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 */
u_char scr_map[256];
u_char scr_rmap[256];
-#ifndef PC98
static int initial_video_mode; /* initial video mode # */
-static int bios_video_mode; /* video mode # set by BIOS */
-#endif
int fonts_loaded = 0
#ifdef STD8X16FONT
| FONT_16
@@ -243,7 +219,6 @@ static int extra_history_size =
static void none_saver(int blank) { }
static void (*current_saver)(int blank) = none_saver;
-static void (*default_saver)(int blank) = none_saver;
d_ioctl_t *sc_user_ioctl;
static int sticky_splash = FALSE;
@@ -264,7 +239,7 @@ static struct tty sccons[MAXCONS+2];
#define SC_CONSOLE 255
u_short *Crtat;
#ifdef PC98
-u_short *Atrat;
+u_short *Atrat;
static u_char default_kanji = UJIS;
#endif
static const int nsccons = MAXCONS+2;
@@ -279,20 +254,40 @@ static const int nsccons = MAXCONS+2;
#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))
+
/* prototypes */
static int scattach(struct isa_device *dev);
-static ointhand2_t scintr;
+static kbd_callback_func_t sckbdevent;
static int scparam(struct tty *tp, struct termios *t);
static int scprobe(struct isa_device *dev);
-static int scvidprobe(int unit, int flags);
-static int sckbdprobe(int unit, int flags);
+static int scvidprobe(int unit, int flags, int cons);
+static int sckbdprobe(int unit, int flags, int cons);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
static void scshutdown(int howto, void *arg);
-static u_int scgetc(u_int flags);
+static u_int scgetc(keyboard_t *kbd, 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);
@@ -300,9 +295,19 @@ static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark);
static int get_scr_num(void);
static timeout_t scrn_timer;
static void scrn_update(scr_stat *scp, int show_cursor);
-static void scrn_saver(void (*saver)(int), int blank);
+#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 set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border);
+static int restore_scrn_saver_mode(scr_stat *scp);
static void stop_scrn_saver(void (*saver)(int));
static int wait_scrn_saver_stop(void);
+#define scsplash_stick(stick) (sticky_splash = (stick))
+#else
+#define scsplash_stick(stick)
+#endif /* NSPLASH */
static int switch_scr(scr_stat *scp, u_int next_scr);
static void exchange_scr(void);
static void scan_esc(scr_stat *scp, u_char c);
@@ -310,15 +315,13 @@ 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 move_crsr(scr_stat *scp, int x, int y);
-static u_char *get_fstr(u_int c, u_int *len);
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);
-#ifndef PC98
-static void set_keyboard(int command, int data);
-#endif
-static void update_leds(int which);
+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);
@@ -336,14 +339,6 @@ static void draw_cutmarking(scr_stat *scp);
static void remove_cutmarking(scr_stat *scp);
static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
-#ifdef SC_SPLASH_SCREEN
-static void scsplash_init(scr_stat *scp);
-static void scsplash_term(scr_stat *scp);
-static void scsplash_saver(int show);
-#define scsplash_stick(stick) (sticky_splash = (stick))
-#else
-#define scsplash_stick(stick)
-#endif
static cn_probe_t sccnprobe;
static cn_init_t sccninit;
@@ -413,26 +408,20 @@ at2pc98(unsigned int attr)
static void
draw_cursor_image(scr_stat *scp)
{
-#ifndef PC98
+#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;
-#endif
-#ifdef PC98
- int pos = scp->cursor_pos - scp->scr_buf;
- while((inb(TEXT_GDC + 0) & 0x04) == 0) {}
- outb(TEXT_GDC + 2, 0x49); /* CSRW */
- outb(TEXT_GDC + 0, pos & 0xff); /* EADl */
- outb(TEXT_GDC + 0, pos >> 8); /* EADh */
-#else
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 *)(get_adapter(scp)->va_window)
+ ptr = (u_short *)(scp->adp->va_window)
+ (scp->cursor_pos - scp->scr_buf);
/* do we have a destructive cursor ? */
@@ -487,7 +476,7 @@ remove_cursor_image(scr_stat *scp)
sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
scp->cursor_oldpos - scp->scr_buf, 0);
else
- *((u_short *)(get_adapter(scp)->va_window)
+ *((u_short *)(scp->adp->va_window)
+ (scp->cursor_oldpos - scp->scr_buf))
= scp->cursor_saveunder;
#endif
@@ -515,242 +504,72 @@ move_crsr(scr_stat *scp, int x, int y)
static int
scprobe(struct isa_device *dev)
{
- if (!scvidprobe(dev->id_unit, dev->id_flags)) {
+ if (!scvidprobe(dev->id_unit, dev->id_flags, FALSE)) {
if (bootverbose)
printf("sc%d: no video adapter is found.\n", dev->id_unit);
return (0);
}
-#ifndef PC98
-#if defined(VESA) && defined(VM86)
- if (vesa_load())
- return FALSE;
-#endif
-
- (*biosvidsw.diag)(bootverbose);
-#endif /* PC98 */
-
- sc_port = dev->id_iobase;
- if (sckbdprobe(dev->id_unit, dev->id_flags))
- return (IO_KBDSIZE);
- else
- return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+ return ((sckbdprobe(dev->id_unit, dev->id_flags, FALSE)) ? -1 : 0);
}
/* probe video adapters, return TRUE if found */
static int
-scvidprobe(int unit, int flags)
+scvidprobe(int unit, int flags, int cons)
{
-#ifndef PC98
video_adapter_t *adp;
-#endif
- /* do this test only once */
- if (init_done != COLD)
- return (crtc_type != -1);
+ /*
+ * Access the video adapter driver through the back door!
+ * Video adapter drivers need to be configured before syscons.
+ * However, when syscons is being probed as the low-level console,
+ * they have not been initialized yet. We force them to initialize
+ * themselves here. XXX
+ */
+ vid_configure(cons ? VIO_PROBE_ONLY : 0);
-#ifdef PC98
- Crtat = (u_short *)TEXT_VRAM;
- Atrat = (u_short *)TEXT_VRAM + ATTR_OFFSET;
- crtc_type = KD_PC98;
-#else
- if ((*biosvidsw.init)() <= 0)
- return FALSE;
- if ((adp = (*biosvidsw.adapter)(V_ADP_PRIMARY)) == NULL)
- return FALSE;
+ /* 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 */
- crtc_type = adp->va_type;
- crtc_vga = (crtc_type == KD_VGA);
- crtc_addr = adp->va_crtc_addr;
Crtat = (u_short *)adp->va_window;
- adp_flags = adp->va_flags;
+#ifdef PC98
+ Atrat = Crtat + ATTR_OFFSET;
+#endif
initial_video_mode = adp->va_initial_mode;
- bios_video_mode = adp->va_initial_bios_mode;
-#endif /* PC98 */
return TRUE;
}
/* probe the keyboard, return TRUE if found */
static int
-sckbdprobe(int unit, int flags)
+sckbdprobe(int unit, int flags, int cons)
{
-#ifndef PC98
- int codeset;
- int c = -1;
- int m;
- int res, id;
-#endif
-
- sc_kbdc = kbdc_open(sc_port);
-#ifndef PC98
- if (!kbdc_lock(sc_kbdc, TRUE)) {
- /* driver error? */
- printf("sc%d: unable to lock the controller.\n", unit);
- return ((flags & DETECT_KBD) ? FALSE : TRUE);
- }
+ /* access the keyboard driver through the backdoor! */
+ kbd_configure(cons ? KB_CONF_PROBE_ONLY : 0);
- /* flush any noise in the buffer */
- empty_both_buffers(sc_kbdc, 10);
-
- /* save the current keyboard controller command byte */
- m = kbdc_get_device_mask(sc_kbdc) & ~KBD_KBD_CONTROL_BITS;
- c = get_controller_command_byte(sc_kbdc);
- if (c == -1) {
- /* CONTROLLER ERROR */
- printf("sc%d: unable to get the current command byte value.\n", unit);
- goto fail;
- }
- if (bootverbose)
- printf("sc%d: the current keyboard controller command byte %04x\n",
- unit, c);
-#if 0
- /* override the keyboard lock switch */
- c |= KBD_OVERRIDE_KBD_LOCK;
-#endif
-
- /*
- * The keyboard may have been screwed up by the boot block.
- * We may just be able to recover from error by testing the controller
- * and the keyboard port. The controller command byte needs to be saved
- * before this recovery operation, as some controllers seem to set
- * the command byte to particular values.
- */
- test_controller(sc_kbdc);
- test_kbd_port(sc_kbdc);
-
- /* enable the keyboard port, but disable the keyboard intr. */
- if (!set_controller_command_byte(sc_kbdc,
- KBD_KBD_CONTROL_BITS,
- KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT)) {
- /* CONTROLLER ERROR
- * there is very little we can do...
- */
- printf("sc%d: unable to set the command byte.\n", unit);
- goto fail;
- }
-
- /*
- * Check if we have an XT keyboard before we attempt to reset it.
- * The procedure assumes that the keyboard and the controller have
- * been set up properly by BIOS and have not been messed up
- * during the boot process.
- */
- codeset = -1;
- if (flags & XT_KEYBD)
- /* the user says there is a XT keyboard */
- codeset = 1;
-#ifdef DETECT_XT_KEYBOARD
- else if ((c & KBD_TRANSLATION) == 0) {
- /* SET_SCANCODE_SET is not always supported; ignore error */
- if (send_kbd_command_and_data(sc_kbdc, KBDC_SET_SCANCODE_SET, 0)
- == KBD_ACK)
- codeset = read_kbd_data(sc_kbdc);
- }
- if (bootverbose)
- printf("sc%d: keyboard scancode set %d\n", unit, codeset);
-#endif /* DETECT_XT_KEYBOARD */
-
- if (flags & KBD_NORESET) {
- write_kbd_command(sc_kbdc, KBDC_ECHO);
- if (read_kbd_data(sc_kbdc) != KBD_ECHO) {
- empty_both_buffers(sc_kbdc, 10);
- test_controller(sc_kbdc);
- test_kbd_port(sc_kbdc);
- if (bootverbose)
- printf("sc%d: failed to get response from the keyboard.\n",
- unit);
- goto fail;
- }
- } else {
- /* reset keyboard hardware */
- if (!reset_kbd(sc_kbdc)) {
- /* KEYBOARD ERROR
- * Keyboard reset may fail either because the keyboard doen't
- * exist, or because the keyboard doesn't pass the self-test,
- * or the keyboard controller on the motherboard and the keyboard
- * somehow fail to shake hands. It is just possible, particularly
- * in the last case, that the keyoard controller may be left
- * in a hung state. test_controller() and test_kbd_port() appear
- * to bring the keyboard controller back (I don't know why and
- * how, though.)
- */
- empty_both_buffers(sc_kbdc, 10);
- test_controller(sc_kbdc);
- test_kbd_port(sc_kbdc);
- /* We could disable the keyboard port and interrupt... but,
- * the keyboard may still exist (see above).
- */
- if (bootverbose)
- printf("sc%d: failed to reset the keyboard.\n", unit);
- goto fail;
- }
- }
-
- /*
- * Allow us to set the XT_KEYBD flag in UserConfig so that keyboards
- * such as those on the IBM ThinkPad laptop computers can be used
- * with the standard console driver.
- */
- if (codeset == 1) {
- if (send_kbd_command_and_data(
- sc_kbdc, KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) {
- /* XT kbd doesn't need scan code translation */
- c &= ~KBD_TRANSLATION;
- } else {
- /* KEYBOARD ERROR
- * The XT kbd isn't usable unless the proper scan code set
- * is selected.
- */
- printf("sc%d: unable to set the XT keyboard mode.\n", unit);
- goto fail;
- }
- }
- /* enable the keyboard port and intr. */
- if (!set_controller_command_byte(sc_kbdc,
- KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
- (c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK))
- | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
- /* CONTROLLER ERROR
- * This is serious; we are left with the disabled keyboard intr.
- */
- printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
- goto fail;
- }
-
- /* Get the ID of the keyboard, if any */
- empty_kbd_buffer(sc_kbdc, 5);
- res = send_kbd_command(sc_kbdc, KBDC_SEND_DEV_ID);
- if (res == KBD_ACK) {
- /* 10ms delay */
- DELAY(10000);
- id = (read_kbd_data(sc_kbdc) << 8) | read_kbd_data(sc_kbdc);
- if (bootverbose)
- printf("sc%d: keyboard device ID: %04x\n", unit, id);
+ /* 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 */
- kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
- kbdc_lock(sc_kbdc, FALSE);
-#endif /* !PC98 */
return TRUE;
-#ifndef PC98
-fail:
- if (c != -1)
- /* try to restore the command byte as before, if possible */
- set_controller_command_byte(sc_kbdc, 0xff, c);
- kbdc_set_device_mask(sc_kbdc,
- (flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
- kbdc_lock(sc_kbdc, FALSE);
- return FALSE;
-#endif /* !PC98 */
}
#if NAPM > 0
static int
scresume(void *dummy)
{
- shfts = ctls = alts = agrs = metas = accents = 0;
- return 0;
+ if (kbd != NULL)
+ kbd_clear_state(kbd);
+ return 0;
}
#endif
@@ -758,7 +577,7 @@ static int
scattach(struct isa_device *dev)
{
scr_stat *scp;
-#ifndef PC98
+#if defined(VESA) && defined(VM86)
video_info_t info;
#endif
dev_t cdev = makedev(CDEV_MAJOR, 0);
@@ -766,14 +585,12 @@ scattach(struct isa_device *dev)
int vc;
#endif
- dev->id_ointr = scintr;
scinit();
+ scp = console[0];
sc_flags = dev->id_flags;
- if (!ISFONTAVAIL(adp_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
sc_flags &= ~CHAR_CURSOR;
- scp = console[0];
-
/* copy temporary buffer to final buffer */
scp->scr_buf = NULL;
#ifdef PC98
@@ -786,28 +603,27 @@ scattach(struct isa_device *dev)
#endif
/* cut buffer is available only when the mouse pointer is used */
- if (ISMOUSEAVAIL(adp_flags))
+ if (ISMOUSEAVAIL(scp->adp->va_flags))
sc_alloc_cut_buffer(scp, FALSE);
/* initialize history buffer & pointers */
sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE);
-#ifndef PC98
#if defined(VESA) && defined(VM86)
if ((sc_flags & VESA800X600)
- && ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
-#ifdef SC_SPLASH_SCREEN
- scsplash_term(scp);
+ && ((*vidsw[scp->ad]->get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
+#if NSPLASH > 0
+ splash_term(scp->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;
-#ifdef SC_SPLASH_SCREEN
- scsplash_init(scp);
+#if NSPLASH > 0
+ /* put up the splash again! */
+ splash_init(scp->adp, scsplash_callback);
#endif
}
#endif /* VESA && VM86 */
-#endif /* PC98 */
/* initialize cursor stuff */
if (!ISGRAPHSC(scp))
@@ -816,20 +632,30 @@ scattach(struct isa_device *dev)
/* get screen update going */
scrn_timer((void *)TRUE);
- update_leds(scp->status);
+ /* set up the keyboard */
+ kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ update_kbd_state(scp->status, LOCK_MASK);
+ if (bootverbose) {
+ printf("sc%d:", dev->id_unit);
+ if (adapter >= 0)
+ printf(" fb%d", adapter);
+ if (keyboard >= 0)
+ printf(" kbd%d", keyboard);
+ printf("\n");
+ }
printf("sc%d: ", dev->id_unit);
- switch(crtc_type) {
+ switch(scp->adp->va_type) {
#ifdef PC98
case KD_PC98:
printf(" <text mode>");
break;
#else
case KD_VGA:
- printf("VGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono");
+ printf("VGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
break;
case KD_EGA:
- printf("EGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono");
+ printf("EGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
break;
case KD_CGA:
printf("CGA");
@@ -887,6 +713,7 @@ int
scopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct tty *tp = scdevtotty(dev);
+ keyarg_t key;
if (!tp)
return(ENXIO);
@@ -898,7 +725,9 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
ttychars(tp);
/* Use the current setting of the <-- key as default VERASE. */
/* If the Delete key is preferable, an stty is necessary */
- tp->t_cc[VERASE] = key_map.key[0x0e].map[0];
+ 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];
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
tp->t_cflag = TTYDEF_CFLAG;
@@ -914,10 +743,8 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
return(EBUSY);
if (minor(dev) < MAXCONS && !console[minor(dev)]) {
console[minor(dev)] = alloc_scp();
-#ifndef PC98
if (ISGRAPHSC(console[minor(dev)]))
sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16);
-#endif /* PC98 */
}
if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
tp->t_winsize.ws_col = console[minor(dev)]->xsize;
@@ -994,38 +821,53 @@ scwrite(dev_t dev, struct uio *uio, int flag)
return((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
-static void
-scintr(int unit)
+static int
+sckbdevent(keyboard_t *thiskbd, int event, void *arg)
{
static struct tty *cur_tty;
- int c, len;
+ int c;
+ size_t len;
u_char *cp;
+ /* assert(thiskbd == kbd) */
+
+ switch (event) {
+ case KBDIO_KEYINPUT:
+ break;
+ case KBDIO_UNLOADING:
+ kbd = NULL;
+ kbd_release(thiskbd, (void *)keyboard);
+ return 0;
+ default:
+ return EINVAL;
+ }
+
/*
* Loop while there is still input to get from the keyboard.
* 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(SCGETC_NONBLOCK)) != NOKEY) {
+ while ((c = scgetc(thiskbd, SCGETC_NONBLOCK)) != NOKEY) {
cur_tty = VIRTUAL_TTY(get_scr_num());
if (!(cur_tty->t_state & TS_ISOPEN))
if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN))
continue;
- switch (c & 0xff00) {
+ switch (KEYFLAGS(c)) {
case 0x0000: /* normal key */
- (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty);
+ (*linesw[cur_tty->t_line].l_rint)(KEYCHAR(c), cur_tty);
break;
case FKEY: /* function key, return string */
- if (cp = get_fstr((u_int)c, (u_int *)&len)) {
+ cp = kbd_get_fkeystr(thiskbd, KEYCHAR(c), &len);
+ if (cp != NULL) {
while (len-- > 0)
- (*linesw[cur_tty->t_line].l_rint)(*cp++ & 0xFF, cur_tty);
+ (*linesw[cur_tty->t_line].l_rint)(*cp++, cur_tty);
}
break;
case MKEY: /* meta is active, prepend ESC */
(*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty);
- (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty);
+ (*linesw[cur_tty->t_line].l_rint)(KEYCHAR(c), cur_tty);
break;
case BKEY: /* backtab fixed sequence (esc [ Z) */
(*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty);
@@ -1035,17 +877,11 @@ scintr(int unit)
}
}
-#if 0
- if (cur_console->status & MOUSE_ENABLED) {
- cur_console->status &= ~MOUSE_VISIBLE;
- remove_mouse_image(cur_console);
- }
-#else
if (cur_console->status & MOUSE_VISIBLE) {
remove_mouse_image(cur_console);
cur_console->status &= ~MOUSE_VISIBLE;
}
-#endif
+ return 0;
}
static int
@@ -1065,9 +901,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
int i;
struct tty *tp;
scr_stat *scp;
-#ifndef PC98
- video_adapter_t *adp;
-#endif
int s;
tp = scdevtotty(dev);
@@ -1093,11 +926,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 ? */
-#ifdef PC98
- *(int*)data = 0;
-#else
- *(int *)data = (adp_flags & V_ADP_COLOR) ? 1 : 0;
-#endif
+ *(int *)data = (scp->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
return 0;
case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
@@ -1115,10 +944,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
else
sc_flags &= ~BLINK_CURSOR;
if ((*(int*)data) & 0x02) {
-#ifndef PC98
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
return ENXIO;
-#endif /* PC98 */
sc_flags |= CHAR_CURSOR;
} else
sc_flags &= ~CHAR_CURSOR;
@@ -1127,10 +954,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* are affected. Update the cursor in the current console...
*/
if (!ISGRAPHSC(cur_console)) {
+ s = spltty();
remove_cursor_image(cur_console);
if (sc_flags & CHAR_CURSOR)
set_destructive_cursor(cur_console);
draw_cursor_image(cur_console);
+ splx(s);
}
return 0;
@@ -1192,10 +1021,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
mouse_info_t buf;
/* FIXME: */
-#ifndef PC98
- if (!ISMOUSEAVAIL(get_adapter(scp)->va_flags))
+ if (!ISMOUSEAVAIL(scp->adp->va_flags))
return ENODEV;
-#endif /* PC98 */
if (cmd == OLD_CONS_MOUSECTL) {
static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
@@ -1457,8 +1284,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
}
/* make screensaver happy */
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
+ sc_touch_scrn_saver();
return 0;
}
@@ -1579,7 +1405,9 @@ 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;
- ptr->mk_keylock = scp->status & LOCK_KEY_MASK;
+ if (scp == cur_console)
+ save_kbd_state(scp);
+ ptr->mk_keylock = scp->status & LOCK_MASK;
return 0;
}
return EINVAL;
@@ -1611,10 +1439,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
scsplash_stick(FALSE);
saver_mode = *(int *)data;
s = spltty();
+#if NSPLASH > 0
if ((error = wait_scrn_saver_stop())) {
splx(s);
return error;
}
+#endif /* NSPLASH */
scp->status |= SAVER_RUNNING;
scsplash_stick(TRUE);
splx(s);
@@ -1643,38 +1473,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
return 0;
-#ifdef PC98
- case SW_PC98_80x25:
- case SW_PC98_80x30: /* PC98 TEXT MODES */
- if (!crtc_vga)
- return ENXIO;
- scp->xsize = 80;
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
- if (scp->history != NULL)
- i = imax(scp->history_size / scp->xsize
- - imax(SC_HISTORY_SIZE, scp->ysize), 0);
- else
- i = 0;
- switch (cmd & 0xff) {
- case M_PC98_80x25:
- scp->ysize = 25;
- break;
-#ifdef LINE30
- case M_PC98_80x30:
- scp->ysize = LINE30_ROW;
- break;
-#endif
- default:
- return EINVAL;
- }
-#endif
-
case VT_SETMODE: /* set screen switcher mode */
{
struct vt_mode *mode;
@@ -1779,43 +1577,36 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KDSKBSTATE: /* set keyboard state (locks) */
- if (*(int *)data & ~LOCK_KEY_MASK)
+ if (*(int *)data & ~LOCK_MASK)
return EINVAL;
- scp->status &= ~LOCK_KEY_MASK;
+ scp->status &= ~LOCK_MASK;
scp->status |= *(int *)data;
if (scp == cur_console)
- update_leds(scp->status);
+ update_kbd_state(scp->status, LOCK_MASK);
return 0;
case KDGKBSTATE: /* get keyboard state (locks) */
- *(int *)data = scp->status & LOCK_KEY_MASK;
+ if (scp == cur_console)
+ save_kbd_state(scp);
+ *(int *)data = scp->status & LOCK_MASK;
return 0;
case KDSETRAD: /* set keyboard repeat & delay rates */
-#ifndef PC98
if (*(int *)data & ~0x7f)
return EINVAL;
- if (sc_kbdc != NULL)
- set_keyboard(KBDC_SET_TYPEMATIC, *(int *)data);
-#endif
- return 0;
+ error = kbd_ioctl(kbd, KDSETRAD, data);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ return error;
case KDSKBMODE: /* set keyboard mode */
switch (*(int *)data) {
+ case K_XLATE: /* switch to XLT ascii mode */
case K_RAW: /* switch to RAW scancode mode */
- scp->status &= ~KBD_CODE_MODE;
- scp->status |= KBD_RAW_MODE;
- return 0;
-
case K_CODE: /* switch to CODE mode */
- scp->status &= ~KBD_RAW_MODE;
- scp->status |= KBD_CODE_MODE;
- return 0;
-
- case K_XLATE: /* switch to XLT ascii mode */
- if (scp == cur_console && scp->status & KBD_RAW_MODE)
- shfts = ctls = alts = agrs = metas = accents = 0;
- scp->status &= ~(KBD_RAW_MODE | KBD_CODE_MODE);
+ scp->kbd_mode = *(int *)data;
+ if (scp == cur_console)
+ kbd_ioctl(kbd, cmd, data);
return 0;
default:
return EINVAL;
@@ -1823,10 +1614,15 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
/* NOT REACHED */
case KDGKBMODE: /* get keyboard mode */
- *(int *)data = (scp->status & KBD_RAW_MODE) ? K_RAW :
- ((scp->status & KBD_CODE_MODE) ? K_CODE : K_XLATE);
+ *(int *)data = scp->kbd_mode;
return 0;
+ case KDGKBINFO:
+ error = kbd_ioctl(kbd, cmd, data);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ return error;
+
case KDMKTONE: /* sound the bell */
if (*(int*)data)
do_bell(scp, (*(int*)data)&0xffff,
@@ -1878,44 +1674,74 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KDGKBTYPE: /* get keyboard type */
- *(int *)data = 0; /* type not known (yet) */
+ error = kbd_ioctl(kbd, cmd, data);
+ if (error == ENOIOCTL) {
+ /* always return something? XXX */
+ *(int *)data = 0;
+ }
return 0;
case KDSETLED: /* set keyboard LED status */
- if (*(int *)data & ~LED_MASK)
+ if (*(int *)data & ~LED_MASK) /* FIXME: LOCK_MASK? */
return EINVAL;
scp->status &= ~LED_MASK;
scp->status |= *(int *)data;
if (scp == cur_console)
- update_leds(scp->status);
+ update_kbd_leds(scp->status);
return 0;
case KDGETLED: /* get keyboard LED status */
+ if (scp == cur_console)
+ save_kbd_state(scp);
*(int *)data = scp->status & LED_MASK;
return 0;
- case GETFKEY: /* get functionkey string */
- if (*(u_short*)data < n_fkey_tab) {
- fkeyarg_t *ptr = (fkeyarg_t*)data;
- bcopy(&fkey_tab[ptr->keynum].str, ptr->keydef,
- fkey_tab[ptr->keynum].len);
- ptr->flen = fkey_tab[ptr->keynum].len;
- return 0;
- }
- else
- return EINVAL;
+ case CONS_SETKBD: /* set the new keyboard */
+ {
+ keyboard_t *newkbd;
- case SETFKEY: /* set functionkey string */
- if (*(u_short*)data < n_fkey_tab) {
- fkeyarg_t *ptr = (fkeyarg_t*)data;
- bcopy(ptr->keydef, &fkey_tab[ptr->keynum].str,
- min(ptr->flen, MAXFK));
- fkey_tab[ptr->keynum].len = min(ptr->flen, MAXFK);
- return 0;
+ s = spltty();
+ newkbd = kbd_get_keyboard(*(int *)data);
+ if (newkbd == NULL) {
+ splx(s);
+ return EINVAL;
+ }
+ error = 0;
+ if (kbd != newkbd) {
+ i = kbd_allocate(newkbd->kb_name, newkbd->kb_unit,
+ (void *)&keyboard, sckbdevent, NULL);
+ /* i == newkbd->kb_index */
+ if (i >= 0) {
+ if (kbd != NULL) {
+ save_kbd_state(cur_console);
+ kbd_release(kbd, (void *)&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);
+ } else {
+ error = EPERM; /* XXX */
+ }
+ }
+ splx(s);
+ return error;
}
- else
- return EINVAL;
+ 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 (error == 0) {
+ kbd = NULL;
+ keyboard = -1;
+ }
+ }
+ splx(s);
+ return error;
+
case GIO_SCRNMAP: /* get output translation table */
bcopy(&scr_map, data, sizeof(scr_map));
return 0;
@@ -1926,36 +1752,19 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
scr_rmap[scr_map[i]] = i;
return 0;
- case GIO_KEYMAP: /* get keyboard translation table */
- bcopy(&key_map, data, sizeof(key_map));
- return 0;
-
- case PIO_KEYMAP: /* set keyboard translation table */
- accents = 0;
- bzero(&accent_map, sizeof(accent_map));
- bcopy(data, &key_map, sizeof(key_map));
- return 0;
-
- case GIO_DEADKEYMAP: /* get accent key translation table */
- bcopy(&accent_map, data, sizeof(accent_map));
- return 0;
-
- case PIO_DEADKEYMAP: /* set accent key translation table */
- accents = 0;
- bcopy(data, &accent_map, sizeof(accent_map));
- return 0;
+ case GIO_KEYMAP: /* get keyboard translation table */
+ case PIO_KEYMAP: /* set keyboard translation table */
+ case GIO_DEADKEYMAP: /* get accent key translation table */
+ 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);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ return error;
-#ifdef PC98
case PIO_FONT8x8: /* set 8x8 dot font */
- case GIO_FONT8x8: /* get 8x8 dot font */
- case PIO_FONT8x14: /* set 8x14 dot font */
- case GIO_FONT8x14: /* get 8x14 dot font */
- case PIO_FONT8x16: /* set 8x16 dot font */
- case GIO_FONT8x16: /* get 8x16 dot font */
- return ENXIO;
-#else
- case PIO_FONT8x8: /* set 8x8 dot font */
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
return ENXIO;
bcopy(data, font_8, 8*256);
fonts_loaded |= FONT_8;
@@ -1969,7 +1778,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case GIO_FONT8x8: /* get 8x8 dot font */
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
return ENXIO;
if (fonts_loaded & FONT_8) {
bcopy(font_8, data, 8*256);
@@ -1979,7 +1788,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x14: /* set 8x14 dot font */
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
return ENXIO;
bcopy(data, font_14, 14*256);
fonts_loaded |= FONT_14;
@@ -1994,7 +1803,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case GIO_FONT8x14: /* get 8x14 dot font */
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
return ENXIO;
if (fonts_loaded & FONT_14) {
bcopy(font_14, data, 14*256);
@@ -2004,7 +1813,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x16: /* set 8x16 dot font */
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
return ENXIO;
bcopy(data, font_16, 16*256);
fonts_loaded |= FONT_16;
@@ -2018,7 +1827,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case GIO_FONT8x16: /* get 8x16 dot font */
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
+ if (!ISFONTAVAIL(scp->adp->va_flags))
return ENXIO;
if (fonts_loaded & FONT_16) {
bcopy(font_16, data, 16*256);
@@ -2026,7 +1835,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
}
else
return ENXIO;
-#endif /* PC98 */
#ifdef PC98
case ADJUST_CLOCK: /* /dev/rtc for 98note resume */
@@ -2106,16 +1914,15 @@ sccnprobe(struct consdev *cp)
return;
}
- if (!scvidprobe(dvp->id_unit, dvp->id_flags)) {
+ if (!scvidprobe(dvp->id_unit, dvp->id_flags, TRUE)) {
cp->cn_pri = CN_DEAD;
return;
}
+ sckbdprobe(dvp->id_unit, dvp->id_flags, TRUE);
/* initialize required fields */
cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
cp->cn_pri = CN_INTERNAL;
-
- sc_kbdc = kbdc_open(sc_port);
}
static void
@@ -2128,9 +1935,34 @@ static void
sccnputc(dev_t dev, int c)
{
u_char buf[1];
- int s;
scr_stat *scp = console[0];
term_stat save = scp->term;
+ u_short *p;
+ int s;
+ int i;
+
+ if (scp == cur_console && 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);
+ }
+#if 1 /* XXX */
+ scstart(VIRTUAL_TTY(get_scr_num()));
+#endif
+ }
scp->term = kernel_console;
current_default = &kernel_default;
@@ -2142,7 +1974,7 @@ sccnputc(dev_t dev, int c)
current_default = &user_default;
scp->term = save;
- s = spltty(); /* block scintr and scrn_timer */
+ s = spltty(); /* block sckbdevent and scrn_timer */
sccnupdate(scp);
splx(s);
}
@@ -2150,35 +1982,63 @@ sccnputc(dev_t dev, int c)
static int
sccngetc(dev_t dev)
{
- int s = spltty(); /* block scintr and scrn_timer while we poll */
+ return sccngetch(0);
+}
+
+static int
+sccncheckc(dev_t dev)
+{
+ return sccngetch(SCGETC_NONBLOCK);
+}
+
+static int
+sccngetch(int flags)
+{
+ int cur_mode;
+ int s = spltty(); /* block sckbdevent and scrn_timer while we poll */
int c;
/*
* Stop the screen saver and update the screen if necessary.
* What if we have been running in the screen saver code... XXX
*/
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
+ sc_touch_scrn_saver();
sccnupdate(cur_console);
- c = scgetc(SCGETC_CN);
- splx(s);
- return(c);
-}
+ if (kbd == NULL) {
+ splx(s);
+ return -1;
+ }
-static int
-sccncheckc(dev_t dev)
-{
- int s = spltty(); /* block scintr and scrn_timer while we poll */
- int c;
+ /*
+ * Make sure the keyboard is accessible even when the kbd device
+ * driver is disabled.
+ */
+ kbd_enable(kbd);
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
- sccnupdate(cur_console);
+ /* 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);
+
+ c = scgetc(kbd, SCGETC_CN | flags);
- c = scgetc(SCGETC_CN | SCGETC_NONBLOCK);
+ cur_console->kbd_mode = cur_mode;
+ kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
+ kbd_disable(kbd);
splx(s);
- return(c == NOKEY ? -1 : c); /* c == -1 can't happen */
+
+ switch (KEYFLAGS(c)) {
+ case 0: /* normal char */
+ return KEYCHAR(c);
+ case FKEY: /* function key */
+ return c; /* XXX */
+ case NOKEY:
+ case ERRKEY:
+ default:
+ return -1;
+ }
+ /* NOT REACHED */
}
static void
@@ -2190,18 +2050,18 @@ sccnupdate(scr_stat *scp)
return;
if (panicstr || shutdown_in_progress) {
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
+ sc_touch_scrn_saver();
} else if (scp != cur_console) {
return;
}
if (!run_scrn_saver)
scrn_idle = FALSE;
+#if NSPLASH > 0
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
if (scp->status & SAVER_RUNNING)
stop_scrn_saver(current_saver);
-
+#endif /* NSPLASH */
if (scp != cur_console || blink_in_progress || switch_in_progress)
return;
@@ -2246,37 +2106,12 @@ scrn_timer(void *arg)
}
s = spltty();
- /*
- * With release 2.1 of the Xaccel server, the keyboard is left
- * hanging pretty often. Apparently an interrupt from the
- * keyboard is lost, and I don't know why (yet).
- * This ugly hack calls scintr if input is ready for the keyboard
- * and conveniently hides the problem. XXX
- */
- /* Try removing anything stuck in the keyboard controller; whether
- * it's a keyboard scan code or mouse data. `scintr()' doesn't
- * read the mouse data directly, but `kbdio' routines will, as a
- * side effect.
- */
- if (kbdc_lock(sc_kbdc, TRUE)) {
- /*
- * We have seen the lock flag is not set. Let's reset the flag early;
- * otherwise `update_led()' failes which may want the lock
- * during `scintr()'.
- */
- kbdc_lock(sc_kbdc, FALSE);
- if (kbdc_data_ready(sc_kbdc))
- scintr(0);
- }
-
scp = cur_console;
/* should we stop the screen saver? */
getmicrouptime(&tv);
- if (panicstr || shutdown_in_progress) {
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
- }
+ if (panicstr || shutdown_in_progress)
+ sc_touch_scrn_saver();
if (run_scrn_saver) {
scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time);
} else {
@@ -2285,10 +2120,11 @@ scrn_timer(void *arg)
if (scrn_blank_time > 0)
run_scrn_saver = TRUE;
}
+#if NSPLASH > 0
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
if (scp->status & SAVER_RUNNING)
stop_scrn_saver(current_saver);
-
+#endif /* NSPLASH */
/* should we just return ? */
if (blink_in_progress || switch_in_progress) {
if (arg)
@@ -2304,7 +2140,7 @@ scrn_timer(void *arg)
/* should we activate the screen saver? */
if ((saver_mode == CONS_LKM_SAVER) && scrn_idle)
if (!ISGRAPHSC(scp) || (scp->status & SAVER_RUNNING))
- scrn_saver(current_saver, TRUE);
+ (*current_saver)(TRUE);
if (arg)
timeout(scrn_timer, (void *)TRUE, hz / 25);
@@ -2385,25 +2221,90 @@ scrn_update(scr_stat *scp, int show_cursor)
scp->start = scp->xsize*scp->ysize - 1;
}
-int
+#if NSPLASH > 0
+
+static int
+scsplash_callback(int event)
+{
+ int error;
+
+ switch (event) {
+ case SPLASH_INIT:
+ if (add_scrn_saver(scsplash_saver) == 0) {
+ run_scrn_saver = TRUE;
+ if (cold && !(boothowto & (RB_VERBOSE | RB_CONFIG))) {
+ scsplash_stick(TRUE);
+ (*current_saver)(TRUE);
+ }
+ }
+ return 0;
+
+ case SPLASH_TERM:
+ if (current_saver == scsplash_saver) {
+ scsplash_stick(FALSE);
+ error = remove_scrn_saver(scsplash_saver);
+ if (error)
+ return error;
+ }
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+}
+
+static void
+scsplash_saver(int show)
+{
+ static int busy = FALSE;
+ static int failed = FALSE;
+ scr_stat *scp;
+
+ if (busy)
+ return;
+ busy = TRUE;
+
+ scp = cur_console;
+ if (show) {
+ if (!failed) {
+ if (!scrn_blanked)
+ set_scrn_saver_mode(scp, -1, NULL, 0);
+ if (splash(scp->adp, TRUE) == 0) {
+ scrn_blanked = TRUE;
+ } else {
+ failed = TRUE;
+ scsplash_stick(FALSE);
+ printf("scsplash_saver(): failed to put up the image\n");
+ restore_scrn_saver_mode(scp);
+ }
+ }
+ } else if (!sticky_splash) {
+ if (scrn_blanked && (splash(scp->adp, FALSE) == 0)) {
+ restore_scrn_saver_mode(scp);
+ scrn_blanked = FALSE;
+ }
+ }
+ busy = FALSE;
+}
+
+static int
add_scrn_saver(void (*this_saver)(int))
{
-#ifdef SC_SPLASH_SCREEN
- if (current_saver == scsplash) {
- scsplash_stick(FALSE);
- stop_scrn_saver(scsplash);
+ int error;
+
+ if (current_saver != none_saver) {
+ error = remove_scrn_saver(current_saver);
+ if (error)
+ return error;
}
-#endif
- if (current_saver != default_saver)
- return EBUSY;
run_scrn_saver = FALSE;
saver_mode = CONS_LKM_SAVER;
current_saver = this_saver;
return 0;
}
-int
+static int
remove_scrn_saver(void (*this_saver)(int))
{
if (current_saver != this_saver)
@@ -2416,35 +2317,77 @@ remove_scrn_saver(void (*this_saver)(int))
* before stopping the current saver, rather than blocking by `splXX()'.
*/
current_saver = none_saver;
- if (scrn_blanked > 0)
+ if (scrn_blanked)
stop_scrn_saver(this_saver);
- if (scrn_blanked > 0)
- return EBUSY; /* XXX */
+ return (scrn_blanked ? EBUSY : 0);
+}
- current_saver = default_saver;
- return 0;
+static int
+set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border)
+{
+ int s;
+
+ /* assert(scp == cur_console) */
+ s = spltty();
+ scp->splash_save_mode = scp->mode;
+ scp->splash_save_status = scp->status & (GRAPHICS_MODE | PIXEL_MODE);
+ scp->status &= ~PIXEL_MODE;
+ scp->status |= (UNKNOWN_MODE | SAVER_RUNNING);
+ splx(s);
+ if (mode < 0)
+ return 0;
+ scp->mode = mode;
+ if (set_mode(scp) == 0) {
+ if (scp->adp->va_mode_flags & V_INFO_GRAPHICS)
+ scp->status |= GRAPHICS_MODE;
+ if (pal != NULL)
+ load_palette(scp->adp, pal);
+ set_border(scp, border);
+ return 0;
+ } else {
+ s = spltty();
+ scp->mode = scp->splash_save_mode;
+ scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING);
+ scp->status |= scp->splash_save_status;
+ splx(s);
+ return 1;
+ }
}
-static void
-scrn_saver(void (*saver)(int), int blank)
+static int
+restore_scrn_saver_mode(scr_stat *scp)
{
- static int busy = FALSE;
+ int mode;
+ int status;
+ int s;
- if (busy)
- return;
- busy = TRUE;
- (*saver)(blank);
- busy = FALSE;
+ /* assert(scp == cur_console) */
+ s = spltty();
+ mode = scp->mode;
+ status = scp->status;
+ scp->mode = scp->splash_save_mode;
+ scp->status &= ~(UNKNOWN_MODE | GRAPHICS_MODE | SAVER_RUNNING);
+ scp->status |= scp->splash_save_status;
+ if (set_mode(scp) == 0) {
+ load_palette(scp->adp, palette);
+ splx(s);
+ return 0;
+ } else {
+ scp->mode = mode;
+ scp->status = status;
+ splx(s);
+ return 1;
+ }
}
static void
stop_scrn_saver(void (*saver)(int))
{
- scrn_saver(saver, FALSE);
+ (*saver)(FALSE);
run_scrn_saver = FALSE;
/* the screen saver may have chosen not to stop after all... */
- if (scrn_blanked > 0)
+ if (scrn_blanked)
return;
mark_all(cur_console);
@@ -2458,7 +2401,7 @@ wait_scrn_saver_stop(void)
{
int error = 0;
- while (scrn_blanked > 0) {
+ while (scrn_blanked) {
run_scrn_saver = FALSE;
error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0);
run_scrn_saver = FALSE;
@@ -2468,6 +2411,15 @@ wait_scrn_saver_stop(void)
return error;
}
+#endif /* NSPLASH */
+
+void
+sc_touch_scrn_saver(void)
+{
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
+}
+
void
sc_clear_screen(scr_stat *scp)
{
@@ -2490,9 +2442,8 @@ static int
switch_scr(scr_stat *scp, u_int next_scr)
{
/* delay switch if actively updating screen */
- if (scrn_blanked > 0 || write_in_progress || blink_in_progress) {
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
+ if (scrn_blanked || write_in_progress || blink_in_progress) {
+ sc_touch_scrn_saver();
delayed_next_scr = next_scr+1;
return 0;
}
@@ -2551,7 +2502,12 @@ switch_scr(scr_stat *scp, u_int next_scr)
static void
exchange_scr(void)
{
+ /* 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);
+
+ /* set up the video for the new screen */
cur_console = new_scp;
#ifdef PC98
if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp) || ISUNKNOWNSC(new_scp))
@@ -2564,20 +2520,17 @@ exchange_scr(void)
if (ISTEXTSC(new_scp) && (sc_flags & CHAR_CURSOR))
set_destructive_cursor(new_scp);
if (ISGRAPHSC(old_scp))
- load_palette(new_scp, palette);
+ load_palette(new_scp->adp, palette);
#endif
- if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE ||
- old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE)
- shfts = ctls = alts = agrs = metas = accents = 0;
set_border(new_scp, new_scp->border);
- update_leds(new_scp->status);
+
+ /* 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);
+
delayed_next_scr = FALSE;
mark_all(new_scp);
-#ifdef PC98
- if (new_scp->mode == 0x102) {
- bzero(Crtat, 800*600/8);
- }
-#endif
}
static void
@@ -3272,7 +3225,7 @@ scan_esc(scr_stat *scp, u_char c)
sc_flags &= ~CHAR_CURSOR;
#else /* PC98 */
if ((scp->term.param[0] & 0x02)
- && ISFONTAVAIL(get_adapter(scp)->va_flags))
+ && ISFONTAVAIL(scp->adp->va_flags))
sc_flags |= CHAR_CURSOR;
else
sc_flags &= ~CHAR_CURSOR;
@@ -3287,10 +3240,12 @@ scan_esc(scr_stat *scp, u_char c)
* are affected. Update the cursor in the current console...
*/
if (!ISGRAPHSC(cur_console)) {
+ i = spltty();
remove_cursor_image(cur_console);
if (sc_flags & CHAR_CURSOR)
set_destructive_cursor(cur_console);
draw_cursor_image(cur_console);
+ splx(i);
}
break;
@@ -3786,12 +3741,9 @@ kanji_end:
static void
scinit(void)
{
-#ifdef PC98
- u_int hw_cursor;
-#else
+ video_adapter_t *adp;
int col;
int row;
-#endif
u_int i;
if (init_done != COLD)
@@ -3799,32 +3751,18 @@ scinit(void)
init_done = WARM;
#ifdef PC98
- if (pc98_machine_type & M_8M) {
- BELL_PITCH = 1339;
- } else {
- BELL_PITCH = 1678;
- }
- outb(0x62, 0xd);
- outb(0xA2, 0xd);
- /* Extract cursor location */
- while((inb(TEXT_GDC + 0) & 0x04) == 0) {} /* GDC wait */
- outb(TEXT_GDC + 2, 0xe0); /* CSRR */
- while((inb(TEXT_GDC + 0) & 0x1) == 0) {} /* GDC wait */
- hw_cursor = inb(TEXT_GDC + 2); /* EADl */
- hw_cursor |= (inb(TEXT_GDC + 2) << 8); /* EADh */
- inb(TEXT_GDC + 2); /* dummy */
- inb(TEXT_GDC + 2); /* dummy */
- inb(TEXT_GDC + 2); /* dummy */
+ if (pc98_machine_type & M_8M)
+ BELL_PITCH = 1339;
+ else
+ BELL_PITCH = 1678;
+#endif
- if (hw_cursor >= ROW*COL) {
- hw_cursor = 0;
- }
- crtc_vga = TRUE;
-#else /* IBM-PC */
- /* extract the hardware cursor location and move it out of the way */
- (*biosvidsw.read_hw_cursor)(V_ADP_PRIMARY, &col, &row);
- (*biosvidsw.set_hw_cursor)(V_ADP_PRIMARY, -1, -1);
-#endif /* PC98 */
+ /* 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);
+#endif
/* set up the first console */
current_default = &user_default;
@@ -3834,23 +3772,11 @@ scinit(void)
/* copy screen to temporary buffer */
if (ISTEXTSC(console[0]))
-#ifdef PC98
- generic_bcopy(Crtat, sc_buffer,
- console[0]->xsize * console[0]->ysize * sizeof(u_short));
-#else /* PC98 */
- generic_bcopy((ushort *)(get_adapter(console[0])->va_window), sc_buffer,
+ generic_bcopy((ushort *)(console[0]->adp->va_window), sc_buffer,
console[0]->xsize * console[0]->ysize * sizeof(u_short));
-#endif /* PC98 */
console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
= sc_buffer;
-#ifdef PC98
- console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor;
- console[0]->atr_buf = Atrat;
- console[0]->cursor_atr = Atrat + hw_cursor;
- console[0]->xpos = hw_cursor % COL;
- console[0]->ypos = hw_cursor / COL;
-#else
if (col >= console[0]->xsize)
col = 0;
if (row >= console[0]->ysize)
@@ -3859,7 +3785,11 @@ scinit(void)
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;
#endif
for (i=1; i<MAXCONS; i++)
console[i] = NULL;
@@ -3875,12 +3805,11 @@ scinit(void)
scr_map[i] = scr_rmap[i] = i;
}
#ifdef PC98
- scr_map[0x5c] = (u_char)0xfc; /* for backslash */
+ scr_map[0x5c] = (u_char)0xfc; /* for backslash */
#endif
-#ifndef PC98
/* Save font and palette */
- if (ISFONTAVAIL(get_adapter(cur_console)->va_flags)) {
+ if (ISFONTAVAIL(cur_console->adp->va_flags)) {
if (fonts_loaded & FONT_16) {
copy_font(cur_console, LOAD, 16, font_16);
} else {
@@ -3892,22 +3821,20 @@ scinit(void)
* FONT KLUDGE
* Always use the font page #0. XXX
*/
- (*biosvidsw.show_font)(cur_console->adp, 0);
+ (*vidsw[cur_console->ad]->show_font)(cur_console->adp, 0);
}
- save_palette(cur_console, palette);
+ save_palette(cur_console->adp, palette);
-#ifdef SC_SPLASH_SCREEN
- /* put up the splash. */
- scsplash_init(cur_console);
-#endif
+#if NSPLASH > 0
+ /* we are ready to put up the splash image! */
+ splash_init(cur_console->adp, scsplash_callback);
#endif
}
static void
scshutdown(int howto, void *arg)
{
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
+ sc_touch_scrn_saver();
if (!cold && cur_console->smode.mode == VT_AUTO
&& console[0]->smode.mode == VT_AUTO)
switch_scr(cur_console, 0);
@@ -3919,8 +3846,10 @@ sc_clean_up(scr_stat *scp)
{
int error;
+#if NSPLASH > 0
if ((error = wait_scrn_saver_stop()))
return error;
+#endif /* NSPLASH */
scp->status &= ~MOUSE_VISIBLE;
remove_cutmarking(scp);
return 0;
@@ -4023,13 +3952,13 @@ static scr_stat
#ifdef PC98
sc_alloc_cut_buffer(scp, TRUE);
#else /* PC98 */
- if (ISMOUSEAVAIL(get_adapter(scp)->va_flags))
+ if (ISMOUSEAVAIL(scp->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 (get_adapter(scp)->va_flags & V_ADP_MODECHANGE)
+ if (scp->adp->va_flags & V_ADP_MODECHANGE)
#endif
set_mode(scp);
*/
@@ -4043,26 +3972,14 @@ static scr_stat
static void
init_scp(scr_stat *scp)
{
-#ifndef PC98
video_info_t info;
-#endif
-#ifdef PC98
- scp->mode = M_PC98_80x25;
- scp->scr_buf = NULL;
- scp->atr_buf = NULL;
- scp->font_size = 16;
-
- scp->xsize = COL;
- scp->ysize = ROW;
- scp->xpixel = scp->xsize * 8;
- scp->ypixel = scp->ysize * scp->font_size;
-#else
- scp->adp = V_ADP_PRIMARY;
- (*biosvidsw.get_info)(scp->adp, initial_video_mode, &info);
+ scp->ad = adapter;
+ scp->adp = vid_get_adapter(scp->ad);
+ (*vidsw[scp->ad]->get_info)(scp->adp, initial_video_mode, &info);
scp->status = 0;
- scp->mode = scp->initial_mode = initial_video_mode;
+ scp->mode = initial_video_mode;
scp->scr_buf = NULL;
if (info.vi_flags & V_INFO_GRAPHICS) {
scp->status |= GRAPHICS_MODE;
@@ -4079,7 +3996,6 @@ init_scp(scr_stat *scp)
scp->font_size = info.vi_cheight;
}
scp->xoff = scp->yoff = 0;
-#endif
scp->xpos = scp->ypos = 0;
scp->saved_xpos = scp->saved_ypos = -1;
scp->start = scp->xsize * scp->ysize;
@@ -4104,15 +4020,13 @@ init_scp(scr_stat *scp)
scp->mouse_signal = 0;
scp->mouse_pid = 0;
scp->mouse_proc = NULL;
+ scp->kbd_mode = K_XLATE;
scp->bell_pitch = BELL_PITCH;
scp->bell_duration = BELL_DURATION;
-#ifdef PC98
- scp->status = 0;
- scp->status |= CURSOR_ENABLED;
-#else
+#ifndef PC98
scp->status |= (*(u_int8_t *)pa_to_va(0x417) & 0x20) ? NLKED : 0;
- scp->status |= CURSOR_ENABLED;
#endif
+ scp->status |= CURSOR_ENABLED;
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
@@ -4127,20 +4041,6 @@ init_scp(scr_stat *scp)
#endif
}
-static u_char
-*get_fstr(u_int c, u_int *len)
-{
- u_int i;
-
- if (!(c & FKEY))
- return(NULL);
- i = (c & 0xFF) - F_FN;
- if (i > n_fkey_tab)
- return(NULL);
- *len = fkey_tab[i].len;
- return(fkey_tab[i].str);
-}
-
static void
history_to_screen(scr_stat *scp)
{
@@ -4201,151 +4101,46 @@ history_down_line(scr_stat *scp)
* return NOKEY if there is nothing there.
*/
static u_int
-scgetc(u_int flags)
+scgetc(keyboard_t *kbd, u_int flags)
{
- struct keyent_t *key;
- u_char scancode, keycode;
- u_int state, action;
- int c;
- static u_char esc_flag = 0, compose = 0;
- static u_int chr = 0;
+ u_int c;
+ int this_scr;
+ int f;
+ int i;
+
+ if (kbd == NULL)
+ return NOKEY;
next_code:
+ /* I don't like this, but... XXX */
+ if (flags & SCGETC_CN)
+ sccnupdate(cur_console);
/* first see if there is something in the keyboard port */
- if (flags & SCGETC_NONBLOCK) {
- c = read_kbd_data_no_wait(sc_kbdc);
- if (c == -1)
- return(NOKEY);
- } else {
- do {
- c = read_kbd_data(sc_kbdc);
- } while(c == -1);
+ for (;;) {
+ c = kbd_read_char(kbd, !(flags & SCGETC_NONBLOCK));
+ if (c == ERRKEY) {
+ if (!(flags & SCGETC_CN))
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ } else if (c == NOKEY)
+ return c;
+ else
+ break;
}
- scancode = (u_char)c;
/* make screensaver happy */
- if (!(scancode & 0x80)) {
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
- }
+ if (!(c & RELKEY))
+ sc_touch_scrn_saver();
- if (!(flags & SCGETC_CN)) {
+ if (!(flags & SCGETC_CN))
/* do the /dev/random device a favour */
- add_keyboard_randomness(scancode);
-
- if (cur_console->status & KBD_RAW_MODE)
- return scancode;
- }
-
- keycode = scancode & 0x7F;
- switch (esc_flag) {
- case 0x00: /* normal scancode */
- switch(scancode) {
- case 0xB8: /* left alt (compose key) */
- if (compose) {
- compose = 0;
- if (chr > 255) {
- do_bell(cur_console,
- BELL_PITCH, BELL_DURATION);
- chr = 0;
- }
- }
- break;
- case 0x38:
- if (!compose) {
- compose = 1;
- chr = 0;
- }
- break;
- case 0xE0:
- case 0xE1:
- esc_flag = scancode;
- goto next_code;
- }
- break;
- case 0xE0: /* 0xE0 prefix */
- esc_flag = 0;
- switch (keycode) {
- case 0x1C: /* right enter key */
- keycode = 0x59;
- break;
- case 0x1D: /* right ctrl key */
- keycode = 0x5A;
- break;
- case 0x35: /* keypad divide key */
- keycode = 0x5B;
- break;
- case 0x37: /* print scrn key */
- keycode = 0x5C;
- break;
- case 0x38: /* right alt key (alt gr) */
- keycode = 0x5D;
- break;
- case 0x47: /* grey home key */
- keycode = 0x5E;
- break;
- case 0x48: /* grey up arrow key */
- keycode = 0x5F;
- break;
- case 0x49: /* grey page up key */
- keycode = 0x60;
- break;
- case 0x4B: /* grey left arrow key */
- keycode = 0x61;
- break;
- case 0x4D: /* grey right arrow key */
- keycode = 0x62;
- break;
- case 0x4F: /* grey end key */
- keycode = 0x63;
- break;
- case 0x50: /* grey down arrow key */
- keycode = 0x64;
- break;
- case 0x51: /* grey page down key */
- keycode = 0x65;
- break;
- case 0x52: /* grey insert key */
- keycode = 0x66;
- break;
- case 0x53: /* grey delete key */
- keycode = 0x67;
- break;
+ add_keyboard_randomness(c);
- /* the following 3 are only used on the MS "Natural" keyboard */
- case 0x5b: /* left Window key */
- keycode = 0x69;
- break;
- case 0x5c: /* right Window key */
- keycode = 0x6a;
- break;
- case 0x5d: /* menu key */
- keycode = 0x6b;
- break;
- default: /* ignore everything else */
- goto next_code;
- }
- break;
- case 0xE1: /* 0xE1 prefix */
- esc_flag = 0;
- if (keycode == 0x1D)
- esc_flag = 0x1D;
- goto next_code;
- /* NOT REACHED */
- case 0x1D: /* pause / break */
- esc_flag = 0;
- if (keycode != 0x45)
- goto next_code;
- keycode = 0x68;
- break;
- }
-
- if (!(flags & SCGETC_CN) && (cur_console->status & KBD_CODE_MODE))
- return (keycode | (scancode & 0x80));
+ if (cur_console->kbd_mode != K_XLATE)
+ return KEYCHAR(c);
/* if scroll-lock pressed allow history browsing */
- if (cur_console->history && cur_console->status & SLKED) {
- int i;
+ if (!ISGRAPHSC(cur_console) && cur_console->history
+ && cur_console->status & SLKED) {
cur_console->status &= ~CURSOR_ENABLED;
if (!(cur_console->status & BUFFER_SAVED)) {
@@ -4371,10 +4166,11 @@ next_code:
cur_console->history + cur_console->history_size)
#ifdef PC98
{
-#endif
cur_console->history_head=cur_console->history;
-#ifdef PC98
- cur_console->his_atr_head=cur_console->his_atr; }
+ 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;
@@ -4383,12 +4179,10 @@ next_code:
#endif
history_to_screen(cur_console);
}
- switch (scancode) {
-#ifdef PC98
- case 0x3E: /* home key */
-#else
- case 0x47: /* home key */
-#endif
+ 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;
@@ -4396,11 +4190,8 @@ next_code:
history_to_screen(cur_console);
goto next_code;
-#ifdef PC98
- case 0x3F: /* help key */
-#else
- case 0x4F: /* end key */
-#endif
+ 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);
@@ -4412,183 +4203,65 @@ next_code:
history_to_screen(cur_console);
goto next_code;
-#ifdef PC98
- case 0x3A: /* up arrow key */
-#else
- case 0x48: /* up arrow key */
-#endif
+ case SPCLKEY | FKEY | F(50): /* up arrow key */
+ remove_cutmarking(cur_console);
if (history_up_line(cur_console))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ if (!(flags & SCGETC_CN))
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
goto next_code;
-#ifdef PC98
- case 0x3D: /* down arrow key */
-#else
- case 0x50: /* down arrow key */
-#endif
+ case SPCLKEY | FKEY | F(58): /* down arrow key */
+ remove_cutmarking(cur_console);
if (history_down_line(cur_console))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ if (!(flags & SCGETC_CN))
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
goto next_code;
-#ifdef PC98
- case 0x36: /* roll up key */
-#else
- case 0x49: /* page up key */
-#endif
+ 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)) {
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ if (!(flags & SCGETC_CN))
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
break;
}
goto next_code;
-#ifdef PC98
- case 0x37: /* roll down key */
-#else
- case 0x51: /* page down key */
-#endif
+ 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)) {
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ if (!(flags & SCGETC_CN))
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
break;
}
goto next_code;
}
}
- if (compose) {
- switch (scancode) {
- /* key pressed process it */
- case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */
- chr = (scancode - 0x40) + chr*10;
- goto next_code;
- case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */
- chr = (scancode - 0x47) + chr*10;
- goto next_code;
- case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */
- chr = (scancode - 0x4E) + chr*10;
- goto next_code;
- case 0x52: /* keypad 0 */
- chr *= 10;
- goto next_code;
-
- /* key release, no interest here */
- case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */
- case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */
- case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */
- case 0xD2: /* keypad 0 */
- goto next_code;
-
- case 0x38: /* left alt key */
- break;
- default:
- if (chr) {
- compose = chr = 0;
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
- goto next_code;
- }
- break;
- }
- }
-
- state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0));
- if ((!agrs && (cur_console->status & ALKED))
- || (agrs && !(cur_console->status & ALKED)))
- keycode += ALTGR_OFFSET;
- key = &key_map.key[keycode];
- if ( ((key->flgs & FLAG_LOCK_C) && (cur_console->status & CLKED))
- || ((key->flgs & FLAG_LOCK_N) && (cur_console->status & NLKED)) )
- state ^= 1;
-
- /* Check for make/break */
- action = key->map[state];
- if (scancode & 0x80) { /* key released */
- if (key->spcl & (0x80>>state)) {
- switch (action) {
- case LSH:
- shfts &= ~1;
- break;
- case RSH:
- shfts &= ~2;
- break;
- case LCTR:
- ctls &= ~1;
- break;
- case RCTR:
- ctls &= ~2;
- break;
- case LALT:
- alts &= ~1;
- break;
- case RALT:
- alts &= ~2;
- break;
- case NLK:
- nlkcnt = 0;
- break;
- case CLK:
-#ifdef PC98
- cur_console->status &= ~CLKED;
- update_leds(cur_console->status);
-#else
- clkcnt = 0;
-#endif
- break;
- case SLK:
- slkcnt = 0;
- break;
- case ASH:
- agrs = 0;
- break;
- case ALK:
- alkcnt = 0;
- break;
- case META:
- metas = 0;
- break;
- }
- }
- if (chr && !compose) {
- action = chr;
- chr = 0;
- return(action);
- }
+ /*
+ * Process and consume special keys here. Return a plain char code
+ * or a char code with the META flag or a function key code.
+ */
+ if (c & RELKEY) {
+ /* key released */
+ /* goto next_code */
} else {
/* key pressed */
- if (key->spcl & (0x80>>state)) {
- switch (action) {
+ if (c & SPCLKEY) {
+ c &= ~SPCLKEY;
+ switch (KEYCHAR(c)) {
/* LOCKING KEYS */
- case NLK:
- if (!nlkcnt) {
- nlkcnt++;
- if (cur_console->status & NLKED)
- cur_console->status &= ~NLKED;
- else
- cur_console->status |= NLKED;
- update_leds(cur_console->status);
- }
- break;
- case CLK:
-#ifdef PC98
- cur_console->status |= CLKED;
- update_leds(cur_console->status);
-#else
- if (!clkcnt) {
- clkcnt++;
- if (cur_console->status & CLKED)
- cur_console->status &= ~CLKED;
- else
- cur_console->status |= CLKED;
- update_leds(cur_console->status);
- }
-#endif
+ case NLK: case CLK: case ALK:
break;
case SLK:
- if (!slkcnt) {
- slkcnt++;
+ kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&f);
+ if (f & SLKED) {
+ cur_console->status |= SLKED;
+ } else {
if (cur_console->status & SLKED) {
cur_console->status &= ~SLKED;
- if (cur_console->status & BUFFER_SAVED){
+ if (cur_console->status & BUFFER_SAVED) {
int i;
u_short *ptr = cur_console->history_save;
#ifdef PC98
@@ -4612,11 +4285,12 @@ next_code:
cur_console->history +
cur_console->history_size)
#ifdef PC98
- {
-#endif
+ {
+ ptr = cur_console->history;
+ ptr_a = cur_console->his_atr;
+ }
+#else
ptr = cur_console->history;
-#ifdef PC98
- ptr_a = cur_console->his_atr; }
#endif
}
cur_console->status &= ~BUFFER_SAVED;
@@ -4629,73 +4303,64 @@ next_code:
}
scstart(VIRTUAL_TTY(get_scr_num()));
}
- else
- cur_console->status |= SLKED;
- update_leds(cur_console->status);
- }
- break;
- case ALK:
- if (!alkcnt) {
- alkcnt++;
- if (cur_console->status & ALKED)
- cur_console->status &= ~ALKED;
- else
- cur_console->status |= ALKED;
- update_leds(cur_console->status);
}
break;
/* NON-LOCKING KEYS */
case NOP:
+ case LSH: case RSH: case LCTR: case RCTR:
+ case LALT: case RALT: case ASH: case META:
break;
+
+ case BTAB:
+ return c;
+
case SPSC:
/* force activatation/deactivation of the screen saver */
- accents = 0;
- if (scrn_blanked <= 0) {
+ if (!scrn_blanked) {
run_scrn_saver = TRUE;
scrn_time_stamp -= scrn_blank_time;
}
-#ifdef SC_SPLASH_SCREEN
+#if NSPLASH > 0
if (cold) {
/*
* While devices are being probed, the screen saver need
* to be invoked explictly. XXX
*/
- if (scrn_blanked > 0) {
+ if (scrn_blanked) {
scsplash_stick(FALSE);
stop_scrn_saver(current_saver);
} else {
if (!ISGRAPHSC(cur_console)) {
scsplash_stick(TRUE);
- scrn_saver(current_saver, TRUE);
+ (*current_saver)(TRUE);
}
}
}
-#endif
+#endif /* NSPLASH */
break;
+
case RBT:
#ifndef SC_DISABLE_REBOOT
- accents = 0;
shutdown_nice();
#endif
break;
- case SUSP:
+
#if NAPM > 0
- accents = 0;
+ case SUSP:
apm_suspend(PMST_SUSPEND);
-#endif
break;
-
case STBY:
-#if NAPM > 0
- accents = 0;
apm_suspend(PMST_STANDBY);
-#endif
break;
+#else
+ case SUSP:
+ case STBY:
+ break;
+#endif
case DBG:
#ifdef DDB /* try to switch to console 0 */
- accents = 0;
/*
* TRY to make sure the screen saver is stopped,
* and the screen is updated before switching to
@@ -4710,135 +4375,47 @@ next_code:
printf("No debugger in kernel\n");
#endif
break;
- case LSH:
- shfts |= 1;
- break;
- case RSH:
- shfts |= 2;
- break;
- case LCTR:
- ctls |= 1;
- break;
- case RCTR:
- ctls |= 2;
- break;
- case LALT:
- alts |= 1;
- break;
- case RALT:
- alts |= 2;
- break;
- case ASH:
- agrs = 1;
- break;
- case META:
- metas = 1;
- break;
+
case NEXT:
- {
- int next, this = get_scr_num();
- accents = 0;
- for (next = this+1; next != this; next = (next+1)%MAXCONS) {
- struct tty *tp = VIRTUAL_TTY(next);
+ this_scr = get_scr_num();
+ for (i = this_scr + 1; i != this_scr; i = (i + 1)%MAXCONS) {
+ struct tty *tp = VIRTUAL_TTY(i);
if (tp->t_state & TS_ISOPEN) {
- switch_scr(cur_console, next);
+ switch_scr(cur_console, i);
break;
}
}
- }
break;
- case BTAB:
- accents = 0;
- return(BKEY);
+
default:
- if (action >= F_ACC && action <= L_ACC) {
- /* turn it into an index */
- action -= F_ACC - 1;
- if ((action > accent_map.n_accs)
- || (accent_map.acc[action - 1].accchar == 0)) {
- /*
- * The index is out of range or pointing to an
- * empty entry.
- */
- accents = 0;
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
- }
- /*
- * If the same accent key has been hit twice,
- * produce the accent char itself.
- */
- if (action == accents) {
- action = accent_map.acc[accents - 1].accchar;
- accents = 0;
- if (metas)
- action |= MKEY;
- return (action);
- }
- /* remember the index and wait for the next key stroke */
- accents = action;
- break;
- }
- if (accents > 0) {
- accents = 0;
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
- }
- if (action >= F_SCR && action <= L_SCR) {
- switch_scr(cur_console, action - F_SCR);
+ if (KEYCHAR(c) >= F_SCR && KEYCHAR(c) <= L_SCR) {
+ switch_scr(cur_console, KEYCHAR(c) - F_SCR);
break;
}
- if (action >= F_FN && action <= L_FN)
- action |= FKEY;
- return(action);
+ /* assert(c & FKEY) */
+ return c;
}
- }
- else {
- if (accents) {
- struct acc_t *acc;
- int i;
-
- acc = &accent_map.acc[accents - 1];
- accents = 0;
- /*
- * If the accent key is followed by the space key,
- * produce the accent char itself.
- */
- if (action == ' ') {
- action = acc->accchar;
- if (metas)
- action |= MKEY;
- return (action);
- }
- for (i = 0; i < NUM_ACCENTCHARS; ++i) {
- if (acc->map[i][0] == 0) /* end of the map entry */
- break;
- if (acc->map[i][0] == action) {
- action = acc->map[i][1];
- if (metas)
- action |= MKEY;
- return (action);
- }
- }
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
- goto next_code;
- }
- if (metas)
- action |= MKEY;
- return(action);
+ /* goto next_code */
+ } else {
+ /* regular keys (maybe MKEY is set) */
+ return c;
}
}
+
goto next_code;
}
int
scmmap(dev_t dev, vm_offset_t offset, int nprot)
{
-#ifdef PC98
- if (offset > 0x48000 - PAGE_SIZE)
-#else
- if (offset > 0x20000 - PAGE_SIZE)
-#endif
- return -1;
- return i386_btop((VIDEOMEM + offset));
+ struct tty *tp;
+ struct scr_stat *scp;
+
+ tp = scdevtotty(dev);
+ if (!tp)
+ return ENXIO;
+ scp = sc_get_scr_stat(tp->t_dev);
+ return (*vidsw[scp->ad]->mmap)(scp->adp, offset);
}
/*
@@ -4870,87 +4447,64 @@ mask2attr(struct term_stat *term)
return attr;
}
-#ifndef PC98
-static void
-set_keyboard(int command, int data)
+static int
+save_kbd_state(scr_stat *scp)
{
- int s;
-
- if (sc_kbdc == NULL)
- return;
-
- /* prevent the timeout routine from polling the keyboard */
- if (!kbdc_lock(sc_kbdc, TRUE))
- return;
+ int state;
+ int error;
- /* disable the keyboard and mouse interrupt */
- s = spltty();
-#if 0
- c = get_controller_command_byte(sc_kbdc);
- if ((c == -1)
- || !set_controller_command_byte(sc_kbdc,
- kbdc_get_device_mask(sc_kbdc),
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
- /* CONTROLLER ERROR */
- kbdc_lock(sc_kbdc, FALSE);
- splx(s);
- return;
+ error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ if (error == 0) {
+ scp->status &= ~LOCK_MASK;
+ scp->status |= state;
}
- /*
- * Now that the keyboard controller is told not to generate
- * the keyboard and mouse interrupts, call `splx()' to allow
- * the other tty interrupts. The clock interrupt may also occur,
- * but the timeout routine (`scrn_timer()') will be blocked
- * by the lock flag set via `kbdc_lock()'
- */
- splx(s);
-#endif
+ return error;
+}
- if (send_kbd_command_and_data(sc_kbdc, command, data) != KBD_ACK)
- send_kbd_command(sc_kbdc, KBDC_ENABLE_KBD);
+static int
+update_kbd_state(int new_bits, int mask)
+{
+ int state;
+ int error;
-#if 0
- /* restore the interrupts */
- if (!set_controller_command_byte(sc_kbdc,
- kbdc_get_device_mask(sc_kbdc),
- c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
- /* CONTROLLER ERROR */
+ if (mask != LOCK_MASK) {
+ error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ if (error)
+ return error;
+ state &= ~mask;
+ state |= new_bits & mask;
+ } else {
+ state = new_bits & LOCK_MASK;
}
-#else
- splx(s);
-#endif
- kbdc_lock(sc_kbdc, FALSE);
+ error = kbd_ioctl(kbd, KDSKBSTATE, (caddr_t)&state);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ return error;
}
-#endif
-static void
-update_leds(int which)
+static int
+update_kbd_leds(int which)
{
-#ifndef PC98
- static u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-
- /* replace CAPS led with ALTGR led for ALTGR keyboards */
- if (key_map.n_keys > ALTGR_OFFSET) {
- if (which & ALKED)
- which |= CLKED;
- else
- which &= ~CLKED;
- }
+ int error;
- set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]);
-#endif
+ which &= LOCK_MASK;
+ error = kbd_ioctl(kbd, KDSETLED, (caddr_t)&which);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ return error;
}
int
set_mode(scr_stat *scp)
{
-#ifndef PC98
video_info_t info;
- video_adapter_t *adp;
/* reject unsupported mode */
- if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
+ if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info))
return 1;
/* if this vty is not currently showing, do nothing */
@@ -4958,14 +4512,24 @@ set_mode(scr_stat *scp)
return 0;
/* setup video hardware for the given mode */
- adp = get_adapter(scp);
- (*biosvidsw.set_mode)(scp->adp, scp->mode);
- Crtat = (u_short *)adp->va_window;
+ (*vidsw[scp->ad]->set_mode)(scp->adp, scp->mode);
+ Crtat = (u_short *)scp->adp->va_window;
+
+#ifdef PC98
+ if (scp->status & UNKNOWN_MODE) {
+ while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
+ outb(0x62, 0xc); /* text off */
+ outb(0xA2, 0xd); /* graphics on */
+ } else {
+ while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
+ outb(0x62, 0xd); /* text off */
+ outb(0xA2, 0xc); /* graphics on */
+ }
+#endif
if (!(scp->status & GRAPHICS_MODE)) {
/* load appropriate font */
- if (!(scp->status & PIXEL_MODE)
- && ISFONTAVAIL(get_adapter(scp)->va_flags)) {
+ if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->adp->va_flags)) {
if (scp->font_size < 14) {
if (fonts_loaded & FONT_8)
copy_font(scp, LOAD, 8, font_8);
@@ -4977,57 +4541,28 @@ set_mode(scr_stat *scp)
copy_font(scp, LOAD, 14, font_14);
}
/*
- * FONT KLUDGE:
- * This is an interim kludge to display correct font.
- * Always use the font page #0 on the video plane 2.
- * Somehow we cannot show the font in other font pages on
- * some video cards... XXX
- */
- (*biosvidsw.show_font)(scp->adp, 0);
+ * FONT KLUDGE:
+ * This is an interim kludge to display correct font.
+ * Always use the font page #0 on the video plane 2.
+ * Somehow we cannot show the font in other font pages on
+ * some video cards... XXX
+ */
+ (*vidsw[scp->ad]->show_font)(scp->adp, 0);
}
mark_all(scp);
}
if (scp->status & PIXEL_MODE)
- generic_bzero((u_char *)(adp->va_window), scp->xpixel*scp->ypixel/8);
+ generic_bzero((u_char *)(scp->adp->va_window),
+ scp->xpixel*scp->ypixel/8);
set_border(scp, scp->border);
+#ifndef PC98
/* move hardware cursor out of the way */
- (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
-
- return 0;
-#else /* PC98 */
-
- if (scp != cur_console)
- return 1;
-
- /* setup video hardware for the given mode */
-#ifdef LINE30
- switch (scp->mode) {
- case M_PC98_80x25: /* VGA TEXT MODES */
- initialize_gdc(T25_G400);
- break;
- case M_PC98_80x30:
- initialize_gdc(T30_G400);
- break;
- default:
- break;
- }
+ (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1);
#endif
- if (scp->status & UNKNOWN_MODE) {
- while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
- outb(0x62, 0xc); /* text off */
- outb(0xA2, 0xd); /* graphics on */
- } else {
- while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
- outb(0x62, 0xd); /* text off */
- outb(0xA2, 0xc); /* graphics on */
- }
- /* set border color for this (virtual) console */
- set_border(scp, scp->border);
return 0;
-#endif /* PC98 */
}
void
@@ -5041,7 +4576,7 @@ set_border(scr_stat *scp, int color)
int ylen;
int i;
- (*biosvidsw.set_border)(scp->adp, color);
+ (*vidsw[scp->ad]->set_border)(scp->adp, color);
if (scp->status & PIXEL_MODE) {
outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
@@ -5049,7 +4584,7 @@ set_border(scr_stat *scp, int color)
outw(GDCIDX, 0x0f01); /* set/reset enable */
outw(GDCIDX, 0xff08); /* bit mask */
outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
- p = (u_char *)(get_adapter(scp)->va_window);
+ p = (u_char *)(scp->adp->va_window);
xoff = scp->xoff;
yoff = scp->yoff*scp->font_size;
xlen = scp->xpixel/8;
@@ -5070,20 +4605,13 @@ set_border(scr_stat *scp, int color)
outw(GDCIDX, 0x0001); /* set/reset enable */
}
#else /* PC98 */
- switch (crtc_type) {
- case KD_PC98:
- outb(0x6c, color << 4);
- break;
- default:
- break;
- }
+ (*vidsw[scp->ad]->set_border)(scp->adp, color);
#endif /* PC98 */
}
void
copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
{
-#ifndef PC98
/*
* FONT KLUDGE:
* This is an interim kludge to display correct font.
@@ -5093,14 +4621,13 @@ copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
*/
font_loading_in_progress = TRUE;
if (operation == LOAD) {
- (*biosvidsw.load_font)(scp->adp, 0, font_size, buf, 0, 256);
+ (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, buf, 0, 256);
if (sc_flags & CHAR_CURSOR)
set_destructive_cursor(scp);
} else if (operation == SAVE) {
- (*biosvidsw.save_font)(scp->adp, 0, font_size, buf, 0, 256);
+ (*vidsw[scp->ad]->save_font)(scp->adp, 0, font_size, buf, 0, 256);
}
font_loading_in_progress = FALSE;
-#endif
}
static void
@@ -5110,9 +4637,10 @@ set_destructive_cursor(scr_stat *scp)
u_char cursor[32];
u_char *font_buffer;
int font_size;
+ int crtc_addr;
int i;
- if (!ISFONTAVAIL(get_adapter(scp)->va_flags)
+ if (!ISFONTAVAIL(scp->adp->va_flags)
|| (scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
return;
@@ -5148,10 +4676,11 @@ set_destructive_cursor(scr_stat *scp)
(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;
- (*biosvidsw.load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1);
+ (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1);
font_loading_in_progress = FALSE;
#endif
}
@@ -5409,10 +4938,11 @@ draw_mouse_image(scr_stat *scp)
#else
u_short buffer[32];
u_short xoffset, yoffset;
- u_short *crt_pos = (u_short *)(get_adapter(scp)->va_window)
+ 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) {
@@ -5461,10 +4991,11 @@ draw_mouse_image(scr_stat *scp)
#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;
- (*biosvidsw.load_font)(scp->adp, 0, 32, scp->mouse_cursor,
+ (*vidsw[scp->ad]->load_font)(scp->adp, 0, 32, scp->mouse_cursor,
SC_MOUSE_CHAR, 4);
font_loading_in_progress = FALSE;
@@ -5494,7 +5025,7 @@ remove_mouse_image(scr_stat *scp)
#ifdef PC98
crt_pos = Atrat + (scp->mouse_oldpos - scp->scr_buf);
#else
- crt_pos = (u_short *)(get_adapter(scp)->va_window)
+ crt_pos = (u_short *)(scp->adp->va_window)
+ (scp->mouse_oldpos - scp->scr_buf);
#endif
@@ -5522,7 +5053,7 @@ draw_cutmarking(scr_stat *scp)
#ifdef PC98
crt_pos = Atrat;
#else
- crt_pos = (u_short *)(get_adapter(scp)->va_window);
+ 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));
@@ -5609,23 +5140,25 @@ blink_screen(void *arg)
#ifdef PC98
if (blink_in_progress & 1){
fillw(scr_map[0x20],
- Crtat, scp->xsize * scp->ysize);
+ (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],
- Crtat, scp->xsize * scp->ysize);
+ (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 *)(get_adapter(scp)->va_window),
+ (u_short *)(scp->adp->va_window),
scp->xsize * scp->ysize);
else
fillw(kernel_default.rev_color | scr_map[0x20],
- (u_short *)(get_adapter(scp)->va_window),
+ (u_short *)(scp->adp->va_window),
scp->xsize * scp->ysize);
#endif
blink_in_progress--;
@@ -5637,28 +5170,9 @@ void
sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
{
#ifdef PC98
- if (ISTEXTSC(scp)) {
- generic_bcopy(p + from, Crtat + from,
+ if (ISTEXTSC(scp))
+ generic_bcopy(p + from, (u_short *)(scp->adp->va_window) + from,
(to - from + 1)*sizeof(u_short));
- } else if (scp->mode == 0x102) {
- u_char *d, *e;
- int i,j;
-
- if (mark)
- mark = 255;
- d = (u_char *)Crtat;
- d += 10 + 6*16*100 + (from%80) + 16*100*(from/80);
- for (i = from ; i <= to ; i++) {
- e = d;
- for (j = 0 ; j < 16; j++) {
- *e = mark^font_16[(p[i]&0xff)*16+j];
- e+=100;
- }
- d++;
- if ((i % 80) == 79)
- d += 20 + 15*100;
- }
- }
#else /* PC98 */
u_char *font;
u_char volatile *d;
@@ -5672,7 +5186,7 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
u_char c;
if (ISTEXTSC(scp)) {
- generic_bcopy(p + from, (u_short *)(get_adapter(scp)->va_window) + from,
+ generic_bcopy(p + from, (u_short *)(scp->adp->va_window) + from,
(to - from + 1)*sizeof(u_short));
} else /* if ISPIXELSC(scp) */ {
if (mark)
@@ -5686,7 +5200,7 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
font = font_14;
line_length = scp->xpixel/8;
xsize = scp->xsize;
- d = (u_char *)(get_adapter(scp)->va_window)
+ d = (u_char *)(scp->adp->va_window)
+ scp->xoff + scp->yoff*font_size*line_length
+ (from%xsize) + font_size*line_length*(from/xsize);
@@ -5756,203 +5270,4 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
#endif /* PC98 */
}
-#ifdef SC_SPLASH_SCREEN
-
-static void
-scsplash_init(scr_stat *scp)
-{
- video_info_t info;
-
- if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) {
- default_saver = scsplash_saver;
- scrn_blank_time = DEFAULT_BLANKTIME;
- run_scrn_saver = TRUE;
- if (!(boothowto & (RB_VERBOSE | RB_CONFIG))) {
- scsplash_stick(TRUE);
- scsplash_saver(TRUE);
- }
- }
-}
-
-static void
-scsplash_term(scr_stat *scp)
-{
- default_saver = none_saver;
- scsplash_stick(FALSE);
- remove_scrn_saver(scsplash_saver);
- scsplash_unload(scp);
-}
-
-static void
-scsplash_saver(int show)
-{
- if (show)
- scsplash(TRUE);
- else if (!sticky_splash)
- scsplash(FALSE);
-}
-
-#endif /* SC_SPLASH_SCREEN */
-
-#if defined(PC98) && defined(LINE30) /* 30line */
-
-static void master_gdc_cmd(unsigned int cmd)
-{
- while ( (inb(0x60) & 2) != 0);
- outb(0x62, cmd);
-}
-
-static void master_gdc_prm(unsigned int pmtr)
-{
- while ( (inb(0x60) & 2) != 0);
- outb(0x60, pmtr);
-}
-
-static void master_gdc_word_prm(unsigned int wpmtr)
-{
- master_gdc_prm(wpmtr & 0x00ff);
- master_gdc_prm((wpmtr >> 8) & 0x00ff);
-}
-
-static void master_gdc_fifo_empty(void)
-{
- while ( (inb(0x60) & 4) == 0);
-}
-
-static void master_gdc_wait_vsync(void)
-{
- while ( (inb(0x60) & 0x20) != 0);
- while ( (inb(0x60) & 0x20) == 0);
-}
-
-static void gdc_cmd(unsigned int cmd)
-{
- while ( (inb(0xa0) & 2) != 0);
- outb( 0xa2, cmd);
-}
-
-static void gdc_prm(unsigned int pmtr)
-{
- while ( (inb(0xa0) & 2) != 0);
- outb( 0xa0, pmtr);
-}
-
-static void gdc_word_prm(unsigned int wpmtr)
-{
- gdc_prm(wpmtr & 0x00ff);
- gdc_prm((wpmtr >> 8) & 0x00ff);
-}
-
-static void gdc_fifo_empty(void)
-{
- while ( (inb(0xa0) & 0x04) == 0);
-}
-
-static void gdc_wait_vsync(void)
-{
- while ( (inb(0xa0) & 0x20) != 0);
- while ( (inb(0xa0) & 0x20) == 0);
-}
-
-static int check_gdc_clock(void)
-{
- if ((inb(0x31) & 0x80) == 0){
- return _5MHZ;
- } else {
- return _2_5MHZ;
- }
-}
-
-static void initialize_gdc(unsigned int mode)
-{
- /* start 30line initialize */
- int m_mode,s_mode,gdc_clock;
- gdc_clock = check_gdc_clock();
-
- if (mode == T25_G400){
- m_mode = _25L;
- }else{
- m_mode = _30L;
- }
-
- s_mode = 2*mode+gdc_clock;
-
- gdc_INFO = m_mode;
-
- master_gdc_cmd(_GDC_RESET);
- master_gdc_cmd(_GDC_MASTER);
- gdc_cmd(_GDC_RESET);
- gdc_cmd(_GDC_SLAVE);
-
- /* GDC Master */
- master_gdc_cmd(_GDC_SYNC);
- master_gdc_prm(0x00); /* flush less */ /* text & graph */
- master_gdc_prm(master_param[m_mode][GDC_CR]);
- master_gdc_word_prm(((master_param[m_mode][GDC_HFP] << 10)
- + (master_param[m_mode][GDC_VS] << 5)
- + master_param[m_mode][GDC_HS]));
- master_gdc_prm(master_param[m_mode][GDC_HBP]);
- master_gdc_prm(master_param[m_mode][GDC_VFP]);
- master_gdc_word_prm(((master_param[m_mode][GDC_VBP] << 10)
- + (master_param[m_mode][GDC_LF])));
- master_gdc_fifo_empty();
- master_gdc_cmd(_GDC_PITCH);
- master_gdc_prm(MasterPCH);
- master_gdc_fifo_empty();
-
- /* GDC slave */
- gdc_cmd(_GDC_SYNC);
- gdc_prm(0x06);
- gdc_prm(slave_param[s_mode][GDC_CR]);
- gdc_word_prm((slave_param[s_mode][GDC_HFP] << 10)
- + (slave_param[s_mode][GDC_VS] << 5)
- + (slave_param[s_mode][GDC_HS]));
- gdc_prm(slave_param[s_mode][GDC_HBP]);
- gdc_prm(slave_param[s_mode][GDC_VFP]);
- gdc_word_prm((slave_param[s_mode][GDC_VBP] << 10)
- + (slave_param[s_mode][GDC_LF]));
- gdc_fifo_empty();
- gdc_cmd(_GDC_PITCH);
- gdc_prm(SlavePCH[gdc_clock]);
- gdc_fifo_empty();
-
- /* set Master GDC scroll param */
- master_gdc_wait_vsync();
- master_gdc_wait_vsync();
- master_gdc_wait_vsync();
- master_gdc_cmd(_GDC_SCROLL);
- master_gdc_word_prm(0);
- master_gdc_word_prm((master_param[m_mode][GDC_LF] << 4) | 0x0000);
- master_gdc_fifo_empty();
-
- /* set Slave GDC scroll param */
- gdc_wait_vsync();
- gdc_cmd(_GDC_SCROLL);
- gdc_word_prm(0);
- if (gdc_clock == _5MHZ){
- gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
- }else{
- gdc_word_prm(SlaveScrlLF[mode] << 4);
- }
- gdc_fifo_empty();
-
- gdc_word_prm(0);
- if (gdc_clock == _5MHZ){
- gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
- }else{
- gdc_word_prm(SlaveScrlLF[mode] << 4);
- }
- gdc_fifo_empty();
-
- /* sync start */
- gdc_cmd(_GDC_STOP);
-
- gdc_wait_vsync();
- gdc_wait_vsync();
- gdc_wait_vsync();
-
- master_gdc_cmd(_GDC_START);
-}
-#endif /* 30 line */
-
#endif /* NSC */
diff --git a/sys/pc98/pc98/syscons.h b/sys/pc98/pc98/syscons.h
index 7370c8b260e8..a265d15277ae 100644
--- a/sys/pc98/pc98/syscons.h
+++ b/sys/pc98/pc98/syscons.h
@@ -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: syscons.h,v 1.26 1998/12/16 14:57:38 kato Exp $
+ * $Id: syscons.h,v 1.27 1999/01/17 15:42:27 kato Exp $
*/
#ifndef _PC98_PC98_SYSCONS_H_
@@ -57,10 +57,7 @@
}
/* status flags */
-#define LOCK_KEY_MASK 0x0000F
#define UNKNOWN_MODE 0x00010
-#define KBD_RAW_MODE 0x00020
-#define KBD_CODE_MODE 0x00040
#define SWITCH_WAIT_REL 0x00080
#define SWITCH_WAIT_ACQ 0x00100
#define BUFFER_SAVED 0x00200
@@ -77,9 +74,12 @@
#define VISUAL_BELL 0x00001
#define BLINK_CURSOR 0x00002
#define CHAR_CURSOR 0x00004
+/* these options are now obsolete; use corresponding options for kbd driver */
+#if 0
#define DETECT_KBD 0x00008
#define XT_KEYBD 0x00010
#define KBD_NORESET 0x00020
+#endif
#define QUIET_BELL 0x00040
#define VESA800X600 0x00080
@@ -146,7 +146,8 @@ typedef struct term_stat {
} term_stat;
typedef struct scr_stat {
- int adp; /* video adapter index */
+ int ad; /* video adapter index */
+ video_adapter_t *adp; /* video adapter structure */
u_short *scr_buf; /* buffer when off screen */
#ifdef PC98
u_short *atr_buf; /* buffer when off screen */
@@ -167,6 +168,7 @@ typedef struct scr_stat {
int end; /* modified area end */
term_stat term; /* terminal emulation stuff */
int status; /* status (bitfield) */
+ int kbd_mode; /* keyboard I/O mode */
u_short *cursor_pos; /* cursor buffer position */
u_short *cursor_oldpos; /* cursor old buffer position */
#ifndef PC98
@@ -190,7 +192,6 @@ typedef struct scr_stat {
u_short bell_duration;
u_short bell_pitch;
u_char border; /* border color */
- int initial_mode; /* initial mode */
int mode; /* mode */
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
@@ -207,10 +208,8 @@ typedef struct scr_stat {
#endif
int history_size; /* size of history buffer */
struct apmhook r_hook; /* reconfiguration support */
-#ifdef SC_SPLASH_SCREEN
int splash_save_mode; /* saved mode for splash screen */
int splash_save_status; /* saved status for splash screen */
-#endif
#ifdef KANJI
u_char kanji_1st_char;
#define KTYPE_ASCII 0
@@ -266,13 +265,12 @@ scr_stat *sc_get_scr_stat(dev_t dev);
void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image);
void set_border(scr_stat *scp, int color);
-#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal)
-#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal)
-#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp)
-
-int add_scrn_saver(void (*this)(int));
-int remove_scrn_saver(void (*this)(int));
+#define save_palette(adp, pal) \
+ (*vidsw[(adp)->va_index]->save_palette)((adp), (pal))
+#define load_palette(adp, pal) \
+ (*vidsw[(adp)->va_index]->load_palette)((adp), (pal))
+void sc_touch_scrn_saver(void);
void sc_clear_screen(scr_stat *scp);
void sc_move_mouse(scr_stat *scp, int x, int y);
int sc_clean_up(scr_stat *scp);
@@ -290,13 +288,6 @@ int sc_set_pixel_mode(scr_stat *scp, struct tty *tp,
int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
struct proc *p);
-#ifdef SC_SPLASH_SCREEN
-/* splash.c */
-void scsplash(int);
-int scsplash_load(scr_stat *scp);
-int scsplash_unload(scr_stat *scp);
-#endif
-
#ifdef PC98
unsigned int at2pc98(unsigned int attr);
#endif