Readd the vt(4) driver and corresponding tools.

This commit is contained in:
ed 2011-03-22 21:31:31 +00:00
parent 059b3a821c
commit 98e93f6b12
32 changed files with 7824 additions and 10 deletions

View File

@ -311,6 +311,8 @@
..
sys
..
teken
..
ufs
ffs
..

View File

@ -215,6 +215,9 @@ copies:
cd ${.CURDIR}/../sys/rpc; \
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 types.h \
${DESTDIR}${INCLUDEDIR}/rpc
cd ${.CURDIR}/../sys/teken; \
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 teken.h \
${DESTDIR}${INCLUDEDIR}/teken
symlinks:
@${ECHO} "Setting up symlinks to kernel source tree..."

View File

@ -102,7 +102,7 @@ pccarddevs.h standard \
compile-with "${AWK} -f $S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \
no-obj no-implicit-rule before-depend \
clean "pccarddevs.h"
teken_state.h optional sc \
teken_state.h optional sc | vt \
dependency "$S/teken/gensequences $S/teken/sequences" \
compile-with "${AWK} -f $S/teken/gensequences $S/teken/sequences > teken_state.h" \
no-obj no-implicit-rule before-depend \
@ -1921,6 +1921,16 @@ dev/utopia/utopia.c optional utopia
dev/vge/if_vge.c optional vge
dev/vkbd/vkbd.c optional vkbd
dev/vr/if_vr.c optional vr pci
dev/vt/font/font_default.c optional vt
dev/vt/hw/intel/intel.c optional vt vt_intel
dev/vt/hw/vga/vga.c optional vt vt_vga
dev/vt/logo/logo_freebsd.c optional vt
dev/vt/vt_buf.c optional vt
dev/vt/vt_consolectl.c optional vt
dev/vt/vt_core.c optional vt
dev/vt/vt_font.c optional vt
dev/vt/vt_history.c optional vt
dev/vt/vt_sysmouse.c optional vt
dev/vte/if_vte.c optional vte pci
dev/vx/if_vx.c optional vx
dev/vx/if_vx_eisa.c optional vx eisa
@ -2279,6 +2289,7 @@ kern/subr_sleepqueue.c standard
kern/subr_smp.c standard
kern/subr_stack.c optional ddb | stack | ktr
kern/subr_taskqueue.c standard
kern/subr_terminal.c optional vt
kern/subr_trap.c standard
kern/subr_turnstile.c standard
kern/subr_uio.c standard
@ -3155,7 +3166,7 @@ security/mac_portacl/mac_portacl.c optional mac_portacl
security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids
security/mac_stub/mac_stub.c optional mac_stub
security/mac_test/mac_test.c optional mac_test
teken/teken.c optional sc
teken/teken.c optional sc | vt
ufs/ffs/ffs_alloc.c optional ffs
ufs/ffs/ffs_balloc.c optional ffs
ufs/ffs/ffs_inode.c optional ffs

View File

@ -237,6 +237,7 @@ dev/tpm/tpm_isa.c optional tpm isa
dev/uart/uart_cpu_i386.c optional uart
dev/acpica/acpi_if.m standard
dev/acpi_support/acpi_wmi_if.m standard
dev/vt/hw/xboxfb/xboxfb.c optional vt_xboxfb
dev/wpi/if_wpi.c optional wpi
i386/acpica/acpi_machdep.c optional acpi
acpi_wakecode.o optional acpi \

File diff suppressed because it is too large Load Diff

157
sys/dev/vt/hw/intel/intel.c Normal file
View File

@ -0,0 +1,157 @@
/*-
* Copyright (c) 2005 Marcel Moolenaar
* All rights reserved.
*
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Ed Schouten
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/vt/vt.h>
#include <dev/vt/hw/intel/intel_reg.h>
#define PCI_VENDOR_INTEL 0x8086
#define PCI_DEVICE_I965GM 0x2a02
static int intel_probe(device_t);
static int intel_attach(device_t);
static device_method_t intel_methods[] = {
DEVMETHOD(device_probe, intel_probe),
DEVMETHOD(device_attach, intel_attach),
{ 0, 0 }
};
static vd_init_t intel_vtinit;
static vd_bitblt_t intel_vtbitblt;
static struct vt_driver intel_vtops = {
.vd_init = intel_vtinit,
.vd_bitblt = intel_vtbitblt,
};
struct intel_softc {
bus_space_tag_t i_reg_tag;
bus_space_handle_t i_reg_handle;
};
#define REG_READ(sc, ofs) \
bus_space_read_4(sc->i_reg_tag, sc->i_reg_handle, ofs)
#define REG_WRITE(sc, ofs, val) \
bus_space_write_4(sc->i_reg_tag, sc->i_reg_handle, ofs, val)
static devclass_t intel_devclass;
static driver_t intel_driver = {
"vt_intel",
intel_methods,
sizeof(struct intel_softc)
};
static void
intel_initialize_graphics(struct vt_device *vd)
{
struct intel_softc *sc = vd->vd_softc;
uint32_t x;
/* Disable VGA. */
/* XXX: Doesn't work? Region returns 0xffffffff! */
x = REG_READ(sc, INTEL_VB_VGACNTRL);
x |= INTEL_VB_VGACNTRL_DISABLE;
REG_WRITE(sc, INTEL_VB_VGACNTRL, x);
}
static int
intel_probe(device_t dev)
{
if (pci_get_vendor(dev) != PCI_VENDOR_INTEL)
return (ENXIO);
if (pci_get_class(dev) != PCIC_DISPLAY)
return (ENXIO);
switch (pci_get_device(dev)) {
case PCI_DEVICE_I965GM:
device_set_desc(dev, "Intel 965GM");
break;
default:
return (ENXIO);
}
return (BUS_PROBE_DEFAULT);
}
static int
intel_attach(device_t dev)
{
struct intel_softc *sc = device_get_softc(dev);
struct resource *res;
int rid;
rid = 0x0a;
res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (res == NULL)
return (ENXIO);
sc->i_reg_tag = rman_get_bustag(res);
sc->i_reg_handle = rman_get_bushandle(res);
/* XXX */
vt_allocate(&intel_vtops, sc);
return (0);
}
static int
intel_vtinit(struct vt_device *vd)
{
vd->vd_width = 1024;
vd->vd_height = 768;
intel_initialize_graphics(vd);
return (0);
}
static void
intel_vtbitblt(struct vt_device *vd, const uint8_t *src,
vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
term_color_t fg, term_color_t bg)
{
}
DRIVER_MODULE(intel, pci, intel_driver, intel_devclass, 0, 0);

View File

@ -0,0 +1,38 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Ed Schouten
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _DEV_VT_HW_INTEL_INTEL_REG_H_
#define _DEV_VT_HW_INTEL_INTEL_REG_H_
#define INTEL_VB_VGACNTRL 0x71400
#define INTEL_VB_VGACNTRL_DISABLE 0x80000000
#endif /* !_DEV_VT_HW_INTEL_INTEL_REG_H_ */

598
sys/dev/vt/hw/vga/vga.c Normal file
View File

@ -0,0 +1,598 @@
/*-
* Copyright (c) 2005 Marcel Moolenaar
* All rights reserved.
*
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Ed Schouten
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <dev/vt/vt.h>
#include <dev/vt/hw/vga/vga_reg.h>
#include <machine/bus.h>
#if defined(__amd64__) || defined(__i386__)
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#endif /* __amd64__ || __i386__ */
struct vga_softc {
bus_space_tag_t vga_fb_tag;
bus_space_handle_t vga_fb_handle;
bus_space_tag_t vga_reg_tag;
bus_space_handle_t vga_reg_handle;
int vga_curcolor;
};
/* Convenience macros. */
#define MEM_READ1(sc, ofs) \
bus_space_read_1(sc->vga_fb_tag, sc->vga_fb_handle, ofs)
#define MEM_WRITE1(sc, ofs, val) \
bus_space_write_1(sc->vga_fb_tag, sc->vga_fb_handle, ofs, val)
#define REG_READ1(sc, reg) \
bus_space_read_1(sc->vga_reg_tag, sc->vga_reg_handle, reg)
#define REG_WRITE1(sc, reg, val) \
bus_space_write_1(sc->vga_reg_tag, sc->vga_reg_handle, reg, val)
#define VT_VGA_WIDTH 640
#define VT_VGA_HEIGHT 480
#define VT_VGA_MEMSIZE (VT_VGA_WIDTH * VT_VGA_HEIGHT / 8)
static vd_init_t vga_init;
static vd_blank_t vga_blank;
static vd_bitblt_t vga_bitblt;
static vd_putchar_t vga_putchar;
static const struct vt_driver vt_vga_driver = {
.vd_init = vga_init,
.vd_blank = vga_blank,
.vd_bitblt = vga_bitblt,
.vd_putchar = vga_putchar,
};
/*
* Driver supports both text mode and graphics mode. Make sure the
* buffer is always big enough to support both.
*/
static struct vga_softc vga_conssoftc;
VT_CONSDEV_DECLARE(vt_vga_driver, MAX(80, PIXEL_WIDTH(VT_VGA_WIDTH)),
MAX(25, PIXEL_HEIGHT(VT_VGA_HEIGHT)), &vga_conssoftc);
static inline void
vga_setcolor(struct vt_device *vd, term_color_t color)
{
struct vga_softc *sc = vd->vd_softc;
if (sc->vga_curcolor != color) {
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
REG_WRITE1(sc, VGA_GC_DATA, color);
sc->vga_curcolor = color;
}
}
static void
vga_blank(struct vt_device *vd, term_color_t color)
{
struct vga_softc *sc = vd->vd_softc;
u_int ofs;
vga_setcolor(vd, color);
for (ofs = 0; ofs < VT_VGA_MEMSIZE; ofs++)
MEM_WRITE1(sc, ofs, 0xff);
}
static inline void
vga_bitblt_put(struct vt_device *vd, u_long dst, term_color_t color,
uint8_t v)
{
struct vga_softc *sc = vd->vd_softc;
/* Skip empty writes, in order to avoid palette changes. */
if (v != 0x00) {
vga_setcolor(vd, color);
/*
* When this MEM_READ1() gets disabled, all sorts of
* artifacts occur. This is because this read loads the
* set of 8 pixels that are about to be changed. There
* is one scenario where we can avoid the read, namely
* if all pixels are about to be overwritten anyway.
*/
if (v != 0xff)
MEM_READ1(sc, dst);
MEM_WRITE1(sc, dst, v);
}
}
static inline void
vga_bitblt_draw(struct vt_device *vd, const uint8_t *src,
u_long ldst, uint8_t shift, unsigned int width, unsigned int height,
term_color_t color, int negate)
{
u_long dst;
int w;
uint8_t b, r, out;
for (; height > 0; height--) {
dst = ldst;
ldst += VT_VGA_WIDTH / 8;
r = 0;
for (w = width; w > 0; w -= 8) {
b = *src++;
if (negate) {
b = ~b;
/* Don't go too far. */
if (w < 8)
b &= 0xff << (8 - w);
}
/* Reintroduce bits from previous column. */
out = (b >> shift) | r;
r = b << (8 - shift);
vga_bitblt_put(vd, dst++, color, out);
}
/* Print the remainder. */
vga_bitblt_put(vd, dst, color, r);
}
}
static void
vga_bitblt(struct vt_device *vd, const uint8_t *src,
vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
term_color_t fg, term_color_t bg)
{
struct vga_softc *sc = vd->vd_softc;
u_long dst;
uint8_t shift;
dst = (VT_VGA_WIDTH * top + left) / 8;
shift = left % 8;
if (sc->vga_curcolor == fg) {
vga_bitblt_draw(vd, src, dst, shift, width, height, fg, 0);
vga_bitblt_draw(vd, src, dst, shift, width, height, bg, 1);
} else {
vga_bitblt_draw(vd, src, dst, shift, width, height, bg, 1);
vga_bitblt_draw(vd, src, dst, shift, width, height, fg, 0);
}
}
/*
* Binary searchable table for Unicode to CP437 conversion.
*/
struct unicp437 {
uint16_t unicode_base;
uint8_t cp437_base;
uint8_t length;
};
static const struct unicp437 cp437table[] = {
{ 0x0020, 0x20, 0x5e }, { 0x00a0, 0x20, 0x00 },
{ 0x00a1, 0xad, 0x00 }, { 0x00a2, 0x9b, 0x00 },
{ 0x00a3, 0x9c, 0x00 }, { 0x00a5, 0x9d, 0x00 },
{ 0x00a7, 0x15, 0x00 }, { 0x00aa, 0xa6, 0x00 },
{ 0x00ab, 0xae, 0x00 }, { 0x00ac, 0xaa, 0x00 },
{ 0x00b0, 0xf8, 0x00 }, { 0x00b1, 0xf1, 0x00 },
{ 0x00b2, 0xfd, 0x00 }, { 0x00b5, 0xe6, 0x00 },
{ 0x00b6, 0x14, 0x00 }, { 0x00b7, 0xfa, 0x00 },
{ 0x00ba, 0xa7, 0x00 }, { 0x00bb, 0xaf, 0x00 },
{ 0x00bc, 0xac, 0x00 }, { 0x00bd, 0xab, 0x00 },
{ 0x00bf, 0xa8, 0x00 }, { 0x00c4, 0x8e, 0x01 },
{ 0x00c6, 0x92, 0x00 }, { 0x00c7, 0x80, 0x00 },
{ 0x00c9, 0x90, 0x00 }, { 0x00d1, 0xa5, 0x00 },
{ 0x00d6, 0x99, 0x00 }, { 0x00dc, 0x9a, 0x00 },
{ 0x00df, 0xe1, 0x00 }, { 0x00e0, 0x85, 0x00 },
{ 0x00e1, 0xa0, 0x00 }, { 0x00e2, 0x83, 0x00 },
{ 0x00e4, 0x84, 0x00 }, { 0x00e5, 0x86, 0x00 },
{ 0x00e6, 0x91, 0x00 }, { 0x00e7, 0x87, 0x00 },
{ 0x00e8, 0x8a, 0x00 }, { 0x00e9, 0x82, 0x00 },
{ 0x00ea, 0x88, 0x01 }, { 0x00ec, 0x8d, 0x00 },
{ 0x00ed, 0xa1, 0x00 }, { 0x00ee, 0x8c, 0x00 },
{ 0x00ef, 0x8b, 0x00 }, { 0x00f0, 0xeb, 0x00 },
{ 0x00f1, 0xa4, 0x00 }, { 0x00f2, 0x95, 0x00 },
{ 0x00f3, 0xa2, 0x00 }, { 0x00f4, 0x93, 0x00 },
{ 0x00f6, 0x94, 0x00 }, { 0x00f7, 0xf6, 0x00 },
{ 0x00f8, 0xed, 0x00 }, { 0x00f9, 0x97, 0x00 },
{ 0x00fa, 0xa3, 0x00 }, { 0x00fb, 0x96, 0x00 },
{ 0x00fc, 0x81, 0x00 }, { 0x00ff, 0x98, 0x00 },
{ 0x0192, 0x9f, 0x00 }, { 0x0393, 0xe2, 0x00 },
{ 0x0398, 0xe9, 0x00 }, { 0x03a3, 0xe4, 0x00 },
{ 0x03a6, 0xe8, 0x00 }, { 0x03a9, 0xea, 0x00 },
{ 0x03b1, 0xe0, 0x01 }, { 0x03b4, 0xeb, 0x00 },
{ 0x03b5, 0xee, 0x00 }, { 0x03bc, 0xe6, 0x00 },
{ 0x03c0, 0xe3, 0x00 }, { 0x03c3, 0xe5, 0x00 },
{ 0x03c4, 0xe7, 0x00 }, { 0x03c6, 0xed, 0x00 },
{ 0x03d5, 0xed, 0x00 }, { 0x2010, 0x2d, 0x00 },
{ 0x2014, 0x2d, 0x00 }, { 0x2018, 0x60, 0x00 },
{ 0x2019, 0x27, 0x00 }, { 0x201c, 0x22, 0x00 },
{ 0x201d, 0x22, 0x00 }, { 0x2022, 0x07, 0x00 },
{ 0x203c, 0x13, 0x00 }, { 0x207f, 0xfc, 0x00 },
{ 0x20a7, 0x9e, 0x00 }, { 0x20ac, 0xee, 0x00 },
{ 0x2126, 0xea, 0x00 }, { 0x2190, 0x1b, 0x00 },
{ 0x2191, 0x18, 0x00 }, { 0x2192, 0x1a, 0x00 },
{ 0x2193, 0x19, 0x00 }, { 0x2194, 0x1d, 0x00 },
{ 0x2195, 0x12, 0x00 }, { 0x21a8, 0x17, 0x00 },
{ 0x2202, 0xeb, 0x00 }, { 0x2208, 0xee, 0x00 },
{ 0x2211, 0xe4, 0x00 }, { 0x2212, 0x2d, 0x00 },
{ 0x2219, 0xf9, 0x00 }, { 0x221a, 0xfb, 0x00 },
{ 0x221e, 0xec, 0x00 }, { 0x221f, 0x1c, 0x00 },
{ 0x2229, 0xef, 0x00 }, { 0x2248, 0xf7, 0x00 },
{ 0x2261, 0xf0, 0x00 }, { 0x2264, 0xf3, 0x00 },
{ 0x2265, 0xf2, 0x00 }, { 0x2302, 0x7f, 0x00 },
{ 0x2310, 0xa9, 0x00 }, { 0x2320, 0xf4, 0x00 },
{ 0x2321, 0xf5, 0x00 }, { 0x2500, 0xc4, 0x00 },
{ 0x2502, 0xb3, 0x00 }, { 0x250c, 0xda, 0x00 },
{ 0x2510, 0xbf, 0x00 }, { 0x2514, 0xc0, 0x00 },
{ 0x2518, 0xd9, 0x00 }, { 0x251c, 0xc3, 0x00 },
{ 0x2524, 0xb4, 0x00 }, { 0x252c, 0xc2, 0x00 },
{ 0x2534, 0xc1, 0x00 }, { 0x253c, 0xc5, 0x00 },
{ 0x2550, 0xcd, 0x00 }, { 0x2551, 0xba, 0x00 },
{ 0x2552, 0xd5, 0x00 }, { 0x2553, 0xd6, 0x00 },
{ 0x2554, 0xc9, 0x00 }, { 0x2555, 0xb8, 0x00 },
{ 0x2556, 0xb7, 0x00 }, { 0x2557, 0xbb, 0x00 },
{ 0x2558, 0xd4, 0x00 }, { 0x2559, 0xd3, 0x00 },
{ 0x255a, 0xc8, 0x00 }, { 0x255b, 0xbe, 0x00 },
{ 0x255c, 0xbd, 0x00 }, { 0x255d, 0xbc, 0x00 },
{ 0x255e, 0xc6, 0x01 }, { 0x2560, 0xcc, 0x00 },
{ 0x2561, 0xb5, 0x00 }, { 0x2562, 0xb6, 0x00 },
{ 0x2563, 0xb9, 0x00 }, { 0x2564, 0xd1, 0x01 },
{ 0x2566, 0xcb, 0x00 }, { 0x2567, 0xcf, 0x00 },
{ 0x2568, 0xd0, 0x00 }, { 0x2569, 0xca, 0x00 },
{ 0x256a, 0xd8, 0x00 }, { 0x256b, 0xd7, 0x00 },
{ 0x256c, 0xce, 0x00 }, { 0x2580, 0xdf, 0x00 },
{ 0x2584, 0xdc, 0x00 }, { 0x2588, 0xdb, 0x00 },
{ 0x258c, 0xdd, 0x00 }, { 0x2590, 0xde, 0x00 },
{ 0x2591, 0xb0, 0x02 }, { 0x25a0, 0xfe, 0x00 },
{ 0x25ac, 0x16, 0x00 }, { 0x25b2, 0x1e, 0x00 },
{ 0x25ba, 0x10, 0x00 }, { 0x25bc, 0x1f, 0x00 },
{ 0x25c4, 0x11, 0x00 }, { 0x25cb, 0x09, 0x00 },
{ 0x25d8, 0x08, 0x00 }, { 0x25d9, 0x0a, 0x00 },
{ 0x263a, 0x01, 0x01 }, { 0x263c, 0x0f, 0x00 },
{ 0x2640, 0x0c, 0x00 }, { 0x2642, 0x0b, 0x00 },
{ 0x2660, 0x06, 0x00 }, { 0x2663, 0x05, 0x00 },
{ 0x2665, 0x03, 0x01 }, { 0x266a, 0x0d, 0x01 },
};
static uint8_t
vga_get_cp437(term_char_t c)
{
int min, mid, max;
min = 0;
max = (sizeof(cp437table) / sizeof(struct unicp437)) - 1;
if (c < cp437table[0].unicode_base ||
c > cp437table[max].unicode_base + cp437table[max].length)
return '?';
while (max >= min) {
mid = (min + max) / 2;
if (c < cp437table[mid].unicode_base)
max = mid - 1;
else if (c > cp437table[mid].unicode_base +
cp437table[mid].length)
min = mid + 1;
else
return (c - cp437table[mid].unicode_base +
cp437table[mid].cp437_base);
}
return '?';
}
static void
vga_putchar(struct vt_device *vd, term_char_t c,
vt_axis_t top, vt_axis_t left, term_color_t fg, term_color_t bg)
{
struct vga_softc *sc = vd->vd_softc;
uint8_t ch, attr;
/*
* Convert character to CP437, which is the character set used
* by the VGA hardware by default.
*/
ch = vga_get_cp437(c);
/*
* Convert colors to VGA attributes.
*/
attr = bg << 4 | fg;
MEM_WRITE1(sc, 0x18000 + (top * 80 + left) * 2 + 0, ch);
MEM_WRITE1(sc, 0x18000 + (top * 80 + left) * 2 + 1, attr);
}
static void
vga_initialize_graphics(struct vt_device *vd)
{
struct vga_softc *sc = vd->vd_softc;
/* Clock select. */
REG_WRITE1(sc, VGA_GEN_MISC_OUTPUT_W, VGA_GEN_MO_VSP | VGA_GEN_MO_HSP |
VGA_GEN_MO_PB | VGA_GEN_MO_ER | VGA_GEN_MO_IOA);
/* Set sequencer clocking and memory mode. */
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_CLOCKING_MODE);
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_CM_89);
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_MEMORY_MODE);
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_MM_OE | VGA_SEQ_MM_EM);
/* Set the graphics controller in graphics mode. */
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_MISCELLANEOUS);
REG_WRITE1(sc, VGA_GC_DATA, 0x04 + VGA_GC_MISC_GA);
/* Program the CRT controller. */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_HORIZ_TOTAL);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x5f); /* 760 */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_HORIZ_DISP_END);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x4f); /* 640 - 8 */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_HORIZ_BLANK);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x50); /* 640 */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_END_HORIZ_BLANK);
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_EHB_CR + 2);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_HORIZ_RETRACE);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x54); /* 672 */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_END_HORIZ_RETRACE);
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_EHR_EHB + 0);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_TOTAL);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x0b); /* 523 */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_OVERFLOW);
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_OF_VT9 | VGA_CRTC_OF_LC8 |
VGA_CRTC_OF_VBS8 | VGA_CRTC_OF_VRS8 | VGA_CRTC_OF_VDE8);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MAX_SCAN_LINE);
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_MSL_LC9);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_RETRACE_START);
REG_WRITE1(sc, VGA_CRTC_DATA, 0xea); /* 480 + 10 */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_RETRACE_END);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x0c);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_DISPLAY_END);
REG_WRITE1(sc, VGA_CRTC_DATA, 0xdf); /* 480 - 1*/
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_OFFSET);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x28);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_VERT_BLANK);
REG_WRITE1(sc, VGA_CRTC_DATA, 0xe7); /* 480 + 7 */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_END_VERT_BLANK);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x04);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MODE_CONTROL);
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_MC_WB | VGA_CRTC_MC_AW |
VGA_CRTC_MC_SRS | VGA_CRTC_MC_CMS);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_LINE_COMPARE);
REG_WRITE1(sc, VGA_CRTC_DATA, 0xff); /* 480 + 31 */
REG_WRITE1(sc, VGA_GEN_FEATURE_CTRL_W, 0);
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_MAP_MASK);
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_MM_EM3 | VGA_SEQ_MM_EM2 |
VGA_SEQ_MM_EM1 | VGA_SEQ_MM_EM0);
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_CHAR_MAP_SELECT);
REG_WRITE1(sc, VGA_SEQ_DATA, 0);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
REG_WRITE1(sc, VGA_GC_DATA, 0);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
REG_WRITE1(sc, VGA_GC_DATA, 0x0f);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_COLOR_COMPARE);
REG_WRITE1(sc, VGA_GC_DATA, 0);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_DATA_ROTATE);
REG_WRITE1(sc, VGA_GC_DATA, 0);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_READ_MAP_SELECT);
REG_WRITE1(sc, VGA_GC_DATA, 0);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_MODE);
REG_WRITE1(sc, VGA_GC_DATA, 0);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_COLOR_DONT_CARE);
REG_WRITE1(sc, VGA_GC_DATA, 0x0f);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_BIT_MASK);
REG_WRITE1(sc, VGA_GC_DATA, 0xff);
}
static void
vga_initialize(struct vt_device *vd, int textmode)
{
struct vga_softc *sc = vd->vd_softc;
uint8_t x;
/* Make sure the VGA adapter is not in monochrome emulation mode. */
x = REG_READ1(sc, VGA_GEN_MISC_OUTPUT_R);
REG_WRITE1(sc, VGA_GEN_MISC_OUTPUT_W, x | VGA_GEN_MO_IOA);
/* Unprotect CRTC registers 0-7. */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_RETRACE_END);
x = REG_READ1(sc, VGA_CRTC_DATA);
REG_WRITE1(sc, VGA_CRTC_DATA, x & ~VGA_CRTC_VRE_PR);
/*
* Wait for the vertical retrace.
* NOTE: this code reads the VGA_GEN_INPUT_STAT_1 register, which has
* the side-effect of clearing the internal flip-flip of the attribute
* controller's write register. This means that because this code is
* here, we know for sure that the first write to the attribute
* controller will be a write to the address register. Removing this
* code therefore also removes that guarantee and appropriate measures
* need to be taken.
*/
do {
x = REG_READ1(sc, VGA_GEN_INPUT_STAT_1);
x &= VGA_GEN_IS1_VR | VGA_GEN_IS1_DE;
} while (x != (VGA_GEN_IS1_VR | VGA_GEN_IS1_DE));
/* Now, disable the sync. signals. */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MODE_CONTROL);
x = REG_READ1(sc, VGA_CRTC_DATA);
REG_WRITE1(sc, VGA_CRTC_DATA, x & ~VGA_CRTC_MC_HR);
/* Asynchronous sequencer reset. */
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_RESET);
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_RST_SR);
if (!textmode)
vga_initialize_graphics(vd);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_PRESET_ROW_SCAN);
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_START);
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_CS_COO);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_END);
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_ADDR_HIGH);
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_ADDR_LOW);
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_LOC_HIGH);
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_LOC_LOW);
REG_WRITE1(sc, VGA_CRTC_DATA, 0x59);
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_UNDERLINE_LOC);
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_UL_UL);
if (textmode) {
/* Set the attribute controller to blink disable. */
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_MODE_CONTROL);
REG_WRITE1(sc, VGA_AC_WRITE, 0);
} else {
/* Set the attribute controller in graphics mode. */
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_MODE_CONTROL);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_MC_GA);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_HORIZ_PIXEL_PANNING);
REG_WRITE1(sc, VGA_AC_WRITE, 0);
}
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(0));
REG_WRITE1(sc, VGA_AC_WRITE, 0);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(1));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(2));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_G);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(3));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SG | VGA_AC_PAL_R);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(4));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(5));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R | VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(6));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_G | VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(7));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R | VGA_AC_PAL_G | VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(8));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(9));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB | VGA_AC_PAL_R);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(10));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB | VGA_AC_PAL_G);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(11));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_G);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(12));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB | VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(13));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(14));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB | VGA_AC_PAL_G | VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(15));
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_G | VGA_AC_PAL_B);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_OVERSCAN_COLOR);
REG_WRITE1(sc, VGA_AC_WRITE, 0);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_COLOR_PLANE_ENABLE);
REG_WRITE1(sc, VGA_AC_WRITE, 0x0f);
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_COLOR_SELECT);
REG_WRITE1(sc, VGA_AC_WRITE, 0);
if (!textmode) {
u_int ofs;
/*
* Done. Clear the frame buffer. All bit planes are
* enabled, so a single-paged loop should clear all
* planes.
*/
for (ofs = 0; ofs < VT_VGA_MEMSIZE; ofs++) {
MEM_READ1(sc, ofs);
MEM_WRITE1(sc, ofs, 0);
}
}
/* Re-enable the sequencer. */
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_RESET);
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_RST_SR | VGA_SEQ_RST_NAR);
/* Re-enable the sync signals. */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MODE_CONTROL);
x = REG_READ1(sc, VGA_CRTC_DATA);
REG_WRITE1(sc, VGA_CRTC_DATA, x | VGA_CRTC_MC_HR);
if (!textmode) {
/* Switch to write mode 3, because we'll mainly do bitblt. */
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_MODE);
REG_WRITE1(sc, VGA_GC_DATA, 3);
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
REG_WRITE1(sc, VGA_GC_DATA, 0x0f);
}
}
static int
vga_init(struct vt_device *vd)
{
struct vga_softc *sc = vd->vd_softc;
int textmode = 0;
#if defined(__amd64__)
sc->vga_fb_tag = AMD64_BUS_SPACE_MEM;
sc->vga_fb_handle = KERNBASE + VGA_MEM_BASE;
sc->vga_reg_tag = AMD64_BUS_SPACE_IO;
sc->vga_reg_handle = VGA_REG_BASE;
#elif defined(__i386__)
sc->vga_fb_tag = I386_BUS_SPACE_MEM;
sc->vga_fb_handle = KERNBASE + VGA_MEM_BASE;
sc->vga_reg_tag = I386_BUS_SPACE_IO;
sc->vga_reg_handle = VGA_REG_BASE;
#else
# error "Architecture not yet supported!"
#endif
TUNABLE_INT_FETCH("hw.vga.textmode", &textmode);
if (textmode) {
vd->vd_flags |= VDF_TEXTMODE;
vd->vd_width = 80;
vd->vd_height = 25;
} else {
vd->vd_width = VT_VGA_WIDTH;
vd->vd_height = VT_VGA_HEIGHT;
}
vga_initialize(vd, textmode);
return (CN_INTERNAL);
}

220
sys/dev/vt/hw/vga/vga_reg.h Normal file
View File

@ -0,0 +1,220 @@
/*-
* Copyright (c) 2005 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _DEV_VT_HW_VGA_VGA_REG_H_
#define _DEV_VT_HW_VGA_VGA_REG_H_
/*
* The VGA adapter uses two I/O port blocks. One of these blocks, the CRT
* controller registers, can be located either at 0x3B0 or at 0x3D0 in I/O
* port space. This allows compatibility with the monochrome adapter, which
* has the CRT controller registers at 0x3B0.
*
* It is assumed that compatibility with the monochrome adapter is not of
* interest anymore. As such, the CRT controller can be located at 0x3D0 in
* I/O port space unconditionally. This means that the 2 I/O blocks are
* always adjacent and can therefore be treated as a single logical I/O port
* range. In practical terms: there only has to be a single tag and handle
* to access all registers.
*
* The following definitions are taken from or inspired by:
* Programmer's Guide to the EGA, VGA, and Super VGA Cards -- 3rd ed.,
* Richard F. Ferraro, Addison-Wesley, ISBN 0-201-62490-7
*/
#define VGA_MEM_BASE 0xA0000
#define VGA_MEM_SIZE 0x10000
#define VGA_REG_BASE 0x3c0
#define VGA_REG_SIZE 0x10+0x0c
/* Attribute controller registers. */
#define VGA_AC_WRITE 0x00
#define VGA_AC_READ 0x01
#define VGA_AC_PALETTE(x) (x) /* 0 <= x <= 15 */
#define VGA_AC_PAL_SR 0x20 /* Secondary red */
#define VGA_AC_PAL_SG 0x10 /* Secondary green */
#define VGA_AC_PAL_SB 0x08 /* Secondary blue */
#define VGA_AC_PAL_R 0x04 /* Red */
#define VGA_AC_PAL_G 0x02 /* Green */
#define VGA_AC_PAL_B 0x01 /* Blue */
#define VGA_AC_MODE_CONTROL (32+16)
#define VGA_AC_MC_IPS 0x80 /* Internal palette size */
#define VGA_AC_MC_PCS 0x40 /* Pixel clock select */
#define VGA_AC_MC_PPC 0x20 /* Pixel panning compat. */
#define VGA_AC_MC_BI 0x08 /* Blink/intensity */
#define VGA_AC_MC_ELG 0x04 /* Enable line graphics cc. */
#define VGA_AC_MC_DT 0x02 /* Display type */
#define VGA_AC_MC_GA 0x01 /* Graphics/alphanumeric */
#define VGA_AC_OVERSCAN_COLOR (32+17)
#define VGA_AC_COLOR_PLANE_ENABLE (32+18)
#define VGA_AC_HORIZ_PIXEL_PANNING (32+19)
#define VGA_AC_COLOR_SELECT (32+20)
#define VGA_AC_CS_C67 0x0C /* Color reg. addr. bits 6+7 */
#define VGA_AC_CS_C45 0x03 /* Color reg. addr. bits 4+5 */
/* General registers. */
#define VGA_GEN_MISC_OUTPUT_W 0x02 /* Write only. */
#define VGA_GEN_MISC_OUTPUT_R 0x0c /* Read only. */
#define VGA_GEN_MO_VSP 0x80 /* Vertical sync. polarity */
#define VGA_GEN_MO_HSP 0x40 /* Horiz. sync. polarity */
#define VGA_GEN_MO_PB 0x20 /* Page bit for odd/even */
#define VGA_GEN_MO_CS 0x0C /* Clock select */
#define VGA_GEN_MO_ER 0x02 /* Enable RAM */
#define VGA_GEN_MO_IOA 0x01 /* Input/output address */
#define VGA_GEN_INPUT_STAT_0 0x02 /* Read only. */
#define VGA_GEN_FEATURE_CTRL_W 0x1a /* Write only. */
#define VGA_GEN_FEATURE_CTRL_R 0x0a /* Read only. */
#define VGA_GEN_INPUT_STAT_1 0x1a /* Read only. */
#define VGA_GEN_IS1_VR 0x08 /* Vertical retrace */
#define VGA_GEN_IS1_DE 0x01 /* Display enable not */
/* Sequencer registers. */
#define VGA_SEQ_ADDRESS 0x04
#define VGA_SEQ_RESET 0
#define VGA_SEQ_RST_SR 0x02 /* Synchronous reset */
#define VGA_SEQ_RST_NAR 0x01 /* No async. reset */
#define VGA_SEQ_CLOCKING_MODE 1
#define VGA_SEQ_CM_SO 0x20 /* Screen off */
#define VGA_SEQ_CM_S4 0x10 /* Shift four */
#define VGA_SEQ_CM_DC 0x08 /* Dot clock */
#define VGA_SEQ_CM_SL 0x04 /* Shift load */
#define VGA_SEQ_CM_89 0x01 /* 8/9 Dot clocks */
#define VGA_SEQ_MAP_MASK 2
#define VGA_SEQ_MM_EM3 0x08 /* Enable memory plane 3 */
#define VGA_SEQ_MM_EM2 0x04 /* Enable memory plane 2 */
#define VGA_SEQ_MM_EM1 0x02 /* Enable memory plane 1 */
#define VGA_SEQ_MM_EM0 0x01 /* Enable memory plane 0 */
#define VGA_SEQ_CHAR_MAP_SELECT 3
#define VGA_SEQ_CMS_SAH 0x20 /* Char. A (bit 2) */
#define VGA_SEQ_CMS_SBH 0x10 /* Char. B (bit 2) */
#define VGA_SEQ_CMS_SA 0x0C /* Char. A (bit 0+1) */
#define VGA_SEQ_CMS_SB 0x03 /* Char. B (bit 0+1) */
#define VGA_SEQ_MEMORY_MODE 4
#define VGA_SEQ_MM_C4 0x08 /* Chain four */
#define VGA_SEQ_MM_OE 0x04 /* Odd/even */
#define VGA_SEQ_MM_EM 0x02 /* Extended memory */
#define VGA_SEQ_DATA 0x05
/* Color registers. */
#define VGA_PEL_MASK 0x06
#define VGA_PEL_ADDR_RD_MODE 0x07 /* Write only. */
#define VGA_DAC_STATE 0x07 /* Read only. */
#define VGA_PEL_ADDR_WR_MODE 0x08
#define VGA_PEL_DATA 0x09
/* Graphics controller registers. */
#define VGA_GC_ADDRESS 0x0e
#define VGA_GC_SET_RESET 0
#define VGA_GC_ENABLE_SET_RESET 1
#define VGA_GC_COLOR_COMPARE 2
#define VGA_GC_DATA_ROTATE 3
#define VGA_GC_DR_FS_XOR 0x18 /* Function select - XOR */
#define VGA_GC_DR_FS_OR 0x10 /* Function select - OR */
#define VGA_GC_DR_FS_AND 0x08 /* Function select - AND */
#define VGA_GC_DR_RC 0x07 /* Rotate count */
#define VGA_GC_READ_MAP_SELECT 4
#define VGA_GC_MODE 5
#define VGA_GC_MODE_SR 0x60 /* Shift register */
#define VGA_GC_MODE_OE 0x10 /* Odd/even */
#define VGA_GC_MODE_RM 0x08 /* Read mode */
#define VGA_GC_MODE_WM 0x03 /* Write mode */
#define VGA_GC_MISCELLANEOUS 6
#define VGA_GC_MISC_MM 0x0C /* memory map */
#define VGA_GC_MISC_COE 0x02 /* Chain odd/even */
#define VGA_GC_MISC_GA 0x01 /* Graphics/text mode */
#define VGA_GC_COLOR_DONT_CARE 7
#define VGA_GC_BIT_MASK 8
#define VGA_GC_DATA 0x0f
/* CRT controller registers. */
#define VGA_CRTC_ADDRESS 0x14
#define VGA_CRTC_HORIZ_TOTAL 0
#define VGA_CRTC_HORIZ_DISP_END 1
#define VGA_CRTC_START_HORIZ_BLANK 2
#define VGA_CRTC_END_HORIZ_BLANK 3
#define VGA_CRTC_EHB_CR 0x80 /* Compatible read */
#define VGA_CRTC_EHB_DES 0x60 /* Display enable skew */
#define VGA_CRTC_EHB_EHB 0x1F /* End horizontal blank */
#define VGA_CRTC_START_HORIZ_RETRACE 4
#define VGA_CRTC_END_HORIZ_RETRACE 5
#define VGA_CRTC_EHR_EHB 0x80 /* End horizontal blanking */
#define VGA_CRTC_EHR_HRD 0x60 /* Horizontal retrace delay */
#define VGA_CRTC_EHR_EHR 0x1F /* End horizontal retrace */
#define VGA_CRTC_VERT_TOTAL 6
#define VGA_CRTC_OVERFLOW 7
#define VGA_CRTC_OF_VRS9 0x80 /* Vertical retrace start */
#define VGA_CRTC_OF_VDE9 0x40 /* Vertical disp. enable end */
#define VGA_CRTC_OF_VT9 0x20 /* Vertical total (bit 9) */
#define VGA_CRTC_OF_LC8 0x10 /* Line compare */
#define VGA_CRTC_OF_VBS8 0x08 /* Start vertical blanking */
#define VGA_CRTC_OF_VRS8 0x04 /* Vertical retrace start */
#define VGA_CRTC_OF_VDE8 0x02 /* Vertical disp. enable end */
#define VGA_CRTC_OF_VT8 0x01 /* Vertical total (bit 8) */
#define VGA_CRTC_PRESET_ROW_SCAN 8
#define VGA_CRTC_PRS_BP 0x60 /* Byte panning */
#define VGA_CRTC_PRS_PRS 0x1F /* Preset row scan */
#define VGA_CRTC_MAX_SCAN_LINE 9
#define VGA_CRTC_MSL_2T4 0x80 /* 200-to-400 line conversion */
#define VGA_CRTC_MSL_LC9 0x40 /* Line compare (bit 9) */
#define VGA_CRTC_MSL_VBS9 0x20 /* Start vertical blanking */
#define VGA_CRTC_MSL_MSL 0x1F /* Maximum scan line */
#define VGA_CRTC_CURSOR_START 10
#define VGA_CRTC_CS_COO 0x20 /* Cursor on/off */
#define VGA_CRTC_CS_CS 0x1F /* Cursor start */
#define VGA_CRTC_CURSOR_END 11
#define VGA_CRTC_CE_CSK 0x60 /* Cursor skew */
#define VGA_CRTC_CE_CE 0x1F /* Cursor end */
#define VGA_CRTC_START_ADDR_HIGH 12
#define VGA_CRTC_START_ADDR_LOW 13
#define VGA_CRTC_CURSOR_LOC_HIGH 14
#define VGA_CRTC_CURSOR_LOC_LOW 15
#define VGA_CRTC_VERT_RETRACE_START 16
#define VGA_CRTC_VERT_RETRACE_END 17
#define VGA_CRTC_VRE_PR 0x80 /* Protect register 0-7 */
#define VGA_CRTC_VRE_BW 0x40 /* Bandwidth */
#define VGA_CRTC_VRE_VRE 0x1F /* Vertical retrace end */
#define VGA_CRTC_VERT_DISPLAY_END 18
#define VGA_CRTC_OFFSET 19
#define VGA_CRTC_UNDERLINE_LOC 20
#define VGA_CRTC_UL_DW 0x40 /* Double word mode */
#define VGA_CRTC_UL_CB4 0x20 /* Count by four */
#define VGA_CRTC_UL_UL 0x1F /* Underline location */
#define VGA_CRTC_START_VERT_BLANK 21
#define VGA_CRTC_END_VERT_BLANK 22
#define VGA_CRTC_MODE_CONTROL 23
#define VGA_CRTC_MC_HR 0x80 /* hardware reset */
#define VGA_CRTC_MC_WB 0x40 /* Word/byte mode */
#define VGA_CRTC_MC_AW 0x20 /* Address wrap */
#define VGA_CRTC_MC_CBT 0x08 /* Count by two */
#define VGA_CRTC_MC_HRS 0x04 /* Horizontal retrace select */
#define VGA_CRTC_MC_SRS 0x02 /* Select row scan counter */
#define VGA_CRTC_MC_CMS 0x01 /* Compatibility mode support */
#define VGA_CRTC_LINE_COMPARE 24
#define VGA_CRTC_DATA 0x15
#endif /* !_DEV_VT_HW_VGA_VGA_REG_H_ */

View File

@ -0,0 +1,197 @@
/*-
* Copyright (c) 2005 Rink Springer
* All rights reserved.
*
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Ed Schouten
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <dev/vt/vt.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/xbox.h>
struct xbox_softc {
bus_space_tag_t xbox_fb_tag;
bus_space_handle_t xbox_fb_handle;
};
/* Convenience macros. */
#define MEM_WRITE4(sc, ofs, val) \
bus_space_write_4(sc->xbox_fb_tag, sc->xbox_fb_handle, ofs, val)
#define VT_XBOX_WIDTH 640
#define VT_XBOX_HEIGHT 480
static vd_init_t xbox_init;
static vd_blank_t xbox_blank;
static vd_bitblt_t xbox_bitblt;
static const struct vt_driver vt_xbox_driver = {
.vd_init = xbox_init,
.vd_blank = xbox_blank,
.vd_bitblt = xbox_bitblt,
};
static struct xbox_softc xbox_conssoftc;
VT_CONSDEV_DECLARE(vt_xbox_driver, PIXEL_WIDTH(VT_XBOX_WIDTH),
PIXEL_HEIGHT(VT_XBOX_HEIGHT), &xbox_conssoftc);
static const uint32_t colormap[] = {
0x00000000, /* Black */
0x00ff0000, /* Red */
0x0000ff00, /* Green */
0x00c0c000, /* Brown */
0x000000ff, /* Blue */
0x00c000c0, /* Magenta */
0x0000c0c0, /* Cyan */
0x00c0c0c0, /* Light grey */
0x00808080, /* Dark grey */
0x00ff8080, /* Light red */
0x0080ff80, /* Light green */
0x00ffff80, /* Yellow */
0x008080ff, /* Light blue */
0x00ff80ff, /* Light magenta */
0x0080ffff, /* Light cyan */
0x00ffffff, /* White */
};
static void
xbox_blank(struct vt_device *vd, term_color_t color)
{
struct xbox_softc *sc = vd->vd_softc;
u_int ofs;
uint32_t c;
c = colormap[color];
for (ofs = 0; ofs < (VT_XBOX_WIDTH * VT_XBOX_HEIGHT) * 4; ofs += 4)
MEM_WRITE4(sc, ofs, c);
}
static void
xbox_bitblt(struct vt_device *vd, const uint8_t *src,
vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
term_color_t fg, term_color_t bg)
{
struct xbox_softc *sc = vd->vd_softc;
u_long line;
uint32_t fgc, bgc;
int c;
uint8_t b = 0;
fgc = colormap[fg];
bgc = colormap[bg];
line = (VT_XBOX_WIDTH * top + left) * 4;
for (; height > 0; height--) {
line += VT_XBOX_WIDTH * 4;
for (c = 0; c < width; c++) {
if (c % 8 == 0)
b = *src++;
else
b <<= 1;
MEM_WRITE4(sc, line + c * 4, b & 0x80 ? fgc : bgc);
}
}
}
static void
xbox_initialize(struct vt_device *vd)
{
int i;
/*
* We must make a mapping from video framebuffer memory
* to real. This is very crude: we map the entire
* videomemory to PAGE_SIZE! Since our kernel lives at
* it's relocated address range (0xc0xxxxxx), it won't
* care.
*
* We use address PAGE_SIZE and up so we can still trap
* NULL pointers. Once the real init is called, the
* mapping will be done via the OS and stored in a more
* sensible location ... but since we're not fully
* initialized, this is our only way to go :-(
*/
for (i = 0; i < (XBOX_FB_SIZE / PAGE_SIZE); i++) {
pmap_kenter(((i + 1) * PAGE_SIZE),
XBOX_FB_START + (i * PAGE_SIZE));
}
pmap_kenter((i + 1) * PAGE_SIZE,
XBOX_FB_START_PTR - XBOX_FB_START_PTR % PAGE_SIZE);
/* Ensure the framebuffer is where we want it to be. */
*(uint32_t *)((i + 1) * PAGE_SIZE + XBOX_FB_START_PTR % PAGE_SIZE) =
XBOX_FB_START;
/* Clear the screen. */
xbox_blank(vd, TC_BLACK);
}
static int
xbox_init(struct vt_device *vd)
{
struct xbox_softc *sc = vd->vd_softc;
if (!arch_i386_is_xbox)
return (CN_DEAD);
sc->xbox_fb_tag = I386_BUS_SPACE_MEM;
sc->xbox_fb_handle = PAGE_SIZE;
vd->vd_width = VT_XBOX_WIDTH;
vd->vd_height = VT_XBOX_HEIGHT;
xbox_initialize(vd);
return (CN_INTERNAL);
}
static void
xbox_remap(void *unused)
{
if (!arch_i386_is_xbox)
return;
xbox_conssoftc.xbox_fb_handle =
(bus_space_handle_t)pmap_mapdev(XBOX_FB_START, XBOX_FB_SIZE);
}
SYSINIT(xboxfb, SI_SUB_DRIVERS, SI_ORDER_ANY, xbox_remap, NULL);

View File

@ -0,0 +1,641 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
unsigned int vt_logo_width = 257;
unsigned int vt_logo_height = 219;
unsigned int vt_logo_depth = 1;
unsigned char vt_logo_image[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff,
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff,
0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x07,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff,
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1f, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff,
0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f,
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x81, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf0, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff,
0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x07, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x83, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xc7, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0x7f, 0xff, 0xff, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f,
0xff, 0xff, 0xf3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xe3,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xc7, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1,
0xff, 0xff, 0x8f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0x0f,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0x07, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x0f, 0xfe, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x01, 0xf8, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x07, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfc, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f,
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x07,
0xff, 0xf0, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xfe, 0x00,
0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff,
0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x1f,
0xf8, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x03, 0xfc, 0x00, 0xff,
0xe0, 0xff, 0xc0, 0x1f, 0x80, 0x0f, 0xfc, 0x00, 0x00, 0x3f, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x1f, 0xc0,
0x1f, 0x00, 0x01, 0xff, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x7e, 0x01, 0xfc, 0x00, 0x07, 0x80, 0x3e, 0x00, 0x00,
0x7f, 0x80, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
0x3f, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1f, 0xc0, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x3f, 0x03, 0xf0,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00,
0x3e, 0x00, 0x00, 0x07, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfc, 0x00, 0x00, 0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
0x03, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0xf8, 0x00,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0x03, 0xe0,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00,
0x00, 0x07, 0xfc, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xc0, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00,
0x3e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff,
0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00,
0xf8, 0x00, 0x00, 0x1f, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x7e, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f,
0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0xf8, 0x00, 0x00,
0x3f, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00,
0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0xf8, 0x00, 0x00, 0x3f, 0x03, 0xf8,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xfc, 0x00, 0x00,
0x01, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff,
0xff, 0xc0, 0x00, 0xf8, 0x00, 0x00, 0x7e, 0x01, 0xfc, 0x00, 0x00, 0x00,
0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00, 0x03, 0xfc, 0x07,
0xf8, 0x07, 0xfe, 0x03, 0xff, 0x00, 0x00, 0xff, 0xc0, 0x3f, 0xe0, 0x00,
0xfc, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00, 0x07, 0xf0, 0x01, 0xf8, 0x0f, 0xf0,
0x00, 0x7f, 0x80, 0x01, 0xfe, 0x00, 0x0f, 0xf0, 0x00, 0xfc, 0x00, 0x01,
0xfc, 0x00, 0xff, 0x80, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00,
0xfc, 0x00, 0x00, 0x07, 0xe0, 0x00, 0xf8, 0x1f, 0xc0, 0x00, 0x3f, 0xc0,
0x03, 0xfc, 0x00, 0x03, 0xf8, 0x00, 0xfe, 0x00, 0x0f, 0xfc, 0x00, 0x7f,
0xe0, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xfe, 0x00, 0x00,
0x0f, 0xc0, 0x00, 0x78, 0x1f, 0x80, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00,
0x01, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xf0, 0x00, 0x00,
0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xff, 0x00, 0x00, 0x0f, 0x80, 0x00,
0x00, 0x3f, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0xfc, 0x00,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x0f, 0x80, 0xff, 0xff, 0xfc, 0x0f, 0x80, 0x00, 0x00, 0x7e, 0x00,
0x00, 0x03, 0xf0, 0x07, 0xe0, 0x00, 0x00, 0x7e, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x07, 0xff, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80,
0xff, 0xff, 0xfc, 0x1f, 0x80, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x03, 0xf0,
0x0f, 0xc0, 0x00, 0x00, 0x7e, 0x00, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01,
0xff, 0xc0, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xff, 0xff, 0xfe,
0x1f, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00,
0x00, 0x3e, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xf0, 0x00,
0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xff, 0xff, 0xfc, 0x1f, 0x00, 0x00,
0x00, 0xfc, 0x00, 0x00, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x00, 0x1f, 0x00,
0xfc, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0xfc, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x0f, 0x80, 0xff, 0xff, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x00,
0x00, 0x00, 0xf8, 0x1f, 0x80, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00,
0x07, 0xf0, 0x00, 0x07, 0xff, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80,
0xfe, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x01, 0xf8,
0x1f, 0x80, 0x00, 0x00, 0x1f, 0x00, 0xf8, 0x00, 0x00, 0x03, 0xf8, 0x00,
0x01, 0xff, 0x80, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xfc, 0x00, 0x00,
0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff,
0xff, 0xff, 0x80, 0xf8, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x7f, 0xc0,
0x3e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80,
0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0xe0, 0x3e, 0x00, 0x00,
0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0xf8, 0x00, 0x00,
0x00, 0xfc, 0x00, 0x00, 0x0f, 0xf0, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00,
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf8,
0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00,
0x00, 0x03, 0xf8, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00,
0x1f, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff,
0xff, 0xff, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x01, 0xf8,
0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x00,
0xf8, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00,
0x00, 0x3e, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xfc, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x00, 0x7c, 0x00,
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7e, 0x00,
0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0x00,
0x1f, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00,
0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc,
0x3e, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00,
0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00,
0x01, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7e, 0x00,
0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
0x00, 0x7c, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x03, 0xf0, 0x00,
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00,
0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x07, 0xe0, 0x00, 0xfc, 0x00, 0x00,
0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00,
0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x01, 0xfc,
0x3e, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
0x00, 0x1f, 0x80, 0x00, 0x0c, 0x00, 0x03, 0xf0, 0x00, 0x01, 0x80, 0x00,
0xf8, 0x00, 0x00, 0x01, 0xf8, 0x70, 0x00, 0x03, 0xf8, 0x3e, 0x00, 0x00,
0x1f, 0xc0, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0xc0,
0x00, 0x3e, 0x00, 0x03, 0xfc, 0x00, 0x03, 0xc0, 0x00, 0xf8, 0x00, 0x00,
0x03, 0xf8, 0xfc, 0x00, 0x07, 0xf8, 0x3f, 0x00, 0x00, 0x7f, 0x80, 0x00,
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x7e, 0x00,
0x01, 0xfe, 0x00, 0x0f, 0xe0, 0x00, 0xf8, 0x00, 0x00, 0x07, 0xf0, 0xff,
0x80, 0x0f, 0xf0, 0x3f, 0x00, 0x01, 0xff, 0x00, 0x00, 0xfc, 0x00, 0x00,
0x1f, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x03, 0xfe, 0x00, 0x00, 0xff, 0xc0,
0x3f, 0xc0, 0x00, 0xf8, 0x00, 0x00, 0x3f, 0xe0, 0xff, 0xf8, 0x7f, 0xe0,
0x3f, 0x80, 0x1f, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
0x00, 0x03, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00,
0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff,
0xf8, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0xff,
0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff,
0xff, 0x80, 0x7f, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x00,
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00,
0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f,
0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x00,
0x1f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff,
0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xfc, 0x00,
0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x00,
0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00,
0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
};

View File

@ -0,0 +1,6 @@
PROG= fontcvt
MAN1=
WARNS?= 6
.include <bsd.prog.mk>

View File

@ -0,0 +1,385 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static unsigned int width, wbytes, height;
struct glyph {
TAILQ_ENTRY(glyph) g_list;
uint8_t *g_data;
unsigned int g_index;
};
static TAILQ_HEAD(, glyph) glyph_list = TAILQ_HEAD_INITIALIZER(glyph_list);
static unsigned int glyph_total, glyph_normal, glyph_bold,
glyph_unique, glyph_dupe;
struct mapping {
TAILQ_ENTRY(mapping) m_list;
unsigned int m_char;
unsigned int m_length;
struct glyph *m_glyph;
};
TAILQ_HEAD(mapping_list, mapping);
static struct mapping_list mapping_list_normal =
TAILQ_HEAD_INITIALIZER(mapping_list_normal);
static struct mapping_list mapping_list_bold =
TAILQ_HEAD_INITIALIZER(mapping_list_bold);
static unsigned int mapping_total, mapping_normal, mapping_normal_folded,
mapping_bold, mapping_bold_folded, mapping_unique, mapping_dupe;
static void
usage(void)
{
fprintf(stderr,
"usage: fontcvt width height normal.bdf bold.bdf out.fnt\n");
exit(1);
}
static int
add_mapping(struct glyph *gl, unsigned int c, int bold)
{
struct mapping *mp;
struct mapping_list *ml;
mapping_total++;
if (bold) {
int found = 0;
TAILQ_FOREACH(mp, &mapping_list_normal, m_list) {
if (mp->m_char < c)
continue;
else if (mp->m_char > c)
break;
found = 1;
/*
* No mapping is needed if it's equal to the
* normal mapping.
*/
if (mp->m_glyph == gl) {
mapping_dupe++;
return (0);
}
}
if (!found) {
fprintf(stderr,
"Character %u not in normal font!\n", c);
return (1);
}
}
mp = malloc(sizeof *mp);
mp->m_char = c;
mp->m_glyph = gl;
mp->m_length = 0;
ml = bold ? &mapping_list_bold : &mapping_list_normal;
if (TAILQ_LAST(ml, mapping_list) != NULL &&
TAILQ_LAST(ml, mapping_list)->m_char >= c) {
fprintf(stderr, "Bad ordering at character %u\n", c);
return (1);
}
TAILQ_INSERT_TAIL(ml, mp, m_list);
if (bold)
mapping_bold++;
else
mapping_normal++;
mapping_unique++;
return (0);
}
static struct glyph *
add_glyph(const uint8_t *bytes, int bold, int fallback)
{
struct glyph *gl;
glyph_total++;
if (bold)
glyph_bold++;
else
glyph_normal++;
TAILQ_FOREACH(gl, &glyph_list, g_list) {
if (memcmp(gl->g_data, bytes, wbytes * height) == 0) {
glyph_dupe++;
return (gl);
}
}
gl = malloc(sizeof *gl);
gl->g_data = malloc(wbytes * height);
memcpy(gl->g_data, bytes, wbytes * height);
if (fallback)
TAILQ_INSERT_HEAD(&glyph_list, gl, g_list);
else
TAILQ_INSERT_TAIL(&glyph_list, gl, g_list);
glyph_unique++;
return (gl);
}
static int
parse_bdf(const char *filename, int bold __unused)
{
FILE *fp;
char *ln;
size_t length;
uint8_t bytes[wbytes * height];
unsigned int curchar = 0, i, line;
struct glyph *gl;
fp = fopen(filename, "r");
if (fp == NULL) {
perror(filename);
return (1);
}
while ((ln = fgetln(fp, &length)) != NULL) {
ln[length - 1] = '\0';
if (strncmp(ln, "ENCODING ", 9) == 0) {
curchar = atoi(ln + 9);
}
if (strcmp(ln, "BITMAP") == 0) {
for (i = 0; i < height; i++) {
if ((ln = fgetln(fp, &length)) == NULL) {
fprintf(stderr, "Unexpected EOF!\n");
return (1);
}
ln[length - 1] = '\0';
sscanf(ln, "%x", &line);
if (wbytes == 1) {
bytes[i] = line;
} else if (wbytes == 2) {
bytes[i * 2 + 0] = line >> 8;
bytes[i * 2 + 1] = line;
} else {
fprintf(stderr,
"Unsupported wbytes!\n");
return (1);
}
}
/* Prevent adding two glyphs for 0xFFFD */
if (curchar == 0xFFFD) {
if (!bold)
gl = add_glyph(bytes, bold, 1);
} else if (curchar >= 0x20) {
gl = add_glyph(bytes, bold, 0);
if (add_mapping(gl, curchar, bold) != 0)
return (1);
}
}
}
return (0);
}
static void
number_glyphs(void)
{
struct glyph *gl;
unsigned int idx = 0;
TAILQ_FOREACH(gl, &glyph_list, g_list)
gl->g_index = idx++;
}
static void
write_glyphs(FILE *fp)
{
struct glyph *gl;
TAILQ_FOREACH(gl, &glyph_list, g_list)
fwrite(gl->g_data, wbytes * height, 1, fp);
}
static void
fold_mappings(int bold)
{
struct mapping_list *ml;
struct mapping *mn, *mp, *mbase;
if (bold)
ml = &mapping_list_bold;
else
ml = &mapping_list_normal;
mp = mbase = TAILQ_FIRST(ml);
for (mp = mbase = TAILQ_FIRST(ml); mp != NULL; mp = mn) {
mn = TAILQ_NEXT(mp, m_list);
if (mn != NULL && mn->m_char == mp->m_char + 1 &&
mn->m_glyph->g_index == mp->m_glyph->g_index + 1)
continue;
mbase->m_length = mp->m_char - mbase->m_char + 1;
mbase = mp = mn;
if (bold)
mapping_bold_folded++;
else
mapping_normal_folded++;
}
}
struct file_mapping {
uint32_t source;
uint16_t destination;
uint16_t length;
} __packed;
static void
write_mappings(FILE *fp, int bold)
{
struct mapping_list *ml;
struct mapping *mp;
struct file_mapping fm;
unsigned int i = 0, j = 0;
if (bold)
ml = &mapping_list_bold;
else
ml = &mapping_list_normal;
TAILQ_FOREACH(mp, ml, m_list) {
j++;
if (mp->m_length > 0) {
i += mp->m_length;
fm.source = htobe32(mp->m_char);
fm.destination = htobe16(mp->m_glyph->g_index);
fm.length = htobe16(mp->m_length - 1);
fwrite(&fm, sizeof fm, 1, fp);
}
}
assert(i == j);
}
struct file_header {
uint8_t magic[8];
uint8_t width;
uint8_t height;
uint16_t nglyphs;
uint16_t nmappings_normal;
uint16_t nmappings_bold;
} __packed;
static int
write_fnt(const char *filename)
{
FILE *fp;
struct file_header fh = {
.magic = "VFNT 1.0",
};
fp = fopen(filename, "wb");
if (fp == NULL) {
perror(filename);
return (1);
}
fh.width = width;
fh.height = height;
fh.nglyphs = htobe16(glyph_unique);
fh.nmappings_normal = htobe16(mapping_normal_folded);
fh.nmappings_bold = htobe16(mapping_bold_folded);
fwrite(&fh, sizeof fh, 1, fp);
write_glyphs(fp);
write_mappings(fp, 0);
write_mappings(fp, 1);
return (0);
}
int
main(int argc, char *argv[])
{
assert(sizeof(struct file_header) == 16);
assert(sizeof(struct file_mapping) == 8);
if (argc != 6)
usage();
width = atoi(argv[1]);
wbytes = howmany(width, 8);
height = atoi(argv[2]);
if (parse_bdf(argv[3], 0) != 0)
return (1);
if (parse_bdf(argv[4], 1) != 0)
return (1);
number_glyphs();
fold_mappings(0);
fold_mappings(1);
if (write_fnt(argv[5]) != 0)
return (1);
printf(
"Statistics:\n"
"- glyph_total: %5u\n"
"- glyph_normal: %5u\n"
"- glyph_bold: %5u\n"
"- glyph_unique: %5u\n"
"- glyph_dupe: %5u\n"
"- mapping_total: %5u\n"
"- mapping_normal: %5u\n"
"- mapping_normal_folded: %5u\n"
"- mapping_bold: %5u\n"
"- mapping_bold_folded: %5u\n"
"- mapping_unique: %5u\n"
"- mapping_dupe: %5u\n",
glyph_total,
glyph_normal, glyph_bold,
glyph_unique, glyph_dupe,
mapping_total,
mapping_normal, mapping_normal_folded,
mapping_bold, mapping_bold_folded,
mapping_unique, mapping_dupe);
return (0);
}

View File

@ -0,0 +1,12 @@
#!/bin/sh
for i in 6:12 8:14 8:16 10:20 11:22 12:24 14:28 16:32
do
C=`echo $i | cut -f 1 -d :`
R=`echo $i | cut -f 2 -d :`
./fontcvt \
$C $R \
~/terminus-font-4.30/ter-u${R}n.bdf \
~/terminus-font-4.30/ter-u${R}b.bdf \
terminus-u${R}.vfnt
gzip -9nf terminus-u${R}.vfnt
done

View File

@ -0,0 +1,6 @@
PROG= mkkfont
MAN1=
WARNS?= 6
.include <bsd.prog.mk>

View File

@ -0,0 +1,181 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/param.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct file_mapping {
uint32_t source;
uint16_t destination;
uint16_t length;
} __packed;
struct file_header {
uint8_t magic[8];
uint8_t width;
uint8_t height;
uint16_t nglyphs;
uint16_t nmappings_normal;
uint16_t nmappings_bold;
} __packed;
static int
print_glyphs(struct file_header *fh)
{
unsigned int gbytes, nglyphs, j, k, total;
uint8_t *gbuf;
gbytes = howmany(fh->width, 8) * fh->height;
nglyphs = be16toh(fh->nglyphs);
printf("\nstatic uint8_t font_bytes[%u * %u] = {", nglyphs, gbytes);
total = nglyphs * gbytes;
gbuf = malloc(total);
if (fread(gbuf, total, 1, stdin) != 1) {
perror("glyph");
return (1);
}
for (j = 0; j < total; j += 12) {
for (k = 0; k < 12 && k < total - j; k++) {
printf(k == 0 ? "\n\t" : " ");
printf("0x%02hhx,", gbuf[j + k]);
}
}
free(gbuf);
printf("\n};\n");
return (0);
}
static int
print_mappings(struct file_header *fh, int bold)
{
struct file_mapping fm;
const char *name;
unsigned int nmappings, i, col = 0;
if (bold) {
nmappings = be16toh(fh->nmappings_bold);
name = "bold";
} else {
nmappings = be16toh(fh->nmappings_normal);
name = "normal";
}
if (nmappings == 0)
return (0);
printf("\nstatic struct vt_font_map font_mapping_%s[%u] = {",
name, nmappings);
for (i = 0; i < nmappings; i++) {
if (fread(&fm, sizeof fm, 1, stdin) != 1) {
perror("mapping");
return (1);
}
printf(col == 0 ? "\n\t" : " ");
printf("{ 0x%04x, 0x%04x, 0x%02x },",
be32toh(fm.source), be16toh(fm.destination),
be16toh(fm.length));
col = (col + 1) % 2;
}
printf("\n};\n");
return (0);
}
static int
print_info(struct file_header *fh)
{
unsigned int nnormal, nbold;
printf(
"\nstruct vt_font vt_font_default = {\n"
"\t.vf_width\t\t= %u,\n"
"\t.vf_height\t\t= %u,\n"
"\t.vf_bytes\t\t= font_bytes,\n",
fh->width, fh->height);
nnormal = be16toh(fh->nmappings_normal);
nbold = be16toh(fh->nmappings_bold);
if (nnormal != 0)
printf(
"\t.vf_normal\t\t= font_mapping_normal,\n"
"\t.vf_normal_length\t= %u,\n", nnormal);
if (nbold != 0)
printf(
"\t.vf_bold\t\t= font_mapping_bold,\n"
"\t.vf_bold_length\t\t= %u,\n", nbold);
printf("\t.vf_refcount\t\t= 1,\n};\n");
return (0);
}
int
main(int argc __unused, char *argv[] __unused)
{
struct file_header fh;
if (fread(&fh, sizeof fh, 1, stdin) != 1) {
perror("file_header");
return (1);
}
if (memcmp(fh.magic, "VFNT 1.0", 8) != 0) {
fprintf(stderr, "Bad magic\n");
return (1);
}
printf("#include <dev/vt/vt.h>\n");
if (print_glyphs(&fh) != 0)
return (1);
if (print_mappings(&fh, 0) != 0)
return (1);
if (print_mappings(&fh, 1) != 0)
return (1);
if (print_info(&fh) != 0)
return (1);
return (0);
}

View File

@ -0,0 +1,5 @@
#!/bin/sh
for i in 12 14 16 20 22 24 28 32
do
zcat ../fontcvt/terminus-u${i}.vfnt.gz | ./mkkfont > terminus-u${i}.c
done

View File

@ -0,0 +1,6 @@
PROG= setfont
MAN1=
WARNS?= 6
.include <bsd.prog.mk>

View File

@ -0,0 +1,85 @@
#include <sys/consio.h>
#include <sys/endian.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
struct file_header {
uint8_t magic[8];
uint8_t width;
uint8_t height;
uint16_t nglyphs;
uint16_t nmappings_normal;
uint16_t nmappings_bold;
} __packed;
static vfnt_map_t *
load_mappingtable(unsigned int nmappings)
{
vfnt_map_t *t;
unsigned int i;
if (nmappings == 0)
return (NULL);
t = malloc(sizeof *t * nmappings);
if (fread(t, sizeof *t * nmappings, 1, stdin) != 1) {
perror("mappings");
exit(1);
}
for (i = 0; i < nmappings; i++) {
t[i].src = be32toh(t[i].src);
t[i].dst = be16toh(t[i].dst);
t[i].len = be16toh(t[i].len);
}
return (t);
}
int
main(int argc __unused, char *argv[] __unused)
{
struct file_header fh;
static vfnt_t vfnt;
size_t glyphsize;
if (fread(&fh, sizeof fh, 1, stdin) != 1) {
perror("file_header");
return (1);
}
if (memcmp(fh.magic, "VFNT 1.0", 8) != 0) {
fprintf(stderr, "Bad magic\n");
return (1);
}
vfnt.nnormal = be16toh(fh.nmappings_normal);
vfnt.nbold = be16toh(fh.nmappings_bold);
vfnt.nglyphs = be16toh(fh.nglyphs);
vfnt.width = fh.width;
vfnt.height = fh.height;
glyphsize = howmany(vfnt.width, 8) * vfnt.height * vfnt.nglyphs;
vfnt.glyphs = malloc(glyphsize);
if (fread(vfnt.glyphs, glyphsize, 1, stdin) != 1) {
perror("glyphs");
return (1);
}
vfnt.normal = load_mappingtable(vfnt.nnormal);
vfnt.bold = load_mappingtable(vfnt.nbold);
if (ioctl(STDOUT_FILENO, PIO_VFONT, &vfnt) == -1) {
perror("PIO_VFONT");
return (1);
}
return (0);
}

279
sys/dev/vt/vt.h Normal file
View File

@ -0,0 +1,279 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _DEV_VT_VT_H_
#define _DEV_VT_VT_H_
#include <sys/param.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/callout.h>
#include <sys/condvar.h>
#include <sys/consio.h>
#include <sys/kbio.h>
#include <sys/terminal.h>
#define VT_MAXWINDOWS 12
#define VT_CONSWINDOW 0
struct vt_driver;
void vt_allocate(struct vt_driver *, void *);
typedef unsigned int vt_axis_t;
/*
* List of locks
* (d) locked by vd_lock
* (b) locked by vb_lock
* (G) locked by Giant
* (u) unlocked, locked by higher levels
* (c) const until freeing
* (?) yet to be determined
*/
/*
* Per-device datastructure.
*/
struct vt_device {
struct vt_window *vd_windows[VT_MAXWINDOWS]; /* (c) Windows. */
struct vt_window *vd_curwindow; /* (d) Current window. */
const struct vt_driver *vd_driver; /* (c) Graphics driver. */
void *vd_softc; /* (u) Driver data. */
vt_axis_t vd_width; /* (?) Screen width. */
vt_axis_t vd_height; /* (?) Screen height. */
struct mtx vd_lock; /* Per-device lock. */
struct cv vd_winswitch; /* (d) Window switch notify. */
struct callout vd_timer; /* (d) Display timer. */
int vd_flags; /* (d) Device flags. */
#define VDF_TEXTMODE 0x01 /* Do text mode rendering. */
#define VDF_SPLASH 0x02 /* Splash screen active. */
#define VDF_ASYNC 0x04 /* vt_timer() running. */
#define VDF_INVALID 0x08 /* Entire screen should be re-rendered. */
#define VDF_DEAD 0x10 /* Early probing found nothing. */
int vd_keyboard; /* (G) Keyboard index. */
unsigned int vd_unit; /* (c) Device unit. */
/* XXX: HACK */
unsigned int vd_scrollpos; /* (d) Last scroll position. */
};
/*
* Per-window terminal screen buffer.
*
* Because redrawing is performed asynchronously, the buffer keeps track
* of a rectangle that needs to be redrawn (vb_dirtyrect). Because this
* approach seemed to cause suboptimal performance (when the top left
* and the bottom right of the screen are modified), it also uses a set
* of bitmasks to keep track of the rows and columns (mod 64) that have
* been modified.
*/
struct vt_bufmask {
uint64_t vbm_row, vbm_col;
#define VBM_DIRTY UINT64_MAX
};
struct vt_buf {
struct mtx vb_lock; /* Buffer lock. */
term_pos_t vb_size; /* (b) Screen dimensions. */
int vb_flags; /* (b) Flags. */
#define VBF_CURSOR 0x1 /* Cursor visible. */
#define VBF_STATIC 0x2 /* Buffer is statically allocated. */
term_pos_t vb_cursor; /* (u) Cursor position. */
term_rect_t vb_dirtyrect; /* (b) Dirty rectangle. */
struct vt_bufmask vb_dirtymask; /* (b) Dirty bitmasks. */
term_char_t *vb_buffer; /* (u) Data buffer. */
};
void vtbuf_copy(struct vt_buf *, const term_rect_t *, const term_pos_t *);
void vtbuf_fill(struct vt_buf *, const term_rect_t *, term_char_t);
void vtbuf_init_early(struct vt_buf *);
void vtbuf_init(struct vt_buf *, const term_pos_t *);
void vtbuf_grow(struct vt_buf *, const term_pos_t *);
void vtbuf_putchar(struct vt_buf *, const term_pos_t *, term_char_t);
void vtbuf_cursor_position(struct vt_buf *, const term_pos_t *);
void vtbuf_cursor_visibility(struct vt_buf *, int);
void vtbuf_undirty(struct vt_buf *, term_rect_t *, struct vt_bufmask *);
#define VTBUF_FIELD(vb, r, c) \
(vb)->vb_buffer[(r) * (vb)->vb_size.tp_col + (c)]
#define VTBUF_ISCURSOR(vb, r, c) \
((vb)->vb_flags & VBF_CURSOR && \
(vb)->vb_cursor.tp_row == (r) && (vb)->vb_cursor.tp_col == (c))
#define VTBUF_DIRTYROW(mask, row) \
((mask)->vbm_row & ((uint64_t)1 << ((row) % 64)))
#define VTBUF_DIRTYCOL(mask, col) \
((mask)->vbm_col & ((uint64_t)1 << ((col) % 64)))
/*
* Per-window history tracking.
*
* XXX: Unimplemented!
*/
struct vt_history {
unsigned int vh_offset;
};
void vthistory_add(struct vt_history *vh, struct vt_buf *vb,
const term_rect_t *r);
#define VHS_SET 0
#define VHS_CUR 1
#define VHS_END 2
void vthistory_seek(struct vt_history *vh, int offset, int whence);
void vthistory_getpos(const struct vt_history *vh, unsigned int *offset);
#define VTHISTORY_FIELD(vh, r, c) \
('?' | (TF_BOLD|TF_REVERSE) << 22 | TC_GREEN << 26 | TC_BLACK << 29)
/*
* Per-window datastructure.
*/
struct vt_window {
struct vt_device *vw_device; /* (c) Device. */
struct terminal *vw_terminal; /* (c) Terminal. */
struct vt_buf vw_buf; /* (u) Screen buffer. */
struct vt_history vw_history; /* (?) History buffer. */
struct vt_font *vw_font; /* (d) Graphical font. */
unsigned int vw_number; /* (c) Window number. */
int vw_kbdmode; /* (?) Keyboard mode. */
unsigned int vw_flags; /* (d) Per-window flags. */
#define VWF_BUSY 0x1 /* Busy reconfiguring device. */
#define VWF_OPENED 0x2 /* TTY in use. */
#define VWF_SCROLL 0x4 /* Keys influence scrollback. */
#define VWF_CONSOLE 0x8 /* Kernel message console window. */
};
/*
* Per-device driver routines.
*
* vd_bitblt is used when the driver operates in graphics mode, while
* vd_putchar is used when the driver operates in text mode
* (VDF_TEXTMODE).
*/
typedef int vd_init_t(struct vt_device *vd);
typedef void vd_blank_t(struct vt_device *vd, term_color_t color);
typedef void vd_bitblt_t(struct vt_device *vd, const uint8_t *src,
vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
term_color_t fg, term_color_t bg);
typedef void vd_putchar_t(struct vt_device *vd, term_char_t,
vt_axis_t top, vt_axis_t left, term_color_t fg, term_color_t bg);
struct vt_driver {
/* Console attachment. */
vd_init_t *vd_init;
/* Drawing. */
vd_blank_t *vd_blank;
vd_bitblt_t *vd_bitblt;
/* Text mode operation. */
vd_putchar_t *vd_putchar;
};
/*
* Console device madness.
*
* Utility macro to make early vt(4) instances work.
*/
extern const struct terminal_class vt_termclass;
void vt_upgrade(struct vt_device *vd);
#define PIXEL_WIDTH(w) ((w) / 8)
#define PIXEL_HEIGHT(h) ((h) / 16)
#define VT_CONSDEV_DECLARE(driver, width, height, softc) \
static struct terminal driver ## _consterm; \
static struct vt_window driver ## _conswindow; \
static struct vt_device driver ## _consdev = { \
.vd_driver = &driver, \
.vd_softc = (softc), \
.vd_flags = VDF_INVALID, \
.vd_windows = { [VT_CONSWINDOW] = &driver ## _conswindow, }, \
.vd_curwindow = &driver ## _conswindow, \
}; \
static term_char_t driver ## _constextbuf[(width) * (height)]; \
static struct vt_window driver ## _conswindow = { \
.vw_number = VT_CONSWINDOW, \
.vw_flags = VWF_CONSOLE, \
.vw_buf = { \
.vb_buffer = driver ## _constextbuf, \
.vb_flags = VBF_STATIC, \
.vb_size = { \
.tp_row = height, \
.tp_col = width, \
}, \
}, \
.vw_device = &driver ## _consdev, \
.vw_terminal = &driver ## _consterm, \
.vw_kbdmode = K_XLATE, \
}; \
TERMINAL_DECLARE_EARLY(driver ## _consterm, vt_termclass, \
&driver ## _conswindow); \
SYSINIT(vt_early_cons, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, \
vt_upgrade, &driver ## _consdev)
/*
* Fonts.
*
* Remapping tables are used to map Unicode points to glyphs. They need
* to be sorted, because vtfont_lookup() performs a binary search. Each
* font has two remapping tables, for normal and bold. When a character
* is not present in bold, it uses a normal glyph. When no glyph is
* available, it uses glyph 0, which is normally equal to U+FFFD.
*/
struct vt_font_map {
uint32_t vfm_src;
uint16_t vfm_dst;
uint16_t vfm_len;
};
struct vt_font {
struct vt_font_map *vf_bold;
struct vt_font_map *vf_normal;
uint8_t *vf_bytes;
unsigned int vf_height, vf_width,
vf_normal_length, vf_bold_length;
unsigned int vf_refcount;
};
const uint8_t *vtfont_lookup(const struct vt_font *vf, term_char_t c);
struct vt_font *vtfont_ref(struct vt_font *vf);
void vtfont_unref(struct vt_font *vf);
int vtfont_load(vfnt_t *f, struct vt_font **ret);
/* Sysmouse. */
void sysmouse_process_event(mouse_info_t *mi);
#endif /* !_DEV_VT_VT_H_ */

261
sys/dev/vt/vt_buf.c Normal file
View File

@ -0,0 +1,261 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>
#include <dev/vt/vt.h>
static MALLOC_DEFINE(M_VTBUF, "vtbuf", "vt buffer");
#define VTBUF_LOCK(vb) mtx_lock_spin(&(vb)->vb_lock)
#define VTBUF_UNLOCK(vb) mtx_unlock_spin(&(vb)->vb_lock)
static inline uint64_t
vtbuf_dirty_axis(unsigned int begin, unsigned int end)
{
uint64_t left, right, mask;
/*
* Mark all bits between begin % 64 and end % 64 dirty.
* This code is functionally equivalent to:
*
* for (i = begin; i < end; i++)
* mask |= (uint64_t)1 << (i % 64);
*/
/* Obvious case. Mark everything dirty. */
if (end - begin >= 64)
return (VBM_DIRTY);
/* 1....0; used bits on the left. */
left = VBM_DIRTY << begin % 64;
/* 0....1; used bits on the right. */
right = VBM_DIRTY >> -end % 64;
/*
* Only take the intersection. If the result of that is 0, it
* means that the selection crossed a 64 bit boundary along the
* way, which means we have to take the complement.
*/
mask = left & right;
if (mask == 0)
mask = left | right;
return (mask);
}
static inline void
vtbuf_dirty(struct vt_buf *vb, const term_rect_t *area)
{
VTBUF_LOCK(vb);
if (vb->vb_dirtyrect.tr_begin.tp_row > area->tr_begin.tp_row)
vb->vb_dirtyrect.tr_begin.tp_row = area->tr_begin.tp_row;
if (vb->vb_dirtyrect.tr_begin.tp_col > area->tr_begin.tp_col)
vb->vb_dirtyrect.tr_begin.tp_col = area->tr_begin.tp_col;
if (vb->vb_dirtyrect.tr_end.tp_row < area->tr_end.tp_row)
vb->vb_dirtyrect.tr_end.tp_row = area->tr_end.tp_row;
if (vb->vb_dirtyrect.tr_end.tp_col < area->tr_end.tp_col)
vb->vb_dirtyrect.tr_end.tp_col = area->tr_end.tp_col;
vb->vb_dirtymask.vbm_row |=
vtbuf_dirty_axis(area->tr_begin.tp_row, area->tr_end.tp_row);
vb->vb_dirtymask.vbm_col |=
vtbuf_dirty_axis(area->tr_begin.tp_col, area->tr_end.tp_col);
VTBUF_UNLOCK(vb);
}
static inline void
vtbuf_dirty_cell(struct vt_buf *vb, const term_pos_t *p)
{
term_rect_t area;
area.tr_begin = *p;
area.tr_end.tp_row = p->tp_row + 1;
area.tr_end.tp_col = p->tp_col + 1;
vtbuf_dirty(vb, &area);
}
static void
vtbuf_make_undirty(struct vt_buf *vb)
{
vb->vb_dirtyrect.tr_begin = vb->vb_size;
vb->vb_dirtyrect.tr_end.tp_row = vb->vb_dirtyrect.tr_end.tp_col = 0;
vb->vb_dirtymask.vbm_row = vb->vb_dirtymask.vbm_col = 0;
}
void
vtbuf_undirty(struct vt_buf *vb, term_rect_t *r, struct vt_bufmask *m)
{
VTBUF_LOCK(vb);
*r = vb->vb_dirtyrect;
*m = vb->vb_dirtymask;
vtbuf_make_undirty(vb);
VTBUF_UNLOCK(vb);
}
void
vtbuf_copy(struct vt_buf *vb, const term_rect_t *r, const term_pos_t *p2)
{
const term_pos_t *p1 = &r->tr_begin;
term_rect_t area;
unsigned int rows, cols;
int pr;
rows = r->tr_end.tp_row - r->tr_begin.tp_row;
cols = r->tr_end.tp_col - r->tr_begin.tp_col;
/* Handle overlapping copies. */
if (p2->tp_row < p1->tp_row) {
/* Move data up. */
for (pr = 0; pr < rows; pr++)
memmove(
&VTBUF_FIELD(vb, p2->tp_row + pr, p2->tp_col),
&VTBUF_FIELD(vb, p1->tp_row + pr, p1->tp_col),
cols * sizeof(term_char_t));
} else {
/* Move data down. */
for (pr = rows - 1; pr >= 0; pr--)
memmove(
&VTBUF_FIELD(vb, p2->tp_row + pr, p2->tp_col),
&VTBUF_FIELD(vb, p1->tp_row + pr, p1->tp_col),
cols * sizeof(term_char_t));
}
area.tr_begin = *p2;
area.tr_end.tp_row = p2->tp_row + rows;
area.tr_end.tp_col = p2->tp_col + cols;
vtbuf_dirty(vb, &area);
}
void
vtbuf_fill(struct vt_buf *vb, const term_rect_t *r, term_char_t c)
{
unsigned int pr, pc;
for (pr = r->tr_begin.tp_row; pr < r->tr_end.tp_row; pr++)
for (pc = r->tr_begin.tp_col; pc < r->tr_end.tp_col; pc++)
VTBUF_FIELD(vb, pr, pc) = c;
vtbuf_dirty(vb, r);
}
void
vtbuf_init_early(struct vt_buf *vb)
{
vb->vb_flags |= VBF_CURSOR;
vtbuf_make_undirty(vb);
mtx_init(&vb->vb_lock, "vtbuf", NULL, MTX_SPIN);
}
void
vtbuf_init(struct vt_buf *vb, const term_pos_t *p)
{
vb->vb_size = *p;
vb->vb_buffer = malloc(p->tp_row * p->tp_col * sizeof(term_char_t),
M_VTBUF, M_WAITOK);
vtbuf_init_early(vb);
}
void
vtbuf_grow(struct vt_buf *vb, const term_pos_t *p)
{
term_char_t *old, *new;
if (p->tp_row > vb->vb_size.tp_row ||
p->tp_col > vb->vb_size.tp_col) {
/* Allocate new buffer. */
new = malloc(p->tp_row * p->tp_col * sizeof(term_char_t),
M_VTBUF, M_WAITOK|M_ZERO);
/* Toggle it. */
VTBUF_LOCK(vb);
old = vb->vb_flags & VBF_STATIC ? NULL : vb->vb_buffer;
vb->vb_buffer = new;
vb->vb_flags &= ~VBF_STATIC;
vb->vb_size = *p;
vtbuf_make_undirty(vb);
VTBUF_UNLOCK(vb);
/* Deallocate old buffer. */
if (old != NULL)
free(old, M_VTBUF);
}
}
void
vtbuf_putchar(struct vt_buf *vb, const term_pos_t *p, term_char_t c)
{
if (VTBUF_FIELD(vb, p->tp_row, p->tp_col) != c) {
VTBUF_FIELD(vb, p->tp_row, p->tp_col) = c;
vtbuf_dirty_cell(vb, p);
}
}
void
vtbuf_cursor_position(struct vt_buf *vb, const term_pos_t *p)
{
if (vb->vb_flags & VBF_CURSOR) {
vtbuf_dirty_cell(vb, &vb->vb_cursor);
vb->vb_cursor = *p;
vtbuf_dirty_cell(vb, &vb->vb_cursor);
} else {
vb->vb_cursor = *p;
}
}
void
vtbuf_cursor_visibility(struct vt_buf *vb, int yes)
{
int oflags, nflags;
VTBUF_LOCK(vb);
oflags = vb->vb_flags;
if (yes)
vb->vb_flags |= VBF_CURSOR;
else
vb->vb_flags &= ~VBF_CURSOR;
nflags = vb->vb_flags;
VTBUF_UNLOCK(vb);
if (oflags != nflags)
vtbuf_dirty_cell(vb, &vb->vb_cursor);
}

View File

@ -0,0 +1,79 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/consio.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <dev/vt/vt.h>
static d_ioctl_t consolectl_ioctl;
static struct cdevsw consolectl_cdevsw = {
.d_version = D_VERSION,
.d_ioctl = consolectl_ioctl,
.d_name = "consolectl",
};
static int
consolectl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
struct thread *td)
{
switch (cmd) {
case CONS_GETVERS:
*(int*)data = 0x200;
return 0;
case CONS_MOUSECTL: {
mouse_info_t *mi = (mouse_info_t*)data;
sysmouse_process_event(mi);
return (0);
}
default:
printf("consolectl: unknown ioctl: %c:%lx\n",
(char)IOCGROUP(cmd), IOCBASECMD(cmd));
return (ENOIOCTL);
}
}
static void
consolectl_drvinit(void *unused)
{
make_dev(&consolectl_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
"consolectl");
}
SYSINIT(consolectl, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, consolectl_drvinit, NULL);

1041
sys/dev/vt/vt_core.c Normal file

File diff suppressed because it is too large Load Diff

212
sys/dev/vt/vt_font.c Normal file
View File

@ -0,0 +1,212 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/refcount.h>
#include <sys/systm.h>
#include <dev/vt/vt.h>
static MALLOC_DEFINE(M_VTFONT, "vtfont", "vt font");
/* Some limits to prevent abnormal fonts from being loaded. */
#define VTFONT_MAXMAPPINGS 1024
#define VTFONT_MAXGLYPHSIZE 262144
#define VTFONT_MAXDIMENSION 128
static uint16_t
vtfont_bisearch(const struct vt_font_map *map, unsigned int len, uint32_t src)
{
int min, mid, max;
min = 0;
max = len - 1;
/* Empty font map. */
if (len == 0)
return (0);
/* Character below minimal entry. */
if (src < map[0].vfm_src)
return (0);
/* Optimization: ASCII characters occur very often. */
if (src <= map[0].vfm_src + map[0].vfm_len)
return (src - map[0].vfm_src + map[0].vfm_dst);
/* Character above maximum entry. */
if (src > map[max].vfm_src + map[max].vfm_len)
return (0);
/* Binary search. */
while (max >= min) {
mid = (min + max) / 2;
if (src < map[mid].vfm_src)
max = mid - 1;
else if (src > map[mid].vfm_src + map[mid].vfm_len)
min = mid + 1;
else
return (src - map[mid].vfm_src + map[mid].vfm_dst);
}
return (0);
}
const uint8_t *
vtfont_lookup(const struct vt_font *vf, term_char_t c)
{
uint32_t src;
uint16_t dst;
size_t stride;
src = TCHAR_CHARACTER(c);
if (TCHAR_FORMAT(c) & TF_BOLD) {
dst = vtfont_bisearch(vf->vf_bold, vf->vf_bold_length, src);
if (dst != 0)
goto found;
}
dst = vtfont_bisearch(vf->vf_normal, vf->vf_normal_length, src);
found:
stride = howmany(vf->vf_width, 8) * vf->vf_height;
return (&vf->vf_bytes[dst * stride]);
}
struct vt_font *
vtfont_ref(struct vt_font *vf)
{
refcount_acquire(&vf->vf_refcount);
return (vf);
}
void
vtfont_unref(struct vt_font *vf)
{
if (refcount_release(&vf->vf_refcount)) {
free(vf->vf_normal, M_VTFONT);
free(vf->vf_bold, M_VTFONT);
free(vf->vf_bytes, M_VTFONT);
free(vf, M_VTFONT);
}
}
static int
vtfont_validate_map(struct vt_font_map *vfm, unsigned int length,
unsigned int nglyphs)
{
unsigned int i, last = 0;
for (i = 0; i < length; i++) {
/* Not ordered. */
if (i > 0 && vfm[i].vfm_src <= last)
return (EINVAL);
/*
* Destination extends amount of glyphs.
*/
if (vfm[i].vfm_dst >= nglyphs ||
vfm[i].vfm_dst + vfm[i].vfm_len >= nglyphs)
return (EINVAL);
last = vfm[i].vfm_src + vfm[i].vfm_len;
}
return (0);
}
int
vtfont_load(vfnt_t *f, struct vt_font **ret)
{
size_t glyphsize;
struct vt_font *vf;
int error;
/* Make sure the dimensions are valid. */
if (f->width < 1 || f->height < 1)
return (EINVAL);
if (f->width > VTFONT_MAXDIMENSION || f->height > VTFONT_MAXDIMENSION)
return (E2BIG);
/* Not too many mappings. */
if (f->nnormal > VTFONT_MAXMAPPINGS || f->nbold > VTFONT_MAXMAPPINGS)
return (E2BIG);
/* Character 0 must always be present. */
if (f->nglyphs < 1)
return (EINVAL);
glyphsize = howmany(f->width, 8) * f->height * f->nglyphs;
if (glyphsize > VTFONT_MAXGLYPHSIZE)
return (E2BIG);
/* Allocate new font structure. */
vf = malloc(sizeof *vf, M_VTFONT, M_WAITOK);
vf->vf_normal = malloc(f->nnormal * sizeof(struct vt_font_map),
M_VTFONT, M_WAITOK);
vf->vf_bold = malloc(f->nbold * sizeof(struct vt_font_map),
M_VTFONT, M_WAITOK);
vf->vf_bytes = malloc(glyphsize, M_VTFONT, M_WAITOK);
vf->vf_height = f->height;
vf->vf_width = f->width;
vf->vf_normal_length = f->nnormal;
vf->vf_bold_length = f->nbold;
vf->vf_refcount = 1;
/* Copy in data. */
error = copyin(f->normal, vf->vf_normal,
vf->vf_normal_length * sizeof(struct vt_font_map));
if (error)
goto bad;
error = copyin(f->bold, vf->vf_bold,
vf->vf_bold_length * sizeof(struct vt_font_map));
if (error)
goto bad;
error = copyin(f->glyphs, vf->vf_bytes, glyphsize);
if (error)
goto bad;
/* Validate mappings. */
error = vtfont_validate_map(vf->vf_normal, vf->vf_normal_length,
f->nglyphs);
if (error)
goto bad;
error = vtfont_validate_map(vf->vf_bold, vf->vf_bold_length,
f->nglyphs);
if (error)
goto bad;
/* Success. */
*ret = vf;
return (0);
bad: vtfont_unref(vf);
return (error);
}

73
sys/dev/vt/vt_history.c Normal file
View File

@ -0,0 +1,73 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <dev/vt/vt.h>
void
vthistory_add(struct vt_history *vh, struct vt_buf *vb, const term_rect_t *r)
{
/* XXX! */
if (vh->vh_offset != 0) {
vh->vh_offset += r->tr_end.tp_row - r->tr_begin.tp_row;
if (vh->vh_offset > 100)
vh->vh_offset = 100;
}
}
void
vthistory_seek(struct vt_history *vh, int offset, int whence)
{
/* XXX! */
switch (whence) {
case VHS_SET:
vh->vh_offset = offset;
break;
case VHS_CUR:
vh->vh_offset += offset;
break;
case VHS_END:
vh->vh_offset = 100 + offset;
break;
}
if (vh->vh_offset > 100)
vh->vh_offset = 100;
}
void
vthistory_getpos(const struct vt_history *vh, unsigned int *offset)
{
*offset = vh->vh_offset;
}

395
sys/dev/vt/vt_sysmouse.c Normal file
View File

@ -0,0 +1,395 @@
/*-
* Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
* All rights reserved.
*
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/condvar.h>
#include <sys/conf.h>
#include <sys/consio.h>
#include <sys/fcntl.h>
#include <sys/filio.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mouse.h>
#include <sys/poll.h>
#include <sys/random.h>
#include <sys/selinfo.h>
#include <sys/sigio.h>
#include <sys/signalvar.h>
#include <sys/systm.h>
#include <sys/uio.h>
#include <dev/vt/vt.h>
static d_open_t sysmouse_open;
static d_close_t sysmouse_close;
static d_read_t sysmouse_read;
static d_ioctl_t sysmouse_ioctl;
static d_poll_t sysmouse_poll;
static struct cdevsw sysmouse_cdevsw = {
.d_version = D_VERSION,
.d_open = sysmouse_open,
.d_close = sysmouse_close,
.d_read = sysmouse_read,
.d_ioctl = sysmouse_ioctl,
.d_poll = sysmouse_poll,
.d_name = "sysmouse",
};
static struct mtx sysmouse_lock;
static struct cv sysmouse_sleep;
static struct selinfo sysmouse_bufpoll;
static int sysmouse_level;
static mousestatus_t sysmouse_status;
static int sysmouse_flags;
#define SM_ASYNC 0x1
static struct sigio *sysmouse_sigio;
#define SYSMOUSE_MAXFRAMES 250 /* 2 KB */
static MALLOC_DEFINE(M_SYSMOUSE, "sysmouse", "sysmouse device");
static unsigned char *sysmouse_buffer;
static unsigned int sysmouse_start, sysmouse_length;
static int
sysmouse_buf_read(struct uio *uio, unsigned int length)
{
unsigned char buf[MOUSE_SYS_PACKETSIZE];
int error;
if (sysmouse_buffer == NULL)
return (ENXIO);
else if (sysmouse_length == 0)
return (EWOULDBLOCK);
memcpy(buf, sysmouse_buffer +
sysmouse_start * MOUSE_SYS_PACKETSIZE, MOUSE_SYS_PACKETSIZE);
sysmouse_start = (sysmouse_start + 1) % SYSMOUSE_MAXFRAMES;
sysmouse_length--;
mtx_unlock(&sysmouse_lock);
error = uiomove(buf, length, uio);
mtx_lock(&sysmouse_lock);
return (error);
}
static void
sysmouse_buf_store(const unsigned char buf[MOUSE_SYS_PACKETSIZE])
{
unsigned int idx;
if (sysmouse_buffer == NULL || sysmouse_length == SYSMOUSE_MAXFRAMES)
return;
idx = (sysmouse_start + sysmouse_length) % SYSMOUSE_MAXFRAMES;
memcpy(sysmouse_buffer + idx * MOUSE_SYS_PACKETSIZE, buf,
MOUSE_SYS_PACKETSIZE);
sysmouse_length++;
cv_broadcast(&sysmouse_sleep);
selwakeup(&sysmouse_bufpoll);
if (sysmouse_flags & SM_ASYNC && sysmouse_sigio != NULL)
pgsigio(&sysmouse_sigio, SIGIO, 0);
}
void
sysmouse_process_event(mouse_info_t *mi)
{
/* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
static const int buttonmap[8] = {
MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
MOUSE_MSC_BUTTON3UP,
MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
MOUSE_MSC_BUTTON2UP,
MOUSE_MSC_BUTTON1UP,
0,
};
unsigned char buf[MOUSE_SYS_PACKETSIZE];
int x, y, z;
random_harvest(mi, sizeof *mi, 2, 0, RANDOM_MOUSE);
mtx_lock(&sysmouse_lock);
switch (mi->operation) {
case MOUSE_ACTION:
sysmouse_status.button = mi->u.data.buttons;
/* FALLTHROUGH */
case MOUSE_MOTION_EVENT:
x = mi->u.data.x;
y = mi->u.data.y;
z = mi->u.data.z;
break;
case MOUSE_BUTTON_EVENT:
x = y = z = 0;
if (mi->u.event.value > 0)
sysmouse_status.button |= mi->u.event.id;
else
sysmouse_status.button &= ~mi->u.event.id;
break;
default:
goto done;
}
sysmouse_status.dx += x;
sysmouse_status.dy += y;
sysmouse_status.dz += z;
sysmouse_status.flags |= ((x || y || z) ? MOUSE_POSCHANGED : 0) |
(sysmouse_status.obutton ^ sysmouse_status.button);
if (sysmouse_status.flags == 0)
goto done;
/* The first five bytes are compatible with MouseSystems. */
buf[0] = MOUSE_MSC_SYNC |
buttonmap[sysmouse_status.button & MOUSE_STDBUTTONS];
x = imax(imin(x, 255), -256);
buf[1] = x >> 1;
buf[3] = x - buf[1];
y = -imax(imin(y, 255), -256);
buf[2] = y >> 1;
buf[4] = y - buf[2];
/* Extended part. */
z = imax(imin(z, 127), -128);
buf[5] = (z >> 1) & 0x7f;
buf[6] = (z - (z >> 1)) & 0x7f;
/* Buttons 4-10. */
buf[7] = (~sysmouse_status.button >> 3) & 0x7f;
sysmouse_buf_store(buf);
done: mtx_unlock(&sysmouse_lock);
}
static int
sysmouse_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
void *buf;
buf = malloc(MOUSE_SYS_PACKETSIZE * SYSMOUSE_MAXFRAMES,
M_SYSMOUSE, M_WAITOK);
mtx_lock(&sysmouse_lock);
if (sysmouse_buffer == NULL) {
sysmouse_buffer = buf;
sysmouse_start = sysmouse_length = 0;
sysmouse_level = 0;
} else {
free(buf, M_SYSMOUSE);
}
mtx_unlock(&sysmouse_lock);
return (0);
}
static int
sysmouse_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
{
mtx_lock(&sysmouse_lock);
free(sysmouse_buffer, M_SYSMOUSE);
sysmouse_buffer = NULL;
mtx_unlock(&sysmouse_lock);
return (0);
}
static int
sysmouse_read(struct cdev *dev, struct uio *uio, int ioflag)
{
unsigned int length;
ssize_t oresid;
int error = 0;
oresid = uio->uio_resid;
mtx_lock(&sysmouse_lock);
length = sysmouse_level >= 1 ? MOUSE_SYS_PACKETSIZE :
MOUSE_MSC_PACKETSIZE;
while (uio->uio_resid >= length) {
error = sysmouse_buf_read(uio, length);
if (error == 0) {
/* Process the next frame. */
continue;
} else if (error != EWOULDBLOCK) {
/* Error (e.g. EFAULT). */
break;
} else {
/* Block. */
if (oresid != uio->uio_resid || ioflag & O_NONBLOCK)
break;
error = cv_wait_sig(&sysmouse_sleep, &sysmouse_lock);
if (error != 0)
break;
}
}
mtx_unlock(&sysmouse_lock);
return (error);
}
static int
sysmouse_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
struct thread *td)
{
switch (cmd) {
case FIOASYNC:
mtx_lock(&sysmouse_lock);
if (*(int *)data)
sysmouse_flags |= SM_ASYNC;
else
sysmouse_flags &= ~SM_ASYNC;
mtx_unlock(&sysmouse_lock);
return (0);
case FIONBIO:
return (0);
case FIOGETOWN:
*(int *)data = fgetown(&sysmouse_sigio);
return (0);
case FIOSETOWN:
return (fsetown(*(int *)data, &sysmouse_sigio));
case MOUSE_GETHWINFO: {
mousehw_t *hw = (mousehw_t *)data;
hw->buttons = 10;
hw->iftype = MOUSE_IF_SYSMOUSE;
hw->type = MOUSE_MOUSE;
hw->model = MOUSE_MODEL_GENERIC;
hw->hwid = 0;
return (0);
}
case MOUSE_GETLEVEL:
*(int *)data = sysmouse_level;
return (0);
case MOUSE_GETMODE: {
mousemode_t *mode = (mousemode_t *)data;
mode->rate = -1;
mode->resolution = -1;
mode->accelfactor = 0;
mode->level = sysmouse_level;
switch (mode->level) {
case 0:
mode->protocol = MOUSE_PROTO_MSC;
mode->packetsize = MOUSE_MSC_PACKETSIZE;
mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
mode->syncmask[1] = MOUSE_MSC_SYNC;
break;
case 1:
mode->protocol = MOUSE_PROTO_SYSMOUSE;
mode->packetsize = MOUSE_SYS_PACKETSIZE;
mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
mode->syncmask[1] = MOUSE_SYS_SYNC;
break;
}
return (0);
}
case MOUSE_GETSTATUS:
mtx_lock(&sysmouse_lock);
*(mousestatus_t *)data = sysmouse_status;
sysmouse_status.flags = 0;
sysmouse_status.obutton = sysmouse_status.button;
sysmouse_status.dx = 0;
sysmouse_status.dy = 0;
sysmouse_status.dz = 0;
mtx_unlock(&sysmouse_lock);
return (0);
case MOUSE_SETLEVEL: {
int level;
level = *(int *)data;
if (level != 0 && level != 1)
return (EINVAL);
sysmouse_level = level;
return (0);
}
case MOUSE_SETMODE: {
mousemode_t *mode = (mousemode_t *)data;
switch (mode->level) {
case -1:
/* Do nothing. */
break;
case 0:
case 1:
sysmouse_level = mode->level;
break;
default:
return (EINVAL);
}
return (0);
}
default:
printf("sysmouse: unknown ioctl: %c:%lx\n",
(char)IOCGROUP(cmd), IOCBASECMD(cmd));
return (ENOIOCTL);
}
}
static int
sysmouse_poll(struct cdev *dev, int events, struct thread *td)
{
int revents = 0;
mtx_lock(&sysmouse_lock);
if (events & (POLLIN|POLLRDNORM)) {
if (sysmouse_length > 0)
revents = events & (POLLIN|POLLRDNORM);
else
selrecord(td, &sysmouse_bufpoll);
}
mtx_unlock(&sysmouse_lock);
return (revents);
}
static void
sysmouse_drvinit(void *unused)
{
mtx_init(&sysmouse_lock, "sysmouse", NULL, MTX_DEF);
cv_init(&sysmouse_sleep, "sysmrd");
make_dev(&sysmouse_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
"sysmouse");
}
SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sysmouse_drvinit, NULL);

View File

@ -11,13 +11,13 @@ options KDB
options DDB
options XBOX # kernel is for XBOX
device xboxfb # frame buffer support (REQUIRED!)
device sc # syscons
device fb
device vt
device vt_xboxfb # frame buffer support (REQUIRED!)
# no support yet for root device name fetching
options ROOTDEVNAME=\"ufs:ad0s1a\"
#options ROOTDEVNAME=\"ufs:ad0s1a\"
#options ROOTDEVNAME=\"cd9660:acd0\"
options ROOTDEVNAME=\"ufs:label/xboxa\"
options SCHED_4BSD # 4BSD scheduler
options INET # InterNETworking
@ -35,6 +35,7 @@ options NFSCLIENT # Network Filesystem Client
options CD9660 # ISO 9660 Filesystem
#options PROCFS # Process filesystem (requires PSEUDOFS)
#options PSEUDOFS # Pseudo-filesystem framework
options GEOM_LABEL # Provides labelization
#options COMPAT_FREEBSD4 # Compatible with FreeBSD4
#options KTRACE # ktrace(1) support
#options SYSVSHM # SYSV-style shared memory
@ -74,6 +75,8 @@ device pty # BSD-style compatibility pseudo ttys
# Note that 'bpf' is required for DHCP.
device bpf # Berkeley packet filter
device kbdmux # keyboard multiplexer
# USB support
options USB_DEBUG # enable debug msgs
#device uhci # UHCI PCI->USB interface

544
sys/kern/subr_terminal.c Normal file
View File

@ -0,0 +1,544 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/cons.h>
#include <sys/consio.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/terminal.h>
#include <sys/tty.h>
#include <machine/stdarg.h>
static MALLOC_DEFINE(M_TERMINAL, "terminal", "terminal device");
/*
* Locking.
*
* Normally we don't need to lock down the terminal emulator, because
* the TTY lock is already held when calling teken_input().
* Unfortunately this is not the case when the terminal acts as a
* console device, because cnputc() can be called at the same time.
* This means terminals may need to be locked down using a spin lock.
*/
#define TERMINAL_LOCK(tm) do { \
if ((tm)->tm_flags & TF_CONS) \
mtx_lock_spin(&(tm)->tm_mtx); \
else if ((tm)->tm_tty != NULL) \
tty_lock((tm)->tm_tty); \
} while (0)
#define TERMINAL_UNLOCK(tm) do { \
if ((tm)->tm_flags & TF_CONS) \
mtx_unlock_spin(&(tm)->tm_mtx); \
else if ((tm)->tm_tty != NULL) \
tty_unlock((tm)->tm_tty); \
} while (0)
#define TERMINAL_LOCK_TTY(tm) do { \
if ((tm)->tm_flags & TF_CONS) \
mtx_lock_spin(&(tm)->tm_mtx); \
} while (0)
#define TERMINAL_UNLOCK_TTY(tm) do { \
if ((tm)->tm_flags & TF_CONS) \
mtx_unlock_spin(&(tm)->tm_mtx); \
} while (0)
#define TERMINAL_LOCK_CONS(tm) mtx_lock_spin(&(tm)->tm_mtx)
#define TERMINAL_UNLOCK_CONS(tm) mtx_unlock_spin(&(tm)->tm_mtx)
/*
* TTY routines.
*/
static tsw_open_t termtty_open;
static tsw_close_t termtty_close;
static tsw_outwakeup_t termtty_outwakeup;
static tsw_ioctl_t termtty_ioctl;
static struct ttydevsw terminal_tty_class = {
.tsw_open = termtty_open,
.tsw_close = termtty_close,
.tsw_outwakeup = termtty_outwakeup,
.tsw_ioctl = termtty_ioctl,
};
/*
* Terminal emulator routines.
*/
static tf_bell_t termteken_bell;
static tf_cursor_t termteken_cursor;
static tf_putchar_t termteken_putchar;
static tf_fill_t termteken_fill;
static tf_copy_t termteken_copy;
static tf_param_t termteken_param;
static tf_respond_t termteken_respond;
static teken_funcs_t terminal_drawmethods = {
.tf_bell = termteken_bell,
.tf_cursor = termteken_cursor,
.tf_putchar = termteken_putchar,
.tf_fill = termteken_fill,
.tf_copy = termteken_copy,
.tf_param = termteken_param,
.tf_respond = termteken_respond,
};
/* Kernel message formatting. */
static const teken_attr_t kernel_message = {
.ta_fgcolor = TC_WHITE,
.ta_bgcolor = TC_BLACK,
.ta_format = TF_BOLD,
};
static const teken_attr_t default_message = {
.ta_fgcolor = TC_WHITE,
.ta_bgcolor = TC_BLACK,
};
#define TCHAR_CREATE(c, a) ((c) | \
(a)->ta_format << 22 | \
teken_256to8((a)->ta_fgcolor) << 26 | \
teken_256to8((a)->ta_bgcolor) << 29)
static void
terminal_init(struct terminal *tm)
{
if (tm->tm_flags & TF_CONS)
mtx_init(&tm->tm_mtx, "trmlck", NULL, MTX_SPIN);
teken_init(&tm->tm_emulator, &terminal_drawmethods, tm);
teken_set_defattr(&tm->tm_emulator, &default_message);
}
struct terminal *
terminal_alloc(const struct terminal_class *tc, void *softc)
{
struct terminal *tm;
tm = malloc(sizeof(struct terminal), M_TERMINAL, M_WAITOK|M_ZERO);
terminal_init(tm);
tm->tm_class = tc;
tm->tm_softc = softc;
return (tm);
}
static void
terminal_sync_ttysize(struct terminal *tm)
{
struct tty *tp;
tp = tm->tm_tty;
if (tp == NULL)
return;
tty_lock(tp);
tty_set_winsize(tp, &tm->tm_winsize);
tty_unlock(tp);
}
void
terminal_maketty(struct terminal *tm, const char *fmt, ...)
{
struct tty *tp;
char name[8];
va_list ap;
va_start(ap, fmt);
vsnrprintf(name, sizeof name, 32, fmt, ap);
va_end(ap);
tp = tty_alloc(&terminal_tty_class, tm);
tty_makedev(tp, NULL, name);
tm->tm_tty = tp;
terminal_sync_ttysize(tm);
}
void
terminal_set_winsize(struct terminal *tm, const struct winsize *size)
{
term_rect_t r;
tm->tm_winsize = *size;
r.tr_begin.tp_row = r.tr_begin.tp_col = 0;
r.tr_end.tp_row = size->ws_row;
r.tr_end.tp_col = size->ws_col;
TERMINAL_LOCK(tm);
teken_set_winsize(&tm->tm_emulator, &r.tr_end);
TERMINAL_UNLOCK(tm);
/* Blank screen. */
tm->tm_class->tc_fill(tm, &r,
TCHAR_CREATE((teken_char_t)' ', &default_message));
terminal_sync_ttysize(tm);
}
/*
* XXX: This function is a kludge. Drivers like vt(4) need to
* temporarily stop input when resizing, etc. This should ideally be
* handled within the driver.
*/
void
terminal_mute(struct terminal *tm, int yes)
{
TERMINAL_LOCK(tm);
if (yes)
tm->tm_flags |= TF_MUTE;
else
tm->tm_flags &= ~TF_MUTE;
TERMINAL_UNLOCK(tm);
}
void
terminal_input_char(struct terminal *tm, term_char_t c)
{
struct tty *tp;
tp = tm->tm_tty;
if (tp == NULL)
return;
/* Strip off any attributes. */
c = TCHAR_CHARACTER(c);
tty_lock(tp);
/*
* Conversion to UTF-8.
*/
if (c < 0x80) {
ttydisc_rint(tp, c, 0);
} else if (c < 0x800) {
char str[2] = {
0xc0 | (c >> 6),
0x80 | (c & 0x3f)
};
ttydisc_rint_simple(tp, str, sizeof str);
} else if (c < 0x10000) {
char str[3] = {
0xe0 | (c >> 12),
0x80 | ((c >> 6) & 0x3f),
0x80 | (c & 0x3f)
};
ttydisc_rint_simple(tp, str, sizeof str);
} else {
char str[4] = {
0xf0 | (c >> 18),
0x80 | ((c >> 12) & 0x3f),
0x80 | ((c >> 6) & 0x3f),
0x80 | (c & 0x3f)
};
ttydisc_rint_simple(tp, str, sizeof str);
}
ttydisc_rint_done(tp);
tty_unlock(tp);
}
void
terminal_input_raw(struct terminal *tm, char c)
{
struct tty *tp;
tp = tm->tm_tty;
if (tp == NULL)
return;
tty_lock(tp);
ttydisc_rint(tp, c, 0);
ttydisc_rint_done(tp);
tty_unlock(tp);
}
void
terminal_input_special(struct terminal *tm, unsigned int k)
{
struct tty *tp;
const char *str;
tp = tm->tm_tty;
if (tp == NULL)
return;
str = teken_get_sequence(&tm->tm_emulator, k);
if (str == NULL)
return;
tty_lock(tp);
ttydisc_rint_simple(tp, str, strlen(str));
ttydisc_rint_done(tp);
tty_unlock(tp);
}
/*
* Binding with the TTY layer.
*/
static int
termtty_open(struct tty *tp)
{
struct terminal *tm = tty_softc(tp);
tm->tm_class->tc_opened(tm, 1);
return (0);
}
static void
termtty_close(struct tty *tp)
{
struct terminal *tm = tty_softc(tp);
tm->tm_class->tc_opened(tm, 0);
}
static void
termtty_outwakeup(struct tty *tp)
{
struct terminal *tm = tty_softc(tp);
char obuf[128];
size_t olen;
unsigned int flags = 0;
while ((olen = ttydisc_getc(tp, obuf, sizeof obuf)) > 0) {
TERMINAL_LOCK_TTY(tm);
if (!(tm->tm_flags & TF_MUTE)) {
tm->tm_flags &= ~TF_BELL;
teken_input(&tm->tm_emulator, obuf, olen);
flags |= tm->tm_flags;
}
TERMINAL_UNLOCK_TTY(tm);
}
tm->tm_class->tc_done(tm);
if (flags & TF_BELL)
tm->tm_class->tc_bell(tm);
}
static int
termtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
struct terminal *tm = tty_softc(tp);
int error;
switch (cmd) {
case CONS_GETINFO: {
vid_info_t *vi = (vid_info_t *)data;
const teken_pos_t *p;
int fg, bg;
if (vi->size != sizeof(vid_info_t))
return (EINVAL);
/* Already help the console driver by filling in some data. */
p = teken_get_cursor(&tm->tm_emulator);
vi->mv_row = p->tp_row;
vi->mv_col = p->tp_col;
p = teken_get_winsize(&tm->tm_emulator);
vi->mv_rsz = p->tp_row;
vi->mv_csz = p->tp_col;
teken_get_defattr_cons25(&tm->tm_emulator, &fg, &bg);
vi->mv_norm.fore = fg;
vi->mv_norm.back = bg;
/* XXX: keep vidcontrol happy; bold backgrounds. */
vi->mv_rev.fore = bg;
vi->mv_rev.back = fg & 0x7;
break;
}
}
/*
* Unlike various other drivers, this driver will never
* deallocate TTYs. This means it's safe to temporarily unlock
* the TTY when handling ioctls.
*/
tty_unlock(tp);
error = tm->tm_class->tc_ioctl(tm, cmd, data, td);
tty_lock(tp);
return (error);
}
/*
* Binding with the kernel and debug console.
*/
static cn_probe_t termcn_probe;
static cn_init_t termcn_init;
static cn_term_t termcn_term;
static cn_getc_t termcn_getc;
static cn_putc_t termcn_putc;
const struct consdev_ops termcn_ops = {
.cn_probe = termcn_probe,
.cn_init = termcn_init,
.cn_term = termcn_term,
.cn_getc = termcn_getc,
.cn_putc = termcn_putc,
};
static void
termcn_probe(struct consdev *cp)
{
struct terminal *tm = cp->cn_arg;
terminal_init(tm);
tm->tm_class->tc_cnprobe(tm, cp);
}
static void
termcn_init(struct consdev *cp)
{
}
static void
termcn_term(struct consdev *cp)
{
}
static int
termcn_getc(struct consdev *cp)
{
struct terminal *tm = cp->cn_arg;
return (tm->tm_class->tc_cngetc(tm));
}
static void
termcn_putc(struct consdev *cp, int c)
{
struct terminal *tm = cp->cn_arg;
teken_attr_t backup;
char cv = c;
TERMINAL_LOCK_CONS(tm);
if (!(tm->tm_flags & TF_MUTE)) {
backup = *teken_get_curattr(&tm->tm_emulator);
teken_set_curattr(&tm->tm_emulator, &kernel_message);
teken_input(&tm->tm_emulator, &cv, 1);
teken_set_curattr(&tm->tm_emulator, &backup);
}
TERMINAL_UNLOCK_CONS(tm);
tm->tm_class->tc_done(tm);
}
/*
* Binding with the terminal emulator.
*/
static void
termteken_bell(void *softc)
{
struct terminal *tm = softc;
tm->tm_flags |= TF_BELL;
}
static void
termteken_cursor(void *softc, const teken_pos_t *p)
{
struct terminal *tm = softc;
tm->tm_class->tc_cursor(tm, p);
}
static void
termteken_putchar(void *softc, const teken_pos_t *p, teken_char_t c,
const teken_attr_t *a)
{
struct terminal *tm = softc;
tm->tm_class->tc_putchar(tm, p, TCHAR_CREATE(c, a));
}
static void
termteken_fill(void *softc, const teken_rect_t *r, teken_char_t c,
const teken_attr_t *a)
{
struct terminal *tm = softc;
tm->tm_class->tc_fill(tm, r, TCHAR_CREATE(c, a));
}
static void
termteken_copy(void *softc, const teken_rect_t *r, const teken_pos_t *p)
{
struct terminal *tm = softc;
tm->tm_class->tc_copy(tm, r, p);
}
static void
termteken_param(void *softc, int cmd, unsigned int arg)
{
struct terminal *tm = softc;
tm->tm_class->tc_param(tm, cmd, arg);
}
static void
termteken_respond(void *softc, const void *buf, size_t len)
{
#if 0
struct terminal *tm = softc;
struct tty *tp;
/*
* Only inject a response into the TTY if the data actually
* originated from the TTY.
*
* XXX: This cannot be done right now. The TTY could pick up
* other locks. It could also in theory cause loops, when the
* TTY performs echoing of a command that generates even more
* input.
*/
tp = tm->tm_tty;
if (tp == NULL)
return;
ttydisc_rint_simple(tp, buf, len);
ttydisc_rint_done(tp);
#endif
}

View File

@ -1352,6 +1352,16 @@ tty_flush(struct tty *tp, int flags)
}
}
void
tty_set_winsize(struct tty *tp, struct winsize *wsz)
{
if (memcmp(&tp->t_winsize, wsz, sizeof *wsz) == 0)
return;
tp->t_winsize = *wsz;
tty_signal_pgrp(tp, SIGWINCH);
}
static int
tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
struct thread *td)
@ -1658,10 +1668,7 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
return (0);
case TIOCSWINSZ:
/* Set window size. */
if (bcmp(&tp->t_winsize, data, sizeof(struct winsize)) == 0)
return (0);
tp->t_winsize = *(struct winsize*)data;
tty_signal_pgrp(tp, SIGWINCH);
tty_set_winsize(tp, data);
return (0);
case TIOCEXCL:
tp->t_flags |= TF_EXCLUDE;

View File

@ -209,12 +209,33 @@ struct fnt16 {
};
typedef struct fnt16 fnt16_t;
struct vfnt_map {
uint32_t src;
uint16_t dst;
uint16_t len;
};
typedef struct vfnt_map vfnt_map_t;
struct vfnt {
vfnt_map_t *normal;
vfnt_map_t *bold;
uint8_t *glyphs;
unsigned int nnormal;
unsigned int nbold;
unsigned int nglyphs;
unsigned int width;
unsigned int height;
};
typedef struct vfnt vfnt_t;
#define PIO_FONT8x8 _IOW('c', 64, fnt8_t)
#define GIO_FONT8x8 _IOR('c', 65, fnt8_t)
#define PIO_FONT8x14 _IOW('c', 66, fnt14_t)
#define GIO_FONT8x14 _IOR('c', 67, fnt14_t)
#define PIO_FONT8x16 _IOW('c', 68, fnt16_t)
#define GIO_FONT8x16 _IOR('c', 69, fnt16_t)
#define PIO_VFONT _IOW('c', 70, vfnt_t)
#define GIO_VFONT _IOR('c', 71, vfnt_t)
/* get video mode information */
struct colors {

156
sys/sys/terminal.h Normal file
View File

@ -0,0 +1,156 @@
/*-
* Copyright (c) 2009 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _SYS_TERMINAL_H_
#define _SYS_TERMINAL_H_
#include <sys/param.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/cons.h>
#include <sys/linker_set.h>
#include <sys/ttycom.h>
#include <teken/teken.h>
struct terminal;
struct thread;
struct tty;
/*
* The terminal layer is an abstraction on top of the TTY layer and the
* console interface. It can be used by system console drivers to
* easily interact with the kernel console and TTYs.
*
* Terminals contain terminal emulators, which means console drivers
* don't need to implement their own terminal emulator. The terminal
* emulator deals with UTF-8 exclusively. This means that term_char_t,
* the data type used to store input/output characters will always
* contain Unicode codepoints.
*
* To save memory usage, the top bits of term_char_t will contain other
* attributes, like colors. Right now term_char_t is composed as
* follows:
*
* Bits Meaning
* 0-20: Character value
* 21: Unused
* 22-25: Bold, underline, blink, reverse
* 26-28: Foreground color
* 29-31: Background color
*/
typedef uint32_t term_char_t;
#define TCHAR_CHARACTER(c) ((c) & 0x1fffff)
#define TCHAR_FORMAT(c) (((c) >> 22) & 0xf)
#define TCHAR_FGCOLOR(c) (((c) >> 26) & 0x7)
#define TCHAR_BGCOLOR(c) ((c) >> 29)
typedef teken_color_t term_color_t;
#define TCOLOR_LIGHT(c) ((c) | 0x8)
#define TCOLOR_DARK(c) ((c) & ~0x8)
typedef teken_pos_t term_pos_t;
typedef teken_rect_t term_rect_t;
typedef void tc_cursor_t(struct terminal *tm, const term_pos_t *p);
typedef void tc_putchar_t(struct terminal *tm, const term_pos_t *p,
term_char_t c);
typedef void tc_fill_t(struct terminal *tm, const term_rect_t *r,
term_char_t c);
typedef void tc_copy_t(struct terminal *tm, const term_rect_t *r,
const term_pos_t *p);
typedef void tc_param_t(struct terminal *tm, int cmd, unsigned int arg);
typedef void tc_done_t(struct terminal *tm);
typedef void tc_cnprobe_t(struct terminal *tm, struct consdev *cd);
typedef int tc_cngetc_t(struct terminal *tm);
typedef void tc_opened_t(struct terminal *tm, int opened);
typedef int tc_ioctl_t(struct terminal *tm, u_long cmd, caddr_t data,
struct thread *td);
typedef void tc_bell_t(struct terminal *tm);
struct terminal_class {
/* Terminal emulator. */
tc_cursor_t *tc_cursor;
tc_putchar_t *tc_putchar;
tc_fill_t *tc_fill;
tc_copy_t *tc_copy;
tc_param_t *tc_param;
tc_done_t *tc_done;
/* Low-level console interface. */
tc_cnprobe_t *tc_cnprobe;
tc_cngetc_t *tc_cngetc;
/* Misc. */
tc_opened_t *tc_opened;
tc_ioctl_t *tc_ioctl;
tc_bell_t *tc_bell;
};
struct terminal {
const struct terminal_class *tm_class;
void *tm_softc;
struct mtx tm_mtx;
struct tty *tm_tty;
teken_t tm_emulator;
struct winsize tm_winsize;
unsigned int tm_flags;
#define TF_MUTE 0x1 /* Drop incoming data. */
#define TF_BELL 0x2 /* Bell needs to be sent. */
#define TF_CONS 0x4 /* Console device (needs spinlock). */
};
#ifdef _KERNEL
struct terminal *terminal_alloc(const struct terminal_class *tc, void *softc);
void terminal_maketty(struct terminal *tm, const char *fmt, ...);
void terminal_set_winsize(struct terminal *tm, const struct winsize *size);
void terminal_mute(struct terminal *tm, int yes);
void terminal_input_char(struct terminal *tm, term_char_t c);
void terminal_input_raw(struct terminal *tm, char c);
void terminal_input_special(struct terminal *tm, unsigned int k);
/* Kernel console helper interface. */
extern const struct consdev_ops termcn_ops;
#define TERMINAL_DECLARE_EARLY(name, class, softc) \
static struct terminal name = { \
.tm_class = &class, \
.tm_softc = softc, \
.tm_flags = TF_CONS, \
}; \
CONSOLE_DEVICE(name ## _consdev, termcn_ops, &name)
#endif /* _KERNEL */
#endif /* !_SYS_TERMINAL_H_ */

View File

@ -161,6 +161,7 @@ void tty_rel_gone(struct tty *tp);
#define tty_lock(tp) mtx_lock((tp)->t_mtx)
#define tty_unlock(tp) mtx_unlock((tp)->t_mtx)
#define tty_lock_owned(tp) mtx_owned((tp)->t_mtx)
#define tty_lock_assert(tp,ma) mtx_assert((tp)->t_mtx, (ma))
#define tty_getlock(tp) ((tp)->t_mtx)
@ -186,6 +187,7 @@ int tty_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
struct thread *td);
int tty_ioctl_compat(struct tty *tp, u_long cmd, caddr_t data,
int fflag, struct thread *td);
void tty_set_winsize(struct tty *tp, struct winsize *wsz);
void tty_init_console(struct tty *tp, speed_t speed);
void tty_flush(struct tty *tp, int flags);
void tty_hiwat_in_block(struct tty *tp);