summaryrefslogtreecommitdiffstats
path: root/sys/pc98/cbus
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1999-06-24 10:51:40 +0000
committerkato <kato@FreeBSD.org>1999-06-24 10:51:40 +0000
commit2e2fe43a357a07fe5a62764e2d21d93dd709f407 (patch)
tree4fd299a6d70722066b5c33820fff20f0284d4c11 /sys/pc98/cbus
parent4859384f0d8a6d9a04c7f3c535176758cd205454 (diff)
downloadFreeBSD-src-2e2fe43a357a07fe5a62764e2d21d93dd709f407.zip
FreeBSD-src-2e2fe43a357a07fe5a62764e2d21d93dd709f407.tar.gz
PC98 part of the second phase of syscons reorganization.
Submitted by: yokota
Diffstat (limited to 'sys/pc98/cbus')
-rw-r--r--sys/pc98/cbus/gdc.c319
-rw-r--r--sys/pc98/cbus/sc_machdep.h61
-rw-r--r--sys/pc98/cbus/scgdcrndr.c180
-rw-r--r--sys/pc98/cbus/scvtb.c364
-rw-r--r--sys/pc98/cbus/sio.c4
-rw-r--r--sys/pc98/cbus/syscons_cbus.c193
6 files changed, 1053 insertions, 68 deletions
diff --git a/sys/pc98/cbus/gdc.c b/sys/pc98/cbus/gdc.c
index a6efd2a..e98f35e 100644
--- a/sys/pc98/cbus/gdc.c
+++ b/sys/pc98/cbus/gdc.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pc98gdc.c,v 1.8 1999/05/09 04:56:42 kato Exp $
+ * $Id: pc98gdc.c,v 1.9 1999/05/30 16:53:20 phk Exp $
*/
#include "gdc.h"
@@ -72,7 +72,7 @@ typedef struct gdc_softc {
#define GDC_SOFTC(unit) \
((gdc_softc_t *)devclass_get_softc(gdc_devclass, unit))
-devclass_t gdc_devclass;
+static devclass_t gdc_devclass;
static int gdcprobe(device_t dev);
static int gdc_attach(device_t dev);
@@ -99,13 +99,15 @@ static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
static d_open_t gdcopen;
static d_close_t gdcclose;
static d_read_t gdcread;
+static d_write_t gdcwrite;
static d_ioctl_t gdcioctl;
+static d_mmap_t gdcmmap;
static struct cdevsw vga_cdevsw = {
/* open */ gdcopen,
/* close */ gdcclose,
- /* read */ noread,
- /* write */ nowrite,
+ /* read */ gdcread,
+ /* write */ gdcwrite,
/* ioctl */ gdcioctl,
/* stop */ nostop,
/* reset */ noreset,
@@ -139,9 +141,24 @@ static int
gdc_attach(device_t dev)
{
gdc_softc_t *sc;
+ int error;
sc = device_get_softc(dev);
- return gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
+ error = gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
+ if (error)
+ return error;
+
+#ifdef FB_INSTALL_CDEV
+ /* attach a virtual frame buffer device */
+ error = fb_attach(makedev(0, GDC_MKMINOR(unit)), sc->adp, &gdc_cdevsw);
+ if (error)
+ return error;
+#endif /* FB_INSTALL_CDEV */
+
+ if (bootverbose)
+ (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose);
+
+ return 0;
}
static int
@@ -152,7 +169,7 @@ gdc_probe_unit(int unit, gdc_softc_t *sc, int flags)
bzero(sc, sizeof(*sc));
sw = vid_get_switch(DRIVER_NAME);
if (sw == NULL)
- return 0;
+ return ENXIO;
return (*sw->probe)(unit, &sc->adp, NULL, flags);
}
@@ -160,30 +177,78 @@ static int
gdc_attach_unit(int unit, gdc_softc_t *sc, int flags)
{
video_switch_t *sw;
- int error;
sw = vid_get_switch(DRIVER_NAME);
if (sw == NULL)
return ENXIO;
+ return (*sw->init)(unit, sc->adp, flags);
+}
- error = (*sw->init)(unit, sc->adp, flags);
- if (error)
- return ENXIO;
+/* cdev driver functions */
#ifdef FB_INSTALL_CDEV
- /* attach a virtual frame buffer device */
- error = fb_attach(makedev(0, GDC_MKMINOR(unit)), scp->adp,
- &vga_cdevsw);
- if (error)
- return error;
-#endif /* FB_INSTALL_CDEV */
- if (bootverbose)
- (*sw->diag)(sc->adp, bootverbose);
+static int
+gdcopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ gdc_softc_t *sc;
- return 0;
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+ if (mode & (O_CREAT | O_APPEND | O_TRUNC))
+ return ENODEV;
+
+ return genfbopen(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+static int
+gdcclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbclose(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+static int
+gdcread(dev_t dev, struct uio *uio, int flag)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+static int
+gdcwrite(dev_t dev, struct uio *uio, int flag)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+static int
+gdcioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, p);
}
+static int
+gdcmmap(dev_t dev, vm_offset_t offset, int prot)
+{
+ gdc_softc_t *sc;
+
+ sc = GDC_SOFTC(GDC_UNIT(dev));
+ return genfbmmap(&sc->gensc, sc->adp, offset, prot);
+}
+
+#endif /* FB_INSTALL_CDEV */
+
/* LOW-LEVEL */
#include <machine/clock.h>
@@ -213,7 +278,7 @@ static video_adapter_t adapter_init_value[] = {
V_ADP_COLOR | V_ADP_MODECHANGE | V_ADP_BORDER,
IO_GDC1, 16, TEXT_GDC, /* va_io*, XXX */
VIDEO_BUF_BASE, VIDEO_BUF_SIZE, /* va_mem* */
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, /* va_window* */
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, /* va_window* */
0, 0, /* va_buffer, va_buffer_size */
0, M_PC98_80x25, 0, /* va_*mode* */
},
@@ -224,6 +289,7 @@ static video_adapter_t biosadapter[1];
/* video driver declarations */
static int gdc_configure(int flags);
static int gdc_nop(void);
+static int gdc_err(video_adapter_t *adp, ...);
static vi_probe_t gdc_probe;
static vi_init_t gdc_init;
static vi_get_info_t gdc_get_info;
@@ -235,11 +301,11 @@ static vi_load_state_t gdc_load_state;
static vi_read_hw_cursor_t gdc_read_hw_cursor;
static vi_set_hw_cursor_t gdc_set_hw_cursor;
static vi_set_hw_cursor_shape_t gdc_set_hw_cursor_shape;
-static vi_mmap_t gdc_mmap;
+static vi_blank_display_t gdc_blank_display;
+static vi_mmap_t gdc_mmap_buf;
+static vi_ioctl_t gdc_dev_ioctl;
static vi_diag_t gdc_diag;
-static int gdc_err(video_adapter_t *adp, ...);
-
static video_switch_t gdcvidsw = {
gdc_probe,
gdc_init,
@@ -258,8 +324,14 @@ static video_switch_t gdcvidsw = {
gdc_read_hw_cursor,
gdc_set_hw_cursor,
gdc_set_hw_cursor_shape,
- (vi_blank_display_t *)gdc_nop,
- gdc_mmap,
+ gdc_blank_display,
+ gdc_mmap_buf,
+ gdc_dev_ioctl,
+ (vi_clear_t *)gdc_err,
+ (vi_fill_rect_t *)gdc_err,
+ (vi_bitblt_t *)gdc_err,
+ (int (*)(void))gdc_err,
+ (int (*)(void))gdc_err,
gdc_diag,
};
@@ -271,15 +343,15 @@ VIDEO_DRIVER(gdc, gdcvidsw, gdc_configure);
static video_info_t bios_vmode[] = {
{ M_PC98_80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
#ifdef LINE30
{ M_PC98_80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
+ TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
#endif
{ EOT },
};
-static int init_done = FALSE;
+static int gdc_init_done = FALSE;
/* local functions */
static int map_gen_mode_num(int type, int color, int mode);
@@ -287,7 +359,7 @@ static int probe_adapters(void);
static void dump_buffer(u_char *buf, size_t len);
#define prologue(adp, flag, err) \
- if (!init_done || !((adp)->va_flags & (flag))) \
+ if (!gdc_init_done || !((adp)->va_flags & (flag))) \
return (err)
/* a backdoor for the console driver */
@@ -336,9 +408,9 @@ probe_adapters(void)
video_info_t info;
/* do this test only once */
- if (init_done)
+ if (gdc_init_done)
return 1;
- init_done = TRUE;
+ gdc_init_done = TRUE;
biosadapter[0] = adapter_init_value[0];
biosadapter[0].va_flags |= V_ADP_PROBED;
@@ -547,6 +619,12 @@ gdc_nop(void)
}
static int
+gdc_err(video_adapter_t *adp, ...)
+{
+ return ENODEV;
+}
+
+static int
gdc_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
{
probe_adapters();
@@ -587,8 +665,8 @@ gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
{
int i;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode);
for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
@@ -596,10 +674,11 @@ gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
continue;
if (mode == bios_vmode[i].vi_mode) {
*info = bios_vmode[i];
+ info->vi_buffer_size = info->vi_window_size*info->vi_planes;
return 0;
}
}
- return 1;
+ return EINVAL;
}
/*
@@ -614,7 +693,7 @@ gdc_query_mode(video_adapter_t *adp, video_info_t *info)
video_info_t buf;
int i;
- if (!init_done)
+ if (!gdc_init_done)
return -1;
for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
@@ -661,16 +740,16 @@ gdc_set_mode(video_adapter_t *adp, int mode)
{
video_info_t info;
- prologue(adp, V_ADP_MODECHANGE, 1);
+ prologue(adp, V_ADP_MODECHANGE, ENODEV);
mode = map_gen_mode_num(adp->va_type,
adp->va_flags & V_ADP_COLOR, mode);
if (gdc_get_info(adp, mode, &info))
- return 1;
+ return EINVAL;
#ifdef LINE30
switch (info.vi_mode) {
- case M_PC98_80x25: /* VGA TEXT MODES */
+ case M_PC98_80x25: /* GDC TEXT MODES */
initialize_gdc(T25_G400);
break;
case M_PC98_80x30:
@@ -744,7 +823,7 @@ gdc_set_border(video_adapter_t *adp, int color)
static int
gdc_save_state(video_adapter_t *adp, void *p, size_t size)
{
- return 1;
+ return ENODEV;
}
/*
@@ -754,7 +833,7 @@ gdc_save_state(video_adapter_t *adp, void *p, size_t size)
static int
gdc_load_state(video_adapter_t *adp, void *p)
{
- return 1;
+ return ENODEV;
}
/*
@@ -767,11 +846,11 @@ gdc_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
u_int16_t off;
int s;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
+ return ENODEV;
s = spltty();
master_gdc_cmd(0xe0); /* _GDC_CSRR */
@@ -802,14 +881,30 @@ gdc_set_hw_cursor(video_adapter_t *adp, int col, int row)
u_int16_t off;
int s;
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
if ((col == -1) && (row == -1)) {
off = -1;
+ /* XXX */
+ if (epson_machine_id == 0x20) {
+ s = spltty();
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ splx(s);
+ }
} else {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
+ return ENODEV;
+ /* XXX */
+ if (epson_machine_id == 0x20) {
+ s = spltty();
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ splx(s);
+ }
off = row*adp->va_info.vi_width + col;
}
@@ -834,6 +929,9 @@ gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
int end;
int s;
+ if (!gdc_init_done)
+ return ENXIO;
+
start = celsize - (base + height);
end = celsize - base - 1;
/*
@@ -846,28 +944,76 @@ gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
--end;
s = spltty();
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ if (height > 0)
+ outb(0x0c17, inb(0xc17) | 0x08);
+ else
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
master_gdc_cmd(0x4b); /* _GDC_CSRFORM */
master_gdc_prm(((height > 0) ? 0x80 : 0) /* cursor on/off */
- | (celsize - 1) & 0x1f); /* cel size */
+ | ((celsize - 1) & 0x1f)); /* cel size */
master_gdc_word_prm(((end & 0x1f) << 11) /* end line */
| (12 << 6) /* blink rate */
| (blink ? 0x20 : 0) /* blink on/off */
| (start & 0x1f)); /* start line */
splx(s);
- return 1;
+ return 0;
}
-static void
-dump_buffer(u_char *buf, size_t len)
+/*
+ * blank_display()
+ * Put the display in power save/power off mode.
+ */
+static int
+gdc_blank_display(video_adapter_t *adp, int mode)
{
- int i;
+ int s;
- for(i = 0; i < len;) {
- printf("%02x ", buf[i]);
- if ((++i % 16) == 0)
- printf("\n");
+ if (!gdc_init_done)
+ return ENXIO;
+
+ s = splhigh();
+ switch (mode) {
+ case V_DISPLAY_SUSPEND:
+ case V_DISPLAY_STAND_BY:
+ /*
+ * FIXME: I don't know how to put the display into `suspend'
+ * or `stand-by' mode via GDC...
+ */
+ /* FALL THROUGH */
+
+ case V_DISPLAY_BLANK:
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ outb(0xc17, inb(0xc17) & ~0x08);
+ outb(0xc16, inb(0xc16) & ~0x02);
+ outb(0x43f, 0x40);
+ } else {
+ while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
+ ;
+ outb(TEXT_GDC + 2, 0xc); /* text off */
+ }
+ break;
+
+ case V_DISPLAY_ON:
+ if (epson_machine_id == 0x20) { /* XXX */
+ outb(0x43f, 0x42);
+ outb(0xc17, inb(0xc17) | 0x08);
+ outb(0xc16, inb(0xc16) | 0x02);
+ outb(0x43f, 0x40);
+ } else {
+ while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
+ ;
+ outb(TEXT_GDC + 2, 0xd); /* text on */
+ }
+ break;
}
+ splx(s);
+ return 0;
}
/*
@@ -875,11 +1021,58 @@ dump_buffer(u_char *buf, size_t len)
* Mmap frame buffer.
*/
static int
-gdc_mmap(video_adapter_t *adp, vm_offset_t offset)
+gdc_mmap_buf(video_adapter_t *adp, vm_offset_t offset, int prot)
{
- if (offset > 0x48000 - PAGE_SIZE)
+ /* FIXME: is this correct? XXX */
+ if (offset > VIDEO_BUF_SIZE - PAGE_SIZE)
return -1;
- return i386_btop((VIDEO_BUF_BASE + offset));
+ return i386_btop(adp->va_info.vi_window + offset);
+}
+
+static int
+gdc_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
+{
+ switch (cmd) {
+ case FBIO_GETWINORG: /* get frame buffer window origin */
+ *(u_int *)arg = 0;
+ return 0;
+
+ case FBIO_SETWINORG: /* set frame buffer window origin */
+ case FBIO_SETDISPSTART: /* set display start address */
+ case FBIO_SETLINEWIDTH: /* set scan line length in pixel */
+ case FBIO_GETPALETTE: /* get color palette */
+ case FBIO_SETPALETTE: /* set color palette */
+ case FBIOGETCMAP: /* get color palette */
+ case FBIOPUTCMAP: /* set color palette */
+ return ENODEV;
+
+ case FBIOGTYPE: /* get frame buffer type info. */
+ ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type);
+ ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height;
+ ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width;
+ ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth;
+ if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8))
+ ((struct fbtype *)arg)->fb_cmsize = 0;
+ else
+ ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth;
+ ((struct fbtype *)arg)->fb_size = adp->va_buffer_size;
+ return 0;
+
+ default:
+ return fb_commonioctl(adp, cmd, arg);
+ }
+}
+
+static void
+dump_buffer(u_char *buf, size_t len)
+{
+ int i;
+
+ for(i = 0; i < len;) {
+ printf("%02x ", buf[i]);
+ if ((++i % 16) == 0)
+ printf("\n");
+ }
}
/*
@@ -894,8 +1087,8 @@ gdc_diag(video_adapter_t *adp, int level)
int i;
#endif
- if (!init_done)
- return 1;
+ if (!gdc_init_done)
+ return ENXIO;
fb_dump_adp_info(DRIVER_NAME, adp, level);
@@ -912,10 +1105,4 @@ gdc_diag(video_adapter_t *adp, int level)
return 0;
}
-static int
-gdc_err(video_adapter_t *adp, ...)
-{
- return 0;
-}
-
#endif /* NGDC > 0 */
diff --git a/sys/pc98/cbus/sc_machdep.h b/sys/pc98/cbus/sc_machdep.h
new file mode 100644
index 0000000..59cdf56
--- /dev/null
+++ b/sys/pc98/cbus/sc_machdep.h
@@ -0,0 +1,61 @@
+/*-
+ * $Id: $
+ */
+
+#ifndef _PC98_PC98_SC_MACHDEP_H_
+#define _PC98_PC98_SC_MACHDEP_H_
+
+#undef SC_ALT_MOUSE_IMAGE
+#undef SC_DFLT_FONT
+#undef SC_MOUSE_CHAR
+#undef SC_PIXEL_MODE
+#undef SC_NO_FONT_LOADING
+#define SC_NO_FONT_LOADING 1
+#undef SC_NO_PALETTE_LOADING
+#define SC_NO_PALETTE_LOADING 1
+
+#ifndef SC_KERNEL_CONS_ATTR
+#define SC_KERNEL_CONS_ATTR (FG_LIGHTGREY | BG_BLACK)
+#endif
+
+#define KANJI 1
+
+#define BELL_DURATION 5
+#define BELL_PITCH_8M 1339
+#define BELL_PITCH_5M 1678
+
+#define UJIS 0
+#define SJIS 1
+
+#define PRINTABLE(c) ((c) > 0x1b || ((c) > 0x0f && (c) < 0x1b) \
+ || (c) < 0x07)
+
+#define ISMOUSEAVAIL(af) (1)
+#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
+#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE)
+
+#ifdef KANJI
+
+#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee))
+#define IS_KTYPE_KANA(A) ((A) & 0x11)
+#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0)
+
+#define _SCR_MD_STAT_DECLARED_
+typedef struct {
+ u_char kanji_1st_char;
+ u_char kanji_type;
+#define KTYPE_ASCII 0 /* ASCII */
+#define KTYPE_KANA 1 /* HANKAKU */
+#define KTYPE_JKANA 0x10 /* JIS HANKAKU */
+#define KTYPE_7JIS 0x20 /* JIS */
+#define KTYPE_SJIS 2 /* Shift JIS */
+#define KTYPE_UJIS 4 /* UJIS */
+#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */
+#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */
+#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */
+#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */
+} scr_md_stat_t;
+
+#endif /* KANJI */
+
+#endif /* !_PC98_PC98_SC_MACHDEP_H_ */
diff --git a/sys/pc98/cbus/scgdcrndr.c b/sys/pc98/cbus/scgdcrndr.c
new file mode 100644
index 0000000..e1ce7b8
--- /dev/null
+++ b/sys/pc98/cbus/scgdcrndr.c
@@ -0,0 +1,180 @@
+/*-
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "gdc.h"
+#include "opt_syscons.h"
+#include "opt_gdc.h"
+
+#if NSC > 0 && NGDC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#ifndef SC_RENDER_DEBUG
+#define SC_RENDER_DEBUG 0
+#endif
+
+static vr_clear_t gdc_txtclear;
+static vr_draw_border_t gdc_txtborder;
+static vr_draw_t gdc_txtdraw;
+static vr_set_cursor_t gdc_txtcursor_shape;
+static vr_draw_cursor_t gdc_txtcursor;
+#ifndef SC_NO_CUTPASTE
+static vr_draw_mouse_t gdc_txtmouse;
+#else
+#define gdc_txtmouse (vr_draw_mouse_t *)gdc_nop
+#endif
+
+#ifndef SC_NO_MODE_CHANGE
+static vr_draw_border_t gdc_grborder;
+#endif
+
+static void gdc_nop(scr_stat *scp, ...);
+
+static sc_rndr_sw_t txtrndrsw = {
+ gdc_txtclear,
+ gdc_txtborder,
+ gdc_txtdraw,
+ gdc_txtcursor_shape,
+ gdc_txtcursor,
+ (vr_blink_cursor_t *)gdc_nop,
+ (vr_set_mouse_t *)gdc_nop,
+ gdc_txtmouse,
+};
+RENDERER(gdc, 0, txtrndrsw);
+
+#ifndef SC_NO_MODE_CHANGE
+static sc_rndr_sw_t grrndrsw = {
+ (vr_clear_t *)gdc_nop,
+ gdc_grborder,
+ (vr_draw_t *)gdc_nop,
+ (vr_set_cursor_t *)gdc_nop,
+ (vr_draw_cursor_t *)gdc_nop,
+ (vr_blink_cursor_t *)gdc_nop,
+ (vr_set_mouse_t *)gdc_nop,
+ (vr_draw_mouse_t *)gdc_nop,
+};
+RENDERER(gdc, GRAPHICS_MODE, grrndrsw);
+#endif /* SC_NO_MODE_CHANGE */
+
+static void
+gdc_nop(scr_stat *scp, ...)
+{
+}
+
+/* text mode renderer */
+
+static void
+gdc_txtclear(scr_stat *scp, int c, int attr)
+{
+ sc_vtb_clear(&scp->scr, c, attr);
+}
+
+static void
+gdc_txtborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+static void
+gdc_txtdraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t p;
+ int c;
+ int a;
+
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+
+ if (flip) {
+ p = sc_vtb_pointer(&scp->scr, from);
+ for (; count-- > 0; ++from) {
+ c = sc_vtb_getc(&scp->vtb, from);
+ a = sc_vtb_geta(&scp->vtb, from) ^ 0x4;
+ sc_vtb_putchar(&scp->scr, p, c, a);
+ }
+ } else {
+ sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
+ }
+}
+
+static void
+gdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
+{
+ if (base < 0 || base >= scp->font_size)
+ return;
+ /* the caller may set height <= 0 in order to disable the cursor */
+ (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
+ base, height,
+ scp->font_size, blink);
+}
+
+static void
+gdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
+{
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
+ at%scp->xsize, at/scp->xsize);
+ } else {
+ if (scp->status & VR_CURSOR_ON)
+ (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
+ -1, -1);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+}
+
+#ifndef SC_NO_CUTPASTE
+
+static void
+draw_txtmouse(scr_stat *scp, int x, int y)
+{
+ int at;
+
+ at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ sc_vtb_putc(&scp->scr, at,
+ sc_vtb_getc(&scp->scr, at),
+ sc_vtb_geta(&scp->scr, at) ^ 0x4);
+}
+
+static void
+remove_txtmouse(scr_stat *scp, int x, int y)
+{
+}
+
+static void
+gdc_txtmouse(scr_stat *scp, int x, int y, int on)
+{
+ if (on)
+ draw_txtmouse(scp, x, y);
+ else
+ remove_txtmouse(scp, x, y);
+}
+
+#endif /* SC_NO_CUTPASTE */
+
+#ifndef SC_NO_MODE_CHANGE
+
+/* graphics mode renderer */
+
+static void
+gdc_grborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+#endif /* SC_NO_MODE_CHANGE */
+
+#endif /* NSC > 0 && NGDC > 0 */
diff --git a/sys/pc98/cbus/scvtb.c b/sys/pc98/cbus/scvtb.c
new file mode 100644
index 0000000..64f4cb6
--- /dev/null
+++ b/sys/pc98/cbus/scvtb.c
@@ -0,0 +1,364 @@
+/*-
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#define ATTR_OFFSET 0x2000
+
+#define vtb_wrap(vtb, at, offset) \
+ (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
+
+static u_int16_t at2pc98(u_int16_t attr);
+static vm_offset_t sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
+
+static u_int16_t
+at2pc98(u_int16_t attr)
+{
+ static u_char ibmpc_to_pc98[16] = {
+ 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
+ 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
+ };
+ static u_char ibmpc_to_pc98rev[16] = {
+ 0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5,
+ 0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
+ };
+ u_char fg_at, bg_at;
+ u_int16_t at;
+
+ if (attr & 0x00FF)
+ return (attr);
+
+ fg_at = ((attr >> 8) & 0x0F);
+ bg_at = ((attr >> 12) & 0x0F);
+
+ if (bg_at) {
+ if (bg_at & 0x08) {
+ if (bg_at & 0x07) {
+ /* reverse & blink */
+ at = ibmpc_to_pc98rev[bg_at] | 0x02;
+ } else {
+ /* normal & blink */
+ at = ibmpc_to_pc98[fg_at] | 0x02;
+ }
+ } else {
+ /* reverse */
+ at = ibmpc_to_pc98rev[bg_at];
+ }
+ } else {
+ /* normal */
+ at = ibmpc_to_pc98[fg_at];
+ }
+ at |= attr;
+ return (at);
+}
+
+void
+sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
+{
+ vtb->vtb_flags = 0;
+ vtb->vtb_type = type;
+ vtb->vtb_cols = cols;
+ vtb->vtb_rows = rows;
+ vtb->vtb_size = cols*rows;
+ vtb->vtb_buffer = NULL;
+ vtb->vtb_tail = 0;
+
+ switch (type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if ((buf == NULL) && (cols*rows != 0)) {
+ vtb->vtb_buffer =
+ (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
+ M_DEVBUF,
+ (wait) ? M_WAITOK : M_NOWAIT);
+ if (vtb->vtb_buffer != NULL) {
+ bzero((void *)sc_vtb_pointer(vtb, 0),
+ cols*rows*sizeof(u_int16_t)*2);
+ }
+ } else {
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ }
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ case VTB_FRAMEBUFFER:
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+sc_vtb_destroy(sc_vtb_t *vtb)
+{
+ vm_offset_t p;
+
+ vtb->vtb_flags = 0;
+ vtb->vtb_cols = 0;
+ vtb->vtb_rows = 0;
+ vtb->vtb_size = 0;
+ vtb->vtb_tail = 0;
+
+ p = vtb->vtb_buffer;
+ vtb->vtb_buffer = NULL;
+ switch (vtb->vtb_type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if (p != NULL)
+ free((void *)p, M_DEVBUF);
+ break;
+ default:
+ break;
+ }
+ vtb->vtb_type = VTB_INVALID;
+}
+
+size_t
+sc_vtb_size(int cols, int rows)
+{
+ return (size_t)(cols*rows*sizeof(u_int16_t)*2);
+}
+
+int
+sc_vtb_getc(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
+ else
+ return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
+}
+
+int
+sc_vtb_geta(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
+ else
+ return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
+}
+
+void
+sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ writew(sc_vtb_pointer(vtb, at), c);
+ writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
+ } else {
+ *(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
+ *(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
+ }
+}
+
+vm_offset_t
+sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ writew(p, c);
+ writew(p + ATTR_OFFSET, at2pc98(a));
+ } else {
+ *(u_int16_t *)p = c;
+ *(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
+ }
+ return (p + sizeof(u_int16_t));
+}
+
+vm_offset_t
+sc_vtb_pointer(sc_vtb_t *vtb, int at)
+{
+ return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
+}
+
+static vm_offset_t
+sc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
+{
+ return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
+ + ((vtb->vtb_type == VTB_FRAMEBUFFER) ?
+ ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
+}
+
+int
+sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
+{
+ return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
+}
+
+void
+sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+ fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+ fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
+ }
+}
+
+void
+sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
+{
+ if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_toio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
+ (void *)sc_vtb_attr_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ }
+}
+
+void
+sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
+{
+ int len;
+
+ if (vtb2->vtb_type != VTB_RINGBUFFER)
+ return;
+
+ while (count > 0) {
+ len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
+ if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
+ sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
+ (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ }
+ from += len;
+ count -= len;
+ vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
+ }
+}
+
+void
+sc_vtb_seek(sc_vtb_t *vtb, int pos)
+{
+ vtb->vtb_tail = pos%vtb->vtb_size;
+}
+
+void
+sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at), count);
+ fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
+ fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
+ }
+}
+
+void
+sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ int len;
+
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ len = vtb->vtb_size - at - count;
+ if (len > 0) {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at + count),
+ sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
+ sc_vtb_attr_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at + count),
+ (void *)sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
+ (void *)sc_vtb_attr_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ fillw_io(at2pc98(attr),
+ sc_vtb_attr_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ fillw(at2pc98(attr),
+ (void *)sc_vtb_attr_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ }
+}
+
+void
+sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size) {
+ count = vtb->vtb_size - at;
+ } else {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at),
+ sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ bcopy_io(sc_vtb_attr_pointer(vtb, at),
+ sc_vtb_attr_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at),
+ (void *)sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ bcopy((void *)sc_vtb_attr_pointer(vtb, at),
+ (void *)sc_vtb_attr_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ fillw_io(c, sc_vtb_pointer(vtb, at), count);
+ fillw_io(at2pc98(attr),
+ sc_vtb_attr_pointer(vtb, at), count);
+ } else {
+ fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
+ fillw(at2pc98(attr),
+ (void *)sc_vtb_attr_pointer(vtb, at), count);
+ }
+}
+
+#endif /* NSC */
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index c09af65..40fdd2c 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sio.c,v 1.96 1999/05/11 08:38:28 kato Exp $
+ * $Id: sio.c,v 1.97 1999/05/30 16:53:22 phk Exp $
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* from: i386/isa sio.c,v 1.234
*/
@@ -3931,7 +3931,7 @@ static cn_checkc_t siocncheckc;
static cn_getc_t siocngetc;
static cn_putc_t siocnputc;
-CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc);
/* To get the GDB related variables */
#if DDB > 0
diff --git a/sys/pc98/cbus/syscons_cbus.c b/sys/pc98/cbus/syscons_cbus.c
new file mode 100644
index 0000000..5bca2d0
--- /dev/null
+++ b/sys/pc98/cbus/syscons_cbus.c
@@ -0,0 +1,193 @@
+/*-
+ * $Id: $
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/cons.h>
+#include <machine/console.h>
+#include <machine/clock.h>
+
+#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/pc98_machdep.h>
+
+#include <dev/syscons/syscons.h>
+
+#include <i386/isa/timerreg.h>
+
+#include <isa/isavar.h>
+
+static devclass_t sc_devclass;
+
+static int scprobe(device_t dev);
+static int scattach(device_t dev);
+static int scresume(device_t dev);
+
+static device_method_t sc_methods[] = {
+ DEVMETHOD(device_probe, scprobe),
+ DEVMETHOD(device_attach, scattach),
+ DEVMETHOD(device_resume, scresume),
+ { 0, 0 }
+};
+
+static driver_t sc_driver = {
+ SC_DRIVER_NAME,
+ sc_methods,
+ 1, /* XXX */
+};
+
+static sc_softc_t main_softc = { 0, 0, 0, -1, NULL, -1, NULL, };
+
+static int
+scprobe(device_t dev)
+{
+ /* No pnp support */
+ if (isa_get_vendorid(dev))
+ return (ENXIO);
+
+ device_set_desc(dev, "System console");
+ return sc_probe_unit(device_get_unit(dev), isa_get_flags(dev));
+}
+
+static int
+scattach(device_t dev)
+{
+ return sc_attach_unit(device_get_unit(dev), isa_get_flags(dev));
+}
+
+static int
+scresume(device_t dev)
+{
+ return sc_resume_unit(device_get_unit(dev));
+}
+
+int
+sc_max_unit(void)
+{
+ return devclass_get_maxunit(sc_devclass);
+}
+
+sc_softc_t
+*sc_get_softc(int unit, int flags)
+{
+ sc_softc_t *sc;
+
+ if ((unit < 0) || (unit >= NSC))
+ return NULL;
+ if (flags & SC_KERNEL_CONSOLE) {
+ /* FIXME: clear if it is wired to another unit! */
+ main_softc.unit = unit;
+ return &main_softc;
+ } else {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, unit);
+ if (!(sc->flags & SC_INIT_DONE)) {
+ sc->unit = unit;
+ sc->keyboard = -1;
+ sc->adapter = -1;
+ }
+ return sc;
+ }
+}
+
+sc_softc_t
+*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
+{
+ sc_softc_t *sc;
+ int units;
+ int i;
+
+ sc = &main_softc;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ units = devclass_get_maxunit(sc_devclass);
+ for (i = 0; i < units; ++i) {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, i);
+ if (sc == NULL)
+ continue;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ }
+ return NULL;
+}
+
+int
+sc_get_cons_priority(int *unit, int *flags)
+{
+ int disabled;
+ int u, f;
+ int i;
+
+ *unit = -1;
+ for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) {
+ u = resource_query_unit(i);
+ if ((resource_int_value(SC_DRIVER_NAME, u, "disabled",
+ &disabled) == 0) && disabled)
+ continue;
+ if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
+ f = 0;
+ if (f & SC_KERNEL_CONSOLE) {
+ /* the user designates this unit to be the console */
+ *unit = u;
+ *flags = f;
+ break;
+ }
+ if (*unit < 0) {
+ /* ...otherwise remember the first found unit */
+ *unit = u;
+ *flags = f;
+ }
+ }
+ if ((i < 0) && (*unit < 0))
+ return CN_DEAD;
+ return CN_INTERNAL;
+}
+
+void
+sc_get_bios_values(bios_values_t *values)
+{
+ values->cursor_start = 0;
+ values->cursor_end = 16;
+ values->shift_state = 0;
+ if (pc98_machine_type & M_8M)
+ values->bell_pitch = BELL_PITCH_8M;
+ else
+ values->bell_pitch = BELL_PITCH_5M;
+}
+
+int
+sc_tone(int herz)
+{
+ int pitch;
+
+ if (herz) {
+ /* enable counter 1 */
+ outb(0x35, inb(0x35) & 0xf7);
+ /* set command for counter 1, 2 byte write */
+ if (acquire_timer1(TIMER_16BIT | TIMER_SQWAVE))
+ return EBUSY;
+ /* set pitch */
+ pitch = timer_freq/herz;
+ outb(TIMER_CNTR1, pitch);
+ outb(TIMER_CNTR1, pitch >> 8);
+ } else {
+ /* disable counter 1 */
+ outb(0x35, inb(0x35) | 0x08);
+ release_timer1();
+ }
+ return 0;
+}
+
+DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
+
+#endif /* NSC > 0 */
OpenPOWER on IntegriCloud